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 |
|
|
|
|
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); |
|
|
|
|
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 ( |
|
|
|
|
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__) |
|
|
|
|
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")]); |
|
|
|
|
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 |
|
|
|
|
238
|
|
|
. ' <a href="' . SYMPHONY_URL . '/system/authors/new/" accesskey="c">' |
|
|
|
|
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
|
|
|
} |
|
|
|
|
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')))); |
|
|
|
|
284
|
|
|
if ($canonical_link) { |
285
|
|
|
$this->addElementToHead(new XMLElement('link', null, array( |
286
|
|
|
'rel' => 'canonical', |
287
|
|
|
'href' => SYMPHONY_URL . $canonical_link, |
288
|
|
|
))); |
289
|
|
|
} |
|
|
|
|
290
|
|
|
$this->appendSubheading(($this->_context[0] == 'new' ? __('Untitled') : $author->getFullName())); |
|
|
|
|
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
|
|
|
|
|
|
|
|
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()) { |
|
|
|
|
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')); |
|
|
|
|
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
|
|
|
} |
|
|
|
|
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'))); |
|
|
|
|
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'])))); |
|
|
|
|
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')); |
|
|
|
|
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/"); |
|
|
|
|
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/'); |
|
|
|
|
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()) |
|
|
|
|
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 ( |
|
|
|
|
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 ( |
|
|
|
|
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')); |
|
|
|
|
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)) { |
|
|
|
|
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
|
|
|
} |
|
|
|
|
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
|
|
|
} |
|
|
|
|
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
.