|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* Titan Framework class |
|
4
|
|
|
* |
|
5
|
|
|
* @package Titan Framework |
|
6
|
|
|
*/ |
|
7
|
|
|
|
|
8
|
|
|
if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. |
|
9
|
|
|
} |
|
10
|
|
|
|
|
11
|
|
|
/** |
|
12
|
|
|
* TitanFramework class |
|
13
|
|
|
* |
|
14
|
|
|
* @since 1.0 |
|
15
|
|
|
*/ |
|
16
|
|
|
class TitanFramework { |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* All TitanFramework instances |
|
20
|
|
|
* @var array |
|
21
|
|
|
*/ |
|
22
|
|
|
private static $instances = array(); |
|
23
|
|
|
|
|
24
|
|
|
/** |
|
25
|
|
|
* The current option namespace. |
|
26
|
|
|
* Options will be prefixed with this in the database |
|
27
|
|
|
* @var string |
|
28
|
|
|
*/ |
|
29
|
|
|
public $optionNamespace; |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* All main containers (admin pages, meta boxes, customizer section) |
|
33
|
|
|
* @var array of TitanFrameworkAdminPage, TitanFrameworkMetaBox, & TitanFrameworkCustomizer |
|
34
|
|
|
*/ |
|
35
|
|
|
private $mainContainers = array(); |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* All Google Font options used. This is for enqueuing Google Fonts for the frontend |
|
39
|
|
|
* TODO Move this to the TitanFrameworkOptionSelectGooglefont class and let it enqueue from there |
|
40
|
|
|
* @var array TitanFrameworkOptionSelectGooglefont |
|
41
|
|
|
*/ |
|
42
|
|
|
private $googleFontsOptions = array(); |
|
|
|
|
|
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* We store option ids which should not be created here |
|
46
|
|
|
* @var array |
|
47
|
|
|
* @see removeOption() |
|
48
|
|
|
*/ |
|
49
|
|
|
private $optionsToRemove = array(); |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* Holds the values of all admin (page & tab) options. We need this since |
|
53
|
|
|
* @var array of TitanFrameworkOption |
|
54
|
|
|
*/ |
|
55
|
|
|
private $adminOptions; |
|
56
|
|
|
|
|
57
|
|
|
/** |
|
58
|
|
|
* The CSS class instance used |
|
59
|
|
|
* @var TitanFrameworkCSS |
|
60
|
|
|
*/ |
|
61
|
|
|
public $cssInstance; |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* We store the options (with IDs) here, used for ensuring our serialized option |
|
65
|
|
|
* value doesn't get cluttered with unused options |
|
66
|
|
|
* @var array |
|
67
|
|
|
*/ |
|
68
|
|
|
public $optionsUsed = array(); |
|
69
|
|
|
|
|
70
|
|
|
/** |
|
71
|
|
|
* The current list of settings |
|
72
|
|
|
* @var array |
|
73
|
|
|
*/ |
|
74
|
|
|
public $settings = array(); |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* Default settings |
|
78
|
|
|
* @var array |
|
79
|
|
|
*/ |
|
80
|
|
|
private $defaultSettings = array( |
|
81
|
|
|
'css' => 'generate', // If 'generate', Titan will try and generate a cacheable |
|
82
|
|
|
// CSS file (or inline if it can't). |
|
83
|
|
|
// If 'inline', CSS will be printed out in the head tag, |
|
84
|
|
|
// If false, CSS will not be generated nor printed. |
|
85
|
|
|
); |
|
86
|
|
|
|
|
87
|
|
|
|
|
88
|
|
|
/** |
|
89
|
|
|
* Gets an instance of the framework for the namespace |
|
90
|
|
|
* |
|
91
|
|
|
* @since 1.0 |
|
92
|
|
|
* |
|
93
|
|
|
* @param string $optionNamespace The namespace to get options from. |
|
94
|
|
|
* |
|
95
|
|
|
* @return TitanFramework |
|
96
|
|
|
*/ |
|
97
|
|
|
public static function getInstance( $optionNamespace ) { |
|
98
|
|
|
|
|
99
|
|
|
// Clean namespace. |
|
100
|
|
|
$optionNamespace = str_replace( ' ', '-', trim( strtolower( $optionNamespace ) ) ); |
|
101
|
|
|
|
|
102
|
|
|
foreach ( self::$instances as $instance ) { |
|
103
|
|
|
if ( $instance->optionNamespace == $optionNamespace ) { |
|
104
|
|
|
return $instance; |
|
105
|
|
|
} |
|
106
|
|
|
} |
|
107
|
|
|
|
|
108
|
|
|
$newInstance = new TitanFramework( $optionNamespace ); |
|
109
|
|
|
self::$instances[] = $newInstance; |
|
110
|
|
|
return $newInstance; |
|
111
|
|
|
} |
|
112
|
|
|
|
|
113
|
|
|
|
|
114
|
|
|
/** |
|
115
|
|
|
* Gets all active instances of Titan Framework |
|
116
|
|
|
* |
|
117
|
|
|
* @since 1.9.2 |
|
118
|
|
|
* |
|
119
|
|
|
* @return array An array of TitanFramework objects |
|
120
|
|
|
*/ |
|
121
|
|
|
public static function getAllInstances() { |
|
122
|
|
|
return self::$instances; |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
|
|
126
|
|
|
/** |
|
127
|
|
|
* Creates a new TitanFramework object |
|
128
|
|
|
* |
|
129
|
|
|
* @since 1.0 |
|
130
|
|
|
* |
|
131
|
|
|
* @param string $optionNamespace The namespace to get options from. |
|
132
|
|
|
*/ |
|
133
|
|
|
function __construct( $optionNamespace ) { |
|
|
|
|
|
|
134
|
|
|
|
|
135
|
|
|
// Clean namespace. |
|
136
|
|
|
$optionNamespace = str_replace( ' ', '-', trim( strtolower( $optionNamespace ) ) ); |
|
137
|
|
|
|
|
138
|
|
|
$this->optionNamespace = $optionNamespace; |
|
139
|
|
|
$this->settings = $this->defaultSettings; |
|
140
|
|
|
|
|
141
|
|
|
do_action( 'tf_init', $this ); |
|
142
|
|
|
do_action( 'tf_init_' . $this->optionNamespace, $this ); |
|
143
|
|
|
|
|
144
|
|
|
$this->cssInstance = new TitanFrameworkCSS( $this ); |
|
145
|
|
|
|
|
146
|
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'loadAdminScripts' ) ); |
|
147
|
|
|
add_action( 'tf_create_option_' . $this->optionNamespace, array( $this, 'rememberAllOptions' ) ); |
|
148
|
|
|
add_filter( 'tf_create_option_continue_' . $this->optionNamespace, array( $this, 'removeChildThemeOptions' ), 10, 2 ); |
|
149
|
|
|
|
|
150
|
|
|
// Create a save option filter for customizer options. |
|
151
|
|
|
add_filter( 'pre_update_option', array( $this, 'addCustomizerSaveFilter' ), 10, 3 ); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
|
|
155
|
|
|
/** |
|
156
|
|
|
* Action hook on tf_create_option to remember all the options, used to ensure that our |
|
157
|
|
|
* serialized option does not get cluttered with unused options |
|
158
|
|
|
* |
|
159
|
|
|
* @since 1.2.1 |
|
160
|
|
|
* |
|
161
|
|
|
* @param TitanFrameworkOption $option The option that was just created. |
|
162
|
|
|
* |
|
163
|
|
|
* @return void |
|
164
|
|
|
*/ |
|
165
|
|
|
public function rememberAllOptions( $option ) { |
|
166
|
|
|
if ( ! empty( $option->settings['id'] ) ) { |
|
167
|
|
|
|
|
168
|
|
|
if ( is_admin() && isset( $this->optionsUsed[ $option->settings['id'] ] ) ) { |
|
169
|
|
|
self::displayFrameworkError( |
|
170
|
|
|
sprintf( __( 'All option IDs per namespace must be unique. The id %s has been used multiple times.', TF_I18NDOMAIN ), |
|
171
|
|
|
'<code>' . $option->settings['id'] . '</code>' |
|
172
|
|
|
) |
|
173
|
|
|
); |
|
174
|
|
|
} |
|
175
|
|
|
|
|
176
|
|
|
$this->optionsUsed[ $option->settings['id'] ] = $option; |
|
177
|
|
|
} |
|
178
|
|
|
} |
|
179
|
|
|
|
|
180
|
|
|
|
|
181
|
|
|
/** |
|
182
|
|
|
* Loads all the admin scripts used by Titan Framework |
|
183
|
|
|
* |
|
184
|
|
|
* @since 1.0 |
|
185
|
|
|
* |
|
186
|
|
|
* @param string $hook The slug of admin page that called the enqueue. |
|
187
|
|
|
* |
|
188
|
|
|
* @return void |
|
189
|
|
|
*/ |
|
190
|
|
|
public function loadAdminScripts( $hook ) { |
|
191
|
|
|
|
|
192
|
|
|
// Get all options panel IDs. |
|
193
|
|
|
$panel_ids = array(); |
|
194
|
|
|
if ( ! empty( $this->mainContainers['admin-page'] ) ) { |
|
195
|
|
|
foreach ( $this->mainContainers['admin-page'] as $admin_panel ) { |
|
196
|
|
|
$panel_ids[] = $admin_panel->panelID; |
|
197
|
|
|
} |
|
198
|
|
|
} |
|
199
|
|
|
|
|
200
|
|
|
// Only enqueue scripts if we're on a Titan options page. |
|
201
|
|
|
if ( in_array( $hook, $panel_ids ) || ! empty( $this->mainContainers['meta-box'] ) ) { |
|
202
|
|
|
wp_enqueue_media(); |
|
203
|
|
|
wp_enqueue_script( 'tf-serialize', TitanFramework::getURL( '../js/min/serialize-min.js', __FILE__ ) ); |
|
204
|
|
|
wp_enqueue_script( 'tf-styling', TitanFramework::getURL( '../js/min/admin-styling-min.js', __FILE__ ) ); |
|
205
|
|
|
wp_enqueue_style( 'tf-admin-styles', TitanFramework::getURL( '../css/admin-styles.css', __FILE__ ) ); |
|
206
|
|
|
} |
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
|
|
210
|
|
|
/** |
|
211
|
|
|
* Gets all the admin page options (not meta & customizer) and loads them from the database into |
|
212
|
|
|
* a class variable. This is needed because all our admin page options are contained in a single entry. |
|
213
|
|
|
* |
|
214
|
|
|
* @since 1.9 |
|
215
|
|
|
* |
|
216
|
|
|
* @return array All admin options currently in the instance |
|
217
|
|
|
*/ |
|
218
|
|
|
protected function getInternalAdminOptions() { |
|
219
|
|
|
if ( empty( $this->adminOptions ) ) { |
|
220
|
|
|
$this->adminOptions = array(); |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
if ( ! empty( $this->adminOptions ) ) { |
|
224
|
|
|
return $this->adminOptions; |
|
225
|
|
|
} |
|
226
|
|
|
|
|
227
|
|
|
// Check if we have options saved already. |
|
228
|
|
|
$currentOptions = get_option( $this->optionNamespace . '_options' ); |
|
229
|
|
|
|
|
230
|
|
|
// First time run, this action hook can be used to trigger something. |
|
231
|
|
|
if ( false === $currentOptions ) { |
|
232
|
|
|
do_action( 'tf_init_no_options_' . $this->optionNamespace ); |
|
233
|
|
|
} |
|
234
|
|
|
|
|
235
|
|
|
// Put all the available options in our global variable for future checking. |
|
236
|
|
|
if ( ! empty( $currentOptions ) && ! count( $this->adminOptions ) ) { |
|
237
|
|
|
$this->adminOptions = unserialize( $currentOptions ); |
|
238
|
|
|
} |
|
239
|
|
|
|
|
240
|
|
|
if ( empty( $this->adminOptions ) ) { |
|
241
|
|
|
$this->adminOptions = array(); |
|
242
|
|
|
} |
|
243
|
|
|
|
|
244
|
|
|
return $this->adminOptions; |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
|
|
248
|
|
|
/** |
|
249
|
|
|
* Gets the admin page option that's loaded into the instance, used by the option class |
|
250
|
|
|
* |
|
251
|
|
|
* @since 1.9 |
|
252
|
|
|
* |
|
253
|
|
|
* @param string $optionName The ID of the option (not namespaced). |
|
254
|
|
|
* @param mixed $defaultValue The default value to return if the option isn't available yet. |
|
255
|
|
|
* |
|
256
|
|
|
* @return mixed The option value |
|
257
|
|
|
* |
|
258
|
|
|
* @see TitanFrameworkOption->getValue() |
|
259
|
|
|
*/ |
|
260
|
|
|
public function getInternalAdminPageOption( $optionName, $defaultValue = false ) { |
|
261
|
|
|
|
|
262
|
|
|
// Run this first to ensure that adminOptions carries all our admin page options. |
|
263
|
|
|
$this->getInternalAdminOptions(); |
|
264
|
|
|
|
|
265
|
|
|
if ( array_key_exists( $optionName, $this->adminOptions ) ) { |
|
266
|
|
|
return $this->adminOptions[ $optionName ]; |
|
267
|
|
|
} else { |
|
268
|
|
|
return $defaultValue; |
|
269
|
|
|
} |
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
|
|
273
|
|
|
/** |
|
274
|
|
|
* Sets the admin page option that's loaded into the instance, used by the option class. |
|
275
|
|
|
* Doesn't perform a save, only sets the value in the class variable. |
|
276
|
|
|
* |
|
277
|
|
|
* @since 1.9 |
|
278
|
|
|
* |
|
279
|
|
|
* @param string $optionName The ID of the option (not namespaced). |
|
280
|
|
|
* @param mixed $value The value to set. |
|
281
|
|
|
* |
|
282
|
|
|
* @return bool Always returns true |
|
283
|
|
|
* |
|
284
|
|
|
* @see TitanFrameworkOption->setValue() |
|
285
|
|
|
*/ |
|
286
|
|
|
public function setInternalAdminPageOption( $optionName, $value ) { |
|
287
|
|
|
|
|
288
|
|
|
// Run this first to ensure that adminOptions carries all our admin page options. |
|
289
|
|
|
$this->getInternalAdminOptions(); |
|
290
|
|
|
|
|
291
|
|
|
$this->adminOptions[ $optionName ] = $value; |
|
292
|
|
|
return true; |
|
293
|
|
|
} |
|
294
|
|
|
|
|
295
|
|
|
|
|
296
|
|
|
/** |
|
297
|
|
|
* Saves all the admin (not meta & customizer) options which are currently loaded into this instance |
|
298
|
|
|
* |
|
299
|
|
|
* @since 1.0 |
|
300
|
|
|
* |
|
301
|
|
|
* @return array All admin options currently in the instance |
|
302
|
|
|
*/ |
|
303
|
|
|
public function saveInternalAdminPageOptions() { |
|
304
|
|
|
|
|
305
|
|
|
// Run this first to ensure that adminOptions carries all our admin page options. |
|
306
|
|
|
$this->getInternalAdminOptions(); |
|
307
|
|
|
|
|
308
|
|
|
update_option( $this->optionNamespace . '_options', serialize( $this->adminOptions ) ); |
|
309
|
|
|
do_action( 'tf_save_options_' . $this->optionNamespace ); |
|
310
|
|
|
return $this->adminOptions; |
|
311
|
|
|
} |
|
312
|
|
|
|
|
313
|
|
|
|
|
314
|
|
|
/** |
|
315
|
|
|
* Create a admin page |
|
316
|
|
|
* |
|
317
|
|
|
* @deprecated 1.9 Use createContainer() with 'type' => 'admin-page' or createAdminPanel() instead. |
|
318
|
|
|
* @since 1.0 |
|
319
|
|
|
* |
|
320
|
|
|
* @param array $settings The arguments for creating the admin page. |
|
321
|
|
|
* |
|
322
|
|
|
* @return TitanFrameworkAdminPage The created admin page |
|
323
|
|
|
*/ |
|
324
|
|
|
public function createAdminPanel( $settings ) { |
|
325
|
|
|
// _deprecated_function( __FUNCTION__, '1.9', 'createAdminPage' ); |
|
|
|
|
|
|
326
|
|
|
return $this->createAdminPage( $settings ); |
|
327
|
|
|
} |
|
328
|
|
|
|
|
329
|
|
|
|
|
330
|
|
|
/** |
|
331
|
|
|
* Create a admin page |
|
332
|
|
|
* |
|
333
|
|
|
* @since 1.0 |
|
334
|
|
|
* |
|
335
|
|
|
* @param array $settings The arguments for creating the admin page. |
|
336
|
|
|
* |
|
337
|
|
|
* @return TitanFrameworkAdminPage The created admin page |
|
338
|
|
|
*/ |
|
339
|
|
|
public function createAdminPage( $settings ) { |
|
340
|
|
|
$settings['type'] = 'admin-page'; |
|
341
|
|
|
$container = $this->createContainer( $settings ); |
|
|
|
|
|
|
342
|
|
|
do_action( 'tf_admin_panel_created_' . $this->optionNamespace, $container ); |
|
343
|
|
|
return $container; |
|
344
|
|
|
} |
|
345
|
|
|
|
|
346
|
|
|
|
|
347
|
|
|
/** |
|
348
|
|
|
* Create a meta box |
|
349
|
|
|
* |
|
350
|
|
|
* @since 1.0 |
|
351
|
|
|
* |
|
352
|
|
|
* @param array $settings The arguments for creating the meta box. |
|
353
|
|
|
* |
|
354
|
|
|
* @return TitanFrameworkMetaBox The created meta box |
|
355
|
|
|
*/ |
|
356
|
|
|
public function createMetaBox( $settings ) { |
|
357
|
|
|
$settings['type'] = 'meta-box'; |
|
358
|
|
|
return $this->createContainer( $settings ); |
|
|
|
|
|
|
359
|
|
|
} |
|
360
|
|
|
|
|
361
|
|
|
|
|
362
|
|
|
/** |
|
363
|
|
|
* Create a customizer section |
|
364
|
|
|
* |
|
365
|
|
|
* @deprecated 1.9 Use createContainer() with 'type' => 'customizer' or createCustomizer instead. |
|
366
|
|
|
* @since 1.0 |
|
367
|
|
|
* |
|
368
|
|
|
* @param array $settings The arguments for creating a customizer section. |
|
369
|
|
|
* |
|
370
|
|
|
* @return TitanFrameworkCustomizer The created section |
|
371
|
|
|
*/ |
|
372
|
|
|
public function createThemeCustomizerSection( $settings ) { |
|
373
|
|
|
// _deprecated_function( __FUNCTION__, '1.9', 'createContainer' ); |
|
|
|
|
|
|
374
|
|
|
return $this->createCustomizer( $settings ); |
|
375
|
|
|
} |
|
376
|
|
|
|
|
377
|
|
|
|
|
378
|
|
|
/** |
|
379
|
|
|
* Create a customizer section |
|
380
|
|
|
* |
|
381
|
|
|
* @since 1.9 |
|
382
|
|
|
* |
|
383
|
|
|
* @param array $settings The arguments for creating a customizer section. |
|
384
|
|
|
* |
|
385
|
|
|
* @return TitanFrameworkCustomizer The created section |
|
386
|
|
|
*/ |
|
387
|
|
|
public function createCustomizer( $settings ) { |
|
388
|
|
|
$settings['type'] = 'customizer'; |
|
389
|
|
|
$container = $this->createContainer( $settings ); |
|
|
|
|
|
|
390
|
|
|
do_action( 'tf_theme_customizer_created_' . $this->optionNamespace, $container ); |
|
391
|
|
|
return $container; |
|
392
|
|
|
} |
|
393
|
|
|
|
|
394
|
|
|
|
|
395
|
|
|
/** |
|
396
|
|
|
* Creates a container (e.g. admin page, meta box, customizer section) depending |
|
397
|
|
|
* on the `type` parameter given in $settings |
|
398
|
|
|
* |
|
399
|
|
|
* @since 1.9 |
|
400
|
|
|
* |
|
401
|
|
|
* @param array $settings The arguments for creating the container. |
|
402
|
|
|
* |
|
403
|
|
|
* @return TitanFrameworkCustomizer|TitanFrameworkAdminPage|TitanFrameworkMetaBox The created container |
|
404
|
|
|
*/ |
|
405
|
|
|
public function createContainer( $settings ) { |
|
406
|
|
|
if ( empty( $settings['type'] ) ) { |
|
407
|
|
|
self::displayFrameworkError( sprintf( __( '%s needs a %s parameter.', TF_I18NDOMAIN ), '<code>' . __FUNCTION__ . '</code>', '<code>type</code>' ) ); |
|
408
|
|
|
return; |
|
409
|
|
|
} |
|
410
|
|
|
|
|
411
|
|
|
$type = strtolower( $settings['type'] ); |
|
412
|
|
|
$class = 'TitanFramework' . str_replace( ' ', '', ucfirst( str_replace( '-', ' ', $settings['type'] ) ) ); |
|
413
|
|
|
$action = str_replace( '-', '_', $type ); |
|
414
|
|
|
$container = false; |
|
415
|
|
|
|
|
416
|
|
|
if ( ! class_exists( $class ) ) { |
|
417
|
|
|
self::displayFrameworkError( sprintf( __( 'Container of type %s, does not exist.', TF_I18NDOMAIN ), '<code>' . $settings['type'] . '</code>' ) ); |
|
418
|
|
|
return; |
|
419
|
|
|
} |
|
420
|
|
|
|
|
421
|
|
|
// Create the container object. |
|
422
|
|
|
$container = new $class( $settings, $this ); |
|
423
|
|
|
if ( empty( $this->mainContainers[ $type ] ) ) { |
|
424
|
|
|
$this->mainContainers[ $type ] = array(); |
|
425
|
|
|
} |
|
426
|
|
|
|
|
427
|
|
|
$this->mainContainers[ $type ][] = $container; |
|
428
|
|
|
|
|
429
|
|
|
do_action( 'tf_' . $action . '_created_' . $this->optionNamespace, $container ); |
|
430
|
|
|
|
|
431
|
|
|
return $container; |
|
432
|
|
|
} |
|
433
|
|
|
|
|
434
|
|
|
|
|
435
|
|
|
/** |
|
436
|
|
|
* A function available ONLY to CHILD themes to stop the creation of options |
|
437
|
|
|
* created by the PARENT theme. |
|
438
|
|
|
* |
|
439
|
|
|
* @since 1.2.1 |
|
440
|
|
|
* @access public |
|
441
|
|
|
* |
|
442
|
|
|
* @param string $optionName The id of the option to remove / stop from being created. |
|
443
|
|
|
* |
|
444
|
|
|
* @return void |
|
445
|
|
|
*/ |
|
446
|
|
|
public function removeOption( $optionName ) { |
|
447
|
|
|
$this->optionsToRemove[] = $optionName; |
|
448
|
|
|
} |
|
449
|
|
|
|
|
450
|
|
|
|
|
451
|
|
|
/** |
|
452
|
|
|
* Hook to the tf_create_option_continue filter, to check whether or not to continue |
|
453
|
|
|
* adding an option (if the option id was used in $titan->removeOption). |
|
454
|
|
|
* |
|
455
|
|
|
* @since 1.2.1 |
|
456
|
|
|
* @access public |
|
457
|
|
|
* |
|
458
|
|
|
* @param boolean $continueCreating If true, the option will be created. |
|
459
|
|
|
* @param array $optionSettings The settings for the option to be created. |
|
460
|
|
|
* |
|
461
|
|
|
* @return boolean If true, continue with creating the option. False to stop it.. |
|
462
|
|
|
*/ |
|
463
|
|
|
public function removeChildThemeOptions( $continueCreating, $optionSettings ) { |
|
464
|
|
|
if ( ! count( $this->optionsToRemove ) ) { |
|
465
|
|
|
return $continueCreating; |
|
466
|
|
|
} |
|
467
|
|
|
if ( empty( $optionSettings['id'] ) ) { |
|
468
|
|
|
return $continueCreating; |
|
469
|
|
|
} |
|
470
|
|
|
if ( in_array( $optionSettings['id'], $this->optionsToRemove ) ) { |
|
471
|
|
|
return false; |
|
472
|
|
|
} |
|
473
|
|
|
return $continueCreating; |
|
474
|
|
|
} |
|
475
|
|
|
|
|
476
|
|
|
|
|
477
|
|
|
/** |
|
478
|
|
|
* Get an option |
|
479
|
|
|
* |
|
480
|
|
|
* @since 1.0 |
|
481
|
|
|
* |
|
482
|
|
|
* @param string $optionName The name of the option. |
|
483
|
|
|
* @param int $postID The post ID if this is a meta option. |
|
484
|
|
|
* |
|
485
|
|
|
* @return mixed The option value |
|
486
|
|
|
*/ |
|
487
|
|
|
public function getOption( $optionName, $postID = null ) { |
|
488
|
|
|
$value = false; |
|
489
|
|
|
|
|
490
|
|
|
// Get the option value. |
|
491
|
|
|
if ( array_key_exists( $optionName, $this->optionsUsed ) ) { |
|
492
|
|
|
$option = $this->optionsUsed[ $optionName ]; |
|
493
|
|
|
$value = $option->getValue( $postID ); |
|
494
|
|
|
} |
|
495
|
|
|
|
|
496
|
|
|
return apply_filters( 'tf_get_option_' . $this->optionNamespace, $value, $optionName, $postID ); |
|
497
|
|
|
} |
|
498
|
|
|
|
|
499
|
|
|
|
|
500
|
|
|
/** |
|
501
|
|
|
* Gets a set of options. Pass an associative array containing the option names as keys and |
|
502
|
|
|
* the values you want to be retained if the option names are not implemented. |
|
503
|
|
|
* |
|
504
|
|
|
* @since 1.9 |
|
505
|
|
|
* |
|
506
|
|
|
* @param array $optionArray An associative array containing option names as keys. |
|
507
|
|
|
* @param int $postID The post ID if this is a meta option. |
|
508
|
|
|
* |
|
509
|
|
|
* @return array An array containing the values saved. |
|
510
|
|
|
* |
|
511
|
|
|
* @see $this->getOption() |
|
512
|
|
|
*/ |
|
513
|
|
|
public function getOptions( $optionArray, $postID = null ) { |
|
514
|
|
|
foreach ( $optionArray as $optionName => $originalValue ) { |
|
515
|
|
|
if ( array_key_exists( $optionName, $this->optionsUsed ) ) { |
|
516
|
|
|
$optionArray[ $optionName ] = $this->getOption( $optionName, $postID ); |
|
517
|
|
|
} |
|
518
|
|
|
} |
|
519
|
|
|
return apply_filters( 'tf_get_options_' . $this->optionNamespace, $optionArray, $postID ); |
|
520
|
|
|
} |
|
521
|
|
|
|
|
522
|
|
|
|
|
523
|
|
|
/** |
|
524
|
|
|
* Sets an option |
|
525
|
|
|
* |
|
526
|
|
|
* @since 1.0 |
|
527
|
|
|
* |
|
528
|
|
|
* @param string $optionName The name of the option to save. |
|
529
|
|
|
* @param mixed $value The value of the option. |
|
530
|
|
|
* @param int $postID The ID of the parent post if this is a meta box option. |
|
531
|
|
|
* |
|
532
|
|
|
* @return boolean Always returns true |
|
533
|
|
|
*/ |
|
534
|
|
|
public function setOption( $optionName, $value, $postID = null ) { |
|
535
|
|
|
|
|
536
|
|
|
// Get the option value. |
|
537
|
|
|
if ( array_key_exists( $optionName, $this->optionsUsed ) ) { |
|
538
|
|
|
$option = $this->optionsUsed[ $optionName ]; |
|
539
|
|
|
$option->setValue( $value, $postID ); |
|
540
|
|
|
} |
|
541
|
|
|
|
|
542
|
|
|
do_action( 'tf_set_option_' . $this->optionNamespace, $optionName, $value, $postID ); |
|
543
|
|
|
|
|
544
|
|
|
return true; |
|
545
|
|
|
} |
|
546
|
|
|
|
|
547
|
|
|
|
|
548
|
|
|
/** |
|
549
|
|
|
* Deletes ALL the options for the namespace. Even deletes all meta found in all posts. |
|
550
|
|
|
* Mainly used for unit tests |
|
551
|
|
|
* |
|
552
|
|
|
* @since 1.9 |
|
553
|
|
|
* |
|
554
|
|
|
* @return void |
|
555
|
|
|
*/ |
|
556
|
|
|
public function deleteAllOptions() { |
|
557
|
|
|
|
|
558
|
|
|
// Delete all admin options. |
|
559
|
|
|
delete_option( $this->optionNamespace . '_options' ); |
|
560
|
|
|
$this->adminOptions = array(); |
|
561
|
|
|
|
|
562
|
|
|
// Delete all meta options. |
|
563
|
|
|
global $wpdb; |
|
|
|
|
|
|
564
|
|
|
$allPosts = $wpdb->get_results( 'SELECT ID FROM ' . $wpdb->posts, ARRAY_A ); |
|
565
|
|
|
if ( ! empty( $allPosts ) ) { |
|
566
|
|
|
foreach ( $allPosts as $row ) { |
|
567
|
|
|
$allMeta = get_post_meta( $row['ID'] ); |
|
568
|
|
|
|
|
569
|
|
|
// Only remove meta data that the framework created. |
|
570
|
|
|
foreach ( $allMeta as $metaName => $dummy ) { |
|
571
|
|
|
if ( stripos( $metaName, $this->optionNamespace . '_' ) === 0 ) { |
|
572
|
|
|
delete_post_meta( $row['ID'], $metaName ); |
|
573
|
|
|
} |
|
574
|
|
|
} |
|
575
|
|
|
} |
|
576
|
|
|
} |
|
577
|
|
|
|
|
578
|
|
|
// Delete all theme mods. |
|
579
|
|
|
$allThemeMods = get_theme_mods(); |
|
580
|
|
|
if ( ! empty( $allThemeMods ) && is_array( $allThemeMods ) ) { |
|
581
|
|
|
foreach ( $allThemeMods as $optionName => $dummy ) { |
|
582
|
|
|
|
|
583
|
|
|
// Only remove theme mods that the framework created. |
|
584
|
|
|
if ( stripos( $optionName, $this->optionNamespace . '_' ) === 0 ) { |
|
585
|
|
|
remove_theme_mod( $optionName ); |
|
586
|
|
|
} |
|
587
|
|
|
} |
|
588
|
|
|
} |
|
589
|
|
|
} |
|
590
|
|
|
|
|
591
|
|
|
|
|
592
|
|
|
/** |
|
593
|
|
|
* Generates style rules which can use options as their values |
|
594
|
|
|
* |
|
595
|
|
|
* @since 1.0 |
|
596
|
|
|
* |
|
597
|
|
|
* @param string $CSSString The styles to render. |
|
598
|
|
|
* |
|
599
|
|
|
* @return void |
|
600
|
|
|
*/ |
|
601
|
|
|
public function createCSS( $CSSString ) { |
|
602
|
|
|
$this->cssInstance->addCSS( $CSSString ); |
|
603
|
|
|
} |
|
604
|
|
|
|
|
605
|
|
|
|
|
606
|
|
|
/** |
|
607
|
|
|
* Displays an error notice |
|
608
|
|
|
* |
|
609
|
|
|
* @since 1.0 |
|
610
|
|
|
* |
|
611
|
|
|
* @param string $message The error message to display. |
|
612
|
|
|
* @param array|object $errorObject The object to dump inside the error message. |
|
613
|
|
|
* |
|
614
|
|
|
* @return void |
|
615
|
|
|
*/ |
|
616
|
|
|
public static function displayFrameworkError( $message, $errorObject = null ) { |
|
617
|
|
|
// Clean up the debug object for display. e.g. If this is a setting, we can have lots of blank values. |
|
618
|
|
|
if ( is_array( $errorObject ) ) { |
|
619
|
|
|
foreach ( $errorObject as $key => $val ) { |
|
620
|
|
|
if ( '' === $val ) { |
|
621
|
|
|
unset( $errorObject[ $key ] ); |
|
622
|
|
|
} |
|
623
|
|
|
} |
|
624
|
|
|
} |
|
625
|
|
|
|
|
626
|
|
|
// Display an error message. |
|
627
|
|
|
?> |
|
628
|
|
|
<div style='margin: 20px; text-align: center;'><strong><?php echo TF_NAME ?> Error:</strong> |
|
629
|
|
|
<?php echo $message ?> |
|
630
|
|
|
<?php |
|
631
|
|
|
if ( ! empty( $errorObject ) ) : |
|
632
|
|
|
?> |
|
633
|
|
|
<pre><code style="display: inline-block; padding: 10px"><?php echo print_r( $errorObject, true ) ?></code></pre> |
|
634
|
|
|
<?php |
|
635
|
|
|
endif; |
|
636
|
|
|
?> |
|
637
|
|
|
</div> |
|
638
|
|
|
<?php |
|
639
|
|
|
} |
|
640
|
|
|
|
|
641
|
|
|
|
|
642
|
|
|
/** |
|
643
|
|
|
* Acts the same way as plugins_url( 'script', __FILE__ ) but returns then correct url |
|
644
|
|
|
* when called from inside a theme. |
|
645
|
|
|
* |
|
646
|
|
|
* @since 1.1.2 |
|
647
|
|
|
* |
|
648
|
|
|
* @param string $script the script to get the url to, relative to $file. |
|
649
|
|
|
* @param string $file the current file, should be __FILE__. |
|
650
|
|
|
* |
|
651
|
|
|
* @return string the url to $script |
|
652
|
|
|
*/ |
|
653
|
|
|
public static function getURL( $script, $file ) { |
|
654
|
|
|
$parentTheme = trailingslashit( get_template_directory() ); |
|
655
|
|
|
$childTheme = trailingslashit( get_stylesheet_directory() ); |
|
656
|
|
|
$plugin = trailingslashit( dirname( $file ) ); |
|
657
|
|
|
|
|
658
|
|
|
// Windows sometimes mixes up forward and back slashes, ensure forward slash for correct URL output. |
|
659
|
|
|
$parentTheme = str_replace( '\\', '/', $parentTheme ); |
|
660
|
|
|
$childTheme = str_replace( '\\', '/', $childTheme ); |
|
661
|
|
|
$file = str_replace( '\\', '/', $file ); |
|
662
|
|
|
|
|
663
|
|
|
$url = ''; |
|
664
|
|
|
|
|
665
|
|
|
// Framework is in a parent theme. |
|
666
|
|
|
if ( stripos( $file, $parentTheme ) !== false ) { |
|
667
|
|
|
$dir = trailingslashit( dirname( str_replace( $parentTheme, '', $file ) ) ); |
|
668
|
|
|
if ( './' == $dir ) { |
|
669
|
|
|
$dir = ''; |
|
670
|
|
|
} |
|
671
|
|
|
$url = trailingslashit( get_template_directory_uri() ) . $dir . $script; |
|
672
|
|
|
|
|
673
|
|
|
} else if ( stripos( $file, $childTheme ) !== false ) { |
|
674
|
|
|
// Framework is in a child theme. |
|
675
|
|
|
$dir = trailingslashit( dirname( str_replace( $childTheme, '', $file ) ) ); |
|
676
|
|
|
if ( './' == $dir ) { |
|
677
|
|
|
$dir = ''; |
|
678
|
|
|
} |
|
679
|
|
|
$url = trailingslashit( get_stylesheet_directory_uri() ) . $dir . $script; |
|
680
|
|
|
|
|
681
|
|
|
} else { |
|
682
|
|
|
// Framework is a or in a plugin. |
|
683
|
|
|
$url = plugins_url( $script, $file ); |
|
684
|
|
|
} |
|
685
|
|
|
|
|
686
|
|
|
// Replace /foo/../ with '/'. |
|
687
|
|
|
$url = preg_replace( '/\/(?!\.\.)[^\/]+\/\.\.\//', '/', $url ); |
|
688
|
|
|
|
|
689
|
|
|
return $url; |
|
690
|
|
|
} |
|
691
|
|
|
|
|
692
|
|
|
|
|
693
|
|
|
/** |
|
694
|
|
|
* Sets a value in the $setting class variable |
|
695
|
|
|
* |
|
696
|
|
|
* @since 1.6 |
|
697
|
|
|
* |
|
698
|
|
|
* @param string $setting The name of the setting. |
|
699
|
|
|
* @param string $value The value to set. |
|
700
|
|
|
* |
|
701
|
|
|
* @return void |
|
702
|
|
|
*/ |
|
703
|
|
|
public function set( $setting, $value ) { |
|
704
|
|
|
$oldValue = $this->settings[ $setting ]; |
|
705
|
|
|
$this->settings[ $setting ] = $value; |
|
706
|
|
|
|
|
707
|
|
|
do_action( 'tf_setting_' . $setting . '_changed_' . $this->optionNamespace, $value, $oldValue ); |
|
708
|
|
|
} |
|
709
|
|
|
|
|
710
|
|
|
|
|
711
|
|
|
/** |
|
712
|
|
|
* Gets the CSS generated |
|
713
|
|
|
* |
|
714
|
|
|
* @since 1.6 |
|
715
|
|
|
* |
|
716
|
|
|
* @return string The generated CSS |
|
717
|
|
|
*/ |
|
718
|
|
|
public function generateCSS() { |
|
719
|
|
|
return $this->cssInstance->generateCSS(); |
|
720
|
|
|
} |
|
721
|
|
|
|
|
722
|
|
|
|
|
723
|
|
|
|
|
724
|
|
|
/** |
|
725
|
|
|
* Adds a 'tf_save_option_{namespace}_{optionID}' filter to all Customizer options |
|
726
|
|
|
* which are just about to be saved |
|
727
|
|
|
* |
|
728
|
|
|
* This uses the `pre_update_option` filter to check all the options being saved if it's |
|
729
|
|
|
* a theme_mod option. It further checks whether these are Titan customizer options, |
|
730
|
|
|
* then attaches the new hook into those. |
|
731
|
|
|
* |
|
732
|
|
|
* @since 1.8 |
|
733
|
|
|
* |
|
734
|
|
|
* @param mixed $value The value to be saved in the options. |
|
735
|
|
|
* @param string $optionName The option name. |
|
736
|
|
|
* @param mixed $oldValue The previously stored value. |
|
737
|
|
|
* |
|
738
|
|
|
* @return mixed The modified value to save |
|
739
|
|
|
* |
|
740
|
|
|
* @see pre_update_option filter |
|
741
|
|
|
*/ |
|
742
|
|
|
public function addCustomizerSaveFilter( $value, $optionName, $oldValue ) { |
|
|
|
|
|
|
743
|
|
|
|
|
744
|
|
|
$theme = get_option( 'stylesheet' ); |
|
745
|
|
|
|
|
746
|
|
|
// Intercept theme mods only. |
|
747
|
|
|
if ( strpos( $optionName, 'theme_mods_' . $theme ) !== 0 ) { |
|
748
|
|
|
return $value; |
|
749
|
|
|
} |
|
750
|
|
|
|
|
751
|
|
|
// We expect theme mods to be an array. |
|
752
|
|
|
if ( ! is_array( $value ) ) { |
|
753
|
|
|
return $value; |
|
754
|
|
|
} |
|
755
|
|
|
|
|
756
|
|
|
// Checks whether a Titan customizer is in place. |
|
757
|
|
|
$customizerUsed = false; |
|
758
|
|
|
|
|
759
|
|
|
// Go through all our customizer options and filter them for saving. |
|
760
|
|
|
$optionIDs = array(); |
|
761
|
|
|
if ( ! empty( $this->mainContainers['customizer'] ) ) { |
|
762
|
|
|
foreach ( $this->mainContainers['customizer'] as $customizer ) { |
|
763
|
|
|
foreach ( $customizer->options as $option ) { |
|
764
|
|
|
if ( ! empty( $option->settings['id'] ) ) { |
|
765
|
|
|
$optionID = $option->settings['id']; |
|
766
|
|
|
$themeModName = $this->optionNamespace . '_' . $option->settings['id']; |
|
767
|
|
|
|
|
768
|
|
|
if ( ! array_key_exists( $themeModName, $value ) ) { |
|
769
|
|
|
continue; |
|
770
|
|
|
} |
|
771
|
|
|
|
|
772
|
|
|
$customizerUsed = true; |
|
773
|
|
|
|
|
774
|
|
|
// Try and unserialize if possible. |
|
775
|
|
|
$tempValue = $value[ $themeModName ]; |
|
776
|
|
|
if ( is_serialized( $tempValue ) ) { |
|
777
|
|
|
$tempValue = unserialize( $tempValue ); |
|
778
|
|
|
} |
|
779
|
|
|
|
|
780
|
|
|
// Hook 'tf_save_option_{namespace}'. |
|
781
|
|
|
$newValue = apply_filters( 'tf_save_option_' . $this->optionNamespace, $tempValue, $option->settings['id'] ); |
|
782
|
|
|
|
|
783
|
|
|
// Hook 'tf_save_option_{namespace}_{optionID}'. |
|
784
|
|
|
$newValue = apply_filters( 'tf_save_option_' . $themeModName, $tempValue ); |
|
785
|
|
|
|
|
786
|
|
|
// We mainly check for equality here so that we won't have to serialize IF the value wasn't touched anyway. |
|
787
|
|
|
if ( $newValue != $tempValue ) { |
|
788
|
|
|
if ( is_array( $newValue ) ) { |
|
789
|
|
|
$newValue = serialize( $newValue ); |
|
790
|
|
|
} |
|
791
|
|
|
|
|
792
|
|
|
$value[ $themeModName ] = $newValue; |
|
793
|
|
|
} |
|
794
|
|
|
} |
|
795
|
|
|
} |
|
796
|
|
|
} |
|
797
|
|
|
} |
|
798
|
|
|
|
|
799
|
|
|
if ( $customizerUsed ) { |
|
800
|
|
|
/** This action is documented in class-admin-page.php */ |
|
801
|
|
|
$namespace = $this->optionNamespace; |
|
802
|
|
|
do_action( "tf_pre_save_options_{$namespace}", $this->mainContainers['customizer'] ); |
|
803
|
|
|
} |
|
804
|
|
|
|
|
805
|
|
|
return $value; |
|
806
|
|
|
} |
|
807
|
|
|
} |
|
808
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.