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

listener   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 405
Duplicated Lines 5.43 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 50
lcom 1
cbo 2
dl 22
loc 405
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
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 viewonline_ideas() 0 9 5
A submit_idea_template() 0 21 3
A submit_idea_before() 4 10 2
A submit_idea_after() 4 18 3
A edit_idea_title() 0 13 5
A is_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] === 'viewtopic' && $event['row']['session_forum_id'] == $this->config['ideas_forum_id']) ||
283
			($event['on_page'][1] === 'app' && strrpos($event['row']['session_page'], 'app.' . $this->php_ext . '/ideas') === 0))
284
		{
285
			$event['location'] = $this->language->lang('VIEWING_IDEAS');
286
			$event['location_url'] = $this->helper->route('phpbb_ideas_index_controller');
287
		}
288
	}
289
290
	/**
291
	 * Modify the Ideas forum's posting page
292
	 *
293
	 * @param \phpbb\event\data $event The event object
294
	 */
295
	public function submit_idea_template($event)
296
	{
297
		if (!$this->is_ideas_forum($event['forum_id']))
298
		{
299
			return;
300
		}
301
302
		// Alter some posting page template vars
303
		if ($event['mode'] === 'post')
304
		{
305
			$event['page_title'] = $this->language->lang('POST_IDEA');
306
			$event->update_subarray('page_data', 'L_POST_A', $this->language->lang('POST_IDEA'));
307
			$event->update_subarray('page_data', 'U_VIEW_FORUM', $this->helper->route('phpbb_ideas_index_controller'));
308
		}
309
310
		// Alter posting page breadcrumbs to link to the ideas controller
311
		$this->template->alter_block_array('navlinks', [
312
			'U_BREADCRUMB'		=> $this->helper->route('phpbb_ideas_index_controller'),
313
			'BREADCRUMB_NAME'	=> $this->language->lang('IDEAS'),
314
		], false, 'change');
315
	}
316
317
	/**
318
	 * Prepare post data vars before posting a new idea/topic.
319
	 *
320
	 * @param \phpbb\event\data $event The event object
321
	 */
322
	public function submit_idea_before($event)
323
	{
324 View Code Duplication
		if (!$this->is_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...
325
		{
326
			return;
327
		}
328
329
		// We need $post_time after submit_post(), but it's not available in the post $data, unless we set it now
330
		$event->update_subarray('data', 'post_time', time());
331
	}
332
333
	/**
334
	 * Submit the idea data after posting a new idea/topic.
335
	 *
336
	 * @param \phpbb\event\data $event The event object
337
	 */
338
	public function submit_idea_after($event)
339
	{
340 View Code Duplication
		if (!$this->is_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...
341
		{
342
			return;
343
		}
344
345
		$this->ideas->submit($event['data']);
346
347
		// Show users who's posts need approval a special message
348
		if (!$this->auth->acl_get('f_noapprove', $event['data']['forum_id']))
349
		{
350
			// Using refresh and trigger error because we can't throw http_exceptions from posting.php
351
			$url = $this->helper->route('phpbb_ideas_index_controller');
352
			meta_refresh(10, $url);
353
			trigger_error($this->language->lang('IDEA_STORED_MOD', $url));
354
		}
355
	}
356
357
	/**
358
	 * Update the idea's title when post title is edited.
359
	 *
360
	 * @param \phpbb\event\data $event The event object
361
	 * @return void
362
	 * @access public
363
	 */
364
	public function edit_idea_title($event)
365
	{
366
		if ($event['mode'] !== 'edit' ||
367
			!$event['update_subject'] ||
368
			!$this->is_ideas_forum($event['forum_id']) ||
369
			!$this->is_first_post($event['post_data']['topic_first_post_id'], $event['post_id']))
370
		{
371
			return;
372
		}
373
374
		$idea = $this->ideas->get_idea_by_topic_id($event['topic_id']);
375
		$this->ideas->set_title($idea['idea_id'], $event['post_data']['post_subject']);
376
	}
377
378
	/**
379
	 * Test if we are on the posting page for a new idea
380
	 *
381
	 * @param string $mode       Mode should be post
382
	 * @param int    $forum_id   The forum posting is being made in
383
	 * @param bool   $topic_flag Flag for the state of the topic_id
384
	 *
385
	 * @return bool True if mode is post, forum is Ideas forum, and a topic id is
386
	 *              expected to exist yet, false if any of these tests failed.
387
	 */
388
	protected function is_post_idea($mode, $forum_id, $topic_flag = true)
389
	{
390
		if ($mode !== 'post')
391
		{
392
			return false;
393
		}
394
395
		if (!$this->is_ideas_forum($forum_id))
396
		{
397
			return false;
398
		}
399
400
		return $topic_flag;
401
	}
402
403
	/**
404
	 * Check if forum id is for the ideas the forum
405
	 *
406
	 * @param int $forum_id
407
	 * @return bool
408
	 * @access public
409
	 */
410
	protected function is_ideas_forum($forum_id)
411
	{
412
		return (int) $forum_id === (int) $this->config['ideas_forum_id'];
413
	}
414
415
	/**
416
	 * Check if a post is the first post in a topic
417
	 *
418
	 * @param int|string $topic_first_post_id
419
	 * @param int|string $post_id
420
	 * @return bool
421
	 * @access protected
422
	 */
423
	protected function is_first_post($topic_first_post_id, $post_id)
424
	{
425
		return (int) $topic_first_post_id === (int) $post_id;
426
	}
427
}
428