Passed
Push — master ( a1de92...1a465b )
by Robbie
03:52
created

src/Services/ElementTabProvider.php (1 issue)

1
<?php
2
namespace DNADesign\Elemental\Services;
3
4
use DNADesign\Elemental\Models\BaseElement;
5
use Psr\SimpleCache\CacheInterface;
6
use SilverStripe\Core\ClassInfo;
7
use SilverStripe\Core\Config\Configurable;
8
use SilverStripe\Core\Flushable;
9
use SilverStripe\Core\Injector\Injector;
10
use SilverStripe\Forms\Tab;
11
use SilverStripe\Forms\TabSet;
12
13
/**
14
 * Provides top-level CMS field tab names for any element that extends BaseElement
15
 *
16
 * Note that this will be replaced by GraphQL form schema caching (see
17
 * http://github.com/silverstripe/silverstripe-admin/issues/627 ). This service may be removed without warning in a
18
 * minor release.
19
 *
20
 * @internal
21
 */
22
class ElementTabProvider implements Flushable
23
{
24
    use Configurable;
25
26
    /**
27
     * Set to true to refresh the tab cache on flush
28
     *
29
     * @config
30
     * @var bool
31
     */
32
    private static $regenerate_on_flush = false;
0 ignored issues
show
The private property $regenerate_on_flush is not used, and could be removed.
Loading history...
33
34
    /**
35
     * @var CacheInterface
36
     */
37
    protected $cache;
38
39
    /**
40
     * Get the top level tab names for the given element class
41
     *
42
     * @param string $elementClass
43
     * @return array Array of the tabs for the element
44
     */
45
    public function getTabsForElement($elementClass)
46
    {
47
        if (null !== ($tabs = $this->getCache()->get($this->getCacheKey($elementClass)))) {
48
            return $tabs;
49
        }
50
51
        return $this->generateTabsForElement($elementClass);
52
    }
53
54
    /**
55
     * This function is triggered early in the request if the "flush" query
56
     * parameter has been set. Each class that implements Flushable implements
57
     * this function which looks after it's own specific flushing functionality.
58
     *
59
     * @see FlushMiddleware
60
     */
61
    public static function flush()
62
    {
63
        /** @var static $self */
64
        $self = singleton(static::class);
65
66
        $self->getCache()->clear();
67
68
        if ($self->config()->get('regenerate_on_flush')) {
69
            $self->generateAllTabs();
70
        }
71
    }
72
73
    /**
74
     * @param CacheInterface $cache
75
     * @return $this
76
     */
77
    public function setCache($cache)
78
    {
79
        $this->cache = $cache;
80
        return $this;
81
    }
82
83
    /**
84
     * @return CacheInterface
85
     */
86
    protected function getCache()
87
    {
88
        return $this->cache;
89
    }
90
91
    /**
92
     * Identify and regenerate all tab names for all elemental blocks (and cache them)
93
     *
94
     * @return void
95
     */
96
    protected function generateAllTabs()
97
    {
98
        foreach (ClassInfo::subclassesFor(BaseElement::class) as $class) {
99
            $this->generateTabsForElement($class);
100
        }
101
    }
102
103
    /**
104
     * Generate top level tab names for the given element class (and cache them)
105
     *
106
     * @param string $elementClass
107
     * @return array
108
     */
109
    protected function generateTabsForElement($elementClass)
110
    {
111
        // Create the specified element
112
        /** @var BaseElement $element */
113
        $element = Injector::inst()->create($elementClass);
114
115
        // Generate CMS fields and grab the "Root" tabset.
116
        /** @var TabSet $tabset */
117
        $tabset = $element->getCMSFields()->fieldByName('Root');
118
119
        // Get and map the tab names/titles into an associative array
120
        $tabs = [];
121
        /** @var Tab $tabDefinition */
122
        foreach ($tabset->Tabs() as $tabDefinition) {
123
            $tabs[] = [
124
                'name' => $tabDefinition->getName(),
125
                'title' => $tabDefinition->Title(),
126
            ];
127
        }
128
129
        // Cache them for next time
130
        $this->getCache()->set($this->getCacheKey($elementClass), $tabs);
131
132
        return $tabs;
133
    }
134
135
    /**
136
     * Generate a valid cache key from the given element class.
137
     *
138
     * @param string $className
139
     * @return string
140
     */
141
    protected function getCacheKey($className)
142
    {
143
        return 'Tabs.' . str_replace(['\\'], '-', $className);
144
    }
145
}
146