PluginProbe
CoolClock / 4.1
CoolClock v4.1
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 +80 -379 4.3.64.1 View file →
@@ -5,11 +5,11 @@
5 5 */
6 6
7 7 class CoolClock {
8 8
9 - static $plugin_version;
9 + static $plugin_version = '4.0.99';
10 10
11 - static $script_version = '3.2.2';
11 + static $script_version = '3.1.0';
12 12
13 13 private static $plugin_url;
14 14
15 15 private static $plugin_basename;
@@ -17,300 +17,128 @@
17 17 private static $min = '.min';
18 18
19 19 static $add_script = false;
20 20
21 + static $add_moreskins = false;
22 +
21 23 private static $done_excanvas = false;
22 24
23 - static $defaults = array(
24 - 'skin' => 'swissrail',
25 + static $defaults = array (
26 + 'skin' => 'swissRail',
25 27 'radius' => 100,
26 - 'noseconds' => false, // true to hide second hand
28 + 'noseconds' => false, // Hide seconds
27 29 'gmtoffset' => '', // GMT offset
28 - 'showdigital' => '', // show digital time or date
29 - 'scale' => '', // Define alternative clock type: 'logClock' logarithmic or 'logClockRev' reversed
30 - 'font' => '', // Define font size and family for digital time, default '15px monospace'
31 - 'fontcolor' => '' // Define font color for digital time, default '#333'
30 + 'showdigital' => '', // Show digital time or date
31 + 'scale' => 'linear', // Define type of clock linear/logarithmic/log reversed
32 + 'digitalcolor' => '#333'
32 33 );
33 34
34 - static $showdigital_options = array(
35 + static $showdigital_options = array (
35 36 '' => '',
36 37 'digital12' => 'showDigital'
37 38 );
38 39
39 - static $advanced_defaults = array(
40 + static $advanced = false;
41 +
42 + static $advanced_defaults = array (
40 43 'subtext' => '',
41 44 'align' => 'center'
42 45 );
43 46
44 - static $more_skins_config = array();
47 + static $default_skins = ['swissRail','chunkySwiss','chunkySwissOnBlack'];
45 48
46 - static $advanced_skins_config = array();
49 + static $more_skins = ['fancy','machine','simonbaird_com','classic','modern','simple','securephp','Tes2','Lev','Sand','Sun','Tor','Cold','Babosa','Tumb','Stone','Disc','watermelon','mister'];
47 50
48 - static $skins_config = array();
51 + static $advanced_skins = [];
49 52
50 - /**
51 - * DEPRICATED ARGUMENTS
52 - * keep these for backward compatibility with old advanced extension
53 - */
54 - static $default_skins = array('swissRail');
55 - static $more_skins = array();
56 - static $advanced_skins = array();
57 - static $advanced = false;
58 - /* end unused arguments */
53 + static $advanced_skins_config = [];
59 54
60 - static $clock_types = array(
55 + static $clock_types = array (
61 56 'linear' => '',
62 - 'logclock' => 'logClock',
63 - 'logclockrev' => 'logClockRev'
57 + 'logClock' => 'logClock',
58 + 'logClockRev' => 'logClockRev'
64 59 );
65 60
66 - static $allowed_tags = array(
67 - 'a' => array(
68 - 'href' => array(),
69 - 'title' => array(),
70 - 'target' => array()
71 - ),
72 - 'br' => array(),
73 - 'em' => array(),
74 - 'strong' => array(),
75 - );
76 -
77 61 /**
78 - * INIT
62 + * MAIN
79 63 */
80 64
81 - public function __construct( $plugin_file, $plugin_version )
82 - {
83 - // VARS
84 - self::$plugin_url = plugins_url( '/', $plugin_file );
85 - self::$plugin_basename = plugin_basename( $plugin_file );
86 - self::$plugin_version = $plugin_version;
65 + public static function canvas( $atts ) {
66 + extract( $atts );
87 67
88 - if ( defined('WP_DEBUG') && WP_DEBUG ) {
89 - self::$min = '';
90 - }
91 -
92 - // text domain
93 - add_action( 'plugins_loaded', array( __CLASS__, 'textdomain' ) );
94 -
95 - // widgets
96 - add_action( 'widgets_init', array( __CLASS__, 'register_widget' ) );
97 -
98 - // enqueue scripts but only if shortcode or widget has been used
99 - // so it has to be done as late as the wp_footer action
100 - add_action( 'wp_footer', array( __CLASS__, 'enqueue_scripts' ), 1 );
101 -
102 - add_filter( 'plugin_row_meta', array( __CLASS__, 'plugin_meta_links' ), 10, 2);
103 -
104 - // backward compat
105 - add_filter( 'coolclock_shortcode', array( __CLASS__, 'filter_shortcode'), 10, 3 );
106 - add_filter( 'coolclock_widget', array( __CLASS__, 'filter_widget'), 10, 3 );
107 -
108 - /**************
109 - * SHORTCODE
110 - **************/
111 -
112 - add_shortcode( 'coolclock', array( 'CoolClock_Shortcode', 'handle_shortcode' ) );
113 -
114 - // prevent texturizing shortcode content
115 - add_filter( 'no_texturize_shortcodes', array( 'CoolClock_Shortcode', 'no_wptexturize') );
116 - }
117 -
118 - /**
119 - * METHODS
120 - */
121 -
122 - /**
123 - * Build canvas output
124 - *
125 - * @since 2.0
126 - *
127 - * @param array $atts Array of sanitized attributes
128 - *
129 - * @return string Canvas tag
130 - */
131 -
132 - public static function canvas( $atts )
133 - {
134 - /**
135 - * ARRAY VALUES
136 - * 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 - * If the Advanced extension is activated, there is also 'minimal' available.
138 - * radius @param int Define the clock radius.
139 - * noseconds @param bool True to hide the second hand.
140 - * gmtoffset @param float Timezone offset relative the Greenwhich Mean Time
141 - * showdigital @param string|bool Set to 'digital12' to show the time in 12h digital format (with am/pm).
142 - * font @param string Set to a font size, family and style for the digital time
143 - * fontcolor @param string Set to a color value to change the digital time color
144 - * scale @param string Optional alternative clock scale 'logClock' or 'logClockRev'
145 - * subtext @param string Optional text, centered below the clock
146 - * align @param string Sets floating of the clock: 'left', 'right' or 'center'
147 - */
148 -
149 - // get defaults for missing attributes
150 - $defaults = array_merge( self::$defaults, self::$advanced_defaults );
151 -
152 - $atts = apply_filters( 'coolclock_atts', $atts, $defaults );
153 -
154 - // CoolClock fields array
155 - $fields = array();
156 - $fields[] = 'CoolClock';
157 - // skin id
158 - $fields[] = !empty( $atts['skin'] ) ? $atts['skin'] : $defaults['skin'];
159 - // radius
160 - $fields[] = !empty( $atts['radius'] ) && is_numeric($atts['radius']) ? (int) $atts['radius'] : $defaults['radius'];
161 - // noseconds
162 - $noseconds = isset( $atts['noseconds'] ) ? (bool) $atts['noseconds'] : $defaults['noseconds'];
163 - $fields[] = $noseconds ? 'noSeconds' : '';
164 - // gmt offset
165 - $fields[] = isset( $atts['gmtoffset'] ) && is_numeric( $atts['gmtoffset'] ) ? (float) $atts['gmtoffset'] : $defaults['gmtoffset'];
166 - // show digital
167 - $showdigital = isset($atts['showdigital']) ? $atts['showdigital'] : $defaults['showdigital'];
168 - if ( true === $showdigital )
169 - $showdigital = 'digital12';
170 - $fields[] = isset( self::$showdigital_options[$showdigital] ) ? self::$showdigital_options[$showdigital] : '';
171 - // clock type
172 - $scale = isset( $atts['scale'] ) ? strtolower( $atts['scale'] ) : $defaults['scale'];
173 - $fields[] = isset( self::$clock_types[$scale] ) ? self::$clock_types[$scale] : '';
174 - // set font color
175 - $fields[] = isset( $atts['fontcolor'] ) ? $atts['fontcolor'] : $defaults['fontcolor'];
176 -
177 - $fields = apply_filters( 'coolclock_fields_array', $fields, $atts, $defaults );
178 -
179 - // build output
180 68 $output = '';
181 69
182 70 if ( ! self::$done_excanvas ){
183 71 $output .= '<!--[if lte IE 8]>';
184 - $output .= '<script type="text/javascript" src="'. self::$plugin_url . 'js/excanvas' . self::$min . '.js"></script>';
72 + $output .= '<script type=\'text/javascript\' src=\'' . self::$plugin_url . 'js/excanvas' . self::$min . '.js\'></script>';
185 73 $output .= '<![endif]-->' . PHP_EOL;
186 74 self::$done_excanvas = true;
187 75 }
188 76
189 - $styles = apply_filters( 'coolclock_canvas_styles', array(), $atts, $defaults );
77 + $output .= '<div class="coolclock';
190 78
79 + // align class ans style
80 + $output .= ( $align ) ? ' align' . $align : '';
81 + $output .= '" style="width:' . 2 * $radius . 'px;max-width:100%;height:auto">';
191 82 // canvas parameters
192 - $output .= '<canvas class="' . implode(':',$fields) . '"' . CoolClock::inline_style( $styles ) . '></canvas>';
83 + $output .= '<canvas class="CoolClock:' . $skin . ':' . $radius . ':';
84 + $output .= ( $noseconds == 'true' || $noseconds == '1' ) ? 'noSeconds:' : ':';
85 + $output .= $gmtoffset;
193 86
194 - // sub text
195 - $subtext = ( isset( $atts['subtext'] ) ) ? $atts['subtext'] : $defaults['subtext'];
196 - if ( !empty( $subtext ) )
197 - $output .= '<div class="coolclock-subtext">' . $subtext . '</div>';
87 + // show digital
88 + if ( $showdigital == 'true' || $showdigital == '1' )
89 + $showdigital = 'digital12'; // backward compat
198 90
199 - return $output;
200 - }
91 + if ( isset(self::$showdigital_options[$showdigital]) )
92 + $output .= ':'.self::$showdigital_options[$showdigital];
93 + else
94 + $output .= ':';
201 95
202 - /**
203 - * Create inline style attribute from array
204 - *
205 - * @since 4.3
206 - *
207 - * @param array $styles array with style parameters and their values
208 - *
209 - * @return string inline style attribute style="..." complete with leading space
210 - */
96 + // set type
97 + if ( isset(self::$clock_types[$scale]) )
98 + $output .= ':'.self::$clock_types[$scale];
99 + else
100 + $output .= ':';
211 101
212 - public static function inline_style( $styles )
213 - {
214 - $style_arr = array();
102 + // set font
103 + if ( isset($font) )
104 + $output .= ':'.$font;
105 + else
106 + $output .= ':';
215 107
216 - foreach ( $styles as $key => $value ) {
217 - $style_arr[] = $key . ':' . $value;
218 - }
108 + // set font color
109 + if ( isset($digitalcolor) )
110 + $output .= ':'.$digitalcolor;
111 + else
112 + $output .= ':';
219 113
220 - $style = ! empty($style_arr) ? ' style="' . implode( ';', $style_arr ) . '"' : '';
114 + $output .= '"></canvas>';
115 + $output .= ( $subtext ) ? '<div style="width:100%;text-align:center;padding-bottom:10px">' . $subtext . '</div></div>' : '</div>';
221 116
222 - return $style;
117 + return $output;
223 118 }
224 119
225 - /**
226 - * Parse skin name and user skin parameters
227 - *
228 - * @since 3.2.0
229 - *
230 - * @param string $skin_name skin name
231 - * @param string $skin_parms skin parameters, preferably in JSON format
232 - *
233 - * @return string either found matching skin name or 'invalid_or_missing_skin' on failure
234 - */
235 -
236 - public static function parse_skin( $skin_name, $skin_parms = '' )
237 - {
238 - $skin = strtolower($skin_name);
239 - $skin_array = array();
240 -
241 - // check for empty or default skin first
242 - if ( empty($skin) || $skin == self::$defaults['skin'] )
243 - // return the matching skin name
244 - return self::$defaults['skin'];
245 -
246 - // short-circuit if skin name is already in the config array
247 - if ( array_key_exists( $skin, self::$skins_config ) )
248 - // return the matching skin name
249 - return $skin;
250 -
251 - // search in the more_skins and advanced_skins arrays
252 - $all_skins = self::get_all_skins();
253 - if ( array_key_exists( $skin, $all_skins ) ) {
254 - // fetch parameters from skins array
255 - $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
260 - $skin_array = self::skin_array( $skin_parms );
261 -
262 - if ( empty( $skin_array ) )
263 - // set faulty skin name
264 - return 'no_skin_found';
265 - }
266 -
267 - // add found skin parameters to the config array
268 - self::$skins_config[$skin] = $skin_array;
269 -
270 - // return the matching skin name
271 - return $skin;
272 - }
273 -
274 - public static function get_all_skins() {
275 -
276 - if ( empty( self::$more_skins_config ) ) {
277 -
278 - include COOLCLOCK_DIR . 'includes/moreskins.php';
279 -
280 - self::$more_skins_config = $more_skins;
281 -
282 - }
283 -
284 - return array_merge( self::$more_skins_config, self::$advanced_skins_config );
285 - }
286 -
287 120 public static function enqueue_scripts() {
288 - // bail if we don't need script
289 121 if ( ! self::$add_script )
290 122 return;
291 123
292 - $script = '';
124 + wp_enqueue_script( 'coolclock', self::$plugin_url . 'js/coolclock' . self::$min . '.js', array('jquery'), self::$script_version, true );
293 125
294 - if ( !empty( self::$skins_config ) ) {
126 + if ( self::$add_moreskins )
127 + wp_enqueue_script( 'coolclock-moreskins', self::$plugin_url . 'js/moreskins' . self::$min . '.js', array('coolclock'), self::$script_version, true );
295 128
296 - /**
297 - * Load IE 6/7 specific JSON polyfill
298 - */
299 - wp_enqueue_script( 'json2' );
129 + if ( is_array( self::$advanced_skins_config ) && !empty( self::$advanced_skins_config ) ) {
130 + $script = 'jQuery.extend(CoolClock.config.skins, {' . PHP_EOL;
131 + // loop through plugin custom skins
132 + foreach (self::$advanced_skins_config as $key => $value)
133 + $script .= $key.':{'.$value.'},' . PHP_EOL;
134 + $script .= '});';
300 135
301 - $script .= 'CoolClock.config.skins = JSON.parse(\'' . json_encode( self::$skins_config ) . '\');';
302 -
136 + if ( self::$add_moreskins )
137 + wp_add_inline_script( 'coolclock-moreskins', $script );
138 + else
139 + wp_add_inline_script( 'coolclock', $script );
303 140 }
304 -
305 - $script .= PHP_EOL . 'if(document.readyState!="loading"&&document.addEventListener){document.addEventListener("DOMContentLoaded",function(){CoolClock.findAndCreateClocks();})}else{CoolClock.findAndCreateClocks();};';
306 -
307 - wp_enqueue_script( 'coolclock', self::$plugin_url . 'js/coolclock' . self::$min . '.js', false, self::$script_version, true );
308 -
309 - wp_add_inline_script( 'coolclock', $script );
310 -
311 - // called late so should end up in the footer
312 - wp_enqueue_style( 'coolclock', self::$plugin_url . 'css/coolclock' . self::$min . '.css' );
313 141 }
314 142
315 143 public static function textdomain() {
316 144 load_plugin_textdomain( 'coolclock', false, dirname(self::$plugin_basename).'/languages' );
@@ -319,146 +147,19 @@
319 147 public static function register_widget() {
320 148 register_widget("CoolClock_Widget");
321 149 }
322 150
323 - // add links to plugin's description
324 - public static function plugin_meta_links($links, $file) {
325 - $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>';
327 -
328 - if ( $file == self::$plugin_basename ) {
329 - $links[] = $support_link;
330 - $links[] = $rate_link;
331 - }
332 -
333 - return $links;
334 - }
335 -
336 151 /**
337 - * Turn custom skin user input into an array
338 - *
339 - * @since 2.0
340 - *
341 - * @param string $skin
342 - *
343 - * @return array array of skin parameters
344 - */
152 + * INIT
153 + */
345 154
346 - public static function skin_array( $skin )
347 - {
348 - // remove everything following a ; to thwart any script injection
349 - $parts = explode( ';', $skin, 2 );
350 - $sanitized = $parts[0];
351 - // strip all kind of whitespace
352 - $sanitized = preg_replace("/\s+/", '', $sanitized);;
353 - $sanitized = ltrim( $sanitized, '{' );
354 - $sanitized = rtrim( $sanitized, '}' ) . '}';
355 - // by now, the string should start with a double quote
356 - if ( 0 !== strpos( $sanitized, '"' ) ) {
357 - // regex for (re)wrapping all keys in double quotes
358 - $sanitized = preg_replace( "/(['\"])?([a-zA-Z0-9_]+)(['\"])?:([^\/])/", '"$2":$4', $sanitized );
359 - }
155 + public function __construct( $file ) {
156 + // VARS
157 + self::$plugin_url = plugins_url( '/', $file );
158 + self::$plugin_basename = plugin_basename( $file );
360 159
361 - // fist attempt to decode json string
362 - $skin_array = json_decode( '{' . $sanitized . '}', true );
363 -
364 - // not valid json? then do it the hard way
365 - if ( null === $skin_array ) :
366 -
367 - // remove all spaces and tabs
368 - $sanitized = str_replace( array( ' ', "\t", '"', "'" ), '', $sanitized );
369 -
370 - // break it all up in little parts
371 - // this converts valid skin javascript object into json, but messes up all else :/
372 - $elements = explode( '},', $sanitized );
373 -
374 - // start fresh
375 - $skin_array = array();
376 -
377 - // and build array
378 - foreach( $elements as $element ) {
379 - $pair = explode( ':{', $element );
380 - // validate key
381 - $part = str_replace( '{', '', $pair[0] );
382 - if ( ! in_array( $part, array('outerBorder','smallIndicator','largeIndicator','hourHand','minuteHand','secondHand','secondDecoration') ) )
383 - continue;
384 - // constuct value
385 - $value = array();
386 - $parameters = explode( ',', $pair[1] );
387 - for( $i=0; $i < count( $parameters ); $i++ ) {
388 - $pairs = explode( ':', $parameters[$i] );
389 - $parm_val = str_replace( '}', '', $pairs[1] );
390 - $value[$pairs[0]] = is_numeric($parm_val) ? (float) $parm_val : (string) $parm_val;
391 - }
392 - $skin_array[$part] = $value;
393 - }
394 -
395 - endif;
396 -
397 - return $skin_array;
398 - }
399 -
400 - /**
401 - * Sanitize color value user input
402 - *
403 - * @since 4.2
404 - *
405 - * @param string $color
406 - *
407 - * @return string hex color value or text for named color
408 - */
409 -
410 - public static function colorval( $color )
411 - {
412 - $color = wp_strip_all_tags( $color );
413 - $color = trim( $color );
414 - $color = str_replace( array( '"', '\'', ':'), '', $color );
415 - $color_arr = explode( ' ', $color, 2 );
416 - $color = esc_attr( $color_arr[0] );
417 -
418 - if ( substr($color, 0, 1) == '#' ) {
419 - if ( ctype_xdigit( substr( $color, 1 ) ) )
420 - return $color;
421 -
422 - return substr( $color, 1 );
423 - }
424 -
425 - return ctype_xdigit( $color ) ? '#'.$color : $color;
426 - }
427 -
428 - /**
429 - * Filter shortcode output
430 - *
431 - * @since 4.3
432 - *
433 - * @param string $output output
434 - * @param array $atts array of shortcode attributes
435 - * @param string $content shortcode content
436 - *
437 - * @return string output
438 - */
439 -
440 - public static function filter_shortcode( $output, $atts, $content )
441 - {
442 - // add backward compat filter
443 - return apply_filters( 'coolclock_shortcode_advanced', $output, $atts, $content );
444 - }
445 -
446 - /**
447 - * Filter widget output
448 - *
449 - * @since 4.3
450 - *
451 - * @param string $output output
452 - * @param array $args array of widget parameters
453 - * @param array $instance widget instance array parameters
454 - *
455 - * @return string output
456 - */
457 -
458 - public static function filter_widget( $output, $args, $instance )
459 - {
460 - // add backward compat filter
461 - return apply_filters( 'coolclock_widget_advanced', $output, $args, $instance );
462 - }
160 + if ( defined('WP_DEBUG') && WP_DEBUG ) {
161 + self::$min = '';
162 + }
163 + }
463 164
464 165 }