<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<sect1 id="zend.navigation.containers">
    <title>Containers</title>

    <para>
        Containers have methods for adding, retrieving, deleting and
        iterating pages. Containers implement the
        <ulink url="http://php.net/spl">SPL</ulink> interfaces
        <classname>RecursiveIterator</classname> and
        <classname>Countable</classname>, meaning that a container can
        be iterated using the SPL
        <classname>RecursiveIteratorIterator</classname> class.
    </para>

    <sect2 id="zend.navigation.containers.creating">
        <title>Creating containers</title>

        <para>
            <classname>Zend_Navigation_Container</classname> is
            abstract, and can not be instantiated directly. Use
            <classname>Zend_Navigation</classname> if you want to
            instantiate a container.
        </para>

        <para>
            <classname>Zend_Navigation</classname> can be constructed
            entirely empty, or take an array or a
            <classname>Zend_Config</classname> object with pages to put in the
            container. Each page in the given array/config will eventually be
            passed to the <methodname>addPage()</methodname> method of the container class,
            which means that each element in the array/config can be an array or
            a config object, or a <classname>Zend_Navigation_Page</classname>
            instance.
        </para>

        <example id="zend.navigation.containers.creating.example.array">
            <title>Creating a container using an array</title>

            <programlisting language="php"><![CDATA[
/*
 * Create a container from an array
 *
 * Each element in the array will be passed to
 * Zend_Navigation_Page::factory() when constructing.
 */
$container = new Zend_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'
    )
));
]]></programlisting>
        </example>

        <example id="zend.navigation.containers.creating.example.config">
            <title>Creating a container using a config object</title>

            <para>
                Example for INI:
            </para>

            <programlisting language="ini"><![CDATA[
[nav]
zend.label = "Zend"
zend.uri = "http://www.zend-project.com/"
zend.order = "100"

page1.label = "Page 1"
page1.uri = "page1"
page1.pages.page1_1.label = "Page 1.1"
page1.pages.page1_1.uri = "page1/page1_1"

page2.label = "Page 2"
page2.uri = "page2"
page2.pages.page2_1.label = "Page 2.1"
page2.pages.page2_1.uri = "page2/page2_1"
page2.pages.page2_2.label = "Page 2.2"
page2.pages.page2_2.uri = "page2/page2_2"
page2.pages.page2_2.pages.page2_2_1.label = "Page 2.2.1"
page2.pages.page2_2.pages.page2_2_1.uri = "page2/page2_2/page2_2_1"
page2.pages.page2_2.pages.page2_2_2.label = "Page 2.2.2"
page2.pages.page2_2.pages.page2_2_2.uri = "page2/page2_2/page2_2_2"
page2.pages.page2_2.pages.page2_2_2.active = "1"
page2.pages.page2_3.label = "Page 2.3"
page2.pages.page2_3.uri = "page2/page2_3"
page2.pages.page2_3.pages.page2_3_1.label = "Page 2.3.1"
page2.pages.page2_3.pages.page2_3_1.uri = "page2/page2_3/page2_3_1"
page2.pages.page2_3.pages.page2_3_2.label = "Page 2.3.2"
page2.pages.page2_3.pages.page2_3_2.uri = "page2/page2_3/page2_3_2"
page2.pages.page2_3.pages.page2_3_2.visible = "0"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_1.label = "Page 2.3.2.1"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_1.uri = "page2/page2_3/page2_3_2/1"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_1.active = "1"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_2.label = "Page 2.3.2.2"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_2.uri = "page2/page2_3/page2_3_2/2"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_2.active = "1"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_2.pages.page_2_3_2_2_1.label = "Ignore"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_2.pages.page_2_3_2_2_1.uri = "#"
page2.pages.page2_3.pages.page2_3_2.pages.page2_3_2_2.pages.page_2_3_2_2_1.active = "1"
page2.pages.page2_3.pages.page2_3_3.label = "Page 2.3.3"
page2.pages.page2_3.pages.page2_3_3.uri = "page2/page2_3/page2_3_3"
page2.pages.page2_3.pages.page2_3_3.resource = "admin"
page2.pages.page2_3.pages.page2_3_3.pages.page2_3_3_1.label = "Page 2.3.3.1"
page2.pages.page2_3.pages.page2_3_3.pages.page2_3_3_1.uri = "page2/page2_3/page2_3_3/1"
page2.pages.page2_3.pages.page2_3_3.pages.page2_3_3_1.active = "1"
page2.pages.page2_3.pages.page2_3_3.pages.page2_3_3_2.label = "Page 2.3.3.2"
page2.pages.page2_3.pages.page2_3_3.pages.page2_3_3_2.uri = "page2/page2_3/page2_3_3/2"
page2.pages.page2_3.pages.page2_3_3.pages.page2_3_3_2.resource = "guest"
page2.pages.page2_3.pages.page2_3_3.pages.page2_3_3_2.active = "1"

page3.label = "Page 3"
page3.uri = "page3"
page3.pages.page3_1.label = "Page 3.1"
page3.pages.page3_1.uri = "page3/page3_1"
page3.pages.page3_1.resource = "guest"
page3.pages.page3_2.label = "Page 3.2"
page3.pages.page3_2.uri = "page3/page3_2"
page3.pages.page3_2.resource = "member"
page3.pages.page3_2.pages.page3_2_1.label = "Page 3.2.1"
page3.pages.page3_2.pages.page3_2_1.uri = "page3/page3_2/page3_2_1"
page3.pages.page3_2.pages.page3_2_2.label = "Page 3.2.2"
page3.pages.page3_2.pages.page3_2_2.uri = "page3/page3_2/page3_2_2"
page3.pages.page3_2.pages.page3_2_2.resource = "admin"
page3.pages.page3_3.label = "Page 3.3"
page3.pages.page3_3.uri = "page3/page3_3"
page3.pages.page3_3.resource = "special"
page3.pages.page3_3.pages.page3_3_1.label = "Page 3.3.1"
page3.pages.page3_3.pages.page3_3_1.uri = "page3/page3_3/page3_3_1"
page3.pages.page3_3.pages.page3_3_1.visible = "0"
page3.pages.page3_3.pages.page3_3_2.label = "Page 3.3.2"
page3.pages.page3_3.pages.page3_3_2.uri = "page3/page3_3/page3_3_2"
page3.pages.page3_3.pages.page3_3_2.resource = "admin"

home.label = "Home"
home.order = "-100"
home.module = "default"
home.controller = "index"
home.action = "index"
]]></programlisting>

            <programlisting language="php"><![CDATA[
$config    = new Zend_Config_Ini('/path/to/navigation.ini', 'nav');
$container = new Zend_Navigation($config);
]]></programlisting>

            <para>
                Example for JSON:
            </para>

            <programlisting language="json"><![CDATA[
{
  "nav": {
    "zend": {
      "label": "Zend",
      "uri": "http:\/\/www.zend-project.com\/",
      "order": "100"
    },
    "page1": {
      "label": "Page 1",
      "uri": "page1",
      "pages": {
        "page1_1": {
          "label": "Page 1.1",
          "uri": "page1\/page1_1"
        }
      }
    },
    "page2": {
      "label": "Page 2",
      "uri": "page2",
      "pages": {
        "page2_1": {
          "label": "Page 2.1",
          "uri": "page2\/page2_1"
        },
        "page2_2": {
          "label": "Page 2.2",
          "uri": "page2\/page2_2",
          "pages": {
            "page2_2_1": {
              "label": "Page 2.2.1",
              "uri": "page2\/page2_2\/page2_2_1"
            },
            "page2_2_2": {
              "label": "Page 2.2.2",
              "uri": "page2\/page2_2\/page2_2_2",
              "active": "1"
            }
          }
        },
        "page2_3": {
          "label": "Page 2.3",
          "uri": "page2\/page2_3",
          "pages": {
            "page2_3_1": {
              "label": "Page 2.3.1",
              "uri": "page2\/page2_3\/page2_3_1"
            },
            "page2_3_2": {
              "label": "Page 2.3.2",
              "uri": "page2\/page2_3\/page2_3_2",
              "visible": "0",
              "pages": {
                "page2_3_2_1": {
                  "label": "Page 2.3.2.1",
                  "uri": "page2\/page2_3\/page2_3_2\/1",
                  "active": "1"
                },
                "page2_3_2_2": {
                  "label": "Page 2.3.2.2",
                  "uri": "page2\/page2_3\/page2_3_2\/2",
                  "active": "1",
                  "pages": {
                    "page_2_3_2_2_1": {
                      "label": "Ignore",
                      "uri": "#",
                      "active": "1"
                    }
                  }
                }
              }
            },
            "page2_3_3": {
              "label": "Page 2.3.3",
              "uri": "page2\/page2_3\/page2_3_3",
              "resource": "admin",
              "pages": {
                "page2_3_3_1": {
                  "label": "Page 2.3.3.1",
                  "uri": "page2\/page2_3\/page2_3_3\/1",
                  "active": "1"
                },
                "page2_3_3_2": {
                  "label": "Page 2.3.3.2",
                  "uri": "page2\/page2_3\/page2_3_3\/2",
                  "resource": "guest",
                  "active": "1"
                }
              }
            }
          }
        }
      }
    },
    "page3": {
      "label": "Page 3",
      "uri": "page3",
      "pages": {
        "page3_1": {
          "label": "Page 3.1",
          "uri": "page3\/page3_1",
          "resource": "guest"
        },
        "page3_2": {
          "label": "Page 3.2",
          "uri": "page3\/page3_2",
          "resource": "member",
          "pages": {
            "page3_2_1": {
              "label": "Page 3.2.1",
              "uri": "page3\/page3_2\/page3_2_1"
            },
            "page3_2_2": {
              "label": "Page 3.2.2",
              "uri": "page3\/page3_2\/page3_2_2",
              "resource": "admin"
            }
          }
        },
        "page3_3": {
          "label": "Page 3.3",
          "uri": "page3\/page3_3",
          "resource": "special",
          "pages": {
            "page3_3_1": {
              "label": "Page 3.3.1",
              "uri": "page3\/page3_3\/page3_3_1",
              "visible": "0"
            },
            "page3_3_2": {
              "label": "Page 3.3.2",
              "uri": "page3\/page3_3\/page3_3_2",
              "resource": "admin"
            }
          }
        }
      }
    },
    "home": {
      "label": "Home",
      "order": "-100",
      "module": "default",
      "controller": "index",
      "action": "index"
    }
  }
}
]]></programlisting>

            <programlisting language="php"><![CDATA[
$config    = new Zend_Config_Json('/path/to/navigation.json', 'nav');
$container = new Zend_Navigation($config);
]]></programlisting>

            <para>
                Example for XML:
            </para>

            <programlisting language="xml"><![CDATA[
<?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>
                            <uri>page2/page2_2/page2_2_2</uri>
                            <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>
]]></programlisting>

            <programlisting language="php"><![CDATA[
$config    = new Zend_Config_Xml('/path/to/navigation.xml', 'nav');
$container = new Zend_Navigation($config);
]]></programlisting>

            <para>
                Example for YAML:
            </para>

            <programlisting language="yaml"><![CDATA[
nav: 
  zend: 
    label: Zend
    uri: http://www.zend-project.com/
    order: 100
  page1: 
    label: Page 1
    uri: page1
    pages: 
      page1_1: 
        label: Page 1.1
        uri: page1/page1_1
  page2: 
    label: Page 2
    uri: page2
    pages: 
      page2_1: 
        label: Page 2.1
        uri: page2/page2_1
      page2_2: 
        label: Page 2.2
        uri: page2/page2_2
        pages: 
          page2_2_1: 
            label: Page 2.2.1
            uri: page2/page2_2/page2_2_1
          page2_2_2: 
            label: Page 2.2.2
            uri: page2/page2_2/page2_2_2
            active: 1
      page2_3: 
        label: Page 2.3
        uri: page2/page2_3
        pages: 
          page2_3_1: 
            label: Page 2.3.1
            uri: page2/page2_3/page2_3_1
          page2_3_2: 
            label: Page 2.3.2
            uri: page2/page2_3/page2_3_2
            visible: 0
            pages: 
              page2_3_2_1: 
                label: Page 2.3.2.1
                uri: page2/page2_3/page2_3_2/1
                active: 1
              page2_3_2_2: 
                label: Page 2.3.2.2
                uri: page2/page2_3/page2_3_2/2
                active: 1
                pages: 
                  page_2_3_2_2_1: 
                    label: Ignore
                    uri: #
                    active: 1
          page2_3_3: 
            label: Page 2.3.3
            uri: page2/page2_3/page2_3_3
            resource: admin
            pages: 
              page2_3_3_1: 
                label: Page 2.3.3.1
                uri: page2/page2_3/page2_3_3/1
                active: 1
              page2_3_3_2: 
                label: Page 2.3.3.2
                uri: page2/page2_3/page2_3_3/2
                resource: guest
                active: 1
  page3: 
    label: Page 3
    uri: page3
    pages: 
      page3_1: 
        label: Page 3.1
        uri: page3/page3_1
        resource: guest
      page3_2: 
        label: Page 3.2
        uri: page3/page3_2
        resource: member
        pages: 
          page3_2_1: 
            label: Page 3.2.1
            uri: page3/page3_2/page3_2_1
          page3_2_2: 
            label: Page 3.2.2
            uri: page3/page3_2/page3_2_2
            resource: admin
      page3_3: 
        label: Page 3.3
        uri: page3/page3_3
        resource: special
        pages: 
          page3_3_1: 
            label: Page 3.3.1
            uri: page3/page3_3/page3_3_1
            visible: 0
          page3_3_2: 
            label: Page 3.3.2
            uri: page3/page3_3/page3_3_2
            resource: admin
  home: 
    label: Home
    order: -100
    module: default
    controller: index
    action: index
]]></programlisting>

            <programlisting language="php"><![CDATA[
$config    = new Zend_Config_Yaml'/path/to/navigation.yaml', 'nav');
$container = new Zend_Navigation($config);
]]></programlisting>

        </example>
    </sect2>

    <sect2 id="zend.navigation.containers.adding">
        <title>Adding pages</title>

        <para>
            Adding pages to a container can be done with the methods
            <methodname>addPage()</methodname>, <methodname>addPages()</methodname>, or
            <methodname>setPages()</methodname>. See examples below for explanation.
        </para>

        <example id="zend.navigation.containers.adding.example">
            <title>Adding pages to a container</title>

            <programlisting language="php"><![CDATA[
// create container
$container = new Zend_Navigation();

// add page by giving a page instance
$container->addPage(Zend_Navigation_Page::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);

// add container
$container->addPages(new Zend_Navigation(array(
    array(
        'label'  => 'Move up',
        'action' => 'up',
    ),
    array(
        'label'  => 'Move down',
        'action' => 'down',
    ),
)));

// remove existing pages and add the given pages
$container->setPages($pages);
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.navigation.containers.removing">
        <title>Removing pages</title>

        <para>
            Removing pages can be done with <methodname>removePage()</methodname> or
            <methodname>removePages()</methodname>. The first method accepts a an instance
            of a page, or an integer. The integer corresponds to the
            <property>order</property> a page has. The latter method will remove all
            pages in the container.
        </para>

        <example id="zend.navigation.containers.removing.example">
            <title>Removing pages from a container</title>

            <programlisting language="php"><![CDATA[
$container = new Zend_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
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.navigation.containers.finding">
        <title>Finding pages</title>

        <para>
            Containers have finder methods for retrieving pages.
            They are <methodname>findOneBy($property, $value, $useRegex = false)</methodname>,
            <methodname>findAllBy($property, $value, $useRegex = false)</methodname>, and
            <methodname>findBy($property, $value, $all = false, $useRegex = false)</methodname>.
            Those methods will recursively search the container for
            pages matching the given <command>$page->$property == $value</command>
            or when regular expressions are used: 
            <command>preg_match($value, $page->$property)</command>.
            The first method, <methodname>findOneBy()</methodname>, will return a
            single page matching the property with the given value, or
            <constant>NULL</constant> if it cannot be found. The second method will return
            all pages with a property matching the given value. The third
            method will call one of the two former methods depending on the
            <varname>$all</varname> flag.
        </para>

        <para>
            The finder methods can also be used magically by appending the
            property name to <property>findBy</property>, <property>findOneBy</property>, or
            <property>findAllBy</property>, e.g. <methodname>findOneByLabel('Home')</methodname> to
            return the first matching page with label 'Home'.
            Other combinations are <methodname>findByLabel(...)</methodname>,
            <methodname>findOnyByTitle(...)</methodname>,
            <methodname>findAllByController(...)</methodname>, etc. Finder
            methods also work on custom properties, such as
            <methodname>findByFoo('bar')</methodname>.
        </para>

        <example id="zend.navigation.containers.finding.example">
            <title>Finding pages in a container</title>

            <programlisting language="php"><![CDATA[
$container = new Zend_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
]]></programlisting>

            <para>
                Use regular expressions to find pages:
            </para>
            
            <programlisting language="php"><![CDATA[
$found = $container->findBy('class','/my/', false, true); // returns Page 1.2
$found = $container->findOneBy('class', '/my/', true); // returns Page 1.2
$found = $container->findBy('class', '/my/', true, true); // returns Page 1.2 and Page 2
$found = $container->findAllBy('class', '/my/', true); // returns Page 1.2 and Page 2
$found = $container->findOneByClass('/my/', true); // returns Page 1.2
$found = $container->findAllByClass('/my/', true); // returns Page 1.2 and Page 2
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.navigation.containers.iterating">
        <title>Iterating containers</title>

        <para>
            <classname>Zend_Navigation_Container</classname> implements
            <classname>RecursiveIteratorIterator</classname>, and can be
            iterated using any <classname>Iterator</classname> class. To iterate
            a container recursively, use the
            <classname>RecursiveIteratorIterator</classname> class.
        </para>

        <example id="zend.navigation.containers.iterating.example">
            <title>Iterating a container</title>

            <programlisting language="php"><![CDATA[
/*
 * Create a container from an array
 */
$container = new Zend_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;
}
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.navigation.containers.other">
        <title>Other operations</title>

        <para>
            The method <methodname>hasPage(Zend_Navigation_Page $page)</methodname> checks
            if the container has the given page. The method <methodname>hasPages()</methodname>
            checks if there are any pages in the container, and is equivalent
            to <command>count($container) > 1</command>.
        </para>

        <para>
            The <methodname>toArray()</methodname> method converts the container and the
            pages in it to an array. This can be useful for serializing and
            debugging.
        </para>

        <example id="zend.navigation.containers.other.example.toarray">
            <title>Converting a container to an array</title>

            <programlisting language="php"><![CDATA[
$container = new Zend_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) "Zend_Navigation_Page_Uri"
    ["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) "Zend_Navigation_Page_Uri"
    ["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) "Zend_Navigation_Page_Uri"
        ["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) "Zend_Navigation_Page_Uri"
        ["pages"]=> array(0) {
        }
        ["uri"]=> string(1) "#"
      }
    }
    ["uri"]=> string(1) "#"
  }
}
*/
]]></programlisting>
        </example>
    </sect2>
</sect1>
