main_listener   B
last analyzed

Complexity

Total Complexity 44

Size/Duplication

Total Lines 370
Duplicated Lines 0 %

Importance

Changes 29
Bugs 1 Features 1
Metric Value
eloc 102
c 29
b 1
f 1
dl 0
loc 370
rs 8.8798
wmc 44

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A getSubscribedEvents() 0 13 1
A append_agreement() 0 10 3
A setup_media_configs() 0 5 1
A enable_media_sites() 0 17 4
A modify_tag_templates() 0 12 2
A disable_media_embed() 0 14 3
A configure_url_parsing() 0 7 2
A set_permissions() 0 4 1
A get_siteIds() 0 5 2
A check_signature() 0 6 4
A check_magic_urls() 0 5 3
A check_forum_permission() 0 6 3
A check_bbcode_enabled() 0 8 2
A media_embed_help() 0 20 2
A add_custom_sites() 0 18 4
A setup_media_bbcode() 0 4 1
A setup_cache_dir() 0 9 3
A check_pm_permission() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like main_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.

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 main_listener, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 *
4
 * phpBB Media Embed PlugIn extension for the phpBB Forum Software package.
5
 *
6
 * @copyright (c) 2016 phpBB Limited <https://www.phpbb.com>
7
 * @license GNU General Public License, version 2 (GPL-2.0)
8
 *
9
 */
10
11
namespace phpbb\mediaembed\event;
12
13
use phpbb\auth\auth;
0 ignored issues
show
Bug introduced by
The type phpbb\auth\auth was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use phpbb\config\config;
0 ignored issues
show
Bug introduced by
The type phpbb\config\config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use phpbb\config\db_text;
0 ignored issues
show
Bug introduced by
The type phpbb\config\db_text was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use phpbb\language\language;
0 ignored issues
show
Bug introduced by
The type phpbb\language\language was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use phpbb\mediaembed\collection\customsitescollection;
18
use phpbb\mediaembed\ext;
19
use phpbb\template\template;
0 ignored issues
show
Bug introduced by
The type phpbb\template\template was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\EventD...ventSubscriberInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use Symfony\Component\Yaml\Yaml;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Yaml\Yaml was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
23
/**
24
 * Event listener
25
 */
