PluginProbe ʕ •ᴥ•ʔ
WP Popular Posts / 7.4.0
WP Popular Posts v7.4.0
4.0.8 4.0.9 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 5.0.0 5.0.1 5.0.2 5.1.0 5.2.0 5.2.1 5.2.2 5.2.3 5.2.4 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.2.0 6.2.1 6.3.0 6.3.1 6.3.2 6.3.3 6.3.4 6.4.0 6.4.1 6.4.2 7.0.0 7.0.1 7.1.0 7.2.0 7.3.0 7.3.1 7.3.2 7.3.3 7.3.4 7.3.5 7.3.6 7.3.7 7.3.8 7.4.0 trunk 2.3.7 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.2 4.0.3 4.0.5 4.0.6
wordpress-popular-posts / src / Helper.php
wordpress-popular-posts / src Last commit date
Activation 8 months ago Admin 3 weeks ago Block 3 weeks ago Compatibility 8 months ago Container 8 months ago Front 1 year ago Rest 8 months ago Shortcode 1 year ago Traits 4 years ago Widget 3 weeks ago Bootstrap.php 5 years ago Cache.php 8 months ago Helper.php 3 weeks ago I18N.php 5 years ago Image.php 8 months ago Output.php 3 weeks ago Query.php 3 weeks ago Settings.php 3 weeks ago Themer.php 8 months ago Translate.php 3 years ago Upgrader.php 8 months ago WordPressPopularPosts.php 8 months ago deprecated.php 4 years ago template-tags.php 3 weeks ago
Helper.php
492 lines
1 <?php
2
3 namespace WordPressPopularPosts;
4
5 class Helper {
6
7 /**
8 * Checks for valid number.
9 *
10 * @since 2.1.6
11 * @param int number
12 * @return bool
13 */
14 public static function is_number($number) /** @TODO: starting PHP 8.0 $number can be declared as mixed $number */
15 {
16 return ! empty($number) && is_numeric($number) && (intval($number) == floatval($number));
17 }
18
19 /**
20 * Converts a number into a short version, eg: 1000 -> 1k
21 *
22 * @see https://gist.github.com/RadGH/84edff0cc81e6326029c
23 * @since 5.2.0
24 * @param int
25 * @param int
26 * @return mixed string|bool
27 */
28 public static function prettify_number($number, $precision = 1) /** @TODO: starting PHP 8.0 $number can be declared as mixed $number */
29 {
30 if ( ! is_numeric($number) ) {
31 return false;
32 }
33
34 if ( $number < 900 ) {
35 // 0 - 900
36 $n_format = number_format($number, $precision);
37 $suffix = '';
38 } elseif ( $number < 900000 ) {
39 // 0.9k-850k
40 $n_format = number_format($number / 1000, $precision);
41 $suffix = 'k';
42 } elseif ( $number < 900000000 ) {
43 // 0.9m-850m
44 $n_format = number_format($number / 1000000, $precision);
45 $suffix = 'm';
46 } elseif ( $number < 900000000000 ) {
47 // 0.9b-850b
48 $n_format = number_format($number / 1000000000, $precision);
49 $suffix = 'b';
50 } else {
51 // 0.9t+
52 $n_format = number_format($number / 1000000000000, $precision);
53 $suffix = 't';
54 }
55
56 // Remove unnecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1"
57 // Intentionally does not affect partials, eg "1.50" -> "1.50"
58 if ( $precision > 0 ) {
59 $dotzero = '.' . str_repeat('0', $precision);
60 $n_format = str_replace($dotzero, '', $n_format);
61 }
62
63 return $n_format . $suffix;
64 }
65
66 /**
67 * Returns an array of start date and end date (with timestamps maybe).
68 *
69 * @since 7.3.9
70 * @param string
71 * @param int
72 * @param string
73 * @return array
74 */
75 public static function get_dates($time_range = 'last24hours', $time_unit = 24, $time_quantity = 'hour')
76 {
77 $time_units = ['MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH'];
78 $now = new \DateTime(Helper::now(), wp_timezone());
79 $end_date = clone $now;
80
81 $start_date = null;
82 $include_timestamp = true;
83
84 switch($time_range) {
85 case 'last24hours':
86 case 'daily':
87 $start_date = $now->sub(new \DateInterval('P1D'));
88 break;
89 case 'today':
90 $start_date = $now->setTime(0, 0, 0);
91 $end_date = $end_date->setTime(23, 59, 59);
92 break;
93 case 'last7days':
94 case 'weekly':
95 $start_date = $now->sub(new \DateInterval('P6D'));
96 $include_timestamp = false;
97 break;
98 case 'last30days':
99 case 'monthly':
100 $start_date = $now->sub(new \DateInterval('P29D'));
101 $include_timestamp = false;
102 break;
103 case 'custom':
104 $time_units = ['MINUTE', 'HOUR', 'DAY', 'WEEK', 'MONTH'];
105
106 // Valid time unit
107 if (
108 $time_unit
109 && in_array(strtoupper($time_unit), $time_units)
110 && $time_quantity
111 && filter_var($time_quantity, FILTER_VALIDATE_INT)
112 && $time_quantity > 0
113 ) {
114 $time_unit = strtoupper($time_unit);
115
116 if ( 'MINUTE' == $time_unit ) {
117 $start_date = $now->sub(new \DateInterval('PT' . $time_quantity . 'M'));
118 } elseif ( 'HOUR' == $time_unit ) {
119 $start_date = $now->sub(new \DateInterval('PT' . $time_quantity . 'H'));
120 } elseif ( 'DAY' == $time_unit ) {
121 if ( $time_quantity === 1 ) {
122 $start_date = $end_date;
123 } else {
124 $start_date = $now->sub(new \DateInterval('P' . $time_quantity . 'D'))
125 ->add(new \DateInterval('P1D'));
126 }
127
128 $include_timestamp = false;
129 } elseif ( 'WEEK' == $time_unit ) {
130 $start_date = $now->sub(new \DateInterval('P' . $time_quantity . 'W'))
131 ->add(new \DateInterval('P1D'));
132 $include_timestamp = false;
133 } else {
134 $start_date = $now->sub(new \DateInterval('P' . $time_quantity . 'M'))
135 ->add(new \DateInterval('P1D'));
136 $include_timestamp = false;
137 }
138 }
139 // Invalid time unit, default to last 24 hours
140 else {
141 $start_date = $now->sub(new \DateInterval('P1D'));
142 }
143 break;
144 default:
145 $start_date = $now->sub(new \DateInterval('P1D'));
146 break;
147 }
148
149 $dates = [
150 [
151 $start_date->format('Y-m-d'),
152 $end_date->format('Y-m-d')
153 ],
154 [
155 $start_date->format('Y-m-d H:i:s'),
156 $end_date->format('Y-m-d H:i:s')
157 ],
158 $include_timestamp
159 ];
160
161 return $dates;
162 }
163
164 /**
165 * Checks for valid date.
166 *
167 * @since 4.0.0
168 * @param string $date
169 * @param string $format
170 * @return bool
171 */
172 public static function is_valid_date(?string $date, $format = 'Y-m-d')
173 {
174 $d = $date ? \DateTime::createFromFormat($format, $date) : false;
175 return $d && $d->format($format) === $date;
176 }
177
178 /**
179 * Returns an array of dates between two dates.
180 *
181 * @since 4.0.0
182 * @param string $start_date
183 * @param string $end_date
184 * @param string $format
185 * @return array|bool
186 */
187 public static function get_date_range(string $start_date, string $end_date, string $format = 'Y-m-d')
188 {
189 if (
190 self::is_valid_date($start_date, $format)
191 && self::is_valid_date($end_date, $format)
192 ) {
193 $dates = [];
194
195 $begin = new \DateTime($start_date, wp_timezone());
196 $end = new \DateTime($end_date, wp_timezone());
197
198 if ( $begin < $end ) {
199 while( $begin <= $end ) {
200 $dates[] = $begin->format($format);
201 $begin->modify('+1 day');
202 }
203 }
204 else {
205 while( $begin >= $end ) {
206 $dates[] = $begin->format($format);
207 $begin->modify('-1 day');
208 }
209 }
210
211 return $dates;
212 }
213
214 return false;
215 }
216
217 /**
218 * Returns server date.
219 *
220 * @since 2.1.6
221 * @access private
222 * @return string
223 */
224 public static function curdate()
225 {
226 return current_datetime()->format('Y-m-d');
227 }
228
229 /**
230 * Returns mysql datetime.
231 *
232 * @since 2.1.6
233 * @access private
234 * @return string
235 */
236 public static function now()
237 {
238 return current_datetime()->format('Y-m-d H:i:s');
239 }
240
241 /**
242 * Returns current timestamp.
243 *
244 * @since 5.0.2
245 * @return string
246 */
247 public static function timestamp()
248 {
249 return current_datetime()->getTimestamp();
250 }
251
252 /**
253 * Checks whether a string is a valid timestamp.
254 *
255 * @since 5.2.0
256 * @param string $string
257 * @return bool
258 */
259 public static function is_timestamp($string) /** @TODO: starting PHP 8.0 $string can be declared as mixed $string */
260 {
261 if (
262 ( is_int($string) || ctype_digit($string) )
263 && strtotime(date('Y-m-d H:i:s', $string)) === (int) $string
264 ) {
265 return true;
266 }
267
268 return false;
269 }
270
271 /**
272 * Returns time.
273 *
274 * @since 2.3.0
275 * @return string
276 */
277 public static function microtime_float()
278 {
279 list($msec, $sec) = explode(' ', microtime());
280 return (float) $msec + (float) $sec;
281 }
282
283 /**
284 * Merges two associative arrays recursively.
285 *
286 * @since 2.3.4
287 * @link http://www.php.net/manual/en/function.array-merge-recursive.php#92195
288 * @param array array1
289 * @param array array2
290 * @return array
291 */
292 public static function merge_array_r(array $array1, array $array2)
293 {
294 $merged = $array1;
295
296 foreach( $array2 as $key => &$value ) {
297 if ( is_array($value) && isset($merged[$key]) && is_array($merged[$key]) ) {
298 $merged[$key] = self::merge_array_r($merged[$key], $value);
299 } else {
300 $merged[$key] = $value;
301 }
302 }
303
304 return $merged;
305 }
306
307 /**
308 * Truncates text.
309 *
310 * @since 4.0.0
311 * @param string $text
312 * @param int $length
313 * @param bool $truncate_by_words
314 * @return string
315 */
316 public static function truncate(string $text = '', int $length = 25, bool $truncate_by_words = false, string $more = '...')
317 {
318 if ( '' !== $text ) {
319 $charset = get_bloginfo('charset');
320
321 // Truncate by words
322 if ( $truncate_by_words ) {
323 $words = explode(' ', $text, $length + 1);
324
325 if ( count($words) > $length ) {
326 array_pop($words);
327 $text = rtrim(implode(' ', $words), ',.') . $more;
328 }
329 }
330 // Truncate by characters
331 elseif ( mb_strlen($text, $charset) > $length ) {
332 $text = rtrim(mb_substr($text, 0, $length, $charset), ' ,.') . $more;
333 }
334 }
335
336 return $text;
337 }
338
339 /**
340 * Gets post/page ID if current page is singular
341 *
342 * @since 3.1.2
343 */
344 public static function is_single()
345 {
346 $trackable = [];
347 $registered_post_types = get_post_types(['public' => true], 'names');
348
349 foreach( $registered_post_types as $post_type ) {
350 $trackable[] = $post_type;
351 }
352
353 $trackable = apply_filters('wpp_trackable_post_types', $trackable);
354
355 if (
356 is_singular($trackable)
357 && ! is_front_page()
358 && ! is_preview()
359 && ! is_trackback()
360 && ! is_feed()
361 && ! is_robots()
362 && ! is_customize_preview()
363 ) {
364 return get_queried_object_id();
365 }
366
367 return false;
368 }
369
370 /**
371 * Adds scheme to a given URL.
372 *
373 * @since 5.0.0
374 * @param string $url
375 * @param string $scheme
376 * @return string|bool
377 */
378 public static function add_scheme(?string $url, string $scheme = 'https://')
379 {
380 $url_args = parse_url($url);
381
382 if ( $url_args ) {
383 // No need to do anything, URL is fine
384 if ( isset($url_args['scheme']) ) {
385 return $url;
386 }
387 // Return URL with scheme
388 return $scheme . $url_args['host'] . $url_args['path'];
389 }
390
391 // Invalid/malformed URL
392 return false;
393 }
394
395 /**
396 * Checks whether an URL points to an actual image.
397 *
398 * This function used to live in src/Image, moved it here
399 * on version 5.4.0 to use it where needed.
400 *
401 * @since 5.0.0
402 * @access private
403 * @param string
404 * @return array|bool
405 */
406 public static function is_image_url(string $url)
407 {
408 $path = parse_url($url, PHP_URL_PATH);
409 $encoded_path = array_map('urlencode', explode('/', $path));
410 $parse_url = str_replace($path, implode('/', $encoded_path), $url);
411
412 if ( ! filter_var($parse_url, FILTER_VALIDATE_URL) ) {
413 return false;
414 }
415
416 // Check extension
417 $file_name = basename($path);
418 $file_name = sanitize_file_name($file_name);
419 $ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
420 $allowed_ext = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'avif'];
421
422 if ( ! in_array($ext, $allowed_ext) ) {
423 return false;
424 }
425
426 // sanitize URL, just in case
427 $image_url = esc_url($url);
428 // remove querystring
429 preg_match('/[^\?]+\.(jpg|jpeg|gif|png|webp|avif)/i', $image_url, $matches);
430
431 return ( is_array($matches) && ! empty($matches) ) ? $matches : false;
432 }
433
434 /**
435 * Sanitizes HTML output.
436 *
437 * @since 6.3.3
438 * @param string $html
439 * @param array $options Public options
440 * @return string $html The (sanitized) HTML code
441 */
442 public static function sanitize_html(string $html, array $options)
443 {
444 $allowed_tags = wp_kses_allowed_html('post');
445
446 if ( isset($allowed_tags['form']) ) {
447 unset($allowed_tags['form']);
448 }
449
450 if (
451 isset($options['theme']['name'])
452 && $options['theme']['name']
453 ) {
454 $allowed_tags['style'] = [
455 'id' => 1,
456 'nonce' => 1
457 ];
458 }
459
460 $allowed_tags['img']['decoding'] = true;
461 $allowed_tags['img']['srcset'] = true;
462
463 return wp_kses($html, $allowed_tags);
464 }
465
466 /**
467 * Retrieves post/page content from the database.
468 *
469 * @param int $id
470 * @return mixed
471 */
472 public static function get_post_content(int $id)
473 {
474 /** @var wpdb $wpdb */
475 global $wpdb;
476
477 $posts_table = "{$wpdb->posts}";
478
479 //phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
480 $content = $wpdb->get_var(
481 $wpdb->prepare(
482 "SELECT post_content FROM %i WHERE ID = %d;",
483 $posts_table,
484 $id
485 )
486 );
487 //phpcs:enable
488
489 return ( $content ) ? sanitize_post_field('post_content', $content, $id, 'display') : '';
490 }
491 }
492