CMB2_Utils

CMB2 Utilities.

Defined (1)

The class is defined in the following location(s).

/includes/CMB2_Utils.php  
  1. class CMB2_Utils { 
  2.  
  3. /** 
  4. * The WordPress ABSPATH constant. 
  5. * @var string 
  6. * @since 2.2.3 
  7. */ 
  8. protected static $ABSPATH = ABSPATH; 
  9.  
  10. /** 
  11. * The url which is used to load local resources. 
  12. * @var string 
  13. * @since 2.0.0 
  14. */ 
  15. protected static $url = ''; 
  16.  
  17. /** 
  18. * Utility method that attempts to get an attachment's ID by it's url 
  19. * @since 1.0.0 
  20. * @param string $img_url Attachment url 
  21. * @return int|false Attachment ID or false 
  22. */ 
  23. public static function image_id_from_url( $img_url ) { 
  24. $attachment_id = 0; 
  25. $dir = wp_upload_dir(); 
  26.  
  27. // Is URL in uploads directory? 
  28. if ( false === strpos( $img_url, $dir['baseurl'] . '/' ) ) { 
  29. return false; 
  30.  
  31. $file = basename( $img_url ); 
  32.  
  33. $query_args = array( 
  34. 'post_type' => 'attachment',  
  35. 'post_status' => 'inherit',  
  36. 'fields' => 'ids',  
  37. 'meta_query' => array( 
  38. array( 
  39. 'value' => $file,  
  40. 'compare' => 'LIKE',  
  41. 'key' => '_wp_attachment_metadata',  
  42. ),  
  43. ); 
  44.  
  45. $query = new WP_Query( $query_args ); 
  46.  
  47. if ( $query->have_posts() ) { 
  48.  
  49. foreach ( $query->posts as $post_id ) { 
  50. $meta = wp_get_attachment_metadata( $post_id ); 
  51. $original_file = basename( $meta['file'] ); 
  52. $cropped_image_files = isset( $meta['sizes'] ) ? wp_list_pluck( $meta['sizes'], 'file' ) : array(); 
  53. if ( $original_file === $file || in_array( $file, $cropped_image_files ) ) { 
  54. $attachment_id = $post_id; 
  55. break; 
  56.  
  57.  
  58. return 0 === $attachment_id ? false : $attachment_id; 
  59.  
  60. /** 
  61. * Utility method that returns time string offset by timezone 
  62. * @since 1.0.0 
  63. * @param string $tzstring Time string 
  64. * @return string Offset time string 
  65. */ 
  66. public static function timezone_offset( $tzstring ) { 
  67. $tz_offset = 0; 
  68.  
  69. if ( ! empty( $tzstring ) && is_string( $tzstring ) ) { 
  70. if ( 'UTC' === substr( $tzstring, 0, 3 ) ) { 
  71. $tzstring = str_replace( array( ':15', ':30', ':45' ), array( '.25', '.5', '.75' ), $tzstring ); 
  72. return intval( floatval( substr( $tzstring, 3 ) ) * HOUR_IN_SECONDS ); 
  73.  
  74. try { 
  75. $date_time_zone_selected = new DateTimeZone( $tzstring ); 
  76. $tz_offset = timezone_offset_get( $date_time_zone_selected, date_create() ); 
  77. } catch ( Exception $e ) { 
  78. self::log_if_debug( __METHOD__, __LINE__, $e->getMessage() ); 
  79.  
  80.  
  81. return $tz_offset; 
  82.  
  83. /** 
  84. * Utility method that returns a timezone string representing the default timezone for the site. 
  85. * Roughly copied from WordPress, as get_option('timezone_string') will return 
  86. * an empty string if no value has been set on the options page. 
  87. * A timezone string is required by the wp_timezone_choice() used by the 
  88. * select_timezone field. 
  89. * @since 1.0.0 
  90. * @return string Timezone string 
  91. */ 
  92. public static function timezone_string() { 
  93. $current_offset = get_option( 'gmt_offset' ); 
  94. $tzstring = get_option( 'timezone_string' ); 
  95.  
  96. // Remove old Etc mappings. Fallback to gmt_offset. 
  97. if ( false !== strpos( $tzstring, 'Etc/GMT' ) ) { 
  98. $tzstring = ''; 
  99.  
  100. if ( empty( $tzstring ) ) { // Create a UTC+- zone if no timezone string exists 
  101. if ( 0 == $current_offset ) { 
  102. $tzstring = 'UTC+0'; 
  103. } elseif ( $current_offset < 0 ) { 
  104. $tzstring = 'UTC' . $current_offset; 
  105. } else { 
  106. $tzstring = 'UTC+' . $current_offset; 
  107.  
  108. return $tzstring; 
  109.  
  110. /** 
  111. * Returns a timestamp, first checking if value already is a timestamp. 
  112. * @since 2.0.0 
  113. * @param string|int $string Possible timestamp string 
  114. * @return int Time stamp 
  115. */ 
  116. public static function make_valid_time_stamp( $string ) { 
  117. if ( ! $string ) { 
  118. return 0; 
  119.  
  120. return self::is_valid_time_stamp( $string ) 
  121. ? (int) $string : 
  122. strtotime( (string) $string ); 
  123.  
  124. /** 
  125. * Determine if a value is a valid timestamp 
  126. * @since 2.0.0 
  127. * @param mixed $timestamp Value to check 
  128. * @return boolean Whether value is a valid timestamp 
  129. */ 
  130. public static function is_valid_time_stamp( $timestamp ) { 
  131. return (string) (int) $timestamp === (string) $timestamp 
  132. && $timestamp <= PHP_INT_MAX 
  133. && $timestamp >= ~PHP_INT_MAX; 
  134.  
  135. /** 
  136. * Checks if a value is 'empty'. Still accepts 0. 
  137. * @since 2.0.0 
  138. * @param mixed $value Value to check 
  139. * @return bool True or false 
  140. */ 
  141. public static function isempty( $value ) { 
  142. return null === $value || '' === $value || false === $value; 
  143.  
  144. /** 
  145. * Checks if a value is not 'empty'. 0 doesn't count as empty. 
  146. * @since 2.2.2 
  147. * @param mixed $value Value to check 
  148. * @return bool True or false 
  149. */ 
  150. public static function notempty( $value ) { 
  151. return null !== $value && '' !== $value && false !== $value; 
  152.  
  153. /** 
  154. * Filters out empty values (not including 0). 
  155. * @since 2.2.2 
  156. * @param mixed $value Value to check 
  157. * @return bool True or false 
  158. */ 
  159. public static function filter_empty( $value ) { 
  160. return array_filter( $value, array( __CLASS__, 'notempty' ) ); 
  161.  
  162. /** 
  163. * Insert a single array item inside another array at a set position 
  164. * @since 2.0.2 
  165. * @param array &$array Array to modify. Is passed by reference, and no return is needed. 
  166. * @param array $new New array to insert 
  167. * @param int $position Position in the main array to insert the new array 
  168. */ 
  169. public static function array_insert( &$array, $new, $position ) { 
  170. $before = array_slice( $array, 0, $position - 1 ); 
  171. $after = array_diff_key( $array, $before ); 
  172. $array = array_merge( $before, $new, $after ); 
  173.  
  174. /** 
  175. * Defines the url which is used to load local resources. 
  176. * This may need to be filtered for local Window installations. 
  177. * If resources do not load, please check the wiki for details. 
  178. * @since 1.0.1 
  179. * @return string URL to CMB2 resources 
  180. */ 
  181. public static function url( $path = '' ) { 
  182. if ( self::$url ) { 
  183. return self::$url . $path; 
  184.  
  185. $cmb2_url = self::get_url_from_dir( cmb2_dir() ); 
  186.  
  187. /** 
  188. * Filter the CMB location url 
  189. * @param string $cmb2_url Currently registered url 
  190. */ 
  191. self::$url = trailingslashit( apply_filters( 'cmb2_meta_box_url', $cmb2_url, CMB2_VERSION ) ); 
  192.  
  193. return self::$url . $path; 
  194.  
  195. /** 
  196. * Converts a system path to a URL 
  197. * @since 2.2.2 
  198. * @param string $dir Directory path to convert. 
  199. * @return string Converted URL. 
  200. */ 
  201. public static function get_url_from_dir( $dir ) { 
  202. $dir = self::normalize_path( $dir ); 
  203.  
  204. // Let's test if We are in the plugins or mu-plugins dir. 
  205. $test_dir = trailingslashit( $dir ) . 'unneeded.php'; 
  206. if ( 
  207. 0 === strpos( $test_dir, self::normalize_path( WPMU_PLUGIN_DIR ) ) 
  208. || 0 === strpos( $test_dir, self::normalize_path( WP_PLUGIN_DIR ) ) 
  209. ) { 
  210. // Ok, then use plugins_url, as it is more reliable. 
  211. return trailingslashit( plugins_url( '', $test_dir ) ); 
  212.  
  213. // Ok, now let's test if we are in the theme dir. 
  214. $theme_root = self::normalize_path( get_theme_root() ); 
  215. if ( 0 === strpos( $dir, $theme_root ) ) { 
  216. // Ok, then use get_theme_root_uri. 
  217. return set_url_scheme( 
  218. trailingslashit( 
  219. str_replace( 
  220. untrailingslashit( $theme_root ),  
  221. untrailingslashit( get_theme_root_uri() ),  
  222. $dir 
  223. ); 
  224.  
  225. // Check to see if it's anywhere in the root directory 
  226.  
  227. $site_dir = self::normalize_path( self::$ABSPATH ); 
  228. $site_url = trailingslashit( is_multisite() ? network_site_url() : site_url() ); 
  229.  
  230. $url = str_replace( 
  231. array( $site_dir, WP_PLUGIN_DIR ),  
  232. array( $site_url, WP_PLUGIN_URL ),  
  233. $dir 
  234. ); 
  235.  
  236. return set_url_scheme( $url ); 
  237.  
  238. /** 
  239. * `wp_normalize_path` wrapper for back-compat. Normalize a filesystem path. 
  240. * On windows systems, replaces backslashes with forward slashes 
  241. * and forces upper-case drive letters. 
  242. * Allows for two leading slashes for Windows network shares, but 
  243. * ensures that all other duplicate slashes are reduced to a single. 
  244. * @since 2.2.0 
  245. * @param string $path Path to normalize. 
  246. * @return string Normalized path. 
  247. */ 
  248. protected static function normalize_path( $path ) { 
  249. if ( function_exists( 'wp_normalize_path' ) ) { 
  250. return wp_normalize_path( $path ); 
  251.  
  252. // Replace newer WP's version of wp_normalize_path. 
  253. $path = str_replace( '\\', '/', $path ); 
  254. $path = preg_replace( '|(?<=.)/+|', '/', $path ); 
  255. if ( ':' === substr( $path, 1, 1 ) ) { 
  256. $path = ucfirst( $path ); 
  257.  
  258. return $path; 
  259.  
  260. /** 
  261. * Get timestamp from text date 
  262. * @since 2.2.0 
  263. * @param string $value Date value 
  264. * @param string $date_format Expected date format 
  265. * @return mixed Unix timestamp representing the date. 
  266. */ 
  267. public static function get_timestamp_from_value( $value, $date_format ) { 
  268. $date_object = date_create_from_format( $date_format, $value ); 
  269. return $date_object ? $date_object->setTime( 0, 0, 0 )->getTimeStamp() : strtotime( $value ); 
  270.  
  271. /** 
  272. * Takes a php date() format string and returns a string formatted to suit for the date/time pickers 
  273. * It will work with only with the following subset ot date() options: 
  274. * d, j, z, m, n, y, and Y. 
  275. * A slight effort is made to deal with escaped characters. 
  276. * Other options are ignored, because they would either bring compatibility problems between PHP and JS, or 
  277. * bring even more translation troubles. 
  278. * @since 2.2.0 
  279. * @param string $format php date format 
  280. * @return string reformatted string 
  281. */ 
  282. public static function php_to_js_dateformat( $format ) { 
  283.  
  284. // order is relevant here, since the replacement will be done sequentially. 
  285. $supported_options = array( 
  286. 'd' => 'dd', // Day, leading 0 
  287. 'j' => 'd', // Day, no 0 
  288. 'z' => 'o', // Day of the year, no leading zeroes,  
  289. // 'D' => 'D', // Day name short, not sure how it'll work with translations 
  290. // 'l' => 'DD', // Day name full, idem before 
  291. 'm' => 'mm', // Month of the year, leading 0 
  292. 'n' => 'm', // Month of the year, no leading 0 
  293. // 'M' => 'M', // Month, Short name 
  294. // 'F' => 'MM', // Month, full name,  
  295. 'y' => 'y', // Year, two digit 
  296. 'Y' => 'yy', // Year, full 
  297. 'H' => 'HH', // Hour with leading 0 (24 hour) 
  298. 'G' => 'H', // Hour with no leading 0 (24 hour) 
  299. 'h' => 'hh', // Hour with leading 0 (12 hour) 
  300. 'g' => 'h', // Hour with no leading 0 (12 hour),  
  301. 'i' => 'mm', // Minute with leading 0,  
  302. 's' => 'ss', // Second with leading 0,  
  303. 'a' => 'tt', // am/pm 
  304. 'A' => 'TT' // AM/PM 
  305. ); 
  306.  
  307. foreach ( $supported_options as $php => $js ) { 
  308. // replaces every instance of a supported option, but skips escaped characters 
  309. $format = preg_replace( "~(?<!\\\\)$php~", $js, $format ); 
  310.  
  311. $format = preg_replace_callback( '~(?:\\\.)+~', array( __CLASS__, 'wrap_escaped_chars' ), $format ); 
  312.  
  313. return $format; 
  314.  
  315. /** 
  316. * Helper function for CMB_Utils->php_to_js_dateformat, because php 5.2 was retarded. 
  317. * @since 2.2.0 
  318. * @param $value Value to wrap/escape 
  319. * @return string Modified value 
  320. */ 
  321. public static function wrap_escaped_chars( $value ) { 
  322. return "'" . str_replace( '\\', '', $value[0] ) . "'"; 
  323.  
  324. /** 
  325. * Send to debug.log if WP_DEBUG is defined and true 
  326. * @since 2.2.0 
  327. * @param string $function Function name 
  328. * @param int $line Line number 
  329. * @param mixed $msg Message to output 
  330. * @param mixed $debug Variable to print_r 
  331. */ 
  332. public static function log_if_debug( $function, $line, $msg, $debug = null ) { 
  333. if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { 
  334. error_log( "In $function, $line:" . print_r( $msg, true ) . ( $debug ? print_r( $debug, true ) : '' ) ); 
  335.  
  336. /** 
  337. * Determine a file's extension 
  338. * @since 1.0.0 
  339. * @param string $file File url 
  340. * @return string|false File extension or false 
  341. */ 
  342. public static function get_file_ext( $file ) { 
  343. $parsed = @parse_url( $file, PHP_URL_PATH ); 
  344. return $parsed ? strtolower( pathinfo( $parsed, PATHINFO_EXTENSION ) ) : false; 
  345.  
  346. /** 
  347. * Get the file name from a url 
  348. * @since 2.0.0 
  349. * @param string $value File url or path 
  350. * @return string File name 
  351. */ 
  352. public static function get_file_name_from_path( $value ) { 
  353. $parts = explode( '/', $value ); 
  354. return is_array( $parts ) ? end( $parts ) : $value; 
  355.  
  356. /** 
  357. * Check if WP version is at least $version. 
  358. * @since 2.2.2 
  359. * @param string $version WP version string to compare. 
  360. * @return bool Result of comparison check. 
  361. */ 
  362. public static function wp_at_least( $version ) { 
  363. return version_compare( get_bloginfo( 'version' ), $version, '>=' ); 
  364.  
  365. /** 
  366. * Combines attributes into a string for a form element. 
  367. * @since 1.1.0 
  368. * @param array $attrs Attributes to concatenate. 
  369. * @param array $attr_exclude Attributes that should NOT be concatenated. 
  370. * @return string String of attributes for form element. 
  371. */ 
  372. public static function concat_attrs( $attrs, $attr_exclude = array() ) { 
  373. $attr_exclude[] = 'rendered'; 
  374. $attributes = ''; 
  375. foreach ( $attrs as $attr => $val ) { 
  376. $excluded = in_array( $attr, (array) $attr_exclude, true ); 
  377. $empty = false === $val && 'value' !== $attr; 
  378. if ( ! $excluded && ! $empty ) { 
  379. // if data attribute, use single quote wraps, else double 
  380. $quotes = false !== stripos( $attr, 'data-' ) ? "'" : '"'; 
  381. $attributes .= sprintf( ' %1$s=%3$s%2$s%3$s', $attr, $val, $quotes ); 
  382. return $attributes; 
  383.