Passed
Push — master ( 4b0b81...09dd65 )
by Alain
02:55
created

ShortcodeManager::get_shortcode_class()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 7
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 7
loc 7
ccs 0
cts 6
cp 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
crap 6
1
<?php
2
/**
3
 * Shortcode Manager.
4
 *
5
 * @package   BrightNucleus\Shortcode
6
 * @author    Alain Schlesser <[email protected]>
7
 * @license   GPL-2.0+
8
 * @link      http://www.brightnucleus.com/
9
 * @copyright 2015-2016 Alain Schlesser, Bright Nucleus
10
 */
11
12
namespace BrightNucleus\Shortcode;
13
14
use BrightNucleus\Config\ConfigInterface;
15
use BrightNucleus\Config\ConfigTrait;
16
use BrightNucleus\Dependency\DependencyManagerInterface;
17
use BrightNucleus\Exception\RuntimeException;
18
19
/**
20
 * Shortcode Manager.
21
 *
22
 * This class manages all the shortcodes that it gets passed within a
23
 * ConfigInterface.
24
 *
25
 * @since   0.1.0
26
 *
27
 * @package BrightNucleus\Shortcode
28
 * @author  Alain Schlesser <[email protected]>
29
 */
30
class ShortcodeManager {
31
32
	use ConfigTrait;
33
34
	/*
35
	 * The delimiter that is used to express key-subkey relations in the config.
36
	 */
37
	const CONFIG_SEPARATOR = '/';
38
39
	/*
40
	 * Default classes that are used when omitted from the config.
41
	 */
42
	const DEFAULT_SHORTCODE             = __NAMESPACE__ . '\Shortcode';
43
	const DEFAULT_SHORTCODE_ATTS_PARSER = __NAMESPACE__ . '\ShortcodeAttsParser';
44
	const DEFAULT_SHORTCODE_UI          = __NAMESPACE__ . '\ShortcodeUI';
45
46
	/*
47
	 * The names of the configuration keys.
48
	 */
49
	const KEY_CUSTOM_ATTS_PARSER = 'custom_atts_parser';
50
	const KEY_CUSTOM_CLASS       = 'custom_class';
51
	const KEY_CUSTOM_UI          = 'custom_ui';
52
	const KEY_TAGS               = 'tags';
53
	const KEY_UI                 = 'ui';
54
	/**
55
	 * Collection of ShortcodeInterface objects.
56
	 *
57
	 * @since 0.1.0
58
	 *
59
	 * @var ShortcodeInterface[]
60
	 */
61
	protected $shortcodes = [ ];
62
63
	/**
64
	 * DependencyManagerInterface implementation.
65
	 *
66
	 * @since 0.1.0
67
	 *
68
	 * @var DependencyManagerInterface
69
	 */
70
	protected $dependencies;
71
72
	/**
73
	 * Collection of ShortcodeUIInterface objects.
74
	 *
75
	 * @since 0.1.0
76
	 *
77
	 * @var ShortcodeUIInterface[]
78
	 */
79
	protected $shortcode_uis = [ ];
80
81
	/**
82
	 * Instantiate a ShortcodeManager object.
83
	 *
84
	 * @since 0.1.0
85
	 *
86
	 * @param DependencyManagerInterface $dependencies Dependencies that are
87
	 *                                                 needed by the
88
	 *                                                 shortcodes.
89
	 * @param ConfigInterface            $config       Configuration to set up
90
	 *                                                 the shortcodes.
91
	 * @throws RuntimeException If the config could not be processed.
92
	 */
93
	public function __construct(
94
		ConfigInterface $config,
95
		DependencyManagerInterface $dependencies
96
	) {
97
		$this->processConfig( $config );
98
99
		if ( ! $this->hasConfigKey( self::KEY_TAGS ) ) {
100
			return;
101
		}
102
103
		$this->dependencies = $dependencies;
104
105
		$this->init_shortcodes();
106
	}
107
108
	/**
109
	 * Initialize the Shortcode Manager.
110
	 *
111
	 * @since 0.1.0
112
	 */
113
	public function init_shortcodes() {
114
115
		foreach ( $this->getConfigKey( self::KEY_TAGS ) as $tag => $config ) {
116
			$this->init_shortcode( $tag );
117
		}
118
	}
119
120
	/**
121
	 * Initialize a single shortcode.
122
	 *
123
	 * @since 0.1.0
124
	 *
125
	 * @param string $tag The tag of the shortcode to register.
126
	 */
127
	protected function init_shortcode( $tag ) {
128
		$shortcode_class       = $this->get_shortcode_class( $tag );
129
		$shortcode_atts_parser = $this->get_shortcode_atts_parser_class( $tag );
130
131
		$atts_parser = new $shortcode_atts_parser(
132
			$this->config->getSubConfig( self::KEY_TAGS, $tag )
0 ignored issues
show
Unused Code introduced by
The call to ConfigInterface::getSubConfig() has too many arguments starting with self::KEY_TAGS.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
133
		);
134
135
		$this->shortcodes[] = new $shortcode_class(
136
			$tag,
137
			$this->config,
138
			$atts_parser,
139
			$this->dependencies
140
		);
141
142
		if ( $this->hasConfigKey( self::KEY_TAGS, $tag, self::KEY_UI ) ) {
143
			$this->init_shortcode_ui( $tag );
144
		}
145
	}
146
147
	/**
148
	 * Get the class name of an implementation of the ShortcodeInterface.
149
	 *
150
	 * @since 0.1.0
151
	 *
152
	 * @param string $tag Shortcode tag to get the class for.
153
	 * @return string Class name of the Shortcode.
154
	 */
155 View Code Duplication
	protected function get_shortcode_class( $tag ) {
0 ignored issues
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...
156
		$key             = [ self::KEY_TAGS, $tag, self::KEY_CUSTOM_CLASS ];
157
		$shortcode_class = $this->hasConfigKey( $key )
158
			? $this->getConfigKey( $key )
159
			: self::DEFAULT_SHORTCODE;
160
		return $shortcode_class;
161
	}
162
163
	/**
164
	 * Get the class name of an implementation of the
165
	 * ShortcodeAttsParsersInterface.
166
	 *
167
	 * @since 0.1.0
168
	 *
169
	 * @param string $tag Shortcode tag to get the class for.
170
	 * @return string Class name of the ShortcodeAttsParser.
171
	 */
172 View Code Duplication
	protected function get_shortcode_atts_parser_class( $tag ) {
0 ignored issues
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...
173
		$key         = [ self::KEY_TAGS, $tag, self::KEY_CUSTOM_ATTS_PARSER ];
174
		$atts_parser = $this->hasConfigKey( $key )
175
			? $this->getConfigKey( $key )
176
			: self::DEFAULT_SHORTCODE_ATTS_PARSER;
177
		return $atts_parser;
178
	}
179
180
	/**
181
	 * Initialize the Shortcode UI for a single shortcode.
182
	 *
183
	 * @since 0.1.0
184
	 *
185
	 * @param string $tag The tag of the shortcode to register the UI for.
186
	 */
187
	protected function init_shortcode_ui( $tag ) {
188
		$shortcode_ui_class = $this->get_shortcode_ui_class( $tag );
189
190
		$this->shortcode_uis[] = new $shortcode_ui_class(
191
			$tag,
192
			$this->config,
193
			$this->dependencies
194
		);
195
	}
196
197
	/**
198
	 * Get the class name of an implementation of the ShortcodeUIInterface.
199
	 *
200
	 * @since 0.1.0
201
	 *
202
	 * @param string $tag Configuration settings.
203
	 * @return string Class name of the ShortcodeUI.
204
	 */
205 View Code Duplication
	protected function get_shortcode_ui_class( $tag ) {
0 ignored issues
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...
206
		$key      = [ self::KEY_TAGS, $tag, self::KEY_CUSTOM_UI ];
207
		$ui_class = $this->hasConfigKey( $key )
208
			? $this->getConfigKey( $key )
209
			: self::DEFAULT_SHORTCODE_UI;
210
		return $ui_class;
211
	}
212
213
	/**
214
	 * Register all of the shortcode handlers.
215
	 *
216
	 * @since 0.1.0
217
	 *
218
	 * @return void
219
	 */
220
	public function register() {
221
		array_walk( $this->shortcodes, function ( $shortcode ) {
222
			/** @var ShortcodeInterface $shortcode */
223
			$shortcode->register();
224
		} );
225
226
		// This hook only gets fired when Shortcode UI plugin is active.
227
		\add_action(
228
			'register_shortcode_ui',
229
			[ $this, 'register_shortcode_ui', ]
230
		);
231
	}
232
233
	/**
234
	 * Register the shortcode UI handlers.
235
	 *
236
	 * @since 0.1.0
237
	 */
238
	public function register_shortcode_ui() {
239
		$template = $this->get_page_template();
240
		$context  = [ 'page_template' => $template ];
241
242
		array_walk( $this->shortcode_uis,
243
			function ( $shortcode_ui ) use ( $context ) {
244
				/** @var ShortcodeUIInterface $shortcode_ui */
245
				$shortcode_ui->register( $context );
246
			}
247
		);
248
	}
249
250
	/**
251
	 * Get the name of the page template.
252
	 *
253
	 * @since 0.1.0
254
	 *
255
	 * @return string Name of the page template.
256
	 */
257
	protected function get_page_template() {
258
		$template = str_replace(
259
			\trailingslashit( \get_stylesheet_directory() ),
260
			'',
261
			\get_page_template()
262
		);
263
		return $template;
264
	}
265
}
266