This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * Abstract class to extend from when implementing a Pico plugin |
||
5 | * |
||
6 | * @see PicoPluginInterface |
||
7 | * |
||
8 | * @author Daniel Rudolf |
||
9 | * @link http://picocms.org |
||
10 | * @license http://opensource.org/licenses/MIT |
||
11 | * @version 1.0 |
||
12 | */ |
||
13 | abstract class AbstractPicoPlugin implements PicoPluginInterface |
||
14 | { |
||
15 | /** |
||
16 | * Current instance of Pico |
||
17 | * |
||
18 | * @see PicoPluginInterface::getPico() |
||
19 | * @var Pico |
||
20 | */ |
||
21 | private $pico; |
||
22 | |||
23 | /** |
||
24 | * Boolean indicating if this plugin is enabled (true) or disabled (false) |
||
25 | * |
||
26 | * @see PicoPluginInterface::isEnabled() |
||
27 | * @see PicoPluginInterface::setEnabled() |
||
28 | * @var boolean |
||
29 | */ |
||
30 | protected $enabled = true; |
||
31 | |||
32 | /** |
||
33 | * Boolean indicating if this plugin was ever enabled/disabled manually |
||
34 | * |
||
35 | * @see PicoPluginInterface::isStatusChanged() |
||
36 | * @var boolean |
||
37 | */ |
||
38 | protected $statusChanged = false; |
||
39 | |||
40 | /** |
||
41 | * List of plugins which this plugin depends on |
||
42 | * |
||
43 | * @see AbstractPicoPlugin::checkDependencies() |
||
44 | * @see PicoPluginInterface::getDependencies() |
||
45 | * @var string[] |
||
46 | */ |
||
47 | protected $dependsOn = array(); |
||
48 | |||
49 | /** |
||
50 | * List of plugin which depend on this plugin |
||
51 | * |
||
52 | * @see AbstractPicoPlugin::checkDependants() |
||
53 | * @see PicoPluginInterface::getDependants() |
||
54 | * @var object[] |
||
55 | */ |
||
56 | private $dependants; |
||
57 | |||
58 | /** |
||
59 | * @see PicoPluginInterface::__construct() |
||
60 | */ |
||
61 | public function __construct(Pico $pico) |
||
62 | { |
||
63 | $this->pico = $pico; |
||
64 | } |
||
65 | |||
66 | /** |
||
67 | * @see PicoPluginInterface::handleEvent() |
||
68 | */ |
||
69 | public function handleEvent($eventName, array $params) |
||
70 | { |
||
71 | // plugins can be enabled/disabled using the config |
||
72 | if ($eventName === 'onConfigLoaded') { |
||
73 | $pluginEnabled = $this->getConfig(get_called_class() . '.enabled'); |
||
74 | if ($pluginEnabled !== null) { |
||
75 | $this->setEnabled($pluginEnabled); |
||
76 | } else { |
||
77 | $pluginConfig = $this->getConfig(get_called_class()); |
||
78 | if (is_array($pluginConfig) && isset($pluginConfig['enabled'])) { |
||
79 | $this->setEnabled($pluginConfig['enabled']); |
||
80 | } |
||
81 | } |
||
82 | } |
||
83 | |||
84 | if ($this->isEnabled() || ($eventName === 'onPluginsLoaded')) { |
||
85 | if (method_exists($this, $eventName)) { |
||
86 | call_user_func_array(array($this, $eventName), $params); |
||
87 | } |
||
88 | } |
||
89 | } |
||
90 | |||
91 | /** |
||
92 | * @see PicoPluginInterface::setEnabled() |
||
93 | */ |
||
94 | public function setEnabled($enabled, $recursive = true, $auto = false) |
||
95 | { |
||
96 | $this->statusChanged = (!$this->statusChanged) ? !$auto : true; |
||
97 | $this->enabled = (bool) $enabled; |
||
98 | |||
99 | if ($enabled) { |
||
100 | $this->checkDependencies($recursive); |
||
101 | } else { |
||
102 | $this->checkDependants($recursive); |
||
103 | } |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * @see PicoPluginInterface::isEnabled() |
||
108 | */ |
||
109 | public function isEnabled() |
||
110 | { |
||
111 | return $this->enabled; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @see PicoPluginInterface::isStatusChanged() |
||
116 | */ |
||
117 | public function isStatusChanged() |
||
118 | { |
||
119 | return $this->statusChanged; |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * @see PicoPluginInterface::getPico() |
||
124 | */ |
||
125 | public function getPico() |
||
126 | { |
||
127 | return $this->pico; |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * Passes all not satisfiable method calls to Pico |
||
132 | * |
||
133 | * @see Pico |
||
134 | * @param string $methodName name of the method to call |
||
135 | * @param array $params parameters to pass |
||
136 | * @return mixed return value of the called method |
||
137 | */ |
||
138 | public function __call($methodName, array $params) |
||
139 | { |
||
140 | if (method_exists($this->getPico(), $methodName)) { |
||
141 | return call_user_func_array(array($this->getPico(), $methodName), $params); |
||
142 | } |
||
143 | |||
144 | throw new BadMethodCallException( |
||
145 | 'Call to undefined method ' . get_class($this->getPico()) . '::' . $methodName . '() ' |
||
146 | . 'through ' . get_called_class() . '::__call()' |
||
147 | ); |
||
148 | } |
||
149 | |||
150 | /** |
||
151 | * Enables all plugins which this plugin depends on |
||
152 | * |
||
153 | * @see PicoPluginInterface::getDependencies() |
||
154 | * @param boolean $recursive enable required plugins automatically |
||
155 | * @return void |
||
156 | * @throws RuntimeException thrown when a dependency fails |
||
157 | */ |
||
158 | protected function checkDependencies($recursive) |
||
159 | { |
||
160 | foreach ($this->getDependencies() as $pluginName) { |
||
161 | try { |
||
162 | $plugin = $this->getPlugin($pluginName); |
||
163 | } catch (RuntimeException $e) { |
||
164 | throw new RuntimeException( |
||
165 | "Unable to enable plugin '" . get_called_class() . "':" |
||
166 | . "Required plugin '" . $pluginName . "' not found" |
||
167 | ); |
||
168 | } |
||
169 | |||
170 | // plugins which don't implement PicoPluginInterface are always enabled |
||
171 | if (is_a($plugin, 'PicoPluginInterface') && !$plugin->isEnabled()) { |
||
172 | if ($recursive) { |
||
173 | View Code Duplication | if (!$plugin->isStatusChanged()) { |
|
0 ignored issues
–
show
|
|||
174 | $plugin->setEnabled(true, true, true); |
||
175 | } else { |
||
176 | throw new RuntimeException( |
||
177 | "Unable to enable plugin '" . get_called_class() . "':" |
||
178 | . "Required plugin '" . $pluginName . "' was disabled manually" |
||
179 | ); |
||
180 | } |
||
181 | } else { |
||
182 | throw new RuntimeException( |
||
183 | "Unable to enable plugin '" . get_called_class() . "':" |
||
184 | . "Required plugin '" . $pluginName . "' is disabled" |
||
185 | ); |
||
186 | } |
||
187 | } |
||
188 | } |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * @see PicoPluginInterface::getDependencies() |
||
193 | */ |
||
194 | public function getDependencies() |
||
195 | { |
||
196 | return (array) $this->dependsOn; |
||
197 | } |
||
198 | |||
199 | /** |
||
200 | * Disables all plugins which depend on this plugin |
||
201 | * |
||
202 | * @see PicoPluginInterface::getDependants() |
||
203 | * @param boolean $recursive disabled dependant plugins automatically |
||
204 | * @return void |
||
205 | * @throws RuntimeException thrown when a dependency fails |
||
206 | */ |
||
207 | protected function checkDependants($recursive) |
||
208 | { |
||
209 | $dependants = $this->getDependants(); |
||
210 | if (!empty($dependants)) { |
||
211 | if ($recursive) { |
||
212 | foreach ($this->getDependants() as $pluginName => $plugin) { |
||
213 | View Code Duplication | if ($plugin->isEnabled()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
214 | if (!$plugin->isStatusChanged()) { |
||
215 | $plugin->setEnabled(false, true, true); |
||
216 | } else { |
||
217 | throw new RuntimeException( |
||
218 | "Unable to disable plugin '" . get_called_class() . "': " |
||
219 | . "Required by manually enabled plugin '" . $pluginName . "'" |
||
220 | ); |
||
221 | } |
||
222 | } |
||
223 | } |
||
224 | } else { |
||
225 | $dependantsList = 'plugin' . ((count($dependants) > 1) ? 's' : '') . ' '; |
||
226 | $dependantsList .= "'" . implode("', '", array_keys($dependants)) . "'"; |
||
227 | throw new RuntimeException( |
||
228 | "Unable to disable plugin '" . get_called_class() . "': " |
||
229 | . "Required by " . $dependantsList |
||
230 | ); |
||
231 | } |
||
232 | } |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * @see PicoPluginInterface::getDependants() |
||
237 | */ |
||
238 | public function getDependants() |
||
239 | { |
||
240 | if ($this->dependants === null) { |
||
241 | $this->dependants = array(); |
||
242 | foreach ($this->getPlugins() as $pluginName => $plugin) { |
||
243 | // only plugins which implement PicoPluginInterface support dependencies |
||
244 | if (is_a($plugin, 'PicoPluginInterface')) { |
||
245 | $dependencies = $plugin->getDependencies(); |
||
246 | if (in_array(get_called_class(), $dependencies)) { |
||
247 | $this->dependants[$pluginName] = $plugin; |
||
248 | } |
||
249 | } |
||
250 | } |
||
251 | } |
||
252 | |||
253 | return $this->dependants; |
||
254 | } |
||
255 | } |
||
256 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.