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