Completed
Push — master ( b26fc8...c06b74 )
by Cheren
02:20
created

Toolbar::getInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
/**
3
 * CakeCMS Core
4
 *
5
 * This file is part of the of the simple cms based on CakePHP 3.
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @package   Core
10
 * @license   MIT
11
 * @copyright MIT License http://www.opensource.org/licenses/mit-license.php
12
 * @link      https://github.com/CakeCMS/Core".
13
 * @author    Sergey Kalistratov <[email protected]>
14
 */
15
16
namespace Core\Utility;
17
18
use Cake\Core\App;
19
use JBZoo\Utils\Slug;
20
use Cake\Utility\Inflector;
21
use Core\Toolbar\ToolbarItem;
22
23
/**
24
 * Class Toolbar
25
 *
26
 * @package Core\Utility
27
 */
28
class Toolbar
29
{
30
31
    const DEFAULT_NAME = 'toolbar';
32
33
    /**
34
     * Button type objects.
35
     *
36
     * @var array
37
     */
38
    protected $_buttons = [];
39
40
    /**
41
     *  Toolbar array items.
42
     *
43
     * @var array
44
     */
45
    protected $_items = [];
46
47
    /**
48
     * Toolbar name.
49
     *
50
     * @var string
51
     */
52
    protected $_name;
53
54
    /**
55
     * Stores the singleton instances of various toolbar.
56
     *
57
     * @var array
58
     */
59
    protected static $_instances = [];
60
61
    /**
62
     * Toolbar constructor.
63
     *
64
     * @param string $name
65
     */
66
    public function __construct($name = self::DEFAULT_NAME)
67
    {
68
        $this->_name = $name;
69
    }
70
71
    /**
72
     * Set a value.
73
     *
74
     * @return bool
75
     */
76
    public function appendButton()
77
    {
78
        $btn = func_get_args();
79
        array_push($this->_items, $btn);
80
81
        return true;
82
    }
83
84
    /**
85
     * Get toolbar instance.
86
     *
87
     * @param string $name
88
     * @return array|Toolbar
89
     */
90
    public static function getInstance($name = self::DEFAULT_NAME)
91
    {
92
        if (empty(self::$_instances[$name])) {
93
            self::$_instances[$name] = new Toolbar($name);
94
        }
95
96
        return self::$_instances[$name];
97
    }
98
99
    /**
100
     * Get toolbar items.
101
     *
102
     * @return array
103
     */
104
    public function getItems()
105
    {
106
        return $this->_items;
107
    }
108
109
    /**
110
     * Get toolbar name.
111
     *
112
     * @return string
113
     */
114
    public function getName()
115
    {
116
        return $this->_name;
117
    }
118
119
    /**
120
     * Load object of item type.
121
     *
122
     * @param $type
123
     * @return ToolbarItem|bool
124
     */
125
    public function loadItemType($type)
126
    {
127
        $signature = md5($type);
128
        if (isset($this->_buttons[$signature])) {
129
            return $this->_buttons[$signature];
130
        }
131
132
        list($plugin, $name) = pluginSplit($type);
133
        $alias = Slug::filter($name, '_');
134
        $aliasClass = Inflector::classify($alias);
135
136
        $className = $this->_getItemClassName($plugin, $aliasClass);
0 ignored issues
show
Bug introduced by
It seems like $aliasClass defined by \Cake\Utility\Inflector::classify($alias) on line 134 can also be of type boolean; however, Core\Utility\Toolbar::_getItemClassName() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
137
138
        if (!$className) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $className of type string|false is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
139
            return false;
140
        }
141
142
        $this->_buttons[$signature] = new $className($this);
143
        return $this->_buttons[$signature];
144
    }
145
146
    /**
147
     * Set a prepend value.
148
     *
149
     * @return bool
150
     */
151
    public function prependButton()
152
    {
153
        $btn = func_get_args();
154
        array_unshift($this->_items, $btn);
155
156
        return true;
157
    }
158
159
    /**
160
     * Render toolbar items.
161
     *
162
     * @return string
163
     */
164
    public function render()
165
    {
166
        $output = [];
167
        foreach ($this->_items as $item) {
168
            $output[] = $this->renderItem($item);
169
        }
170
171
        return implode(PHP_EOL, $output);
172
    }
173
174
    /**
175
     * Render toolbar item html.
176
     *
177
     * @param $node
178
     * @return null|string
179
     */
180
    public function renderItem(&$node)
181
    {
182
        $type = $node[0];
183
        $item = $this->loadItemType($type);
184
185
        if ($item === false) {
186
            return null;
187
        }
188
189
        return $item->render($node);
190
    }
191
192
    /**
193
     * Get full class name.
194
     *
195
     * @param string $plugin
196
     * @param string $aliasClass
197
     * @return bool|string
198
     */
199
    protected function _getItemClassName($plugin, $aliasClass)
200
    {
201
        if ($plugin === null) {
202
            $plugin = 'Core';
203
        }
204
205
        $buttonClass = $plugin . '.ToolbarItem' . $aliasClass;
206
        $className   = App::className($buttonClass, 'Toolbar');
207
208
        if ($className === false) {
209
            $buttonClass = 'ToolbarItem' . $aliasClass;
210
            $className   = App::className($buttonClass, 'Toolbar');
211
        }
212
213
        return $className;
214
    }
215
}
216