Completed
Pull Request — master (#127)
by Matt
01:21
created

listener   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 422
Duplicated Lines 5.21 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 50
lcom 1
cbo 2
dl 22
loc 422
rs 8.4
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 14 14 1
A adjust_quickmod_tools() 0 25 2
B viewonline_ideas() 0 21 6
A getSubscribedEvents() 0 13 1
A ideas_forum_redirect() 0 9 3
A show_post_buttons() 0 13 3
D show_idea() 0 98 17
A submit_idea_template() 0 27 2
A submit_idea_before() 4 9 2
A submit_idea_after() 4 18 3
A edit_idea_title() 0 13 5
A in_post_idea() 0 14 3
A is_ideas_forum() 0 4 1
A is_first_post() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like listener often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use listener, and based on these observations, apply Extract Interface, too.

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)
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
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
			// Use the custom base url if set, otherwise default to normal routing
107
			$url = $this->config['ideas_base_url'] ?: $this->helper->route('phpbb_ideas_index_controller');
108
			redirect($url);
109
		}
110
	}
111
112
	/**
113
	 * Show post buttons (hide delete, quote or warn user buttons)
114
	 *
115
	 * @param \phpbb\event\data $event The event object
116
	 * @return void
117
	 * @access public
118
	 */
119
	public function show_post_buttons($event)
120
	{
121
		if (!$this->is_ideas_forum($event['row']['forum_id']))
122
		{
123
			return;
124
		}
125
126
		if ($this->is_first_post($event['topic_data']['topic_first_post_id'], $event['row']['post_id']))
127
		{
128
			$event->update_subarray('post_row', 'U_DELETE', false);
129
			$event->update_subarray('post_row', 'U_WARN', false);
130
		}
131
	}
132
133
	/**
134
	 * Show the idea related to the current topic
135
	 *
136
	 * @param \phpbb\event\data $event The event object
137
	 * @return void
138
	 * @access public
139
	 */
140
	public function show_idea($event)
