Example #1
0
 public static function reInitData()
 {
     static::cleanUp();
     $totalCnt = 0;
     $offset = 0;
     $stat = array();
     while (true) {
         $res = Location\Name\LocationTable::getList(array('select' => array('NAME', 'LOCATION_ID', 'TID' => 'LOCATION.TYPE_ID'), 'filter' => array('=LOCATION.TYPE.CODE' => array('CITY', 'VILLAGE', 'STREET'), '=LANGUAGE_ID' => 'ru'), 'limit' => self::STEP_SIZE, 'offset' => $offset));
         $cnt = 0;
         while ($item = $res->fetch()) {
             if (strlen($item['NAME'])) {
                 $words = static::parseQuery($item['NAME']);
                 foreach ($words as $k => &$word) {
                     try {
                         static::add(array('WORD' => $word, 'TYPE_ID' => $item['TID'], 'LOCATION_ID' => $item['LOCATION_ID']));
                     } catch (\Bitrix\Main\DB\SqlQueryException $e) {
                         // duplicate or smth
                     }
                 }
                 $stat['W_' . count($words)] += 1;
                 //_print_r($words);
             }
             $cnt++;
             $totalCnt++;
         }
         if (!$cnt) {
             break;
         }
         $offset += self::STEP_SIZE;
     }
     _print_r('Total: ' . $totalCnt);
     _print_r($stat);
 }
Example #2
0
 protected function getSubpercentForStageCreateDictionary()
 {
     if (!isset($this->data['LOC_NAMES_2_INDEX_COUNT'])) {
         $item = Location\Name\LocationTable::getList(array('select' => array('CNT'), 'filter' => WordTable::getFilterForInitData(array('TYPES' => Finder::getIndexedTypes(), 'LANGS' => Finder::getIndexedLanguages()))))->fetch();
         $this->data['LOC_NAMES_2_INDEX_COUNT'] = intval($item['CNT']);
     }
     return $this->getSubPercentByTotalAndDone($this->data['LOC_NAMES_2_INDEX_COUNT'], $this->data['OFFSET']);
 }
Example #3
0
 /**
  * Deletes location from the tree
  *
  *
  */
 public static function delete($primary, $behaviour = array('REBALANCE' => true, 'DELETE_SUBTREE' => true, 'RESET_LEGACY' => true))
 {
     $primary = Assert::expectIntegerPositive($primary, '$primary');
     if (!is_array($behaviour)) {
         $behaviour = array();
     }
     if (!isset($behaviour['REBALANCE'])) {
         $behaviour['REBALANCE'] = true;
     }
     if (!isset($behaviour['RESET_LEGACY'])) {
         $behaviour['RESET_LEGACY'] = true;
     }
     if (!isset($behaviour['DELETE_SUBTREE'])) {
         $behaviour['DELETE_SUBTREE'] = true;
     }
     // delete connected data of sub-nodes
     if ($behaviour['DELETE_SUBTREE']) {
         $rangeSql = parent::getSubtreeRangeSqlForNode($primary);
         Name\LocationTable::deleteMultipleByParentRangeSql($rangeSql);
         ExternalTable::deleteMultipleByParentRangeSql($rangeSql);
     }
     if ($behaviour['RESET_LEGACY']) {
         $data = static::getList(array('filter' => array('=ID' => $primary), 'select' => array('TYPE_ID')))->fetch();
     }
     $delResult = parent::delete($primary, $behaviour);
     // delete connected data
     if ($delResult->isSuccess()) {
         Name\LocationTable::deleteMultipleForOwner($primary);
         ExternalTable::deleteMultipleForOwner($primary);
         if ($behaviour['RESET_LEGACY'] && intval($data['TYPE_ID'])) {
             $type = TypeTable::getList(array('filter' => array('=ID' => $data['TYPE_ID']), 'select' => array('CODE')))->fetch();
             if (strlen($type['CODE']) && in_array($type['CODE'], array('COUNTRY', 'REGION', 'CITY'))) {
                 static::resetLegacyPath();
             }
         }
         $GLOBALS['CACHE_MANAGER']->ClearByTag('sale-location-data');
         Search\Finder::setIndexInvalid();
     }
     return $delResult;
 }
