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

Cecilapp / Cecil / 7063372205

01 Dec 2023 05:46PM UTC coverage: 82.179%. First build
7063372205

Pull #1855

github

web-flow
Merge edc57e7a5 into 88411271b
Pull Request #1855: refactor: menus creation enhanced

24 of 25 new or added lines in 2 files covered. (96.0%)

2813 of 3423 relevant lines covered (82.18%)

0.82 hits per line

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

86.36
/src/Step/Menus/Create.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <arnaud@ligny.fr>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13

14
namespace Cecil\Step\Menus;
15

16
use Cecil\Collection\Menu\Collection as MenusCollection;
17
use Cecil\Collection\Menu\Entry;
18
use Cecil\Collection\Menu\Menu;
19
use Cecil\Collection\Page\Page;
20
use Cecil\Exception\RuntimeException;
21
use Cecil\Logger\PrintLogger;
22
use Cecil\Renderer\Page as PageRenderer;
23
use Cecil\Step\AbstractStep;
24

25
/**
26
 * Creates menus collection.
27
 */
28
class Create extends AbstractStep
29
{
30
    /** @var array */
31
    protected $menus;
32

33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function getName(): string
37
    {
38
        return 'Creating menus';
1✔
39
    }
40

41
    /**
42
     * {@inheritdoc}
43
     *
44
     * @throws RuntimeException
45
     */
46
    public function process(): void
47
    {
48
        // creates a 'menus' collection for each language, with a default 'main' menu
49
        foreach ($this->config->getLanguages() as $language) {
1✔
50
            $this->menus[$language['code']] = new MenusCollection('menus');
1✔
51
            $this->menus[$language['code']]->add(new Menu('main'));
1✔
52
        }
53

54
        // collects 'menu' entries from pages
55
        $this->collectPages();
1✔
56

57
        /**
58
         * Removing/adding/replacing menus entries from config.
59
         * ie:
60
         *   menus:
61
         *     main:
62
         *       - id: example
63
         *         name: "Example"
64
         *         url: https://example.com
65
         *         weight: 999
66
         *       - id: about
67
         *         enabled: false.
68
         */
69
        foreach ($this->config->getLanguages() as $language) {
1✔
70
            if ($menusConfig = (array) $this->config->get('menus', $language['code'], false)) {
1✔
71
                $totalConfig = array_sum(array_map('count', $menusConfig));
1✔
72
                $countConfig = 0;
1✔
73

74
                foreach ($menusConfig as $menuConfig => $entry) {
1✔
75
                    // add Menu if not exists
76
                    if (!$this->menus[$language['code']]->has($menuConfig)) {
1✔
77
                        $this->menus[$language['code']]->add(new Menu($menuConfig));
×
78
                    }
79
                    /** @var \Cecil\Collection\Menu\Menu $menu */
80
                    $menu = $this->menus[$language['code']]->get($menuConfig);
1✔
81
                    foreach ($entry as $key => $properties) {
1✔
82
                        $countConfig++;
1✔
83
                        $enabled = true;
1✔
84
                        $updated = false;
1✔
85

86
                        // ID is required
87
                        if (!isset($properties['id'])) {
1✔
NEW
88
                            throw new RuntimeException(sprintf('Key "id" is required for entry at position %s in "%s" menu', $key, $menu));
×
89
                        }
90
                        // is entry already exists?
91
                        if ($menu->has($properties['id'])) {
1✔
92
                            // removes a not enabled entry
93
                            if (isset($properties['enabled']) && $properties['enabled'] === false) {
1✔
94
                                $enabled = false;
1✔
95
                                $menu->remove($properties['id']);
1✔
96

97
                                $message = sprintf('Config menu entry "%s (%s) > %s" removed', (string) $menu, $language['code'], $properties['id']);
1✔
98
                                $this->builder->getLogger()->info($message, ['progress' => [$countConfig, $totalConfig]]);
1✔
99
                                continue;
1✔
100
                            }
101
                            // merges properties
102
                            $updated = true;
1✔
103
                            $current = $menu->get($properties['id'])->toArray();
1✔
104
                            $properties = array_merge($current, $properties);
1✔
105
                        }
106
                        // adds/replaces entry
107
                        if ($enabled) {
1✔
108
                            $item = (new Entry($properties['id']))
1✔
109
                                ->setName($properties['name'] ?? ucfirst($properties['id']))
1✔
110
                                ->setUrl((new \Cecil\Assets\Url($this->builder, $properties['url'] ?? '404', ['language' => $language['code']]))->getUrl())
1✔
111
                                ->setWeight((int) ($properties['weight'] ?? 0));
1✔
112
                            $menu->add($item);
1✔
113

114
                            $message = sprintf('Config menu entry "%s (%s) > %s" %s (name: %s, url: %s, weight: %s)', (string) $menu, $language['code'], $item->getId(), $updated ? 'updated' : 'created', $item-> getName(), $item->getUrl(), $item->getWeight());
1✔
115
                            $this->builder->getLogger()->info($message, ['progress' => [$countConfig, $totalConfig]]);
1✔
116
                        }
117
                    }
118
                }
119
            }
120
        }
121

122
        $this->builder->setMenus($this->menus);
1✔
123
    }
124

125
    /**
126
     * Collects pages with a menu variable.
127
     */
128
    protected function collectPages(): void
129
    {
130
        $filteredPages = $this->builder->getPages()->filter(function (Page $page) {
1✔
131
            return $page->hasVariable('menu')
1✔
132
                && $page->getVariable('published')
1✔
133
                && \in_array($page->getVariable('language', $this->config->getLanguageDefault()), array_column($this->config->getLanguages(), 'code'));
1✔
134
        });
1✔
135

136
        $total = \count($filteredPages);
1✔
137
        $count = 0;
1✔
138
        /** @var \Cecil\Collection\Page\Page $page */
139
        foreach ($filteredPages as $page) {
1✔
140
            $count++;
1✔
141
            $language = $page->getVariable('language', $this->config->getLanguageDefault());
1✔
142
            /**
143
             * Array case.
144
             *
145
             * ie 1:
146
             *   menu: [main, navigation]
147
             * ie 2:
148
             *   menu:
149
             *     main:
150
             *       weight: 999
151
             */
152
            if (\is_array($page->getVariable('menu'))) {
1✔
153
                foreach ($page->getVariable('menu') as $key => $value) {
1✔
154
                    $menuName = $key;
1✔
155
                    $properties = $value;
1✔
156
                    $weight = null;
1✔
157
                    if (\is_int($key)) {
1✔
158
                        $menuName = $value;
1✔
159
                        $properties = null;
1✔
160
                    }
161
                    if (!\is_string($menuName)) {
1✔
162
                        $this->builder->getLogger()->error(
×
163
                            sprintf(
×
164
                                'Menu\'s name of page "%s" must be a string, not "%s"',
×
165
                                $page->getId(),
×
166
                                PrintLogger::format($menuName)
×
167
                            ),
×
168
                            ['progress' => [$count, $total]]
×
169
                        );
×
170
                        continue;
×
171
                    }
172
                    $item = (new Entry($page->getIdWithoutLang()))
1✔
173
                        ->setName($page->getVariable('title'))
1✔
174
                        ->setUrl((new PageRenderer($this->config))->getUrl($page));
1✔
175
                    if (isset($properties['weight'])) {
1✔
176
                        $weight = $properties['weight'];
1✔
177
                        $item->setWeight((int) $properties['weight']);
1✔
178
                    }
179
                    // add Menu if not exists
180
                    if (!$this->menus[$language]->has($menuName)) {
1✔
181
                        $this->menus[$language]->add(new Menu($menuName));
1✔
182
                    }
183
                    /** @var \Cecil\Collection\Menu\Menu $menu */
184
                    $menu = $this->menus[$language]->get($menuName);
1✔
185
                    $menu->add($item);
1✔
186

187
                    $message = sprintf('Page menu entry "%s (%s) > %s" created (name: %s, weight: %s)', $menu->getId(), $language, $item->getId(), $item->getName(), $weight ?? 'N/A');
1✔
188
                    $this->builder->getLogger()->info($message, ['progress' => [$count, $total]]);
1✔
189
                }
190
                continue;
1✔
191
            }
192
            /**
193
             * String case.
194
             *
195
             * ie:
196
             *   menu: main
197
             */
198
            $item = (new Entry($page->getIdWithoutLang()))
1✔
199
                ->setName($page->getVariable('title'))
1✔
200
                ->setUrl((new PageRenderer($this->config))->getUrl($page));
1✔
201
            // add Menu if not exists
202
            if (!$this->menus[$language]->has($page->getVariable('menu'))) {
1✔
203
                $this->menus[$language]->add(new Menu($page->getVariable('menu')));
×
204
            }
205
            /** @var \Cecil\Collection\Menu\Menu $menu */
206
            $menu = $this->menus[$language]->get($page->getVariable('menu'));
1✔
207
            $menu->add($item);
1✔
208

209
            $message = sprintf('Page menu entry "%s (%s) > %s" created (name: %s)', $menu->getId(), $language, $item->getId(), $item->getName());
1✔
210
            $this->builder->getLogger()->info($message, ['progress' => [$count, $total]]);
1✔
211
        }
212
    }
213
}
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

© 2026 Coveralls, Inc