141
	{
142
		if (!$this->is_ideas_forum($event['forum_id']))
143
		{
144
			return;
145
		}
146
147
		$idea = $this->ideas->get_idea_by_topic_id($event['topic_data']['topic_id']);
148
149
		if (!$idea)
150
		{
151
			return;
152
		}
153
154
		$mod = $this->auth->acl_get('m_', (int) $this->config['ideas_forum_id']);
155
		$own = $idea['idea_author'] === $this->user->data['user_id'];
156
157
		if ($mod)
158
		{
159
			$this->template->assign_var('STATUS_ARY', ideas::$statuses);
160
161
			// Add quick mod option for deleting an idea
162
			$this->template->alter_block_array('quickmod', array(
163
				'VALUE'		=> 'delete_topic', // delete topic is used here simply to enable ajax
164
				'TITLE'		=> $this->language->lang('DELETE_IDEA'),
165
				'LINK'		=> $this->link_helper->get_idea_link($idea['idea_id'], 'delete'),
166
			));
167
		}
168
169
		$points = $idea['idea_votes_up'] - $idea['idea_votes_down'];
170
		$can_vote = (bool) ($idea['idea_status'] != ideas::$statuses['IMPLEMENTED'] &&
171
			$idea['idea_status'] != ideas::$statuses['DUPLICATE'] &&
172
			$this->auth->acl_get('f_vote', (int) $this->config['ideas_forum_id']) &&
173
			$event['topic_data']['topic_status'] != ITEM_LOCKED);
174
175
		$s_voted_up = $s_voted_down = false;
176
		if ($idea['idea_votes_up'] || $idea['idea_votes_down'])
177
		{
178
			$votes = $this->ideas->get_voters($idea['idea_id']);
179
180
			foreach ($votes as $vote)
181
			{
182
				$this->template->assign_block_vars('votes_' . ($vote['vote_value'] ? 'up' : 'down'), array(
183
					'USER' => $vote['user'],
184
				));
185
186
				if ($this->user->data['user_id'] == $vote['user_id'])
187
				{
188
					$s_voted_up = ((int) $vote['vote_value'] === 1);
189
					$s_voted_down = ((int) $vote['vote_value'] === 0);
190
				}
191
			}
192
		}
193
194
		$this->template->assign_vars(array(
195
			'IDEA_ID'			=> $idea['idea_id'],
196
			'IDEA_TITLE'		=> $idea['idea_title'],
197
			'IDEA_VOTES'		=> $idea['idea_votes_up'] + $idea['idea_votes_down'],
198
			'IDEA_VOTES_UP'		=> $idea['idea_votes_up'],
199
			'IDEA_VOTES_DOWN'	=> $idea['idea_votes_down'],
200
			'IDEA_POINTS'		=> $points,
201
			'IDEA_STATUS_ID'	=> $idea['idea_status'],
202
			'IDEA_STATUS_NAME'	=> $this->ideas->get_status_from_id($idea['idea_status']),
203
204
			'IDEA_DUPLICATE'	=> $idea['duplicate_id'] ? $this->ideas->get_title($idea['duplicate_id']) : '',
205
			'IDEA_RFC'			=> $idea['rfc_link'],
206
			'IDEA_TICKET'		=> $idea['ticket_id'],
207
			'IDEA_IMPLEMENTED'	=> $idea['implemented_version'],
208
209
			'S_IS_MOD'			=> $mod,
210
			'S_CAN_EDIT'		=> $mod || $own,
211
			'S_CAN_VOTE'		=> $can_vote,
212
			'S_CAN_VOTE_UP'		=> $can_vote && !$s_voted_up,
213
			'S_CAN_VOTE_DOWN'	=> $can_vote && !$s_voted_down,
214
			'S_VOTED'			=> $s_voted_up || $s_voted_down,
215
			'S_VOTED_UP'		=> $s_voted_up,
216
			'S_VOTED_DOWN'		=> $s_voted_down,
217
218
			'U_CHANGE_STATUS'	=> $this->link_helper->get_idea_link($idea['idea_id'], 'status', true),
219
			'U_EDIT_DUPLICATE'	=> $this->link_helper->get_idea_link($idea['idea_id'], 'duplicate', true),
220
			'U_EDIT_RFC'		=> $this->link_helper->get_idea_link($idea['idea_id'], 'rfc', true),
221
			'U_EDIT_IMPLEMENTED'=> $this->link_helper->get_idea_link($idea['idea_id'], 'implemented', true),
222
			'U_EDIT_TICKET'		=> $this->link_helper->get_idea_link($idea['idea_id'], 'ticket', true),
223
			'U_REMOVE_VOTE'		=> $this->link_helper->get_idea_link($idea['idea_id'], 'removevote', true),
224
			'U_IDEA_VOTE'		=> $this->link_helper->get_idea_link($idea['idea_id'], 'vote', true),
225
			'U_IDEA_DUPLICATE'	=> $this->link_helper->get_idea_link($idea['duplicate_id']),
226
			'U_IDEA_STATUS_LINK'=> $this->helper->route('phpbb_ideas_list_controller', ['status' => $idea['idea_status']]),
227
			'U_SEARCH_MY_IDEAS' => $this->helper->route('phpbb_ideas_list_controller', ['sort' => ideas::SORT_MYIDEAS, 'status' => '-1']),
228
			'U_TITLE_LIVESEARCH'=> $this->helper->route('phpbb_ideas_livesearch_controller'),
229
		));
230
231
		// Use Ideas breadcrumbs
232
		$this->template->destroy_block_vars('navlinks');
233
		$this->template->assign_block_vars('navlinks', array(
234
			'U_VIEW_FORUM'		=> $this->helper->route('phpbb_ideas_index_controller'),
235
			'FORUM_NAME'		=> $this->language->lang('IDEAS'),
236
		));
237
	}
