public function indexAction() { $this->view->one = K_Registry::get('one'); K_Registry::write('h1', $this->view->one['header']); // var_dump($one); K_Crumbs::add(array('Новости', 'taxi-novosti')); K_Crumbs::add(array($this->view->one['tree_title'], $this->view->one['tree_name'])); $next = K_Tree::getNextBro('', $this->view->one); $prev = K_Tree::getPrevBro('', $this->view->one); $this->view->next = $next['tree_name']; $this->view->prev = $prev['tree_name']; $this->render('one'); }
public function loadChildsAction() { $nodeChilds = array(); if (intval($_POST['treeid'])) { $nodeChilds = K_Tree::getChilds(intval($_POST['treeid'])); } $field = 'tree_' . $_POST['field']; $returnJSON = array(); foreach ($nodeChilds as $v) { $id = $v['tree_id']; $child['title'] = $v["tree_title"]; $child['value'] = $v[$field]; $returnJSON[$id] = $child; } $this->putJSON($returnJSON); }
/** * Загружает структуру формы для ноды по её типу итема * * * */ public static function loadTypeFormStructure($treeId, $formMethodsClass = false, $formMethodsParams = array()) { $treeTable = new K_Tree_Model(); $resultData = ''; $node = K_Tree::getNode($treeId); //treeTable->select()->where('`tree_id`='.(int)$treeId)->fetchRow(); return self::loadTypeStructure($node['tree_type'], $formMethodsClass, $formMethodsParams); }
public static function getTypeBlocks($nodePid, $limit = false) { $parentNodeData = K_Tree::getNode($nodePid); $typesModel = new K_Tree_Types_Model(); $types = $typesModel->select('type_name')->fetchArray(); $rtypes = array(); $rtypesTables = array(); $rtypesAll = array(); $query = new K_Db_Query(); $result = $query->q('SELECT * FROM `tree` WHERE `tree_lkey`>=' . $parentNodeData['tree_lkey'] . ' AND `tree_rkey`<=' . $parentNodeData['tree_rkey'] . ' ORDER BY `tree_lkey` ASC ' . ($limit ? ' LIMIT ' . $limit : '')); $usedTypes = array(); for ($i = 0; $i < sizeof($result); $i++) { $data[$i] = $result[$i]->toArray(); if (!in_array($data[$i]['tree_type'], $usedTypes)) { $usedTypes[] = $data[$i]['tree_type']; } } $allResults = array(); $rData = array(); $i = 1; foreach ($types as $type) { if (in_array($type['type_name'], $usedTypes)) { $rtypes[] = $type['type_name']; $rtypesTables = '`type_' . $type['type_name'] . '` AS `ty' . $i . '`'; $rtypesAll = '`ty' . $i . '`.*'; $rtypesWhere = '`tr`.`tree_id`=`ty' . $i . '`.`type_' . $type['type_name'] . '_id`'; $result = $query->q('SELECT `tr`.*, ' . $rtypesAll . ' FROM `tree` AS `tr`, ' . $rtypesTables . ' WHERE ' . $rtypesWhere . ' AND `tr`.`tree_lkey`>=' . $parentNodeData['tree_lkey'] . ' AND `tr`.`tree_rkey`<=' . $parentNodeData['tree_rkey'] . ' ORDER BY `tr`.`tree_lkey` ASC ' . ($limit ? ' LIMIT ' . $limit : '')); foreach ($result as $key => $value) { $result[$key] = $value->toArray(); foreach ($result[$key] as $typeField => $typeValue) { $rData[$key][str_replace('type_' . $type['type_name'] . '_', '', $typeField)] = $typeValue; } } $allResults = array_merge($allResults, $rData); $i++; } } $rAllResults = array(); foreach ($allResults as $key => $value) { $rAllResults[$value['tree_lkey']] = $value; } ksort($rAllResults); $rrAllResults = array(); $i = 0; foreach ($rAllResults as $value) { $rrAllResults[$i] = $value; $i++; } return $rrAllResults; }
private static function aclTreeLoadRules($allRules) { foreach ($allRules as $v) { $nodeIds = K_Tree::getParents($v['tree_rule_resource_id']); $nodeIdsArr = $nodeIds; $nodeIdsArr[] = $v['tree_rule_resource_id']; $fullNodeResourse = implode('/', $nodeIdsArr); //полный ресурс ноды if (!self::$aclTree->has($fullNodeResourse)) { // грузим ресурсы только если нода не загруженна. // проверяем есть ли у ноды предки if (count($nodeIds) > 0) { $nodeIds[] = $v['tree_rule_resource_id']; $tmpIds = $nodeIds; //проверяем на сколько загруженна ветка ресурса $i = count($nodeIds) - 1; foreach ($nodeIds as $k => $n) { $i--; array_pop($tmpIds); $rosourceParent = implode('/', $tmpIds); // ресурс предка ноды if (self::$aclTree->has($rosourceParent)) { break; } } // echo "*******\n"; $resourseArr = $tmpIds; // стартовая позиция с которой загружены ресурсы // догружаем ресурсы ветки ноды вместе с нодой for ($m = $i + 1; $m < count($nodeIds); $m++) { $resourseArr[] = $nodeIds[$m]; $resourse = strtolower(implode('/', $resourseArr)); // echo $rosourceParent."-parent\n"; // echo $resourse."-node\n"; self::$aclTree->add(new K_Acl_Resource($resourse), $rosourceParent == '' ? null : $rosourceParent, null); $rosourceParent = $resourse; } } else { //нет предков сразу грузим ресурс без предка, если он не загружен if (!self::$aclTree->has($v['tree_rule_resource_id'])) { self::$aclTree->add(new K_Acl_Resource($v['tree_rule_resource_id']), null, null); } } } // echo $v['role']." ".$fullNodeResourse.' '.$v['privilege']." ". $v['tree_ruleType'] ; //устанавливамем правило switch ($v['tree_ruleType']) { case 'allow': self::$aclTree->allow($v['role'], $fullNodeResourse, $v['privilege']); break; case 'deny': self::$aclTree->deny($v['role'], $fullNodeResourse, $v['privilege']); break; } } //K_Cache_Manager::get('unlim')->save('ATR', self::$aclTree); self::saveAclArrays('ATR', self::$aclTree); }
public function getParents() { $nodeParents = array(); $treeid = intval($_POST['treeid']); if ($treeid) { $nodeParents = K_Tree::getParents($treeid); } $this->putJSON($nodeParents); }
public static function addNode($typeModel, $type, $tree, $nodeTitle, $nodeName, $saveData, $errSql = false) { if (empty($nodeName) || empty($nodeTitle)) { return false; } $nodeId = K_Tree::add($tree, $type, strtolower(preg_replace("/[^a-z0-9-]/i", "", K_String::rus2lat(preg_replace('/\\s+/', '-', trim($nodeName))))), trim($nodeTitle), 1, 0); if ($nodeId) { $saveData['type_' . $type . '_id'] = $nodeId; K_Db_Adapter::$defaultAdapter->lastQueryError = false; $typeModel->save($saveData); // echo K_Db_Adapter::$defaultAdapter->lastSqlQuery; // K_cli::nbr(); if (K_Db_Adapter::$defaultAdapter->lastQueryError) { if ($errSql) { echo K_Db_Adapter::$defaultAdapter->lastSqlQuery; } K_Tree::delete($nodeId); } else { return $nodeId; } } return false; }
protected function testAction() { $this->putJSON(K_Tree::reStoreTreeKeys(0, 0)); }
public static function addField($form, $type, $element, $elementData, $formData) { switch ($type) { case 'text': $form->{$type}($element->values->name, !empty($elementData) ? $elementData : (!empty($element->values->default) ? $element->values->default : ''), array('class' => $element->values->class, 'id' => $element->values->id, 'placeholder' => $element->values->placeholder)); break; case 'textarea': $form->{$type}($element->values->name, !empty($elementData) ? $elementData : (!empty($element->values->default) ? $element->values->default : ''), array('class' => $element->values->class, 'id' => $element->values->id, 'placeholder' => $element->values->placeholder)); break; case 'wysiwyg': $form->textarea($element->values->name, !empty($elementData) ? $elementData : (!empty($element->values->default) ? $element->values->default : ''), array('class' => $element->values->class . ' wysiwyg-redactor', 'id' => $element->values->id)); echo ' <script type="text/javascript"> $(function() { $(".wysiwyg-redactor").ckeditor({ allowedContent: true, toolbar: "Standard", removePlugins : "resize,about,save", filebrowserBrowseUrl : "/adm/plugins/ckfinder/ckfinder.html", filebrowserImageBrowseUrl : "/adm/plugins/ckfinder/ckfinder.html?Type=Images", filebrowserFlashBrowseUrl : "/adm/plugins/ckfinder/ckfinder.html?Type=Flash", filebrowserUploadUrl : "/adm/plugins/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files", filebrowserImageUploadUrl : "/adm/plugins/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images", filebrowserFlashUploadUrl : "/adm/plugins/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Flash", editorConfig : function( config ) { CKEDITOR.replace( "content_id", { allowedContent: true}) config.protectedSource.push(/<(style)[^>]*>.*<\\/style>/ig); return config; } }); }); </script>'; /* $(".wysiwyg-redactor").redactor({ imageUpload: "/admin/api/uploadImage", autoformat: true, cleanUp: true, convertDivs: false, removeClasses: true, removeStyles: true, convertLinks: false, buttons: ["html", "|", "formatting", "|", "bold", "italic" , "deleted","|","norderedlist", "orderedlist", "outdent", "indent", "|","image","video","table", "link", "|","fontcolor", "backcolor", "|","alignleft", "aligncenter", "alignright", "justify", "|","horizontalrule", "fullscreen"] }); */ break; case 'formbuilder': K_Loader::load('formbuilder', APP_PATH . '/plugins'); $form_builder = new Formbuilder(unserialize($elementData)); echo ' <div id="my-form-builder"></div> <input type="hidden" name="' . $element->values->name . '" id="f_' . $element->values->name . '"></div> <script type="text/javascript"> $("#my-form-builder").formbuilder({ "save_url": false, "load_url": false, "preview_url": false, "saveInDom": true, ' . (!empty($elementData) ? '"load_source": ' . $form_builder->render_json(false) . ',' : '') . ' "domElementId": "f_' . $element->values->name . '", "useJson" : true }); </script> '; break; case 'file': $form->{$type}($element->values->name, array('class' => $element->values->class, 'id' => $element->values->id)); if (self::$adminka) { echo ' <input type="checkbox" name="' . $element->values->name . '_delete">Удалить файл</input>'; } if ($elementData) { echo '<div>' . (preg_match('/^.*\\.(jpg|png|jpeg|gif|bmp)$/im', $elementData) ? '<br /><img src="/images/' . $elementData . '?h=120" style="margin-top:5px" /></div>' : '<span class="file_address_text"><a href="/upload/' . htmlentities(urlencode($elementData)) . '">' . $elementData . '</a></span></div>'); } break; case 'multifile': echo '<div id = ' . $element->values->id . ' data-filename = ' . $element->values->name . ' class = "multifile">'; $i = 0; if ($elementData) { $fileArr = unserialize($elementData); if (count($fileArr)) { foreach ($fileArr as $v) { echo '<div style="margin:15px 0" id="' . $element->values->id . '_a_' . $i . '">'; echo '<input type="text" value="' . $v['t'] . '" style="width:150px;margin-right:5px" name="' . $element->values->name . '_t_' . $i . '" id="' . $element->values->id . '_t_' . $i . '"/>'; $form->file($element->values->name . '_f_' . $i, array('class' => $element->values->class, 'id' => $element->values->id . '_f_' . $i)); if (self::$adminka) { echo '<br/> <input type="checkbox" name="' . $element->values->name . '_delete_' . $i . '">Удалить файл</input>'; } echo '<div>' . (preg_match('/^.*\\.(jpg|png|jpeg|gif|bmp)$/im', $v['f']) ? '<br /><img src="/images/' . $v['f'] . '?w=150&h=150&zc=C" style="margin-top:5px" /></div><br/>' : '<span class="file_address_text"><a href="/upload/' . htmlentities(urlencode($v['f'])) . '">' . ($v['t'] ? $v['t'] : $v['f']) . '</a></span></div><br/>'); $i++; echo '</div>'; } } } if (!$i) { echo '<div style="margin:15px 0" id="' . $element->values->id . '_a_0">'; echo '<input type="text" style="width:150px;margin-right:5px" name="' . $element->values->name . '_t_0" id="' . $element->values->id . '_t_0"/>'; $form->file($element->values->name . '_f_0', array('style' => 'width:220px', 'class' => $element->values->class, 'id' => $element->values->id . '_f_0')); echo '<a data-fileid="' . $element->values->id . '_0' . '" class="file_field_delete" href="javascript:void(0);" title="Убрать лишний"></a>'; echo '</div>'; } echo '</div>'; echo "<script type=\"text/javascript\"> \n \$(function(){\n \$('#" . $element->values->id . "').multifile(); \n });\n </script>"; break; case 'select': $listOptions = self::getListOptions($element); $listAttr = array('class' => $element->values->class, 'id' => $element->values->id); if ($element->multiple == "checked") { $listAttr['multiple'] = 'multiple'; } // var_dump($element); $treeIds = array(); if ($element->values->method) { $params = json_decode($element->values->method, true); // var_dump($params); // $params = explode(':',$element->values->method); $source = trim($params['node']); $field = 'tree_' . $params['field']; if (strpos($params['field'], 'type') !== false) { $field = str_replace('type_', '', $params['field']); } if (preg_match('/^\\/.*\\/$/', $source)) { // var_dump($params); $goParams = array_merge($params['go'], array('orderby' => $params['order'][1])); // var_dump($goParams); $nodeChilds = K_TreeQuery::crt($source)->types($params['filter'])->limit($params['limit'])->order($params['order'][0])->go($goParams); // var_dump($nodeChilds); // var_dump($nodeChilds); // $start=$nodeChilds[1]['tree_level']; // var_dump($treeBrach); // str_repeat(' ',$v['tree_level']).$v['tree_title'] $firstNode = true; foreach ($nodeChilds as $v) { if ($firstNode == true) { $startLevel = $v['tree_level']; } $firstNode = false; $title = $v[$field]; $treeIds[$title] = $v['tree_id']; // str_repeat(' ',$v['tree_level']-$start). if ($params['title'] && count($params['title'])) { $optTitle = array(); foreach ($params['title'] as $tile) { $optTitle[] = $v[$tile]; } $listOptions[0][$title] = str_repeat(' ', $v['tree_level'] - $startLevel) . implode(' - ', $optTitle); } else { $listOptions[0][$title] = str_repeat(' ', $v['tree_level'] - $startLevel) . $v['tree_title']; } } //var_dump( $listOptions[0] ); } else { $node = K_Tree::getNode($elementData); $nodesBro = K_Tree::getChilds($node['tree_pid']); foreach ($nodesBro as $v) { $title = $v[$field]; $treeIds[$title] = $v['tree_id']; $listOptions[0][$title] = $v['tree_title']; } echo "<script type=\"text/javascript\"> \n \$('#" . $source . "').off('.formsel'); \n \$('#" . $source . "').on('change.formsel',function(){selectLoad(this,'#{$listAttr['id']}','{$params['0']}','')});\n </script>"; /* if(! empty($elementData)){ $checkJs="if(v.value=='$elementData'){cheked='selected=\"selected\"}"; // $this->loadSelect[$source]=array('select'=>$listAttr['id'],'field'=>$params['0'],'opt'=>$elementData); echo "selectLoad('#".$source ."','#{$listAttr['id']}','{$params['0']}','$elementData',);"; } */ } } $form->{$type}($element->values->name . (isset($listAttr['multiple']) && $listAttr['multiple'] ? '[]' : ''), $listOptions[0], !empty($elementData) ? $elementData : $listOptions[0], $listAttr, $treeIds); break; case 'checkbox': $listOptions = self::getListOptions($element); $listAttr = array('class' => $element->values->class, 'id' => $element->values->id); if (count($listOptions[0]) > 0) { $i = 1; foreach ($listOptions[0] as $key => $value) { echo '<label>'; $form->{$type}($element->values->name . (count($listOptions[0]) > 1 ? '[]' : ''), $listOptions[1] == $i || count($listOptions[0]) == 1 && $elementData == 'on' ? true : false, $key, $listAttr); echo $key . ' ' . '</label>'; $i++; } } break; case 'radio': $listOptions = self::getListOptions($element); $listAttr = array('class' => $element->values->class, 'id' => $element->values->id); if (count($listOptions[0]) > 0) { $i = 1; foreach ($listOptions[0] as $key => $value) { echo '<label>'; $form->{$type}($element->values->name . (count($listOptions[0]) > 1 ? '[]' : ''), $listOptions[1] == $i || count($listOptions[0]) == 1 && $elementData == 'on' ? true : false, $key, $listAttr); echo $key . ' ' . '</label>'; $i++; } } // var_dump($listOptions[0]); // $form->$type($element->values->name . (''), $listOptions[0], $listOptions[1], $listAttr); break; case 'submit': $form->{$type}($element->values->label, array('class' => $element->values->class, 'id' => $element->values->id)); break; case 'reset': $form->{$type}($element->values->label, array('class' => $element->values->class, 'id' => $element->values->id)); break; case 'hidden': $form->{$type}($element->values->name, $element->values->value, array('class' => $element->values->class, 'id' => $element->values->id)); break; } }
$nodeId = (int) $this->getParam('id'); $node = K_Tree::getNode($nodeId); if ($node['tree_bloked'] == '1' || $nodeId == '1') { echo 'Этот элемент заблокирован! <script type="text/javascript"> enableTree(); $.jstree._reference(\'#tree\').set_text( $(\'#node_{$nodeId}\') ,"{$updateValues[\'tree_title\']}"); $(".node_information-{$nodeId}").find("b").text("{$newTreeLink}"); </script>'; return; } $treeTable = new K_Tree_Model(); $updateValues = array(); if (isset($_POST['tree_title']) && !empty($_POST['tree_title'])) { $updateValues['tree_title'] = $_POST['tree_title']; } if (isset($_POST['tree_name']) && !empty($_POST['tree_name'])) { $updateValues['tree_name'] = preg_replace("/[^a-z0-9,-]/i", "", $_POST['tree_name']); $updateValues['tree_title'] = preg_replace("/[\"']/i", "", $_POST['tree_title']); if (strlen($updateValues['tree_name']) < 1) { throw new Exception('Название элемента не соответствует'); } $nodeData = K_Tree::getNode($nodeId); $partsOfLink = explode('/', substr($nodeData['tree_link'], 0, -1)); $newTreeLink = $nodeData['tree_link']; if ($partsOfLink) { $partsOfLink[sizeof($partsOfLink) - 1] = $updateValues['tree_name']; $newTreeLink = implode('/', $partsOfLink) . '/'; } $query = new K_Db_Query(); $query->q('UPDATE `tree` SET `tree_link` = CONCAT(REPLACE(LEFT(tree_link, ' . strlen($nodeData['tree_link']) . '), "' . $nodeData['tree_link'] . '", "' . $newTreeLink . '"), SUBSTRING(tree_link, ' . (strlen($nodeData['tree_link']) + 1) . ')) WHERE `tree_lkey`>=' . $nodeData['tree_lkey'] . ' AND `tree_rkey`<=' . $nodeData['tree_rkey']); } $treeTable->update($updateValues, '`tree_id` = ' . $nodeId); echo <<<HTML \t\tЭлемент успешно обновлён! <script type="text/javascript">\t \t\t enableTree(); \$.jstree._reference('#tree').set_text( \$('#node_{$nodeId}') ,"{$updateValues['tree_title']}"); \t//\t\$("#tree.node_{$nodeId}").find(".title:first").text("{$updateValues['tree_title']}"); \t\t\t\$(".node_information-{$nodeId}").find("b").text("{$newTreeLink}"); </script> HTML; } public function updateseoAction() { $this->disableRender = true; $nodeId = (int) $this->getParam('id'); $data = array('tree_meta_title' => trim($_POST['title']), 'tree_meta_description' => trim($_POST['description']), 'tree_meta_keywords' => trim($_POST['keywords']), 'tree_meta_canonical' => trim($_POST['canonical'])); $treeTable = new K_Tree_Model(); $treeTable->update($data, '`tree_id` = ' . $nodeId); echo 'Сео данные успешно обновлены!
/** Выбирает ветку ноды со всей её инфой ,которая храниться в смежных таблицах типов * * */ public static function gNodes($opt, $limit = false, $parentNodeData = false) { // Этап 1 формирование настроек для выполнения // для поддержки старого упрощенного варианта if (!is_array($opt)) { $opt = array("id" => $opt, "limit" => $limit); } $opt = array_merge(array("id" => 0, "limit" => false, "offset" => 0, "types" => false, "condit" => '', 'filter' => false, "idIndex" => false, "joins" => false, "group" => false, "order" => false, "more" => array('cascade' => false, "childs" => false, "test" => false, 'meta', 'count' => false, 'orderby' => "ASC", "aliases" => false)), $opt); $rtypes = array(); $rtypesTables = array(); $rtypesAll = array(); $query = new K_Db_Query(); if (!$parentNodeData) { $parentNodeData = K_Tree::getNode($opt["id"]); } //Этап 2 выборка и формирование списка типов с которыми будем работать if (!$opt['types']) { if ($opt['more']['childs']) { /* if (is_numeric($opt["id"])){ $pid=$opt["id"]; } else{ $node=K_Tree::getNode($opt["id"]); $pid=$node['tree_id']; }*/ $q = 'SELECT DISTINCT tree_type FROM tree where tree_pid="' . $parentNodeData['tree_id'] . '" ORDER BY tree_lkey ASC limit 1'; $result = $query->q($q); } else { $q = 'SELECT DISTINCT tree_type FROM `tree` WHERE `tree_lkey`>=' . $parentNodeData['tree_lkey'] . ' AND `tree_rkey`<=' . $parentNodeData['tree_rkey'] . ' ' . ($opt['filter'] ? ' AND tree_type="' . $opt['filter'] . '"' : '') . ' ORDER BY `tree_lkey` ASC ' . ($opt["limit"] ? ' LIMIT ' . $opt["limit"] : ''); $result = $query->q($q); } $usedTypes = array(); for ($i = 0; $i < sizeof($result); $i++) { $data[$i] = $result[$i]->toArray(); if (!in_array($data[$i]['tree_type'], $usedTypes)) { $usedTypes[] = $data[$i]['tree_type']; } } // K_debug::get()->dump($usedTypes); //этап 3 выборка итемов требуемых типов $allResults = array(); $rData = array(); $i = 1; $topLevel = true; $casCadeStart = false; $casCadeIds = array(); // при каскаде убираем тип папка, он только будет мишать if ($opt['more']['cascade'] && ($usedTypes[0] = 'folder')) { array_shift($usedTypes); } } else { $usedTypes = $opt['types']; } foreach ($usedTypes as $type) { //каскадная выборка(сперва выбираються ноды верхнего порядка по типу, к ним применяються условия, потом по pid выбираються ноды следующиего уровня) $inStr = ''; if ($opt['more']['cascade'] && count($casCadeIds)) { $casCadeIdsIn = implode(',', $casCadeIds); $inStr = ' AND tr.tree_pid IN (' . $casCadeIdsIn . ')'; } if (in_array($type, $usedTypes)) { $rtypes[] = $type; $rtypesTables = '`type_' . $type . '` AS ty '; $rtypesAll = 'ty.*'; $tp = $type; //дополнительные условия для выборки $rtypesWhere = '`tr`.`tree_id`=ty.type_' . $type . '_id' . ($opt['condit'][$type] ? $opt['condit'][$type] : ''); // if ($conditions)echo 'SELECT `tr`.*, '.$rtypesAll.' FROM `tree` AS `tr`, '.$rtypesTables.' WHERE '.$rtypesWhere.' AND `tr`.`tree_lkey`>='.$parentNodeData['tree_lkey'].' AND `tr`.`tree_rkey`<='.$parentNodeData['tree_rkey'].' ORDER BY `tr`.`tree_lkey` ASC '.($limit ? ' LIMIT '.$limit : ''); // array('tour'=>array('resort'=>'to_city','hotel'=>'hotel','country'=>'country')); //array('price'=>array('pid'=>array('max'=>'price'))); $agreg = ''; $group = ''; // группировки по типу, найти минимальное, максимальное, сумму для определённого типа if ($opt['group'][$tp]) { $grp = $opt['group'][$tp]; foreach ($grp as $k => $v) { $kCell = 'type_' . $tp . '_' . $k; $group[] = " group by {$k}"; foreach ($v as $t => $y) { $agreg[] = "{$t}(" . 'ty.type_' . $tp . '_' . "{$y})"; } $agreg = ',' . implode(', ', $agreg); $group = implode(' ', $group); } } //дополнительные джойны, для каждого типа, в дальнейшем cделать их автоматическими $jJoin = ''; $jTables = ''; if ($opt['joins'][$tp]) { foreach ($opt['joins'][$tp] as $k => $v) { $kTable = 'type_' . $k; $jTablesA[] = "{$kTable}.*"; $jJoin[] = " LEFT JOIN {$kTable} ON {$kTable}.{$kTable}" . "_id=ty.type_{$tp}" . '_' . "{$v} "; } $jJoin = implode(' ', $jJoin); $jTables = ',' . implode(',', $jTablesA); } $limitStr = ''; if (!$opt['more']['count']) { $topLevel = false; } // при каскадной выборке лимит работает только для верхнего типа if ($opt['more']['cascade']) { if ($topLevel) { $limitStr = $opt['limit'] ? ' LIMIT ' . $opt['offset'] . ', ' . $opt['limit'] : ''; } } else { // при простой выборке лимит делиться на все типы по чучуть if (count($usedTypes) > 1) { $typeCount = count($usedTypes); $limitForType = floor($opt['limit'] / $typeCount); $offsetForType = floor($opt['offset'] / $typeCount); if ($topLevel) { // разницу добавим к верхнему уровню:К ПРИМЕРУ 10 разобьёться на троих так 4 3 3 $limitForType += $opt['limit'] - $limitForType * $typeCount; $offsetForType += $opt['offset'] - $offsetForType * $typeCount; } $limitStr = $limitForType ? ' LIMIT ' . $offsetForType . ', ' . $limitForType : ''; } else { if ($opt['limit']) { $limitStr = ' LIMIT ' . $opt['offset'] . ', ' . $opt['limit']; } } } // сортировка, если её нет то сортируеться по левому ключу if ($opt['order'][$tp]) { if (is_string($opt['order'][$tp])) { $opt['order'][$tp] = array($opt['order'][$tp]); } $orderArr = array(); if (is_string($opt['more']['orderby'])) { $opt['more']['orderby'] = array($opt['more']['orderby']); } $ior = 0; foreach ($opt['order'][$tp] as $v) { $orderArr[] = 'ty.' . 'type_' . $tp . '_' . $v . ' ' . $opt['more']['orderby'][$ior]; $ior++; } $orderFields = implode(',', $orderArr); $orderBY = ' ORDER BY ' . $orderFields . ' '; } else { $orderBY = ' ORDER BY `tr`.`tree_lkey` ASC '; } //основной запроc, $qv = 'SELECT' . ($limitStr ? ' SQL_CALC_FOUND_ROWS ' : '') . ' `tr`.*, ' . $rtypesAll . ' ' . $jTables . ' ' . $agreg . ' FROM `tree` AS `tr`, ' . $rtypesTables . ' ' . $jJoin . ' WHERE ' . $rtypesWhere . ' AND `tr`.`tree_lkey`>=' . $parentNodeData['tree_lkey'] . ' AND `tr`.`tree_rkey`<=' . $parentNodeData['tree_rkey'] . ' ' . $inStr . ' ' . $group . $orderBY . $limitStr; $result = $query->q($qv); if ($limitStr) { $сountResult = $query->q("SELECT FOUND_ROWS() as cItems;"); $countItems += $сountResult[0]['cItems']; } if ($opt['more']['test']) { K_debug::get()->addMessage($countItems); } if ($opt['more']['test']) { K_debug::get()->addMessage($qv); } $casCadeIds = array(); foreach ($result as $key => $value) { $result[$key] = $value->toArray(); $aResults = array(); foreach ($result[$key] as $typeField => $typeValue) { $aResults[str_replace('type_' . $type . '_', '', $typeField)] = $typeValue; // K_debug::get()->dump($key); } if ($opt['more']['aliases'] == true && $aResults['tree_type'] == 'alias') { $aliases[$aResults['tree_lkey']] = $aResults['elementid']; // var_dump( $aResults); } $allResults[$aResults['tree_lkey']] = $aResults; //каскадная выборка(сперва выбираються ноды верхнего порядка по типу, к ним применяються условия, потом по pid выбираються ноды следующиего уровня) // сохраним id нод if ($opt['more']['cascade']) { $casCadeIds[] = $aResults["tree_id"]; } $i++; } if ($opt['more']['cascade'] && !count($casCadeIds)) { break; } //$allResults = array_merge($allResults, $rData); $topLevel = false; } } //Этап 4 постобработка, получение данных в нужном нам виде ,подключение алиасов /** * @todo группировка итемов по типу и вывод в массив * * **/ //K_debug::get()->dump($rAllResults); //проверка на алиасы, если они есть выбираем все элементы по алиасам и заменяем ими алиасы // var_dump($aliases); $aliasesIdsStr = implode(',', array_unique($aliases)); if (count($aliases) && $aliasesIdsStr) { //Узнаём все типы алиасов $q = 'SELECT DISTINCT tree_type FROM tree where tree_id IN(' . implode(',', $aliases) . ')'; $aliasesTypesResult = $query->q($q); //массив таблиц из которых будем выбирать foreach ($aliasesTypesResult as $v) { $aliasesTypes[] = $v['tree_type']; $aliasesTypesTables[] = 'type_' . $v['tree_type']; $aliasesTypesTablesWhere[] = 'type_' . $v['tree_type'] . '.' . 'type_' . $v['tree_type'] . '_id = tree.tree_id'; } //массив условий для выбора типов $qv = 'SELECT * FROM tree, ' . implode(',', $aliasesTypesTables) . ' WHERE tree.tree_id IN(' . implode(',', $aliases) . ') AND ' . implode(',', $aliasesTypesTablesWhere); $aliasesResult = $query->q($qv); foreach ($aliasesResult as $v) { $aliasesResultKeyId[$v['tree_id']] = K_Cupitems::stripFieldsArr($v, 'type_' . $v['tree_type']); } //var_dump($aliasesResultKeyId); foreach ($allResults as $v) { if ($v['tree_type'] == 'alias') { $elementid = $aliases[$v['tree_lkey']]; unset($allResults[$v['tree_lkey']]['tree_type']); $aliasElementResult = array_merge($aliasesResultKeyId[$elementid], $allResults[$v['tree_lkey']]); $allResults[$v['tree_lkey']] = $aliasElementResult; //$aliasesResultKeyId[$elementid]; // array_merge($aliasesResultKeyId[$elementid],$allResults[$v['tree_lkey']]); // var_dump($aliasesResultKeyId[$elementid]); } } } //сортируем по левому ключу: if (!$opt['order']) { ksort($allResults); } $claer = true; if ($opt['group']) { // если есть группировка // нумеруем индексы по id $rrAllResults = array(); foreach ($allResults as $key => $value) { $rrAllResults[$value['tree_id']] = $value; } $allResults = $rrAllResults; // K_debug::get()->dump($allResults); $rAllResults = array(); foreach ($allResults as $key => $value) { //если была группировка по этому типу то в массиве ответа к родительским нодам прикрепляем детей в виде индекса node_childs $tp = $value['tree_type']; if ($opt['group'][$tp]) { $tId = $value['tree_pid']; // K_debug::get()->dump($tId); $allResults[$tId]['node_childs'][] = $value['tree_id']; // K_debug::get()->dump($rAllResults[$tId]['node_childs']); } } $claer = false; } //если есть необходимость переназвать иднексы называем их по одному из полей ноды if ($opt['idIndex']) { $allResults; foreach ($allResults as $value) { if ($opt['idIndex']) { $tId = $value['tree_id']; if (is_string($idIndex)) { $tId = $value[$opt['idIndex']]; } $rAllResults[$tId] = $value; } } $claer = false; } // если всё чисто то просто пронумеруем все элементы выборки по порядку if ($claer) { $i = 0; foreach ($allResults as $value) { $rAllResults[$i] = $value; $i++; } } if ($opt['more']['test']) { K_debug::get()->dump($rAllResults); } if ($opt['more']['meta']) { return array($rAllResults, $parentNodeData); } if ($opt['more']['count']) { return array($rAllResults, $countItems); } return $rAllResults; }