Example #4
0
 public static function getIndexMap()
 {
     $locationTable = Location\LocationTable::getTableName();
     $locationNameTable = Location\Name\LocationTable::getTableName();
     $locationExternalTable = Location\ExternalTable::getTableName();
     return array('IX_B_SALE_LOC_MARGINS' => array('TABLE' => $locationTable, 'COLUMNS' => array('LEFT_MARGIN', 'RIGHT_MARGIN')), 'IX_B_SALE_LOC_MARGINS_REV' => array('TABLE' => $locationTable, 'COLUMNS' => array('RIGHT_MARGIN', 'LEFT_MARGIN')), 'IX_B_SALE_LOC_PARENT' => array('TABLE' => $locationTable, 'COLUMNS' => array('PARENT_ID')), 'IX_B_SALE_LOC_DL' => array('TABLE' => $locationTable, 'COLUMNS' => array('DEPTH_LEVEL')), 'IX_B_SALE_LOC_TYPE' => array('TABLE' => $locationTable, 'COLUMNS' => array('TYPE_ID')), 'IX_B_SALE_LOC_NAME_NAME_U' => array('TABLE' => $locationNameTable, 'COLUMNS' => array('NAME_UPPER')), 'IX_B_SALE_LOC_NAME_LI_LI' => array('TABLE' => $locationNameTable, 'COLUMNS' => array('LOCATION_ID', 'LANGUAGE_ID')), 'IX_B_SALE_LOC_EXT_LID_SID' => array('TABLE' => $locationExternalTable, 'COLUMNS' => array('LOCATION_ID', 'SERVICE_ID')), 'IXS_LOCATION_COUNTRY_ID' => array('TABLE' => $locationTable, 'COLUMNS' => array('COUNTRY_ID')), 'IXS_LOCATION_REGION_ID' => array('TABLE' => $locationTable, 'COLUMNS' => array('REGION_ID')), 'IXS_LOCATION_CITY_ID' => array('TABLE' => $locationTable, 'COLUMNS' => array('CITY_ID')), 'IX_B_SALE_LOCATION_1' => array('TABLE' => $locationTable, 'COLUMNS' => array('COUNTRY_ID'), 'DROP_ONLY' => true), 'IX_B_SALE_LOCATION_2' => array('TABLE' => $locationTable, 'COLUMNS' => array('REGION_ID'), 'DROP_ONLY' => true), 'IX_B_SALE_LOCATION_3' => array('TABLE' => $locationTable, 'COLUMNS' => array('CITY_ID'), 'DROP_ONLY' => true));
 }
Example #5
0
 public function convertTree()
 {
     $res = Location\Name\LocationTable::getList(array('select' => array('ID'), 'limit' => 1))->fetch();
     if (!$res['ID']) {
         $this->grabTree();
         $this->convertCountries();
         $this->convertRegions();
         $this->convertCities();
         $this->resort();
         $this->insertTreeInfo();
         $this->insertNames();
     }
 }
Example #6
0
 /**
  * <p>Метод удаляет все местоположения из базы. Метод динамичный.</p> <br><br>
  *
  *
  * @return mixed 
  *
  * @static
  * @link http://dev.1c-bitrix.ru/api_help/sale/classes/csalelocation/csalelocation__deleteall.1cda6559.php
  * @author Bitrix
  */
 public static function DeleteAll()
 {
     global $DB;
     foreach (GetModuleEvents("sale", "OnBeforeLocationDeleteAll", true) as $arEvent) {
         if (ExecuteModuleEventEx($arEvent) === false) {
             return false;
         }
     }
     if (self::isLocationProMigrated()) {
         //main
         $DB->Query("DELETE FROM " . Location\LocationTable::getTableName());
         $DB->Query("DELETE FROM " . Location\GroupTable::getTableName());
         $DB->Query("DELETE FROM " . Location\TypeTable::getTableName());
         //names
         $DB->Query("DELETE FROM " . Location\Name\LocationTable::getTableName());
         $DB->Query("DELETE FROM " . Location\Name\GroupTable::getTableName());
         $DB->Query("DELETE FROM " . Location\Name\TypeTable::getTableName());
         //links
         $DB->Query("DELETE FROM " . Location\GroupLocationTable::getTableName());
         $DB->Query("DELETE FROM " . Location\SiteLocationTable::getTableName());
         $DB->Query("DELETE FROM " . Delivery\DeliveryLocationTable::getTableName());
         //other
         $DB->Query("DELETE FROM " . Location\DefaultSiteTable::getTableName());
         $DB->Query("DELETE FROM " . Location\ExternalTable::getTableName());
         $DB->Query("DELETE FROM " . Location\ExternalServiceTable::getTableName());
     }
     $DB->Query("DELETE FROM b_sale_location2location_group");
     $DB->Query("DELETE FROM b_sale_location_group_lang");
     $DB->Query("DELETE FROM b_sale_location_group");
     $DB->Query("DELETE FROM b_sale_delivery2location");
     $DB->Query("DELETE FROM b_sale_location");
     $DB->Query("DELETE FROM b_sale_location_city_lang");
     $DB->Query("DELETE FROM b_sale_location_city");
     $DB->Query("DELETE FROM b_sale_location_country_lang");
     $DB->Query("DELETE FROM b_sale_location_country");
     $DB->Query("DELETE FROM b_sale_location_region_lang");
     $DB->Query("DELETE FROM b_sale_location_region");
     $DB->Query("DELETE FROM b_sale_location_zip");
     foreach (GetModuleEvents("sale", "OnLocationDeleteAll", true) as $arEvent) {
         ExecuteModuleEventEx($arEvent);
     }
 }