238
239
	/**
240
	 * Adjust the QuickMod tools displayed
241
	 * (hide options to delete, restore, make global, sticky or announcement)
242
	 *
243
	 * @param \phpbb\event\data $event The event object
244
	 * @return void
245
	 * @access public
246
	 */
247
	public function adjust_quickmod_tools($event)
248
	{
249
		if (!$this->is_ideas_forum($event['forum_id']))
250
		{
251
			return;
252
		}
253
254
		$quickmod_array = $event['quickmod_array'];
255
256
		//$quickmod_array['lock'][1] = false;
257
		//$quickmod_array['unlock'][1] = false;
258
		$quickmod_array['delete_topic'][1] = false;
259
		$quickmod_array['restore_topic'][1] = false;
260
		//$quickmod_array['move'][1] = false;
261
		//$quickmod_array['split'][1] = false;
262
		//$quickmod_array['merge'][1] = false;
263
		//$quickmod_array['merge_topic'][1] = false;
264
		//$quickmod_array['fork'][1] = false;
265
		$quickmod_array['make_normal'][1] = false;
266
		$quickmod_array['make_sticky'][1] = false;
267
		$quickmod_array['make_announce'][1] = false;
268
		$quickmod_array['make_global'][1] = false;
269
270
		$event['quickmod_array'] = $quickmod_array;
271
	}
272
273
	/**
274
	 * Show users as viewing Ideas on Who Is Online page
275
	 *
276
	 * @param \phpbb\event\data $event The event object
277
	 * @return void
278
	 * @access public
279
	 */
280
	public function viewonline_ideas($event)
281
	{
282
		if ($event['on_page'][1] === 'app')
283
		{
284
			if (strrpos($event['row']['session_page'], 'app.' . $this->php_ext . '/ideas/post') === 0)
285
			{
286
				$event['location'] = $this->language->lang('POSTING_NEW_IDEA');
287
				$event['location_url'] = $this->helper->route('phpbb_ideas_index_controller');
288
			}
289
			else if (strrpos($event['row']['session_page'], 'app.' . $this->php_ext . '/ideas') === 0)
290
			{
291
				$event['location'] = $this->language->lang('VIEWING_IDEAS');
292
				$event['location_url'] = $this->helper->route('phpbb_ideas_index_controller');
293
			}
294
		}
295
		else if ($event['on_page'][1] === 'viewtopic' && $event['row']['session_forum_id'] == $this->config['ideas_forum_id'])
296
		{
297
			$event['location'] = $this->language->lang('VIEWING_IDEAS');
298
			$event['location_url'] = $this->helper->route('phpbb_ideas_index_controller');
299
		}
300
	}
301
302
	/**
303
	 * Modify template vars on the post a new idea page
304
	 *
305
	 * @param \phpbb\event\data $event The event object
306
	 */
307
	public function submit_idea_template($event)
308
	{
309
		if (!$this->in_post_idea($event['mode'], $event['forum_id']))
310
		{
311
			return;
312
		}
313
314
		// Alter posting page template vars
315
		$event['page_title'] = $this->language->lang('NEW_IDEA');
316
		$event->update_subarray('page_data', 'L_POST_A', $this->language->lang('POST_IDEA'));
317
		$event->update_subarray('page_data', 'U_VIEW_FORUM', $this->helper->route('phpbb_ideas_index_controller'));
318
319
		// Do not show the Save Draft button
320
		$event->update_subarray('page_data', 'S_SAVE_ALLOWED', false);
321
		$event->update_subarray('page_data', 'S_HAS_DRAFTS', false);
322
323
		// Alter posting page breadcrumbs
324
		$this->template->alter_block_array('navlinks', [
325
			'U_BREADCRUMB'		=> $this->helper->route('phpbb_ideas_index_controller'),
326
			'BREADCRUMB_NAME'	=> $this->language->lang('IDEAS'),
327
		], false, 'change');
328
329
		$this->template->alter_block_array('navlinks', [
330
			'U_VIEW_FORUM'	=> $this->helper->route('phpbb_ideas_post_controller'),
331
			'FORUM_NAME'	=> $this->language->lang('NEW_IDEA'),
332
		], true, 'insert');
333
	}
