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

listener   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 410
Duplicated Lines 5.37 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

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