Example #7
0
 public function initializeData()
 {
     $res = Location\Name\LocationTable::getList(array('select' => array('NAME', 'LOCATION_ID'), 'filter' => static::getFilterForInitData(array('TYPES' => $this->procData['ALLOWED_TYPES'], 'LANGS' => $this->procData['ALLOWED_LANGS'])), 'order' => array('LOCATION_ID' => 'asc'), 'limit' => static::STEP_SIZE, 'offset' => $this->procData['OFFSET']));
     $cnt = 0;
     while ($item = $res->fetch()) {
         if (strlen($item['NAME'])) {
             if ($this->procData['CURRENT_LOCATION'] != $item['LOCATION_ID']) {
                 $this->procData['CURRENT_LOCATION_WORDS'] = array();
             }
             $this->procData['CURRENT_LOCATION'] = $item['LOCATION_ID'];
             $words = static::parseString($item['NAME']);
             foreach ($words as $k => &$word) {
                 $wordHash = md5($word);
                 $wordId = false;
                 if (isset($this->dictionaryIndex[$wordHash])) {
                     $wordId = $this->dictionaryIndex[$wordHash];
                 } else {
                     $wordId = static::getIdByWord($word);
                     // check if the word was added previously
                 }
                 if ($wordId === false) {
                     $wordId = $this->dictionaryInserter->insert(array('WORD' => $word));
                     $this->dictionaryIndex[$wordHash] = $wordId;
                 }
                 if ($wordId !== false && !isset($this->procData['CURRENT_LOCATION_WORDS'][$wordId])) {
                     $this->procData['CURRENT_LOCATION_WORDS'][$wordId] = true;
                     $this->word2LocationInserter->insert(array('LOCATION_ID' => intval($item['LOCATION_ID']), 'WORD_ID' => intval($wordId)));
                 }
             }
         }
         $cnt++;
     }
     $this->procData['OFFSET'] += static::STEP_SIZE;
     $this->dictionaryInserter->flush();
     $this->word2LocationInserter->flush();
     return !$cnt;
 }
Example #8
0
 public function restoreIndexes($certainIndex = false)
 {
     $locationTable = Location\LocationTable::getTableName();
     $locationNameTable = Location\Name\LocationTable::getTableName();
     $map = array('IX_B_SALE_LOC_MARGINS' => array('TABLE' => $locationTable, 'COLUMNS' => array('LEFT_MARGIN', 'RIGHT_MARGIN')), 'IX_B_SALE_LOC_MARGINS_REV' => array('TABLE' => $locationTable, 'COLUMNS' => array('RIGHT_MARGIN', 'LEFT_MARGIN')), 'IX_B_SALE_LOC_PARENT' => array('TABLE' => $locationTable, 'COLUMNS' => array('PARENT_ID')), 'IX_B_SALE_LOC_DL' => array('TABLE' => $locationTable, 'COLUMNS' => array('DEPTH_LEVEL')), 'IX_B_SALE_LOC_TYPE' => array('TABLE' => $locationTable, 'COLUMNS' => array('TYPE_ID')), 'IX_B_SALE_LOC_NAME_NAME_U' => array('TABLE' => $locationNameTable, 'COLUMNS' => array('NAME_UPPER')), 'IX_B_SALE_LOC_NAME_LI_LI' => array('TABLE' => $locationNameTable, 'COLUMNS' => array('LOCATION_ID', 'LANGUAGE_ID')));
     foreach ($map as $ixName => $ixData) {
         if ($certainIndex !== false && $certainIndex != $ixName) {
             continue;
         }
         if ($this->checkIndexExistsByName($ixName, $ixData['TABLE'])) {
             return false;
         }
         $this->dbConnection->query('CREATE INDEX ' . $ixName . ' ON ' . $ixData['TABLE'] . ' (' . implode(', ', $ixData['COLUMNS']) . ')');
     }
 }
