PluginProbe
CoolClock / 4.3.9
CoolClock v4.3.9
4.3.9 4.3.8 trunk 0.1 2.0 2.9.8 3.0 3.1 3.2 3.3 4.0 4.1 4.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7
← All changes | includes/class-coolclock.php +61 -75 4.3.44.3.9 View file →
@@ -5,22 +5,20 @@
5 5 */
6 6
7 7 class CoolClock {
8 8
9 - static $plugin_version;
9 + static ?string $plugin_version;
10 10
11 11 static $script_version = '3.2.2';
12 12
13 - private static $plugin_url;
13 + private static ?string $plugin_url;
14 14
15 - private static $plugin_basename;
15 + private static ?string $plugin_basename;
16 16
17 17 private static $min = '.min';
18 18
19 19 static $add_script = false;
20 20
21 - private static $done_excanvas = false;
22 -
23 21 static $defaults = array(
24 22 'skin' => 'swissrail',
25 23 'radius' => 100,
26 24 'noseconds' => false, // true to hide second hand
@@ -74,13 +72,16 @@
74 72 'strong' => array(),
75 73 );
76 74
77 75 /**
78 - * INIT
76 + * Constructor
77 + *
78 + * @since 4.3
79 + *
80 + * @param string $plugin_file Plugin file path
81 + * @param string $plugin_version Plugin version
79 82 */
80 -
81 - public function __construct( $plugin_file, $plugin_version )
82 - {
83 + public function __construct( string $plugin_file, string $plugin_version ) {
83 84 // VARS
84 85 self::$plugin_url = plugins_url( '/', $plugin_file );
85 86 self::$plugin_basename = plugin_basename( $plugin_file );
86 87 self::$plugin_version = $plugin_version;
@@ -88,11 +89,8 @@
88 89 if ( defined('WP_DEBUG') && WP_DEBUG ) {
89 90 self::$min = '';
90 91 }
91 92
92 - // text domain
93 - add_action( 'plugins_loaded', array( __CLASS__, 'textdomain' ) );
94 -
95 93 // widgets
96 94 add_action( 'widgets_init', array( __CLASS__, 'register_widget' ) );
97 95
98 96 // enqueue scripts but only if shortcode or widget has been used
@@ -115,12 +113,8 @@
115 113 add_filter( 'no_texturize_shortcodes', array( 'CoolClock_Shortcode', 'no_wptexturize') );
116 114 }
117 115
118 116 /**
119 - * METHODS
120 - */
121 -
122 - /**
123 117 * Build canvas output
124 118 *
125 119 * @since 2.0
126 120 *
@@ -127,11 +121,9 @@
127 121 * @param array $atts Array of sanitized attributes
128 122 *
129 123 * @return string Canvas tag
130 124 */
131 -
132 - public static function canvas( $atts )
133 - {
125 + public static function canvas( $atts ) {
134 126 /**
135 127 * ARRAY VALUES
136 128 * skin @param string Skin ID. Must be one of these: 'swissRail' (default skin), 'chunkySwiss', 'chunkySwissOnBlack', 'fancy', 'machine', 'simonbaird_com', 'classic', 'modern', 'simple', 'securephp', 'Tes2', 'Lev', 'Sand', 'Sun', 'Tor', 'Cold', 'Babosa', 'Tumb', 'Stone', 'Disc', 'watermelon' or 'mister'.
137 129 * If the Advanced extension is activated, there is also 'minimal' available.
@@ -178,19 +170,12 @@
178 170
179 171 // build output
180 172 $output = '';
181 173
182 - if ( ! self::$done_excanvas ){
183 - $output .= '<!--[if lte IE 8]>';
184 - $output .= '<script type="text/javascript" src="'. self::$plugin_url . 'js/excanvas' . self::$min . '.js"></script>';
185 - $output .= '<![endif]-->' . PHP_EOL;
186 - self::$done_excanvas = true;
187 - }
188 -
189 174 $styles = apply_filters( 'coolclock_canvas_styles', array(), $atts, $defaults );
190 175
191 176 // canvas parameters
192 - $output .= '<canvas class="' . implode(':',$fields) . '"' . CoolClock::inline_style( $styles ) . '></canvas>';
177 + $output .= '<canvas class="' . implode( ':', array_map('esc_attr', $fields) ) . '"' . CoolClock::inline_style( $styles ) . '></canvas>';
193 178
194 179 // sub text
195 180 $subtext = ( isset( $atts['subtext'] ) ) ? $atts['subtext'] : $defaults['subtext'];
196 181 if ( !empty( $subtext ) )
@@ -207,11 +192,9 @@
207 192 * @param array $styles array with style parameters and their values
208 193 *
209 194 * @return string inline style attribute style="..." complete with leading space
210 195 */
211 -
212 - public static function inline_style( $styles )
213 - {
196 + public static function inline_style( $styles ) {
214 197 $style_arr = array();
215 198
216 199 foreach ( $styles as $key => $value ) {
217 200 $style_arr[] = $key . ':' . $value;
@@ -231,38 +214,39 @@
231 214 * @param string $skin_parms skin parameters, preferably in JSON format
232 215 *
233 216 * @return string either found matching skin name or 'invalid_or_missing_skin' on failure
234 217 */
218 + public static function parse_skin( $skin_name, $skin_parms = '' ) {
219 + $skin = strtolower( $skin_name ); // user input, sanitize!
220 + $skin = preg_replace( '/[^a-z0-9_-]/', '', $skin );
235 221
236 - public static function parse_skin( $skin_name, $skin_parms = '' )
237 - {
238 - $skin = strtolower($skin_name);
239 - $skin_array = array();
240 -
241 222 // check for empty or default skin first
242 - if ( empty($skin) || $skin == self::$defaults['skin'] )
223 + if ( empty($skin) || $skin === self::$defaults['skin'] ) {
243 224 // return the matching skin name
244 225 return self::$defaults['skin'];
226 + }
245 227
246 228 // short-circuit if skin name is already in the config array
247 - if ( array_key_exists( $skin, self::$skins_config ) )
229 + if ( array_key_exists( $skin, self::$skins_config ) ) {
248 230 // return the matching skin name
249 231 return $skin;
232 + }
250 233
251 234 // search in the more_skins and advanced_skins arrays
252 - $all_skins = self::get_all_skins();
235 + $all_skins = self::get_all_skins();
236 + $skin_array = array();
237 +
253 238 if ( array_key_exists( $skin, $all_skins ) ) {
254 239 // fetch parameters from skins array
255 240 $skin_array = is_array( $all_skins[$skin] ) ? $all_skins[$skin] : self::skin_array( $all_skins[$skin] );
256 - }
257 - // try to build a skin config from passed parameters
258 - else {
259 - // fetch parameters from custom skin user input
241 + } else {
242 + // try to build a skin config from passed parameters (user input, sanitize!)
260 243 $skin_array = self::skin_array( $skin_parms );
261 244
262 - if ( empty( $skin_array ) )
245 + if ( empty( $skin_array ) ) {
263 246 // set faulty skin name
264 247 return 'no_skin_found';
248 + }
265 249 }
266 250
267 251 // add found skin parameters to the config array
268 252 self::$skins_config[$skin] = $skin_array;
@@ -270,21 +254,29 @@
270 254 // return the matching skin name
271 255 return $skin;
272 256 }
273 257
258 + /**
259 + * Get all available skins
260 + *
261 + * @since 3.2.0
262 + *
263 + * @return array array of all skins
264 + */
274 265 public static function get_all_skins() {
275 266
276 267 if ( empty( self::$more_skins_config ) ) {
277 -
278 - include COOLCLOCK_DIR . 'includes/moreskins.php';
279 -
280 - self::$more_skins_config = $more_skins;
281 -
268 + self::$more_skins_config = include COOLCLOCK_DIR . 'includes/moreskins.php';
282 269 }
283 270
284 271 return array_merge( self::$more_skins_config, self::$advanced_skins_config );
285 272 }
286 273
274 + /**
275 + * Enqueue scripts
276 + *
277 + * @since 3.2.0
278 + */
287 279 public static function enqueue_scripts() {
288 280 // bail if we don't need script
289 281 if ( ! self::$add_script )
290 282 return;
@@ -292,15 +284,14 @@
292 284 $script = '';
293 285
294 286 if ( !empty( self::$skins_config ) ) {
295 287
296 - /**
297 - * Load IE 6/7 specific JSON polyfill
298 - */
299 - wp_enqueue_script( 'json2' );
288 + $skins = wp_json_encode( self::$skins_config );
289 + if ( false === $skins ) {
290 + $skins = '{} /* skin parse error, please fix your custom skin */';
291 + }
300 292
301 - $script .= 'CoolClock.config.skins = JSON.parse(\'' . json_encode( self::$skins_config ) . '\');';
302 -
293 + $script .= 'CoolClock.config.skins = ' . $skins . ';';
303 294 }
304 295
305 296 $script .= PHP_EOL . 'if(document.readyState!="loading"&&document.addEventListener){document.addEventListener("DOMContentLoaded",function(){CoolClock.findAndCreateClocks();})}else{CoolClock.findAndCreateClocks();};';
306 297
@@ -308,23 +299,24 @@
308 299
309 300 wp_add_inline_script( 'coolclock', $script );
310 301
311 302 // called late so should end up in the footer
312 - wp_enqueue_style( 'coolclock', self::$plugin_url . 'css/coolclock' . self::$min . '.css' );
303 + wp_enqueue_style( 'coolclock', self::$plugin_url . 'css/coolclock' . self::$min . '.css', array(), self::$script_version );
313 304 }
314 305
315 - public static function textdomain() {
316 - load_plugin_textdomain( 'coolclock', false, dirname(self::$plugin_basename).'/languages' );
317 - }
318 -
319 306 public static function register_widget() {
320 307 register_widget("CoolClock_Widget");
321 308 }
322 309
323 - // add links to plugin's description
324 - public static function plugin_meta_links($links, $file) {
310 + /**
311 + * Add links to plugin's description in the plugins list
312 + *
313 + * @param array $links Array of links to display
314 + * @param string $file Plugin file path
315 + */
316 + public static function plugin_meta_links( array $links, string $file ) {
325 317 $support_link = '<a target="_blank" href="https://wordpress.org/support/plugin/coolclock/">' . __('Support','coolclock') . '</a>';
326 - $rate_link = '<a target="_blank" href="https://wordpress.org/support/plugin/coolclock/reviews/?filter=5#new-post">' . __('Rate ★★★★★','coolclock') . '</a>';
318 + $rate_link = '<a target="_blank" href="https://wordpress.org/support/plugin/coolclock/reviews/">' . __('Rate this plugin','coolclock') . '</a>';
327 319
328 320 if ( $file == self::$plugin_basename ) {
329 321 $links[] = $support_link;
330 322 $links[] = $rate_link;
@@ -341,11 +333,9 @@
341 333 * @param string $skin
342 334 *
343 335 * @return array array of skin parameters
344 336 */
345 -
346 - public static function skin_array( $skin )
347 - {
337 + public static function skin_array( $skin ) {
348 338 // remove everything following a ; to thwart any script injection
349 339 $parts = explode( ';', $skin, 2 );
350 340 $sanitized = $parts[0];
351 341 // strip all kind of whitespace
@@ -405,13 +395,14 @@
405 395 * @param string $color
406 396 *
407 397 * @return string hex color value or text for named color
408 398 */
409 -
410 - public static function colorval( $color )
411 - {
399 + public static function colorval( $color ) {
412 400 $color = wp_strip_all_tags( $color );
413 401 $color = trim( $color );
402 + $color = str_replace( array( '"', '\'', ':'), '', $color );
403 + $color_arr = explode( ' ', $color, 2 );
404 + $color = esc_attr( $color_arr[0] );
414 405
415 406 if ( substr($color, 0, 1) == '#' ) {
416 407 if ( ctype_xdigit( substr( $color, 1 ) ) )
417 408 return $color;
@@ -432,11 +423,9 @@
432 423 * @param string $content shortcode content
433 424 *
434 425 * @return string output
435 426 */
436 -
437 - public static function filter_shortcode( $output, $atts, $content )
438 - {
427 + public static function filter_shortcode( $output, $atts, $content ) {
439 428 // add backward compat filter
440 429 return apply_filters( 'coolclock_shortcode_advanced', $output, $atts, $content );
441 430 }
442 431
@@ -450,12 +439,9 @@
450 439 * @param array $instance widget instance array parameters
451 440 *
452 441 * @return string output
453 442 */
454 -
455 - public static function filter_widget( $output, $args, $instance )
456 - {
443 + public static function filter_widget( $output, $args, $instance ) {
457 444 // add backward compat filter
458 445 return apply_filters( 'coolclock_widget_advanced', $output, $args, $instance );
459 446 }
460 -
461 447 }