334
335
	/**
336
	 * Prepare posting parameters before posting a new idea/topic.
337
	 *
338
	 * @param \phpbb\event\data $event The event object
339
	 */
340
	public function submit_idea_before($event)
341
	{
342 View Code Duplication
		if (!$this->in_post_idea($event['mode'], $event['data']['forum_id'], empty($event['data']['topic_id'])))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
343
		{
344
			return;
345
		}
346
347
		$event->update_subarray('data', 'post_time', time());
348
	}
349
350
	/**
351
	 * Submit an idea after submit_post when posting a new idea/topic.
352
	 *
353
	 * @param \phpbb\event\data $event The event object
354
	 */
355
	public function submit_idea_after($event)
356
	{
357 View Code Duplication
		if (!$this->in_post_idea($event['mode'], $event['data']['forum_id'], !empty($event['data']['topic_id'])))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
358
		{
359
			return;
360
		}
361
362
		$this->ideas->submit($event['data']);
363
364
		// Show users who's posts need approval a special message
365
		if (!$this->auth->acl_get('f_noapprove', $this->config['ideas_forum_id']))
366
		{
367
			// Use refresh and trigger error because we can't throw http_exceptions from posting.php
368
			$url = $this->helper->route('phpbb_ideas_index_controller');
369
			meta_refresh(10, $url);
370
			trigger_error($this->language->lang('IDEA_STORED_MOD', $url));
371
		}
372
	}
373
374
	/**
375
	 * Update the idea's title when post title is edited.
376
	 *
377
	 * @param \phpbb\event\data $event The event object
378
	 * @return void
379
	 * @access public
380
	 */
381
	public function edit_idea_title($event)
382
	{
383
		if ($event['mode'] !== 'edit' ||
384
			!$event['update_subject'] ||
385
			!$this->is_ideas_forum($event['forum_id']) ||
386
			!$this->is_first_post($event['post_data']['topic_first_post_id'], $event['post_id']))
387
		{
388
			return;
389
		}
390
391
		$idea = $this->ideas->get_idea_by_topic_id($event['topic_id']);
392
		$this->ideas->set_title($idea['idea_id'], $event['post_data']['post_subject']);
393
	}
394
395
	/**
396
	 * Test if we are on the posting page for a new idea
397
	 *
398
	 * @param string $mode       Mode should be post
399
	 * @param int    $forum_id   The forum posting is being made in
400
	 * @param bool   $topic_flag Flag for the state of the topic_id
401
	 *
402
	 * @return bool True if mode is post, forum is Ideas forum, and a topic id is
403
	 *              expected to exist yet, false if any of these tests failed.
404
	 */
405
	protected function in_post_idea($mode, $forum_id, $topic_flag = true)
406
	{
407
		if ($mode !== 'post')
408
		{
409
			return false;
410
		}
411
412
		if (!$this->is_ideas_forum($forum_id))
413
		{
414
			return false;
415
		}
416
417
		return $topic_flag;
418
	}
419
420
	/**
421
	 * Check if forum id is for the ideas the forum
422
	 *
423
	 * @param int $forum_id
424
	 * @return bool
425
	 * @access public
426
	 */
427
	protected function is_ideas_forum($forum_id)
428
	{
429
		return (int) $forum_id === (int) $this->config['ideas_forum_id'];
430
	}
431
432
	/**
433
	 * Check if a post is the first post in a topic
434
	 *
435
	 * @param int|string $topic_first_post_id
436
	 * @param int|string $post_id
437
	 * @return bool
438
	 * @access protected
439
	 */
440
	protected function is_first_post($topic_first_post_id, $post_id)
441
	{
442
		return (int) $topic_first_post_id === (int) $post_id;
443
	}
444
}
445