Example #9
0
 /**
  *
  *
  * @param
  *
  * @return
  */
 protected static function findNoIndex($parameters)
 {
     $dbConnection = Main\HttpApplication::getConnection();
     $dbHelper = $dbConnection->getSqlHelper();
     // tables
     $locationTable = Location\LocationTable::getTableName();
     $locationNameTable = Location\Name\LocationTable::getTableName();
     $locationGroupTable = Location\GroupLocationTable::getTableName();
     $locationSiteTable = Location\SiteLocationTable::getTableName();
     $locationTypeTable = Location\TypeTable::getTableName();
     //////////////////////////////////
     // sql parameters prepare
     //////////////////////////////////
     $filter = static::parseFilter($parameters['filter']);
     if (strlen($filter['SITE_ID']['VALUE'])) {
         $filterSite = $dbHelper->forSql(substr($filter['SITE_ID']['VALUE'], 0, 2));
         $hasLocLinks = Location\SiteLocationTable::checkLinkUsage($filterSite, Location\SiteLocationTable::DB_LOCATION_FLAG);
         $hasGrpLinks = Location\SiteLocationTable::checkLinkUsage($filterSite, Location\SiteLocationTable::DB_GROUP_FLAG);
         $doFilterBySite = true;
     }
     if (strlen($filter['PHRASE']['VALUE'])) {
         $doFilterByName = true;
         $filterName = ToUpper($dbHelper->forSql($filter['PHRASE']['VALUE']));
     }
     if (intval($filter['ID']['VALUE'])) {
         $doFilterById = true;
         $filterId = intval($filter['ID']['VALUE']);
     }
     if (intval($filter['CODE']['VALUE'])) {
         $doFilterByCode = true;
         $filterCode = $dbHelper->forSql($filter['CODE']['VALUE']);
     }
     $doFilterByLang = true;
     if (strlen($filter['NAME.LANGUAGE_ID']['VALUE'])) {
         $filterLang = $dbHelper->forSql(substr($filter['NAME.LANGUAGE_ID']['VALUE'], 0, 2));
     } else {
         $filterLang = LANGUAGE_ID;
     }
     if (isset($filter['PARENT_ID']) && intval($filter['PARENT_ID']['VALUE']) >= 0) {
         $doFilterByParent = true;
         $filterParentId = intval($filter['PARENT_ID']['VALUE']);
     }
     if (intval($filter['TYPE_ID']['VALUE'])) {
         $doFilterByType = true;
         $filterTypeId = intval($filter['TYPE_ID']['VALUE']);
     }
     // filter select fields
     if (!is_array($parameters['select'])) {
         $parameters['select'] = array();
     }
     $map = Location\LocationTable::getMap();
     $nameAlias = false;
     foreach ($parameters['select'] as $alias => $field) {
         if ($field == 'CHILD_CNT') {
             $doCountChildren = true;
         }
         if ($field == 'NAME.NAME') {
             $nameAlias = $alias;
         }
         if (!isset($map[$field]) || !in_array($map[$field]['data_type'], array('integer', 'string', 'float', 'boolean')) || isset($map[$field]['expression'])) {
             unset($parameters['select'][$alias]);
         }
     }
     //////////////////////////////////
     // sql query build
     //////////////////////////////////
     // mandatory fields to be selected anyway
     // alias => field
     $fields = array('L.ID' => 'L.ID', 'L.CODE' => 'L.CODE', 'L.SORT' => 'L.SORT', 'LT_SORT' => 'LT.DISPLAY_SORT');
     if ($nameAlias === false || !preg_match('#^[a-zA-Z0-9]+$#', $nameAlias)) {
         $fields['NAME'] = 'LN.NAME';
     } else {
         $fields[$nameAlias] = 'LN.NAME';
     }
     $fields = array_merge($fields, array('L.LEFT_MARGIN' => 'L.LEFT_MARGIN', 'L.RIGHT_MARGIN' => 'L.RIGHT_MARGIN'));
     $groupFields = $fields;
     // additional fields to select
     foreach ($parameters['select'] as $alias => $fld) {
         $lFld = 'L.' . $fld;
         // check if field is already selected
         if ((string) $alias === (string) intval($alias)) {
             // already selected
             if (in_array($lFld, $fields)) {
                 continue;
             }
             $fields[$lFld] = $lFld;
             //$groupFields[$lFld] = $lFld;
         } else {
             if (isset($fields[$alias])) {
                 continue;
             }
             $fields[$alias] = $lFld;
             //$groupFields[$alias] = $lFld;
         }
         $groupFields[$lFld] = $lFld;
     }
     if ($doCountChildren) {
         $fields['CHILD_CNT'] = 'COUNT(LC.ID)';
     }
     // make select sql
     $selectSql = array();
     foreach ($fields as $alias => $fld) {
         if ($fld == $alias) {
             $selectSql[] = $fld;
         } else {
             $selectSql[] = $fld . ' as ' . $alias;
         }
     }
     $selectSql = implode(', ', $selectSql);
     //$groupSql = implode(', ', array_keys($groupFields));
     $groupSql = implode(', ', $groupFields);
     $mainSql = "select {$selectSql}\n\t\t\t\t\t\tfrom {$locationTable} L \n\t\t\t\t\t\t\tinner join {$locationNameTable} LN on L.ID = LN.LOCATION_ID\n\t\t\t\t\t\t\tinner join {$locationTypeTable} LT on L.TYPE_ID = LT.ID " . ($doCountChildren ? "\n\t\t\t\t\t\t\t\tleft join {$locationTable} LC on L.ID = LC.PARENT_ID\n\t\t\t\t\t\t\t" : "") . " \n\n\t\t\t\t\t\t%SITE_FILTER_CONDITION%\n\n\t\t\t\t\t\twhere \n\n\t\t\t\t\t\t\t%MAIN_FILTER_CONDITION%\n\n\t\t\t\t\t\t\t%GROUP_BY%\n\t\t\t\t\t\t\t";
     $where = array();
     if ($doFilterByLang) {
         $where[] = "LN.LANGUAGE_ID = '" . $filterLang . "'";
     }
     if ($doFilterByParent) {
         $where[] = "L.PARENT_ID = '" . $filterParentId . "'";
     }
     if ($doFilterById) {
         $where[] = "L.ID = '" . $filterId . "'";
     }
     if ($doFilterByCode) {
         $where[] = "L.CODE = '" . $filterCode . "'";
     }
     if ($doFilterByType) {
         $where[] = "L.TYPE_ID = '" . $filterTypeId . "'";
     }
     if ($doFilterByName) {
         $where[] = "LN.NAME_UPPER like '" . $filterName . "%'";
     }
     $mainSql = str_replace('%MAIN_FILTER_CONDITION%', implode(' and ', $where), $mainSql);
     $needDistinct = false;
     $unionized = false;
     $artificialNav = false;
     if (!$doFilterBySite) {
         $sql = str_replace('%SITE_FILTER_CONDITION%', '', $mainSql);
     } else {
         $sql = array();
         if ($hasLocLinks) {
             $sql[] = str_replace('%SITE_FILTER_CONDITION%', "\n\n\t\t\t\t\tinner join {$locationTable} L2 on L2.LEFT_MARGIN <= L.LEFT_MARGIN and L2.RIGHT_MARGIN >= L.RIGHT_MARGIN\n\t\t\t\t\tinner join {$locationSiteTable} LS2 on L2.ID = LS2.LOCATION_ID and LS2.LOCATION_TYPE = 'L' and LS2.SITE_ID = '{$filterSite}'\n\n\t\t\t\t", $mainSql);
         }
         if ($hasGrpLinks) {
             $sql[] = str_replace('%SITE_FILTER_CONDITION%', "\n\n\t\t\t\t\tinner join {$locationTable} L2 on L2.LEFT_MARGIN <= L.LEFT_MARGIN and L2.RIGHT_MARGIN >= L.RIGHT_MARGIN\n\t\t\t\t\tinner join {$locationGroupTable} LG on LG.LOCATION_ID = L2.ID\n\t\t\t\t\tinner join {$locationSiteTable} LS2 on LG.LOCATION_GROUP_ID = LS2.LOCATION_ID and LS2.LOCATION_TYPE = 'G' and LS2.SITE_ID = '{$filterSite}'\n\n\t\t\t\t", $mainSql);
             $useDistinct = true;
         }
         $cnt = count($sql);
         if ($cnt == 1) {
             $needDistinct = true;
         } else {
             // UNION removes duplicates, so distinct is required only when no union here
             $unionized = true;
         }
         $sql = ($cnt > 1 ? '(' : '') . implode(') union (', $sql) . ($cnt > 1 ? ')' : '');
     }
     // set groupping if needed
     $sql = str_replace('%GROUP_BY%', $needDistinct || $doCountChildren ? "group by {$groupSql}" : '', $sql);
     if (!is_array($parameters['order'])) {
         $sql .= " order by 3, 4 asc, 5";
     } else {
         // currenly spike
         if (isset($parameters['order']['NAME.NAME'])) {
             $sql .= " order by 5 " . ($parameters['order']['NAME.NAME'] == 'asc' ? 'asc' : 'desc');
         }
     }
     $offset = intval($parameters['offset']);
     $limit = intval($parameters['limit']);
     if ($limit) {
         if ($dbConnection->getType() == 'mssql') {
             // due to huge amount of limitations of windowed functions in transact, using artificial nav here
             // (does not support UNION and integer indices in ORDER BY)
             $artificialNav = true;
         } else {
             $sql = $dbHelper->getTopSql($sql, $limit, $offset);
         }
     }
     $res = $dbConnection->query($sql);
     if ($artificialNav) {
         $result = array();
         $i = -1;
         while ($item = $res->fetch()) {
             $i++;
             if ($i < $offset) {
                 continue;
             }
             if ($i >= $offset + $limit) {
                 break;
             }
             $result[] = $item;
         }
         return new DB\ArrayResult($result);
     } else {
         return $res;
     }
 }