26
class main_listener implements EventSubscriberInterface
27
{
28
	/** @var string A link to a rich content media site for demo purposes */
29
	public const MEDIA_DEMO_URL = 'https://youtu.be/Ne18ZQ7LLI0';
30
31
	/** @var auth */
32
	protected $auth;
33
34
	/** @var config $config */
35
	protected $config;
36
37
	/** @var db_text $config_text */
38
	protected $config_text;
39
40
	/** @var language $language */
41
	protected $language;
42
43
	/** @var template $template */
44
	protected $template;
45
46
	/** @var customsitescollection $custom_sites */
47
	protected $custom_sites;
48
49
	/** @var string $cache_dir */
50
	protected $cache_dir;
51
52
	/** @var bool Disable the media embed plugin (plain url parsing) */
53
	protected $disable_plugin = false;
54
55
	/** @var bool Disable the media tag (bbcode parsing) */
56
	protected $disable_tag = false;
57
58
	/**
59
	 * {@inheritDoc}
60
	 */
61
	public static function getSubscribedEvents()
62
	{
63
		return [
64
			'core.text_formatter_s9e_configure_after'	=> [['add_custom_sites', 3], ['enable_media_sites', 2], ['configure_url_parsing', 1], ['modify_tag_templates', 0]],
65
			'core.display_custom_bbcodes'				=> 'setup_media_bbcode',
66
			'core.permissions'							=> 'set_permissions',
67
			'core.help_manager_add_block_before'		=> 'media_embed_help',
68
			'core.posting_modify_message_text'			=> 'check_forum_permission',
69
			'core.ucp_pm_compose_modify_parse_before'	=> 'check_pm_permission',
70
			'core.message_parser_check_message'			=> [['check_signature'], ['check_magic_urls'], ['check_bbcode_enabled']],
71
			'core.text_formatter_s9e_parser_setup'		=> [['disable_media_embed'], ['setup_cache_dir']],
72
			'core.page_header' 							=> 'setup_media_configs',
73
			'core.page_footer'							=> 'append_agreement',
74
		];
75
	}
76
77
	/**
78
	 * Constructor
79
	 *
80
	 * @param auth					$auth
81
	 * @param config				$config
82
	 * @param db_text				$config_text
83
	 * @param language				$language
84
	 * @param template				$template
85
	 * @param customsitescollection	$custom_sites
86
	 * @param string				$cache_dir
87
	 */
88
	public function __construct(auth $auth, config $config, db_text $config_text, language $language, template $template, customsitescollection $custom_sites, $cache_dir)
89
	{
90
		$this->auth = $auth;
91
		$this->config = $config;
92
		$this->language = $language;
93
		$this->template = $template;
94
		$this->config_text = $config_text;
95
		$this->custom_sites = $custom_sites;
96
		$this->cache_dir = $cache_dir;
97
	}
98
99
	/**
100
	 * Add any custom site definitions to the default MediaEmbed sites object
101
	 *
102
	 * @param \phpbb\event\data $event The event object
0 ignored issues
show
Bug introduced by
The type phpbb\event\data was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
103
	 * @return void
104
	 */
105
	public function add_custom_sites($event)
106
	{
107
		$is_phpbb4 = phpbb_version_compare($this->config['version'], '4.0.0-a1', '>=');
0 ignored issues
show
Bug introduced by
The function phpbb_version_compare was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

107
		$is_phpbb4 = /** @scrutinizer ignore-call */ phpbb_version_compare($this->config['version'], '4.0.0-a1', '>=');
Loading history...
108
		$phpbb4_builtins = array_flip([
109
			'applepodcasts', 'bluesky', 'bunny', 'mastodon', 'pastebin', 'threads', 'twitter',
110
		]);
111
112
		foreach ($this->custom_sites->get_collection() as $site)
113
		{
114
			$name = basename($site, ext::YML);
115
116
			// Skip built-in sites when running phpBB 4
117
			if ($is_phpbb4 && isset($phpbb4_builtins[$name]))
118
			{
119
				continue;
120
			}
121
122
			$event['configurator']->MediaEmbed->defaultSites->add($name, Yaml::parseFile($site));
123
		}
124
	}
125
126
	/**
127
	 * Enable media sites
128
	 *
129
	 * @param \phpbb\event\data $event The event object
130
	 * @return void
131
	 */
132
	public function enable_media_sites($event)
133
	{
134
		foreach ($this->get_siteIds() as $siteId)
135
		{
136
			// skip media sites that already exist as a BBCode
137
			if (isset($event['configurator']->BBCodes[$siteId]))
138
			{
139
				continue;
140
			}
141
142
			try
143
			{
144
				$event['configurator']->MediaEmbed->add($siteId);
145
			}
146
			catch (\RuntimeException $e)
147
			{
148
				continue;
149
			}
150
		}
151
	}
152
153
	/**
154
	 * Configure plain URL parsing
155
	 *
156
	 * @param \phpbb\event\data $event The event object
157
	 * @return void
158
	 */
159
	public function configure_url_parsing($event)
160
	{
161
		// Disable plain url parsing?
162
		if (!$this->config->offsetGet('media_embed_parse_urls'))
163
		{
164
			$event['configurator']->MediaEmbed->finalize();
165
			unset($event['configurator']->MediaEmbed);
166
		}
167
	}
168
169
	/**
170
	 * Modify bbcode tag templates
171
	 *
172
	 * @param \phpbb\event\data $event The event object
173
	 * @return void
174
	 */
175
	public function modify_tag_templates($event)
176
	{
177
		try
178
		{
179
			// force YouTube to use the no cookies until the user starts video playback, and fix referrer policy issues
180
			$tag = $event['configurator']->tags['YOUTUBE'];
181
			$tag->template = str_replace(['www.youtube.com', ' allowfullscreen'], ['www.youtube-nocookie.com', ' referrerpolicy="origin" allowfullscreen'], $tag->template);
182
183
			$event['configurator']->finalize();
184
		}
185
		catch (\RuntimeException $e)
186
		{
187
			// do nothing
188
		}
189
	}
190
191
	/**
192
	 * Set template switch for displaying the [media] BBCode button
193
	 *
194
	 * @return void
195
	 */
196
	public function setup_media_bbcode()
197
	{
198
		$this->language->add_lang('common', 'phpbb/mediaembed');
199
		$this->template->assign_var('S_BBCODE_MEDIA', $this->config->offsetGet('media_embed_bbcode'));
200
	}
201
202
	/**
203
	 * Set media embed forum and user PM permission
204
	 *
205
	 * @param	\phpbb\event\data	$event	The event object
206
	 * @return	void
207
	 */
208
	public function set_permissions($event)
209
	{
210
		$event->update_subarray('permissions', 'f_mediaembed', ['lang' => 'ACL_F_MEDIAEMBED', 'cat' => 'content']);
211
		$event->update_subarray('permissions', 'u_pm_mediaembed', ['lang' => 'ACL_U_PM_MEDIAEMBED', 'cat' => 'pm']);
212
	}
213
214
	/**
215
	 * Add Media Embed help to the BBCode Guide
216
	 *
217
	 * @param \phpbb\event\data $event The event object
218
	 * @return void
219
	 */
220
	public function media_embed_help($event)
221
	{
222
		if ($event['block_name'] === 'HELP_BBCODE_BLOCK_OTHERS')
223
		{
224
			$this->language->add_lang('help', 'phpbb/mediaembed');
225
226
			$this->template->assign_block_vars('faq_block', [
227
				'BLOCK_TITLE'	=> $this->language->lang('HELP_EMBEDDING_MEDIA'),
228
				'SWITCH_COLUMN'	=> false,
229
			]);
230
231
			$uid = $bitfield = $flags = '';
232
			$demo_text = self::MEDIA_DEMO_URL;
233
			generate_text_for_storage($demo_text, $uid, $bitfield, $flags, true, true);
0 ignored issues
show
Bug introduced by
The function generate_text_for_storage was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

233
			/** @scrutinizer ignore-call */ 
234
   generate_text_for_storage($demo_text, $uid, $bitfield, $flags, true, true);
Loading history...
234
			$demo_display = generate_text_for_display($demo_text, $uid, $bitfield, $flags);
0 ignored issues
show
Bug introduced by
The function generate_text_for_display was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

234
			$demo_display = /** @scrutinizer ignore-call */ generate_text_for_display($demo_text, $uid, $bitfield, $flags);
Loading history...
235
			$list_sites = implode(', ', $this->get_siteIds());
236
237
			$this->template->assign_block_vars('faq_block.faq_row', [
238
				'FAQ_QUESTION'	=> $this->language->lang('HELP_EMBEDDING_MEDIA_QUESTION'),
239
				'FAQ_ANSWER'	=> $this->language->lang('HELP_EMBEDDING_MEDIA_ANSWER', self::MEDIA_DEMO_URL, $demo_display, $list_sites),
240
			]);
241
		}
242
	}
243
244
	/**
245
	 * Disable Media Embed plugin and tag if necessary
246
	 *
247
	 * @param \phpbb\event\data $event The event object
248
	 * @return void
249
	 */
250
	public function disable_media_embed($event)
251
	{
252
		/** @var \phpbb\textformatter\s9e\parser $service  */
253
		$service = $event['parser'];
254
		$parser = $service->get_parser();
255
256
		if ($this->disable_plugin)
257
		{
258
			$parser->disablePlugin('MediaEmbed');
259
		}
260
261
		if ($this->disable_tag)
262
		{
263
			$parser->disableTag('MEDIA');
264
		}
265
	}
266
267
	/**
268
	 * Set up a cache directory to improve scraping performance
269
	 *
270
	 * @param \phpbb\event\data $event The event object
271
	 * @return void
272
	 */
273
	public function setup_cache_dir($event)
274
	{
275
		if ($this->cache_dir && $this->config->offsetGet('media_embed_enable_cache'))
276
		{
277
			/** @var \phpbb\textformatter\s9e\parser $service  */
278
			$service = $event['parser'];
279
			$parser = $service->get_parser();
280
281
			$parser->registeredVars['cacheDir'] = $this->cache_dir;
282
		}
283
	}
284
285
	/**
286
	 * Check if forum permission allows Media Embed
287
	 *
288
	 * @param \phpbb\event\data $event The event object
289
	 * @return void
290
	 */
291
	public function check_forum_permission($event)
292
	{
293
		if (!$this->auth->acl_get('f_mediaembed', $event['forum_id']) || !$this->auth->acl_get('f_bbcode', $event['forum_id']))
294
		{
295
			$this->disable_plugin = true;
296
			$this->disable_tag = true;
297
		}
298
	}
299
300
	/**
301
	 * Check if user permission allows Media Embed in private messages
302
	 *
303
	 * @return void
304
	 */
305
	public function check_pm_permission()
306
	{
307
		if (!$this->auth->acl_get('u_pm_mediaembed'))
308
		{
309
			$this->disable_plugin = true;
310
			$this->disable_tag = true;
311
		}
312
	}
313
314
	/**
315
	 * Check if signature posting is allowed.
316
	 * Posting signatures is 'sig', reparsing signatures is 'user_signature'.
317
	 *
318
	 * @param \phpbb\event\data $event The event object
319
	 * @return void
320
	 */
321
	public function check_signature($event)
322
	{
323
		if (($event['mode'] === 'sig' || $event['mode'] === 'text_reparser.user_signature') && !$this->config->offsetGet('media_embed_allow_sig'))
324
		{
325
			$this->disable_plugin = true;
326
			$this->disable_tag = true;
327
		}
328
	}
329
330
	/**
331
	 * Check if magic urls is allowed.
332
	 *
333
	 * @param \phpbb\event\data $event The event object
334
	 * @return void
335
	 */
336
	public function check_magic_urls($event)
337
	{
338
		if (!$event['allow_magic_url'] || !$this->config->offsetGet('media_embed_parse_urls'))
339
		{
340
			$this->disable_plugin = true;
341
		}
342
	}
343
344
	/**
345
	 * Check if bbcodes are allowed.
346
	 *
347
	 * @param \phpbb\event\data $event The event object
348
	 * @return void
349
	 */
350
	public function check_bbcode_enabled($event)
351
	{
352
		if (!$event['allow_bbcode'])
353
		{
354
			// Want to leave plugin enabled, but it seems plugin won't work
355
			// when tag is disabled, so we have to disable both it seems.
356
			$this->disable_plugin = true;
357
			$this->disable_tag = true;
358
		}
359
	}
360
361
	public function setup_media_configs()
362
	{
363
		$this->template->assign_vars([
364
			'S_MEDIA_EMBED_FULL_WIDTH' => $this->config->offsetGet('media_embed_full_width'),
365
			'S_MEDIA_EMBED_MAX_WIDTHS' => json_decode($this->config_text->get('media_embed_max_width'), true),
366
		]);
367
	}
368
369
	/**
370
	 * Get allowed sites for media embedding
371
	 *
372
	 * @return array An array of sites
373
	 */
374
	protected function get_siteIds()
375
	{
376
		$siteIds = $this->config_text->get('media_embed_sites');
377
378
		return $siteIds ? json_decode($siteIds, true) : [];
379
	}
380
381
	/**
382
	 * Appends additional language to the privacy policy agreement text.
383
	 *
384
	 * @return void
385
	 */
386
	public function append_agreement()
387
	{
388
		if (!$this->template->retrieve_var('S_AGREEMENT') || ($this->template->retrieve_var('AGREEMENT_TITLE') !== $this->language->lang('PRIVACY')))
389
		{
390
			return;
391
		}
392
393
		$this->language->add_lang('ucp', 'phpbb/mediaembed');
394
395
		$this->template->append_var('AGREEMENT_TEXT', $this->language->lang('MEDIA_EMBED_PRIVACY_POLICY', $this->config['sitename']));
396
	}
397
}
398