Completed
Push — master ( 890140...3a3229 )
by David
02:30
created

BlockRegistry::findBlocksByTag()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 11
rs 9.4285
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\StaticRegistry\Loaders\Block;
11
12
/**
13
 * The block registry can fetch Block objects from the "blocks" directory or from the container.
14
 */
15
class BlockRegistry
16
{
17
    /**
18
     * @var string
19
     */
20
    private $blockDirectory;
21
    /**
22
     * @var ContainerInterface
23
     */
24
    private $container;
25
    /**
26
     * @var CacheInterface
27
     */
28
    private $cache;
29
30
    /**
31
     * An array of array of blocks indexed by id (several blocks can share the same ID)
32
     *
33
     * @var Block[][]
34
     */
35
    private $blocks;
36
37
    public function __construct(string $blockDirectory, ContainerInterface $container, CacheInterface $cache)
38
    {
39
        $this->blockDirectory = rtrim($blockDirectory, '/\\').'/';
40
        $this->container = $container;
41
        $this->cache = $cache;
42
    }
43
44
    /**
45
     * Returns all blocks with a given blockId (several blocks can share the same ID if they have different languages)
46
     *
47
     * @param string $blockId
48
     * @return Block[]
49
     */
50
    public function getBlocks(string $blockId): array
51
    {
52
        $key = 'block__'.$blockId;
53
        $block = $this->cache->get($key);
54
        if ($block === null) {
55
            $block = $this->getBlocksNoCache($blockId);
56
            $this->cache->set($key, $block);
57
        }
58
        return $block;
59
    }
60
61
    /**
62
     * @param string $blockName
63
     * @return Block[]
64
     * @throws BlockNotFoundException
65
     */
66
    private function getBlocksNoCache(string $blockName): array
67
    {
68
        if ($this->container->has($blockName)) {
69
            $entry = $this->container->get($blockName);
70
            if ($entry instanceof Block) {
71
                return [$entry];
72
            }
73
        }
74
75
        $blocks = $this->loadBlocks();
76
        if (isset($blocks[$blockName])) {
77
            return $blocks[$blockName];
78
        }
79
80
        throw BlockNotFoundException::couldNotLoadBlock($blockName);
81
    }
82
83
    /**
84
     * @return Block[][]
85
     */
86
    private function loadBlocks(): array
87
    {
88
        if ($this->blocks === null)
89
        {
90
            $this->blocks = [];
91
            $fileList = new Finder();
92
93
            $fileList->files()->in($this->blockDirectory)->name('/\.html|\.md/')->sortByName();
94
95
            foreach ($fileList as $splFileInfo) {
96
                $block = Block::fromFile($splFileInfo);
97
                $this->blocks[$block->getId()][] = $block;
98
            }
99
        }
100
        return $this->blocks;
101
    }
102
103
    /**
104
     * @param string $tag
105
     * @return Block[]
106
     */
107
    public function findBlocksByTag(string $tag): array
108
    {
109
        $blocks = $this->loadBlocks();
110
111
        $filteredBlocks = [];
112
        foreach ($blocks as $blockArray) {
113
            $filteredBlocks = array_merge($filteredBlocks, array_filter($blockArray, function(Block $block) use ($tag) {
114
                return in_array($tag, $block->getTags(), true);
115
            }));
116
        }
117
        return $filteredBlocks;
118
    }
119
}
120