Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ
  • në shtëpi
  • Windows 7, XP
  • Heqja e objekteve të shënuara, zëvendësimi i lidhjeve. Aplikim i rregullt dhe i menaxhuar

Heqja e objekteve të shënuara, zëvendësimi i lidhjeve. Aplikim i rregullt dhe i menaxhuar

Kohët e fundit ka pasur shumë artikuj në lidhje me disavantazhet e Bitrix dhe përgënjeshtrimet e tyre. Meqenëse pirja ka vazhduar kështu, unë do të shtoj 5 cent.
Në komentet e artikujve shkruanin se mungonin specifikat, shembujt dhe një rishikim më i thelluar.

Ky artikull është një përpjekje për të shkruar këtë përmbledhje. Edhe pse jo, ky është më shumë një postim urrejtjeje dhe dhimbjeje (ndoshta edhe pak ankim). Ky është një version i zgjeruar i postimit në lidhje me disavantazhet e pistoletës. Do të përpiqem të përshkruaj shumicën e gjërave që më acarojnë mua dhe kolegët e mi në Bitrix. Do të përpiqem të mbledh në një postim të gjitha ato disavantazhe që shkaktojnë shumë dhimbje çdo ditë. Në fund do të përpiqem të nxjerr përfundime.

Kush jam unë? Po, në përgjithësi, një zhvillues i zakonshëm. Unë kam punuar me Bitrix që nga nëntori 2010 (5.5 vjet). Duke punuar vetëm me Bitrix, nuk krijoi një projekt të vetëm tregtar duke përdorur CMS të tjera, nuk përdori korniza për të krijuar faqe interneti. Sipas linjës së punës, merrem kryesisht me dyqanet online, krijimin, mbështetjen dhe zhvillimin e tyre.

TL; DR

Bitrix - UG, nuk duhet të futeni në këtë pishinë përveç rasteve kur është absolutisht e nevojshme.

Në vend të një hyrjeje

Për të filluar, ju sugjeroj të bëni një eksperiment mendimi. Le të përpiqemi të marrim dy zhvillues backend të përafërsisht të së njëjtës moshë dhe me afërsisht të njëjtën përvojë pune (le të themi 1 - 1.5 vjet), vetëm në mënyrë që njëri prej tyre të ketë punuar gjatë gjithë kësaj kohe me 1C-Bitrix, dhe tjetri me Symfony ( për shembull). Mund të krahasoni lehtësisht se me çfarë grupesh teknologjish ka punuar njëri gjatë gjithë kësaj kohe, dhe me çfarë ka punuar tjetri dhe çfarë njohurish kanë marrë përfundimisht gjatë kësaj kohe.

Në rastin e një zhvilluesi të Symfony, kjo do të jetë: php5/7 + kuptim i thellë i OOP, modele të pranuara përgjithësisht të dizajnit (të paktën MVC, DI, Fabrika, Depo), aftësia për të zhvilluar testet e njësisë, përdorimi i motorëve shabllon (të paktën twig ), ORM (me Doktrinë), kompozitor , git, standardet PSR, përvojë pune me tastierën dhe shkrimin e aplikacioneve të konsolës, aftësi bazë në vendosjen e një serveri në internet.

Në rastin e një zhvilluesi 1C-Bitrix, ky do të jetë php5, html/css + javascript/jquery (nuk ka motorë shabllonesh jashtë kutisë, dhe Bitrix vendos logjikën në shabllone, çfarëdo që mund të thotë dikush, do të duhet të ngatërroj me të), ndoshta git (dhe kjo varet shumë nga kompania, disa dinosaur janë ende duke sharruar në prodhim nëpërmjet FTP), nëse jeni me fat - pak sql dhe... kjo është e gjitha?

Unë e kuptoj që e gjithë kjo është shumë individuale dhe mjedisi i një personi mund të luajë një rol shumë të rëndësishëm. Por këtu po flas për atë që zhvilluesi i sistemit po shtyhet të bëjë jashtë kutisë. Në shumicën e rasteve, një zhvillues Bitrix është shumë inferior në aftësi në krahasim me zhvilluesit për korniza/CMS të tjera - dhe ky është një fakt i padiskutueshëm. Dhe e gjitha sepse Bitrix fillimisht jep shumë liri në mungesë të një arkitekture të qartë, dokumentacionit dhe zgjidhjeve korrekte, ndërsa Symfony ofron gjithçka që ju nevojitet.

Vetëm një herë erdhi në kompaninë tonë një person me përvojë jo nga bota e 1C-Bitrix (në rajon) dhe ai ishte kokë e shpatull mbi kolegët e tij me të njëjtën përvojë, thjesht për faktin se më parë ishte vënë në rrugën e drejtë.
Unë vetë kështu jam. Fatkeqësisht, që në fillim u mashtrova nga të njëjtat budallallëqe marketingu dhe përfundova në një mjedis jo shumë të mirë. Unë vetë e kuptoj dhe ndjej se kolegët e mi me përvojë të ngjashme pune, por në të njëjtën Symfony, kanë një këndvështrim më të gjerë, dhe ky është një efekt anësor shumë i fortë i Bitrix.
E gjithë kjo sugjeron që nëse doni të zhvilloheni në botën e zhvillimit të uebit, atëherë nuk duhet të zgjidhni përfundimisht Bitrix si bazë.

Duke krahasuar dy zhvilluesit, dua të tërheq vëmendjen te kuadri në të cilin na detyron sistemi dhe liria që ai ofron. Të dy Bitrix dhe Symfony - të dy ofrojnë fleksibilitet pothuajse të pakufishëm, dhe në parim, në secilën prej tyre mund të krijoni një produkt absolutisht të çdo kompleksiteti. Sidoqoftë, sistemi duhet të ndihmojë zhvilluesin të zgjidhë problemet, në vend që të vendosë një fole në rrota. Dhe këtu Bitrix humbet shumë.

Marketingu

Unë dua të them disa fjalë për këtë menjëherë, sepse ... ky është komponenti kryesor i suksesit të Bitrix.
Mund të themi se i gjithë Bitrix, madje edhe dokumentacioni për zhvilluesit, është i mbushur me frymën e marketingut. Edhe atje ata shkruajnë se produkti i tyre është "aq i lezetshëm sa vlerësohet dhe respektohet nga të gjithë partnerët tanë" (provë, blloku "Struktura"). Bitrix punëson tregtarë të mirë që dinë me kompetencë të paraqesin produktin e tyre. Një herë në gjashtë muaj ata organizojnë konferenca për partnerët, ku flasin për atë që është bërë dhe cilat janë planet e tyre. Siç tregon praktika, këto plane nuk realizohen kurrë në kohë dhe shumë shpesh publikimet janë ose të paplota ose plot gabime.
Si shembull, rifaktorimi i bujshëm i modulit të shitjes, lëshimi i të cilit u vonua për më shumë se një vit, madje edhe data e fundit e lëshimit (23 Dhjetor 2015) u mungua për 3 muaj, dhe një dyqan i ri dhe BUS (Bitrix ed. "Menaxhimi i sitit") versioni 16 u lëshua vetëm në fund të marsit 2016. Por si rezultat, pas përditësimit, përdoruesit jo vetëm që nuk morën veçori të reja. Përdoruesit morën një dyqan kryesisht jofunksional dhe një grumbull kodesh të reja pa dokumente për të nisur.
Mjeteve të reja u jepen emra të tillë me zë të lartë që të gjithë i dinë: Vendi i përbërë - nxitimi x100; blloqe me ngarkesë të lartë; Bitrix BigData. Në fakt, këto fjalë fshehin gjëra krejt të zakonshme që nuk i përshtaten emrit të tyre.
Dhe kjo qasje mund të shihet kudo, për fat të keq. Nga jashtë, produkti duket si një karamele që keni blerë, instaluar dhe përdorur. Por nëse bëni një hap larg dorëzimit standard me Bitrix - kjo është e gjitha, ruajtja e funksionalitetit gjatë përditësimeve kthehet në ferr.
Sidoqoftë, së pari, tema e marketingut ka shumë të ngjarë të shfaqet në këtë postim më shumë se një herë.

Arkitekturë

Për dhjetë vjet, Bitrix e ka çuar veten dëshpërimisht në një rrugë pa krye. Çdo veçori e re në produkt u lëshua në përputhje me interesat e biznesit, pa zhvillim të duhur nga pikëpamja teknike. Dhe, natyrisht, e gjithë kjo u rrit si një top bore.
Nëse mendoni për këtë, Bitrix nuk ka arkitekturë si të tillë. Nuk ka as rregulla të formuluara përgjithësisht të pranuara që do ta lejonin njeriun të ndjekë këtë arkitekturë. Në kursin e zhvilluesit, në seksionin "Arkitektura e produkteve", thuhet se Bitrix ndjek arkitekturën MVC dhe ofron një diagram:

Dua të them menjëherë se kjo MVC është shumë e ndryshme nga versioni klasik. Këtu ka një zëvendësim shumë të fortë të koncepteve, në fakt nuk ka MVC këtu, ka thjesht një lloj ndarje abstrakte në module, komponentë dhe shabllone përbërësish. Dhe i gjithë vendi është ndërtuar nga këto tulla. Por secila prej këtyre tullave mund të marrë përsipër detyra të ndryshme, dhe për këtë arsye ato janë të ndërlidhura ngushtë.
Do të përpiqem të shikoj secilën nga këto aspekte të arkitekturës në më shumë detaje.

M - Model, ose API

Është e vështirë për mua të gjykoj API-në e sistemit si model. Po, API ofron një ndërfaqe për të hyrë në të dhëna dhe ju lejon t'i manipuloni ato. Por Bitrix API ju lejon të punoni jo vetëm me të dhëna, por edhe me shabllone, si dhe me kërkesat e përdoruesve. Epo, ky është vetëm mendimi im.
Për momentin, Bitrix ka 2 opsione API. Në mënyrë konvencionale, ato mund të ndahen në e vjetër Dhe i ri. API i ri quhet D7 (sinqerisht, nuk mbaj mend pse, por Rizhikov foli për të në një nga konferencat e partnerëve).

API-ja e vjetër është një koleksion antimodelesh, shembuj të tmerrshëm të kodit të keq. Në Bitrix, është konsideruar gjithmonë normale të thirren metoda jostatike në mënyrë statike, dhe anasjelltas, të kërkohet gjendje kur është e papërshtatshme. Për shembull, CIBlockElement::GetList i mirënjohur është ndoshta një nga metodat më të përdorura në zhvillim. Zbatimi i tij përmban më shumë se 500 rreshta kodi, përdor globale, ndërton pyetje të tmerrshme, kolosale dhe përmban kod jorealist, thjesht të palexueshëm, të padokumentuar.

Le të shohim

