1 | <?php |
||||
2 | /** |
||||
3 | * @package content |
||||
4 | */ |
||||
5 | |||||
6 | /** |
||||
7 | * The Event Editor allows a developer to create events that typically |
||||
8 | * allow Frontend forms to populate Sections or edit Entries. |
||||
9 | */ |
||||
10 | |||||
11 | class contentBlueprintsEvents extends ResourcesPage |
||||
0 ignored issues
–
show
|
|||||
12 | { |
||||
13 | public $_errors = array(); |
||||
14 | |||||
15 | public function __viewIndex($resource_type) |
||||
16 | { |
||||
17 | parent::__viewIndex(ResourceManager::RESOURCE_TYPE_EVENT); |
||||
18 | |||||
19 | $this->setTitle(__('%1$s – %2$s', array(__('Events'), __('Symphony')))); |
||||
20 | $this->appendSubheading(__('Events'), Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL().'new/', __('Create a new event'), 'create button', null, array('accesskey' => 'c'))); |
||||
21 | } |
||||
22 | |||||
23 | public function __viewNew() |
||||
24 | { |
||||
25 | $this->__form(); |
||||
26 | } |
||||
27 | |||||
28 | public function __viewEdit() |
||||
29 | { |
||||
30 | $this->__form(); |
||||
31 | } |
||||
32 | |||||
33 | public function __viewInfo() |
||||
34 | { |
||||
35 | $this->__form(true); |
||||
36 | } |
||||
37 | |||||
38 | public function __form($readonly = false) |
||||
0 ignored issues
–
show
|
|||||
39 | { |
||||
40 | $formHasErrors = (is_array($this->_errors) && !empty($this->_errors)); |
||||
41 | |||||
42 | if ($formHasErrors) { |
||||
43 | $this->pageAlert( |
||||
44 | __('An error occurred while processing this form. See below for details.'), |
||||
45 | Alert::ERROR |
||||
46 | ); |
||||
47 | |||||
48 | // These alerts are only valid if the form doesn't have errors |
||||
49 | } elseif (isset($this->_context[2])) { |
||||
50 | $time = Widget::Time(); |
||||
51 | |||||
52 | switch ($this->_context[2]) { |
||||
53 | case 'saved': |
||||
54 | $message = __('Event updated at %s.', array($time->generate())); |
||||
55 | break; |
||||
56 | case 'created': |
||||
57 | $message = __('Event created at %s.', array($time->generate())); |
||||
58 | } |
||||
59 | |||||
60 | $this->pageAlert( |
||||
61 | $message |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
62 | . ' <a href="' . SYMPHONY_URL . '/blueprints/events/new/" accesskey="c">' |
||||
0 ignored issues
–
show
|
|||||
63 | . __('Create another?') |
||||
64 | . '</a> <a href="' . SYMPHONY_URL . '/blueprints/events/" accesskey="a">' |
||||
65 | . __('View all Events') |
||||
66 | . '</a>', |
||||
67 | Alert::SUCCESS |
||||
68 | ); |
||||
69 | } |
||||
70 | |||||
71 | $isEditing = ($readonly ? true : false); |
||||
0 ignored issues
–
show
|
|||||
72 | $fields = array('name' => null, 'filters' => null); |
||||
73 | $about = array('name' => null); |
||||
74 | $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::EVENT); |
||||
75 | $canonical_link = null; |
||||
76 | |||||
77 | if (isset($_POST['fields'])) { |
||||
78 | $fields = $_POST['fields']; |
||||
79 | |||||
80 | if ($this->_context[0] == 'edit') { |
||||
81 | $isEditing = true; |
||||
82 | } |
||||
83 | } elseif ($this->_context[0] == 'edit' || $this->_context[0] == 'info') { |
||||
84 | $isEditing = true; |
||||
85 | $handle = $this->_context[1]; |
||||
86 | $existing = EventManager::create($handle); |
||||
87 | $about = General::array_map_recursive('stripslashes', $existing->about()); |
||||
0 ignored issues
–
show
The method
about() does not exist on Event .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
88 | |||||
89 | if ($this->_context[0] == 'edit' && !$existing->allowEditorToParse()) { |
||||
0 ignored issues
–
show
The method
allowEditorToParse() does not exist on Event .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
90 | redirect(SYMPHONY_URL . '/blueprints/events/info/' . $handle . '/'); |
||||
91 | } |
||||
92 | |||||
93 | $fields['name'] = $about['name']; |
||||
94 | $fields['source'] = stripslashes($existing->getSource()); |
||||
0 ignored issues
–
show
The method
getSource() does not exist on Event .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
95 | $provided = false; |
||||
96 | |||||
97 | if (!empty($providers)) { |
||||
98 | foreach ($providers as $providerClass => $provider) { |
||||
99 | if ($fields['source'] == call_user_func(array($providerClass, 'getClass'))) { |
||||
100 | $fields = array_merge($fields, $existing->settings()); |
||||
0 ignored issues
–
show
The method
settings() does not exist on Event .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
101 | $provided = true; |
||||
102 | break; |
||||
103 | } |
||||
104 | } |
||||
105 | } |
||||
106 | |||||
107 | if (!$provided) { |
||||
108 | if (isset($existing->eParamFILTERS)) { |
||||
109 | $fields['filters'] = array_map('stripslashes', $existing->eParamFILTERS); |
||||
110 | } |
||||
111 | } |
||||
112 | |||||
113 | $canonical_link = '/blueprints/events/' . $this->_context[0] . '/' . $handle . '/'; |
||||
114 | } |
||||
115 | |||||
116 | $name = null; |
||||
117 | // Handle name on edited changes, or from reading an edited datasource |
||||
118 | if (isset($about['name'])) { |
||||
119 | $name = $about['name']; |
||||
120 | } elseif (isset($fields['name'])) { |
||||
121 | $name = $fields['name']; |
||||
122 | } |
||||
123 | |||||
124 | $this->setPageType('form'); |
||||
125 | $this->setTitle(__(($isEditing ? '%1$s – %2$s – %3$s' : '%2$s – %3$s'), array($name, __('Events'), __('Symphony')))); |
||||
0 ignored issues
–
show
|
|||||
126 | if ($canonical_link) { |
||||
127 | $this->addElementToHead(new XMLElement('link', null, array( |
||||
128 | 'rel' => 'canonical', |
||||
129 | 'href' => SYMPHONY_URL . $canonical_link, |
||||
130 | ))); |
||||
131 | } |
||||
0 ignored issues
–
show
|
|||||
132 | $this->appendSubheading(($isEditing ? $about['name'] : __('Untitled'))); |
||||
0 ignored issues
–
show
|
|||||
133 | $this->insertBreadcrumbs(array( |
||||
134 | Widget::Anchor(__('Events'), SYMPHONY_URL . '/blueprints/events/'), |
||||
135 | )); |
||||
136 | |||||
137 | if (!$readonly) { |
||||
138 | $fieldset = new XMLElement('fieldset'); |
||||
139 | $fieldset->setAttribute('class', 'settings'); |
||||
140 | $fieldset->appendChild(new XMLElement('legend', __('Essentials'))); |
||||
141 | |||||
142 | // Target |
||||
143 | $sources = new XMLElement('div', null, array('class' => 'apply actions')); |
||||
144 | $div = new XMLElement('div'); |
||||
145 | $label = Widget::Label(__('Target'), null, 'apply-label-left'); |
||||
146 | $sources->appendChild($label); |
||||
147 | $sources->appendChild($div); |
||||
148 | |||||
149 | $sections = SectionManager::fetch(null, 'ASC', 'name'); |
||||
150 | $options = array(); |
||||
151 | $section_options = array(); |
||||
152 | $source = isset($fields['source']) ? $fields['source'] : null; |
||||
153 | |||||
154 | if (is_array($sections) && !empty($sections)) { |
||||
155 | $section_options = array('label' => __('Sections'), 'options' => array()); |
||||
156 | |||||
157 | foreach ($sections as $s) { |
||||
158 | $section_options['options'][] = array($s->get('id'), $source == $s->get('id'), General::sanitize($s->get('name'))); |
||||
159 | } |
||||
160 | } |
||||
161 | |||||
162 | $options[] = $section_options; |
||||
163 | |||||
164 | // Loop over the event providers |
||||
165 | if (!empty($providers)) { |
||||
166 | $p = array('label' => __('From extensions'), 'options' => array()); |
||||
167 | |||||
168 | foreach ($providers as $providerClass => $provider) { |
||||
169 | $p['options'][] = array( |
||||
170 | $providerClass, ($fields['source'] == $providerClass), $provider |
||||
171 | ); |
||||
172 | } |
||||
173 | |||||
174 | $options[] = $p; |
||||
175 | } |
||||
176 | |||||
177 | $div->appendChild( |
||||
178 | Widget::Select('source', $options, array('id' => 'event-context')) |
||||
179 | ); |
||||
180 | |||||
181 | if (isset($this->_errors['source'])) { |
||||
182 | $this->Context->prependChild(Widget::Error($sources, $this->_errors['source'])); |
||||
183 | } else { |
||||
184 | $this->Context->prependChild($sources); |
||||
185 | } |
||||
186 | |||||
187 | $this->Form->appendChild( |
||||
188 | Widget::Input('fields[source]', $options[0]['options'][0][0], 'hidden', array('id' => 'event-source')) |
||||
189 | ); |
||||
190 | |||||
191 | // Name |
||||
192 | $group = new XMLElement('div'); |
||||
193 | $label = Widget::Label(__('Name')); |
||||
194 | $label->appendChild(Widget::Input('fields[name]', General::sanitize($fields['name']))); |
||||
195 | |||||
196 | $div = new XMLElement('div'); |
||||
197 | $div->setAttribute('class', 'column'); |
||||
198 | |||||
199 | if (isset($this->_errors['name'])) { |
||||
200 | $div->appendChild(Widget::Error($label, $this->_errors['name'])); |
||||
201 | } else { |
||||
202 | $div->appendChild($label); |
||||
203 | } |
||||
0 ignored issues
–
show
|
|||||
204 | $group->appendChild($div); |
||||
205 | $fieldset->appendChild($group); |
||||
206 | $this->Form->appendChild($fieldset); |
||||
207 | |||||
208 | // Filters |
||||
209 | $fieldset = new XMLElement('fieldset'); |
||||
210 | $fieldset->setAttribute('class', 'settings pickable'); |
||||
211 | $fieldset->appendChild(new XMLElement('legend', __('Filters'))); |
||||
212 | $p = new XMLElement('p', __('Event Filters add additional conditions or actions to an event.')); |
||||
213 | $p->setAttribute('class', 'help'); |
||||
214 | $fieldset->appendChild($p); |
||||
215 | |||||
216 | $filters = isset($fields['filters']) ? $fields['filters'] : array(); |
||||
217 | $options = array( |
||||
218 | array('admin-only', in_array('admin-only', $filters), __('Admin Only')), |
||||
219 | array('send-email', in_array('send-email', $filters), __('Send Notification Email')), |
||||
220 | array('expect-multiple', in_array('expect-multiple', $filters), __('Allow Multiple')), |
||||
221 | ); |
||||
222 | |||||
223 | /** |
||||
224 | * Allows adding of new filter rules to the Event filter rule select box |
||||
225 | * |
||||
226 | * @delegate AppendEventFilter |
||||
227 | * @param string $context |
||||
228 | * '/blueprints/events/(edit|new|info)/' |
||||
229 | * @param array $selected |
||||
230 | * An array of all the selected filters for this Event |
||||
231 | * @param array $options |
||||
232 | * An array of all the filters that are available, passed by reference |
||||
233 | */ |
||||
234 | Symphony::ExtensionManager()->notifyMembers('AppendEventFilter', '/blueprints/events/' . $this->_context[0] . '/', array( |
||||
235 | 'selected' => $filters, |
||||
236 | 'options' => &$options |
||||
237 | )); |
||||
238 | |||||
239 | $fieldset->appendChild(Widget::Select('fields[filters][]', $options, array('multiple' => 'multiple', 'id' => 'event-filters'))); |
||||
240 | $this->Form->appendChild($fieldset); |
||||
241 | |||||
242 | // Connections |
||||
243 | $fieldset = new XMLElement('fieldset'); |
||||
244 | $fieldset->setAttribute('class', 'settings'); |
||||
245 | $fieldset->appendChild(new XMLElement('legend', __('Attach to Pages'))); |
||||
246 | $p = new XMLElement('p', __('The event will only be available on the selected pages.')); |
||||
247 | $p->setAttribute('class', 'help'); |
||||
248 | $fieldset->appendChild($p); |
||||
249 | |||||
250 | $div = new XMLElement('div'); |
||||
251 | $label = Widget::Label(__('Pages')); |
||||
252 | |||||
253 | $pages = PageManager::fetch(); |
||||
254 | $event_handle = str_replace('-', '_', Lang::createHandle($fields['name'])); |
||||
255 | $connections = ResourceManager::getAttachedPages(ResourceManager::RESOURCE_TYPE_EVENT, $event_handle); |
||||
256 | $selected = array(); |
||||
257 | |||||
258 | foreach ($connections as $connection) { |
||||
259 | $selected[] = $connection['id']; |
||||
260 | } |
||||
261 | |||||
262 | $options = array(); |
||||
263 | |||||
264 | foreach ($pages as $page) { |
||||
265 | $options[] = array( |
||||
266 | $page['id'], |
||||
267 | in_array($page['id'], $selected), |
||||
268 | General::sanitize(PageManager::resolvePageTitle($page['id'])) |
||||
269 | ); |
||||
270 | } |
||||
271 | |||||
272 | $label->appendChild(Widget::Select('fields[connections][]', $options, array('multiple' => 'multiple'))); |
||||
273 | $div->appendChild($label); |
||||
274 | |||||
275 | $fieldset->appendChild($div); |
||||
276 | $this->Form->appendChild($fieldset); |
||||
277 | |||||
278 | // Providers |
||||
279 | if (!empty($providers)) { |
||||
280 | foreach ($providers as $providerClass => $provider) { |
||||
281 | if ($isEditing && $fields['source'] !== call_user_func(array($providerClass, 'getSource'))) { |
||||
282 | continue; |
||||
283 | } |
||||
284 | |||||
285 | call_user_func_array(array($providerClass, 'buildEditor'), array($this->Form, &$this->_errors, $fields, $handle)); |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
286 | } |
||||
287 | } |
||||
288 | } else { |
||||
289 | // Author |
||||
290 | if (isset($about['author']['website'])) { |
||||
291 | $link = Widget::Anchor($about['author']['name'], General::validateURL($about['author']['website'])); |
||||
292 | } elseif (isset($about['author']['email'])) { |
||||
293 | $link = Widget::Anchor($about['author']['name'], 'mailto:' . $about['author']['email']); |
||||
294 | } else { |
||||
295 | $link = $about['author']['name']; |
||||
296 | } |
||||
297 | |||||
298 | if ($link) { |
||||
299 | $fieldset = new XMLElement('fieldset'); |
||||
300 | $fieldset->setAttribute('class', 'settings'); |
||||
301 | $fieldset->appendChild(new XMLElement('legend', __('Author'))); |
||||
302 | $fieldset->appendChild(new XMLElement('p', $link->generate(false))); |
||||
303 | $this->Form->appendChild($fieldset); |
||||
304 | } |
||||
305 | |||||
306 | // Version |
||||
307 | $fieldset = new XMLElement('fieldset'); |
||||
308 | $fieldset->setAttribute('class', 'settings'); |
||||
309 | $fieldset->appendChild(new XMLElement('legend', __('Version'))); |
||||
310 | $version = array_key_exists('version', $about) ? $about['version'] : null; |
||||
311 | $release_date = array_key_exists('release-date', $about) ? $about['release-date'] : filemtime(EventManager::__getDriverPath($handle)); |
||||
312 | |||||
313 | if (preg_match('/^\d+(\.\d+)*$/', $version)) { |
||||
314 | $fieldset->appendChild( |
||||
315 | new XMLElement('p', __('%1$s released on %2$s', array($version, DateTimeObj::format($release_date, __SYM_DATE_FORMAT__)))) |
||||
0 ignored issues
–
show
|
|||||
316 | ); |
||||
317 | } elseif (!is_null($version)) { |
||||
318 | $fieldset->appendChild( |
||||
319 | new XMLElement('p', __('Created by %1$s at %2$s', array($version, DateTimeObj::format($release_date, __SYM_DATE_FORMAT__)))) |
||||
320 | ); |
||||
321 | } else { |
||||
322 | $fieldset->appendChild( |
||||
323 | new XMLElement('p', __('Last modified on %s', array(DateTimeObj::format($release_date, __SYM_DATE_FORMAT__)))) |
||||
324 | ); |
||||
325 | } |
||||
0 ignored issues
–
show
|
|||||
326 | $this->Form->appendChild($fieldset); |
||||
327 | } |
||||
328 | |||||
329 | // If we are editing an event, it assumed that the event has documentation |
||||
330 | $fieldset = new XMLElement('fieldset'); |
||||
331 | $fieldset->setAttribute('id', 'event-documentation'); |
||||
332 | $fieldset->setAttribute('class', 'settings'); |
||||
333 | |||||
334 | if ($isEditing && method_exists($existing, 'documentation')) { |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
335 | $doc = $existing->documentation(); |
||||
336 | |||||
337 | if ($doc) { |
||||
338 | $fieldset->setValue( |
||||
339 | '<legend>' . __('Documentation') . '</legend>' . PHP_EOL . |
||||
340 | General::tabsToSpaces(is_object($doc) ? $doc->generate(true, 4) : $doc) |
||||
341 | ); |
||||
342 | } |
||||
343 | } |
||||
344 | |||||
345 | $this->Form->appendChild($fieldset); |
||||
346 | |||||
347 | $div = new XMLElement('div'); |
||||
348 | $div->setAttribute('class', 'actions'); |
||||
349 | $div->appendChild(Widget::Input('action[save]', ($isEditing ? __('Save Changes') : __('Create Event')), 'submit', array('accesskey' => 's'))); |
||||
0 ignored issues
–
show
|
|||||
350 | |||||
351 | if ($isEditing) { |
||||
352 | $button = new XMLElement('button', __('Delete')); |
||||
353 | $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'button confirm delete', 'title' => __('Delete this event'), 'type' => 'submit', 'accesskey' => 'd', 'data-message' => __('Are you sure you want to delete this event?'))); |
||||
354 | $div->appendChild($button); |
||||
355 | } |
||||
356 | |||||
357 | if (!$readonly) { |
||||
358 | $this->Form->appendChild($div); |
||||
359 | } |
||||
360 | } |
||||
361 | |||||
362 | public function __actionNew() |
||||
363 | { |
||||
364 | if (array_key_exists('save', $_POST['action'])) { |
||||
365 | return $this->__formAction(); |
||||
0 ignored issues
–
show
Are you sure the usage of
$this->__formAction() targeting contentBlueprintsEvents::__formAction() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
366 | } |
||||
367 | } |
||||
368 | |||||
369 | public function __actionEdit() |
||||
370 | { |
||||
371 | if (array_key_exists('save', $_POST['action'])) { |
||||
372 | return $this->__formAction(); |
||||
0 ignored issues
–
show
Are you sure the usage of
$this->__formAction() targeting contentBlueprintsEvents::__formAction() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
373 | } elseif (array_key_exists('delete', $_POST['action'])) { |
||||
374 | /** |
||||
375 | * Prior to deleting the Event file. Target file path is provided. |
||||
376 | * |
||||
377 | * @delegate EventPreDelete |
||||
378 | * @since Symphony 2.2 |
||||
379 | * @param string $context |
||||
380 | * '/blueprints/events/' |
||||
381 | * @param string $file |
||||
382 | * The path to the Event file |
||||
383 | */ |
||||
384 | Symphony::ExtensionManager()->notifyMembers('EventPreDelete', '/blueprints/events/', array('file' => EVENTS . "/event." . $this->_context[1] . ".php")); |
||||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
/event. does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() Coding Style
Comprehensibility
introduced
by
The string literal
.php does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||||
385 | |||||
386 | if (!General::deleteFile(EVENTS . '/event.' . $this->_context[1] . '.php')) { |
||||
387 | $this->pageAlert( |
||||
388 | __('Failed to delete %s.', array('<code>' . $this->_context[1] . '</code>')) |
||||
389 | . ' ' . __('Please check permissions on %s.', array('<code>/workspace/events</code>')), |
||||
390 | Alert::ERROR |
||||
391 | ); |
||||
392 | } else { |
||||
393 | $pages = ResourceManager::getAttachedPages(ResourceManager::RESOURCE_TYPE_EVENT, $this->_context[1]); |
||||
394 | |||||
395 | foreach ($pages as $page) { |
||||
396 | ResourceManager::detach(ResourceManager::RESOURCE_TYPE_EVENT, $this->_context[1], $page['id']); |
||||
397 | } |
||||
398 | |||||
399 | redirect(SYMPHONY_URL . '/blueprints/events/'); |
||||
0 ignored issues
–
show
|
|||||
400 | } |
||||
401 | } |
||||
402 | } |
||||
403 | |||||
404 | public function __actionIndex($resource_type) |
||||
405 | { |
||||
406 | return parent::__actionIndex(ResourceManager::RESOURCE_TYPE_EVENT); |
||||
0 ignored issues
–
show
Are you sure the usage of
parent::__actionIndex(Re...r::RESOURCE_TYPE_EVENT) targeting ResourcesPage::__actionIndex() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes. ![]() |
|||||
407 | } |
||||
408 | |||||
409 | public function __formAction() |
||||
410 | { |
||||
411 | $fields = $_POST['fields']; |
||||
412 | $this->_errors = array(); |
||||
413 | $providers = Symphony::ExtensionManager()->getProvidersOf(iProvider::EVENT); |
||||
414 | $providerClass = null; |
||||
415 | |||||
416 | if (trim($fields['name']) == '') { |
||||
417 | $this->_errors['name'] = __('This is a required field'); |
||||
418 | } elseif (strpos($fields['name'], '\\') !== false) { |
||||
419 | $this->_errors['name'] = __('This field contains invalid characters') . ' (\\)'; |
||||
420 | } elseif (!preg_match('/^[a-z]/i', $fields['name'])) { |
||||
421 | $this->_errors['name'] = __('The name of the event must begin with a letter.'); |
||||
422 | } |
||||
423 | |||||
424 | if (trim($fields['source']) == '') { |
||||
425 | $this->_errors['source'] = __('This is a required field'); |
||||
426 | } |
||||
427 | |||||
428 | $filters = isset($fields['filters']) ? $fields['filters'] : array(); |
||||
429 | |||||
430 | // See if a Provided Datasource is saved |
||||
431 | if (!empty($providers)) { |
||||
432 | foreach ($providers as $providerClass => $provider) { |
||||
433 | if ($fields['source'] == call_user_func(array($providerClass, 'getSource'))) { |
||||
434 | call_user_func_array(array($providerClass, 'validate'), array(&$fields, &$this->_errors)); |
||||
435 | break; |
||||
436 | } |
||||
437 | |||||
438 | unset($providerClass); |
||||
439 | } |
||||
440 | } |
||||
441 | |||||
442 | $classname = Lang::createHandle($fields['name'], 255, '_', false, true, array('@^[^a-z\d]+@i' => '', '/[^\w\-\.]/i' => '')); |
||||
443 | $rootelement = str_replace('_', '-', $classname); |
||||
444 | $extends = 'SectionEvent'; |
||||
445 | |||||
446 | // Check to make sure the classname is not empty after handlisation. |
||||
447 | if (empty($classname) && !isset($this->_errors['name'])) { |
||||
448 | $this->_errors['name'] = __('Please ensure name contains at least one Latin-based character.', array($classname)); |
||||
449 | } |
||||
450 | |||||
451 | $file = EVENTS . '/event.' . $classname . '.php'; |
||||
0 ignored issues
–
show
|
|||||
452 | $isDuplicate = false; |
||||
453 | $queueForDeletion = null; |
||||
454 | |||||
455 | if ($this->_context[0] == 'new' && is_file($file)) { |
||||
456 | $isDuplicate = true; |
||||
457 | } elseif ($this->_context[0] == 'edit') { |
||||
458 | $existing_handle = $this->_context[1]; |
||||
459 | |||||
460 | if ($classname != $existing_handle && is_file($file)) { |
||||
461 | $isDuplicate = true; |
||||
462 | } elseif ($classname != $existing_handle) { |
||||
463 | $queueForDeletion = EVENTS . '/event.' . $existing_handle . '.php'; |
||||
464 | } |
||||
465 | } |
||||
466 | |||||
467 | // Duplicate |
||||
468 | if ($isDuplicate) { |
||||
469 | $this->_errors['name'] = __('An Event with the name %s already exists', array('<code>' . $classname . '</code>')); |
||||
470 | } |
||||
471 | |||||
472 | if (empty($this->_errors)) { |
||||
473 | $source = $fields['source']; |
||||
474 | $params = array( |
||||
475 | 'rootelement' => $rootelement, |
||||
476 | ); |
||||
477 | |||||
478 | $about = array( |
||||
479 | 'name' => $fields['name'], |
||||
480 | 'version' => 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), |
||||
481 | 'release date' => DateTimeObj::getGMT('c'), |
||||
482 | 'author name' => Symphony::Author()->getFullName(), |
||||
483 | 'author website' => URL, |
||||
0 ignored issues
–
show
|
|||||
484 | 'author email' => Symphony::Author()->get('email') |
||||
485 | ); |
||||
486 | |||||
487 | // If there is a provider, get their template |
||||
488 | if ($providerClass) { |
||||
489 | $eventShell = file_get_contents(call_user_func(array($providerClass, 'getTemplate'))); |
||||
490 | } else { |
||||
491 | $eventShell = file_get_contents($this->getTemplate('blueprints.event')); |
||||
0 ignored issues
–
show
It seems like
$this->getTemplate('blueprints.event') can also be of type false ; however, parameter $filename of file_get_contents() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
492 | $about['trigger condition'] = $rootelement; |
||||
493 | } |
||||
494 | |||||
495 | $this->__injectAboutInformation($eventShell, $about); |
||||
496 | |||||
497 | // Replace the name |
||||
498 | $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell); |
||||
499 | |||||
500 | // Build the templates |
||||
501 | if ($providerClass) { |
||||
502 | $eventShell = call_user_func(array($providerClass, 'prepare'), $fields, $params, $eventShell); |
||||
503 | } else { |
||||
504 | $this->__injectFilters($eventShell, $filters); |
||||
505 | |||||
506 | // Add Documentation |
||||
507 | $ajaxEventDoc = new contentAjaxEventDocumentation(); |
||||
508 | $doc_parts = array(); |
||||
509 | |||||
510 | // Add Documentation (Success/Failure) |
||||
511 | $ajaxEventDoc->addEntrySuccessDoc($doc_parts, $rootelement, $filters); |
||||
512 | $ajaxEventDoc->addEntryFailureDoc($doc_parts, $rootelement, $filters); |
||||
513 | |||||
514 | // Filters |
||||
515 | $ajaxEventDoc->addDefaultFiltersDoc($doc_parts, $rootelement, $filters); |
||||
516 | |||||
517 | // Frontend Markup |
||||
518 | $ajaxEventDoc->addFrontendMarkupDoc($doc_parts, $rootelement, $fields['source'], $filters); |
||||
519 | $ajaxEventDoc->addSendMailFilterDoc($doc_parts, $filters); |
||||
520 | |||||
521 | /** |
||||
522 | * Allows adding documentation for new filters. A reference to the $documentation |
||||
523 | * array is provided, along with selected filters |
||||
524 | * @delegate AppendEventFilterDocumentation |
||||
525 | * @param string $context |
||||
526 | * '/blueprints/events/(edit|new|info)/' |
||||
527 | * @param array $selected |
||||
528 | * An array of all the selected filters for this Event |
||||
529 | * @param array $documentation |
||||
530 | * An array of all the documentation XMLElements, passed by reference |
||||
531 | * @param string $rootelment |
||||
532 | * The name of this event, as a handle. |
||||
533 | */ |
||||
534 | Symphony::ExtensionManager()->notifyMembers('AppendEventFilterDocumentation', '/blueprints/events/', array( |
||||
535 | 'selected' => $filters, |
||||
536 | 'documentation' => &$doc_parts, |
||||
537 | 'rootelement' => $rootelement |
||||
538 | )); |
||||
539 | |||||
540 | $documentation = join(PHP_EOL, array_map(function($part) { |
||||
0 ignored issues
–
show
|
|||||
541 | return rtrim($part->generate(true, 4)); |
||||
542 | }, $doc_parts)); |
||||
543 | $documentation = str_replace('\'', '\\\'', $documentation); |
||||
544 | |||||
545 | $eventShell = str_replace('<!-- CLASS EXTENDS -->', $extends, $eventShell); |
||||
546 | $eventShell = str_replace('<!-- DOCUMENTATION -->', General::tabsToSpaces($documentation, 4), $eventShell); |
||||
547 | } |
||||
548 | |||||
549 | $eventShell = str_replace('<!-- ROOT ELEMENT -->', $rootelement, $eventShell); |
||||
550 | $eventShell = str_replace('<!-- CLASS NAME -->', $classname, $eventShell); |
||||
551 | $eventShell = str_replace('<!-- SOURCE -->', addslashes($source), $eventShell); |
||||
552 | |||||
553 | // Remove left over placeholders |
||||
554 | $eventShell = preg_replace(array('/<!--[\w ]++-->/'), '', $eventShell); |
||||
555 | |||||
556 | if ($this->_context[0] == 'new') { |
||||
557 | /** |
||||
558 | * Prior to creating an Event, the file path where it will be written to |
||||
559 | * is provided and well as the contents of that file. |
||||
560 | * |
||||
561 | * @delegate EventsPreCreate |
||||
562 | * @since Symphony 2.2 |
||||
563 | * @param string $context |
||||
564 | * '/blueprints/events/' |
||||
565 | * @param string $file |
||||
566 | * The path to the Event file |
||||
567 | * @param string $contents |
||||
568 | * The contents for this Event as a string passed by reference |
||||
569 | * @param array $filters |
||||
570 | * An array of the filters attached to this event |
||||
571 | */ |
||||
572 | Symphony::ExtensionManager()->notifyMembers('EventPreCreate', '/blueprints/events/', array( |
||||
573 | 'file' => $file, |
||||
574 | 'contents' => &$eventShell, |
||||
575 | 'filters' => $filters |
||||
576 | )); |
||||
577 | } else { |
||||
578 | /** |
||||
579 | * Prior to editing an Event, the file path where it will be written to |
||||
580 | * is provided and well as the contents of that file. |
||||
581 | * |
||||
582 | * @delegate EventPreEdit |
||||
583 | * @since Symphony 2.2 |
||||
584 | * @param string $context |
||||
585 | * '/blueprints/events/' |
||||
586 | * @param string $file |
||||
587 | * The path to the Event file |
||||
588 | * @param string $contents |
||||
589 | * The contents for this Event as a string passed by reference |
||||
590 | * @param array $filters |
||||
591 | * An array of the filters attached to this event |
||||
592 | */ |
||||
593 | Symphony::ExtensionManager()->notifyMembers('EventPreEdit', '/blueprints/events/', array( |
||||
594 | 'file' => $file, |
||||
595 | 'contents' => &$eventShell, |
||||
596 | 'filters' => $filters |
||||
597 | )); |
||||
598 | } |
||||
599 | |||||
600 | // Write the file |
||||
601 | if (!General::writeFile($file, $eventShell, Symphony::Configuration()->get('write_mode', 'file'))) { |
||||
0 ignored issues
–
show
It seems like
Symphony::Configuration(...t('write_mode', 'file') can also be of type array ; however, parameter $perm of General::writeFile() does only seem to accept integer|string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
602 | $this->pageAlert( |
||||
603 | __('Failed to write Event to disk.') |
||||
604 | . ' ' . __('Please check permissions on %s.', array('<code>/workspace/events</code>')), |
||||
605 | Alert::ERROR |
||||
606 | ); |
||||
607 | |||||
608 | // Write successful |
||||
609 | } else { |
||||
610 | if (function_exists('opcache_invalidate')) { |
||||
611 | @opcache_invalidate($file, true); |
||||
0 ignored issues
–
show
It seems like you do not handle an error condition for
opcache_invalidate() . This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
|||||
612 | } |
||||
613 | |||||
614 | // Attach this event to pages |
||||
615 | $connections = $fields['connections']; |
||||
616 | ResourceManager::setPages(ResourceManager::RESOURCE_TYPE_EVENT, is_null($existing_handle) ? $classname : $existing_handle, $connections); |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
617 | |||||
618 | if ($queueForDeletion) { |
||||
619 | General::deleteFile($queueForDeletion); |
||||
620 | |||||
621 | $pages = PageManager::fetch(false, array('events', 'id'), array(" |
||||
622 | `events` REGEXP '[[:<:]]" . $existing_handle . "[[:>:]]' |
||||
623 | ")); |
||||
624 | |||||
625 | if (is_array($pages) && !empty($pages)) { |
||||
626 | foreach ($pages as $page) { |
||||
627 | $page['events'] = preg_replace('/\b'.$existing_handle.'\b/i', $classname, $page['events']); |
||||
628 | |||||
629 | PageManager::edit($page['id'], $page); |
||||
630 | } |
||||
631 | } |
||||
632 | } |
||||
633 | |||||
634 | if ($this->_context[0] == 'new') { |
||||
635 | /** |
||||
636 | * After creating the Event, the path to the Event file is provided |
||||
637 | * |
||||
638 | * @delegate EventPostCreate |
||||
639 | * @since Symphony 2.2 |
||||
640 | * @param string $context |
||||
641 | * '/blueprints/events/' |
||||
642 | * @param string $file |
||||
643 | * The path to the Event file |
||||
644 | */ |
||||
645 | Symphony::ExtensionManager()->notifyMembers('EventPostCreate', '/blueprints/events/', array( |
||||
646 | 'file' => $file |
||||
647 | )); |
||||
648 | } else { |
||||
649 | /** |
||||
650 | * After editing the Event, the path to the Event file is provided |
||||
651 | * |
||||
652 | * @delegate EventPostEdit |
||||
653 | * @since Symphony 2.2 |
||||
654 | * @param string $context |
||||
655 | * '/blueprints/events/' |
||||
656 | * @param string $file |
||||
657 | * The path to the Event file |
||||
658 | * @param string $previous_file |
||||
659 | * The path of the previous Event file in the case where an Event may |
||||
660 | * have been renamed. To get the handle from this value, see |
||||
661 | * `EventManager::__getHandleFromFilename` |
||||
662 | */ |
||||
663 | Symphony::ExtensionManager()->notifyMembers('EventPostEdit', '/blueprints/events/', array( |
||||
664 | 'file' => $file, |
||||
665 | 'previous_file' => ($queueForDeletion) ? $queueForDeletion : null |
||||
666 | )); |
||||
667 | } |
||||
668 | |||||
669 | redirect(SYMPHONY_URL . '/blueprints/events/edit/'.$classname.'/'.($this->_context[0] == 'new' ? 'created' : 'saved') . '/'); |
||||
0 ignored issues
–
show
|
|||||
670 | } |
||||
671 | } |
||||
672 | } |
||||
673 | |||||
674 | public function __injectFilters(&$shell, $elements) |
||||
675 | { |
||||
676 | if (!is_array($elements) || empty($elements)) { |
||||
677 | return; |
||||
678 | } |
||||
0 ignored issues
–
show
|
|||||
679 | $elements = array_map('addslashes', $elements); |
||||
680 | $shell = str_replace('<!-- FILTERS -->', "'" . implode("'," . PHP_EOL . " '", $elements) . "'", $shell); |
||||
681 | } |
||||
682 | |||||
683 | public function __injectAboutInformation(&$shell, $details) |
||||
684 | { |
||||
685 | if (!is_array($details) || empty($details)) { |
||||
686 | return; |
||||
687 | } |
||||
688 | |||||
689 | foreach ($details as $key => $val) { |
||||
690 | if (!is_string($key) || !is_string($val)) { |
||||
691 | continue; |
||||
692 | } |
||||
693 | |||||
694 | $shell = str_replace('<!-- ' . strtoupper(addslashes($key)) . ' -->', addslashes($val), $shell); |
||||
695 | } |
||||
696 | } |
||||
697 | } |
||||
698 |
Classes in PHP are usually named in CamelCase.
In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. The whole name starts with a capital letter as well.
Thus the name database provider becomes
DatabaseProvider
.