Example #10
0
 public function initializeData()
 {
     $dbConnection = Main\HttpApplication::getConnection();
     $res = Location\LocationTable::getList(array('select' => array('ID', 'TYPE_ID', 'DEPTH_LEVEL', 'SORT'), 'order' => array('LEFT_MARGIN' => 'asc'), 'limit' => self::STEP_SIZE, 'offset' => $this->procData['OFFSET']));
     $cnt = 0;
     while ($item = $res->fetch()) {
         $name = Location\Name\LocationTable::getList(array('select' => array('NAME'), 'filter' => array('=LOCATION_ID' => $item['ID'], '=LANGUAGE_ID' => 'ru')))->fetch();
         if ($item['DEPTH_LEVEL'] < $this->procData['DEPTH']) {
             $newPC = array();
             foreach ($this->procData['PATH'] as $dl => $id) {
                 if ($dl >= $item['DEPTH_LEVEL']) {
                     break;
                 }
                 $newPC[$dl] = $id;
             }
             $this->procData['PATH'] = $newPC;
         }
         $this->procData['PATH'][$item['DEPTH_LEVEL']] = array('TYPE' => $item['TYPE_ID'], 'ID' => $item['ID']);
         $this->procData['DEPTH'] = $item['DEPTH_LEVEL'];
         if (is_array($this->procData['ALLOWED_TYPES']) && in_array($item['TYPE_ID'], $this->procData['ALLOWED_TYPES'])) {
             $data = array('LOCATION_ID' => $item['ID'], 'RELEVANCY' => $this->procData['TYPE_SORT'][$item['TYPE_ID']]);
             $wordsAdded = array();
             $k = 1;
             foreach ($this->procData['PATH'] as &$pathItem) {
                 if (!isset($pathItem['WORDS'])) {
                     $sql = "\n\t\t\t\t\t\t\tselect WS.POSITION from " . WordTable::getTableNameWord2Location() . " WL\n\t\t\t\t\t\t\t\tinner join " . WordTable::getTableName() . " WS on WL.WORD_ID = WS.ID\n\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\tWL.LOCATION_ID = '" . intval($pathItem['ID']) . "'\n\t\t\t\t\t\t";
                     $wordRes = $dbConnection->query($sql);
                     $pathItem['WORDS'] = array();
                     while ($wordItem = $wordRes->fetch()) {
                         $pathItem['WORDS'][] = $wordItem['POSITION'];
                     }
                     $pathItem['WORDS'] = array_unique($pathItem['WORDS']);
                 }
                 foreach ($pathItem['WORDS'] as $position) {
                     if (!isset($wordsAdded[$position])) {
                         $this->indexInserter->insert(array_merge(array('POSITION' => $position), $data));
                         $wordsAdded[$position] = true;
                     }
                 }
             }
             unset($pathItem);
         }
         $cnt++;
     }
     $this->indexInserter->flush();
     $this->procData['OFFSET'] += self::STEP_SIZE;
     return !$cnt;
 }
