Completed
Push — master ( d1e0a9...cb6f48 )
by David
11s
created

PageRegistry::getRootMenuItem()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
4
namespace TheCodingMachine\CMS\StaticRegistry\Registry;
5
6
7
use Psr\Container\ContainerInterface;
8
use Psr\SimpleCache\CacheInterface;
9
use Symfony\Component\Finder\Finder;
10
use TheCodingMachine\CMS\Block\BlockInterface;
11
use TheCodingMachine\CMS\StaticRegistry\Loaders\Page;
12
use TheCodingMachine\CMS\StaticRegistry\Loaders\Page404;
0 ignored issues
show
Bug introduced by
The type TheCodingMachine\CMS\Sta...egistry\Loaders\Page404 was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use TheCodingMachine\CMS\StaticRegistry\Menu\MenuItem;
14
use TheCodingMachine\CMS\StaticRegistry\Menu\MenuRegistry;
15
16
/**
17
 * The page registry can fetch Page objects from the "pages" directory or from the container.
18
 */
19
class PageRegistry
20
{
21
    /**
22
     * @var string
23
     */
24
    private $pageDirectory;
25
    /**
26
     * @var CacheInterface
27
     */
28
    private $cache;
29
30
    /**
31
     * An array of pages indexed by URL.
32
     *
33
     * @var Page[][]
34
     */
35
    private $pages;
36
37
    /**
38
     * @var MenuItem
39
     */
40
    private $rootMenuItem;
41
42
    public function __construct(string $pageDirectory, CacheInterface $cache)
43
    {
44
        $this->pageDirectory = rtrim($pageDirectory, '/\\').'/';
45
        $this->cache = $cache;
46
    }
47
48
    public function getPage(string $url, string $domain): Page
49
    {
50
        $pages = $this->getImportedPagesFromCache();
51
52
        if (isset($pages[$domain][$url])) {
53
            return $pages[$domain][$url];
54
        }
55
        if (isset($pages['<any>'][$url])) {
56
            return $pages['<any>'][$url];
57
        }
58
59
        throw PageNotFoundException::couldNotFindPage($url, $domain);
60
    }
61
62
    /**
63
     * @return Page[][]
64
     */
65
    private function getImportedPagesFromCache(): array
66
    {
67
        $key = 'pages';
68
        $pages = $this->cache->get($key);
69
        if ($pages === null) {
70
            $pages = $this->getImportedPages();
71
            $this->cache->set($key, $pages);
72
        }
73
        return $pages;
74
    }
75
76
    /**
77
     * @return Page[][]
78
     * @throws DuplicatePageException
79
     */
80
    private function getImportedPages(): array
81
    {
82
        if ($this->pages === null) {
83
            $this->pages = [];
84
            $fileList = new Finder();
85
86
            $fileList->files()->in($this->pageDirectory)->sortByName();
87
88
            foreach ($fileList as $file) {
89
                $importedPage = Page::fromFile($file->getRealPath());
90
91
                if (isset($this->pages[$importedPage->getWebsite() ?? '<any>'][$importedPage->getUrl()])) {
92
                    throw new DuplicatePageException(sprintf('There are 2 pages claiming the URL %s %s', $importedPage->getUrl(), $importedPage->getWebsite() ? ' of website '.$importedPage->getWebsite() : ''));
93
                }
94
                $this->pages[$importedPage->getWebsite() ?? '<any>'][$importedPage->getUrl()] = $importedPage;
95
            }
96
        }
97
        return $this->pages;
98
    }
99
100
    public function getRootMenuItem(): MenuItem
101
    {
102
        $key = 'rootMenuItem';
103
        $rootMenuItem = $this->cache->get($key);
104
        if ($rootMenuItem === null) {
105
            $rootMenuItem = $this->getRootMenuItemWithoutCache();
106
            $this->cache->set($key, $rootMenuItem);
107
        }
108
        return $rootMenuItem;
109
    }
110
111
    private function getRootMenuItemWithoutCache(): MenuItem
112
    {
113
        if ($this->rootMenuItem === null) {
114
            $menuRegistry = new MenuRegistry();
115
            $pages = $this->getImportedPages();
116
            foreach ($pages as $pagesFromWebsite) {
117
                foreach ($pagesFromWebsite as $page) {
118
                    $menuRegistry->registerMenuItem(
119
                        $page->getMenu(),
120
                        $page->getUrl(),
121
                        $page->getMenuOrder(),
122
                        $page->getMenuCssClass()
123
                    );
124
                }
125
            }
126
            $this->rootMenuItem = $menuRegistry->getRootMenu();
127
        }
128
        return $this->rootMenuItem;
129
    }
130
}
131