1 | <?php |
||||
2 | |||||
3 | /** |
||||
4 | * @package content |
||||
5 | */ |
||||
6 | |||||
7 | /** |
||||
8 | * Controller page for all Symphony Author related activity |
||||
9 | * including making new Authors, editing Authors or deleting |
||||
10 | * Authors from Symphony |
||||
11 | */ |
||||
12 | |||||
13 | class contentSystemAuthors extends AdministrationPage |
||||
0 ignored issues
–
show
|
|||||
14 | { |
||||
15 | public $_Author; |
||||
16 | public $_errors = array(); |
||||
17 | |||||
18 | public function sort(&$sort, &$order, $params) |
||||
19 | { |
||||
20 | if (is_null($sort) || $sort == 'name') { |
||||
21 | return AuthorManager::fetch("first_name $order, last_name", $order); |
||||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $order instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||||
22 | } else { |
||||
23 | $sort = General::sanitize($sort); |
||||
24 | } |
||||
25 | |||||
26 | return AuthorManager::fetch($sort, $order); |
||||
27 | } |
||||
28 | |||||
29 | public function __viewIndex() |
||||
30 | { |
||||
31 | $this->setPageType('table'); |
||||
32 | $this->setTitle(__('%1$s – %2$s', array(__('Authors'), __('Symphony')))); |
||||
33 | |||||
34 | if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) { |
||||
35 | $this->appendSubheading(__('Authors'), Widget::Anchor(__('Create New'), Administration::instance()->getCurrentPageURL().'new/', __('Create a new author'), 'create button', null, array('accesskey' => 'c'))); |
||||
36 | } else { |
||||
37 | $this->appendSubheading(__('Authors')); |
||||
38 | } |
||||
39 | |||||
40 | Sortable::initialize($this, $authors, $sort, $order); |
||||
41 | |||||
42 | $columns = array( |
||||
43 | array( |
||||
44 | 'label' => __('Name'), |
||||
45 | 'sortable' => true, |
||||
46 | 'handle' => 'name' |
||||
47 | ), |
||||
48 | array( |
||||
49 | 'label' => __('Email Address'), |
||||
50 | 'sortable' => true, |
||||
51 | 'handle' => 'email' |
||||
52 | ), |
||||
53 | array( |
||||
54 | 'label' => __('Last Seen'), |
||||
55 | 'sortable' => true, |
||||
56 | 'handle' => 'last_seen' |
||||
57 | ) |
||||
58 | ); |
||||
59 | |||||
60 | if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) { |
||||
61 | $columns = array_merge($columns, array( |
||||
62 | array( |
||||
63 | 'label' => __('User Type'), |
||||
64 | 'sortable' => true, |
||||
65 | 'handle' => 'user_type' |
||||
66 | ), |
||||
67 | array( |
||||
68 | 'label' => __('Language'), |
||||
69 | 'sortable' => true, |
||||
70 | 'handle' => 'language' |
||||
71 | ) |
||||
72 | )); |
||||
73 | } |
||||
74 | |||||
75 | /** |
||||
76 | * Allows the creation of custom table columns for each author. Called |
||||
77 | * after all the table headers columns have been added. |
||||
78 | * |
||||
79 | * @delegate AddCustomAuthorColumn |
||||
80 | * @since Symphony 2.7.0 |
||||
81 | * @param string $context |
||||
82 | * '/system/authors/' |
||||
83 | * @param array $columns |
||||
84 | * An array of the current columns, passed by reference |
||||
85 | */ |
||||
86 | Symphony::ExtensionManager()->notifyMembers('AddCustomAuthorColumn', '/system/authors/', array( |
||||
87 | 'columns' => &$columns, |
||||
88 | )); |
||||
89 | |||||
90 | $aTableHead = Sortable::buildTableHeaders($columns, $sort, $order, (isset($_REQUEST['filter']) ? '&filter=' . $_REQUEST['filter'] : '')); |
||||
91 | |||||
92 | $aTableBody = array(); |
||||
93 | |||||
94 | if (!is_array($authors) || empty($authors)) { |
||||
95 | $aTableBody = array( |
||||
96 | Widget::TableRow(array(Widget::TableData(__('None found.'), 'inactive', null, count($aTableHead))), 'odd') |
||||
97 | ); |
||||
98 | } else { |
||||
99 | foreach ($authors as $a) { |
||||
100 | // Setup each cell |
||||
101 | if ( |
||||
0 ignored issues
–
show
|
|||||
102 | (Symphony::Author()->isDeveloper() || (Symphony::Author()->isManager() && !$a->isDeveloper())) |
||||
103 | || Symphony::Author()->get('id') == $a->get('id') |
||||
104 | ) { |
||||
105 | $td1 = Widget::TableData( |
||||
106 | Widget::Anchor($a->getFullName(), Administration::instance()->getCurrentPageURL() . 'edit/' . $a->get('id') . '/', $a->get('username'), 'author') |
||||
107 | ); |
||||
108 | } else { |
||||
109 | $td1 = Widget::TableData($a->getFullName(), 'inactive'); |
||||
110 | } |
||||
111 | |||||
112 | // Can this Author be edited by the current Author? |
||||
113 | if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) { |
||||
114 | if ($a->get('id') != Symphony::Author()->get('id')) { |
||||
115 | $td1->appendChild(Widget::Label(__('Select Author %s', array($a->getFullName())), null, 'accessible', null, array( |
||||
116 | 'for' => 'author-' . $a->get('id') |
||||
117 | ))); |
||||
118 | $td1->appendChild(Widget::Input('items['.$a->get('id').']', 'on', 'checkbox', array( |
||||
119 | 'id' => 'author-' . $a->get('id') |
||||
120 | ))); |
||||
121 | } |
||||
122 | } |
||||
123 | |||||
124 | $td2 = Widget::TableData(Widget::Anchor($a->get('email'), 'mailto:'.$a->get('email'), __('Email this author'))); |
||||
125 | |||||
126 | if (!is_null($a->get('last_seen'))) { |
||||
127 | $td3 = Widget::TableData( |
||||
128 | DateTimeObj::format($a->get('last_seen'), __SYM_DATETIME_FORMAT__) |
||||
0 ignored issues
–
show
It seems like
DateTimeObj::format($a->..._SYM_DATETIME_FORMAT__) can also be of type false ; however, parameter $value of Widget::TableData() does only seem to accept XMLElement|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
![]() |
|||||
129 | ); |
||||
130 | } else { |
||||
131 | $td3 = Widget::TableData(__('Unknown'), 'inactive'); |
||||
132 | } |
||||
133 | |||||
134 | if ($a->isDeveloper()) { |
||||
135 | $type = 'Developer'; |
||||
136 | } elseif ($a->isManager()) { |
||||
137 | $type = 'Manager'; |
||||
138 | } else { |
||||
139 | $type = 'Author'; |
||||
140 | } |
||||
141 | |||||
142 | $td4 = Widget::TableData(__($type)); |
||||
143 | |||||
144 | $languages = Lang::getAvailableLanguages(); |
||||
145 | |||||
146 | $td5 = Widget::TableData($a->get("language") == null ? __("System Default") : $languages[$a->get("language")]); |
||||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
language 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
System Default 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. ![]() |
|||||
147 | |||||
148 | $tableData = array(); |
||||
149 | // Add a row to the body array, assigning each cell to the row |
||||
150 | if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) { |
||||
151 | $tableData = array($td1, $td2, $td3, $td4, $td5); |
||||
152 | } else { |
||||
153 | $tableData = array($td1, $td2, $td3); |
||||
154 | } |
||||
155 | |||||
156 | /** |
||||
157 | * Allows Extensions to inject custom table data for each Author |
||||
158 | * into the Authors Index |
||||
159 | * |
||||
160 | * @delegate AddCustomAuthorColumnData |
||||
161 | * @since Symphony 2.7.0 |
||||
162 | * @param string $context |
||||
163 | * '/system/authors/' |
||||
164 | * @param array $tableData |
||||
165 | * An array of `Widget::TableData`, passed by reference |
||||
166 | * @param array $columns |
||||
167 | * An array of the current columns |
||||
168 | * @param Author $author |
||||
169 | * The Author object. |
||||
170 | */ |
||||
171 | Symphony::ExtensionManager()->notifyMembers('AddCustomAuthorColumnData', '/system/authors/', array( |
||||
172 | 'tableData' => &$tableData, |
||||
173 | 'columns' => $columns, |
||||
174 | 'author' => $a, |
||||
175 | )); |
||||
176 | |||||
177 | $aTableBody[] = Widget::TableRow($tableData); |
||||
178 | } |
||||
179 | } |
||||
180 | |||||
181 | $table = Widget::Table( |
||||
182 | Widget::TableHead($aTableHead), |
||||
183 | null, |
||||
184 | Widget::TableBody($aTableBody), |
||||
185 | 'selectable', |
||||
186 | null, |
||||
187 | array('role' => 'directory', 'aria-labelledby' => 'symphony-subheading') |
||||
188 | ); |
||||
189 | |||||
190 | $this->Form->appendChild($table); |
||||
191 | |||||
192 | $version = new XMLElement('p', 'Symphony ' . Symphony::Configuration()->get('version', 'symphony'), array( |
||||
193 | 'id' => 'version' |
||||
194 | )); |
||||
195 | |||||
196 | $this->Form->appendChild($version); |
||||
197 | } |
||||
198 | |||||
199 | // Both the Edit and New pages need the same form |
||||
200 | public function __viewNew() |
||||
201 | { |
||||
202 | $this->__form(); |
||||
203 | } |
||||
204 | |||||
205 | public function __viewEdit() |
||||
206 | { |
||||
207 | $this->__form(); |
||||
208 | } |
||||
209 | |||||
210 | public function __form() |
||||
211 | { |
||||
212 | // Handle unknown context |
||||
213 | if (!in_array($this->_context[0], array('new', 'edit'))) { |
||||
214 | Administration::instance()->errorPageNotFound(); |
||||
215 | } |
||||
216 | |||||
217 | if ($this->_context[0] == 'new' && !Symphony::Author()->isDeveloper() && !Symphony::Author()->isManager()) { |
||||
218 | Administration::instance()->throwCustomError( |
||||
219 | __('You are not authorised to access this page.'), |
||||
220 | __('Access Denied'), |
||||
221 | Page::HTTP_STATUS_UNAUTHORIZED |
||||
222 | ); |
||||
223 | } |
||||
224 | |||||
225 | if (isset($this->_context[2])) { |
||||
226 | $time = Widget::Time(); |
||||
227 | |||||
228 | switch ($this->_context[2]) { |
||||
229 | case 'saved': |
||||
230 | $message = __('Author updated at %s.', array($time->generate())); |
||||
231 | break; |
||||
232 | case 'created': |
||||
233 | $message = __('Author created at %s.', array($time->generate())); |
||||
234 | } |
||||
235 | |||||
236 | $this->pageAlert( |
||||
237 | $message |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
238 | . ' <a href="' . SYMPHONY_URL . '/system/authors/new/" accesskey="c">' |
||||
0 ignored issues
–
show
|
|||||
239 | . __('Create another?') |
||||
240 | . '</a> <a href="' . SYMPHONY_URL . '/system/authors/" accesskey="a">' |
||||
241 | . __('View all Authors') |
||||
242 | . '</a>', |
||||
243 | Alert::SUCCESS |
||||
244 | ); |
||||
245 | } |
||||
246 | |||||
247 | $this->setPageType('form'); |
||||
248 | $isOwner = false; |
||||
249 | $isEditing = ($this->_context[0] == 'edit'); |
||||
250 | $canonical_link = null; |
||||
251 | |||||
252 | if (isset($_POST['fields'])) { |
||||
253 | $author = $this->_Author; |
||||
254 | } elseif ($this->_context[0] == 'edit') { |
||||
255 | if (!$author_id = (int)$this->_context[1]) { |
||||
256 | redirect(SYMPHONY_URL . '/system/authors/'); |
||||
257 | } |
||||
258 | |||||
259 | if (!$author = AuthorManager::fetchByID($author_id)) { |
||||
260 | Administration::instance()->throwCustomError( |
||||
261 | __('The author profile you requested does not exist.'), |
||||
262 | __('Author not found'), |
||||
263 | Page::HTTP_STATUS_NOT_FOUND |
||||
264 | ); |
||||
265 | } |
||||
0 ignored issues
–
show
|
|||||
266 | $canonical_link = '/system/authors/edit/' . $author_id . '/'; |
||||
267 | } else { |
||||
268 | $author = new Author(); |
||||
269 | } |
||||
270 | |||||
271 | if ($isEditing && $author->get('id') == Symphony::Author()->get('id')) { |
||||
272 | $isOwner = true; |
||||
273 | } |
||||
274 | |||||
275 | if ($isEditing && !$isOwner && !Symphony::Author()->isDeveloper() && !Symphony::Author()->isManager()) { |
||||
276 | Administration::instance()->throwCustomError( |
||||
277 | __('You are not authorised to edit other authors.'), |
||||
278 | __('Access Denied'), |
||||
279 | Page::HTTP_STATUS_FORBIDDEN |
||||
280 | ); |
||||
281 | } |
||||
282 | |||||
283 | $this->setTitle(__(($this->_context[0] == 'new' ? '%2$s – %3$s' : '%1$s – %2$s – %3$s'), array($author->getFullName(), __('Authors'), __('Symphony')))); |
||||
0 ignored issues
–
show
|
|||||
284 | if ($canonical_link) { |
||||
285 | $this->addElementToHead(new XMLElement('link', null, array( |
||||
286 | 'rel' => 'canonical', |
||||
287 | 'href' => SYMPHONY_URL . $canonical_link, |
||||
288 | ))); |
||||
289 | } |
||||
0 ignored issues
–
show
|
|||||
290 | $this->appendSubheading(($this->_context[0] == 'new' ? __('Untitled') : $author->getFullName())); |
||||
0 ignored issues
–
show
|
|||||
291 | $this->insertBreadcrumbs(array( |
||||
292 | Widget::Anchor(__('Authors'), SYMPHONY_URL . '/system/authors/'), |
||||
293 | )); |
||||
294 | |||||
295 | // Essentials |
||||
296 | $group = new XMLElement('fieldset'); |
||||
297 | $group->setAttribute('class', 'settings'); |
||||
298 | $group->appendChild(new XMLElement('legend', __('Essentials'))); |
||||
299 | |||||
300 | $div = new XMLElement('div'); |
||||
301 | $div->setAttribute('class', 'two columns'); |
||||
302 | |||||
303 | $label = Widget::Label(__('First Name'), null, 'column'); |
||||
304 | $label->appendChild(Widget::Input('fields[first_name]', $author->get('first_name'))); |
||||
305 | $div->appendChild((isset($this->_errors['first_name']) ? Widget::Error($label, $this->_errors['first_name']) : $label)); |
||||
306 | |||||
0 ignored issues
–
show
|
|||||
307 | |||||
308 | $label = Widget::Label(__('Last Name'), null, 'column'); |
||||
309 | $label->appendChild(Widget::Input('fields[last_name]', $author->get('last_name'))); |
||||
310 | $div->appendChild((isset($this->_errors['last_name']) ? Widget::Error($label, $this->_errors['last_name']) : $label)); |
||||
311 | |||||
312 | $group->appendChild($div); |
||||
313 | |||||
314 | $label = Widget::Label(__('Email Address')); |
||||
315 | $label->appendChild(Widget::Input('fields[email]', $author->get('email'), 'text', array('autocomplete' => 'off'))); |
||||
316 | $group->appendChild((isset($this->_errors['email']) ? Widget::Error($label, $this->_errors['email']) : $label)); |
||||
317 | |||||
318 | $this->Form->appendChild($group); |
||||
319 | |||||
320 | // Login Details |
||||
321 | $group = new XMLElement('fieldset'); |
||||
322 | $group->setAttribute('class', 'settings'); |
||||
323 | $group->appendChild(new XMLElement('legend', __('Login Details'))); |
||||
324 | |||||
325 | $div = new XMLElement('div'); |
||||
326 | |||||
327 | $label = Widget::Label(__('Username')); |
||||
328 | $label->appendChild(Widget::Input('fields[username]', $author->get('username'), 'text', array('autocomplete' => 'off'))); |
||||
329 | $div->appendChild((isset($this->_errors['username']) ? Widget::Error($label, $this->_errors['username']) : $label)); |
||||
330 | |||||
331 | // Only developers can change the user type. Primary account should NOT be able to change this |
||||
332 | if ((Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) && !$author->isPrimaryAccount()) { |
||||
0 ignored issues
–
show
|
|||||
333 | |||||
334 | // Create columns |
||||
335 | $div->setAttribute('class', 'two columns'); |
||||
336 | $label->setAttribute('class', 'column'); |
||||
337 | |||||
338 | // User type |
||||
339 | $label = Widget::Label(__('User Type'), null, 'column'); |
||||
340 | |||||
341 | $options = array( |
||||
342 | array('author', false, __('Author')), |
||||
343 | array('manager', $author->isManager(), __('Manager')) |
||||
344 | ); |
||||
345 | |||||
346 | if (Symphony::Author()->isDeveloper()) { |
||||
347 | $options[] = array('developer', $author->isDeveloper(), __('Developer')); |
||||
348 | } |
||||
349 | |||||
350 | $label->appendChild(Widget::Select('fields[user_type]', $options)); |
||||
351 | if (isset($this->_errors['user_type'])) { |
||||
352 | $div->appendChild(Widget::Error($label, $this->_errors['user_type'])); |
||||
353 | } else { |
||||
354 | $div->appendChild($label); |
||||
355 | } |
||||
356 | } |
||||
357 | |||||
358 | $group->appendChild($div); |
||||
359 | |||||
360 | // Password |
||||
361 | $fieldset = new XMLElement('fieldset', null, array('class' => 'two columns', 'id' => 'password')); |
||||
362 | $legend = new XMLElement('legend', __('Password')); |
||||
363 | $help = new XMLElement('i', __('Leave password fields blank to keep the current password')); |
||||
364 | $fieldset->appendChild($legend); |
||||
365 | $fieldset->appendChild($help); |
||||
366 | |||||
367 | /* |
||||
368 | Password reset rules: |
||||
369 | - Primary account can edit all accounts. |
||||
370 | - Developers can edit all developers, managers and authors, and their own. |
||||
371 | - Managers can edit all Authors, and their own. |
||||
372 | - Authors can edit their own. |
||||
373 | */ |
||||
374 | if ($isEditing && !( |
||||
375 | // All accounts can edit their own |
||||
376 | $isOwner |
||||
377 | // Managers can edit all Authors, and their own. |
||||
378 | || (Symphony::Author()->isManager() && $author->isAuthor()) |
||||
379 | // Primary account can edit all accounts. |
||||
380 | || Symphony::Author()->isPrimaryAccount() |
||||
381 | // Developers can edit all developers, managers and authors, and their own. |
||||
382 | || Symphony::Author()->isDeveloper() && $author->isPrimaryAccount() === false |
||||
383 | )) { |
||||
384 | $fieldset->setAttribute('class', 'three columns'); |
||||
385 | |||||
386 | $label = Widget::Label(null, null, 'column'); |
||||
387 | $label->appendChild(Widget::Input('fields[old-password]', null, 'password', array('placeholder' => __('Old Password'), 'autocomplete' => 'off'))); |
||||
388 | $fieldset->appendChild((isset($this->_errors['old-password']) ? Widget::Error($label, $this->_errors['old-password']) : $label)); |
||||
389 | } |
||||
390 | |||||
391 | // New password |
||||
392 | $placeholder = ($isEditing ? __('New Password') : __('Password')); |
||||
0 ignored issues
–
show
|
|||||
393 | $label = Widget::Label(null, null, 'column'); |
||||
394 | $label->appendChild(Widget::Input('fields[password]', null, 'password', array('placeholder' => $placeholder, 'autocomplete' => 'off'))); |
||||
395 | $fieldset->appendChild((isset($this->_errors['password']) ? Widget::Error($label, $this->_errors['password']) : $label)); |
||||
396 | |||||
397 | // Confirm password |
||||
398 | $label = Widget::Label(null, null, 'column'); |
||||
399 | $label->appendChild(Widget::Input('fields[password-confirmation]', null, 'password', array('placeholder' => __('Confirm Password'), 'autocomplete' => 'off'))); |
||||
400 | $fieldset->appendChild((isset($this->_errors['password-confirmation']) ? Widget::Error($label, $this->_errors['password']) : $label)); |
||||
401 | |||||
402 | $group->appendChild($fieldset); |
||||
403 | |||||
404 | // Auth token |
||||
405 | if (Symphony::Author()->isDeveloper() || Symphony::Author()->isManager()) { |
||||
406 | $label = Widget::Label(); |
||||
407 | $group->appendChild(Widget::Input('fields[auth_token_active]', 'no', 'hidden')); |
||||
408 | $input = Widget::Input('fields[auth_token_active]', 'yes', 'checkbox'); |
||||
409 | |||||
410 | if ($author->isTokenActive()) { |
||||
411 | $input->setAttribute('checked', 'checked'); |
||||
412 | } |
||||
413 | |||||
414 | $temp = SYMPHONY_URL . '/login/' . $author->createAuthToken() . '/'; |
||||
415 | $label->setValue(__('%s Allow remote login via', array($input->generate())) . ' <a href="' . $temp . '">' . $temp . '</a>'); |
||||
416 | $group->appendChild($label); |
||||
417 | } |
||||
418 | |||||
419 | $label = Widget::Label(__('Default Area')); |
||||
420 | |||||
421 | $sections = SectionManager::fetch(null, 'ASC', 'sortorder'); |
||||
422 | |||||
423 | $options = array(); |
||||
424 | |||||
425 | // If the Author is the Developer, allow them to set the Default Area to |
||||
426 | // be the Sections Index. |
||||
427 | if ($author->isDeveloper()) { |
||||
428 | $options[] = array( |
||||
429 | '/blueprints/sections/', |
||||
430 | $author->get('default_area') == '/blueprints/sections/', |
||||
431 | __('Sections Index') |
||||
432 | ); |
||||
433 | } |
||||
434 | |||||
435 | if (is_array($sections) && !empty($sections)) { |
||||
436 | foreach ($sections as $s) { |
||||
437 | $options[] = array( |
||||
438 | $s->get('id'), |
||||
439 | $author->get('default_area') == $s->get('id'), |
||||
440 | General::sanitize($s->get('name')) |
||||
441 | ); |
||||
442 | } |
||||
443 | } |
||||
444 | |||||
445 | /** |
||||
446 | * Allows injection or manipulation of the Default Area dropdown for an Author. |
||||
447 | * Take care with adding in options that are only valid for Developers, as if a |
||||
448 | * normal Author is set to that option, they will be redirected to their own |
||||
449 | * Author record. |
||||
450 | * |
||||
451 | * |
||||
452 | * @delegate AddDefaultAuthorAreas |
||||
453 | * @since Symphony 2.2 |
||||
454 | * @param string $context |
||||
455 | * '/system/authors/' |
||||
456 | * @param array $options |
||||
457 | * An associative array of options, suitable for use for the Widget::Select |
||||
458 | * function. By default this will be an array of the Sections in the current |
||||
459 | * installation. New options should be the path to the page after the `SYMPHONY_URL` |
||||
460 | * constant. |
||||
461 | * @param string $default_area |
||||
462 | * The current `default_area` for this Author. |
||||
463 | * @param Author $author |
||||
464 | * The Author object. |
||||
465 | * This parameter is available @since Symphony 2.7.0 |
||||
466 | */ |
||||
467 | Symphony::ExtensionManager()->notifyMembers('AddDefaultAuthorAreas', '/system/authors/', array( |
||||
468 | 'options' => &$options, |
||||
469 | 'default_area' => $author->get('default_area'), |
||||
470 | 'author' => $author, |
||||
471 | )); |
||||
472 | |||||
473 | $label->appendChild(Widget::Select('fields[default_area]', $options)); |
||||
474 | $group->appendChild($label); |
||||
475 | |||||
476 | $this->Form->appendChild($group); |
||||
477 | |||||
478 | // Custom Language Selection |
||||
479 | $languages = Lang::getAvailableLanguages(); |
||||
480 | if (count($languages) > 1) { |
||||
481 | // Get language names |
||||
482 | asort($languages); |
||||
483 | |||||
484 | $group = new XMLElement('fieldset'); |
||||
485 | $group->setAttribute('class', 'settings'); |
||||
486 | $group->appendChild(new XMLElement('legend', __('Custom Preferences'))); |
||||
487 | |||||
488 | $label = Widget::Label(__('Language')); |
||||
489 | |||||
490 | $options = array( |
||||
491 | array(null, is_null($author->get('language')), __('System Default')) |
||||
492 | ); |
||||
493 | |||||
494 | foreach ($languages as $code => $name) { |
||||
495 | $options[] = array($code, $code == $author->get('language'), $name); |
||||
496 | } |
||||
0 ignored issues
–
show
|
|||||
497 | $select = Widget::Select('fields[language]', $options); |
||||
498 | $label->appendChild($select); |
||||
499 | $group->appendChild($label); |
||||
500 | |||||
501 | $this->Form->appendChild($group); |
||||
502 | } |
||||
503 | |||||
504 | // Administration password double check |
||||
505 | if ($isEditing && !$isOwner) { |
||||
506 | $group = new XMLElement('fieldset'); |
||||
507 | $group->setAttribute('class', 'settings'); |
||||
508 | $group->setAttribute('id', 'confirmation'); |
||||
509 | $group->appendChild(new XMLElement('legend', __('Confirmation'))); |
||||
510 | $group->appendChild(new XMLELement('p', __('Please confirm changes to this author with your password.'), array('class' => 'help'))); |
||||
511 | |||||
512 | $label = Widget::Label(__('Password')); |
||||
513 | $label->appendChild(Widget::Input('fields[confirm-change-password]', null, 'password', array( |
||||
514 | 'autocomplete' => 'off', |
||||
515 | 'placeholder' => __('Your Password') |
||||
516 | ))); |
||||
517 | $group->appendChild( |
||||
518 | isset($this->_errors['confirm-change-password']) ? Widget::Error($label, $this->_errors['confirm-change-password']) : $label |
||||
519 | ); |
||||
520 | |||||
521 | $this->Form->appendChild($group); |
||||
522 | } |
||||
523 | |||||
524 | // Actions |
||||
525 | $div = new XMLElement('div'); |
||||
526 | $div->setAttribute('class', 'actions'); |
||||
527 | |||||
528 | $div->appendChild(Widget::Input('action[save]', ($this->_context[0] == 'edit' ? __('Save Changes') : __('Create Author')), 'submit', array('accesskey' => 's'))); |
||||
0 ignored issues
–
show
|
|||||
529 | |||||
530 | if ($isEditing && !$isOwner && !$author->isPrimaryAccount()) { |
||||
531 | $button = new XMLElement('button', __('Delete')); |
||||
532 | $button->setAttributeArray(array('name' => 'action[delete]', 'class' => 'button confirm delete', 'title' => __('Delete this author'), 'type' => 'submit', 'accesskey' => 'd', 'data-message' => __('Are you sure you want to delete this author?'))); |
||||
533 | $div->appendChild($button); |
||||
534 | } |
||||
535 | |||||
536 | $this->Form->appendChild($div); |
||||
537 | |||||
538 | /** |
||||
539 | * Allows the injection of custom form fields given the current `$this->Form` |
||||
540 | * object. Please note that this custom data should be saved in own extension |
||||
541 | * tables and that modifying `tbl_authors` to house your data is highly discouraged. |
||||
542 | * |
||||
543 | * @delegate AddElementstoAuthorForm |
||||
544 | * @since Symphony 2.2 |
||||
545 | * @param string $context |
||||
546 | * '/system/authors/' |
||||
547 | * @param XMLElement $form |
||||
548 | * The contents of `$this->Form` after all the default form elements have been appended. |
||||
549 | * @param Author $author |
||||
550 | * The current Author object that is being edited |
||||
551 | * @param array $fields |
||||
552 | * The POST fields |
||||
553 | * This parameter is available @since Symphony 2.7.0 |
||||
554 | * @param array $errors |
||||
555 | * The error array used to validate the Author. |
||||
556 | * Extension should register their own errors elsewhere and used the value |
||||
557 | * to modify the UI accordingly. |
||||
558 | * This parameter is available @since Symphony 2.7.0 |
||||
559 | */ |
||||
560 | Symphony::ExtensionManager()->notifyMembers('AddElementstoAuthorForm', '/system/authors/', array( |
||||
561 | 'form' => &$this->Form, |
||||
562 | 'author' => $author, |
||||
563 | 'fields' => isset($_POST['fields']) ? $_POST['fields'] : null, |
||||
564 | 'errors' => $this->_errors, |
||||
565 | )); |
||||
566 | } |
||||
567 | |||||
568 | public function __actionNew() |
||||
569 | { |
||||
570 | if (@array_key_exists('save', $_POST['action']) || @array_key_exists('done', $_POST['action'])) { |
||||
571 | $fields = $_POST['fields']; |
||||
572 | |||||
573 | $canCreate = Symphony::Author()->isDeveloper() || Symphony::Author()->isManager(); |
||||
574 | |||||
575 | if (!$canCreate) { |
||||
576 | Administration::instance()->throwCustomError( |
||||
577 | __('You are not authorised to create authors.'), |
||||
578 | __('Access Denied'), |
||||
579 | Page::HTTP_STATUS_UNAUTHORIZED |
||||
580 | ); |
||||
581 | } |
||||
582 | |||||
583 | if (Symphony::Author()->isManager() && $fields['user_type'] !== 'author') { |
||||
584 | $this->_errors['user_type'] = __('The user type is invalid. You can only create Authors.'); |
||||
585 | } |
||||
586 | |||||
587 | $this->_Author = new Author(); |
||||
588 | $this->_Author->set('user_type', $fields['user_type']); |
||||
589 | $this->_Author->set('primary', 'no'); |
||||
590 | $this->_Author->set('email', $fields['email']); |
||||
591 | $this->_Author->set('username', General::sanitize($fields['username'])); |
||||
592 | $this->_Author->set('first_name', General::sanitize($fields['first_name'])); |
||||
593 | $this->_Author->set('last_name', General::sanitize($fields['last_name'])); |
||||
594 | $this->_Author->set('last_seen', null); |
||||
595 | $this->_Author->set('password', (trim($fields['password']) == '' ? '' : Cryptography::hash(Symphony::Database()->cleanValue($fields['password'])))); |
||||
0 ignored issues
–
show
|
|||||
596 | $this->_Author->set('default_area', $fields['default_area']); |
||||
597 | $this->_Author->set('auth_token_active', ($fields['auth_token_active'] ? $fields['auth_token_active'] : 'no')); |
||||
0 ignored issues
–
show
|
|||||
598 | $this->_Author->set('language', isset($fields['language']) ? $fields['language'] : null); |
||||
599 | |||||
600 | /** |
||||
601 | * Creation of a new Author. The Author object is provided as read |
||||
602 | * only through this delegate. |
||||
603 | * |
||||
604 | * @delegate AuthorPreCreate |
||||
605 | * @since Symphony 2.7.0 |
||||
606 | * @param string $context |
||||
607 | * '/system/authors/' |
||||
608 | * @param Author $author |
||||
609 | * The Author object that has just been created, but not yet committed, nor validated |
||||
610 | * @param array $fields |
||||
611 | * The POST fields |
||||
612 | * @param array $errors |
||||
613 | * The error array used to validate the Author, passed by reference. |
||||
614 | * Extension should append to this array if they detect validation problems. |
||||
615 | */ |
||||
616 | Symphony::ExtensionManager()->notifyMembers('AuthorPreCreate', '/system/authors/', array( |
||||
617 | 'author' => $this->_Author, |
||||
618 | 'field' => $fields, |
||||
619 | 'errors' => &$this->_errors, |
||||
620 | )); |
||||
621 | |||||
622 | if (empty($this->_errors) && $this->_Author->validate($this->_errors)) { |
||||
623 | if ($fields['password'] != $fields['password-confirmation']) { |
||||
624 | $this->_errors['password'] = $this->_errors['password-confirmation'] = __('Passwords did not match'); |
||||
625 | } elseif ($author_id = $this->_Author->commit()) { |
||||
626 | /** |
||||
627 | * Creation of a new Author. The Author object is provided as read |
||||
628 | * only through this delegate. |
||||
629 | * |
||||
630 | * @delegate AuthorPostCreate |
||||
631 | * @since Symphony 2.2 |
||||
632 | * @param string $context |
||||
633 | * '/system/authors/' |
||||
634 | * @param Author $author |
||||
635 | * The Author object that has just been created |
||||
636 | * @param integer $author_id |
||||
637 | * The ID of Author ID that was just created |
||||
638 | * @param array $fields |
||||
639 | * The POST fields |
||||
640 | * This parameter is available @since Symphony 2.7.0 |
||||
641 | * @param array $errors |
||||
642 | * The error array used to validate the Author, passed by reference. |
||||
643 | * Extension should append to this array if they detect saving problems. |
||||
644 | * This parameter is available @since Symphony 2.7.0 |
||||
645 | */ |
||||
646 | Symphony::ExtensionManager()->notifyMembers('AuthorPostCreate', '/system/authors/', array( |
||||
647 | 'author' => $this->_Author, |
||||
648 | 'author_id' => $author_id, |
||||
649 | 'field' => $fields, |
||||
650 | 'errors' => &$this->_errors, |
||||
651 | )); |
||||
652 | |||||
653 | if (empty($this->_errors)) { |
||||
654 | redirect(SYMPHONY_URL . "/system/authors/edit/$author_id/created/"); |
||||
0 ignored issues
–
show
As per coding-style, please use concatenation or
sprintf for the variable $author_id instead of interpolation.
It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings. // Instead of
$x = "foo $bar $baz";
// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
![]() |
|||||
655 | } |
||||
656 | } |
||||
657 | } |
||||
658 | |||||
659 | if (is_array($this->_errors) && !empty($this->_errors)) { |
||||
660 | $this->pageAlert(__('There were some problems while attempting to save. Please check below for problem fields.'), Alert::ERROR); |
||||
661 | } else { |
||||
662 | $this->pageAlert( |
||||
663 | __('Unknown errors occurred while attempting to save.') |
||||
664 | . '<a href="' . SYMPHONY_URL . '/system/log/">' |
||||
665 | . __('Check your activity log') |
||||
666 | . '</a>.', |
||||
667 | Alert::ERROR |
||||
668 | ); |
||||
669 | } |
||||
670 | } |
||||
671 | } |
||||
672 | |||||
673 | public function __actionEdit() |
||||
674 | { |
||||
675 | if (!$author_id = (int)$this->_context[1]) { |
||||
676 | redirect(SYMPHONY_URL . '/system/authors/'); |
||||
0 ignored issues
–
show
|
|||||
677 | } |
||||
678 | |||||
679 | $isOwner = ($author_id == Symphony::Author()->get('id')); |
||||
680 | $fields = $_POST['fields']; |
||||
681 | $this->_Author = AuthorManager::fetchByID($author_id); |
||||
682 | |||||
683 | $canEdit = // Managers can edit all Authors, and their own. |
||||
684 | (Symphony::Author()->isManager() && $this->_Author->isAuthor()) |
||||
0 ignored issues
–
show
The method
isAuthor() does not exist on null .
(
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. ![]() |
|||||
685 | // Primary account can edit all accounts. |
||||
686 | || Symphony::Author()->isPrimaryAccount() |
||||
687 | // Developers can edit all developers, managers and authors, and their own, |
||||
688 | // but not the primary account |
||||
689 | || (Symphony::Author()->isDeveloper() && $this->_Author->isPrimaryAccount() === false); |
||||
690 | |||||
691 | if (@array_key_exists('save', $_POST['action']) || @array_key_exists('done', $_POST['action'])) { |
||||
692 | $authenticated = false; |
||||
693 | |||||
694 | if (!$isOwner && !$canEdit) { |
||||
695 | Administration::instance()->throwCustomError( |
||||
696 | __('You are not authorised to modify this author.'), |
||||
697 | __('Access Denied'), |
||||
698 | Page::HTTP_STATUS_UNAUTHORIZED |
||||
699 | ); |
||||
700 | } |
||||
701 | |||||
702 | if ($fields['email'] != $this->_Author->get('email')) { |
||||
703 | $changing_email = true; |
||||
704 | } |
||||
705 | |||||
706 | // Check the old password was correct |
||||
707 | if (isset($fields['old-password']) && strlen(trim($fields['old-password'])) > 0 && Cryptography::compare(Symphony::Database()->cleanValue(trim($fields['old-password'])), $this->_Author->get('password'))) { |
||||
708 | $authenticated = true; |
||||
709 | |||||
710 | // Developers don't need to specify the old password, unless it's their own account |
||||
711 | } elseif ( |
||||
0 ignored issues
–
show
|
|||||
712 | // All accounts can edit their own |
||||
713 | $isOwner || |
||||
714 | // Is allowed to edit? |
||||
715 | $canEdit |
||||
716 | ) { |
||||
717 | $authenticated = true; |
||||
718 | } |
||||
719 | |||||
720 | $this->_Author->set('id', $author_id); |
||||
721 | |||||
722 | if ($this->_Author->isPrimaryAccount() || ($isOwner && Symphony::Author()->isDeveloper())) { |
||||
723 | $this->_Author->set('user_type', 'developer'); // Primary accounts are always developer, Developers can't lower their level |
||||
724 | } elseif (Symphony::Author()->isManager() && isset($fields['user_type'])) { // Manager can only change user type for author and managers |
||||
725 | if ($fields['user_type'] !== 'author' && $fields['user_type'] !== 'manager') { |
||||
726 | $this->_errors['user_type'] = __('The user type is invalid. You can only create Authors.'); |
||||
727 | } else { |
||||
728 | $this->_Author->set('user_type', $fields['user_type']); |
||||
729 | } |
||||
730 | } elseif (Symphony::Author()->isDeveloper() && isset($fields['user_type'])) { |
||||
731 | $this->_Author->set('user_type', $fields['user_type']); // Only developer can change user type |
||||
732 | } |
||||
733 | |||||
734 | $this->_Author->set('email', $fields['email']); |
||||
735 | $this->_Author->set('username', General::sanitize($fields['username'])); |
||||
736 | $this->_Author->set('first_name', General::sanitize($fields['first_name'])); |
||||
737 | $this->_Author->set('last_name', General::sanitize($fields['last_name'])); |
||||
738 | $this->_Author->set('language', isset($fields['language']) ? $fields['language'] : null); |
||||
739 | |||||
740 | if (trim($fields['password']) != '') { |
||||
741 | $this->_Author->set('password', Cryptography::hash(Symphony::Database()->cleanValue($fields['password']))); |
||||
742 | $changing_password = true; |
||||
743 | } |
||||
744 | |||||
745 | // Don't allow authors to set the Section Index as a default area |
||||
746 | // If they had it previously set, just save `null` which will redirect |
||||
747 | // the Author (when logging in) to their own Author record |
||||
748 | if ( |
||||
0 ignored issues
–
show
|
|||||
749 | $this->_Author->get('user_type') == 'author' |
||||
750 | && $fields['default_area'] == '/blueprints/sections/' |
||||
751 | ) { |
||||
752 | $this->_Author->set('default_area', null); |
||||
753 | } else { |
||||
754 | $this->_Author->set('default_area', $fields['default_area']); |
||||
755 | } |
||||
756 | |||||
757 | $this->_Author->set('auth_token_active', ($fields['auth_token_active'] ? $fields['auth_token_active'] : 'no')); |
||||
0 ignored issues
–
show
|
|||||
758 | |||||
759 | /** |
||||
760 | * Before editing an author, provided with the Author object |
||||
761 | * |
||||
762 | * @delegate AuthorPreEdit |
||||
763 | * @since Symphony 2.7.0 |
||||
764 | * @param string $context |
||||
765 | * '/system/authors/' |
||||
766 | * @param Author $author |
||||
767 | * An Author object not yet committed, nor validated |
||||
768 | * @param array $fields |
||||
769 | * The POST fields |
||||
770 | * @param array $errors |
||||
771 | * The error array used to validate the Author, passed by reference. |
||||
772 | * Extension should append to this array if they detect validation problems. |
||||
773 | */ |
||||
774 | Symphony::ExtensionManager()->notifyMembers('AuthorPreEdit', '/system/authors/', array( |
||||
775 | 'author' => $this->_Author, |
||||
776 | 'field' => $fields, |
||||
777 | 'errors' => &$this->_errors, |
||||
778 | )); |
||||
779 | |||||
780 | if (empty($this->_errors) && $this->_Author->validate($this->_errors)) { |
||||
781 | // Admin changing another profile |
||||
782 | if (!$isOwner) { |
||||
783 | $entered_password = Symphony::Database()->cleanValue($fields['confirm-change-password']); |
||||
784 | |||||
785 | if (!isset($fields['confirm-change-password']) || empty($fields['confirm-change-password'])) { |
||||
786 | $this->_errors['confirm-change-password'] = __('Please provide your own password to make changes to this author.'); |
||||
787 | } elseif (Cryptography::compare($entered_password, Symphony::Author()->get('password')) !== true) { |
||||
788 | $this->_errors['confirm-change-password'] = __('Wrong password, please enter your own password to make changes to this author.'); |
||||
789 | } |
||||
790 | } |
||||
791 | |||||
792 | // Author is changing their password |
||||
793 | if (!$authenticated && ($changing_password || $changing_email)) { |
||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Comprehensibility
Best Practice
introduced
by
|
|||||
794 | if ($changing_password) { |
||||
795 | $this->_errors['old-password'] = __('Wrong password. Enter old password to change it.'); |
||||
796 | } elseif ($changing_email) { |
||||
797 | $this->_errors['old-password'] = __('Wrong password. Enter old one to change email address.'); |
||||
798 | } |
||||
799 | |||||
800 | // Passwords provided, but doesn't match. |
||||
801 | } elseif (($fields['password'] != '' || $fields['password-confirmation'] != '') && $fields['password'] != $fields['password-confirmation']) { |
||||
802 | $this->_errors['password'] = $this->_errors['password-confirmation'] = __('Passwords did not match'); |
||||
803 | } |
||||
804 | |||||
805 | // All good, let's save the Author |
||||
806 | if (is_array($this->_errors) && empty($this->_errors) && $this->_Author->commit()) { |
||||
807 | Symphony::Database()->delete('tbl_forgotpass', sprintf(" |
||||
808 | `expiry` < '%s' OR `author_id` = %d", |
||||
809 | DateTimeObj::getGMT('c'), |
||||
810 | $author_id |
||||
811 | )); |
||||
812 | |||||
813 | if ($isOwner) { |
||||
814 | Administration::instance()->login($this->_Author->get('username'), $this->_Author->get('password'), true); |
||||
815 | } |
||||
816 | |||||
817 | /** |
||||
818 | * After editing an author, provided with the Author object |
||||
819 | * |
||||
820 | * @delegate AuthorPostEdit |
||||
821 | * @since Symphony 2.2 |
||||
822 | * @param string $context |
||||
823 | * '/system/authors/' |
||||
824 | * @param Author $author |
||||
825 | * An Author object |
||||
826 | * @param array $fields |
||||
827 | * The POST fields |
||||
828 | * This parameter is available @since Symphony 2.7.0 |
||||
829 | * @param array $errors |
||||
830 | * The error array used to validate the Author, passed by reference. |
||||
831 | * Extension should append to this array if they detect saving problems. |
||||
832 | * This parameter is available @since Symphony 2.7.0 |
||||
833 | */ |
||||
834 | Symphony::ExtensionManager()->notifyMembers('AuthorPostEdit', '/system/authors/', array( |
||||
835 | 'author' => $this->_Author, |
||||
836 | 'field' => $fields, |
||||
837 | 'errors' => &$this->_errors, |
||||
838 | )); |
||||
839 | |||||
840 | if (empty($this->_errors)) { |
||||
841 | redirect(SYMPHONY_URL . '/system/authors/edit/' . $author_id . '/saved/'); |
||||
842 | } |
||||
843 | |||||
844 | // Problems. |
||||
845 | } else { |
||||
846 | $this->pageAlert( |
||||
847 | __('Unknown errors occurred while attempting to save.') |
||||
848 | . '<a href="' . SYMPHONY_URL . '/system/log/">' |
||||
849 | . __('Check your activity log') |
||||
850 | . '</a>.', |
||||
851 | Alert::ERROR |
||||
852 | ); |
||||
853 | } |
||||
854 | } |
||||
855 | |||||
856 | // Author doesn't have valid data, throw back. |
||||
857 | if (is_array($this->_errors) && !empty($this->_errors)) { |
||||
858 | $this->pageAlert(__('There were some problems while attempting to save. Please check below for problem fields.'), Alert::ERROR); |
||||
859 | } |
||||
860 | } elseif (@array_key_exists('delete', $_POST['action'])) { |
||||
861 | // Validate rights |
||||
862 | if (!$canEdit) { |
||||
863 | $this->pageAlert(__('You are not allowed to delete this author.'), Alert::ERROR); |
||||
864 | return; |
||||
865 | } |
||||
0 ignored issues
–
show
|
|||||
866 | // Admin changing another profile |
||||
867 | if (!$isOwner) { |
||||
868 | $entered_password = Symphony::Database()->cleanValue($fields['confirm-change-password']); |
||||
869 | |||||
870 | if (!isset($fields['confirm-change-password']) || empty($fields['confirm-change-password'])) { |
||||
871 | $this->_errors['confirm-change-password'] = __('Please provide your own password to make changes to this author.'); |
||||
872 | } elseif (Cryptography::compare($entered_password, Symphony::Author()->get('password')) !== true) { |
||||
873 | $this->_errors['confirm-change-password'] = __('Wrong password, please enter your own password to make changes to this author.'); |
||||
874 | } |
||||
875 | } |
||||
0 ignored issues
–
show
|
|||||
876 | if (is_array($this->_errors) && !empty($this->_errors)) { |
||||
877 | $this->pageAlert(__('There were some problems while attempting to save. Please check below for problem fields.'), Alert::ERROR); |
||||
878 | return; |
||||
879 | } |
||||
880 | |||||
881 | $this->_Author = AuthorManager::fetchByID($author_id); |
||||
882 | |||||
883 | /** |
||||
884 | * Prior to deleting an author, provided with the Author ID. |
||||
885 | * |
||||
886 | * @delegate AuthorPreDelete |
||||
887 | * @since Symphony 2.2 |
||||
888 | * @param string $context |
||||
889 | * '/system/authors/' |
||||
890 | * @param integer $author_id |
||||
891 | * The ID of Author ID that is about to be deleted |
||||
892 | * @param Author $author |
||||
893 | * The Author object. |
||||
894 | * This parameter is available @since Symphony 2.7.0 |
||||
895 | */ |
||||
896 | Symphony::ExtensionManager()->notifyMembers('AuthorPreDelete', '/system/authors/', array( |
||||
897 | 'author_id' => $author_id, |
||||
898 | 'author' => $this->_Author, |
||||
899 | )); |
||||
900 | |||||
901 | if (!$isOwner) { |
||||
902 | $result = AuthorManager::delete($author_id); |
||||
903 | |||||
904 | /** |
||||
905 | * After deleting an author, provided with the Author ID. |
||||
906 | * |
||||
907 | * @delegate AuthorPostDelete |
||||
908 | * @since Symphony 2.7.0 |
||||
909 | * @param string $context |
||||
910 | * '/system/authors/' |
||||
911 | * @param integer $author_id |
||||
912 | * The ID of Author ID that is about to be deleted |
||||
913 | * @param Author $author |
||||
914 | * The Author object. |
||||
915 | * @param integer $result |
||||
916 | * The result of the delete statement |
||||
917 | */ |
||||
918 | Symphony::ExtensionManager()->notifyMembers('AuthorPostDelete', '/system/authors/', array( |
||||
919 | 'author_id' => $author_id, |
||||
920 | 'author' => $this->_Author, |
||||
921 | 'result' => $result |
||||
922 | )); |
||||
923 | |||||
924 | redirect(SYMPHONY_URL . '/system/authors/'); |
||||
925 | } else { |
||||
926 | $this->pageAlert(__('You cannot remove yourself as you are the active Author.'), Alert::ERROR); |
||||
927 | } |
||||
928 | } |
||||
929 | } |
||||
930 | } |
||||
931 |
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
.