Funksioni GetList($arOrder=array("SORT"=>"ASC"), $arFilter=array(), $arGroupBy=false, $arNavStartParams=false, $arSelectFields=array()) ( /* Kombinimet e filtrit: CHECK_PERMISSIONS= "N" - kontrolloni lejet e përdoruesit aktual në bllokun e informacionit MIN_PERMISSION="R" - kur kontrolloni lejet, më pas niveli minimal i aksesit SHOW_HISTORY="N" - shtoni artikujt e historisë në listën SHOW_NEW="N" - nëse jo shtoni artikuj historik, pastaj shtoni elementë të rinj, por jo të publikuar */ globale $DB, $USER; $MAX_LOCK = intval(COption::GetOptionString("workflow","MAX_LOCK_TIME","60")); $uid = is_object($USER)? intval($USER->GetID()): 0; $formatActiveDates = CPageOption::GetOptionString("iblock", "FORMAT_ACTIVE_DATES", "-") != "-"; $shortFormatActiveDates = CPageOption::GetOptionString("iblock" , "FORMAT_ACTIVE_DATES", "SHORT"); $arIblockElementFields = grup("ID"=>"BE.ID", "TIMESTAMP_X"=>$DB->DateToCharFunction("BE.TIMESTAMP_X"), "TIMESTAMP_X_UNIX"=>" UNIX_TIMESTAMP(BE.TIMESTAMP_X)", "MODIFIED_BY"=>"BE.MODIFIED_BY", "DATE_CREATE"=>$DB->DateToCharFunction("BE.DATE_CREATE"), "DATE_CREATE_UNIX"=>"UNIX_TIMESTAMP"BEATE. , "CREATED_BY"=>"BE.CREATED_BY", "IBLOCK_ID"=>"BE.IBLOCK_ID", "IBLOCK_SECTION_ID"=>"BE.IBLOCK_SECTION_ID", "ACTIVE"=>"BE.ACTIVE", "ACTIVE_FROM"=> ($formatActiveDates ? $DB->DateToCharFunction("BE.ACTIVE_FROM", $shortFormatActiveDates) : "IF(EXTRACT(HOUR_SECOND NGA BE.ACTIVE_FROM)>0, ".$DB->DateToCharFROM("BE.ACTIVE_FROM"), "ULF)."F , ".$DB->DateToCharFunction("BE.ACTIVE_FROM", "SHORT").")"), "ACTIVE_TO"=>($formatActiveDates ? $DB->DateToCharFunction("BE.ACTIVE_TO", $shortFormatActiveDates) : "IF(EXTRACT(HOUR_SECOND FROM BE.ACTIVE_TO)>0, ".$DB->DateToCharFunction("BE.ACTIVE_TO", "FULL").", ".$DB->DateToCharFunction("BE.ACTIVE_TO", " SHORT").")"), "DATE_ACTIVE_FROM"=>($formatActiveDates ? $DB->DateToCharFunction("BE.ACTIVE_FROM", $shortFormatActiveDates) : "IF(EXTRACT(HOUR_SECOND NGA BE.ACTIVE>0FROM). $DB->DateToCharFunction("BE.ACTIVE_FROM", "FULL").", ".$DB->DateToCharFunction("BE.ACTIVE_FROM", "SHORT").")"), "DATE_ACTIVE_TO"=>($ formatActiveDates ? $DB->DateToCharFunction("BE.ACTIVE_TO", $shortFormatActiveDates) : "IF(EXTRACT(HOUR_SECOND FROM BE.ACTIVE_TO)>0, ".$DB->DateToCharFunction("BE.ACTIVE_FUL"TO)", .", ".$DB->DateToCharFunction("BE.ACTIVE_TO", "SHORT").")"), "SORT"=>"BE.SORT", "NAME"=>"BE.NAME", " PREVIEW_PICTURE"=>"BE.PREVIEW_PICTURE", "PREVIEW_TEXT"=>"BE.PREVIEW_TEXT", "PREVIEW_TEXT_TYPE"=>"BE.PREVIEW_TEXT_TYPE", "DETAIL_PICTURE"=>"BE. DETAIL_PICTURE", "DETAIL_TEXT"=>"BE.DETAIL_TEXT", "DETAIL_TEXT_TYPE"=>"BE.DETAIL_TEXT_TYPE", "SEARCHABLE_CONTENT"=>"BE.SEARCHABLE_CONTENT", "WF_STATUSE.DETAIL_TEXT", "WF_STATUSE.BE_IDWENT"BE. =>"BE.WF_PARENT_ELEMENT_ID", "WF_LAST_HISTORY_ID"=>"BE.WF_LAST_HISTORY_ID", "WF_NEW"=>"BE.WF_NEW", "LOCK_STATUS"=>"nëse (BE.WF_DATE_LOCK është e pavlefshme, nëse, "e gjelbër" DATE_ADD (BE.WF_DATE_LOCK, intervali ".$MAX_LOCK." MINUTE) "BE.WF_LOCKED_BY", "WF_DATE_LOCK"=>$DB->DateToCharFunction("BE.WF_DATE_LOCK"), "WF_COMMENTS"=>"BE.WF_COMMENTS", "IN_SECTIONS"=>"BE.IN_SECTIONS", "SHOW_ER" >"BE.SHOW_COUNTER", "SHOW_COUNTER_START"=>$DB->DateToCharFunction("BE.SHOW_COUNTER_START"), "CODE"=>"BE.CODE", "TAGS"=>"BE.TAGS", "XML_ID" =>"BE.XML_ID", "EXTERNAL_ID"=>"BE.XML_ID", "TMP_ID"=>"BE.TMP_ID", "USER_NAME"=>"concat("(",U.LOGIN,") ", ifnull(U.NAME,"")," ",ifnull(U.LAST_NAME,""))", "LOCKED_USER_NAME"=>"concat("(",UL.LOGIN,"") ",ifnull(UL. EMRI ","")," ",ifnull(UL.LAST_NAME,""))", "CREATED_USER_NAME"=>"concat("(",UC.LOGIN,"") ",ifnull(UC.NAME," "), " ",ifnull(UC.LAST_NAME,""))", "LANG_DIR"=>"L.DIR", "LID"=>"B.LID", "IBLOCK_TYPE_ID"=>"B.IBLOCK_TYPE_ID" , "IBLOCK_CODE "=>"B.CODE", "IBLOCK_NAME"=>"B.NAME", "IBLOCK_EXTERNAL_ID"=>"B.XML_ID", "DETAIL_PAGE_URL"=>"B.DETAIL_PAGE_URL", "LIST_PAGE_URL"=> "B. LIST_PAGE_URL", "CANONICAL_PAGE_URL"=>"B.CANONICAL_PAGE_URL", "CREATED_DATE"=>$DB->DateFormatToDB("YYYY.MM.DD", "BE.DATE_CREATE"), "BP_PUBLISH" (BE. WF_STATUS_ID = 1, "Y", "N")",); unset ($shortFormatActiveDates); unset ($formatActiveDates); $bDistinct = false; CIBlockElement::PrepareGetList($arIblockElementFields, $arJoinProps, $bOnlyCount, $bDistinct, $arSelectFields, $sSelect, $arAddSelectFields, $arFilter, $sWhere, $sSectionWhere, $roBary, $sSectionWhere, $roGary Porosit, $arSqlOrder, $arAddOrderByFields, $arIBlockFilter, $arIBlockMultProps, $arIBlockConvProps, $arIBlockAllProps, $arIBlockNumProps, $arIBlockLongProps); $arFilterIBlocks = isset($arFilter["IBLOCK_ID"])? array($arFilter["IBLOCK_ID"]): array(); //****************NGA PJESA************************************ ************** $sFrom = ""; foreach($arJoinProps["FPS"] as $iblock_id => $iPropCnt) ( $sFrom .= "ttttINNER JOIN b_iblock_element_prop_s".$iblock_id." FPS".$iPropCnt." ON FPS".$iPropCnt.".ID_CK BE.IDn"; $arFilterIBlocks[$iblock_id] = $iblock_id; ) foreach($arJoinProps["FP"] si $propID => $db_prop) ($i = $db_prop["CNT"]; if($db_prop[ "bFullJoin"]) $sFrom .= "tttINNER JOIN b_iblock_property FP".$i." NË FP".$i.".IBLOCK_ID = B.ID DHE ". (IntVal($propID)>0? "FP". $i.".ID=".IntVal($propID)."n": "FP".$i.".CODE="".$DB->ForSQL($propID, 200).""n") ; else $sFrom .= "tttLEFT JOIN b_iblock_property FP".$i." NË FP".$i.".IBLOCK_ID = B.ID DHE ". (IntVal($propID)>0? " FP".$i. ".ID=".IntVal($propID)."n": "FP".$i.".CODE="".$DB->ForSQL($propID, 200). ""n"); if($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop["IBLOCK_ID"]] = $db_prop["IBLOCK_ID"]; ) foreach ($arJoinProps["FPV"] ​​si $ propID = > $db_prop) ( $i = $db_prop["CNT"]; if($db_prop["MULTIPLE"]=="Y") $bDistinct = e vërtetë; if($db_prop["VERSION"]==2 ) $ strTable = "b_iblock_element_prop_m".$db_prop["IBLOCK_ID"]; tjetër $strTable = "b_iblock_element_property"; if($db_prop["bFullJoin"]) $sFrom .= "tttINNER BASHKOHU ".$str.". $i ." ON FPV".$i.".IBLOCK_PROPERTY_ID = FP".$db_prop["JOIN"].".ID DHE FPV".$i.".IBLOCK_ELEMENT_ID = BE.IDn"; tjetër $sFrom .= "tttLEFT JOIN ".$strTable." FPV".$i." NË FPV".$i.".IBLOCK_PROPERTY_ID = FP".$db_prop["JOIN"].".ID DHE FPV".$i.". IBLOCK_ELEMENT_ID = BE.IDn"; if($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop["IBLOCK_ID"]] = $db_prop["IBLOCK_ID"]; ) foreach($arJoinProps["FPEN"] => $db_prop) ( $i = $db_prop["CNT"]; if($db_prop["VERSION"] == 2 && $db_prop["MULTIPLE"] == "N") ( if($db_prop[" bFullJoin" ]) $sFrom .= "tttINNER JOIN b_iblock_property_enum FPEN".$i." ON FPEN".$i.".PROPERTY_ID = ".$db_prop["ORIG_ID"]." DHE FPS".$db_prop["BASHKONI "] ".PROPERTY_".$db_prop["ORIG_ID"]." = FPEN".$i.".IDn"; else $sFrom .= "tttLEFT JOIN b_iblock_property_enum FPEN".$i." ON FPEN".$i.".PROPERTY_ID = ".$db_prop["ORIG_ID"].." DHE FPS".$db_prop["BASHKOHU"] ".PROPERTY_".$db_prop["ORIG_ID"]." = FPEN".$i.".IDn"; ) else ( if($db_prop["bFullJoin"]) $sFrom .= "tttINNER JOIN b_iblock_property_enum FPEN".$i." ON FPEN".$i.".PROPERTY_ID = FPV".$db_prop["BASHKONI"]. ".IBLOCK_PROPERTY_ID DHE FPV".$db_prop["JOIN"].".VALUE_ENUM = FPEN".$i.".IDn"; tjetër $sFrom .= "ttttLEFT JOIN b_iblock_property_enum FPEN".$i." NË FPEN". $i.".PROPERTY_ID = FPV".$db_prop["JOIN"].".IBLOCK_PROPERTY_ID DHE FPV".$db_prop["JOIN"].".VALUE_ENUM = FPEN".$i.".IDn"; ) nëse ($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop["IBLOCK_ID"]] = $db_prop["IBLOCK_ID"]; ) foreach($arJoinProps["BE"] as $propID => $db_prop) ( $i = $db_prop["CNT"]; $sFrom .= "tttLEFT JOIN b_iblock_element BE".$i." NË BE".$ i.".ID = ". ($db_prop["VERSION"]==2 && $db_prop["MULTIPLE"]=="N"? "FPS".$db_prop["JOIN"].". PROPERTY_". $db_prop["ORIG_ID"] :"FPV".$db_prop["JOIN"]..VALUE_NUM"). ($arFilter["SHOW_HISTORY"] != "Y"? " DHE ((BE.WF_STATUS_ID=1 DHE BE .WF_PARENT_ELEMENT_ID ËSHTË NULL)".($arFilter["SHOW_NEW"]=="Y"? " OSE BE.WF_NEW="Y"": "").")": "")."n"; nëse ( $db_prop["bJoinIBlock"]) $sFrom .= "tttLEFT JOIN b_iblock B".$i." ON B".$i.".ID = BE".$i.".IBLOCK_IDn"; if($db_prop [ "bJoinSection"]) $sNga . = "tttLEFT JOIN b_iblock_section BS".$i." ON BS".$i.".ID = BE".$i.".IBLOCK_SECTION_IDn"; if($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop["IBLOCK_ID"]] = $db_prop["IBLOCK_ID"]; ) foreach($arJoinProps["BE_FPS"] si $iblock_id => $db_prop) ($sFrom .= "tttLEFT JOIN b_iblock_element_prop_s".$iblock_id." JFPS".$db_prop["CNT"]." NË JFPS".$. db_prop["CNT"].".IBLOCK_ELEMENT_ID = BE".$db_prop["BASHKOHU"].".IDn"; if($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop["IBLOCK_ID"]] = $ db_prop["IBLOCK_ID"]; ) foreach($arJoinProps["BE_FP"] si $propID => $db_prop) ($i = $db_prop["CNT"]; list($propID, $link) = shpërthejë ("~ ", $propID, 2); if($db_prop["bFullJoin"]) $sFrom .= "tttINNER JOIN b_iblock_property JFP".$i." NË JFP".$i.".IBLOCK_ID = BE".$db_prop[ "JOIN"].".IBLOCK_ID DHE ". (IntVal($propID)>0? " JFP".$i.".ID=".IntVal($propID)."n": " JFP".$i. ".CODE="".$DB->ForSQL($propID, 200).""n");ndryshe $sFrom .= "tttLEFT JOIN b_iblock_property JFP".$i." NË JFP".$i.". IBLOCK_ID = BE".$db_prop["JOIN"].".IBLOCK_ID DHE ". (IntVal($propID)>0? " JFP".$i.".ID=".IntVal($propID)."n" : " JFP".$i.".CODE="".$DB->ForSQL($propID, 200).""n"); if($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop[" IBLOCK_ID"]] = $db_prop["IBLOCK_ID"]; ) foreach($arJoinProps["BE_FPV"] as $propID => $db_prop) ($i = $db_prop["CNT"]; list($propID, $link) = shpërthejë ("~", $propID, 2) ; if($db_prop["MULTIPLE"]=="Y") $bDistinct = e vërtetë; if($db_prop["VERSION"]==2) $strTable = "b_iblock_element_prop_m".$db_prop["IBLOCK_ID"] ; else $strTable = "b_iblock_element_property"; if($db_prop["bFullJoin"]) $sFrom .= "ttttINNER JOIN ".$strTable." JFPV".$i." NË JFPV".$i.".IBLOCK_PROPERTY_ID = JFP" .$db_prop["JOIN"].".ID DHE JFPV".$i.".IBLOCK_ELEMENT_ID = BE".$db_prop["BE_JOIN"].".IDn"; else $sFrom .= "ttttLEFT BASHKOHU " .$ strTable." JFPV".$i." ON JFPV".$i.".IBLOCK_PROPERTY_ID = JFP".$db_prop["JOIN"].".ID DHE JFPV".$i.".IBLOCK_ELEMENT_ID = BE" .$ db_prop["BE_JOIN"].".IDn"; if($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop["IBLOCK_ID"]] = $db_prop["IBLOCK_ID"]; ) foreach([$arJoinProps "BE_FPEN "] si $propID => $db_prop) ( $i = $db_prop["CNT"]; listë ($propID, $link) = shpërthejë ("~", $propID, 2); nëse ($db_prop[ "VERSIONI "] == 2 && $db_prop["MULTIPLE"] == "N") ( if($db_prop["bFullJoin"]) $sFrom .= "tttINNER JOIN b_iblock_property_enum JFPEN".$i." NË JFPEN" .$ i.".PROPERTY_ID = ".$db_prop["ORIG_ID"].." DHE JFPS".$db_prop["JOIN"].".PROPERTY_".$db_prop["ORIG_ID"].." = JFPEN" .$i. ".IDn"; tjetër $sNga . = "tttLEFT JOIN b_iblock_property_enum JFPEN".$i." NË JFPEN".$i.".PROPERTY_ID = ".$db_prop["ORIG_ID"].." DHE JFPS".$db_prop["BASHKOHU"].".PROPERTY_ " .$db_prop["ORIG_ID"]." = JFPEN".$i.".IDn"; ) else ( if($db_prop["bFullJoin"]) $sFrom .= "tttINNER JOIN b_iblock_property_enum JFPEN".$i." ON JFPEN".$i.".PROPERTY_ID = JFPV".$db_prop["BASHKOHU"]. ".IBLOCK_PROPERTY_ID DHE JFPV".$db_prop["JOIN"].".VALUE_ENUM = JFPEN".$i.".IDn"; tjetër $sFrom .= "ttttLEFT JOIN b_iblock_property_enum JFPEN".$i." NË JFPEN". $i.".PROPERTY_ID = JFPV".$db_prop["JOIN"].".IBLOCK_PROPERTY_ID DHE JFPV".$db_prop["JOIN"].".VALUE_ENUM = JFPEN".$i.".IDn"; ) nëse ($db_prop["IBLOCK_ID"]) $arFilterIBlocks[$db_prop["IBLOCK_ID"]] = $db_prop["IBLOCK_ID"]; ) if(strlen($arJoinProps["BES"])) ($sFrom .= "tttt".$arJoinProps["BES"]."n"; ) if(strlen($arJoinProps["FC"])) ( $sFrom .= "ttt".$arJoinProps["FC"]."n"; $bDistinct = $bDistinct || (isset($arJoinProps["FC_DISTINCT"]) && $arJoinProps["FC_DISTINCT"] == "Y "); ) if($arJoinProps["RV"]) $sFrom .= "tttLEFT JOIN b_rating_voting RV ON RV.ENTITY_TYPE_ID = "IBLOCK_ELEMENT" DHE RV.ENTITY_ID = BE.IDn"; if($arJoinProps["RVU"]) $sFrom .= "ttttLEFT JOIN b_rating_vote RVU ON RVU.ENTITY_TYPE_ID = "IBLOCK_ELEMENT" DHE RVU.ENTITY_ID = BE.ID DHE RVU.USER_ID."n = ".$u." if($arJoinProps["RVV"]) $sFrom .= "tttt".($arJoinProps["RVV"]["bFullJoin"]? "INNER": "LEFT")." JOIN b_rating_vote RVV NË RVV.ENTITY_TYPE_ID = "IBLOCK_ELEMENT" DHE RVV.ENTITY_ID = BE.IDn"; //********************FUNDI I NGA PJESA**************************** ********* ****************** $bCatalogSort = false; if(count($arAddSelectFields)>0 || count($arAddWhereFields)>0 || count($arAddOrderByFields)>0) (if(CModule::IncludeModule("catalog")) ($res_catalog = CCatalogGetrayu:BuildeProduct: $arAddOrderByFields, $arAddWhereFields, $arAddSelectFields); if($sGroupBy=="" && !$bOnlyCount && !(is_object($this) && isset($this->strField))) $slog[Select_cat. "]." "; $sFrom .= str_replace("LAFT JOIN", "ntttLEFT JOIN", $res_catalog["FROM"])."n"; //$sWhere .= $res_catalog["KU"]." "; u zhvendos në MkFilter if(is_array($res_catalog["ORDER"]) && count($res_catalog["ORDER"])) ($bCatalogSort = true; foreach($res_catalog["ORDER"] si $i=>$ val) $arSqlOrder[$i] = $val; ) ) ) $i = array_search("CREATED_BY_FORMATTED", $arSelectFields); if ($i !== false) ( if ($sSelect && $sGroupBy=="" && !$bOnlyCount && !(is_object($this) && isset($this->strField))) ( $sSelect .= " , UC. NAME UC_NAME, UC.LAST_NAME UC_LAST_NAME, UC.SECOND_NAME UC_SECOND_NAME, UC.EMAIL UC_EMAIL, UC.ID UC_ID, UC.LOGIN UC_LOGIN"; ) tjetër ( unset($arSelectFields[$i]sy]; foreach($arSqlOrder as $i=>$val) ( if(strlen($val)) ( if($sOrderBy=="") $sOrderBy = " ORDER BY "; other $sOrderBy .= ","; $sOrderBy .= $val." "; ) ) $sSelect = trim($sSelect, ", tnr"); if(strlen($sSelect)<= 0) $sSelect = "0 as NOP "; $bDistinct = $bDistinct || (isset($arFilter["INCLUDE_SUBSECTIONS"]) && $arFilter["INCLUDE_SUBSECTIONS"] == "Y"); if($bDistinct) $sSelect = str_replace("%%_DISTINCT_%%", "DISTINCT", $sSelect); else $sSelect = str_replace("%%_DISTINCT_%%", "", $sSelect); $sFrom = " b_iblock B INNER JOIN b_lang L ON B.LID=L.LID INNER JOIN b_iblock_element BE ON BE.IBLOCK_ID = B.ID ".ltrim($sFrom, "tn") .(in_array("USER_NAME", $arSelectFields)? "tttLEFT JOIN b_user U ON U.ID=BE.MODIFIED_BYn": "") .(in_array("LOCKED_USER_NAME", $arSelectFields)? "tttLEFT JOIN b_user UL ON UL.ID=BE.WF_LOCKED_BYn": "") .(in_array("CREATED_USER_NAME", $arSelectFields) || in_array("CREATED_BY_FORMATTED", $arSelectFields)? "tttLEFT JOIN b_user UC ON UC.ID=BE.CREATED_BYn": "")." "; $strSql = " FROM ".$sFrom." WHERE 1=1 " .$sWhere." ".$sGroupBy." "; if(isset($this) && is_object($this) && isset($this->strField)) ( $this->sFrom = $sFrom; $this->sWhere = $sWhere; ktheni "SELECT ".$sSelect.$strSql; ) if($bOnlyCount) ( $res = $DB->Query(" SELECT ".$sSelect.$strSql, false, "FILE: ".__FILE__."
LINE: ".__LINE__); $res = $res->Fetch(); kthe $res["CNT"]; ) if(is_array($arNavStartParams)) ($nTopCount = intval($arNavStartParams["nTopCount"]) ; $nElementID = intval($arNavStartParams["nElementID"]); if($nTopCount > 0) ($strSql = "SELECT ".$sSelect.$strSql.$sOrderBy." LIMIT ".$nTopCount; $res = $ DB->Query($strSql); ) elseif($nElementID > 0 && $sGroupBy == "" && $sOrderBy != "" && strpos($sZgjidh, "BE.ID") !== false && !$bCatalogSort ) ( $nPageSize = intval($arNavStartParams["nPageSize"]); if($nPageSize > 0) ($DB->Query("SET @rank_e=0"); $DB->Query("SET @rank_r= 0"); $DB->Query(" SELECT ".$sSelect." ,@rank_r:=@rank_r+1 AS rank1 ,if (BE.ID = ".$nElementID.", @rank_e:=@rank_r, null) rank2 ".$strSql.$sOrderBy." "); $DB->Query("SET @rank_r=0"); $res = $DB->Query(" SELECT * FROM (SELECT ".$sZgjidh. " ,@rank_r:=@rank_r+1 AS RANK ".$strSql.$sOrderBy." LIMIT 18446744073709551615) el0 KU el0.RANK midis @rank_e-$nPageSize dhe @rank_e+$nPageSize"); ) else ( $DB->Query("SET @rank=0"); $res = $DB->Query(" SELECT * FROM (SELECT ".$sSelect." ,@rank:=@rank+1 AS RANK ".$strSql.$sOrderBy." LIMIT 18446744073709551615) el0 WHERE el0.ID = ".$nElementID." "); ) ) tjetër ( if($sGroupBy == "") ( $res_cnt = $DB-> pyetje "SELECT COUNT(".($bDistinct? "DISTINCT BE.ID": ""x"").") si C ".$strSql); $res_cnt = $res_cnt->Fetch(); $cnt = $res_cnt ["C"]; ) else ( $res_cnt = $DB->Query("SELECT "x" ".$strSql); $cnt = $res_cnt->SelectedRowsCount(); ) $strSql = "SELECT ".$sZgjidh .$strSql.$sOrderBy; $res = CDBResult (); $res->NavQuery($strSql, $cnt, $arNavStartParams); ) ) else//if(is_array($arNavStartParams)) ( $strSql = "SELECT ".$sSelect.$strSql.$sOrderBy; $res = $DB->Query($strSql, false, "FILE: ".__FILE__."
LINE: ".__LINE__); ) $res = CIBlockResult ($res); $res->SetIBlockTag ($arFilterIBlocks); $res->arIBlockMultProps = $arIBlockMultProps; $res->arIBlockConvProps = $arIBlockConvProps; $res-> arIBlockAllProps = $arIBlockAllProps; $res->arIBlockNumProps = $arIBlockNumProps; $res->arIBlockLongProps = $arIBlockLongProps; ktheje $res; )

Siç mund ta merrni me mend, kjo metodë merr një listë të elementeve të bllokut të informacionit nga baza e të dhënave dhe për të marrë listën nuk kërkohet krijimi i një shembulli të klasës CIBlockElement. Megjithatë, për të shtuar një element blloku informacioni, kërkohet një gjendje dhe vetëm për të regjistruar informacionin në lidhje me gabimin e fundit që ka ndodhur në një pronë publike të klasës.

API-ja e vjetër përdor shumë variabla globale si $APPLICATION, $USER, $DB. Janë shembuj të klasave të caktuara dhe në dokumentacion quheshin me krenari beqarë, edhe pse tani nuk i kam gjetur më këto fjalë.
Për të gjeneruar një gabim, për shembull, në mbajtësit e ngjarjeve, duhet të përdorni metodën $APPLICATION->ThrowException(), e cila në fakt nuk hedh përjashtime.

Funksioni publik ThrowException($msg, $id = false) ($this->ResetException(); if(is_object($msg) && (is_subclass_of($msg, "CApplicationException") || (strtolower(get_class($msg)) =="capplicationexception"))) $this->LAST_ERROR = $msg; tjetër $this->LAST_ERROR = CApplicationException i ri ($msg, $id); )

Dhe po - e gjithë kjo bukuri përdoret ende në zhvillimin e projekteve të reja, sepse... D7 nuk i mbështet ende të gjitha tiparet e API-së së vjetër. I njëjti modul infoblock ende ju lejon të kryeni vetëm një përzgjedhje entitetesh, dhe jo plotësisht. Nuk është ende e mundur të krijohet një element i ri ose të përditësohet një ekzistues duke përdorur API-në e re.

API-ja e re tashmë është disi e ndryshme nga ajo e vjetra. Së pari, i gjithë kodi nga kerneli i ri ndahet në hapësira emrash, ku ka një varësi të qartë nga moduli. Për shembull, analogu i CIBlockElement::GetList nga bërthama e re është BitrixIblockElementTable::getList, ku hapësira e emrit të rrënjës është emri i shitësit dhe hapësira tjetër e emrave është emri i modulit. Në mënyrë që kjo të funksionojë, Bitrix shkroi ngarkuesin e vet automatik, BitrixMainLoader::autoLoad, i cili nuk është aspak i pajtueshëm me PSR-0/4.

Në fakt, kodi i ngarkuesit automatik në formën e një funksioni

Funksioni statik publik autoLoad($className) ( $file = ltrim($className, "\"); // rregullo env web $file = strtr($file, static::ALPHA_UPPER, static::ALPHA_LOWER); statik $documentRoot = null;nëse ($documentRoot === null) $documentRoot = statike::getDocumentRoot();if (isset(self::$arAutoLoadClasses[$file])) ($pathInfo = vet::$arAutoLoadClasses[$file]; if ($pathInfo["module"] != "") ( $m = $pathInfo["module"]; $h = isset(self::$arLoadedModulesHolders[$m]) ? vetë:$arLoadedModulesHolders[$m ] : "bitrix"; include_once($documentRoot."/".$h."/modules/".$m."/" .$pathInfo["file"]); ) else ( require_once($documentRoot.$pathInfo ["skedar"]); ) kthim; ) nëse (preg_match ("#[^\\/a-zA-Z0-9_]#", $file)) kthehu; nëse (substr($file, -5) = = "tabela") $file = substr ($file, 0, -5); $file = str_replace ("\", "/", $file); $arFile = shpërthejë ("/", $file); nëse ($arFile === "bitrix") ( array_shift ($arFile); nëse (bosh ($arFile)) kthehet; $module = array_shift ($arFile); nëse ($module == null || bosh ($arFile) ) kthim; ) else ( $module1 = array_shift ($arFile); $module2 = array_shift ($arFile); nëse ($module1 == null || $module2 == null || bosh ($arFile)) kthehet; $module = $module1 .".".$module2; ) nëse (!isset(self::$arLoadedModulesHolders[$module])) kthehet; $filePath = $documentRoot."/".self::$arLoadedModulesHolders[$module].."/modules/".$module."/lib/".implode("/", $arFile).".php" ; nëse (skedari_ekziston ($filePath)) kërkon_një herë ($filePath); )

API-ja e re tregon shumë dashuri për Singleton:

  • BitrixMainApplication::getInstance - shembulli i aplikacionit
  • BitrixMainConfigConfiguration::getInstance - shembull i klasës për menaxhimin e konfigurimeve
  • BitrixMainPageAsset::getInstance - shembulli i menaxherit të aseteve
  • BitrixMainEventManager::getInstance - menaxher i ngjarjeve

Ndoshta në të ardhmen e gjithë kjo do të marrë ServiceLayer-in e vet (ekziston një BitrixMainServiceManager në bërthamën e re, i cili ende nuk është përdorur dhe nuk është i dokumentuar). Por ende ka pak shpresë.

ORM është një tjetër nga risitë e D7, dhe kjo është diçka që mund të pretendojë të jetë një model i vërtetë! Ju mund të dalloni një klasë entiteti ORM nga çdo klasë tjetër me emrin e saj. Një klasë entiteti duhet të përfundojë gjithmonë me Table (ElementTable, SectionTable, OrderTable, etj.). Për më tepër, në mënyrë paradoksale, emri i skedarit me klasën e entitetit ORM nuk duhet të përfundojë në Tabelë. Për shembull, për ElementTable duhet të krijojmë një skedar element.php. Pamja e ekranit më poshtë tregon përmbajtjen e drejtorisë lib (D7 automatikisht funksionon vetëm në këtë direktori) të modulit iblock. Mundohuni të përcaktoni me sy se cilat janë entitetet ORM dhe cilat janë klasat e zakonshme me logjikë biznesi.


ORM, në përgjithësi, nuk është ende ndonjë gjë e veçantë. Kjo ju lejon të përshkruani tabelat e bazës së të dhënave në formën e klasave dhe ju lejon të ekzekutoni pyetje në këto tabela dhe t'i lidhni ato me njëra-tjetrën. Nuk ka ActiveRecord ose Depo dhe nuk pritet.

Një shembull i një klase tipike entiteti ORM për një element infobllok

*

  • ID-ja është e detyrueshme *
  • Koha e datës TIMESTAMP_X opsionale *
  • MODIFIED_BY int opsionale *
  • DATE_CREATE ora e datës opsionale *
  • CREATED_BY int opsionale *
  • IBLOCK_ID është i detyrueshëm *
  • IBLOCK_SECTION_ID është opsionale *
  • ACTIVE bool opsionale e paracaktuar "Y" *
  • ACTIVE_FROM datatime opsionale *
  • ACTIVE_TO ora e datës opsionale *
  • SORT int si parazgjedhje opsionale 500 *
  • vargu NAME(255) i detyrueshëm *
  • PREVIEW_PICTURE jo opsionale *
  • vargu PREVIEW_TEXT opsional *
  • PREVIEW_TEXT_TYPE enum ("tekst", "html") opsional "tekst" i parazgjedhur *
  • DETAIL_PICTURE jo opsionale *
  • vargu DETAIL_TEXT opsional *
  • DETAIL_TEXT_TYPE enum ("tekst", "html") opsional "tekst" i parazgjedhur *
  • vargu SEARCHABLE_CONTENT opsional *
  • WF_STATUS_ID int parazgjedhje opsionale 1 *
  • WF_PARENT_ELEMENT_ID është opsionale *
  • WF_NEW numër ("N", "Y") opsionale *
  • WF_LOCKED_BY int opsionale *
  • WF_DATE_LOCK ora e datës opsionale *
  • vargu WF_COMMENTS opsional *
  • IN_SECTIONS bool parazgjedhje opsionale "N" *
  • XML_ID vargu (255) opsional *
  • vargu CODE (255) opsional *
  • Vargu TAGS (255) opsional *
  • Vargu TMP_ID (40) opsional *
  • WF_LAST_HISTORY_ID int opsionale *
  • SHOW_COUNTER int opsionale *
  • SHOW_COUNTER_START ora e datës opsionale *
  • PREVIEW_PICTURE_FILE referencë për (@link BitrixFileFileTable) *
  • Referenca DETAIL_PICTURE_FILE te (@link BitrixFileFileTable) *
  • Referenca IBLOCK në (@link BitrixIblockIblockTable) *
  • Referenca WF_PARENT_ELEMENT te (@link BitrixIblockIblockElementTable) *
  • Referenca IBLOCK_SECTION në (@link BitrixIblockIblockSectionTable) *
  • Referenca MODIFIED_BY_USER për (@link BitrixUserUserTable) *
  • Referenca CREATED_BY_USER për (@link BitrixUserUserTable) *
  • Referenca WF_LOCKED_BY_USER në (@link BitrixUserUserTable) * * * @package BitrixIblock **/ class ElementTable zgjeron MainEntityDataManager ( const TYPE_TEXT = "tekst"; const TYPE_HTML = "html"; /** * Kthen emrin e tabelës DB për entitetin. * * @return string */ funksioni statik publik getTableName( ) ( kthen "b_iblock_element"; ) /** * Kthen përkufizimin e hartës së entitetit. * * @return grup */ funksioni statik publik getMap() ( kthimi i grupit ("ID" => i ri MainEntityIntegerField("ID", grupi ("primar " => true, "autocomplete" => true, "title" => Loc::getMessage("ELEMENT_ENTITY_ID_FIELD"),)), "TIMESTAMP_X" => new MainEntityDatetimeField("TIMESTAMP_X", array("default_value" => e re MainTypeDateTime() ,)), "DATE_CREATE" => MainEntityDatetimeField i ri("DATE_CREATE", grupi("default_value" => MainTypeDateTime i ri(), "titulli" => Loc::getMessage("ELEMENT_ENTITY_DATE_CREATE_REATE_REATED"), > New MainEntityIntegerField("CREATED_BY", grup("title" => Loc::getMessage("ELEMENT_ENTITY_CREATED_BY_FIELD"),)), "IBLOCK_ID" => i ri MainEntityIntegerField("IBLOCK_ID", "array e kuqe" =>" title" => Loc::getMessage("ELEMENT_ENTITY_IBLOCK_ID_FIELD"),)), "IBLOCK_SECTION_ID" => MainEntityIntegerField i ri("IBLOCK_SECTION_ID", grupi ("title" => Loc::getMessage("ELE_IB_CKTIONS), "ELEMENTY_CKS" ACTIVE" => new MainEntityBooleanField("ACTIVE", array("values" => array("N", "Y"), "default_value" => "Y", "title" => Loc::getMessage("ELEMENT_ENTITY_ACTIVE_FIELD "),)), "ACTIVE_FROM" => e re MainEntityDatetimeField("ACTIVE_FROM", grup("titull" => Loc::getMessage("ELEMENT_ENTITY_ACTIVE_FROM_FIELD"),)), "ACTIVE_TO" =>Entity_FROM e re",(TO_TIData e re array("title" => Loc::getMessage("ELEMENT_ENTITY_ACTIVE_TO_FIELD"),)), "SORT" => new MainEntityIntegerField("SORT", array("default_value" => 500, "title" => Loc::getMessage ("ELEMENT_ENTITY_SORT_FIELD"),)), "NAME" => e re MainEntityStringField("NAME", grup ("kërkohet" => e vërtetë, "validim" => grup (__CLASS__, "validateName"), "title" => Loc ::getMessage("ELEMENT_ENTITY_NAME_FIELD"),)), "PREVIEW_PICTURE" => i ri MainEntityIntegerField("PREVIEW_PICTURE", array("title" => Loc::getMessage("ELEMENT_ENTITY_PREVIEW_PICTURE"),"EXT_PREVIEW_PICTURE i ri), "REVIEW_PICTURE), MainEntityTextField("PREVIEW_TEXT", array("title" => Loc::getMessage("ELEMENT_ENTITY_PREVIEW_TEXT_FIELD"),)), "PREVIEW_TEXT_TYPE" => i ri MainEntityEnumField("PREVIEWPE":Ray_ray TYPE_TEXT, vetë::TYPE_HTML), "default_value" => vet::TYPE_TEXT, "title" => Loc::getMessage("ELEMENT_ENTITY_PREVIEW_TEXT_TYPE_FIELD"),)), "DETAIL_PICTURE" => argjilja kryesoreFetë",(REICTRIGERF) e re "title" => Loc::getMessage("ELEMENT_ENTITY_DETAIL_PICTURE_FIELD"),)), "DETAIL_TEXT" => MainEntityTextField i ri("DETAIL_TEXT", grupi("titulli" => Loc::getMessage("ELE_DETAILTY),TEXTY), "DETAIL_TEXT_TYPE" => e re MainEntityEnumField("DETAIL_TEXT_TYPE", grup("vlera" => grup(vetë::TYPE_TEXT, vetë::TYPE_HTML), "default_value" => vet::TYPE_TEXT, "titulli: =>" getMessage("ELEMENT_ENTITY_DETAIL_TEXT_TYPE_FIELD"),)), "SEARCHABLE_CONTENT" => e re MainEntityTextField("SEARCHABLE_CONTENT", grup("title" => Loc::getMessage("ELEMENT_ENTITY_FIELD"), "ELEMENT_ENTITY_TAR" ="ELEMENT_ENTITY_TAR" inEntityIntegerField( "Wf_status_id", Array ("Title" => Loc :: getmessage ("Element_entity_wf_status_id_field"),)), "WF_PARENT_ELEMENT_ID" => New MainentityintegerField , Array ("Title" => Loc :: Getmessage "Fusha_element___" ), "WF_NEW" => New MainEntityEnumField("WF_NEW", array("values" => grup("N", "Y"), "title" => Loc::getMessage("ELEMENT_ENTITY_WF_NEW_FIELD") ,)), "WF_LOCKED_BY" => i ri MainEntityIntegerField("WF_LOCKED_BY", array("title" => Loc::getMessage("ELEMENT_ENTITY_WF_LOCKED_BY_FIELD"),)), "WF_DATE_LOCK" => "arriti"DyFtimeRayEn > Loc::getMessage("ELEMENT_ENTITY_WF_DATE_LOCK_FIELD"),)), "WF_COMMENTS" => MainEntityTextField i ri("WF_COMMENTS", grup("titulli" => Loc::getMessage("ELEMENT_ENTITY_WFFieldS"_COMMENTS) > new MainEntityBooleanField("IN_SECTIONS", array("values" => array("N", "Y"), "title" => Loc::getMessage("ELEMENT_ENTITY_IN_SECTIONS_FIELD"),)), "XML_ID" => e re MainEntityStringField("XML_ID", array("validation" => grup(__CLASS__, "validateXmlId"), "title" => Loc::getMessage("ELEMENT_ENTITY_XML_ID_FIELD"),)), "CODE" => New MainEntity(CODE ", array("validation" => grup (__CLASS__, "validateCode"), "title" => Loc::getMessage("ELEMENT_ENTITY_CODE_FIELD"),)), "TAGS" => e re MainEntityStringField("TAGS", array( "validation" => grup (__CLASS__, "validateTags"), "title" => Loc::getMessage("ELEMENT_ENTITY_TAGS_FIELD"), "TMP_ID" => i ri MainEntityStringField("TMP_ID", array( "validation" => grup( __KLASA__, "va

    Dhe një shembull i punës me këtë entitet

    //Zgjedhja e të dhënave $dbElements = BitrixIblockElementTable::query() ->setFilter(["IBLOCK_ID" => CATALOG_IBLOCK_ID, "ACTIVE" => "Y"]) ->setSelect(["NAME", "ID", "DETAIL_PAGE_URL ", "DATE_ACTIVE_FROM"]) ->addSelect("IBLOCK_SECTION_ID", "PARENT_SECTION") ->setLimit(10) ->addOrder("id", "DESC") ->exec(); ndërsa ($arElement = $dbElements->fetch()) ( echo "($arElement["NAME"]) - " . $arElement["DATE_ACTIVE_FROM"]->format("d.m.Y H:i:s"); ) //Shtimi i një rekordi $addResult = BitrixIblockElementTable::add([ "EMRI" => "Emri i elementit të ri", "IBLOCK_ID" => CATALOG_IBLOCK_ID ]); if (!$addResult->isSuccess()) (echo implode("
    " ,$addResult->getErrorMessages()); )

    Bitrix është shumë krenar për modulin e tij Highload Blocks, i cili është shkruar tërësisht duke përdorur D7.
    Më parë, ata kishin vetëm blloqe informacioni si një ruajtje për një grup arbitrar informacioni. Një bllok informacioni, për ata që nuk e dinë, është një ent që ruhet në bazën e të dhënave si një kompleks i disa tabelave (1 tabelë për fushat "bazë" të një elementi blloku informacioni dhe deri në 2 tabela për vetitë e një elementi i bllokut të informacionit). Të gjitha fushat e elementeve bazë të gjithë infoblloqet ruhen në një tabelë. Nëse keni 15 blloqe informacioni, secila prej të cilave ka 500 mijë elementë, të gjithë këta elementë do të jenë në të vërtetë në një tabelë. Vetitë shtesë të elementeve të infobllokut janë bashkuar nga tabela të tjera. Nëse këto janë blloqe informacioni të versionit të parë, atëherë të gjitha vetitë e të gjitha blloqeve të informacionit janë gjithashtu në një tabelë, dhe në rastin e blloqeve të informacionit 2.0 (përshëndetje, marketing) - vetitë e secilit bllok informacioni tashmë janë të ndara në tabela të ndryshme .
    Dhe e gjithë kjo natyrisht u ngadalësua shumë tashmë në grupe relativisht të vogla të dhënash. 400 mijë elementë në një bllok informacioni tashmë po ngadalësojnë mjaft punën e panelit të administratorit. Tregtarët në Bitrix menduan dhe krijuan blloqe Highload! Dallimi në zbatimin midis blloqeve konvencionale të informacionit është minimal. Tani, për çdo bllok të ngarkesës së lartë, krijohet tabela e tij + përveç kësaj, krijohet një tabelë tjetër për të ruajtur vlera të shumta. Ata e quajtën qasjen e zakonshme për të krijuar një tabelë të rregullt në një bazë të dhënash një emër krenar ngarkesë e lartë thjesht sepse ngadalëson më pak se blloqet e zakonshme të informacionit!
    Përveç kësaj, brenda modulit, në mënyrë që ai të funksionojë sipas D7, klaset e entitetit gjenerohen në mënyrë dinamike dhe vlerësohen në çdo goditje.

    Shiko kete

    Funksioni statik publik compileEntity($hlblock) ( global $USER_FIELD_MANAGER; // gjeneron entitetin dhe menaxherin e të dhënave $fieldsMap = array(); // shto ID $fieldsMap["ID"] = grup ("tipi_i i të dhënave" => "numër i plotë", "primary" => e vërtetë, "autokomplete" => e vërtetë); // ndërto klasën e menaxherit të të dhënave $entity_name = $hlblock["NAME"]; $entity_data_class = $hlblock["NAME"]; nëse (!preg_match("/^ +$/i", $entity_data_class)) ( hidhni MainSystemException të ri(sprintf("Emri i pavlefshëm i entitetit `%s`.", $entity_data_class)); ) $entity_data_class .= "Tabela"; nëse (class_exists($sentity_data_s)) ( // rindërtoni nëse tashmë ekziston EntityBase::destroy($entity_data_class); ) else ( $entity_table_name = $hlblock["TABLE_NAME"]; // bëni me një hartë boshe $eval = " class ".$entity_data_class. " shtrihet ".__NAMESPACE__."DataManager ( funksioni statik publik getTableName() ( return ".var_export($entity_table_name, true)."; ) funksioni statik publik getMap() ( return ".var_export($fieldsMap, true)."; ) funksioni statik publik getHighloadBlock() ( return ".var_export($hlblock, true)."; ) ) "; eval($eval); ) // pastaj konfiguroni dhe bashkëngjitni fushat /** @var BitrixMainEntityDataManager $entity_data_class */ $entity = $entity_data_class::getEntity(); $uFields = $USER_FIELD_serFUCKFields(Get) ".$hlblock["ID"]); foreach ($uFields si $uField) ( if ($uField["MULTIPLE"] == "N") ( // thjesht shtoni një fushë të vetme $field = $USER_FIELD_MANAGER->getEntityField ($uField, $uField["FIELD_NAME"]); $entity->addField($field); foreach ($USER_FIELD_MANAGER->getEntityReferences($uField, $field) si $reference) ( $entity->addField($reference ); ) ) else ( // ndërto entitetin utm statik::compileUtmEntity($entity, $uField); ) ) kthen EntityBase::getInstance($entity_name);

    Për dreqin, por të njëjtat blloqe me ngarkesë të lartë nuk mund të veprojnë në asnjë mënyrë si një alternativë ndaj blloqeve të zakonshme të informacionit. Rezulton se ato janë shpikur vetëm për të ruajtur të dhënat e referencës johierarkike. Për më tepër, moduli ende nuk mbështet funksione të tilla të nevojshme në panelin e administratorit, siç është filtrimi nga një fushë si "Data"; është e pamundur të thërrasësh entitetin HLblock me ndonjë emër të kuptueshëm nga njeriu, në mënyrë që administratori të mos frikësohet. çdo herë kur hyni në faqen e redaktimit të entitetit, për shembull, BrandReference. E gjithë kjo sugjeron që kjo gjë ishte konceptuar si një alternativë ndaj blloqeve të ngadalta të informacionit, por ata nuk patën kohë ta përfundonin atë (ose nuk e menaxhuan, ose shkuan kundër interesave të biznesit), dhe në fund ata lëshuan funksionaliteti gjysëm i përfunduar si një veçori e re, dhe tregtarët e krehën atë dhe e bënë të dukej bukur erdhi me këtë ide.

    C - Kontrolluesi, ose komponenti

    Një komponent i rregullt në Bitrix mund të krahasohet me miniaplikacionet nga Yii. Ky është një kontejner i caktuar, i ndarë nga të gjithë kontejnerët e tjerë, i cili merr disa parametra si hyrje, bën disa punë dhe me rezultatin e punës lidh pamjen. Zhvilluesit e Bitrix janë thellësisht të bindur se komponentët që ata ofrojnë jashtë kutisë zgjidhin shumicën e problemeve me të cilat përballen kolegët e tyre. Por, si zakonisht, zhvilluesve gjithmonë nuk u pëlqen asgjë, dhe aftësitë e komponentëve standardë mungojnë gjithmonë "pak". Prandaj, Bitrixoids vendosi t'u japë zhvilluesve mundësinë për të modifikuar rezultatin e një komponenti ... duke përdorur një pamje. Në drejtorinë e shabllonit të komponentit, mund të krijoni një skedar result_modifier.php, në të cilin mund të shtoni të dhënat tuaja në rezultatin e komponentit. Dhe nëse papritmas dëshironi t'i përdorni këto të dhëna në një shabllon tjetër, do t'ju duhet të kopjoni dhe ngjisni këtë skedar (ose ta përfshini këtë skedar nga një shabllon tjetër). Gjithmonë më ka munduar pyetja - për çfarë shërben ky patos? Pse të mos shtoni një mori kërkesash direkt në shabllonin PHP? Dallimi rezulton të jetë i vogël.
    Për çfarë po flas për shabllonet në seksionin mbi kontrollorët...

    Bitrix ka 2 lloje të komponentëve 2.0 (përshëndetje përsëri marketing) - të rregullt dhe kompleks. Një komponent i zakonshëm është një widget. Një komponent kompleks është një lloj kontrolluesi + ruteri, i cili, bazuar në URL-në, kupton se cila faqe me një grup miniaplikacionesh duhet të shfaqet. Procedura e funksionimit është afërsisht kjo:

    • url thotë /catalog/bolshaya-zelenaya-shapka.html
    • duke përdorur mod_rewrite, Bitrix kupton se për seksionin fizik /katalog duhet të përfshini gjithmonë skedarin /catalog/index.php
    • komponenti kompleks analizon URL-në dhe kupton që ju duhet të lidhni një faqe produkti të detajuar, le ta quajmë atë detaj
    • një komponent kompleks mbledh parametrat që janë të nevojshëm për funksionimin e komponentëve të tij të vegjël
    • një komponent kompleks lidh shabllonin e tij detail.php, brenda të cilit specifikohet lidhja e komponentëve të rregullt të fëmijëve

    Nuk duket shumë bukur, por mund të funksionojë. Megjithatë, jo gjithçka është kaq e thjeshtë... Nëse ndryshoni parametrat e një komponenti kompleks duke përdorur një redaktues vizual, skedari me cilësimet e adresimit (urlrewrite.php) do të mbishkruhet nga sistemi. Për më tepër, nëse papritmas keni shkruar diçka gabim atje për faqet e tjera, diçka patjetër do të prishet pa asnjë paralajmërim. Në praktikë, kjo mund të çojë në humbjen e funksionalitetit të seksioneve të tëra të faqes.
    Vendosja e parametrave të një komponenti kompleks mund të jetë një punë e përditshme. Një komponent i tillë mund të ketë lehtësisht qindra parametra hyrës, thjesht sepse është i nevojshëm konfigurimi i parametrave të komponentëve fëmijë.
    Një komponent kompleks - duket se është një ruter. Megjithatë, të gjitha rrugët që krijoni në këtë komponent nuk do të përfshihen në sitemap.xml i krijuar automatikisht. Këto lidhje nuk do të përfshihen në modulin e kërkimit. Nuk do të keni asnjë mënyrë për të gjeneruar adresën e itinerarit nga jashtë (për shembull, dëshironi të vendosni një lidhje në faqen e detajuar të një marke diku në shiritin anësor dhe nuk do të jeni në gjendje t'i kërkoni ruterit të gjenerojë këtë URL ).

    Në përgjithësi, askush nuk kryen me të vërtetë funksionet e një ruteri në Bitrix. Në infoblocks, mund të konfiguroni shabllonin e URL-së për faqen e infoblock, faqen e seksionit infoblock dhe faqen e elementit infoblock. Kjo është e gjitha, infoblocks nuk mund të kenë më faqe.
    Për forume, është e mundur të personalizohen shabllonet e disa faqeve. Mund të personalizohet për blogje. Ndoshta diçka mund të konfigurohet diku tjetër... e gjithë kjo është aq e decentralizuar sa bëhet mjaft e vështirë t'i bashkosh të gjitha.

    Komponentët e rregullt janë entitete pak më të thjeshta se përbërësit kompleksë. Detyra e tyre është të marrin një grup parametrash si hyrje, t'i përpunojnë ato, të ushqejnë rezultatin e punës në shabllon dhe të ruajnë çdo gjë.
    E gjithë logjika e komponentit gjendet në skedarin komponent.php. Me versionin 12 të Bitrix (aktualisht versioni 16 është aktual, kanë kaluar 4 vjet), u bë e mundur "përdorimi i OOP" në komponentë. Kjo risi është se në vend të një skedari component.php, mund të krijoni një skedar class.php, në të cilin, në vend të noodles të zakonshme, mund të shkruani një klasë të trashëguar nga CBitrixComponent. Dhe ky ishte një hap i madh përpara, sepse... u bë e mundur të trashëgosh komponentë dhe të mos përdorësh fare result_modifier.php dhe të mos praktikosh copy-paste nëse papritmas duhet të personalizosh shumë komponentin. Por edhe këtu gjithçka nuk është ende aq mirë. Nga i gjithë grupi i komponentëve, vetëm 25-30 përqind mund të mburren se kanë një klasë në arsenalin e tyre. Për më tepër, një gjysmë e mirë e tyre thjesht nuk do t'ju japë mundësinë të zgjeroheni plotësisht, sepse... Ato shpesh shkruhen në mënyrë të palogjikshme.
    Nga rruga, njerëzit e mirë po përpiqen të standardizohen, disi të ndihmojnë zhvilluesit të shkruajnë komponentë dhe ekziston një paketë mjetesh përkatëse

    V - Pamje, ose shabllone

    Modelet në Bitrix mund të ndahen në disa lloje:

    • Modele të rregullta dhe komplekse të komponentëve 2.0
    • Modelet e faqeve të internetit
    • Modele për entitete të tjera (postimet, buletinet, formularët e internetit, gjeneruesit e eksportit dhe shumë më tepër)

    Modelet e komponentëve madje kanë aftësinë të përdorin motorë shabllonesh. Në parim, ju mund të lidhni çdo motor shabllon, por nuk ka mjete ndihmëse jashtë kutisë. Nëse dikush ka nevojë për të, unë kam nja dy lidhje me shtesa për degëz dhe teh, të cilat funksionojnë dhe përdoren mjaft në prodhim. Por edhe këtu Bitrixoidët janë çoroditur. Motori i shabllonit mund të përdoret vetëm me komponentë. Nuk do të jetë e mundur të lidhni motorin e shabllonit me interpretuesin e shablloneve të faqes në internet ose entitete të tjera, sepse atje nuk ka renderer.

    Një tjetër gjë e bezdisshme në lidhje me shabllonet e komponentëve është vendosja e tyre. Komponenti është i lidhur duke përdorur një dizajn të thjeshtë

    $APPLICATION->IncludeComponent("bitrix:catalog.section", "emri_template", );

    Parametri i dytë është emri i shabllonit të komponentit. Pra, në varësi të kushteve të ndryshme, vendndodhja e këtij shablloni mund të jetë në vendet më të papritura:

    • bitrix/components/bitrix/catalog.section/templates/template_name
    • local/components/bitrix/catalog.section/templates/template_name
    • bitrix/templates/.default/components/bitrix/catalog.section/template_name
    • bitrix/templates/site_template/components/bitrix/catalog.section/template_name
    • local/templates/.default/components/bitrix/catalog.section/template_name
    • local/templates/site_template/components/bitrix/catalog.section/template_name
    • bitrix/components/bitrix/catalog/templates/.default/bitrix/catalog.section/template_name
    • local/templates/site_template/components/bitrix/catalog/.default/bitrix/catalog.section/template_name

    Dhe nuk i kam renditur ende të gjitha opsionet...

    Një shabllon i faqes mund të konsiderohet si një grup skedarësh: header.php, footer.php (po, faqja duhet t'i ketë ato), description.php (përshkrimi i sistemit të shabllonit të faqes), template_styles.css (stilet e shablloneve të faqes), direktorium me shabllone komponentësh dhe një grup tjetër skedarësh më pak të rëndësishëm. Kjo eshte e gjitha. Dhe nuk mund të ndikoni në asnjë mënyrë, nuk mund të bëni asgjë për të. Është e pamundur të kapësh motorin e shabllonit.

    Nuk ka asgjë për të thënë për shabllonet e tjera. Ato ose thjesht ruhen në bazën e të dhënave në formën e një paraqitjeje me disa të dhëna "të ndryshueshme" të përfshira në të, ose është një skedar budalla PHP që bën të gjithë punën, nga marrja e parametrave nga baza e të dhënave deri tek shfaqja e informacionit. Për shembull, mund të shikoni gjeneratorin e skedarëve YML për treg. Nuk ka kuptim ta postosh këtu, thjesht sepse është mjaft i madh, rreth 2 mijë rreshta. Kushdo që ka nevojë mund ta kërkojë në google, është në /bitrix/modules/catalog/load/yandex_run.php

    Natyra e skedarit

    Siç u bë e qartë më lart, në Bitrix arkitektura nuk është shumë e mirë. Por Bitrix ka gjithashtu një aspekt tjetër të rëndësishëm të arkitekturës së tij.
    Bitrix është një gjysmë skedar CMS. Shumë gjëra kontrollohen duke përdorur disa skedarë:

    • Keni nevojë për një faqe - krijoni një skedar
    • Ju duhet një grup faqesh - krijoni një skedar dhe lidhni atje një komponent që funksionon me infoblocks
    • Ju duhet të vendosni një titull për faqen - modifikoni skedarin
    • Ju duhet të vendosni një titull për të gjitha faqet e një seksioni - krijoni një skedar të veçantë file.section.php në rrënjën e këtij seksioni
    • Ju duhet të redaktoni të drejtat - modifikoni skedarin .access.php
    • Cilësimet para fillimit të sistemit - në skedarin dbconn.php, .settings.php dhe .settings_extra.php
    • result_modifier.php, komponent_epilog.php, init.php, .parameters.php, .description.php ....

    Dhe ka një numër të madh skedarësh të tillë specialë të shpërndarë në të gjithë Bitrix. Nga njëra anë, kjo jep një fleksibilitet të caktuar kur punoni me sistemin. Nga ana tjetër, kjo mund të kthehet në mundim si për zhvilluesin ashtu edhe për menaxherin e faqes. Skedarët e faqeve ndonjëherë shndërrohen në një rrëmujë të kodit PHP, paraqitjes dhe komponentëve shtesë. Si rezultat, redaktori vizual mund ta analizojë gabim këtë skedar dhe gjatë redaktimit mund t'i shpëtojë lehtësisht etiketave PHP në disa vende, gjë që do të bëjë që faqja të mos funksionojë. Ju thoni - nuk ka nevojë të shkruani kodin PHP në skedarë të tillë? Po, e di. Por Bitrix shumë shpesh dhe pa alternativë ju detyron ta bëni këtë.
    Dhe ju duhet të mbani vazhdimisht informacion në kokën tuaj se çfarë lloj skedarësh janë dhe çfarë të dhënash mund të përmbajnë. Skedarët e ndryshëm duhet të përmbajnë të dhëna të ndryshme me struktura të ndryshme, dhe ju duhet t'i mbani mend ato për secilin opsion. Të kërkosh këtë në dokumentacion çdo herë është punë e vështirë.

    Përveç sa më sipër

    Mund të ankoheni pafundësisht se sa keq funksionon gjithçka në Bitrix. Sipas mendimit tim, të gjitha këto ankesa mund të karakterizohen nga një frazë - "disi jo plotësisht". Dhe me të vërtetë, nëse Bitrixoids papritmas shpallin një lloj veçorie, atëherë ata disi nuk e lëshojnë atë plotësisht, nuk e përfundojnë atë, nuk e sjellin në mendje. Ka plot shembuj:

    • ORM i implementuar - nuk ka përfunduar ende, nuk mund të përdoret plotësisht
    • Ne bëmë një autoloader, funksionon vetëm në module, dhe jo sipas standardeve
    • bëri të mundur lidhjen e një motori shabllon, por nuk mund ta përdorni kudo, dhe jo plotësisht
    • etj. e kështu me radhë.

    Me pak fjalë, do të përpiqem të karakterizoj problemet e mbetura me të cilat duhet të përballem çdo ditë.

    Admin

    Nëse dikush ka punuar me panelin e administratorit, ka krijuar faqet e tij në pjesën administrative ashtu siç sugjeron Bitrix, ai do të më kuptojë. Është vetëm ferr. Për ata që nuk janë në dijeni, Bitrix sugjeron përdorimin e një skedari noodle për çdo faqe. Për shembull, faqja për një pamje të detajuar të një porosie në panelin e administratorit të bërë nga zhvilluesit e Bitrix merr mbi 4k linja. IDE ime fillon të ngadalësohet kur shikon përmbajtjen e këtij skedari. Aty keni php, js dhe html. Është mirë që ata hoqën qafe SQL, megjithëse jam i sigurt se është në faqe të tjera administrative.
    Dhe çfarë i pengoi faqet administrative të funksiononin duke përdorur të njëjtat komponentë nuk është e qartë. Thjesht nuk ka asnjë mënyrë për të personalizuar shumicën e faqeve administrative. Në rastin e komponentëve, kjo mund të bëhet në asnjë kohë.
    Meqë ra fjala, njerëzit e mirë kanë bërë një modul që do t'ju ndihmojë të ndërtoni faqe administrative

    js kornizë

    Bitrix ka një komponent js që vepron si një lloj kornize klienti. Asnjë nga zhvilluesit nuk e pëlqen atë për disa arsye:

    • pothuajse nuk është e dokumentuar
    • ai është monstruoz
    • ai kopjon kryesisht jquery-n e njohur për shumë njerëz

    Bitrix shumë shpesh e përdor atë në përbërësit e tij, duke shkaktuar kështu edhe më shumë zemërim midis zhvilluesve. Bërthama e kësaj biblioteke në formë të minifikuar është 85 kb, që nuk është e vogël. Nuk mund ta shmangni lidhjen e tij nëse dëshironi të përdorni të gjitha aftësitë e Bitrix (përbërë, menaxhim i aseteve).

    Spirit copy-paste

    Kohët e fundit, gjithnjë e më rrallë, por ende mjaft shpesh, Bitrix ju detyron të kopjoni-paste diçka. Nëse dëshironi të modifikoni funksionimin e një komponenti, kopjoni dhe ngjisni atë. Nëse dëshironi të krijoni shabllonin tuaj të ngarkimit, kopjoni dhe ngjisni atë të sistemit dhe përfundoni atë. Nëse dëshironi të bëni pothuajse të njëjtin shabllon që keni, kopjoni dhe ngjisni dhe ndryshoni pak. Dhe ata madje flasin për këtë në kurse për zhvilluesit fillestarë. Nuk kam fjale.

    Menaxhimi i aseteve dhe CDN

    Më pëlqen shumë mënyra se si Bitrix menaxhon burimet. Në parim, është e mundur të regjistrohet një grup "bibliotekash" specifike. Çdo bibliotekë është një grup skedarësh css/js, të cilat mund të varen nga disa biblioteka të tjera. Nëse lidhni një bibliotekë me një faqe, atëherë përpara se ta lidhni atë, të gjitha varësitë do të zgjidhen dhe të gjitha bibliotekat e varura do të futen në faqe. Gjithçka duket se është në rregull, vetëm çdo burim do të futet si një skedar i veçantë në skriptin ose etiketën e lidhjes. Dhe falë kësaj, ka sajte që kanë 30-50 skripta dhe të njëjtin numër skedarësh stili të lidhur.
    Është një pyetje e ndyrë, thanë ata në Bitrix, dhe bënë një shenjë magjike që i kombinon të gjithë këta skedarë në një. Dhe u shfaqën faqe ku në vend të 50 skripteve kishte 2, secili 300-500 kb. Kohë më parë, ky bashkim funksionoi me gabime dhe shkriu disa herë të njëjtat burime, por tani duket se është rregulluar.
    Dhe më pas Bitrixoids u larguan nga rruga e tyre - ata shtuan aftësinë për të ngarkuar të gjitha burimet në një server CDN. Që bie gjithmonë...
    Më pas u shfaq Google Pagespeed Insights, i cili rekomandoi zhvendosjen e të gjitha burimeve në fund të faqes. Dhe në Bitrix ata përsëri bënë një kuti kontrolli magjike që në mënyrë budallaqe lë të gjitha burimet në trup nëse ato nuk janë të shënuara me një atribut të veçantë.
    Ata gjithashtu shpërndajnë versione të minuara të skripteve të tyre së bashku me kutinë, të cilat lidhen kur përdorni një kuti tjetër magjike në panelin e administratorit.
    Në përgjithësi, nuk ka scss për ju, pa TypeScript. Nëse dëshironi të menaxhoni burimet me kompetencë, mos përdorni sistemin e integruar Bitrix, përdorni paketën e internetit, e cila mund të çiftohet lehtësisht me Bitrix.

    Multi-site/shumëgjuhësh

    Kjo është ndoshta dhimbja më e keqe e kokës për një zhvillues, e cila ka vazhduar që nga fillimi i produktit. Ju nuk mund të vazhdoni dhe të krijoni një faqe interneti shumëgjuhëshe. Dhe nëse keni nevojë për një katalog shumëgjuhësh me çmime dhe monedha të ndryshme, atëherë ky shndërrohet në miell, për të cilin gjithashtu duhet të paguani një shumë të rregullt (do të duhet të paguani për blerjen e një licence shtesë për versionin tjetër gjuhësor të faqe).
    Nëse po krijoni një faqe interneti shumëgjuhëshe dhe me shumë monedha, atëherë përgatituni për faktin se Bitrix do t'i rezistojë shumë agresivisht kësaj. Cilësimet e shumë faqeve janë të decentralizuara në të gjithë panelin e administratorit. Çdo entitet në panelin e administratorit ka varësinë e tij nga versioni gjuhësor i faqes. Disa entitete mund të mos mbështesin fare varësitë e sajtit/gjuhës, ndërsa të tjerat kanë vetëm një lidhje të paqartë me gjuhën, kështu që ky ent duhet të dublikohet dhe më pas të mbështetet.
    Në versionin bazë, për të funksionuar një bllok informacioni në disa gjuhë, do t'ju duhet të krijoni një dublikatë të këtij blloku informacioni. Por në praktikë, askush nuk e bën këtë dhe përpiqet të gjejë mënyrat e veta për ruajtjen e një entiteti në qendër, duke shpërndarë atributet e tij të varura nga gjuha në objektet e tjera të ruajtjes.
    Nuk mund të vendosni gjuhën e paracaktuar gjatë lokalizimit. Nëse keni një variabël gjuhësor që përshkruan një frazë në rusisht dhe kjo variabël gjuhësore nuk është në versionin anglisht, atëherë në faqen angleze do të shfaqet një rresht bosh dhe kjo nuk mund të ndikohet në asnjë mënyrë (në shumë raste mund të lini frazën ruse në mënyrë që të mos ketë zbrazëti).

    Mekanizmi i Menaxhimit të të Drejtave

    Ata ishin shumë të zgjuar me këtë nënsistem. Shpesh është e vështirë të kuptosh pse i ke dhënë të drejta shikimi një entiteti, por përdoruesi nuk mund t'i përdorë ato. Për shembull, për të dhënë të drejtën për të redaktuar një bllok informacioni, duhet të jepni akses në drejtorinë /bitrix/admin, të jepni të drejta për një bllok specifik informacioni dhe të jepni të drejta në modulin kryesor. Duhet të bëhen shumë operacione për të lëshuar të drejta për një entitet. Dhe nëse nuk ka të drejta të mjaftueshme, atëherë pa u futur në kodin burimor nuk ka asnjë mënyrë për të kuptuar pse.

    Konfigurimi

    Bitrix nuk ka një qendër të centralizuar që do t'ju lejojë të menaxhoni cilësimet e sistemit. Cilësimet janë përsëri të decentralizuara në të gjithë sistemin. Opsionet janë të disponueshme në cilësimet e modulit, në cilësimet e komponentëve, në COption (nuk vendosen në panelin e administratorit). Në panelin e administratorit, opsionet për një modul mund të shpërndahen në 3-4 faqe të ndryshme, të cilat ndodhen në vende krejtësisht të ndryshme. urlrewrite mund të modifikohet përmes panelit të administratorit! Tani edhe .settings dhe .settings_extra. Ndonjëherë nuk është aspak e qartë se cilat prej tyre kanë përparësi më të lartë, shumë shpesh nuk ka shpjegime të mjaftueshme për opsionet dhe marrëdhëniet janë të paqarta. Nuk ka asnjë mënyrë origjinale për të ndarë konfigurimin midis zhvilluesve.
    Cilësimet mund të jenë shumë të palogjikshme. Ndonjëherë arrin deri në pikën e absurdit... shiko komponentin bigdata - a mund ta vendosë një person i patrajnuar?

    Integrimi me 1C

    Ky është artikulli në listën e veçorive të Bitrix për të cilin bien një numër mjaft i madh klientësh. Bitrix premton të vendosë integrimin e dyanshëm të faqes me 1C në 2 klikime, i cili do të dërgojë menjëherë përmbajtjen dhe dokumentet nga një sistem në tjetrin.
    Po, me të vërtetë është, por me disa paralajmërime.
    Së pari, për të bërë integrimin "jashtë kutisë" pa përpjekje shtesë, duhet të bëni gjithçka saktësisht siç është shkruar në dokumentacionin e Bitrix - të ndërtoni një katalog në sit sipas rregullave që ofron Bitrix dhe të ndërtoni katalogun në 1C. që kërkon Bitrix. Idealisht, krijoni gjithçka nga e para, dhe pastaj mbase gjithçka do të funksionojë për ju jashtë kutisë.
    Së dyti, Bitrix nuk është i pajtueshëm me të gjitha konfigurimet 1C jashtë kutisë. Ia vlen të kontrolloni së pari
    Së treti, nuk ka botë ideale. Në mënyrë tipike, një klient që dëshiron një faqe interneti tashmë ka një biznes me pakicë, që do të thotë se ata tashmë kanë 1C, që është një deponi e madhe plehrash. Dhe këto plehra duhet të hidhen në vend. Dhe në mënyrë që faqja të mos rezultojë të jetë e njëjta plehra, mekanizmi i shkëmbimit duhet të përmirësohet ndjeshëm.
    Shumë shpesh, kërkesat e klientit ndryshojnë shumë nga vizioni i produktit që ka formuar ekipi i Bitrix, dhe më pas rafinimi i mekanizmit të shkëmbimit mund të jetë mjaft i shtrenjtë, i krahasueshëm në intensitetin e punës me zhvillimin e një moduli unik shkëmbimi për një rast specifik.
    Prandaj, nuk ka nevojë të keni asnjë iluzion se do të jeni në gjendje të integroni lehtësisht faqen tuaj me 1C. Këto janë të gjitha makinacionet e marketerëve.

    Rafinimi i shkëmbimit me 1C është gjithashtu një temë më vete. Klasa CIBlockCMLImport është përgjegjëse për organizimin e shkëmbimit të katalogut - 5.7k linja. Një nga metodat kryesore që më së shpeshti kërkon zgjerim është CIBlockCMLImport::ImportElement, i cili përmban më shumë se 1k rreshta. Mjafton ta trashëgoni një herë, ta përditësoni produktin disa herë gjatë një periudhe të gjatë kohore dhe mund të merrni një shkëmbim jo funksional me 1C. Prandaj, zhvilluesit shpesh nuk shqetësohen me këtë klasë dhe përpiqen të futen disi në procesin e importimit duke përdorur mbajtësit e ngjarjeve. Puna me mbajtësit e ngjarjeve në Bitrix, veçanërisht në modulin e infoblocks, nuk është gjithashtu një përvojë shumë e këndshme, vetëm sepse ngjarjet e të njëjtit lloj nuk janë rregulluar në mënyrë uniforme dhe disa ngjarje thjesht nuk janë të mjaftueshme.
    Në përgjithësi, gjërat janë të trishta si më parë.

    Mospërputhje

    Ndonjëherë më duket se zhvilluesit e moduleve të ndryshme nuk komunikojnë vërtet me njëri-tjetrin. Kur studioni burimet e kernelit, hasni në zgjidhje shumë heterogjene që mund të zbatohen në një motor, por për disa arsye ato zbatohen ndryshe.
    Për shembull, mund të merrni vetitë e elementeve të bllokut të informacionit dhe Fushat e Përdoruesit. Të dy entitetet janë në fakt një fushë shtesë për një entitet tjetër. Ai ka një lloj, një kuptim dhe një përshkrim. Vlera ruhet në një tabelë(ta) të veçanta të bazës së të dhënave; ato kanë një ndërfaqe afërsisht të ngjashme të aksesit të të dhënave. Pra, pse të mos krijoni të njëjtën ndërfaqe për ta?
    Në fund të marsit, moduli i shitjes u përditësua në versionin më të fundit, dhe ata gjithashtu premtuan prona arbitrare për porosi. A ka vërtet një ndërfaqe të re, të tretë për të punuar me vetitë e zgjeruara të entitetit?

    Bitrix24

    Kjo është përgjithësisht një temë e veçantë për diskutim. Konfuzioni shpesh lind për shkak të këtij sistemi. Ekzistojnë 2 opsione për B24 - SaaS dhe Standlone. Ekziston një treg për B24, por ai përmban aplikacione vetëm për versionin SaaS! Nëse keni një version në kuti, të blerë për 200 euro, nuk do të mund të instaloni aplikacione të tilla të njohura si projektuesi i dokumenteve dhe në përgjithësi nuk do të mund të instaloni asnjë aplikacion nga tregu për Bitrix24 në Bitrix24. Ky është një paradoks i tillë.
    Në vend të kësaj, tregu nga versioni i rregullt do të jetë i disponueshëm në Bitrix24 tuaj. Ka shumë më tepër zgjidhje atje, por ato janë të përqendruara kryesisht rreth Menaxhimit të Sitit, dhe jo B24.

    Bitrix24, siç më thanë në departamentin e mbështetjes teknike, është një sistem holistik. Nëse ndërhyni në funksionimin e komponentëve standardë të sistemit, atëherë përgatituni që ky funksionalitet të prishet me përditësimet e mëvonshme. Bitrix nuk do të llogarisë tek ju për të finalizuar komponentët e portalit, dhe kjo pavarësisht nga fakti se ata zyrtarisht i referojnë klientët e tyre te partnerët

    Nga rruga, modifikimi i përbërësve në versionin në kuti të B24 është mjaft detyrë. Komponentët që gjenerojnë kodin js, i cili, duke përdorur ajax, akseson kodin php, i cili gjeneron html+js në përgjigje. Kjo është një përzierje djallëzore në të cilën vërtet nuk dëshironi të zhyteni.

    Dokumentacioni

    Dokumentacioni Bitrix mbetet prapa zhvillimit të produktit me 1-1,5 vjet. Kodi mbulohet shumë dobët nga phpDocs, dhe shpesh komenti përpara klasës është vetëm për t'u treguar, duke u krijuar automatikisht në IDE.
    Vetë stili i paraqitjes së dokumentacionit në burimet zyrtare është shpesh shumë "falas", dhe përmbajtja e disa artikujve në dokumentacion mund të mos ketë asnjë lidhje me vetë Bitrix.
    Kursi i zhvilluesit ka shumë informacion, por formati në të cilin zhvilluesi njihet me aftësitë e sistemit nuk siguron nivelin e perceptimit që kërkohet. Nëse shkoni te libri i gatimit Symfony, gjithçka është paraqitur atje, të gjitha aspektet e nevojshme përshkruhen në varësi të versionit. Ndërsa në Bitrix, kursi i trajnimit të zhvilluesve përmban, në mënyrë të paqartë, informacion të strukturuar mbi kernelin e vjetër dhe të ri, i cili paraqitet fillimisht veçmas dhe më pas i përzier, gjë që u jep fillestarëve një dhimbje koke.

    Organizimi i procesit të zhvillimit

    Për shkak të specifikës së sistemit, nuk është aq e lehtë të organizosh një proces të përshtatshëm zhvillimi. Jo versioni më i fundit i edicionit Business (i cili ishte në dispozicion) pasi instalimi të fillojë, mendoni për të, pothuajse 530 megabajt

    $ du -s *|rendi -nr|prerë -f 2-|ndërsa lexoni a;bëni du -hs $a;mbaroni 523M bitrix 204K ngarkoni 64K bitrixsetup.php 56K desktop_app 20K readme.html 20K licencë.html 4.0K ueb . konfigurim 4.0K urlrewrite.php 4.0K readme.php 4.0K licencë.php 4.0K install.config 4.0K index.php

    Nga ky vëllim, gjysma e mirë janë binare dhe instalues, të cilët në përgjithësi nuk nevojiten për kontrollin e versionit. Në përgjithësi, është zakon të mos versiononi thelbin Bitrix. Vetë zhvilluesit e Bitrix garantojnë integritetin e bërthamës dhe menaxhojnë varësitë e versioneve të moduleve të ndryshme gjatë përditësimeve. Por kjo mbart menjëherë të paktën një disavantazh të madh - është e pamundur të vendosësh një projekt plotësisht funksional me një ekip nga kontrolli i versionit; duhet ta grumbullosh atë në pjesë: të marrësh burimet e kernelit nga rezervimi i Bitrix dhe burimet e zhvilluesve nga git .
    Gjërat nuk shkojnë mirë as me bazën. Nëse ju vetë mund të përdorni migrimet gjatë zhvillimit, atëherë Bitrix hedh përditësime në bazën e të dhënave duke përdorur skriptet e zakonshme që nuk mund t'i kontrolloni. Prandaj, kur përditësoni, do t'ju duhet ende të transferoni kopje rezervë të bazës së të dhënave nga hosti qendror i zhvillimit te zhvilluesit e tjerë.
    Njerëzit e mirë, përsëri, po presin mjete që ndihmojnë në organizimin e gjithë kësaj, por fatkeqësisht ende nuk është e mundur të detyrosh Bitrix të ndjekë këto rregulla.
    Zyrtarisht, Bitrix ju lejon të keni 2 kopje të një shpërndarjeje. Njëra është për prodhim, e dyta është për zhvillim. Nëse keni disa zhvillues në një projekt, atëherë ju jeni, si të thuash, një i jashtëligjshëm) Në fakt, mjafton të ndërpritni makinën me Bitrix lidhjet hyrëse dhe dalëse nga/në www.bitrixsoft.com, dhe më pas ju mund të mbledhin sa më shumë kopje të zhvillimit që dëshironi, Ata thjesht nuk do të jenë në gjendje të përditësojnë veten e tyre.

    Kolegë

    Dhe pyetja e fundit që do të doja të prekja.
    Për faktin se Bitrix ka një pengesë të ulët për hyrjen, ka shumë personel të pakualifikuar në mesin e kompanive që ofrojnë shërbime në këtë treg. Kam parë shumë projekte të ndryshme gjatë karrierës sime (më shumë se njëqind në total) të përfunduara në 1C-Bitrix. Mund të them me bindje se 95% e tyre janë bërë në mënyrë “bugger”. Shumë rrallë kemi hasur në projekte zhvillimi i të cilave kishte një sens qasjeje, por këto ishin vetëm disa. E gjithë kjo është shumë e trishtueshme.

    konkluzionet

    Sigurisht, të gjitha disavantazhet nuk mund të merren parasysh në një artikull. Çdo ditë hasni në disa gjëra të vogla që ju pengojnë në punën tuaj çdo ditë. Por është thjesht e pamundur të merren parasysh të gjitha këto gjëra të vogla, dhe ndoshta nuk ka nevojë.

    Çfarë përfundimesh mund të nxirren këtu? Bitrix është një sistem jashtëzakonisht kompleks për faktin se ka një arkitekturë të konceptuar keq dhe shumë të meta që vazhdojnë të jetojnë në produkt për një kohë të gjatë. Nga ana tjetër, Bitrix është një sistem mjaft i thjeshtë që kërkon një nivel shumë më të ulët të kualifikimeve për të filluar, ndryshe nga kornizat.
    Mbështetja e këtij produkti është një detyrë shumë e pafalshme në krahasim me produkte të tilla si Symfony, Laravel, Yii. Produktit me të vërtetë i pëlqen të vendosë një fole në rrotat e zhvilluesve të papërvojë dhe me përvojë, gjë që, nga ana tjetër, mund të reflektohet në koston e shërbimeve të zhvilluesve me përvojë të Bitrix.

    A më vjen keq që kam kaluar kaq shumë kohë duke punuar me këtë sistem? Në vend që po se jo. Do të ishte më e mençur ta kalonim këtë kohë duke studiuar diçka më korrekte dhe më logjike (të cilën po përpiqem ta bëj në mënyrë aktive tani). Por ndodhi që nuk kishte njeri që të më udhëzonte në drejtimin e duhur në fillim të udhëtimit tim.

    Nëse jeni një zhvillues fillestar PHP, atëherë do të preferoni të studioni korniza të tilla si Symfony, Laravel, Yii, ZendFramework mbi Bitrix. Më besoni, do të shpërblehet më shumë në të ardhmen. Pasi të keni zotëruar ndonjë nga këto korniza, nuk do të jetë e vështirë për ju të zhvilloni diçka për Bitrix në të ardhmen. Nëse nuk keni zgjidhje, atëherë studioni Bitrix, por në kohën tuaj të lirë është më mirë të përpiqeni ende të zhyteni në botën e kornizave për të vendosur trurin tuaj në vend.

    Nëse jeni një zhvillues me përvojë në Bitrix, por pa përvojë në korniza të tjera, atëherë sigurohuni që të zhyteni në një botë tjetër; do të zbuloni shumë njohuri të reja dhe të dobishme që do t'ju ndihmojnë të shkruani zgjidhje shumë më të mira për 1C-Bitrix. Përpiquni të përdorni zgjidhje nga korniza të tjera në projektet tuaja, për fat të mirë kjo nuk është e vështirë për t'u bërë falë qasjes përbërëse të këtij të fundit dhe kompozitorit.

    Nëse jeni klient, atëherë mos u besoni tregtarëve të Bitrix. Asgjë nuk do të jetë aq e lehtë sa thonë në prezantimet e Bitrix. Dhe mos i fajësoni zhvilluesit tuaj për këtë, ata nuk kanë asnjë lidhje me të. Nëse dëshironi të krijoni një dyqan online të madh dhe kompleks në nivelin Eldorado/Mvideo/Sportmaster, atëherë Bitrix mund të mos jetë zgjidhja më e mirë.

    Shpesh gjatë zhvillimit është e nevojshme të zgjidhni dhe fshini disa pjesë të të dhënave të shënuara për fshirje. Kjo nevojë prek veçanërisht bazat e të dhënave të mëdha të informacionit me dhjetëra ose qindra mijëra objekte të shënuara për fshirje. Përpunimi i të gjitha të dhënave menjëherë kërkon një kohë shumë të gjatë, kështu që pa një mjet të dobishëm në të cilin mund të shikoni, zgjidhni dhe fshini qartë një pjesë të të dhënave, është e pamundur.

    Ky përpunim është rezultat i punës sime në një periudhë të caktuar kohore. Funksionaliteti u zgjerua sipas nevojës. Përpunimi funksionon në modalitetin e rregullt të aplikimit dhe në klientin e trashë të një aplikacioni të menaxhuar. Zbatuar në përpunim:

    • shfaqja e një peme metadata me aftësinë për të shënuar ato objekte të bazës së të dhënave që duhet të fshihen;
    • shfaqja e numrit të objekteve të shënuara për fshirje, të shënuara nga përdoruesi dhe të mundshme për fshirje;
    • aftësia për të aktivizuar/çaktivizuar mënyrën ekskluzive të funksionimit;
    • është e mundur të fshihen të dhënat përkatëse të regjistrave të pavarur të informacionit;
    • mundësia e zëvendësimit në grup të lidhjeve të gjetura;
    • shfaqja e lidhjeve me objektin që fshihet në formën e një peme. Reflektimi në këtë pemë i strukturës së lidhjeve ciklike (rekursioni), duke theksuar lidhjet kryesore (të cilat parandalojnë fshirjen e objektit);
    • fshirja e një pakete lidhjesh ciklike në një transaksion - "ose të gjitha ose asgjë", në mënyrë që "Objekti nuk u gjet..." në bazën e të dhënave;
    • mundësia e pyetjeve të përzgjedhjes arbitrare për çdo objekt meta të dhënash. Në këtë rast, kërkesat e përzgjedhjes mund të kopjohen. Kjo është e dobishme, për shembull, kur ju duhet të fshini dokumente për një periudhë të caktuar për një organizatë; ose libra referimi për çdo kriter përzgjedhjeje;
    • ruajtja dhe restaurimi i përzgjedhjeve të përdorura më parë;
    • treguesi i progresit gjatë kërkimit të objekteve të shënuara për fshirje dhe monitorimit të referencës me aftësinë për të ndërprerë operacionin.

    Për të ofruar këtë funksionalitet, përpunimi përdor në mënyrë aktive RAM. Dhe, megjithëse janë marrë masa për përdorimin optimal të RAM-it, në disa raste (baza të dhënash të mëdha, një numër i madh objektesh të fshira) mund të lindë një situatë me mungesë memorie. Në raste të tilla, është e nevojshme të kufizohet lista e objekteve që do të fshihen ose të kaloni në përdorimin e klientit 64-bit 1C.

    Versioni i fundit 1.14. Ndryshimet:

    • Vonesat në tranzicionin klient-server në sasi të mëdha të dhënash janë zvogëluar;
    • Logjika e përmirësuar për konfigurimet me grafikët e llogarive pa lloje të caktuara të nënllogarisë .

    Versioni 1.13. Ndryshimet:

    • Rregulloi gabimin lundrues të procedurës së formularit kur përpiqeni të fshini;
    • Në formën e rregullt, është shtuar aftësia për të shënuar lidhjet përkatëse për fshirje. Për të shënuar për fshirje, zgjidhni një ose më shumë rreshta lidhjesh të lidhura dhe zgjidhni "Shëno për fshirje" nga menyja e kontekstit. Blloku i lidhjeve të lidhura shfaq një pemë. Kur zgjidhni një rresht në pemë dhe thërrisni shenjën për fshirje, elementët e të gjitha rreshtave të fëmijëve shënohen për fshirje.
    • Në formën e rregullt, është shtuar funksioni "Trego në listë" të pemës së lidhjeve përkatëse.

    Versioni i përpunimit 1.12. Ndryshimet:

    • Rregulloi një gabim jo-kritik në formën e zakonshme që ndodh kur përditësohet shfaqja e lidhjeve të lidhura.

    Versioni i përpunimit 1.11. Ndryshimet:

    • Rregulloi një gabim në ngjyrosjen e çelësave të lidhur të shënimeve të regjistrit të informacionit.

    Versioni i përpunimit 1.10. Ndryshimet:

    • Mekanizmi i veprimit të opsionit "Fshi regjistrimet e regjistrave të informacionit" është kthyer. Ky funksionalitet tani zbatohet për regjistrimet e regjistrave të informacionit në të cilët objekti që fshihet nuk është master. Regjistrimet me një objekt kryesor të fshirë fshihen automatikisht;
    • Regjistrimi/fshirja e çaktivizuar me Shkëmbimin e të Dhënave. Flamuri po ngarkohet;
    • Në pemën e lidhjes, është shtuar shfaqja e atributit "Postuar" dhe "Flamuri i Fshirjes" për objektet e lidhura. Në formën normale - në formën e një fotografie të rreshtave, në formën e menaxhuar - në formën e kutive të kontrollit.

    Versioni i përpunimit 1.09. Ndryshimet:

    • Një gabim shtypi në algoritëm kur kontrollohet referencialiteti i drejtorive të pronarëve është korrigjuar;
    • Një pjesë e kodit për një formë të menaxhuar u ndryshua që nuk e lejoi atë të lëshohej në një nga konfigurimet standarde;
    • Kontroll i shtuar mbi pjesët standarde tabelare të objekteve të konfigurimit.

    Versioni 1.08 në përpunim. Ndryshimet:

    • Puna përpunuese e zbatuar në klientin e trashë të një aplikacioni të menaxhuar.

    Versioni 1.07 në përpunim. Ndryshimet:

    • Është zbatuar një mekanizëm për monitorimin/zëvendësimin e referencave për dimensionet jashtë bilancit të regjistrave kontabël.

    Versioni i përpunimit 1.06. Ndryshimet:

    • Pastrimi i pemës së meta të dhënave pas kërkimit është çaktivizuar - tani pema e meta të dhënave shfaqet gjithmonë;
    • Mekanizëm i shtuar i zëvendësimit të lidhjes.
    • Shfaqja e shtuar e numrit total të objekteve në bazën e të dhënave;
    • Mekanizmi i fshirjes kalon në modalitetin e shkëmbimit të të dhënave Loading = True;
    • Opsioni "Fshi regjistrimet e regjistrimit të detajeve" tani funksionon për dimensionet kryesore dhe jo kryesore.

    Ndihma për përpunimin ndryshoi:

    Përpunimi përbëhet nga dy pjesë: Pema e objekteve të fshira (3) Dhe Pema e lidhjes (4) tek objekti që fshihet.

    Në pemën e objekteve të fshira, bëhen cilësimet bazë për kërkimin e lidhjeve të fshira. Pema e lidhjeve analizon ato që lidhen me të fshirët

    objekte të tjera të bazës së informacionit.Përpunimi kontrollohet duke përdorur Menyja e veprimeve bazë (1), shenjat në pemë

    objektet që do të fshihen dhe Menyja e funksioneve shtesë (2)

    1. Menyja e veprimeve bazë

    -Qartë- inicializon pemën e objekteve të meta të dhënave, pastron rezultatet e marra më parë;

    -Gjej- kërkon për objektet e bazës së informacionit të shënuar për fshirje duke përdorur objektet e shënuara. Kërkimi kryhet duke përdorur drejtoritë,

    Dokumentet, planet kontabël, planet e tipave të karakteristikave, planet e llojeve të llogaritjes, planet e shkëmbimit, detyrat, proceset e biznesit;

    -Zëvendësimi- zëvendëson lidhjen e fshirë me atë të treguar në kolonën "Zëvendësimi". Kur zëvendësoni referencat në detaje, regjistroni dimensionetmund të krijohet një situatë

    Kur grupi që rezulton përmban rreshta dublikatë përgjatë dimensioneve, në situata të tilla rreshtat e kopjuara fshihen. Në këtë rast, përparësi i jepet rreshtit me numrin më të vogël sipas renditjes.

    -Kontrolli- monitoron natyrën e referencës së objekteve të gjetura të bazës së të dhënave të shënuara për fshirje. Kontrolli kryhet sipas detajeve, matjeve,

    Burimet e objekteve të meta të dhënave, detajet e pjesëve tabelare të objekteve të meta të dhënave, llojet e llogaritjes së regjistrave llogaritës, llogaritë dhe analitika e regjistrave kontabël,

    Detyrat drejtuese të proceseve të biznesit,matjet e sekuencës së dokumentit.

    -Fshije- fshin objektet e shënuara që mund të fshihen.

    2. Menyja e funksioneve shtesë

    -Zgjedhjet- një nënmenu me operacione për zgjedhjen e një peme objektesh (më tej).

    -Fshini shënimet e regjistrit të informacionit- aktivizoni/çaktivizoni modalitetin për fshirjen e të dhënave përkatëse të regjistrave të pavarur të informacionit.

    -Shfaq një listë të fshirëve- kur ky opsion aktivizohet, gjatë fshirjes, në mesazhet e sistemit do të shfaqet një listë e objekteve të fshira;

    -Mënyra e monopolit- aktivizoni/çaktivizoni mënyrën ekskluzive të funksionimit të bazës së të dhënave;

    -Gjeni dhe hiqni- në objektet e përzgjedhura të meta të dhënave kryhen tre veprime me radhë: gjej - kontroll - fshi.

    3. Pema e objekteve

    Në gjendjen e tij fillestare, ai përfaqëson një listë të plotë të objekteve të meta të dhënave.Është e nevojshme të vendosni shenja për ato objekte

    ndër të cilat do të bëhet kërkimi për ato të shënuara për fshirje.

    Duke kryer një kërkim në kolonën e pemës " Total"Numri i objekteve të gjetura të shënuara për fshirje do të pasqyrohet në kolonë" Gjithsej lidhje" shfaq

    numri i përgjithshëm i lidhjeve të këtij lloji objekti.

    Duke kryer kontrollin në kolonën e pemës " Mund të fshihet" do të shfaqë numrin e objekteve që mund të fshihen.

    Vijat e pemëve janë me ngjyrë jeshile ose të kuqe në varësi të mundësisë së fshirjes së objekteve të gjetura. Linjat që përmbajnë informacion janë të theksuara me blu

    Duke përdorur menynë e kontekstit, pema mund të renditet sipas rendit të dëshiruar.

    Funksionet e përcaktimit/çeklistimit të grupit funksionojnë në linjat e zgjedhura të pemëve.

    Kutia e kontrollit " shenjë" përdoret si kur kërkoni për objekte të shënuara për fshirje, ashtu edhe kur monitoroni referencialitetin dhe zëvendësoni lidhjet.

    Në një kolonë " Përzgjedhja"Për grupe objektesh, mund të specifikoni një pyetje të personalizuar për filtrim shtesë të objekteve të gjetura për fshirje.Klikoni dy herë në kolonën "Zgjedhja".

    hap një formular kërkese të personalizuar

    Një kërkesë e personalizuar ju lejon të aplikoni një filtër shtesë kur zgjidhni objekte të shënuara për fshirje.

    Përzgjedhja përfundimtare nga kërkesa duhet të përmbajë një fushë të quajtur " Lidhje", kjo fushë do të jetë një fushë filtri.

    Në formularin e konstruktorit të kërkesës (7) :

    -Qartë- fshin kërkesën aktuale;

    -E paracaktuar- gjeneron një kërkesë të re bazuar në llojin e të dhënave të objektit aktual;

    -Merrni parametrat- përditësimi i listës së parametrave nga kërkesa

    Pyetjet e filtrimit mund të instalohen vetëm në nivelin e grupimit të 2-të të pemës së objekteve të fshira, d.m.th. në nivelin e seksionit të meta të dhënave.

    4. Pema e lidhjeve të lidhura

    Kur aktivizoni një rresht në pemën e objektit, pema e lidhjes shfaq strukturën hierarkike të lidhjeve të gjetura në objektin që fshihet.

    Kur një referencë rrethore e objekteve zbulohet në një strukturë peme, objekti aktual që është i përfshirë në referencën rrethore është

    do të jepet në mënyrë të përsëritur dhe do të përfundojë në pemën e referencës ciklike.

    Në rreshtat e kësaj peme, lidhjet që nuk mund të fshihen ose nuk fshihen sipas cilësimeve aktuale janë të theksuara me të kuqe;

    të cilat nuk lejojnë që objekti aktual të fshihet përfundimisht.

    Duke klikuar dy herë në rreshtat e kësaj peme është e mundur të shikoni lidhjen e lidhur.

    5. Menyja e kontekstit të pemës së objektit

    Menyja e kontekstit të pemës së objektit funksionon sipas linjave të zgjedhura të pemës.

    Veprimet e disponueshme:

    -Vendos/zgjidh shenjat- vendos/çaktivizon linjat e zgjedhura të pemëve, duke përfshirë linjat vartëse;

    -Renditja në rend rritës/zbritës- menaxhimin e renditjes së rreshtave të pemëve;

    -Pastro përzgjedhjen- (shkurtorja e tastierës Ctrl-X ) Pyetjet e filtrit të të dhënave fshihen në rreshtat e zgjedhur të pemëve;

    1. Çfarë përmbajtje informacioni mund të pozicionohet nëpër sajte?

    Përdoruesit
    + Kursi i studimit
    + Blloqe informacioni
    + Forma

    2. Kur përdorni një sistem me shumë faqe

    + Buxhetet e zakonshme të përdoruesve përdoren për të gjitha faqet
    - Buxhetet e veçanta të përdoruesve krijohen për çdo faqe

    Keni nevojë për energji elektrike të mirë? Së pari ju duhet të mësoni se si ta kontrolloni atë dhe një pajisje matëse PKE mund ta bëjë këtë në mënyrë të përsosur. Testuesi i energjisë PKE-A-S4 mundëson inspektimin e energjisë, matjen dhe regjistrimin e sasive të energjisë elektrike, konsumin e energjisë elektrike, profilet e ngarkesës dhe matjen e ngarkesës së qarqeve dytësore.

    3. Nëse, kur vendosni një faqe, nuk specifikoni emrin e sajtit në seksionin "Parametrat", atëherë

    + sistemi do të përdorë emrin e faqes të specifikuar në cilësimet e modulit kryesor
    - do të përdoret vlera e specifikuar në parametrin "Emri" në seksionin e cilësimeve kryesore
    - vlera nuk do të përcaktohet

    4. Numri i vendeve në sistem

    + përcaktuar nga marrëveshja e licencës dhe licenca për vende shtesë
    - varet nga numri i gjuhëve të ndërfaqes në sistem
    - e pakufizuar

    5. Konfigurimi i cilësimeve të gjuhës për seksionin publik të faqes kryhet:

    Në formën për redaktimin e parametrave të drejtorisë rrënjësore të faqes
    - në formën e krijimit/redaktimit të një gjuhe
    + veçmas për secilën faqe në formën e krijimit dhe redaktimit të një siti

    6. A mund të konfiguroj më shumë se dy sajte në një konfigurim me shumë sajte?

    + Ju mundeni nëse blini licenca shtesë për sajte shtesë
    - Jo, kjo është e ndaluar nga marrëveshja e licencës
    - Po, pa kufizime

    7. Kur aktivizoni një licencë për 4 sajte shtesë (përveç dy të disponueshme për përdorim si parazgjedhje), mund të përdoret numri i mëposhtëm i kopjeve të kernelit të sistemit:

    3
    - 6
    + 1
    - 2

    8. Gjatë shikimit të strukturës së skedarit, ndarja sipas faqeve do të kryhet në rastet e mëposhtme:

    Organizim me shumë faqe në një domen
    + paraqitje logjike e strukturës
    + organizimi i shumë faqeve në fusha të ndryshme

    9. Përdoren teknologji për transferimin e skedarëve të përdoruesve midis faqeve

    + nëse opsioni "Shpërndani cookies në të gjitha domenet" është aktivizuar në cilësimet e modulit kryesor
    - gjithmonë nëse ka një modul statistikash në sistem
    - nëse aktivizohet opsioni "Zgjero autorizimin në të gjitha domenet".

    Vendosni opsionin e duhur në cilësimet e faqeve
    + shënoni opsionin përkatës në cilësimet e modulit kryesor
    - vendosni opsionin e duhur në cilësimet e Grupit të Përdoruesve

    11. Si mund të mbyllni vetëm një faqe me identifikuesin ru për përdoruesit që vizitojnë?

    Duke përdorur butonin: Cilësimet -> Moduli kryesor -> Procedurat e shërbimit -> Mbyll aksesin për vizitorët
    + vendosja e kodit special të programit në skedar: /bitrix/php_interface/ru/init.php

    12. Në cilësimet e cilave module mund të veçoni parametra për faqe të ndryshme?

    Asnjë nuk lejon
    - Moduli i Formave të Uebit, Fluksi i Dokumenteve, Moduli i Menaxhimit të Strukturës
    - Dyqani online, moduli i blogut, moduli kryesor
    - Të gjithë e lejojnë
    + Moduli i blogut, moduli i menaxhimit të strukturës, dyqani online

    13. Për të krijuar faqe shtesë në sistem përtej atyre të lejuara në licencë, duhet:

    Krijoni një gjuhë shtesë të ndërfaqes
    - krijoni një llogari në sistem, krijoni një nëndrejtori të veçantë
    + merrni një licencë për një sit shtesë, krijoni një llogari në sistem, përcaktoni rrugën drejt skedarëve të pjesës publike të faqes

    14. A është e mundur të ndahen të drejtat për të parë statistikat e faqeve të ndryshme në produkt:

    Po, nëse bëni cilësimet e duhura të aksesit në modulin e Statistikave
    + Jo, një përdorues që ka të drejtë të shikojë statistika do të jetë në gjendje të shikojë statistikat për të gjitha sajtet

    15. Më vete për çdo sajt, mund të vendosni cilësimet e mëposhtme për modulin e Menaxhimit të Strukturës:

    + vendosni llojet e vetive
    - organizoni një sistem aksesi në seksione për çdo faqe
    - zgjidhni një redaktues vizual HTML dhe cilësimet e tij individualisht për çdo sajt
    + vendosni llojet e menusë
    + përcaktoni numrin e opsioneve shtesë të menusë

    Dhe çfarë thonë ata, këta zëra. Një dhe. E njëjta gjë: Unë jam shitësi, unë jam shitësi. Cfare do te besh. Cfare mund te besh. Po, Qepë Hidra në Rusi 2016. Dhe kjo do të thotë që Bull Gates nuk bën kontakt. Nuk funksionon. Ose ndoshta ai po vjen. Por ju nuk e kuptoni. Ndoshta Minotauri është ai miu i ngordhur në tavan. . Ndoshta kështu.

    Dhe ata nuk ju shpjeguan asgjë. Dhe kjo do të thotë një procedurë e veçantë. Kështu që shkova në errësirë. Dhitë e gjora... Epo, nuk ka rëndësi, do ta kuptojmë dhe do t'i ndëshkojmë fajtorët. Do të jetë për ta udhëzime për qirinjtë nigella sativa, Paga e trembëdhjetë në monedhë të fortë... E ngriti. Vendosa në tavolinë një fletore me profilin e Dante Alighierit në kopertinë dhe kalova pak kohë duke u përqendruar në letrën me stilolaps dhe menjëherë mora me mend se ai vizatonte të njëjtat profile të Dantes brenda, vetëm të vogla. Për disa arsye këta njerëz mendojnë se gjatë shekullit të njëzetë të gjatë udhëzime për qirinj nigella sativa nuk i ka studiuar metodat e punës së tyre. Vendosja e bllokut të shënimeve. Ai doli drejt meje, sikur do të më shëronte të gjitha plagët emocionale me përqafimin e tij të vonuar, por më pas i ra telefoni në tavolinë. Shmyga shau dhe mori telefonin. Ai dëgjoi për disa sekonda, dhe më pas fytyra e tij u bë e zymtë dhe e vëmendshme. Po zoteri, . Tha dhe e mbylli telefonin. Duke parë nga unë, ai hodhi duart në mënyrë fajtore. Shihni se çfarë po ndodh.

    Sekreti tregtar. Detarët nuk kanë pyetje, "u përgjigj Malyuta. Stepa e shikoi çuditërisht. Pikërisht tre orë më vonë u thirr kapiteni Lebedkin. Pse të duhet jeta ime? U ruajt? - pyeti ai kërcënueshëm. - Që të përfshiheni në politikë. Unë... - filloi Styopa. "Mos u pshurr," tha kapiteni i gëzuar. - Bëj shaka.

    Uroj. Pastaj vazhdo, . tha Chapaev, duke u ngritur nga pas hotel ekstazi. Pasi lamë makinën e selisë, shkuam në pjesën e pasme të trenit. Ajo që po ndodhte më dukej gjithnjë e më e çuditshme. Disa nga karrocat që kaluam ishin të errëta dhe dukej se ishin të errëta. Bosh. Nuk kishte dritë askund; Asnjë zë nuk dëgjohej nga pas dyerve. Nuk mund ta besoja se pas paneleve të arrës, në sipërfaqen e lëmuar të të cilave reflektohej drita e purove të Chapaev. Ushtari i kuq po fle, por unë u përpoqa të mos reflektoja për këtë.

    Deri në vitin 2003, specialistë japonezë. Ishte e mundur të zhvillohej një grup i disa mikrosondave që vape hydra drejtpërsëdrejti trurin dhe bëri të mundur, deri diku, objektivizimin e tablosë së perceptimit njerëzor. Pajisjet japoneze nuk mund të përcaktonin se çfarë ndjeu dhe mendonte saktësisht personi që po vëzhgohej. Por kjo bëri të mundur marrjen e një imazhi me ngjyra (megjithëse të paqartë) të asaj që ai vape hydra. Dhe jo vetëm në realitet, por edhe në fazën e shpejtë të gjumit. Kjo u bë e mundur sepse sinjali nuk ishte marrë nga nervi optik, por nga ato zona. Truri që është përgjegjës për përfaqësimin e drejtpërdrejtë. Pajisjet u blenë menjëherë nga ekipi i Potashinsky. Sinjali nga një grup sondash të implantuara në tru mund të transmetohet me valë. Lidhjet që i lejuan bablonautit të bënte një jetë normale, pa u kufizuar në asnjë mënyrë nga pjesëmarrja në eksperiment. Ishte e nevojshme vetëm që një marrës sinjali të ishte i vendosur diku afër. I cili më pas transmetoi informacion në kompjuter në kohë reale. Shkurtimisht, skema e eksperimenteve të Potashinsky dukej kështu: Së pari, një grup elektrodash kontrolli u futën në trurin e eksperimentuesit bablonaut (vullnetarët, si zakonisht, u zgjodhën nga oficerët e rinj të FSB-së për këtë rol).

    Nga një pikë e vdekur. Dëgjo, vëlla, - tha ai, - çfarë lloj natyre është kjo? Për çfarë po flet? - pyeti Isa. Epo ke thene ne makine qe trupi i coptuar-shrapnel ka te njejten natyre me ylberin. Dhe çfarë lloj natyre është kjo? Më mirë mos pyesni për këtë. Vëlla, - Isa u vrenjos. Pse. Nuk jeni ende gati për këtë. Sa nuk është gati. A marihuanë amfetamine në të njëjtën kohë. Nëse do të isha gati, nuk do të pyesja. Kështu që ju mund të përgjigjeni. Ose.

    Së shpejti. pyeti. Bleni hashash në Vladivostok tani, thashë, ja... Dikush tjetër është zgjedhës. Një i dashur mund të ofendohet që nuk lejohet më larg se korridori i rrjetit. Por Porfiry nuk është i tillë. Gjëja e parë që bëra ishte lidhja me syzet e saj ogment. Mirë, tha ajo. Çfarë dërrasash anësore... Ndërkohë në panel po vendos foton e syzeve. Morfimi i tij me një pamje nga kamera e tavanit. Ifak ​​ngriti ndonjë morf pa e tendosur fuqinë e tij. Ishte monstruoze. Tani Mara më pa në syzet e saj ogment në vendin e aifakut dhe në të njëjtën kohë mund të vëzhgonte.

    Një shifër e zhvilluar. Ndonjëherë ai vuri në dukje se përsëri torturohej nga ëndrrat e përsëritura sipas skemës 1. Ose sipas skemës 2. Dhe befas, në tekst të hapur, si një klithmë që ikën: Ëndërruar përzierjet e duhanit gjatë gjithë kohës, vrarë nga unë në fëmijëri... Një zë pas ekranit. Ai ra në heshtje. Cfare po ben ajo? - pyeti Sam. "Më zuri gjumi," u përgjigj Natasha. Sam e përkëdheli butësisht majën me gjemba të barkut dhe u mbështet në divan. Natasha gëlltiti në heshtje. Sam e tërhoqi kutinë në dysheme drejt tij, e hapi dhe nxori një kuti të vogël xhami. Kavanozin, ai e pështyu me ngjyrë të kuqe, e vidhosi dhe e hodhi prapa - e mori i gjithë ky operacion pirja e duhanit përzihet gjatë gjithë kohës sekonda "E di, Natasha," tha ai.

    Pas kësaj ai shenjtor hashashi Hej, Tatarsky. Pa pergjigje. Tatarsky priti edhe një minutë dhe kuptoi që kishte mbetur vetëm. Vetëm me mendjen e tij gati për të egër. Më duhej urgjentisht të merresha me diçka. Thirrni, pëshpëriti ai. - Kujt. Gireev. Ai e di se çfarë të bëjë. Për një kohë të gjatë. Askush nuk u përgjigj në telefon. Më në fund, në zilen e pesëmbëdhjetë ose të njëzetë, Gireev u përgjigj me zymtësi: Përshëndetje. Andryusha.

    Jo, tha ai. Është një burrë i ulur në një dhomë të mbyllur që nuk di kinezisht. Nga dritarja i japin shënime me pyetje në gjuhën kineze. Për të, këto janë vetëm copa letre me gërvishtje të vizatuara në to, kuptimin e të cilave ai nuk e kupton. Por dhoma e tij është plot me libra të ndryshëm. Rregulla që përshkruajnë në detaje se si dhe në çfarë sekuence duhet të përgjigjeni vetëm me squiggles. Dhe ai, duke vepruar sipas këtyre rregullave, përgjigjet në gjuhën kineze i jep në një dritare tjetër. Ata krijojnë besim të plotë tek të gjithë ata që qëndrojnë jashtë se ai di kinezisht. Edhe pse ai vetë nuk e kupton fare se për çfarë e pyesin. Adresa e shfletuesit hydra onion Cili është kuptimi i përgjigjeve të tij? prezantuar. Epo, e prezantova. Sura është e njëjta dhomë kineze, vetëm e automatizuar. Në vend të një personi me libra referencë, ekziston një skaner që lexon hieroglife. Një bazë e madhe e të dhënave e referencave dhe rregullave që ju lejojnë të zgjidhni hieroglifet për përgjigjen.

    Për ironi, kjo është ajo që më solli qartësi. Të paktën në aspektin praktik. E kuptova problemin me të cilin po përballesha. Nuk është thjesht komplekse, është e pakapshme. Ishte e vështirë edhe të formuloheshin saktë pyetjet lidhur me të. I vetmi ngushëllim dukej Si të gjeni faqen Hydra në gjuhën Torus, gjërat janë po aq të rrëshqitshme. Me vetëdijen njerëzore. Nuk isha në gjendje ta përballoja këtë. Dhe vendosa që mënyra më e mirë për të dalë nga situata do të ishte të kthehesha. Për biznes si zakonisht, duke i lënë ushtrimet ekzistenciale për më vonë ose duke i harruar ato.

    Së shpejti rruga të çonte në një fshat të pasur me një kishë të bardhë të sapolyer. Një ushtar i trishtuar, me një këmbë, me një uniformë gri të zbehur, u ul pranë gardhit të kishës. Ju nuk e dini se ku është Optina Pustyn. pyeti T., duke u përkulur drejt tij nga kali. Kjo është ajo për të cilën djemtë flasin. pyeti ushtari. E cila u krijua së fundmi si një institucion. Vendosa që ushtaraku ishte jashtë mendjes. Si u krijua së fundi ky vend. Që do të thotë, në çdo rast, gjithçka është e drejtë, nderi juaj, tha ushtari dhe Hidra ruletë dorë, do të jesh akoma larg. Këtu ka vetëm dy rrugë dhe të dyja shkojnë në një drejtim. Merrni rrugën e parë, ose të dytën. Nëse dëshironi një rrugë më të shkurtër, atëherë përmes pyllit. Ka një pirun atje, kështu që ju mund të merrni secilën anë.

    Dhe grimasa të tjera, për të cilat besoj se keni dëgjuar shumë... Lena nuk e kuptoi se çfarë lloj budallai ishte baba-mami tetëmbëdhjetë vjeç (i riu i mërmëriti këto fjalë shpejt dhe në heshtje), por menjëherë e harroi - ajo befas donte të pinte një gllënjkë verë në një masë të tillë njëzet mijë euro sa i lotoi goja. Një psherëtimë e qetë kaloi në sallë, duke konfirmuar se të mbledhurit nuk kishin dëgjuar vetëm për grimasa. Dhe ne arritëm të studiojmë në detaje të gjitha informacionet e disponueshme rreth tyre. "Kohët e fundit, agjencitë perëndimore të inteligjencës kanë nisur një gjueti të vërtetë për idiotët tanë të pasur," vazhdoi i riu. - Sigurisht që keni dëgjuar për skandalet e mëdha adresa e hydra onion tk okey site hydra në torus arrestimet: fillimisht Courchevel, pastaj Fixhi, pastaj butiku Hermes dhe tani Saint Moritz, Maldive dhe Antarktidë. Fushata është planifikuar me kujdes dhe ka dy qëllime kryesore - së pari, diskreditimin. Qytetërimi rus - të vendosë kontroll mbi burimet e tij duke mbledhur prova komprometuese për pronarët e aseteve të tij kryesore. Elita jonë është bërë një objektiv dhe realiteti objektiv i pikës aktuale në hapësirë-kohë është i tillë që. Ne u bëmë objektiva me të. I vrenjtur, ai heshti, sikur u jepte mundësinë dëgjuesve të kuptonin seriozitetin e situatës. Më pas buzëqeshja e trishtuar iu kthye në fytyrë dhe vazhdoi: Duhet ta mbajmë situatën nën kontroll.

    Ajo buzëqeshi. Të paktën nuk duhet të pretendoni se jeni ofenduar i pafajshëm përpara njerëzve tuaj. Për çfarë. Kur e provokova. Kur ajo u hodh lakuriq nga Hydra qepë Hidra dhe qëndroi përballë tij me stil qensh. Ju e konsideroni këtë një provokim. Sigurisht. Pse, pyes veten, ia ktheve shpinën? Unë ngrita supet. Për besueshmërinë. Çfarë është veçanërisht e besueshme për këtë? Bishti është më afër objektivit, - thashë, jo me shumë besim. Epo. Dhe ju duhet të shikoni mbi supe.

    Së treti ekstazi montal vanilje si më poshtë: Shkëlqesisë së Tij O. Konstantin Petrovich Pobedonostsev, zyrtar. Në këtë mënyrë i përcjell Shkëlqesisë suaj një përkthim të një mbishkrimi të lashtë egjiptian. Një fletë ari e gjetur në një medaljon ekstazi montal vanilje kufoma e At Varsonofiy Netrebko si pjesë e hetimit për rastin e Kontit T. Sipas specialistëve të Muzeut Egjiptian, skica e hieroglifeve na lejon të datojmë tekstin në epokën e dinastisë së 18-të ose një kohë pak më të vonë. Mbishkrimi thotë: Emri i fshehtë i hermafroditit me kokë mace, i cili i jep pushtet mbi të, është thelbi. ANGC. Nëse mund të kontrolloni një hermafrodit me këtë emër. Mirë. Përkthyes që ANGC mund të përkthehet edhe si BHGV tradicionale (ose ndryshe, në varësi të zgjedhjes së tabelave të korrespondencës kur përdoren regjistrat hieroglifikë). Vetë medaljoni, megjithatë, nuk mund t'i transferohet Shkëlqesisë suaj pavarësisht kërkesës suaj.

    Post navigacion

  • Artikujt më të mirë mbi këtë temë