1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* |
4
|
|
|
* Ideas extension for the phpBB Forum Software package. |
5
|
|
|
* |
6
|
|
|
* @copyright (c) phpBB Limited <https://www.phpbb.com> |
7
|
|
|
* @license GNU General Public License, version 2 (GPL-2.0) |
8
|
|
|
* |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace phpbb\ideas\event; |
12
|
|
|
|
13
|
|
|
use phpbb\auth\auth; |
14
|
|
|
use phpbb\config\config; |
15
|
|
|
use phpbb\controller\helper; |
16
|
|
|
use phpbb\ideas\factory\ideas; |
17
|
|
|
use phpbb\ideas\factory\linkhelper; |
18
|
|
|
use phpbb\language\language; |
19
|
|
|
use phpbb\template\template; |
20
|
|
|
use phpbb\user; |
21
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface; |
22
|
|
|
|
23
|
|
|
class listener implements EventSubscriberInterface |
24
|
|
|
{ |
25
|
|
|
/** @var auth */ |
26
|
|
|
protected $auth; |
27
|
|
|
|
28
|
|
|
/* @var config */ |
29
|
|
|
protected $config; |
30
|
|
|
|
31
|
|
|
/* @var helper */ |
32
|
|
|
protected $helper; |
33
|
|
|
|
34
|
|
|
/* @var ideas */ |
35
|
|
|
protected $ideas; |
36
|
|
|
|
37
|
|
|
/** @var language */ |
38
|
|
|
protected $language; |
39
|
|
|
|
40
|
|
|
/* @var linkhelper */ |
41
|
|
|
protected $link_helper; |
42
|
|
|
|
43
|
|
|
/* @var template */ |
44
|
|
|
protected $template; |
45
|
|
|
|
46
|
|
|
/* @var user */ |
47
|
|
|
protected $user; |
48
|
|
|
|
49
|
|
|
/** @var string */ |
50
|
|
|
protected $php_ext; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @param \phpbb\auth\auth $auth |
54
|
|
|
* @param \phpbb\config\config $config |
55
|
|
|
* @param \phpbb\controller\helper $helper |
56
|
|
|
* @param \phpbb\ideas\factory\ideas $ideas |
57
|
|
|
* @param \phpbb\language\language $language |
58
|
|
|
* @param \phpbb\ideas\factory\linkhelper $link_helper |
59
|
|
|
* @param \phpbb\template\template $template |
60
|
|
|
* @param \phpbb\user $user |
61
|
|
|
* @param string $php_ext |
62
|
|
|
*/ |
63
|
|
View Code Duplication |
public function __construct(auth $auth, config $config, helper $helper, ideas $ideas, language $language, linkhelper $link_helper, template $template, user $user, $php_ext) |
|
|
|
|
64
|
|
|
{ |
65
|
|
|
$this->auth = $auth; |
66
|
|
|
$this->config = $config; |
67
|
|
|
$this->helper = $helper; |
68
|
|
|
$this->ideas = $ideas; |
69
|
|
|
$this->language = $language; |
70
|
|
|
$this->link_helper = $link_helper; |
71
|
|
|
$this->template = $template; |
72
|
|
|
$this->user = $user; |
73
|
|
|
$this->php_ext = $php_ext; |
74
|
|
|
|
75
|
|
|
$this->language->add_lang('common', 'phpbb/ideas'); |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @inheritDoc |
80
|
|
|
*/ |
81
|
|
|
public static function getSubscribedEvents() |
82
|
|
|
{ |
83
|
|
|
return array( |
84
|
|
|
'core.viewforum_get_topic_data' => 'ideas_forum_redirect', |
85
|
|
|
'core.viewtopic_modify_post_row' => 'show_post_buttons', |
86
|
|
|
'core.viewtopic_modify_page_title' => 'show_idea', |
87
|
|
|
'core.viewtopic_add_quickmod_option_before' => 'adjust_quickmod_tools', |
88
|
|
|
'core.viewonline_overwrite_location' => 'viewonline_ideas', |
89
|
|
|
'core.posting_modify_template_vars' => 'submit_idea_template', |
90
|
|
|
'core.posting_modify_submit_post_before' => 'submit_idea_before', |
91
|
|
|
'core.posting_modify_submit_post_after' => ['submit_idea_after', 'edit_idea_title'], |
92
|
|
|
); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* Redirect users from the forum to the Ideas centre |
97
|
|
|
* |
98
|
|
|
* @param \phpbb\event\data $event The event object |
99
|
|
|
* @return void |
100
|
|
|
* @access public |
101
|
|
|
*/ |
102
|
|
|
public function ideas_forum_redirect($event) |
103
|
|
|
{ |
104
|
|
|
if ($this->is_ideas_forum($event['forum_id'])) |
105
|
|
|
{ |
106
|
|
|
redirect($this->helper->route('phpbb_ideas_index_controller')); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Show post buttons (hide delete, quote or warn user buttons) |
112
|
|
|
* |
113
|
|
|
* @param \phpbb\event\data $event The event object |
114
|
|
|
* @return void |
115
|
|
|
* @access public |
116
|
|
|
*/ |
117
|
|
|
public function show_post_buttons($event) |
118
|
|
|
{ |
119
|
|
|
if (!$this->is_ideas_forum($event['row']['forum_id'])) |
120
|
|
|
{ |
121
|
|
|
return; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
if ($this->is_first_post($event['topic_data']['topic_first_post_id'], $event['row']['post_id'])) |
125
|
|
|
{ |
126
|
|
|
$event->update_subarray('post_row', 'U_DELETE', false); |
127
|
|
|
$event->update_subarray('post_row', 'U_WARN', false); |
128
|
|
|
} |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* Show the idea related to the current topic |
133
|
|
|
* |
134
|
|
|
* @param \phpbb\event\data $event The event object |
135
|
|
|
* @return void |
136
|
|
|
* @access public |
137
|
|
|
*/ |
138
|
|
|
public function show_idea($event) |
139
|
|
|
{ |
140
|
|
|
if (!$this->is_ideas_forum($event['forum_id'])) |
141
|
|
|
{ |
142
|
|
|
return; |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
$idea = $this->ideas->get_idea_by_topic_id($event['topic_data']['topic_id']); |
146
|
|
|
|
147
|
|
|
if (!$idea) |
148
|
|
|
{ |
149
|
|
|
return; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
$mod = $this->auth->acl_get('m_', (int) $this->config['ideas_forum_id']); |
153
|
|
|
$own = $idea['idea_author'] === $this->user->data['user_id']; |
154
|
|
|
|
155
|
|
|
if ($mod) |
156
|
|
|
{ |
157
|
|
|
$this->template->assign_var('STATUS_ARY', ideas::$statuses); |
158
|
|
|
|
159
|
|
|
// Add quick mod option for deleting an idea |
160
|
|
|
$this->template->alter_block_array('quickmod', array( |
161
|
|
|
'VALUE' => 'delete_topic', // delete topic is used here simply to enable ajax |
162
|
|
|
'TITLE' => $this->language->lang('DELETE_IDEA'), |
163
|
|
|
'LINK' => $this->link_helper->get_idea_link($idea['idea_id'], 'delete'), |
164
|
|
|
)); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
$points = $idea['idea_votes_up'] - $idea['idea_votes_down']; |
168
|
|
|
$can_vote = (bool) ($idea['idea_status'] != ideas::$statuses['IMPLEMENTED'] && |
169
|
|
|
$idea['idea_status'] != ideas::$statuses['DUPLICATE'] && |
170
|
|
|
$this->auth->acl_get('f_vote', (int) $this->config['ideas_forum_id']) && |
171
|
|
|
$event['topic_data']['topic_status'] != ITEM_LOCKED); |
172
|
|
|
|
173
|
|
|
$s_voted_up = $s_voted_down = false; |
174
|
|
|
if ($idea['idea_votes_up'] || $idea['idea_votes_down']) |
175
|
|
|
{ |
176
|
|
|
$votes = $this->ideas->get_voters($idea['idea_id']); |
177
|
|
|
|
178
|
|
|
foreach ($votes as $vote) |
179
|
|
|
{ |
180
|
|
|
$this->template->assign_block_vars('votes_' . ($vote['vote_value'] ? 'up' : 'down'), array( |
181
|
|
|
'USER' => $vote['user'], |
182
|
|
|
)); |
183
|
|
|
|
184
|
|
|
if ($this->user->data['user_id'] == $vote['user_id']) |
185
|
|
|
{ |
186
|
|
|
$s_voted_up = ((int) $vote['vote_value'] === 1); |
187
|
|
|
$s_voted_down = ((int) $vote['vote_value'] === 0); |
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
$this->template->assign_vars(array( |
193
|
|
|
'IDEA_ID' => $idea['idea_id'], |
194
|
|
|
'IDEA_TITLE' => $idea['idea_title'], |
195
|
|
|
'IDEA_VOTES' => $idea['idea_votes_up'] + $idea['idea_votes_down'], |
196
|
|
|
'IDEA_VOTES_UP' => $idea['idea_votes_up'], |
197
|
|
|
'IDEA_VOTES_DOWN' => $idea['idea_votes_down'], |
198
|
|
|
'IDEA_POINTS' => $points, |
199
|
|
|
'IDEA_STATUS_ID' => $idea['idea_status'], |
200
|
|
|
'IDEA_STATUS_NAME' => $this->ideas->get_status_from_id($idea['idea_status']), |
201
|
|
|
|
202
|
|
|
'IDEA_DUPLICATE' => $idea['duplicate_id'] ? $this->ideas->get_title($idea['duplicate_id']) : '', |
203
|
|
|
'IDEA_RFC' => $idea['rfc_link'], |
204
|
|
|
'IDEA_TICKET' => $idea['ticket_id'], |
205
|
|
|
'IDEA_IMPLEMENTED' => $idea['implemented_version'], |
206
|
|
|
|
207
|
|
|
'S_IS_MOD' => $mod, |
208
|
|
|
'S_CAN_EDIT' => $mod || $own, |
209
|
|
|
'S_CAN_VOTE' => $can_vote, |
210
|
|
|
'S_CAN_VOTE_UP' => $can_vote && !$s_voted_up, |
211
|
|
|
'S_CAN_VOTE_DOWN' => $can_vote && !$s_voted_down, |
212
|
|
|
'S_VOTED' => $s_voted_up || $s_voted_down, |
213
|
|
|
'S_VOTED_UP' => $s_voted_up, |
214
|
|
|
'S_VOTED_DOWN' => $s_voted_down, |
215
|
|
|
|
216
|
|
|
'U_CHANGE_STATUS' => $this->link_helper->get_idea_link($idea['idea_id'], 'status', true), |
217
|
|
|
'U_EDIT_DUPLICATE' => $this->link_helper->get_idea_link($idea['idea_id'], 'duplicate', true), |
218
|
|
|
'U_EDIT_RFC' => $this->link_helper->get_idea_link($idea['idea_id'], 'rfc', true), |
219
|
|
|
'U_EDIT_IMPLEMENTED'=> $this->link_helper->get_idea_link($idea['idea_id'], 'implemented', true), |
220
|
|
|
'U_EDIT_TICKET' => $this->link_helper->get_idea_link($idea['idea_id'], 'ticket', true), |
221
|
|
|
'U_REMOVE_VOTE' => $this->link_helper->get_idea_link($idea['idea_id'], 'removevote', true), |
222
|
|
|
'U_IDEA_VOTE' => $this->link_helper->get_idea_link($idea['idea_id'], 'vote', true), |
223
|
|
|
'U_IDEA_DUPLICATE' => $this->link_helper->get_idea_link($idea['duplicate_id']), |
224
|
|
|
'U_IDEA_STATUS_LINK'=> $this->helper->route('phpbb_ideas_list_controller', ['status' => $idea['idea_status']]), |
225
|
|
|
'U_SEARCH_MY_IDEAS' => $this->helper->route('phpbb_ideas_list_controller', ['sort' => ideas::SORT_MYIDEAS, 'status' => '-1']), |
226
|
|
|
'U_TITLE_LIVESEARCH'=> $this->helper->route('phpbb_ideas_livesearch_controller'), |
227
|
|
|
)); |
228
|
|
|
|
229
|
|
|
// Use Ideas breadcrumbs |
230
|
|
|
$this->template->destroy_block_vars('navlinks'); |
231
|
|
|
$this->template->assign_block_vars('navlinks', array( |
232
|
|
|
'U_VIEW_FORUM' => $this->helper->route('phpbb_ideas_index_controller'), |
233
|
|
|
'FORUM_NAME' => $this->language->lang('IDEAS'), |
234
|
|
|
)); |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
/** |
238
|
|
|
* Adjust the QuickMod tools displayed |
239
|
|
|
* (hide options to delete, restore, make global, sticky or announcement) |
240
|
|
|
* |
241
|
|
|
* @param \phpbb\event\data $event The event object |
242
|
|
|
* @return void |
243
|
|
|
* @access public |
244
|
|
|
*/ |
245
|
|
|
public function adjust_quickmod_tools($event) |
246
|
|
|
{ |
247
|
|
|
if (!$this->is_ideas_forum($event['forum_id'])) |
248
|
|
|
{ |
249
|
|
|
return; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
$quickmod_array = $event['quickmod_array']; |
253
|
|
|
|
254
|
|
|
//$quickmod_array['lock'][1] = false; |
255
|
|
|
//$quickmod_array['unlock'][1] = false; |
256
|
|
|
$quickmod_array['delete_topic'][1] = false; |
257
|
|
|
$quickmod_array['restore_topic'][1] = false; |
258
|
|
|
//$quickmod_array['move'][1] = false; |
259
|
|
|
//$quickmod_array['split'][1] = false; |
260
|
|
|
//$quickmod_array['merge'][1] = false; |
261
|
|
|
//$quickmod_array['merge_topic'][1] = false; |
262
|
|
|
//$quickmod_array['fork'][1] = false; |
263
|
|
|
$quickmod_array['make_normal'][1] = false; |
264
|
|
|
$quickmod_array['make_sticky'][1] = false; |
265
|
|
|
$quickmod_array['make_announce'][1] = false; |
266
|
|
|
$quickmod_array['make_global'][1] = false; |
267
|
|
|
|
268
|
|
|
$event['quickmod_array'] = $quickmod_array; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
/** |
272
|
|
|
* Show users as viewing Ideas on Who Is Online page |
273
|
|
|
* |
274
|
|
|
* @param \phpbb\event\data $event The event object |
275
|
|
|
* @return void |
276
|
|
|
* @access public |
277
|
|
|
*/ |
278
|
|
|
public function viewonline_ideas($event) |
279
|
|
|
{ |
280
|
|
|
if (($event['on_page'][1] === 'viewtopic' && $event['row']['session_forum_id'] == $this->config['ideas_forum_id']) || |
281
|
|
|
($event['on_page'][1] === 'app' && strrpos($event['row']['session_page'], 'app.' . $this->php_ext . '/ideas') === 0)) |
282
|
|
|
{ |
283
|
|
|
$event['location'] = $this->language->lang('VIEWING_IDEAS'); |
284
|
|
|
$event['location_url'] = $this->helper->route('phpbb_ideas_index_controller'); |
285
|
|
|
} |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Modify the Ideas forum's posting page |
290
|
|
|
* |
291
|
|
|
* @param \phpbb\event\data $event The event object |
292
|
|
|
*/ |
293
|
|
|
public function submit_idea_template($event) |
294
|
|
|
{ |
295
|
|
|
if (!$this->is_ideas_forum($event['forum_id'])) |
296
|
|
|
{ |
297
|
|
|
return; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
// Alter some posting page template vars |
301
|
|
|
if ($event['mode'] === 'post') |
302
|
|
|
{ |
303
|
|
|
$event['page_title'] = $this->language->lang('POST_IDEA'); |
304
|
|
|
$event->update_subarray('page_data', 'L_POST_A', $this->language->lang('POST_IDEA')); |
305
|
|
|
$event->update_subarray('page_data', 'U_VIEW_FORUM', $this->helper->route('phpbb_ideas_index_controller')); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
// Alter posting page breadcrumbs to link to the ideas controller |
309
|
|
|
$this->template->alter_block_array('navlinks', [ |
310
|
|
|
'U_BREADCRUMB' => $this->helper->route('phpbb_ideas_index_controller'), |
311
|
|
|
'BREADCRUMB_NAME' => $this->language->lang('IDEAS'), |
312
|
|
|
], false, 'change'); |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Prepare post data vars before posting a new idea/topic. |
317
|
|
|
* |
318
|
|
|
* @param \phpbb\event\data $event The event object |
319
|
|
|
*/ |
320
|
|
|
public function submit_idea_before($event) |
321
|
|
|
{ |
322
|
|
View Code Duplication |
if (!$this->is_post_idea($event['mode'], $event['data']['forum_id'], empty($event['data']['topic_id']))) |
|
|
|
|
323
|
|
|
{ |
324
|
|
|
return; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
// We need $post_time after submit_post(), but it's not available in the post $data, unless we set it now |
328
|
|
|
$event->update_subarray('data', 'post_time', time()); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
/** |
332
|
|
|
* Submit the idea data after posting a new idea/topic. |
333
|
|
|
* |
334
|
|
|
* @param \phpbb\event\data $event The event object |
335
|
|
|
*/ |
336
|
|
|
public function submit_idea_after($event) |
337
|
|
|
{ |
338
|
|
View Code Duplication |
if (!$this->is_post_idea($event['mode'], $event['data']['forum_id'], !empty($event['data']['topic_id']))) |
|
|
|
|
339
|
|
|
{ |
340
|
|
|
return; |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
$this->ideas->submit($event['data']); |
344
|
|
|
|
345
|
|
|
// Show users who's posts need approval a special message |
346
|
|
|
if (!$this->auth->acl_get('f_noapprove', $event['data']['forum_id'])) |
347
|
|
|
{ |
348
|
|
|
// Using refresh and trigger error because we can't throw http_exceptions from posting.php |
349
|
|
|
$url = $this->helper->route('phpbb_ideas_index_controller'); |
350
|
|
|
meta_refresh(10, $url); |
351
|
|
|
trigger_error($this->language->lang('IDEA_STORED_MOD', $url)); |
352
|
|
|
} |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Update the idea's title when post title is edited. |
357
|
|
|
* |
358
|
|
|
* @param \phpbb\event\data $event The event object |
359
|
|
|
* @return void |
360
|
|
|
* @access public |
361
|
|
|
*/ |
362
|
|
|
public function edit_idea_title($event) |
363
|
|
|
{ |
364
|
|
|
if ($event['mode'] !== 'edit' || |
365
|
|
|
!$event['update_subject'] || |
366
|
|
|
!$this->is_ideas_forum($event['forum_id']) || |
367
|
|
|
!$this->is_first_post($event['post_data']['topic_first_post_id'], $event['post_id'])) |
368
|
|
|
{ |
369
|
|
|
return; |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
$idea = $this->ideas->get_idea_by_topic_id($event['topic_id']); |
373
|
|
|
$this->ideas->set_title($idea['idea_id'], $event['post_data']['post_subject']); |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* Test if we are on the posting page for a new idea |
378
|
|
|
* |
379
|
|
|
* @param string $mode Mode should be post |
380
|
|
|
* @param int $forum_id The forum posting is being made in |
381
|
|
|
* @param bool $topic_flag Flag for the state of the topic_id |
382
|
|
|
* |
383
|
|
|
* @return bool True if mode is post, forum is Ideas forum, and a topic id is |
384
|
|
|
* expected to exist yet, false if any of these tests failed. |
385
|
|
|
*/ |
386
|
|
|
protected function is_post_idea($mode, $forum_id, $topic_flag = true) |
387
|
|
|
{ |
388
|
|
|
if ($mode !== 'post') |
389
|
|
|
{ |
390
|
|
|
return false; |
391
|
|
|
} |
392
|
|
|
|
393
|
|
|
if (!$this->is_ideas_forum($forum_id)) |
394
|
|
|
{ |
395
|
|
|
return false; |
396
|
|
|
} |
397
|
|
|
|
398
|
|
|
return $topic_flag; |
399
|
|
|
} |
400
|
|
|
|
401
|
|
|
/** |
402
|
|
|
* Check if forum id is for the ideas the forum |
403
|
|
|
* |
404
|
|
|
* @param int $forum_id |
405
|
|
|
* @return bool |
406
|
|
|
* @access public |
407
|
|
|
*/ |
408
|
|
|
protected function is_ideas_forum($forum_id) |
409
|
|
|
{ |
410
|
|
|
return (int) $forum_id === (int) $this->config['ideas_forum_id']; |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
/** |
414
|
|
|
* Check if a post is the first post in a topic |
415
|
|
|
* |
416
|
|
|
* @param int|string $topic_first_post_id |
417
|
|
|
* @param int|string $post_id |
418
|
|
|
* @return bool |
419
|
|
|
* @access protected |
420
|
|
|
*/ |
421
|
|
|
protected function is_first_post($topic_first_post_id, $post_id) |
422
|
|
|
{ |
423
|
|
|
return (int) $topic_first_post_id === (int) $post_id; |
424
|
|
|
} |
425
|
|
|
} |
426
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.