Example #11
0
 /**
  *
  *
  * @param
  *
  * @return
  */
 public static function getListFast($parameters = array())
 {
     $dbConnection = Main\HttpApplication::getConnection();
     $dbHelper = $dbConnection->getSqlHelper();
     // we require autocomplete to answer ASAP, so say hello to direct query
     // tables
     $locationTable = LocationTable::getTableName();
     $locationNameTable = Name\LocationTable::getTableName();
     $locationGroupTable = GroupLocationTable::getTableName();
     $locationSiteTable = SiteLocationTable::getTableName();
     $locationTypeTable = TypeTable::getTableName();
     //////////////////////////////////
     // sql parameters prepare
     //////////////////////////////////
     if (strlen($parameters['filter']['SITE_ID'])) {
         $filterSite = $dbHelper->forSql(substr($parameters['filter']['SITE_ID'], 0, 2));
         $hasLocLinks = SiteLocationTable::checkLinkUsage($filterSite, 'L');
         $hasGrpLinks = SiteLocationTable::checkLinkUsage($filterSite, 'G');
         if ($hasLocLinks || $hasGrpLinks) {
             $doFilterBySite = true;
         }
     }
     if (strlen($parameters['filter']['NAME'])) {
         $doFilterByMainParams = true;
         $doFilterByName = true;
         // user-typed '%' are not allowed in like expression - ddos risk
         $filterName = ToUpper($dbHelper->forSql(str_replace('%', '', $parameters['filter']['NAME'])));
     }
     if (strlen($parameters['filter']['PRIMARY'])) {
         $doFilterByMainParams = true;
         $doFilterByPrimaryCode = true;
         // user-typed '%' are not allowed in like expression - ddos risk
         $filterPrimaryCode = ToLower($dbHelper->forSql(str_replace('%', '', $parameters['filter']['PRIMARY'])));
         if (is_numeric($parameters['filter']['PRIMARY']) && $parameters['filter']['PRIMARY'] == intval($parameters['filter']['PRIMARY'])) {
             $doFilterByPrimaryId = true;
             $filterPrimaryId = intval($parameters['filter']['PRIMARY']);
         }
     }
     if (intval($parameters['filter']['ID'])) {
         $doFilterById = true;
         $filterId = intval($parameters['filter']['ID']);
     }
     if (strlen($parameters['filter']['LANGUAGE_ID'])) {
         $filterLang = $dbHelper->forSql(substr($parameters['filter']['LANGUAGE_ID'], 0, 2));
     }
     if (isset($parameters['filter']['PARENT_ID']) && intval($parameters['filter']['PARENT_ID']) >= 0) {
         $doFilterByParent = true;
         $filterParentId = intval($parameters['filter']['PARENT_ID']);
     }
     if (intval($parameters['filter']['TYPE_ID'])) {
         $doFilterByType = true;
         $filterTypeId = intval($parameters['filter']['TYPE_ID']);
     }
     if (intval($parameters['filter']['EXCLUDE_SUBTREE'])) {
         $doFilterByExclude = true;
         $filterExclude = intval($parameters['filter']['EXCLUDE_SUBTREE']);
         $res = self::getById($filterExclude)->fetch();
         if ($res) {
             $excludeMarginLeft = $res['LEFT_MARGIN'];
             $excludeMarginRight = $res['RIGHT_MARGIN'];
         } else {
             $doFilterByExclude = false;
         }
     }
     // filter select fields
     if (!is_array($parameters['select'])) {
         $parameters['select'] = array();
     }
     $map = self::getMap();
     foreach ($parameters['select'] as $k => $field) {
         if ($field == 'CHILD_CNT') {
             $doCountChildren = true;
         }
         if (in_array($field, array('ID', 'CODE', 'SORT', 'LEFT_MARGIN', 'RIGHT_MARGIN')) || !isset($map[$field]) || !in_array($map[$field]['data_type'], array('integer', 'string', 'float', 'boolean'))) {
             unset($parameters['select'][$k]);
         }
     }
     //////////////////////////////////
     // sql query build
     //////////////////////////////////
     $fields = array('L.ID' => 'L.ID', 'L.CODE' => 'L.CODE', 'L.SORT' => 'L.SORT', 'LT.SORT' => 'LT_SORT', 'LN.NAME' => 'LN.NAME', 'L.LEFT_MARGIN' => 'L.LEFT_MARGIN', 'L.RIGHT_MARGIN' => 'L.RIGHT_MARGIN');
     $groupFields = $fields;
     // for select fields and group fields
     foreach ($parameters['select'] as $fld) {
         if ($fld == 'CHILD_CNT') {
             $fields['COUNT(LC.ID)'] = 'CHILD_CNT';
         } else {
             $lFld = 'L.' . $fld;
             if (isset($fields[$lFld])) {
                 continue;
             }
             $fields[$lFld] = $lFld;
             $groupFields[$lFld] = $lFld;
         }
     }
     // make select sql
     $selectSql = array();
     foreach ($fields as $fld => $alias) {
         if ($fld == $alias) {
             $selectSql[] = $fld;
         } else {
             $selectSql[] = $fld . ' as ' . $alias;
         }
     }
     $selectSql = implode(', ', $selectSql);
     $groupSql = implode(', ', array_keys($groupFields));
     $mainSql = "select {$selectSql}\n\t\t\t\t\t\tfrom {$locationTable} L \n\t\t\t\t\t\t\tinner join {$locationNameTable} LN on L.ID = LN.LOCATION_ID\n\t\t\t\t\t\t\tinner join {$locationTypeTable} LT on L.TYPE_ID = LT.ID " . ($doCountChildren ? "\n\t\t\t\t\t\t\t\tleft join {$locationTable} LC on L.ID = LC.PARENT_ID\n\t\t\t\t\t\t\t" : "") . " \n\n\t\t\t\t\t\t%SITE_FILTER_CONDITION%\n\n\t\t\t\t\t\twhere \n\t\t\t\t\t\t\tLN.LANGUAGE_ID = '{$filterLang}'\n\n\t\t\t\t\t\t\t%MAIN_FILTER_CONDITION%\n\n\t\t\t\t\t\t\t" . ($doFilterByParent ? "\n\t\t\t\t\t\t\t\tand L.PARENT_ID = {$filterParentId}\n\t\t\t\t\t\t\t" : "") . ($doFilterById ? "\n\t\t\t\t\t\t\t\tand L.ID = {$filterId}\n\t\t\t\t\t\t\t" : "") . ($doFilterByExclude ? "\n\t\t\t\t\t\t\t\tand not(L.LEFT_MARGIN <= {$excludeMarginLeft} and L.RIGHT_MARGIN >= {$excludeMarginRight})\n\t\t\t\t\t\t\t" : "") . ($doFilterByType ? "\n\t\t\t\t\t\t\t\tand L.TYPE_ID = {$filterTypeId}\n\t\t\t\t\t\t\t" : "") . ($doCountChildren ? "\n\t\t\t\t\t\t\t\tgroup by {$groupSql}\n\t\t\t\t\t\t\t" : "");
     // todo: when search by ID or CODE, the better way is to break query onto UNIONs: first union stands for NAME_UPPER search, second - for ID exact match and the third - for CODE
     if ($doFilterByMainParams) {
         $mp = array();
         if ($doFilterByPrimaryId) {
             $mp[] = "L.ID = {$filterPrimaryId}";
         }
         if ($doFilterByPrimaryCode) {
             $mp[] = "L.CODE like '{$filterPrimaryCode}%'";
         }
         if ($doFilterByName) {
             $mp[] = "LN.NAME_UPPER like '{$filterName}%'";
         }
         $cnt = count($mp);
         $mainSql = str_replace('%MAIN_FILTER_CONDITION%', ' and ' . ($cnt > 1 ? '(' : '') . implode(' or ', $mp) . ($cnt > 1 ? ')' : ''), $mainSql);
     } else {
         $mainSql = str_replace('%MAIN_FILTER_CONDITION%', '', $mainSql);
     }
     if (!$doFilterBySite) {
         $sql = str_replace('%SITE_FILTER_CONDITION%', '', $mainSql);
     } else {
         $sql = array();
         if ($hasLocLinks) {
             $sql[] = str_replace('%SITE_FILTER_CONDITION%', "\n\n\t\t\t\t\tinner join {$locationTable} L2 on L2.LEFT_MARGIN <= L.LEFT_MARGIN and L2.RIGHT_MARGIN >= L.RIGHT_MARGIN\n\t\t\t\t\tinner join {$locationSiteTable} LS2 on L2.ID = LS2.LOCATION_ID and LS2.LOCATION_TYPE = 'L' and LS2.SITE_ID = '{$filterSite}'\n\n\t\t\t\t", $mainSql);
         }
         if ($hasGrpLinks) {
             $sql[] = str_replace('%SITE_FILTER_CONDITION%', "\n\n\t\t\t\t\tinner join {$locationTable} L2 on L2.LEFT_MARGIN <= L.LEFT_MARGIN and L2.RIGHT_MARGIN >= L.RIGHT_MARGIN\n\t\t\t\t\tinner join {$locationGroupTable} LG on LG.LOCATION_ID = L2.ID\n\t\t\t\t\tinner join {$locationSiteTable} LS2 on LG.LOCATION_GROUP_ID = LS2.LOCATION_ID and LS2.LOCATION_TYPE = 'G' and LS2.SITE_ID = '{$filterSite}'\n\n\t\t\t\t", $mainSql);
         }
         $cnt = count($sql);
         $sql = ($cnt > 1 ? '(' : '') . implode(') union (', $sql) . ($cnt > 1 ? ')' : '');
     }
     if (!is_array($parameters['order'])) {
         $sql .= " order by 3, 4 desc, 5";
     } else {
         // currenly spike
         if (isset($parameters['order']['NAME.NAME'])) {
             $sql .= " order by 5 " . ($parameters['order']['NAME.NAME'] == 'asc' ? 'asc' : 'desc');
         }
     }
     $artificialNav = false;
     $offset = intval($parameters['offset']);
     $limit = intval($parameters['limit']);
     if ($limit) {
         if ($dbConnection->getType() != 'mssql') {
             $sql = $dbHelper->getTopSql($sql, $limit, $offset);
         } else {
             // have no idea how to use limit-offset in UNION for transact
             $artificialNav = true;
         }
     }
     $res = $dbConnection->query($sql);
     if ($artificialNav) {
         $result = array();
         $i = -1;
         while ($item = $res->fetch()) {
             $i++;
             if ($i < $offset) {
                 continue;
             }
             if ($i >= $offset + $limit) {
                 break;
             }
             $result[] = $item;
         }
         return new DB\ArrayResult($result);
     } else {
         return $res;
     }
 }