Passed
Pull Request — master (#373)
by
unknown
03:08
created

ElementTabProvider   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 25
dl 0
loc 127
rs 10
c 0
b 0
f 0
wmc 12

8 Methods

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