• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

timber / timber / 5690057835

pending completion
5690057835

push

github

nlemoine
Merge branch '2.x' of github.com:timber/timber into 2.x-refactor-file-models

# Conflicts:
#	src/Attachment.php
#	src/ExternalImage.php
#	src/FileSize.php
#	src/URLHelper.php

1134 of 1134 new or added lines in 55 files covered. (100.0%)

3923 of 4430 relevant lines covered (88.56%)

59.08 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.83
/src/PagesMenu.php
1
<?php
2

3
namespace Timber;
4

5
use stdClass;
6
use WP_Post;
7

8
/**
9
 * Class PagesMenu
10
 *
11
 * Uses get_pages() to retrieve a list pages and returns it as a Timber menu.
12
 *
13
 * @see get_pages()
14
 *
15
 * @api
16
 * @since 2.0.0
17
 */
18
class PagesMenu extends Menu
19
{
20
    /**
21
     * Initializes a pages menu.
22
     *
23
     * @api
24
     *
25
     * @param null  $menu Unused. Only here for compatibility with the Timber\Menu class.
26
     * @param array $args Optional. Args for wp_list_pages().
27
     *
28
     * @return \Timber\PagesMenu
29
     */
30
    public static function build($menu, $args = []): ?self
31
    {
32
        /**
33
         * Default arguments from wp_page_menu() function.
34
         *
35
         * @see wp_page_menu()
36
         */
37
        $defaults = [
10✔
38
            'sort_column' => 'menu_order, post_title',
10✔
39
            'echo' => true,
10✔
40
            'link_before' => '',
10✔
41
            'link_after' => '',
10✔
42
            'before' => '<ul>',
10✔
43
            'after' => '</ul>',
10✔
44
            'item_spacing' => 'discard',
10✔
45
            'walker' => '',
10✔
46
            'menu_id' => '',
10✔
47
            'menu_class' => 'menu',
10✔
48
            'container' => 'div',
10✔
49
        ];
10✔
50

51
        $args = \wp_parse_args($args, $defaults);
10✔
52

53
        if (!\in_array($args['item_spacing'], ['preserve', 'discard'], true)) {
10✔
54
            // Invalid value, fall back to default.
55
            $args['item_spacing'] = $defaults['item_spacing'];
×
56
        }
57

58
        /**
59
         * Filters the arguments used to generate a page-based menu.
60
         *
61
         * @see wp_page_menu()
62
         *
63
         * @param array $args An array of page menu arguments. See wp_page_menu() for information on
64
         *                    accepted arguments.
65
         */
66
        $args = \apply_filters('wp_page_menu_args', $args);
10✔
67

68
        /**
69
         * Default arguments from wp_list_pages() function.
70
         *
71
         * @see wp_list_pages()
72
         */
73
        $defaults = [
10✔
74
            'depth' => 0,
10✔
75
            'show_date' => '',
10✔
76
            'date_format' => \get_option('date_format'),
10✔
77
            'child_of' => 0,
10✔
78
            'exclude' => '',
10✔
79
            'title_li' => \__('Pages'),
10✔
80
            'echo' => 1,
10✔
81
            'authors' => '',
10✔
82
            'sort_column' => 'menu_order, post_title',
10✔
83
            'link_before' => '',
10✔
84
            'link_after' => '',
10✔
85
            'item_spacing' => 'preserve',
10✔
86
            'walker' => '',
10✔
87
        ];
10✔
88

89
        $args = \wp_parse_args($args, $defaults);
10✔
90

91
        if (!\in_array($args['item_spacing'], ['preserve', 'discard'], true)) {
10✔
92
            // Invalid value, fall back to default.
93
            $args['item_spacing'] = $defaults['item_spacing'];
×
94
        }
95

96
        // Sanitize, mostly to keep spaces out.
97
        $args['exclude'] = \preg_replace('/[^0-9,]/', '', $args['exclude']);
10✔
98

99
        // Allow plugins to filter an array of excluded pages (but don't put a nullstring into the array).
100
        $exclude_array = ($args['exclude'])
10✔
101
            ? \explode(',', $args['exclude'])
×
102
            : [];
10✔
103

104
        /**
105
         * Filters the array of pages to exclude from the pages list.
106
         *
107
         * @param string[] $exclude_array An array of page IDs to exclude.
108
         */
109
        $args['exclude'] = \implode(',', \apply_filters('wp_list_pages_excludes', $exclude_array));
10✔
110

111
        $args['hierarchical'] = 0;
10✔
112

113
        $pages_menu = new static(null, $args);
10✔
114

115
        // Query pages.
116
        $menu_items = \get_pages($pages_menu->args);
10✔
117

118
        if (!empty($menu_items)) {
10✔
119
            $menu_items = \array_map([$pages_menu, 'pre_setup_nav_menu_item'], $menu_items);
8✔
120
            $menu_items = \array_map('wp_setup_nav_menu_item', $menu_items);
8✔
121

122
            /**
123
             * Can’t really apply the "wp_get_nav_menu_items" filter here, because we don’t have a
124
             * $menu object to pass in.
125
             */
126

127
            \_wp_menu_item_classes_by_context($menu_items);
8✔
128

129
            $menu_items_with_children = [];
8✔
130

131
            foreach ((array) $menu_items as $menu_item) {
8✔
132
                if ($menu_item->menu_item_parent) {
8✔
133
                    $menu_items_with_children[$menu_item->menu_item_parent] = true;
2✔
134
                }
135
            }
136

137
            // Add the menu-item-has-children class where applicable.
138
            if (!empty($menu_items_with_children)) {
8✔
139
                foreach ($menu_items as &$menu_item) {
2✔
140
                    if (isset($menu_items_with_children[$menu_item->ID])) {
2✔
141
                        $menu_item->classes[] = 'menu-item-has-children';
2✔
142
                    }
143
                }
144
            }
145

146
            unset($menu_item);
8✔
147

148
            if (\is_array($menu_items)) {
8✔
149
                /**
150
                 * Filters the arguments used to display a navigation menu.
151
                 *
152
                 * @see wp_nav_menu()
153
                 *
154
                 * @param array $args Array of wp_nav_menu() arguments.
155
                 */
156
                $args = \apply_filters('wp_nav_menu_args', $args);
8✔
157
                $args = (object) $args;
8✔
158

159
                /**
160
                 * Filters the sorted list of menu item objects before generating the menu's HTML.
161
                 *
162
                 * @param array     $menu_items The menu items, sorted by each menu item's menu order.
163
                 * @param stdClass $args       An object containing wp_nav_menu() arguments.
164
                 */
165
                $menu_items = \apply_filters('wp_nav_menu_objects', $menu_items, $args);
8✔
166

167
                $menu_items = $pages_menu->convert_menu_items($menu_items);
8✔
168
                $menu_items = $pages_menu->order_children($menu_items);
8✔
169
                $menu_items = $pages_menu->strip_to_depth_limit($menu_items);
8✔
170
            }
171

172
            $pages_menu->items = $menu_items;
8✔
173
        }
174

175
        /**
176
         * Since Timber doesn’t use HTML, serialize the menu object to provide a cacheable string.
177
         *
178
         * Certain caching plugins will use this filter to cache a menu and return it early in the
179
         * `pre_wp_nav_menu` filter.
180
         *
181
         * We can’t use the result of this filter, because it would return a string. That’s why we
182
         * don’t assign the result of the filter to a variable.
183
         *
184
         * @see wp_nav_menu()
185
         */
186
        \apply_filters('wp_nav_menu', \serialize($pages_menu), $args);
10✔
187

188
        return $pages_menu;
10✔
189
    }
190

191
    /**
192
     * Sets up properties needed for mocking nav menu items.
193
     *
194
     * We need to set some properties so that we can use `wp_setup_nav_menu_item()` on the menu
195
     * items and a proper menu item hierarchy can be built.
196
     *
197
     * @param WP_Post $post A post object.
198
     *
199
     * @return WP_Post Updated post object.
200
     */
201
    protected function pre_setup_nav_menu_item($post)
202
    {
203
        $post->object_id = $post->ID;
8✔
204
        $post->menu_item_parent = $post->post_parent;
8✔
205
        $post->object = $post->post_type;
8✔
206
        $post->post_type = 'nav_menu_item';
8✔
207
        $post->type = 'post_type';
8✔
208

209
        return $post;
8✔
210
    }
211
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc