|
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 )
|
|
|
|
|
|
|
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 ) {
|
|
|
|
|
|
|
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 ) {
|
|
|
|
|
|
|
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 ) {
|
|
|
|
|
|
|
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
|
|
|
|
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
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.