File indexing completed on 2025-02-09 07:14:34

0001 <?php
0002 
0003 /**
0004  *  ocs-webserver
0005  *
0006  *  Copyright 2016 by pling GmbH.
0007  *
0008  *    This file is part of ocs-webserver.
0009  *
0010  *    This program is free software: you can redistribute it and/or modify
0011  *    it under the terms of the GNU Affero General Public License as
0012  *    published by the Free Software Foundation, either version 3 of the
0013  *    License, or (at your option) any later version.
0014  *
0015  *    This program is distributed in the hope that it will be useful,
0016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018  *    GNU Affero General Public License for more details.
0019  *
0020  *    You should have received a copy of the GNU Affero General Public License
0021  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022  **/
0023 class Default_Model_DbTable_ProjectCategory extends Local_Model_Table
0024 {
0025 
0026     const CATEGORY_ACTIVE = 1;
0027     const CATEGORY_INACTIVE = 0;
0028     const CATEGORY_NOT_DELETED = 0;
0029     const CATEGORY_DELETED = 1;
0030 
0031     const ORDERED_TITLE = 'title';
0032     const ORDERED_ID = 'project_category_id';
0033     const ORDERED_HIERARCHIC = 'lft';
0034 
0035     protected $_keyColumnsForRow = array('project_category_id');
0036 
0037     protected $_key = 'project_category_id';
0038 
0039     /**
0040      * @var string
0041      */
0042     protected $_name = "project_category";
0043     /**
0044      * @var array
0045      */
0046     protected $_dependentTables = array('Default_Model_DbTable_Project');
0047     /**
0048      * @var array
0049      */
0050     protected $_referenceMap = array(
0051         'Category' => array(
0052             'columns'       => 'project_category_id',
0053             'refTableClass' => 'Default_Model_Project',
0054             'refColumns'    => 'project_category_id'
0055         )
0056     );
0057     /** @var  Zend_Cache_Core */
0058     protected $cache;
0059 
0060     /**
0061      * @inheritDoc
0062      */
0063     public function init()
0064     {
0065         parent::init(); // TODO: Change the autogenerated stub
0066         $this->cache = Zend_Registry::get('cache');
0067     }
0068 
0069     /**
0070      * @return array
0071      * @deprecated
0072      */
0073     public function getSelectList()
0074     {
0075         $selectArr =
0076             $this->_db->fetchAll('SELECT `project_category_id`, `title` FROM `project_category` WHERE `is_active`=1 AND `is_deleted`=0 ORDER BY `orderPos`');
0077 
0078         $arrayModified = array();
0079 
0080         $arrayModified[0] = "ProjectAddFormCatSelect";
0081         foreach ($selectArr as $item) {
0082             $arrayModified[$item['project_category_id']] = stripslashes($item['title']);
0083         }
0084 
0085         return $arrayModified;
0086     }
0087 
0088     /**
0089      * @return array
0090      * @deprecated
0091      */
0092     public function getInternSelectList()
0093     {
0094         $selectArr =
0095             $this->_db->fetchAll('SELECT `project_category_id`, `title` FROM `project_category` WHERE `is_deleted`=0 ORDER BY `orderPos`');
0096 
0097         $arrayModified = array();
0098 
0099         $arrayModified[0] = "ProjectAddFormCatSelect";
0100         foreach ($selectArr as $item) {
0101             $arrayModified[$item['project_category_id']] = stripslashes($item['title']);
0102         }
0103 
0104         return $arrayModified;
0105     }
0106 
0107     /**
0108      * @param $status
0109      * @param $id
0110      *
0111      */
0112     public function setStatus($status, $id)
0113     {
0114         $updateValues = array(
0115             'is_active'  => $status,
0116             'changed_at' => new Zend_Db_Expr('Now()')
0117         );
0118 
0119         $this->update($updateValues, 'project_category_id=' . $id);
0120     }
0121 
0122     /**
0123      * @param $id
0124      *
0125      */
0126     public function setDelete($id)
0127     {
0128         $updateValues = array(
0129             'is_active'  => 0,
0130             'is_deleted' => 1,
0131             'deleted_at' => new Zend_Db_Expr('Now()')
0132         );
0133 
0134         $this->update($updateValues, 'project_category_id=' . $id);
0135     }
0136 
0137     /**
0138      * @return Zend_Db_Table_Rowset_Abstract
0139      * @throws Zend_Cache_Exception
0140      * @deprecated
0141      */
0142     public function fetchAllActive()
0143     {
0144         $cache = $this->cache;
0145         $cacheName = __FUNCTION__;
0146         if (!($categories = $cache->load($cacheName))) {
0147             $q = $this->select()->where('is_active = ?', 1)->where('is_deleted = ?', 0)->order('orderPos');
0148             $categories = $this->fetchAll($q);
0149             $cache->save($categories, $cacheName);
0150         }
0151 
0152         return $categories;
0153     }
0154 
0155     /**
0156      * @param int|array $nodeId
0157      *
0158      * @return array
0159      * @throws Zend_Cache_Exception
0160      * @throws Zend_Db_Statement_Exception
0161      */
0162     public function fetchActive($nodeId)
0163     {
0164         $str = is_array($nodeId) ? implode(',', $nodeId) : $nodeId;
0165         /** @var Zend_Cache_Core $cache */
0166         $cache = $this->cache;
0167         $cacheName = __FUNCTION__ . '_' . md5($str);
0168 
0169         if (false === ($active = $cache->load($cacheName))) {
0170             $inQuery = '?';
0171             if (is_array($nodeId)) {
0172                 $inQuery = implode(',', array_fill(0, count($nodeId), '?'));
0173             }
0174 
0175             $sql = "SELECT *,
0176                   (SELECT
0177                       `project_category_id`
0178                        FROM
0179                          `project_category` AS `t2`
0180                        WHERE
0181                          `t2`.`lft`  < `node`.`lft` AND
0182                          `t2`.`rgt` > `node`.`rgt`
0183                          AND `t2`.`is_deleted` = 0
0184                        ORDER BY
0185                          `t2`.`rgt`-`node`.`rgt` ASC
0186                        LIMIT 1) AS `parent`
0187                 FROM {$this->_name} as node
0188                 WHERE project_category_id IN ($inQuery)
0189                 AND is_active = 1
0190                 ";
0191 
0192             $active = $this->_db->query($sql, $nodeId)->fetchAll();
0193             if (count($active) == 0) {
0194                 $active = array();
0195             }
0196             $cache->save($active, $cacheName, array(), 3600);
0197         }
0198 
0199         return $active;
0200     }
0201 
0202     /**
0203      * @param int|array $nodeId
0204      *
0205      * @return array
0206      * @throws Zend_Db_Statement_Exception
0207      */
0208     public function fetchActiveOrder($nodeId)
0209     {
0210         $inQuery = '?';
0211         if (is_array($nodeId)) {
0212             $inQuery = implode(',', array_fill(0, count($nodeId), '?'));
0213         }
0214 
0215         $sql = "SELECT *,
0216                   (SELECT
0217                       `project_category_id`
0218                        FROM
0219                          `project_category` AS `t2`
0220                        WHERE
0221                          `t2`.`lft`  < `node`.`lft` AND
0222                          `t2`.`rgt` > `node`.`rgt`
0223                          AND `t2`.`is_deleted` = 0
0224                        ORDER BY
0225                          `t2`.`rgt`-`node`.`rgt`ASC
0226                        LIMIT
0227                          1) AS `parent`
0228                 FROM {$this->_name} as node
0229                 WHERE project_category_id IN ($inQuery)
0230                 AND is_active = 1
0231                 ";
0232 
0233         $active = $this->_db->query($sql, $nodeId)->fetchAll();
0234         if (count($active)) {
0235             return $active;
0236         } else {
0237             return array();
0238         }
0239     }
0240 
0241     /* ------------------------ */
0242     /* New Nested Set Functions */
0243     /* ------------------------ */
0244 
0245     public function setCategoryDeleted($id, $updateChildren = true)
0246     {
0247         $node = $this->findCategory($id);
0248         if (count($node->toArray()) == 0) {
0249             return false;
0250         }
0251 
0252         $this->_db->beginTransaction();
0253         try {
0254             $this->_db->query("UPDATE {$this->_name} SET is_active = 0, is_deleted = 1, deleted_at = :del_date WHERE project_category_id = :cat_id;",
0255                 array('cat_id' => $id, 'del_date'=>new Zend_Db_Expr('Now()')));
0256             if ($updateChildren) {
0257                 $this->_db->query("UPDATE {$this->_name} SET is_active = 0, is_deleted = 1, deleted_at = :del_date WHERE lft > :parent_lft AND rgt < :parent_rgt;",
0258                     array('del_date'=>new Zend_Db_Expr('Now()'), 'parent_lft' => $node->lft, 'parent_rgt' => $node->rgt));
0259             }
0260             $this->_db->commit();
0261         } catch (Exception $e) {
0262             $this->_db->rollBack();
0263             Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . print_r($e, true));
0264         }
0265 
0266         return $node;
0267     }
0268 
0269     /**
0270      * @param $title
0271      *
0272      * @return null|Zend_Db_Table_Row_Abstract
0273      * @throws Zend_Exception
0274      */
0275     public function appendNewElement($title)
0276     {
0277         $root = $this->fetchRoot();
0278 
0279         $data['rgt'] = $root->rgt - 1;
0280         $data['title'] = $title;
0281 
0282         return $this->addNewElement($data);
0283     }
0284 
0285     /**
0286      * @return null|Zend_Db_Table_Row_Abstract
0287      */
0288     public function fetchRoot()
0289     {
0290         return $this->fetchRow('`lft` = 0');
0291     }
0292 
0293     /**
0294      * @param array $data
0295      *
0296      * @return null|Zend_Db_Table_Row_Abstract
0297      * @throws Zend_Exception
0298      */
0299     public function addNewElement($data)
0300     {
0301         $this->_db->beginTransaction();
0302         try {
0303             $this->_db->query("UPDATE {$this->_name} SET rgt = rgt + 2 WHERE rgt > :param_right;",
0304                 array('param_right' => $data['rgt']));
0305             $this->_db->query("UPDATE {$this->_name} SET lft = lft + 2 WHERE lft > :param_right;",
0306                 array('param_right' => $data['rgt']));
0307             $this->_db->query("
0308                         INSERT INTO project_category (`lft`, `rgt`, `title`, `is_active`, `name_legacy`, `xdg_type`, `dl_pling_factor`, `show_description`, `source_required`) 
0309                         VALUES (:param_right + 1, :param_right + 2, :param_title, :param_status, :param_legacy, :param_xgd, :param_pling, :param_show_desc, :param_source);",
0310                 array(
0311                     'param_right'  => $data['rgt'],
0312                     'param_title'  => $data['title'],
0313                     'param_status' => $data['is_active'],
0314                     'param_legacy' => $data['name_legacy'],
0315                     'param_xgd'    => $data['xdg_type'],
0316                     'param_show_desc' => $data['show_description'],
0317                     'param_source' => $data['source_required'],
0318                     'param_pling' => $data['dl_pling_factor']
0319                 ));
0320             $this->_db->commit();
0321         } catch (Exception $e) {
0322             $this->_db->rollBack();
0323             Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . print_r($e, true));
0324         }
0325 
0326         return $this->fetchRow('lft = ' . ($data['rgt'] + 1));
0327     }
0328 
0329     /**
0330      * @param $cat_id
0331      *
0332      * @return array
0333      */
0334     public function fetchTreeForJTable($cat_id)
0335     {
0336         $resultRows = $this->fetchTree(false, true, 5);
0337 
0338         $resultForSelect = array();
0339         foreach ($resultRows as $row) {
0340             if (($row['project_category_id'] == $cat_id) OR ($row['parent'] == $cat_id)) {
0341                 continue;
0342             }
0343             $resultForSelect[] = array('DisplayText' => $row['title_show'], 'Value' => $row['project_category_id']);
0344         }
0345 
0346         return $resultForSelect;
0347     }
0348 
0349     /**
0350      * @param bool $isActive
0351      * @param bool $withRoot
0352      * @param int  $depth
0353      *
0354      * @return array
0355      * @internal param int $pageSize
0356      * @internal param int $startIndex
0357      * @internal param bool $clearCache
0358      */
0359     public function fetchTree(
0360         $isActive = false,
0361         $withRoot = true,
0362         $depth = null
0363     ) {
0364         $sqlActive = $isActive == true ? " parent_active = 1 AND pc.is_active = 1" : '';
0365         $sqlRoot = $withRoot == true ? "(pc.lft BETWEEN pc2.lft AND pc2.rgt)" : "(pc.lft BETWEEN pc2.lft AND pc2.rgt) AND pc2.lft > 0";
0366         $sqlDepth = is_null($depth) == true ? '' : " AND depth <= " . (int)$depth;
0367         $sqlHaving = $sqlActive || $sqlDepth ? "HAVING {$sqlActive} {$sqlDepth}" : '';
0368         $sql = "
0369             SELECT
0370                 `pc`.`project_category_id`,
0371                 `pc`.`lft`,
0372                 `pc`.`rgt`,
0373                 `pc`.`title`,
0374                 `pc`.`name_legacy`,
0375                 `pc`.`is_active`,
0376                 `pc`.`orderPos`,
0377                 `pc`.`xdg_type`,
0378                 `pc`.`dl_pling_factor`,
0379                 `pc`.`show_description`,
0380                 `pc`.`source_required`,
0381                 MIN(`pc2`.`is_active`)                                       AS `parent_active`,
0382                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), `pc`.`title`) AS `title_show`,
0383                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), IF(LENGTH(TRIM(`pc`.`name_legacy`))>0,`pc`.`name_legacy`,`pc`.`title`)) AS `title_legacy`,
0384                 count(`pc`.`lft`) - 1                                        AS `depth`,
0385                 GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`)   AS `ancestor_id_path`,
0386                 GROUP_CONCAT(`pc2`.`title` ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path`,
0387                 GROUP_CONCAT(IF(LENGTH(TRIM(`pc2`.`name_legacy`))>0,`pc2`.`name_legacy`,`pc2`.`title`) ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path_legacy`
0388               FROM
0389                   `project_category` AS `pc`
0390               JOIN
0391                     `project_category` AS `pc2` ON {$sqlRoot}
0392               GROUP BY pc.lft
0393               {$sqlHaving}
0394               ORDER BY pc.lft
0395 
0396         ";
0397 
0398         $tree = $this->_db->fetchAll($sql);
0399 
0400         return $tree;
0401     }
0402 
0403     /**
0404      * @param bool $isActive
0405      * @param bool $withRoot
0406      * @param int  $depth
0407      *
0408      * @return array
0409      * @internal param int $pageSize
0410      * @internal param int $startIndex
0411      * @internal param bool $clearCache
0412      */
0413     public function fetchTreeWithParentId(
0414         $isActive = true,
0415         $depth = null
0416     ) {
0417         $sqlActive = $isActive == true ? " parent_active = 1 AND pc.is_active = 1" : '';
0418         $sqlDepth = is_null($depth) == true ? '' : " AND depth <= " . (int)$depth;
0419         $sqlHaving = $sqlActive || $sqlDepth ? "HAVING {$sqlActive} {$sqlDepth}" : '';
0420         $sql = "
0421             SELECT
0422                 `pc`.`project_category_id`,
0423                 `pc`.`lft`,
0424                 `pc`.`rgt`,
0425                 `pc`.`title`,
0426                 `pc`.`name_legacy`,
0427                 `pc`.`is_active`,
0428                 `pc`.`orderPos`,
0429                 `pc`.`xdg_type`,
0430                 `pc`.`dl_pling_factor`,
0431                 `pc`.`mv_pling_factor`,
0432                 `pc`.`show_description`,
0433                 `pc`.`source_required`,
0434                 `blt`.`name` as `browse_list_type_name`,
0435                 `pc`.`browse_list_type`,
0436                 `pc`.`tag_rating`,
0437                 `tg`.`group_name` as `tag_rating_name`,
0438                 MIN(`pc2`.`is_active`)                                       AS `parent_active`,
0439                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), `pc`.`title`) AS `title_show`,
0440                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), IF(LENGTH(TRIM(`pc`.`name_legacy`))>0,`pc`.`name_legacy`,`pc`.`title`)) AS `title_legacy`,
0441                 count(`pc`.`lft`) - 1                                        AS `depth`,
0442                 GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`)   AS `ancestor_id_path`,
0443                 GROUP_CONCAT(`pc2`.`title` ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path`,
0444                 GROUP_CONCAT(IF(LENGTH(TRIM(`pc2`.`name_legacy`))>0,`pc2`.`name_legacy`,`pc2`.`title`) ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path_legacy`,
0445                 SUBSTRING_INDEX( GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`), ',', -1) AS `parent`
0446               FROM
0447                   `project_category` AS `pc`
0448               JOIN
0449                     `project_category` AS `pc2` ON (`pc`.`lft` BETWEEN `pc2`.`lft` AND `pc2`.`rgt`) AND `pc2`.`project_category_id` <> `pc`.`project_category_id`
0450               LEFT JOIN 
0451                     `browse_list_types` AS `blt`  ON `pc`.`browse_list_type` = `blt`.`browse_list_type_id`
0452             LEFT JOIN 
0453             `tag_group` AS `tg`  ON `pc`.`tag_rating` = `tg`.`group_id`
0454               GROUP BY `pc`.`lft`
0455               {$sqlHaving}
0456               ORDER BY pc.lft
0457 
0458         ";
0459 
0460         $tree = $this->_db->fetchAll($sql);
0461 
0462         return $tree;
0463     }
0464 
0465 
0466     /**
0467      * @param bool $isActive
0468      * @param bool $withRoot
0469      * @param int  $depth
0470      *
0471      * @return array
0472      * @internal param int $pageSize
0473      * @internal param int $startIndex
0474      * @internal param bool $clearCache
0475      */
0476     public function fetchTreeWithParentIdAndTags(
0477         $isActive = true,
0478         $depth = null
0479     ) {
0480         $sqlActive = $isActive == true ? " parent_active = 1 AND pc.is_active = 1" : '';
0481         $sqlDepth = is_null($depth) == true ? '' : " AND depth <= " . (int)$depth;
0482         $sqlHaving = $sqlActive || $sqlDepth ? "HAVING {$sqlActive} {$sqlDepth}" : '';
0483         $sql = "
0484               SELECT
0485                 `pc`.`project_category_id`,
0486                 `pc`.`lft`,
0487                 `pc`.`rgt`,
0488                 `pc`.`title`,
0489                 `pc`.`name_legacy`,
0490                 `pc`.`is_active`,
0491                 `pc`.`orderPos`,
0492                 `pc`.`xdg_type`,
0493                 `pc`.`dl_pling_factor`,
0494                 `pc`.`show_description`,
0495                 `pc`.`source_required`,
0496                 MIN(`pc2`.`is_active`)                                       AS `parent_active`,
0497                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), `pc`.`title`) AS `title_show`,
0498                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), IF(LENGTH(TRIM(`pc`.`name_legacy`))>0,`pc`.`name_legacy`,`pc`.`title`)) AS `title_legacy`,
0499                 count(`pc`.`lft`) - 1                                        AS `depth`,
0500                 GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`)   AS `ancestor_id_path`,
0501                 GROUP_CONCAT(`pc2`.`title` ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path`,
0502                 GROUP_CONCAT(IF(LENGTH(TRIM(`pc2`.`name_legacy`))>0,`pc2`.`name_legacy`,`pc2`.`title`) ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path_legacy`,
0503                 SUBSTRING_INDEX( GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`), ',', -1) AS `parent`,
0504                 (SELECT GROUP_CONCAT(`tag`.`tag_name`)
0505                 FROM `category_tag`,`tag`            
0506                 WHERE `tag`.`tag_id` = `category_tag`.`tag_id` AND `category_tag`.`category_id` = `pc`.`project_category_id`        
0507                 GROUP BY `category_tag`.`category_id`) AS `tags_name`,
0508                 (SELECT GROUP_CONCAT(`tag`.`tag_id`)
0509                 FROM `category_tag`,`tag`            
0510                 WHERE `tag`.`tag_id` = `category_tag`.`tag_id` AND `category_tag`.`category_id` = `pc`.`project_category_id`        
0511                 GROUP BY `category_tag`.`category_id`) AS `tags_id`
0512               FROM
0513                   `project_category` AS `pc`
0514               JOIN
0515                     `project_category` AS `pc2` ON (`pc`.`lft` BETWEEN `pc2`.`lft` AND `pc2`.`rgt`) AND `pc2`.`project_category_id` <> `pc`.`project_category_id`
0516               GROUP BY `pc`.`lft`
0517               {$sqlHaving}
0518               ORDER BY pc.lft
0519 
0520         ";
0521 
0522         $tree = $this->_db->fetchAll($sql);
0523 
0524         return $tree;
0525     }
0526     
0527     
0528     /**
0529      * @param bool $isActive
0530      * @param bool $withRoot
0531      * @param int  $depth
0532      *
0533      * @return array
0534      * @internal param int $pageSize
0535      * @internal param int $startIndex
0536      * @internal param bool $clearCache
0537      */
0538     public function fetchTreeWithParentIdAndTagGroups(
0539         $isActive = true,
0540         $depth = null
0541     ) {
0542         $sqlActive = $isActive == true ? " parent_active = 1 AND pc.is_active = 1" : '';
0543         $sqlDepth = is_null($depth) == true ? '' : " AND depth <= " . (int)$depth;
0544         $sqlHaving = $sqlActive || $sqlDepth ? "HAVING {$sqlActive} {$sqlDepth}" : '';
0545         $sql = "
0546               SELECT
0547                 `pc`.`project_category_id`,
0548                 `pc`.`lft`,
0549                 `pc`.`rgt`,
0550                 `pc`.`title`,
0551                 `pc`.`name_legacy`,
0552                 `pc`.`is_active`,
0553                 `pc`.`orderPos`,
0554                 `pc`.`xdg_type`,
0555                 `pc`.`dl_pling_factor`,
0556                 `pc`.`show_description`,
0557                 `pc`.`source_required`,
0558                 MIN(`pc2`.`is_active`)                                       AS `parent_active`,
0559                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), `pc`.`title`) AS `title_show`,
0560                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), IF(LENGTH(TRIM(`pc`.`name_legacy`))>0,`pc`.`name_legacy`,`pc`.`title`)) AS `title_legacy`,
0561                 count(`pc`.`lft`) - 1                                        AS `depth`,
0562                 GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`)   AS `ancestor_id_path`,
0563                 GROUP_CONCAT(`pc2`.`title` ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path`,
0564                 GROUP_CONCAT(IF(LENGTH(TRIM(`pc2`.`name_legacy`))>0,`pc2`.`name_legacy`,`pc2`.`title`) ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path_legacy`,
0565                 SUBSTRING_INDEX( GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`), ',', -1) AS `parent`,
0566                 (SELECT GROUP_CONCAT(`tag_group`.`group_name`)
0567                 FROM `category_tag_group`,`tag_group`            
0568                 WHERE `tag_group`.`group_id` = `category_tag_group`.`tag_group_id` AND `category_tag_group`.`category_id` = `pc`.`project_category_id`        
0569                 GROUP BY `category_tag_group`.`category_id`) AS `tag_group_name`,
0570                 (SELECT GROUP_CONCAT(`tag_group`.`group_id`)
0571                 FROM `category_tag_group`,`tag_group`            
0572                 WHERE `tag_group`.`group_id` = `category_tag_group`.`tag_group_id` AND `category_tag_group`.`category_id` = `pc`.`project_category_id`        
0573                 GROUP BY `category_tag_group`.`category_id`) AS `tag_group_id`
0574               FROM
0575                   `project_category` AS `pc`
0576               JOIN
0577                     `project_category` AS `pc2` ON (`pc`.`lft` BETWEEN `pc2`.`lft` AND `pc2`.`rgt`) AND `pc2`.`project_category_id` <> `pc`.`project_category_id`
0578               GROUP BY `pc`.`lft`
0579               {$sqlHaving}
0580               ORDER BY pc.lft
0581 
0582         ";
0583 
0584         $tree = $this->_db->fetchAll($sql);
0585 
0586         return $tree;
0587     }
0588     
0589     
0590     /**
0591      * @param bool $isActive
0592      * @param bool $withRoot
0593      * @param int  $depth
0594      *
0595      * @return array
0596      * @internal param int $pageSize
0597      * @internal param int $startIndex
0598      * @internal param bool $clearCache
0599      */
0600     public function fetchTreeWithParentIdAndSections(
0601         $isActive = true,
0602         $depth = null
0603     ) {
0604         
0605         $sqlActive = $isActive == true ? " parent_active = 1 AND pc.is_active = 1" : '';
0606         $sqlDepth = is_null($depth) == true ? '' : " AND depth <= " . (int)$depth;
0607         $sqlHaving = $sqlActive || $sqlDepth ? "HAVING {$sqlActive} {$sqlDepth}" : '';
0608         $sql = "
0609               SELECT
0610                 `pc`.`project_category_id`,
0611                 `pc`.`lft`,
0612                 `pc`.`rgt`,
0613                 `pc`.`title`,
0614                 `pc`.`name_legacy`,
0615                 `pc`.`is_active`,
0616                 `pc`.`orderPos`,
0617                 `pc`.`xdg_type`,
0618                 `pc`.`dl_pling_factor`,
0619                 `pc`.`show_description`,
0620                 `pc`.`source_required`,
0621                 MIN(`pc2`.`is_active`)                                       AS `parent_active`,
0622                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), `pc`.`title`) AS `title_show`,
0623                 concat(repeat('&nbsp;&nbsp;',count(`pc`.`lft`) - 1), IF(LENGTH(TRIM(`pc`.`name_legacy`))>0,`pc`.`name_legacy`,`pc`.`title`)) AS `title_legacy`,
0624                 count(`pc`.`lft`) - 1                                        AS `depth`,
0625                 GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`)   AS `ancestor_id_path`,
0626                 GROUP_CONCAT(`pc2`.`title` ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path`,
0627                 GROUP_CONCAT(IF(LENGTH(TRIM(`pc2`.`name_legacy`))>0,`pc2`.`name_legacy`,`pc2`.`title`) ORDER BY `pc2`.`lft` SEPARATOR ' | ') AS `ancestor_path_legacy`,
0628                 SUBSTRING_INDEX( GROUP_CONCAT(`pc2`.`project_category_id` ORDER BY `pc2`.`lft`), ',', -1) AS `parent`,
0629                 (SELECT `section`.name
0630                 FROM `section_category`, `section`
0631                 WHERE `section`.section_id = `section_category`.section_id and `section_category`.`project_category_id` = `pc`.`project_category_id`) AS `section_name`,
0632                 (SELECT `section`.section_id
0633                 FROM `section_category`, `section`
0634            WHERE `section`.section_id = `section_category`.section_id and `section_category`.`project_category_id` = `pc`.`project_category_id`) AS `section_id`
0635               FROM
0636                   `project_category` AS `pc`
0637               JOIN
0638                     `project_category` AS `pc2` ON (`pc`.`lft` BETWEEN `pc2`.`lft` AND `pc2`.`rgt`) AND `pc2`.`project_category_id` <> `pc`.`project_category_id`
0639               GROUP BY `pc`.`lft`
0640               {$sqlHaving}
0641               ORDER BY pc.lft
0642 
0643         ";
0644 
0645         $tree = $this->_db->fetchAll($sql);
0646 
0647         return $tree;
0648     }
0649 
0650 
0651     /**
0652      * @param $cat_id
0653      *
0654      * @return array
0655      */
0656     public function fetchTreeForJTableStores($cat_id)
0657     {
0658         $sql = "
0659                 SELECT
0660                 pc.project_category_id,
0661                 pc.lft,
0662                 pc.rgt,
0663                 pc.title,
0664                 pc.name_legacy,
0665                 pc.is_active,
0666                 pc.orderPos,
0667                 pc.xdg_type,
0668                 pc.dl_pling_factor,
0669                 pc.show_description,
0670                 pc.source_required,
0671                 MIN(pc2.is_active)                                       AS parent_active,
0672                 concat(repeat('&nbsp;&nbsp;',count(pc.lft) - 1), pc.title) AS title_show,
0673                 concat(repeat('&nbsp;&nbsp;',count(pc.lft) - 1), IF(LENGTH(TRIM(pc.name_legacy))>0,pc.name_legacy,pc.title)) AS title_legacy,
0674                 count(pc.lft) - 1                                        AS depth,
0675                 GROUP_CONCAT(pc2.project_category_id ORDER BY pc2.lft)   AS ancestor_id_path,
0676                 GROUP_CONCAT(pc2.title ORDER BY pc2.lft SEPARATOR ' | ') AS ancestor_path,
0677                 GROUP_CONCAT(IF(LENGTH(TRIM(pc2.name_legacy))>0,pc2.name_legacy,pc2.title) ORDER BY pc2.lft SEPARATOR ' | ') AS ancestor_path_legacy,
0678                 SUBSTRING_INDEX( GROUP_CONCAT(pc2.project_category_id ORDER BY pc2.lft), ',', -1) AS parent
0679               FROM
0680                   project_category AS pc
0681               JOIN
0682                     project_category AS pc2 ON (pc.lft BETWEEN pc2.lft AND pc2.rgt) AND (IF(pc.project_category_id <> 34,pc2.project_category_id <> pc.project_category_id,true))
0683               GROUP BY pc.lft
0684               HAVING parent_active = 1 AND pc.is_active = 1
0685               ORDER BY pc.lft
0686         ";
0687         $resultRows = $this->_db->fetchAll($sql);
0688 
0689         $resultForSelect = array();
0690         foreach ($resultRows as $row) {
0691             if (($row['project_category_id'] == $cat_id) OR ($row['parent'] == $cat_id)) {
0692                 continue;
0693             }
0694             $resultForSelect[] = array('DisplayText' => $row['title_show'], 'Value' => $row['project_category_id']);
0695         }
0696 
0697         return $resultForSelect;
0698     }
0699     
0700     /**
0701      * @param $cat_id
0702      *
0703      * @return array
0704      */
0705     public function fetchTreeForJTableSection($cat_id)
0706     {
0707         $sql = "
0708                 SELECT
0709                 pc.project_category_id,
0710                 pc.lft,
0711                 pc.rgt,
0712                 pc.title,
0713                 pc.name_legacy,
0714                 pc.is_active,
0715                 pc.orderPos,
0716                 pc.xdg_type,
0717                 pc.dl_pling_factor,
0718                 pc.show_description,
0719                 pc.source_required,
0720                 MIN(pc2.is_active)                                       AS parent_active,
0721                 concat(repeat('&nbsp;&nbsp;',count(pc.lft) - 1), pc.title) AS title_show,
0722                 concat(repeat('&nbsp;&nbsp;',count(pc.lft) - 1), IF(LENGTH(TRIM(pc.name_legacy))>0,pc.name_legacy,pc.title)) AS title_legacy,
0723                 count(pc.lft) - 1                                        AS depth,
0724                 GROUP_CONCAT(pc2.project_category_id ORDER BY pc2.lft)   AS ancestor_id_path,
0725                 GROUP_CONCAT(pc2.title ORDER BY pc2.lft SEPARATOR ' | ') AS ancestor_path,
0726                 GROUP_CONCAT(IF(LENGTH(TRIM(pc2.name_legacy))>0,pc2.name_legacy,pc2.title) ORDER BY pc2.lft SEPARATOR ' | ') AS ancestor_path_legacy,
0727                 SUBSTRING_INDEX( GROUP_CONCAT(pc2.project_category_id ORDER BY pc2.lft), ',', -1) AS parent
0728               FROM
0729                   project_category AS pc
0730               JOIN
0731                     project_category AS pc2 ON (pc.lft BETWEEN pc2.lft AND pc2.rgt) AND (IF(pc.project_category_id <> 34,pc2.project_category_id <> pc.project_category_id,true))
0732               GROUP BY pc.lft
0733               HAVING parent_active = 1 AND pc.is_active = 1
0734               ORDER BY pc.lft
0735         ";
0736         $resultRows = $this->_db->fetchAll($sql);
0737 
0738         $resultForSelect = array();
0739         foreach ($resultRows as $row) {
0740             if (($row['project_category_id'] == $cat_id) OR ($row['parent'] == $cat_id)) {
0741                 continue;
0742             }
0743             $resultForSelect[] = array('DisplayText' => $row['title_show'], 'Value' => $row['project_category_id']);
0744         }
0745 
0746         return $resultForSelect;
0747     }
0748 
0749     /**
0750      * @param $cat_id
0751      *
0752      * @return array
0753      */
0754     public function fetchTreeForCategoryStores($cat_id)
0755     {
0756         $sql = "
0757                 SELECT
0758                 pc.project_category_id,
0759                 pc.lft,
0760                 pc.rgt,
0761                 pc.title,
0762                 pc.is_active,
0763                 MIN(pc2.is_active)                                       AS parent_active,
0764                 count(pc.lft) - 1                                        AS depth,
0765                 SUBSTRING_INDEX( GROUP_CONCAT(pc2.project_category_id ORDER BY pc2.lft), ',', -1) AS parent
0766               FROM
0767                   project_category AS pc
0768               JOIN
0769                   project_category AS pc2 ON (pc.lft BETWEEN pc2.lft AND pc2.rgt) AND (IF(pc.project_category_id <> 34,pc2.project_category_id <> pc.project_category_id,true))
0770               GROUP BY pc.lft
0771               HAVING parent_active = 1 AND pc.is_active = 1
0772               ORDER BY pc.lft
0773         ";
0774         $resultRows = $this->_db->fetchAll($sql);
0775 
0776         $resultForSelect = array();
0777         foreach ($resultRows as $row) {
0778             if (($row['project_category_id'] == $cat_id) OR ($row['parent'] == $cat_id)) {
0779                 continue;
0780             }
0781             $resultForSelect[] = array('DisplayText' => $row['title'], 'Value' => $row['project_category_id']);
0782         }
0783 
0784         return $resultForSelect;
0785     }
0786 
0787     /**
0788      * @param array $node
0789      * @param int   $newLeftPosition
0790      *
0791      * @return bool
0792      * @throws Zend_Exception
0793      * @deprecated use moveTo instead
0794      */
0795     public function moveElement($node, $newLeftPosition)
0796     {
0797 
0798         $space = $node['rgt'] - $node['lft'] + 1;
0799         $distance = $newLeftPosition - $node['lft'];
0800         $srcPosition = $node['lft'];
0801 
0802         //for backwards movement, we have to fix some values
0803         if ($distance < 0) {
0804             $distance -= $space;
0805             $srcPosition += $space;
0806         }
0807 
0808         $this->_db->beginTransaction();
0809 
0810         try {
0811             // create space for subtree
0812             $this->_db->query("UPDATE {$this->_name} SET rgt = rgt + :space WHERE rgt >= :newLeftPosition;",
0813                 array('space' => $space, 'newLeftPosition' => $newLeftPosition));
0814             $this->_db->query("UPDATE {$this->_name} SET lft = lft + :space WHERE lft >= :newLeftPosition;",
0815                 array('space' => $space, 'newLeftPosition' => $newLeftPosition));
0816 
0817             // move tree
0818             $this->_db->query("UPDATE {$this->_name} SET lft = lft + :distance, rgt = rgt + :distance WHERE lft >= :srcPosition AND rgt < :srcPosition + :space;",
0819                 array('distance' => $distance, 'srcPosition' => $srcPosition, 'space' => $space));
0820 
0821             // remove old space
0822             $this->_db->query("UPDATE {$this->_name} SET rgt = rgt - :space WHERE rgt > :srcPosition;",
0823                 array('space' => $space, 'srcPosition' => $srcPosition));
0824             $this->_db->query("UPDATE {$this->_name} SET lft = lft - :space WHERE lft >= :srcPosition;",
0825                 array('space' => $space, 'srcPosition' => $srcPosition));
0826 
0827             // move it
0828             $this->_db->commit();
0829         } catch (Exception $e) {
0830             $this->_db->rollBack();
0831             Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . print_r($e, true));
0832 
0833             return false;
0834         }
0835 
0836         return true;
0837     }
0838 
0839     public function findAncestor($data)
0840     {
0841         $resultRow = $this->fetchRow("rgt = {$data['lft']} - 1");
0842 
0843         if (($resultRow->rgt - $resultRow->lft) > 1) {
0844             $resultRow = $this->fetchRow("lft = {$resultRow->lft} - 2");
0845         }
0846 
0847         return $resultRow;
0848     }
0849 
0850     /**
0851      * @param $data
0852      *
0853      * @return array|null
0854      * @throws Zend_Db_Statement_Exception
0855      * @throws Zend_Db_Table_Exception
0856      */
0857     public function findPreviousSibling($data)
0858     {
0859         $parent = $this->fetchParentForId($data);
0860         $parent_category_id = $parent->project_category_id;
0861 
0862         $sql = "SELECT node.project_category_id, node.lft, node.rgt, node.title, (SELECT
0863                        `project_category_id`
0864                         FROM
0865                           `project_category` AS `t2`
0866                         WHERE
0867                           `t2`.`lft`  < `node`.`lft` AND
0868                           `t2`.`rgt` > `node`.`rgt`
0869                         ORDER BY
0870                           `t2`.`rgt`-`node`.`rgt`ASC
0871                         LIMIT
0872                           1) AS `parent_category_id`
0873                 FROM project_category AS node,
0874                      project_category AS parent
0875                 WHERE node.lft BETWEEN parent.lft AND parent.rgt
0876                 GROUP BY node.project_category_id
0877                 HAVING parent_category_id = :parent_category_id
0878                 ORDER BY node.lft";
0879 
0880         $siblings = $this->_db->query($sql, array('parent_category_id' => $parent_category_id))->fetchAll();
0881 
0882         $resultRow = null;
0883         $bufferRow = null;
0884 
0885         foreach ($siblings as $row) {
0886             if ($row['project_category_id'] != $data['project_category_id']) {
0887                 $bufferRow = $row;
0888                 continue;
0889             }
0890             $resultRow = $bufferRow;
0891         }
0892 
0893         return $resultRow;
0894     }
0895 
0896     /**
0897      * @param $data
0898      *
0899      * @return Zend_Db_Table_Row_Abstract
0900      * @throws Zend_Db_Statement_Exception
0901      * @throws Zend_Db_Table_Exception
0902      */
0903     public function fetchParentForId($data)
0904     {
0905         $sql = "
0906         SELECT `title`, (SELECT
0907               `project_category_id`
0908                FROM
0909                  `project_category` AS `t2`
0910                WHERE
0911                  `t2`.`lft`  < `node`.`lft` AND
0912                  `t2`.`rgt` > `node`.`rgt`
0913                ORDER BY
0914                  `t2`.`rgt`-`node`.`rgt`ASC
0915                LIMIT
0916                  1) AS `parent`
0917         FROM `project_category` AS `node`
0918         WHERE `project_category_id` = :category_id
0919         ORDER BY (`rgt`-`lft`) DESC
0920         ";
0921         $resultRow = $this->_db->query($sql, array('category_id' => $data['project_category_id']))->fetch();
0922 
0923         return $this->find($resultRow['parent'])->current();
0924     }
0925 
0926     /**
0927      * @param $data
0928      *
0929      * @return array|null
0930      * @throws Zend_Db_Statement_Exception
0931      * @throws Zend_Db_Table_Exception
0932      */
0933     public function findNextSibling($data)
0934     {
0935         $parent = $this->fetchParentForId($data);
0936         $parent_category_id = $parent->project_category_id;
0937 
0938         $sql = "SELECT node.project_category_id, node.lft, node.rgt, node.title, (SELECT
0939                        `project_category_id`
0940                         FROM
0941                           `project_category` AS `t2`
0942                         WHERE
0943                           `t2`.`lft`  < `node`.`lft` AND
0944                           `t2`.`rgt` > `node`.`rgt`
0945                         ORDER BY
0946                           `t2`.`rgt`-`node`.`rgt`ASC
0947                         LIMIT
0948                           1) AS `parent_category_id`
0949                 FROM project_category AS node,
0950                      project_category AS parent
0951                 WHERE node.lft BETWEEN parent.lft AND parent.rgt
0952                 GROUP BY node.project_category_id
0953                 HAVING parent_category_id = :parent_category_id
0954                 ORDER BY node.lft";
0955 
0956         $siblings = $this->_db->query($sql, array('parent_category_id' => $parent_category_id))->fetchAll();
0957 
0958         $resultRow = null;
0959         $found = false;
0960 
0961         foreach ($siblings as $row) {
0962             if ($found == true) {
0963                 $resultRow = $row;
0964                 break;
0965             }
0966             if ($row['project_category_id'] == $data['project_category_id']) {
0967                 $found = true;
0968                 continue;
0969             }
0970         }
0971 
0972         return $resultRow;
0973     }
0974 
0975     /**
0976      * @param $data
0977      *
0978      * @return null|Zend_Db_Table_Row_Abstract
0979      */
0980     public function findPreviousElement($data)
0981     {
0982         $resultRow = $this->fetchRow("rgt = {$data['lft']} - 1");
0983 
0984         if (($resultRow->rgt - $resultRow->lft) > 1) {
0985             $resultRow = $this->fetchRow("lft = {$resultRow->rgt} - 2");
0986         }
0987 
0988         return $resultRow;
0989     }
0990 
0991     /**
0992      * @param $data
0993      *
0994      * @return null|Zend_Db_Table_Row_Abstract
0995      */
0996     public function findNextElement($data)
0997     {
0998         $resultRow = $this->fetchRow("lft = {$data['rgt']} + 1");
0999 
1000         if (($resultRow->rgt - $resultRow->lft) > 1) {
1001             $resultRow = $this->fetchRow("lft = {$resultRow->lft} + 2");
1002         }
1003 
1004         return $resultRow;
1005     }
1006 
1007     /**
1008      * @param string|array $nodeId
1009      * @param array        $options
1010      *
1011      * @return array
1012      * @throws Zend_Exception
1013      */
1014     public function fetchChildTree($nodeId, $options = array())
1015     {
1016         $clearCache = false;
1017         if (isset($options['clearCache'])) {
1018             $clearCache = $options['clearCache'];
1019             unset($options['clearCache']);
1020         }
1021 
1022         /** @var Zend_Cache_Core $cache */
1023         $cache = $this->cache;
1024         $cacheName = __FUNCTION__ . '_' . md5(serialize($nodeId) . serialize($options));
1025 
1026         if ($clearCache) {
1027             $cache->remove($cacheName);
1028         }
1029 
1030         if (!($tree = $cache->load($cacheName))) {
1031 
1032             $extSqlWhereActive = " AND o.is_active = 1";
1033             if (isset($options['isActive']) AND $options['isActive'] == false) {
1034                 $extSqlWhereActive = '';
1035             }
1036 
1037             $extSqlHavingDepth = '';
1038             if (isset($options['depth'])) {
1039                 $extSqlHavingDepth = " HAVING depth <= " . (int)$options['depth'];
1040             }
1041 
1042             $inQuery = '?';
1043             if (is_array($nodeId)) {
1044                 $inQuery = implode(',', array_fill(0, count($nodeId), '?'));
1045             }
1046 
1047             $sql = "SELECT `o`.*,
1048                       COUNT(`p`.`project_category_id`)-1 AS `depth`,
1049                       CONCAT( REPEAT( '&nbsp;&nbsp;', (COUNT(`p`.`title`) - 1) ), `o`.`title`) AS `title_show`,
1050                       `pc`.`product_counter`
1051                     FROM `project_category` AS `n`
1052                     INNER JOIN `project_category` AS `p`
1053                     INNER JOIN `project_category` AS `o`
1054                     LEFT JOIN (SELECT
1055                                  `project`.`project_category_id`,
1056                                  count(`project`.`project_category_id`) AS `product_counter`
1057                                FROM
1058                                  `project`
1059                                WHERE `project`.`status` = 100 AND `project`.`type_id` = 1
1060                                GROUP BY `project`.`project_category_id`) AS `pc` ON `pc`.`project_category_id` = `o`.`project_category_id`
1061                     WHERE `o`.`lft` BETWEEN `p`.`lft` AND `p`.`rgt`
1062                           AND `o`.`lft` BETWEEN `n`.`lft` AND `n`.`rgt`
1063                           AND `n`.`project_category_id` IN ({$inQuery})
1064                           AND `o`.`lft` > `p`.`lft` AND `o`.`lft` > `n`.`lft`
1065                           {$extSqlWhereActive}
1066                     GROUP BY o.lft
1067                     {$extSqlHavingDepth}
1068                     ORDER BY o.lft;
1069                     ;
1070                     ";
1071             $tree = $this->_db->query($sql, $nodeId)->fetchAll();
1072             $cache->save($tree, $cacheName);
1073         }
1074 
1075         return $tree;
1076     }
1077 
1078     /**
1079      * @param int|array $nodeId
1080      * @param bool      $isActive
1081      *
1082      * @return array Set of subnodes
1083      * @throws Zend_Cache_Exception
1084      * @throws Zend_Db_Statement_Exception
1085      */
1086     public function fetchChildElements($nodeId, $isActive = true)
1087     {
1088         if (is_null($nodeId) OR $nodeId == '') {
1089             return array();
1090         }
1091 
1092         /** @var Zend_Cache_Core $cache */
1093         $cache = $this->cache;
1094         $cacheName = __FUNCTION__ . '_' . md5(serialize($nodeId) . (int)$isActive);
1095 
1096         if (($children = $cache->load($cacheName))) {
1097             return $children;
1098         }
1099 
1100         $inQuery = '?';
1101         if (is_array($nodeId)) {
1102             $inQuery = implode(',', array_fill(0, count($nodeId), '?'));
1103         }
1104         $whereActive = $isActive == true ? ' AND o.is_active = 1' : '';
1105         $sql = "
1106             SELECT o.*,
1107                    COUNT(p.project_category_id)-2 AS depth
1108                 FROM project_category AS n,
1109                      project_category AS p,
1110                      project_category AS o
1111                WHERE o.lft BETWEEN p.lft AND p.rgt
1112                  AND o.lft BETWEEN n.lft AND n.rgt
1113                  AND n.project_category_id IN ({$inQuery})
1114                  {$whereActive}
1115             GROUP BY o.lft
1116             HAVING depth > 0
1117             ORDER BY o.lft;
1118         ";
1119         $children = $this->_db->query($sql, $nodeId)->fetchAll();
1120         $cache->save($children, $cacheName);
1121         if (count($children)) {
1122             return $children;
1123         } else {
1124             return array();
1125         }
1126     }
1127 
1128     /**
1129      * @param int|array $nodeId
1130      * @param bool      $isActive
1131      *
1132      * @return array Set of subnodes
1133      * @throws Zend_Cache_Exception
1134      * @throws Zend_Db_Statement_Exception
1135      */
1136     public function fetchChildIds($nodeId, $isActive = true)
1137     {
1138         if (empty($nodeId) OR $nodeId == '') {
1139             return array();
1140         }
1141 
1142         /** @var Zend_Cache_Core $cache */
1143         $cache = $this->cache;
1144         $cacheName = __FUNCTION__ . '_' . md5(serialize($nodeId) . (int)$isActive);
1145 
1146         if (false !== ($children = $cache->load($cacheName))) {
1147             return $children;
1148         }
1149 
1150         $inQuery = '?';
1151         if (is_array($nodeId)) {
1152             $inQuery = implode(',', array_fill(0, count($nodeId), '?'));
1153         }
1154         $whereActive = $isActive == true ? ' AND o.is_active = 1' : '';
1155         $sql = "
1156             SELECT o.project_category_id
1157                 FROM project_category AS n,
1158                      project_category AS p,
1159                      project_category AS o
1160                WHERE o.lft BETWEEN p.lft AND p.rgt
1161                  AND o.lft BETWEEN n.lft AND n.rgt
1162                  AND n.project_category_id IN ({$inQuery})
1163                  {$whereActive}
1164             GROUP BY o.lft
1165             HAVING COUNT(p.project_category_id)-2 > 0
1166             ORDER BY o.lft;
1167         ";
1168         if (APPLICATION_ENV == "development") {
1169             Zend_Registry::get('logger')->debug(__METHOD__ . ' - ' . $sql . ' - ' . json_encode($nodeId));
1170         }
1171         $children = $this->_db->query($sql, $nodeId)->fetchAll();
1172         if (count($children)) {
1173             $result = $this->flattenArray($children);
1174             $result = $this->removeUnnecessaryValues($nodeId, $result);
1175             $cache->save($result, $cacheName);
1176 
1177             return $result;
1178         } else {
1179             return array();
1180         }
1181     }
1182 
1183     /**
1184      *
1185      * @flatten multi-dimensional array
1186      *
1187      * @param array $array
1188      *
1189      * @return array
1190      *
1191      */
1192     private function flattenArray(array $array)
1193     {
1194         $ret_array = array();
1195         foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) as $value) {
1196             $ret_array[] = $value;
1197         }
1198 
1199         return $ret_array;
1200     }
1201 
1202     /**
1203      * @param array $nodeId
1204      * @param array $children
1205      *
1206      * @return array
1207      */
1208     private function removeUnnecessaryValues($nodeId, $children)
1209     {
1210         $nodeId = is_array($nodeId) ? $nodeId : array($nodeId);
1211         return array_diff($children, $nodeId);
1212     }
1213 
1214     /**
1215      * @param        $nodeId
1216      * @param string $orderBy
1217      *
1218      * @return array
1219      * @throws Zend_Db_Statement_Exception
1220      */
1221     public function fetchImmediateChildrenIds($nodeId, $orderBy = self::ORDERED_HIERARCHIC)
1222     {
1223         $sql = "
1224                 SELECT `node`.`project_category_id`
1225                 FROM `project_category` AS `node`
1226                 WHERE `node`.`is_active` = 1
1227                 HAVING (SELECT `parent`.`project_category_id` FROM `project_category` AS `parent` WHERE `parent`.`lft` < `node`.`lft` AND `parent`.`rgt` > `node`.`rgt` ORDER BY `parent`.`rgt`-`node`.`rgt` LIMIT 1) = ?
1228                 ORDER BY `node`.`{$orderBy}`;
1229             ";
1230         $children = $this->_db->query($sql, $nodeId)->fetchAll(Zend_Db::FETCH_NUM);
1231         if (count($children)) {
1232             return $this->flattenArray($children);
1233         } else {
1234             return array();
1235         }
1236     }
1237 
1238     /**
1239      * @param Zend_Db_Table_Row $first
1240      * @param Zend_Db_Table_Row $second
1241      *
1242      * @return \Zend_Db_Table_Row
1243      * @throws Zend_Exception
1244      * @deprecated
1245      */
1246     public function switchElements($first, $second)
1247     {
1248         $bufferLeft = $first->lft;
1249         $bufferRight = $first->rgt;
1250 
1251         $this->_db->beginTransaction();
1252         try {
1253             $this->_db->query("UPDATE {$this->_name} SET rgt = {$second->rgt} WHERE project_category_id = {$first->project_category_id};");
1254             $this->_db->query("UPDATE {$this->_name} SET lft = {$second->lft} WHERE project_category_id = {$first->project_category_id};");
1255 
1256             $this->_db->query("UPDATE {$this->_name} SET rgt = {$bufferRight} WHERE project_category_id = {$second->project_category_id};");
1257             $this->_db->query("UPDATE {$this->_name} SET lft = {$bufferLeft} WHERE project_category_id = {$second->project_category_id};");
1258             $this->_db->commit();
1259         } catch (Exception $e) {
1260             $this->_db->rollBack();
1261             Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . print_r($e, true));
1262         }
1263 
1264         $first->refresh();
1265 
1266         return $first;
1267     }
1268 
1269     /**
1270      * @param int $returnAmount
1271      * @param int $fetchLimit
1272      *
1273      * @return array|false|mixed
1274      */
1275     public function fetchMainCategories($returnAmount = 25, $fetchLimit = 25)
1276     {
1277         $categories = $this->fetchTree(true, false, 1);
1278 
1279         return array_slice($categories, 0, $returnAmount);
1280     }
1281 
1282     /**
1283      * @return array
1284      * @throws Zend_Cache_Exception
1285      * @throws Zend_Db_Statement_Exception
1286      */
1287     public function fetchMainCatIdsOrdered()
1288     {
1289         /** @var Zend_Cache_Core $cache */
1290         $cache = $this->cache;
1291         $cacheName = __FUNCTION__;
1292 
1293         if (($returnValue = $cache->load($cacheName))) {
1294             return $returnValue;
1295         }
1296 
1297         $sql = "
1298                 SELECT
1299                     `node`.`project_category_id`
1300                 FROM
1301                     `project_category` AS `node`
1302                 INNER JOIN
1303                     `project_category` AS `parent`
1304                 WHERE
1305                     `node`.`lft` BETWEEN `parent`.`lft` AND `parent`.`rgt`
1306                         AND `node`.`is_active` = 1
1307                         AND `node`.`is_deleted` = 0
1308                         AND `node`.`lft` > 0
1309                 GROUP BY `node`.`project_category_id`
1310                 HAVING (COUNT(`parent`.`title`) - 1) = 1
1311                 ORDER BY `node`.`orderPos`, `node`.`lft`;
1312         ";
1313 
1314         $result = $this->_db->query($sql)->fetchAll(Zend_Db::FETCH_NUM);
1315         if (count($result) > 0) {
1316             $returnValue = $this->flattenArray($result);
1317             $cache->save($returnValue, $cacheName, array(), 900);
1318 
1319             return $returnValue;
1320         } else {
1321             return array();
1322         }
1323     }
1324 
1325     /**
1326      * @return array
1327      * @throws Zend_Db_Statement_Exception
1328      */
1329     public function fetchMainCatsOrdered()
1330     {
1331         $sql = "
1332                 SELECT
1333                     node.project_category_id, node.title, node.lft, node.rgt
1334                 FROM
1335                     project_category AS node
1336                 INNER JOIN
1337                     project_category AS parent
1338                 WHERE
1339                     node.lft BETWEEN parent.lft AND parent.rgt
1340                         AND node.is_active = 1
1341                         AND node.is_deleted = 0
1342                         AND node.lft > 0
1343                 GROUP BY node.project_category_id
1344                 HAVING (COUNT(parent.title) - 1) = 1
1345                 ORDER BY node.orderPos, node.lft;
1346         ";
1347         $result = $this->_db->query($sql)->fetchAll();
1348         if (count($result) > 0) {
1349             return $result;
1350         } else {
1351             return array();
1352         }
1353     }
1354 
1355     /**
1356      * @param int    $cat_id
1357      * @param string $orderBy
1358      *
1359      * @return array
1360      * @throws Zend_Db_Statement_Exception
1361      */
1362     public function fetchSubCatIds($cat_id, $orderBy = self::ORDERED_HIERARCHIC)
1363     {
1364         $sql = "
1365                 SELECT
1366                     node.project_category_id
1367                 FROM
1368                     project_category AS node
1369                 INNER JOIN
1370                     project_category AS parent
1371                 WHERE
1372                     parent.project_category_id IN (:cat_id)
1373                         --  AND node.lft BETWEEN parent.lft AND parent.rgt
1374                         AND node.lft > parent.lft AND node.rgt < parent.rgt
1375                         AND node.is_active = 1
1376                         AND node.is_deleted = 0
1377                         AND node.lft > 0
1378                 GROUP BY node.project_category_id
1379                 ORDER BY node.`{$orderBy}`
1380                 ;
1381         ";
1382         $result = $this->_db->query($sql, array('cat_id' => $cat_id))->fetchAll(Zend_Db::FETCH_NUM);
1383         if (count($result) > 0) {
1384             //            array_shift($result);
1385             return $this->flattenArray($result);
1386         } else {
1387             return array();
1388         }
1389     }
1390 
1391     /**
1392      * @param int $returnAmount
1393      * @param int $fetchLimit
1394      *
1395      * @return array
1396      */
1397     public function fetchRandomCategories($returnAmount = 5, $fetchLimit = 25)
1398     {
1399         $categories = $this->fetchTree(true, false, 1);
1400 
1401         return $this->_array_random($categories, $returnAmount);
1402     }
1403 
1404     /**
1405      * @param array $categories
1406      * @param int   $count
1407      *
1408      * @return array
1409      */
1410     protected function _array_random($categories, $count = 1)
1411     {
1412         shuffle($categories);
1413 
1414         return array_slice($categories, 0, $count);
1415     }
1416 
1417     /**
1418      * @param int    $currentNodeId
1419      * @param int    $newParentNodeId
1420      * @param string $position
1421      *
1422      * @return bool
1423      * @throws Zend_Db_Statement_Exception
1424      * @throws Zend_Db_Table_Exception
1425      * @throws Zend_Exception
1426      */
1427     public function moveToParent($currentNodeId, $newParentNodeId, $position = 'top')
1428     {
1429         if ($currentNodeId <= 0) {
1430             return false;
1431         }
1432         $currentNode = $this->fetchElement($currentNodeId);
1433         $currentParentNode = $this->fetchParentForId($currentNode);
1434 
1435         if ($newParentNodeId == $currentParentNode->project_category_id) {
1436             return false;
1437         }
1438 
1439         $newParentNode = $this->fetchElement($newParentNodeId);
1440 
1441         if ($position == 'top') {
1442             return $this->moveTo($currentNode, $newParentNode['lft'] + 1);
1443         } else {
1444             return $this->moveTo($currentNode, $newParentNode['rgt']); // move to bottom otherwise
1445         }
1446     }
1447 
1448     /**
1449      * @param int $nodeId
1450      *
1451      * @return array Returns Element as array or (if empty) an array with empty values
1452      * @throws Zend_Db_Table_Exception
1453      */
1454     public function fetchElement($nodeId)
1455     {
1456         if (is_null($nodeId) OR $nodeId == '') {
1457             return $this->createRow();
1458         }
1459 
1460         $currentNode = $this->find($nodeId)->current();
1461 
1462         if ($currentNode === null) {
1463             $resultValue = $this->createRow()->toArray();
1464         } else {
1465             $resultValue = $currentNode->toArray();
1466         }
1467 
1468         return $resultValue;
1469     }
1470 
1471     /**
1472      * @param array $node            complete node data
1473      * @param int   $newLeftPosition new left position for the node
1474      *
1475      * @return bool
1476      * @throws Zend_Exception
1477      */
1478     public function moveTo($node, $newLeftPosition)
1479     {
1480         $space = $node['rgt'] - $node['lft'] + 1;
1481         $distance = $newLeftPosition - $node['lft'];
1482         $srcPosition = $node['lft'];
1483 
1484         //for backwards movement, we have to fix some values
1485         if ($distance < 0) {
1486             $distance -= $space;
1487             $srcPosition += $space;
1488         }
1489 
1490         $this->_db->beginTransaction();
1491 
1492         try {
1493             // create space for subtree
1494             $this->_db->query("UPDATE {$this->_name} SET lft = lft + :space WHERE lft >= :newLeftPosition;",
1495                 array('space' => $space, 'newLeftPosition' => $newLeftPosition));
1496             $this->_db->query("UPDATE {$this->_name} SET rgt = rgt + :space WHERE rgt >= :newLeftPosition;",
1497                 array('space' => $space, 'newLeftPosition' => $newLeftPosition));
1498 
1499             // move tree
1500             $this->_db->query("UPDATE {$this->_name} SET lft = lft + :distance, rgt = rgt + :distance WHERE lft >= :srcPosition AND rgt < :srcPosition + :space;",
1501                 array('distance' => $distance, 'srcPosition' => $srcPosition, 'space' => $space));
1502 
1503             // remove old space
1504             $this->_db->query("UPDATE {$this->_name} SET rgt = rgt - :space WHERE rgt > :srcPosition;",
1505                 array('space' => $space, 'srcPosition' => $srcPosition));
1506             $this->_db->query("UPDATE {$this->_name} SET lft = lft - :space WHERE lft >= :srcPosition;",
1507                 array('space' => $space, 'srcPosition' => $srcPosition));
1508 
1509             // move it
1510             $this->_db->commit();
1511         } catch (Exception $e) {
1512             $this->_db->rollBack();
1513             Zend_Registry::get('logger')->err(__METHOD__ . ' - ' . print_r($e, true));
1514 
1515             return false;
1516         }
1517 
1518         return true;
1519     }
1520 
1521     /**
1522      * @param $productId
1523      *
1524      * @return array
1525      */
1526     public function fetchMainCategoryForProduct($productId)
1527     {
1528         $sql = "SELECT `pc`.`project_category_id`, `pc`.`title`
1529                 FROM `project_category` AS `pc`
1530                 JOIN `project` AS `p` ON `p`.`project_category_id` = `pc`.`project_category_id`
1531                 WHERE `p`.`project_id` = :projectId
1532                 ;";
1533 
1534         return $this->_db->fetchAll($sql, array('projectId' => $productId));
1535     }
1536 
1537     /**
1538      * @param $productId
1539      *
1540      * @return array
1541      * @deprecated
1542      */
1543     public function fetchAllCategoriesForProduct($productId)
1544     {
1545         $sql = "SELECT p.project_id, pc.project_category_id AS category_id, pc.title AS category, ps.project_category_id AS sub_category_id, ps.title AS sub_category
1546                 FROM project AS p
1547                 JOIN project_category AS pc ON p.project_category_id = pc.project_category_id
1548                 LEFT JOIN (SELECT prc.project_category_id, psc.project_id, prc.title FROM project_subcategory AS psc JOIN project_category AS prc ON psc.project_sub_category_id) AS ps ON p.project_id = ps.project_id
1549                 WHERE p.project_id = :projectId
1550                 ";
1551 
1552         return $this->_db->fetchAll($sql, array('projectId' => $productId));
1553     }
1554 
1555     /**
1556      * @param int $cat_id
1557      *
1558      * @return int|string
1559      * @throws Zend_Db_Table_Exception
1560      */
1561     public function countSubCategories($cat_id)
1562     {
1563         $cat = $this->findCategory($cat_id);
1564 
1565         $countSubCat = (int)$cat->rgt - (int)$cat->lft - 1;
1566 
1567         if ($countSubCat < 0) {
1568             return 0;
1569         } else {
1570             return $countSubCat;
1571         }
1572     }
1573 
1574     /**
1575      * @param int $nodeId
1576      *
1577      * @return Zend_Db_Table_Row_Abstract
1578      * @throws Zend_Db_Table_Exception
1579      */
1580     public function findCategory($nodeId)
1581     {
1582         if (is_null($nodeId) OR $nodeId == '') {
1583             return $this->createRow();
1584         }
1585 
1586         $result = $this->find($nodeId);
1587         if (count($result) > 0) {
1588             return $result->current();
1589         } else {
1590             return $this->createRow();
1591         }
1592     }
1593 
1594     /**
1595      * @param $valueCatId
1596      *
1597      * @return array
1598      * @throws Zend_Cache_Exception
1599      * @throws Zend_Db_Statement_Exception
1600      */
1601     public function fetchCategoriesForForm($valueCatId)
1602     {
1603         $level = 0;
1604         $mainCatArray = $this->fetchMainCatForSelect(Default_Model_DbTable_ProjectCategory::ORDERED_TITLE);
1605         $ancestors = array("catLevel-{$level}" => $mainCatArray);
1606         
1607         $level++;
1608 
1609         if (false == empty($valueCatId)) {
1610             
1611             foreach (array_keys($mainCatArray) as $element) {
1612                 if($element == $valueCatId) {
1613                     return $ancestors;
1614                 }
1615             }
1616             
1617             $categoryAncestors = $this->fetchAncestorsAsId($valueCatId);
1618             if ($categoryAncestors) {
1619                 $categoryPath = explode(',', $categoryAncestors['ancestors']);
1620                 foreach ($categoryPath as $element) {
1621                     
1622                     $catResult = $this->fetchImmediateChildren($element, Default_Model_DbTable_ProjectCategory::ORDERED_TITLE);
1623                     $ancestors["catLevel-{$level}"] = $this->prepareDataForFormSelect($catResult);
1624                     
1625                     $level++;
1626                 }
1627             }
1628         }
1629 
1630         return $ancestors;
1631     }
1632     
1633     /**
1634      * @param $valueCatId
1635      *
1636      * @return array
1637      * @throws Zend_Cache_Exception
1638      * @throws Zend_Db_Statement_Exception
1639      */
1640     public function fetchCategoriesForFormNew($valueCatId)
1641     {
1642         $level = 0;
1643         $mainCatArray = $this->fetchMainCatForSelectNew(Default_Model_DbTable_ProjectCategory::ORDERED_TITLE);
1644         $ancestors = array("catLevel-{$level}" => $mainCatArray);
1645         
1646         $level++;
1647 
1648         if (false == empty($valueCatId)) {
1649             
1650             foreach (array_keys($mainCatArray) as $element) {
1651                 if($element == $valueCatId) {
1652                     return $ancestors;
1653                 }
1654             }
1655             
1656             $categoryAncestors = $this->fetchAncestorsAsId($valueCatId);
1657             if ($categoryAncestors) {
1658                 $categoryPath = explode(',', $categoryAncestors['ancestors']);
1659                 foreach ($categoryPath as $element) {
1660                     
1661                     $catResult = $this->fetchImmediateChildren($element, Default_Model_DbTable_ProjectCategory::ORDERED_TITLE);
1662                     $ancestors["catLevel-{$level}"] = $this->prepareDataForFormSelect($catResult);
1663                     
1664                     $level++;
1665                 }
1666             }
1667         }
1668 
1669         return $ancestors;
1670     }
1671 
1672     /**
1673      * @param string $orderBy
1674      *
1675      * @return array
1676      * @throws Zend_Cache_Exception
1677      * @throws Zend_Db_Statement_Exception
1678      */
1679     public function fetchMainCatForSelect($orderBy = self::ORDERED_HIERARCHIC)
1680     {
1681         
1682         $root = $this->fetchRoot();
1683         $resultRows = $this->fetchImmediateChildren($root['project_category_id'], $orderBy);
1684         
1685         /*
1686         $storeCatIds = Zend_Registry::isRegistered('store_category_list') ? Zend_Registry::get('store_category_list') : null;
1687         if(null == $storeCatIds) {
1688             $root = $this->fetchRoot();
1689             $resultRows = $this->fetchImmediateChildren($root['project_category_id'], $orderBy);
1690         } else {
1691             $resultRows = $this->fetchImmediateChildren($storeCatIds, $orderBy, false);
1692         }*/
1693         
1694 
1695         $resultForSelect = $this->prepareDataForFormSelect($resultRows);
1696 
1697         return $resultForSelect;
1698     }
1699     
1700     /**
1701      * @param string $orderBy
1702      *
1703      * @return array
1704      * @throws Zend_Cache_Exception
1705      * @throws Zend_Db_Statement_Exception
1706      */
1707     public function fetchMainCatForSelectNew($orderBy = self::ORDERED_HIERARCHIC)
1708     {
1709         
1710         //$root = $this->fetchRoot();
1711         //$resultRows = $this->fetchImmediateChildrenNew($root['project_category_id'], $orderBy);
1712         
1713         
1714         $storeCatIds = Zend_Registry::isRegistered('store_category_list') ? Zend_Registry::get('store_category_list') : null;
1715         if(null == $storeCatIds) {
1716             $root = $this->fetchRoot();
1717             $resultRows = $this->fetchImmediateChildrenNew($root['project_category_id'], $orderBy);
1718         } else {
1719             $resultRows = $this->fetchImmediateChildrenNew($storeCatIds, $orderBy, false);
1720         }
1721         
1722 
1723         $resultForSelect = $this->prepareDataForFormSelectNew($resultRows);
1724 
1725         return $resultForSelect;
1726     }
1727 
1728     /**
1729      * @param int|array $nodeId
1730      * @param string    $orderBy
1731      *
1732      * @return array
1733      * @throws Zend_Cache_Exception
1734      * @throws Zend_Db_Statement_Exception
1735      */
1736     public function fetchImmediateChildren($nodeId, $orderBy = 'lft')
1737     {
1738         $str = is_array($nodeId) ? implode(',', $nodeId) : $nodeId;
1739         /** @var Zend_Cache_Core $cache */
1740         $cache = $this->cache;
1741         $cacheName = __FUNCTION__ . '_' . md5($str . $orderBy);
1742 
1743         if (false === ($children = $cache->load($cacheName))) {
1744             $inQuery = '?';
1745             if (is_array($nodeId)) {
1746                 $inQuery = implode(',', array_fill(0, count($nodeId), '?'));
1747             }
1748             $sql = '
1749             SELECT node.*, (SELECT parent.project_category_id FROM project_category AS parent WHERE parent.lft < node.lft AND parent.rgt > node.rgt ORDER BY parent.rgt-node.rgt LIMIT 1) AS parent
1750             FROM project_category AS node
1751             WHERE node.is_active = 1
1752             HAVING parent IN (' . $inQuery . ')
1753             ORDER BY node.' . $orderBy . '
1754             ';
1755             $children = $this->_db->query($sql, $nodeId)->fetchAll();
1756             if (count($children) == 0) {
1757                 $children = array();
1758             }
1759             $cache->save($children, $cacheName, array(), 3600);
1760         }
1761 
1762         return $children;
1763     }
1764 
1765     /**
1766      * @param int|array $nodeId
1767      * @param string    $orderBy
1768      *
1769      * @return array
1770      * @throws Zend_Cache_Exception
1771      * @throws Zend_Exception
1772      */
1773     public function fetchImmediateChildrenNew($nodeId, $orderBy = 'lft')
1774     {
1775         $str = is_array($nodeId) ? implode(',', $nodeId) : $nodeId;
1776         /** @var Zend_Cache_Core $cache */
1777         $cache = $this->cache;
1778         $cacheName = __FUNCTION__ . '_' . md5($str . $orderBy);
1779 
1780         if (false === ($children = $cache->load($cacheName))) {
1781             $proCatModel = new Default_Model_ProjectCategory();
1782             $store_config = Zend_Registry::get('store_config');
1783             $store_id = $store_config->store_id;
1784             $rows = $proCatModel->fetchTreeForView($store_id);
1785             $children = array();
1786             
1787             if (is_array($nodeId)) {
1788                 $inQuery = implode(',', array_fill(0, count($nodeId), '?'));
1789                 foreach ($rows as $row) {
1790                     foreach ($nodeId as $node) {
1791                         if($row['id'] == $node) {
1792                             $children[] = $row;
1793                         }
1794                     }
1795                 }
1796             } else {
1797                 foreach ($rows as $row) {
1798                     if($row['parent_id'] == $nodeId) {
1799                         $children[] = $row;
1800                     }
1801                 }
1802             }
1803             if (count($children) == 0) {
1804                 $children = array();
1805             }
1806             $cache->save($children, $cacheName, array(), 3600);
1807         }
1808 
1809         return $children;
1810     }
1811 
1812     /**
1813      * @param $resultRows
1814      *
1815      * @return array
1816      */
1817     protected function prepareDataForFormSelect($resultRows)
1818     {
1819         $resultForSelect = array();
1820         //$resultForSelect[''] = '';
1821         foreach ($resultRows as $row) {
1822             $resultForSelect[$row['project_category_id']] = $row['title'];
1823         }
1824 
1825         return $resultForSelect;
1826     }
1827     
1828     /**
1829      * @param $resultRows
1830      *
1831      * @return array
1832      */
1833     protected function prepareDataForFormSelectNew($resultRows)
1834     {
1835         $resultForSelect = array();
1836         //$resultForSelect[''] = '';
1837         foreach ($resultRows as $row) {
1838             $resultForSelect[$row['id']] = $row['title'];
1839         }
1840 
1841         return $resultForSelect;
1842     }
1843 
1844     /**
1845      * @param $catId
1846      *
1847      * @return array|mixed
1848      */
1849     public function fetchAncestorsAsId($catId)
1850     {
1851         $sql = '
1852         SELECT node.title, GROUP_CONCAT(parent.project_category_id ORDER BY parent.lft) AS ancestors 
1853         FROM project_category AS node
1854         LEFT JOIN project_category AS parent ON parent.lft < node.lft AND parent.rgt > node.rgt AND parent.lft > 0
1855         WHERE node.project_category_id = :categoryId
1856         GROUP BY node.project_category_id
1857         HAVING ancestors IS NOT NULL
1858         ';
1859 
1860         $result = $this->_db->fetchRow($sql, array('categoryId' => $catId));
1861 
1862         if ($result AND count($result) > 0) {
1863             return $result;
1864         } else {
1865             return array();
1866         }
1867     }
1868 
1869     /**
1870      * @param $resultRows
1871      *
1872      * @return array
1873      */
1874     protected function prepareDataForFormSelectWithTitleKey($resultRows)
1875     {
1876         $resultForSelect = array();
1877         //$resultForSelect[''] = '';
1878         foreach ($resultRows as $row) {
1879             $resultForSelect[$row['title']] = $row['project_category_id'];
1880         }
1881 
1882         return $resultForSelect;
1883     }
1884 
1885     /**
1886      * @deprecated
1887      */
1888     protected function initLocalCache()
1889     {
1890         $frontendOptions = array(
1891             'lifetime'                => 3600,
1892             'automatic_serialization' => true
1893         );
1894 
1895         $backendOptions = array(
1896             'cache_dir' => APPLICATION_CACHE,
1897             'file_locking' => true,
1898             'read_control' => true,
1899             'read_control_type' => 'adler32', // default 'crc32'
1900             'hashed_directory_level' => 0,
1901             'hashed_directory_perm' => 0700,
1902             'file_name_prefix' => 'app',
1903             'cache_file_perm' => 700
1904         );
1905 
1906         $this->cache = Zend_Cache::factory(
1907             'Core',
1908             'File',
1909             $frontendOptions,
1910             $backendOptions
1911         );
1912     }
1913 
1914 }