Содержание


Контейнер


Containers, Navigation, ЗФ2, Zend Framework 2, ZF2, ру, ru




В контейнерах находятся методы для добавления, получения, удаления и итерирования страниц. Реализуют SPL интерфейсы RecursiveIterator и Countable, что дает возможность перебирать контейнер используя SPL класс RecursiveIteratorIterator.

 

Создание контейнера

 

Zend\Navigation\Container – абстрактен и не может использоваться напрямую .Для инициализации контейнера необходимо использовать Zend\Navigation.

 

Zend\Navigation может быть создан пустым или в конструктор передан массив, или объект Zend\Config со страницами, которые будут размещены в контейнере. Каждая страница, переданная в массиве или Zend\Config будет передана в метод «addPage()» класса контейнера. Каждый элемент массива или Zend\Config должен быть в свою очередь массивом, объектом Config или экземпляром Zend\Navigation\Page\AbstractPage.

 

Создание контейнера используя массив:

/*
 * Create a container from an array
 *
 * Each element in the array will be passed to
 * ZendNavigationPageAbstractPage::factory() when constructing.
 */
$container = new Zend\Navigation\Navigation(array(
    array(
        'label' => 'Page 1',
        'id' => 'home-link',
        'uri' => '/',
    ),
    array(
        'label' => 'Zend',
        'uri' => 'http://www.zend-project.com/',
        'order' => 100,
    ),
    array(
        'label' => 'Page 2',
        'controller' => 'page2',
        'pages' => array(
            array(
                'label' => 'Page 2.1',
                'action' => 'page2_1',
                'controller' => 'page2',
                'class' => 'special-one',
                'title' => 'This element has a special class',
                'active' => true,
            ),
            array(
                'label' => 'Page 2.2',
                'action' => 'page2_2',
                'controller' => 'page2',
                'class' => 'special-two',
                'title' => 'This element has a special class too',
            ),
        ),
    ),
    array(
        'label' => 'Page 2 with params',
        'action' => 'index',
        'controller' => 'page2',
        // specify a param or two,
        'params' => array(
            'format' => 'json',
            'foo' => 'bar',
        )
    ),
    array(
        'label' => 'Page 2 with params and a route',
        'action' => 'index',
        'controller' => 'page2',
        // specify a route name and a param for the route
        'route' => 'nav-route-example',
        'params' => array(
            'format' => 'json',
        ),
    ),
    array(
        'label' => 'Page 3',
        'action' => 'index',
        'controller' => 'index',
        'module' => 'mymodule',
        'reset_params' => false,
    ),
    array(
        'label' => 'Page 4',
        'uri' => '#',
        'pages' => array(
            array(
                'label' => 'Page 4.1',
                'uri' => '/page4',
                'title' => 'Page 4 using uri',
                'pages' => array(
                    array(
                        'label' => 'Page 4.1.1',
                        'title' => 'Page 4 using mvc params',
                        'action' => 'index',
                        'controller' => 'page4',
                        // let's say this page is active
                        'active' => '1',
                    )
                ),
            ),
        ),
    ),
    array(
        'label' => 'Page 0?',
        'uri' => '/setting/the/order/option',
        // setting order to -1 should make it appear first
        'order' => -1,
    ),
    array(
        'label' => 'Page 5',
        'uri' => '/',
        // this page should not be visible
        'visible' => false,
        'pages' => array(
            array(
                'label' => 'Page 5.1',
                'uri' => '#',
                'pages' => array(
                    array(
                        'label' => 'Page 5.1.1',
                        'uri' => '#',
                        'pages' => array(
                            array(
                                'label' => 'Page 5.1.2',
                                'uri' => '#',
                                // let's say this page is active
                                'active' => true,
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
    array(
        'label' => 'ACL page 1 (guest)',
        'uri' => '#acl-guest',
        'resource' => 'nav-guest',
        'pages' => array(
            array(
                'label' => 'ACL page 1.1 (foo)',
                'uri' => '#acl-foo',
                'resource' => 'nav-foo',
            ),
            array(
                'label' => 'ACL page 1.2 (bar)',
                'uri' => '#acl-bar',
                'resource' => 'nav-bar',
            ),
            array(
                'label' => 'ACL page 1.3 (baz)',
                'uri' => '#acl-baz',
                'resource' => 'nav-baz',
            ),
            array(
                'label' => 'ACL page 1.4 (bat)',
                'uri' => '#acl-bat',
                'resource' => 'nav-bat',
            ),
        ),
    ),
    array(
        'label' => 'ACL page 2 (member)',
        'uri' => '#acl-member',
        'resource' => 'nav-member',
    ),
    array(
        'label' => 'ACL page 3 (admin',
        'uri' => '#acl-admin',
        'resource' => 'nav-admin',
        'pages' => array(
            array(
                'label' => 'ACL page 3.1 (nothing)',
                'uri' => '#acl-nada',
            ),
        ),
    ),
    array(
        'label' => 'Zend Framework',
        'route' => 'zf-route',
    ),
));

Создание контейнера используя объект Config:

/* CONTENTS OF /path/to/navigation.xml:
<?xml version="1.0" encoding="UTF-8"?>
"><config>
    "><nav>
 
        "><zend>
            "><label>Zend"></label>
            "><uri>http://www.zend-project.com/"></uri>
            "><order>100"></order>
        "></zend>
 
        "><page1>
            <label>Page 1</label>
            <uri>page1</uri>
            <pages>
 
                <page1_1>
                    <label>Page 1.1</label>
                    <uri>page1/page1_1</uri>
                </page1_1>
 
            </pages>
        </page1>
 
        <page2>
            <label>Page 2</label>
            <uri>page2</uri>
            <pages>
 
                <page2_1>
                    <label>Page 2.1</label>
                    <uri>page2/page2_1</uri>
                </page2_1>
 
                <page2_2>
                    <label>Page 2.2</label>
                    <uri>page2/page2_2</uri>
                    <pages>
 
                        <page2_2_1>
                            <label>Page 2.2.1</label>
                            <uri>page2/page2_2/page2_2_1</uri>
                        </page2_2_1>
 
                        <page2_2_2>
                            <label>Page 2.2.2</label>
              label span style=              <uri>page2/paspan style==color:#339933/spanlt;urige2_2/page2_2_2</ur
                span style=span style=color:#0000ffcolor:#000000;font-weight:boldi>
                            <active>1</active>
                        </page2_2_2>
 
                    </pages>
                </page2_2>
 
                <page2_3>
                    <label>Page 2.3</label>
                    <uri>page2/page2_3</uri>
                    <pages>
 
                        <page2_3_1>
                            <label>Page 2.3.1</label>
                            <uri>page2/page2_3/page2_3_1</uri>
                        </page2_3_1>
 
                        <page2_3_2>
                            <label>Page 2.3.2</label>
                            <uri>page2/page2_3/page2_3_2</uri>
                            <visible>0</visible>
                            <pages>
 
                                    <page2_3_2_1>
                                        <label>Page 2.3.2.1</label>
                                        <uri>page2/page2_3/page2_3_2/1</uri>
                                        <active>1</active>
                                    </page2_3_2_1>
 
                                    <page2_3_2_2>
                                        <label>Page 2.3.2.2</label>
                                        <uri>page2/page2_3/page2_3_2/2</uri>
                                        <active>1</active>
 
                                        <pages>
                                            <page_2_3_2_2_1>
                                                <label>Ignore</label>
                                                <uri>#</uri>
                                                <active>1</active>
                                            </page_2_3_2_2_1>
                                        </pages>
                                    </page2_3_2_2>
 
                            </pages>
                        </page2_3_2>
 
                        <page2_3_3>
                            <label>Page 2.3.3</label>
                            <uri>page2/page2_3/page2_3_3</uri>
                            <resource>admin</resource>
                            <pages>
 
                                    <page2_3_3_1>
                                        <label>Page 2.3.3.1</label>
                                        <uri>page2/page2_3/page2_3_3/1</uri>
                                        <active>1</active>
                                    </page2_3_3_1>
 
                                    <page2_3_3_2>
                                        <label>Page 2.3.3.2</label>
                                        <uri>page2/page2_3/page2_3_3/2</uri>
                                        <resource>guest</resource>
                                        <active>1</active>
                                    </page2_3_3_2>
 
                            </pages>
                        </page2_3_3>
 
                    </pages>
                </page2_3>
 
            </pages>
        </page2>
 
        <page3>
            <label>Page 3</label>
            <uri>page3</uri>
            <pages>
 
                <page3_1>
                    <label>Page 3.1</label>
                    <uri>page3/page3_1</uri>
                    <resource>guest</resource>
                </page3_1>
 
                <page3_2>
                    <label>Page 3.2</label>
                    <uri>page3/page3_2</uri>
                    <resource>member</resource>
                    <pages>
 
                        <page3_2_1>
                            <label>Page 3.2.1</label>
                            <uri>page3/page3_2/page3_2_1</uri>
                        </page3_2_1>
 
                        <page3_2_2>
                            <label>Page 3.2.2</label>
                            <uri>page3/page3_2/page3_2_2</uri>
                            <resource>admin</resource>
                        </page3_2_2>
 
                    </pages>
                </page3_2>
 
                <page3_3>
                    <label>Page 3.3</label>
                    <uri>page3/page3_3</uri>
                    <resource>special</resource>
                    <pages>
 
                        <page3_3_1>
                            <label>Page 3.3.1</label>
                            <uri>page3/page3_3/page3_3_1</uri>
                            <visible>0</visible>
                        </page3_3_1>
 
                        <page3_3_2>
                            <label>Page 3.3.2</label>
                            <uri>page3/page3_3/page3_3_2</uri>
                            <resource>admin</resource>
                        </page3_3_2>
 
                    </pages>
                </page3_3>
 
            </pages>
        </page3>
 
        <home>
            <label>Home</label>
            <order>-100</order>
            <module>default</module>
            <controller>index</controller>
            <action>index</action>
        </home>
 
    </nav>
</config>
 */
$config = new Zend\Config\Xml('/path/to/navigation.xml', 'nav');
$container = new Zend\Navigation\Navigation($config);

Добавление страниц

 

Добавление страниц в контейнер осуществляется при помощи методов «addPage()», «addPages()», «setPages()»:

 

// create container
$container = new Zend\Navigation\Navigation();
 
// add page by giving a page instance
$container->addPage(
    Zend\Navigation\Page\AbstractPage::factory(
        array(
            'uri' => 'http://www.example.com/',
        )
    )
);
 
// add page by giving an array
$container->addPage(
    array(
        'uri' => 'http://www.example.com/',
    )
);
 
// add page by giving a config object
$container->addPage(
    new Zend\Config(
        array(
            'uri' => 'http://www.example.com/',
        )
    )
);
 
$pages = array(
    array(
        'label'  => 'Save',
        'action' => 'save',
    ),
    array(
        'label' =>  'Delete',
        'action' => 'delete',
    )
);
 
// add two pages
$container->addPages($pages);
 
// remove existing pages and add the given pages
$container->setPages($pages);

Удаление страниц

 

 

Удаление страниц из контейнера осуществляется при помощи методов «removePage()», «removePages()».  Первый метод принимает как параметр экземпляр страницы или целое число. Целое число подразумевает порядковый номер страницы в контейне/span/spanре. Второй метод просто удалит все страницы в контейundefinedspan style=color:#000088нере.

$container = new Zend\Navigation\Navigation(array(
    array(
        'label'  => 'Page 1',
        'action' => 'page1',
    ),
    array(
        'label'  => 'Page 2',
        'action' => 'page2',
        'order'  => 200,
    ),
    array(
        'label'  => 'Page 3',
        'action' => 'page3',
    )
));
 
// remove page by implicit page order
$container->removePage(0);      // removes Page 1
 
// remove page by instance
$page3 = $container->findOneByAction('page3');
$container->removePage($page3); // removes Page 3
 
// remove page by explicit page order
$container->removePage(200);    // removes Page 2
 
// remove all pages
$container->removePages();      // removes all pages

Поиск страниц

 

В контейнере имеются методы для поиска и извлечения страниц: «findOneBy($property, $value)», «findAllBy($property, $value)», «findBy($property, $value, $all = false)». Эти методы рекурсивно перебирают контейнер в поиске страниц, совпадающих с заданной маской: «$page->$property == $value».

 

Метод «findOneBy()» - возвращает одну страницу при совпадении свойства с заданным значением или «NULL», если совпадение не найдено.

 

Метод «findAllBy ()» - вернет все страницы, удовлетворяющие заданным требованиям.

 

Метод «findBy()» - вызовет один из вышеописанных методов, в зависимости от флага «$all».

 

Эти методы так же можно вызывать магически, добавляя к названию метода (findBy, findOneBy, findAllBy) имя нужного свойства (Label, Title, Controller …).

Например: «findOneByLabel('Home')» - вернет первую страницу с «label==Home».

Например возможны такие комбинации: findByLabel(...), findOnyByTitle(...), findAllByController(...) и т.д.

Методы поиска так же работают с пользовательскими свойствами. Например: «findByFoo('bar')». 

$container = new Zend\Navigation\Navigation(array(
    array(
        'label' => 'Page 1',
        'uri'   => 'page-1',
        'foo'   => 'bar',
        'pages' => array(
            array(
                'label' => 'Page 1.1',
                'uri'   => 'page-1.1',
                'foo'   => 'bar',
            ),
            array(
                'label' => 'Page 1.2',
                'uri'   => 'page-1.2',
                'class' => 'my-class',
            ),
            array(
                'type'   => 'uri',
                'label'  => 'Page 1.3',
                'uri'    => 'page-1.3',
                'action' => 'about',
            )
        )
    ),
    array(
        'label'      => 'Page 2',
        'id'         => 'page_2_and_3',
        'class'      => 'my-class',
        'module'     => 'page2',
        'controller' => 'index',
        'action'     => 'page1',
    ),
    array(
        'label'      => 'Page 3',
        'id'         => 'page_2_and_3',
        'module'     => 'page3',
        'controller' => 'index',
    ),
));
 
// The 'id' is not required to be unique, but be aware that
// having two pages with the same id will render the same id attribute
// in menus and breadcrumbs.
$found = $container->findBy('id',
                            'page_2_and_3');      // returns Page 2
$found = $container->findOneBy('id',
                               'page_2_and_3');   // returns Page 2
$found = $container->findBy('id',
                            'page_2_and_3',
                            true);                // returns Page 2 and Page 3
$found = $container->findById('page_2_and_3');    // returns Page 2
$found = $container->findOneById('page_2_and_3'); // returns Page 2
$found = $container->findAllById('page_2_and_3'); // returns Page 2 and Page 3
 
// Find all matching CSS class my-class
$found = $container->findAllBy('class',
                               'my-class');       // returns Page 1.2 and Page 2
$found = $container->findAllByClass('my-class');  // returns Page 1.2 and Page 2
 
// Find first matching CSS class my-class
$found = $container->findOneByClass('my-class');  // returns Page 1.2
 
// Find all matching CSS class non-existant
$found = $container->findAllByClass('non-existant'); // returns array()
 
// Find first matching CSS class non-existant
$found = $container->findOneByClass('non-existant'); // returns null
 
// Find all pages with custom property 'foo' = 'bar'
$found = $container->findAllBy('foo', 'bar'); // returns Page 1 and Page 1.1
 
// To achieve the same magically, 'foo' must be in lowercase.
// This is because 'foo' is a custom property, and thus the
// property name is not normalized to 'Foo'
$found = $container->findAllByfoo('bar');
 
// Find all with controller = 'index'
$found = $container->findAllByController('index'); // returns Page 2 and Page 3

Итерация (перебор)  контейнера

 

Zend\Navigation\Container реализует интерфейс RecursiveIteratorIterator и может быть проитерирован, используя любой класс итерации. Для итерирования рекурсивно используйте класс RecursiveIteratorIterator.

/*
 * Create a container from an array
 */
$container = new Zend\Navigation\Navigation(array(
    array(
        'label' => 'Page 1',
        'uri'   => '#',
    ),
    array(
        'label' => 'Page 2',
        'uri'   => '#',
        'pages' => array(
            array(
                'label' => 'Page 2.1',
                'uri'   => '#',
            ),
            array(
                'label' => 'Page 2.2',
                'uri'   => '#',
            )
        )
    )
    array(
        'label' => 'Page 3',
        'uri'   => '#',
    ),
));
 
// Iterate flat using regular foreach:
// Output: Page 1, Page 2, Page 3
foreach ($container as $page) {
    echo $page->label;
}
 
// Iterate recursively using RecursiveIteratorIterator
$it = new RecursiveIteratorIterator(
        $container, RecursiveIteratorIterator::SELF_FIRST);
 
// Output: Page 1, Page 2, Page 2.1, Page 2.2, Page 3
foreach ($it as $page) {
    echo $page->label;
}

Другие операции

 

Метод «hasPage(Zend\Navigation\Page\AbstractPage $page)» проверяет, если в контейнере заданная страница.

 

Метод «hasPages()» проверяет в контейнере наличие как минимум 1 страницы. Эквивалентен:  «count($container) > 1».

 

Метод  «toArray()» конвертирует контейнер и страницы находящиеся в нем в массив. Может быть полезно при сериализации и отладке.

 

Конвертирование контейнера в массив:

$container = new Zend\Navigation\Navigation(array(
    array(
        'label' => 'Page 1',
        'uri'   => '#',
    ),
    array(
        'label' => 'Page 2',
        'uri'   => '#',
        'pages' => array(
            array(
                'label' => 'Page 2.1',
                'uri'   => '#',
            ),
            array(
                'label' => 'Page 2.2',
               'uri'   => '#',
            ),
        ),
    ),
));
 
var_dump($container->toArray());
 
/* Output:
array(2) {
  [0]=> array(15) {
    ["label"]=> string(6) "Page 1"
    ["id"]=> NULL
    ["class"]=> NULL
    ["title"]=> NULL
    ["target"]=> NULL
    ["rel"]=> array(0) {
    }
    ["rev"]=> array(0) {
    }
    ["order"]=> NULL
    ["resource"]=> NULL
    ["privilege"]=> NULL
    ["active"]=> bool(false)
    ["visible"]=> bool(true)
    ["type"]=> string(23) "ZendNavigationPageUri"
    ["pages"]=> array(0) {
    }
    ["uri"]=> string(1) "#"
  }
  [1]=> array(15) {
    ["label"]=> string(6) "Page 2"
    ["id"]=> NULL
    ["class"]=> NULL
    ["title"]=> NULL
    ["target"]=> NULL
    ["rel"]=> array(0) {
    }
    ["rev"]=> array(0) {
    }
    ["order"]=> NULL
    ["resource"]=> NULL
    ["privilege"]=> NULL
    ["active"]=> bool(false)
    ["visible"]=> bool(true)
    ["type"]=> string(23) "ZendNavigationPageUri"
    ["pages"]=> array(2) {
      [0]=> array(15) {
        ["label"]=> string(8) "Page 2.1"
        ["id"]=> NULL
        ["class"]=> NULL
        ["title"]=> NULL
        ["target"]=> NULL
        ["rel"]=> array(0) {
        }
        ["rev"]=> array(0) {
        }
        ["order"]=> NULL
        ["resource"]=> NULL
        ["privilege"]=> NULL
        ["active"]=> bool(false)
        ["visible"]=> bool(true)
        ["type"]=> string(23) "ZendNavigationPageUri"
        ["pages"]=> array(0) {
        }
        ["uri"]=> string(1) "#"
      }
      [1]=>
      array(15) {
        ["label"]=> string(8) "Page 2.2"
        ["id"]=> NULL
        ["class"]=> NULL
        ["title"]=> NULL
        ["target"]=> NULL
        ["rel"]=> array(0) {
        }
        ["rev"]=> array(0) {
        }
        ["order"]=> NULL
        ["resource"]=> NULL
        ["privilege"]=> NULL
        ["active"]=> bool(false)
        ["visible"]=> bool(true)
        ["type"]=> string(23) "ZendNavigationPageUri"
        ["pages"]=> array(0) {
        }
        ["uri"]=> string(1) "#"
      }
    }
    ["uri"]=> string(1) "#"
  }
}
*/


Автор статьи: DuB