Установка активного класса для
  • при использовании Zend_Navigation, если автоматически не устанавливается.
  • Бывают случаи, когда Zend Navigation сам не может добавить для

  • активный класс. Это может быть из-за разных роутеров, мультиязычности — вариантов достаточно много.

    $container = new Zend_Navigation_Page_Mvc();
    $container->setPages($data);
        foreach ($container->getPages() as $page) {
            $uri = $page->getHref();
            $uri = str_replace($this->_view->baseUrl(), '', $uri);
            $res = str_replace('/', '', $uri);
            if (($uri == $request->getRequestUri()) || ((strlen($res) > 0) && (stristr(str_replace('/', '', $request->getRequestUri()), $res)))) {
                $page->setActive('true');
            }
        }
    Zend_Registry::set('mainMenu', $container);
    

    Ключевой момент — $page->setActive(‘true’);

    Мультиязычный сайт на основе Zend Framework.

    В предыдущем примере можно столкнуться с проблемой обрезания дефолтового языка и генерации роутеров. В этот раз уже выкладываю рабочий проект, только без дизайнов и прочего, т.к. снят с реально действующего сайта.
    Все авторские права данного примера пренадлежат UDSTM, кроме тех частей кода, которые писались другими авторами и распространяются по GNU лицензии.

    Языки мы храним в бд
    language

    -- phpMyAdmin SQL Dump
    -- version 3.5.0-rc1
    -- http://www.phpmyadmin.net
    --
    -- Хост: localhost
    -- Время создания: Апр 10 2012 г., 13:34
    -- Версия сервера: 5.1.40-community
    -- Версия PHP: 5.3.3
    
    SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
    SET time_zone = "+00:00";
    
    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
    /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
    /*!40101 SET NAMES utf8 */;
    
    --
    -- База данных: `marki`
    --
    
    -- --------------------------------------------------------
    
    --
    -- Структура таблицы `language`
    --
    
    CREATE TABLE IF NOT EXISTS `language` (
      `language_id` smallint(11) NOT NULL AUTO_INCREMENT,
      `language_locale` varchar(5) NOT NULL,
      `language_name` varchar(15) NOT NULL,
      `language_pic` varchar(255) DEFAULT NULL,
      `language_visible` enum('0','1') NOT NULL DEFAULT '0',
      `language_pr` smallint(8) NOT NULL,
      PRIMARY KEY (`language_id`),
      KEY `languages_visible` (`language_visible`),
      KEY `language_locale` (`language_locale`),
      KEY `language_pr` (`language_pr`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;
    
    --
    -- Дамп данных таблицы `language`
    --
    
    INSERT INTO `language` (`language_id`, `language_locale`, `language_name`, `language_pic`, `language_visible`, `language_pr`) VALUES
    (5, 'ru', 'Русский', '/images/languages/lang_1331901742.jpg', '0', 1),
    (8, 'en', 'Английский', NULL, '1', 0);
    
    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
    

    таблица для текстовоых страниц:

    -- phpMyAdmin SQL Dump
    -- version 3.5.0-rc1
    -- http://www.phpmyadmin.net
    --
    -- Хост: localhost
    -- Время создания: Апр 10 2012 г., 13:34
    -- Версия сервера: 5.1.40-community
    -- Версия PHP: 5.3.3
    
    SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
    SET time_zone = "+00:00";
    
    /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
    /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
    /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
    /*!40101 SET NAMES utf8 */;
    
    --
    -- База данных: `marki`
    --
    
    -- --------------------------------------------------------
    
    --
    -- Структура таблицы `pages`
    --
    
    CREATE TABLE IF NOT EXISTS `pages` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `parent_id` int(11) NOT NULL,
      `txt` text NOT NULL,
      `title` varchar(255) NOT NULL,
      `external_url` varchar(255) NOT NULL,
      `url` varchar(255) NOT NULL,
      `kw` varchar(255) NOT NULL,
      `dw` varchar(255) NOT NULL,
      `pr` int(5) NOT NULL DEFAULT '999',
      `visible` enum('0','1') NOT NULL DEFAULT '1',
      `pic` varchar(255) NOT NULL,
      `lang_id` smallint(11) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `url` (`url`),
      KEY `visible` (`visible`),
      KEY `lang_id` (`lang_id`)
    ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=17 ;
    
    --
    -- Дамп данных таблицы `pages`
    --
    
    INSERT INTO `pages` (`id`, `parent_id`, `txt`, `title`, `external_url`, `url`, `kw`, `dw`, `pr`, `visible`, `pic`, `lang_id`) VALUES
    (10, 0, '<p>\r\n	wqerwqer</p>\r\n', 'английский тестовы', '', 'anglijskij-testovy', '', '', 999, '1', '', 8),
    (11, 0, '', 'Главная', '/', 'Glavnaja', '', '', 999, '1', '', 5),
    (12, 0, '', 'Каталог', 'catalog', 'Katalog', '', '', 999, '1', '', 5),
    (13, 0, '', 'Новости', 'news', 'Novosti', '', '', 999, '1', '', 5),
    (14, 0, '', 'Акции', '/stock/', 'Aktsii', '', '', 999, '1', '', 5),
    (15, 0, '<p>\r\n	Оплата и доставка</p>\r\n', 'Оплата и доставка', '', 'Oplata-i-dostavka', 'Оплата и доставка', 'Оплата и доставка', 999, '1', '', 5),
    (16, 0, '<p>\r\n	Контакты</p>\r\n', 'Контакты', '', 'Kontakty', 'Контакты', 'Контакты', 999, '1', '', 5);
    
    --
    -- Ограничения внешнего ключа сохраненных таблиц
    --
    
    --
    -- Ограничения внешнего ключа таблицы `pages`
    --
    ALTER TABLE `pages`
      ADD CONSTRAINT `pages_ibfk_1` FOREIGN KEY (`lang_id`) REFERENCES `language` (`language_id`) ON DELETE CASCADE ON UPDATE CASCADE;
    
    /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
    /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
    /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
    

    Как видно, мы в pages имеем ключ langueage_id который ссылается на таблицу langueage. С помощью этого мы можем спокойно разделять контент по языкам.

    В основной bootstrap:

    protected function _initRoutes() {
            $frontController = Zend_Controller_Front::getInstance();
    
            $router = $frontController->getRouter();
            //$router->removeDefaultRoutes();
            $frontController = Zend_Controller_Front::getInstance();
            $frontController->getRouter()->addRoute('default', new Zend_Controller_Router_Route(
                            '/:module/:controller/:action/*',
                            array(
                                'module' => 'default',
                                'controller' => 'index',
                                'action' => 'index',
                                'lang' => $lang
                            )
                    )
            );
    
            // add multilingual route
            $frontController->getRouter()->addRoute('defaultMultilingual', new Zend_Controller_Router_Route(
                            ':lang/:module/:controller/:action/*',
                            array(
                                'module' => 'default',
                                'controller' => 'index',
                                'action' => 'index',
                                'lang' => $lang
                            ),
                            array(
                                'lang' => '\w{2}'
                            )
                    )
            );
            /*         * *********************************** */
            $route = new Zend_Controller_Router_Route(
                            'pages/:key',
                            array(
                                'lang' => '',
                                'module' => 'pages',
                                'controller' => 'show',
                                'action' => 'index',
                                'key' => ':key',
                            )
            );
            $router->addRoute('staticpages', $route);
    
            $route = new Zend_Controller_Router_Route(
                            ':lang/pages/:key',
                            array(
                                'lang' => '',
                                'module' => 'pages',
                                'controller' => 'show',
                                'action' => 'index',
                                'key' => ':key',
                            )
            );
            $router->addRoute('staticpagxes', $route);
    
            /*         * ********************** */
            $router->addRoute(
                    'adminoller', new Zend_Controller_Router_Route('/admin',
                            array(
                                'module' => 'admin',
                                'controller' => 'index',
                                'action' => 'index'
                            )
                    )
            );
            $router->addRoute(
                    'admixnoller', new Zend_Controller_Router_Route('/admin/:controller',
                            array(
                                'module' => 'admin',
                                'controller' => 'index',
                                'action' => 'index'
                            )
                    )
            );
            $router->addRoute(
                    'axdmixnoller', new Zend_Controller_Router_Route('/admin/:controller/:action',
                            array(
                                'module' => 'admin',
                                'controller' => 'index',
                                'action' => 'index'
                            )
                    )
            );
        }
    

    Больше можно посмотрев скачать проект. В этот раз скачать могут только зарегистрированные. Код сырой. Некоторые момент реализованы не совсем хорошо, залито много лишнего: например меню и т.д.. Но это хоть что-то. По крайней мере многие необходимые моменты в этом шаблоне собраны. Запустить можете не пытаться: моделей, стилей нет.

    http://vazelin.org.ua/wp-content/plugins/downloads-manager/img/icons/winrar.gif download: multilanguage_zend_frmaework_application (6.17MB)
    added: 10/04/2012
    clicks: 4
    description: Мультиязычный проект. Демо

    Мультиязычный сайт с использование Zend_Translate.

    1. Пишем плагин, который будет понимать какой язык пользователь хочет видеть. Мне удобно делать языковые версии в таком виде:

    site.com — основной

    site.com/ua/ — украинский

    site.com/de/ — немецкий.

    Пути:

    site.com/blog/page/2/

    site.com/ua/blog/page/2/

     
    UDS/Controller/Plugin/LangSelector.php [идею кода где-то подсмотрел :) ]

    <?php
    
    class UDS_Controller_Plugin_LangSelector extends Zend_Controller_Plugin_Abstract {
    
        public function preDispatch(Zend_Controller_Request_Abstract $request) {
            $lang = $request->getParam('lang', '');
    
            try {
                $locale = new Zend_Locale(Zend_Locale::BROWSER);
            } catch (Exception $e) {
                $locale = new Zend_Locale();
            }
    
            /*         * ********************** */
            if ($lang == 'ru')
                $loc = 'ru_RU';
            else if ($lang == 'en')
                $loc = 'en_CA';
            else if ($lang == 'ua')
                $loc = 'ua_UA';
            else {
                //$lang = $locale->getLanguage();
                $lang = 'ru';
                $loc = 'ru_Ru';
            }
            /*         * ********************** */
            $locale->setLocale($lang);
            Zend_Registry::set('Zend_Locale', $loc);
    
            try {
                $translate = new Zend_Translate(
                                array(
                                    'adapter' => 'gettext',
                                    'content' => APPLICATION_PATH . '/configs/lang/' . $lang . '.mo',
                                    'locale' => $lang
                                )
                );
            } catch (Exception $e) {
                $translate = new Zend_Translate(array(
                            'adapter' => 'gettext',
                            'content' => APPLICATION_PATH . '/configs/lang/ru.mo',
                            'locale' => $lang
                                )
                );
            }
    
            Zend_Registry::set('Zend_Translate', $translate);
            Zend_Registry::set('uds_lang', $lang);
            $langm = new Admin_Model_LanguageMapper();
            $lang_id = $langm->getLanguageId();
            Zend_Registry::set('uds_lang_id', $lang_id);
        }
    
    }
    

    Собственно, это главный плагин, который разбивает строку и понимает какой язык мы используем.
    Zend_Registry::set(‘uds_lang’, $lang) — язык, который мы используем. [return ru, en]
    Zend_Registry::set(‘uds_lang_id’, $lang_id) — id языка в системе. Это нам нужно, чтобы мы могли использовать одну базу данных. Текстовые страницы мы ограничиваем по lang_id, ну и вывод тоже.

    Пример языкового файла en.po [Для создания траслита, нужно использовать что-то на подобе poedit]

    msgid ""
    msgstr ""
    "Project-Id-Version: zftutorial\n"
    "Report-Msgid-Bugs-To: \n"
    "POT-Creation-Date: 2009-11-14 18:16-0500\n"
    "PO-Revision-Date: \n"
    "Last-Translator: Андрей <usja@4life.com.ua>\n"
    "Language-Team: \n"
    "MIME-Version: 1.0\n"
    "Content-Type: text/plain; charset=UTF-8\n"
    "Content-Transfer-Encoding: 8bit\n"
    "X-Poedit-Language: English\n"
    "X-Poedit-Country: UNITED STATES\n"
    "X-Poedit-SourceCharset: utf-8\n"
    "X-Poedit-KeywordsList: translate\n"
    "X-Poedit-Basepath: /home/tmth/webdev/zftutorial\n"
    "X-Poedit-SearchPath-0: application\n"
    
    #: application/modules/library/views/scripts/books/list.phtml:4
    msgid " "
    msgstr " "
    
    msgid "Books"
    msgstr ""
    
    msgid "Shit"
    msgstr "Lajno"
    

    Ну и в конце концов, наш вид:

    <h2>Welcome to: <?= $this->translate('Shit'); ?></h2>
    

    Это кратко. Если копать глубже, точнее осознать как это всё должно работать, можно просидеть несколько дней.

    Zend_Navigation и построение меню из базы с использованием parent_id

    Как работать с Zend_Navigation написано в мануале, а вот как быть, если меню строится не из xml файла? Т.е. — динамически из базы?
    Начнем подготовку.

    основной bootstrap.php

        protected function _initNavigation() {
            $this->bootstrap('FrontController');
            if ($this->_navigation === null) {
                $front = $this->getResource('frontController');
                $navigation = new Plugin_UserMenu();
                $front->registerPlugin($navigation);
                $this->_navigation = $navigation;
            }
            return $this->_navigation;
        }
    

    Plugin_UserMenu — наш плагин, который, собственно, и будет генерировать данные для навигации.

    plugins/UserMenu.php

    <?php
    
    final class Plugin_UserMenu extends Zend_Controller_Plugin_Abstract {
    
        protected $_view;
        public function preDispatch(Zend_Controller_Request_Abstract $request) {
            $mapper = new Admin_Model_PagesMapper();
            $oData = $mapper->fetchAllAsArray();
            $data = Default_View_Helper_SelectParentIdCategories::Tree($oData);
            $layout = Zend_Layout::getMvcInstance();
            $this->_view = $layout->getView();
            $container = new Zend_Navigation();
            $container->setPages($data);
            $this->_view->navigation($container);
        }
    }
    

    Хитрость в fetchAllAsArray():

        public function fetchAllAsArray() {
            $where = $this->getDbTable()->select()
                    ->where('lang_id = ?', Zend_Registry::get('uds_lang_id'))
                    ->order('pr ASC');
            $resultSet = $this->getDbTable()->fetchAll($where);
            $entries = array();
            foreach ($resultSet as $row) {
                $entry['id'] = $row->id;
                $entry['parent_id'] = $row->parent_id;
                $entry['title'] = $row->title;
                $entry['label'] = $row->title;
                $entry['txt'] = $row->txt;
                $entry['kw'] = $row->kw;
                $entry['pic'] = $row->pic;
                $entry['visible'] = $row->visible;
                $entry['external_url'] = $row->external_url;
                $entry['uri'] = $row->external_url;
                $entries[] = $entry;
            }
            return $entries;
        }
    

    $entry['uri'] и $entry['label'] = $row->title используются именно для построения Zend_Navigation. Можно, конечно, при проектировании бд назвать поля таблицы сразу, как хочет zend, но не всегда удобно. По этому так.

    Не забываем, что у нас меню использует древовидную структуру по parent_id. Из мануала Zend_Navigation можно посмотреть пример массива, в каком виде нужно его передавать для Zend_Navigation. Собственно, нам осталось лишь подготовить сам массив. На одном форуме, нашел прекрасную функцию, которая сортирует дерево типа parent_id с помощью всего одного запроса и без рекурсии. Эта функция и вызывывается Default_View_Helper_SelectParentIdCategories::Tree($oData);

    Default_View_Helper_SelectParentIdCategories::Tree

    <?
    
    /* * *************************************************
     * Выкидывает селект под парент id
     */
    
    class Default_View_Helper_SelectParentIdCategories {
    
        public function Tree($rows) {
            $children = array(); // children of each ID
            $ids = array();
            $idName = 'id';
            $pidName = 'parent_id';
            // Collect who are children of whom.
            foreach ($rows as $i => $r) {
                $row = & $rows[$i];
                //$d['label'] = $rows[$i]['title'];
                //$row[] = $d;
                $id = $row[$idName];
                if ($id === null) {
                    continue;
                }
                $pid = $row[$pidName];
                if ($id == $pid)
                    $pid = null;
                $children[$pid][$id] = & $row;
    
                if (!isset($children[$id]))
                    $children[$id] = array();
                $row['pages'] = & $children[$id];
                $ids[$id] = true;
            }
            // Root elements are elements with non-found PIDs.
            $forest = array();
            foreach ($rows as $i => $r) {
                $row = & $rows[$i];
                $id = $row[$idName];
                $pid = $row[$pidName];
                if ($pid == $id)
                    $pid = null;
                if (!isset($ids[$pid])) {
                    $forest[$row[$idName]] = & $row;
                }
                //unset($row[$idName]);
                //unset($row[$pidName]);
            }
            //echo '<pre>';
            //print_r($forest);
             return $forest;
        }
    
        /*     * ******************************** */
    }
    

    Ну и вывод меню в layout:

    <?php print( $this->navigation()->menu()->renderMenu() ); ?>
    

    PS: Кто заметил Zend_Registry::get(‘uds_lang_id’)? Позже будет статья, как сделать мультиязычный сайт с неограниченным количеством языков.

    Zend Framework сложные запросы по условию

    $where = "((group_id = ? OR format_id = ?) AND color_id = ?)";
    $values = array($groupId, $formatId, $colorId);
    
    foreach($values as $value)
        $where = $this->_db->quoteInto($where, $value , '', 1);
    

    Zend_Date и Opera (IE) против Firefox (Chrome)

    Имеем код:

    $ask = '22.02.20012';
    $ar = explode('.', $ask);
    $datearray = array ('year' => $ar[2], 'month' => $ar[1], 'day' => $ar[0]);
    $date = new Zend_Date($datearray);
    $now = date('Y-m-d 00:00:00', strtotime($date));
    $tomorrow = $date->add('24', Zend_Date::HOUR);
    

    Что нам выдаст Firefox и Сhrome?
    [b]now = 2012-02-22 00:00:00
    tomorrow = 2012-02-22 00:00:00
    [/b]
    а вот Opera и IE, в зависимости от локали:
    [b]
    now = 1970-01-01 00:00:00
    tomorrow = 1970-01-02 00:00:00
    [/b]
    хм… копаем, что же у нас в переменной date в IE:
    [b]
    date = 22 Фев 2012
    [/b]

    Видите месяц в Opera?
    Решение нашел — использовать Zend_Locale:

    $ar = explode('.', $ask);
    $datearray = array ('year' => $ar[2], 'month' => $ar[1], 'day' => $ar[0]);
    $date = new Zend_Date($datearray, new Zend_Locale('en_UK'));
    $now = date('Y-m-d 00:00:00', strtotime($date));
    $tomorrow = $date->add('24', Zend_Date::HOUR);
    

    Полезные записки по Zend Framework

    Оставляю себе для быстрого доступа полезняшки

    ApplicationController.php
    class ApplicationController extends Zend_Controller_Action
    {
        public function __construct(...)
        {
            //...
            // this tells the framework to run the MenuController after this
            $this->_helper->actionStack('application', 'menu');
        }
    }
    
    MenuController.php
    class MenuController extends Zend_Controller_Action
    {
        public function applicationAction
        {
            // we don't want to append the menu to the end
            // of the layout content, so:
            $this->_helper->viewRenderer->setResponseSegment('menu');
            $this->view->menu = array('x', 'y', 'z');
        }
    
        public function anotherAction
        {
            $this->_helper->viewRenderer->setResponseSegment('menu');
            $this->view->menu = array('a', 'b', 'b');
        }
    }
    
    layout.phtml (/layouts/)
    <html><head></head><body>
    
    <?= $this->layout()->menu; ?>
    
    <?= $this->layout()->content; ?>
    
    </body></html>
    
    application.phtml (in /views/scripts/menu/)
    <ul>
    <?php foreach( $this->menu as $m ): ?>
      <li><?= $m ?></li>
    <?php endforeach; ?>
    </ul>
    
    another.phtml (in /views/scripts/menu/)
    <ul>
    <?php foreach( $this->menu as $m ): ?>
      <li><?= $m ?></li>
    <?php endforeach; ?>
    </ul>
    

    © http://teethgrinder.co.uk/perm.php?a=Zend-Framework-Menus-Navigation

    Регистрация хелперов в бутстрап:

    $view->addHelperPath('AP/View/Helper/', 'AP_View_Helper');

    Zend_Log или пишем собственный лог PHP в Zend Framework

    Теперь имеем собственный лог. Очень полезно, когда сервер лог не предоставляет, или при работе ошибок нет.
    Добавляем в Bootstrap.php

    $logger = new Zend_Log();
    $writer = new Zend_Log_Writer_Stream(APPLICATION_PATH . './logs/php_errors.log');
    $logger->addWriter($writer);
    $logger->registerErrorHandler();
    

    PHP Fatal error: Cannot access property started with ‘\\0′ inZend/View/Abstract.php on line 308

    После «тихого» обновления PHP и MySql сайт на ZENDе начал вылетать с такой ошибкой:
    PHP Fatal error: Cannot access property started with ‘\\0′ inZend/View/Abstract.php on line 308
    Идём в Abstract.php на 308 строку, видим:

        /**
         * Directly assigns a variable to the view script.
         *
         * Checks first to ensure that the caller is not attempting to set a
         * protected or private member (by checking for a prefixed underscore); if
         * not, the public member is set; otherwise, an exception is raised.
         *
         * @param string $key The variable name.
         * @param mixed $val The variable value.
         * @return void
         * @throws Zend_View_Exception if an attempt to set a private or protected
         * member is detected
         */
        public function __set($key, $val)
        {
            if ('_' != substr($key, 0, 1)) {
                $this->$key = $val;
                return;
            }
    
            require_once 'Zend/View/Exception.php';
            $e = new Zend_View_Exception('Setting private or protected class members is not allowed');
            $e->setView($this);
            throw $e;
        }
    

    На 308 строке нас поджидает: $this->$key = $val;

    Решение кроется в $key = trim($key);

    Должны получить:

        public function __set($key, $val)
        {
            if ('_' != substr($key, 0, 1)) {
                $key = trim($key);
                $this->$key = $val;
                return;
            }
    
            require_once 'Zend/View/Exception.php';
            $e = new Zend_View_Exception('Setting private or protected class members is not allowed');
            $e->setView($this);
            throw $e;
        }
    

    И все, должно заработать.

    Конфиг сервака, на котором слетело:
    PHP Version 5.3.6
    System FreeBSD ***.co.ua 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #1: Mon Jul 11 16:23:06 EEST 2011 admin@***.co.ua:/usr/obj/usr/src/sys/*** i386
    Apache Version Apache/2.2.17 (FreeBSD) mod_ssl/2.2.19 OpenSSL/0.9.8q DAV/2 PHP/5.3.6 SVN/1.6.17

    Функция, которая выводит глубину элемента в (id, parent_id)

        public function getRoot($id)
        {
    
            if ($id > 0)
            {
                $sql = $this->getAdapter()->select()
                        ->from('pages', array('parent_id'))
                        ->where('id = ?', $id)
                        ->limit('1');
                $stmt = $this->getAdapter()->query($sql);
                $result = $stmt->fetchObject();
    
                if ($result->parent_id > 0)
                {
                    $this->depth++;
                    $this->getRoot($result->parent_id);
                }
                return $this->depth;
            }
        }