ElementTypeRegistry::getTabProvider()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 4
rs 10
1
<?php
2
namespace DNADesign\Elemental\Services;
3
4
use DNADesign\Elemental\Models\BaseElement;
5
use InvalidArgumentException;
6
use LogicException;
7
use Psr\SimpleCache\CacheInterface;
8
use SilverStripe\Core\ClassInfo;
9
use SilverStripe\Core\Injector\Injectable;
10
use SilverStripe\Core\Injector\Injector;
11
use SilverStripe\GraphQL\Schema\Exception\SchemaBuilderException;
0 ignored issues
show
Bug introduced by
The type SilverStripe\GraphQL\Sch...\SchemaBuilderException 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...
12
13
class ElementTypeRegistry
14
{
15
    use Injectable;
16
17
    const CACHE_KEY = 'element-types';
18
19
    /**
20
     * @var array
21
     */
22
    protected $elementTypes;
23
24
    /**
25
     * @var CacheInterface
26
     */
27
    protected static $cache;
28
29
    /**
30
     * Register an element type with this registry
31
     *
32
     * @param string $elementClass
33
     * @return $this
34
     * @throws SchemaBuilderException
35
     */
36
    public function registerElement($elementClass)
37
    {
38
        $singleton = singleton($elementClass);
39
40
        if (!$singleton instanceof BaseElement) {
41
            throw new LogicException('Only elements that extend ' . BaseElement::class . ' can be registered');
42
        }
43
44
        // Get the GraphQL type name
45
        $typeName = $singleton->getGraphQLTypeName();
46
47
        $this->elementTypes[] = [
48
            'icon' => $singleton::config()->get('icon'),
49
            'name' => $typeName,
50
            'class' => $elementClass,
51
            'title' => $singleton->getType(),
52
            'inlineEditable' => $singleton->inlineEditable(),
53
            'editTabs' => $this->getTabProvider()->getTabsForElement($elementClass),
54
            // Cast to object as React prop-types expects it.
55
            'config' => (object) $singleton::getBlockConfig(),
56
        ];
57
58
        return $this;
59
    }
60
61
    /**
62
     * Get the schema of the element types that are registered
63
     *
64
     * @return array
65
     */
66
    public function getDefinitions()
67
    {
68
        return $this->elementTypes;
69
    }
70
71
    /**
72
     * Get the element type data for the given instance or class name of an element.
73
     *
74
     * @param $instanceOrClass
75
     * @return mixed
76
     */
77
    public function getDefinition($instanceOrClass)
78
    {
79
        if ($instanceOrClass instanceof BaseElement) {
80
            $instanceOrClass = get_class($instanceOrClass);
81
        }
82
83
        if (!is_string($instanceOrClass)) {
84
            throw new InvalidArgumentException(sprintf(
85
                'Given argument to %s is not an instance of a class extending %s and is not a string',
86
                __METHOD__,
87
                BaseElement::class
88
            ));
89
        }
90
91
        $definitions = $this->getDefinitions();
92
93
        if (!isset($definitions[$instanceOrClass])) {
94
            throw new InvalidArgumentException(sprintf('Unknown element "%s"', $instanceOrClass));
95
        }
96
97
        return $definitions[$instanceOrClass];
98
    }
99
100
    /**
101
     * @internal This API is only intended for use while SilverStripe does not have a caching layer for form schema.
102
     *           See: https://github.com/silverstripe/silverstripe-admin/issues/627
103
     * @return ElementTabProvider
104
     */
105
    protected function getTabProvider()
106
    {
107
        // This is a temporary solution until something client side is implemented to reveal tab names.
108
        return Injector::inst()->get(ElementTabProvider::class);
109
    }
110
111
    /**
112
     * Create a registry and attempt to fill it by resolving element types by introspecting class hierarchy
113
     *
114
     * @return static
115
     */
116
    public static function generate()
117
    {
118
        $registry = static::create();
119
120
        // Look in a cache (if provided) for type details
121
        if (static::$cache && ($types = static::$cache->get(self::CACHE_KEY))) {
122
            $registry->elementTypes = $types;
123
            return $registry;
124
        }
125
126
        // Find all element types
127
        $classNames = ClassInfo::getValidSubClasses(BaseElement::class);
128
        foreach ($classNames as $class) {
129
            // Skip the "abstract" element
130
            if ($class === BaseElement::class) {
131
                continue;
132
            }
133
            $registry->registerElement($class);
134
        }
135
136
        return $registry;
137
    }
138
}
139