/app/helper/class-ms-helper-period.php

  1. <?php 
  2. /** 
  3. * Utilities class 
  4. * 
  5. * @since 1.0.0 
  6. */ 
  7. class MS_Helper_Period extends MS_Helper { 
  8.  
  9. /** 
  10. * Period types 
  11. */ 
  12. const PERIOD_TYPE_DAYS = 'days'; 
  13. const PERIOD_TYPE_WEEKS = 'weeks'; 
  14. const PERIOD_TYPE_MONTHS = 'months'; 
  15. const PERIOD_TYPE_YEARS = 'years'; 
  16.  
  17. /** 
  18. * Date formats 
  19. */ 
  20. const PERIOD_FORMAT = 'Y-m-d'; 
  21. const DATE_TIME_FORMAT = 'Y-m-d H:i'; 
  22. const DATE_FORMAT_SHORT = 'y-m-d'; 
  23.  
  24. /** 
  25. * Add a period interval to a date. 
  26. * 
  27. * @since 1.0.0 
  28. * 
  29. * @param int $period_unit The period unit to add. 
  30. * @param string $period_type The period type to add. 
  31. * @param string|int $start_date The start date to add to. 
  32. * @return string The added date. 
  33. */ 
  34. public static function add_interval( $period_unit, $period_type, $start_date = null ) { 
  35. if ( empty ( $start_date ) ) { 
  36. $start_date = self::current_date(); 
  37. if ( ! is_numeric( $start_date ) ) { 
  38. $start_date = strtotime( $start_date ); 
  39. $result = $start_date; 
  40.  
  41. if ( is_numeric( $period_unit ) && $period_unit > 0 ) { 
  42. $days = self::get_period_in_days( $period_unit, $period_type ); 
  43. $result = strtotime( '+' . $days . 'days', $start_date ); 
  44.  
  45. if ( false === $result ) { 
  46. $result = $start_date; 
  47.  
  48. return apply_filters( 
  49. 'ms_helper_period_add_interval',  
  50. gmdate( self::PERIOD_FORMAT, $result ) 
  51. ); 
  52.  
  53. /** 
  54. * Subtract a period interval to a date. 
  55. * 
  56. * @since 1.0.0 
  57. * 
  58. * @param int $period_unit The period unit to subtract. 
  59. * @param string $period_type The period type to subtract. 
  60. * @param string|int $start_date The start date to subtract to. 
  61. * @return string The subtracted date. 
  62. */ 
  63. public static function subtract_interval( $period_unit, $period_type, $start_date = null ) { 
  64. if ( empty ( $start_date ) ) { 
  65. $start_date = self::current_date(); 
  66. if ( ! is_numeric( $start_date ) ) { 
  67. $start_date = strtotime( $start_date ); 
  68. $result = $start_date; 
  69.  
  70. if ( is_numeric( $period_unit ) && $period_unit > 0 ) { 
  71. $days = self::get_period_in_days( $period_unit, $period_type ); 
  72. $result = strtotime( '-' . $days . 'days', $start_date ); 
  73.  
  74. if ( false === $result ) { 
  75. $result = $start_date; 
  76.  
  77. return apply_filters( 
  78. 'ms_helper_period_subtract_interval',  
  79. gmdate( self::PERIOD_FORMAT, $result ) 
  80. ); 
  81.  
  82. /** 
  83. * Subtract dates. 
  84. * 
  85. * Return (end_date - start_date) in period_type format 
  86. * 
  87. * @since 1.0.0 
  88. * 
  89. * @param Date $end_date The end date to subtract from in the format yyyy-mm-dd 
  90. * @param Date $start_date The start date to subtraction the format yyyy-mm-dd 
  91. * @param int $precission Time constant HOURS_IN_SECONDS will return the 
  92. * difference in hours. Default is DAY_IN_SECONDS (return = days). 
  93. * @param bool $real_diff If set to true then the result is negative if 
  94. * enddate is before startdate. Default is false, which will return 
  95. * the absolute difference which is always positive. 
  96. * @return int The resulting difference of the date subtraction. 
  97. */ 
  98. public static function subtract_dates( $end_date, $start_date, $precission = null, $real_diff = false ) { 
  99. if ( empty( $end_date ) ) { 
  100. // Empty end date is assumed to mean "never" 
  101. $end_date = '2999-12-31'; 
  102.  
  103. $end_date = new DateTime( $end_date ); 
  104. $start_date = new DateTime( $start_date ); 
  105.  
  106. if ( ! is_numeric( $precission ) || $precission <= 0 ) { 
  107. $precission = DAY_IN_SECONDS; 
  108.  
  109. $result = intval( 
  110. ( $end_date->format( 'U' ) - $start_date->format( 'U' ) ) / 
  111. $precission 
  112. ); 
  113.  
  114. if ( ! $real_diff ) { 
  115. $result = abs( $result ); 
  116.  
  117. return apply_filters( 
  118. 'ms_helper_period_subtract_dates',  
  119. $result 
  120. ); 
  121.  
  122. /** 
  123. * Checks two things: First if the_date is a valid date and second if 
  124. * the_date occurs AFTER any other date in the arguments list. 
  125. * 
  126. * This function can be used to compare multiple dates, like 
  127. * $valid = is_after( $today, $date1, $date2, $date3 ); 
  128. * 
  129. * @since 1.0.0 
  130. * 
  131. * @param string|Date $the_date Date value that is compared with other dates. 
  132. * @param string|Date $before_1 Comparison Date 1 
  133. * @param ... 
  134. * @return bool True means that the_date is valid and after all other dates. 
  135. */ 
  136. public static function is_after( $the_date, $before_1 ) { 
  137. $result = true; 
  138.  
  139. if ( ! is_numeric( $the_date ) ) { 
  140. $the_date = strtotime( $the_date ); 
  141.  
  142. if ( empty( $the_date ) ) { 
  143. // No valid date specified. Fail. 
  144. $result = false; 
  145. } else { 
  146. // Valid date specified, compare with other params. 
  147. $dates = func_get_args(); 
  148.  
  149. // Remove the_date from the param list 
  150. array_shift( $dates ); 
  151.  
  152. foreach ( $dates as $comp_date ) { 
  153. if ( ! is_numeric( $comp_date ) ) { 
  154. $comp_date = strtotime( $comp_date ); 
  155.  
  156. // The date param is invalid, skip comparison. 
  157. if ( empty( $comp_date ) ) { continue; } 
  158.  
  159. if ( $comp_date > $the_date ) { 
  160. // Comparison date is bigger (=after) the_date. Fail. 
  161. $result = false; 
  162. break; 
  163.  
  164. return $result; 
  165.  
  166. /** 
  167. * Return current date. 
  168. * 
  169. * @since 1.0.0 
  170. * @param string $format A valid php date format. Default value is 'Y-m-d'. 
  171. * @return string The current date. 
  172. */ 
  173. public static function current_date( $format = null, $ignore_filters = false ) { 
  174. static $Date = array(); 
  175. $key = (string) $format . (int) $ignore_filters; 
  176.  
  177. if ( ! isset( $Date[$key] ) ) { 
  178. if ( empty( $format ) ) { 
  179. $format = self::PERIOD_FORMAT; 
  180.  
  181. $format = apply_filters( 
  182. 'ms_helper_period_current_date_format',  
  183. $format 
  184. ); 
  185.  
  186. $date = gmdate( $format ); 
  187.  
  188. if ( ! $ignore_filters ) { 
  189. $date = apply_filters( 
  190. 'ms_helper_period_current_date',  
  191. $date 
  192. ); 
  193. $Date[$key] = $date; 
  194.  
  195. return $Date[$key]; 
  196.  
  197. /** 
  198. * Return current timestamp. 
  199. * 
  200. * @since 1.0.0 
  201. * @param string $format [ mysql | timestamp | date-format like 'Y-m-d' ]. 
  202. * @return string The current timestamp. 
  203. */ 
  204. public static function current_time( $format = 'mysql', $ignore_filters = false ) { 
  205. static $Time = array(); 
  206. $key = (string) $format . (int) $ignore_filters; 
  207.  
  208. if ( ! isset( $Time[$key] ) ) { 
  209. $time = current_time( $format, 1 ); 
  210.  
  211. if ( ! $ignore_filters ) { 
  212. $time = apply_filters( 
  213. 'ms_helper_period_current_time',  
  214. $time 
  215. ); 
  216.  
  217. $Time[$key] = $time; 
  218.  
  219. return $Time[$key]; 
  220.  
  221. /** 
  222. * Return the existing period types. 
  223. * 
  224. * @since 1.0.0 
  225. * 
  226. * @param string $type [all|singular|plural] 
  227. * @return array The period types and descriptions. 
  228. */ 
  229. public static function get_period_types( $type = 'all' ) { 
  230. $singular = array( 
  231. '1' . self::PERIOD_TYPE_DAYS => __( 'one day', 'membership2' ),  
  232. '1' . self::PERIOD_TYPE_WEEKS => __( 'one week', 'membership2' ),  
  233. '1' . self::PERIOD_TYPE_MONTHS => __( 'one month', 'membership2' ),  
  234. '1' . self::PERIOD_TYPE_YEARS => __( 'one year', 'membership2' ),  
  235. '1-' . self::PERIOD_TYPE_DAYS => __( 'day', 'membership2' ),  
  236. '1-' . self::PERIOD_TYPE_WEEKS => __( 'week', 'membership2' ),  
  237. '1-' . self::PERIOD_TYPE_MONTHS => __( 'month', 'membership2' ),  
  238. '1-' . self::PERIOD_TYPE_YEARS => __( 'year', 'membership2' ),  
  239. ); 
  240. $plural = array( 
  241. self::PERIOD_TYPE_DAYS => __( 'days', 'membership2' ),  
  242. self::PERIOD_TYPE_WEEKS => __( 'weeks', 'membership2' ),  
  243. self::PERIOD_TYPE_MONTHS => __( 'months', 'membership2' ),  
  244. self::PERIOD_TYPE_YEARS => __( 'years', 'membership2' ),  
  245. ); 
  246.  
  247. switch ( $type ) { 
  248. case 'singular': $res = $singular; break; 
  249. case 'plural': $res = $plural; break; 
  250. default: $res = $singular + $plural; break; 
  251.  
  252. return apply_filters( 
  253. 'ms_helper_period_get_periods',  
  254. $res 
  255. ); 
  256.  
  257. /** 
  258. * Get period in days. 
  259. * 
  260. * Convert period in week, month, years to days. 
  261. * 
  262. * @since 1.0.0 
  263. * 
  264. * @param $period The period to convert. 
  265. * 
  266. * @return int The calculated days. 
  267. */ 
  268. public static function get_period_in_days( $unit, $type ) { 
  269. $days = 0; 
  270.  
  271. switch ( $type ) { 
  272. case self::PERIOD_TYPE_DAYS: 
  273. $days = intval( $unit ); 
  274. break; 
  275.  
  276. case self::PERIOD_TYPE_WEEKS: 
  277. $days = intval( $unit ) * 7; 
  278. break; 
  279.  
  280. case self::PERIOD_TYPE_MONTHS: 
  281. $days = intval( $unit ) * 30; 
  282. break; 
  283.  
  284. case self::PERIOD_TYPE_YEARS: 
  285. $days = intval( $unit ) * 365; 
  286. break; 
  287.  
  288. return apply_filters( 
  289. 'ms_helper_period_get_period_in_days',  
  290. $days,  
  291. $type 
  292. ); 
  293.  
  294. public static function get_period_value( $period, $field ) { 
  295. $value = null; 
  296.  
  297. if ( isset( $period[ $field ] ) ) { 
  298. $value = $period[ $field ]; 
  299. } elseif ( 'period_unit' == $field ) { 
  300. $value = 1; 
  301. } elseif ( 'period_type' == $field ) { 
  302. $value = self::PERIOD_TYPE_DAYS; 
  303.  
  304. return apply_filters( 
  305. 'ms_helper_period_get_period_value',  
  306. $value 
  307. ); 
  308.  
  309. public static function get_period_desc( $period, $include_quanity_one = false ) { 
  310. $period_unit = MS_Helper_Period::get_period_value( 
  311. $period,  
  312. 'period_unit' 
  313. ); 
  314. $period_type = MS_Helper_Period::get_period_value( 
  315. $period,  
  316. 'period_type' 
  317. ); 
  318.  
  319. $types = self::get_period_types(); 
  320.  
  321. if ( 1 == $period_unit ) { 
  322. $desc = '%2$s'; 
  323.  
  324. if ( $include_quanity_one ) { 
  325. $period_type = $types['1' . $period_type]; 
  326. } else { 
  327. $period_type = $types['1-' . $period_type]; 
  328. } else { 
  329. $desc = '%1$s %2$s'; 
  330. $desc = sprintf( $desc, $period_unit, $period_type ); 
  331.  
  332. return apply_filters( 
  333. 'ms_helper_period_get_period_desc',  
  334. $desc 
  335. ); 
  336.  
  337. /** 
  338. * Returns a valid value for the specified range-unit. 
  339. * 
  340. * This validation is according to PayPal IPN requiremens: 
  341. * Day -> value will be between 1 - 90 
  342. * Week -> value will be between 1 - 52 
  343. * Month -> value will be between 1 - 24 
  344. * Year -> value will be between 1 - 5 
  345. * 
  346. * @since 1.0.0 
  347. * @param int $value The value to validate 
  348. * @param string $unit Period unit (D/W/M/Y or long days/weeks/...) 
  349. * @return int The validated value 
  350. */ 
  351. public static function validate_range( $value, $unit ) { 
  352. if ( $value <= 1 ) { 
  353. $value = 1; 
  354. } else { 
  355. $unit = strtoupper( $unit[0] ); 
  356. $max = 1; 
  357.  
  358. switch ( $unit ) { 
  359. case 'D': $max = 90; break; 
  360. case 'W': $max = 52; break; 
  361. case 'M': $max = 24; break; 
  362. case 'Y': $max = 5; break; 
  363.  
  364. $value = min( $value, $max ); 
  365.  
  366. return $value; 
  367.  
  368. /** 
  369. * Returns a formated date string 
  370. * 
  371. * @param string $date The date value. 
  372. * @param string $format Optional the format to apply. 
  373. */ 
  374. public static function format_date( $date, $format = null ) { 
  375. if ( empty( $format ) ) { 
  376. $format = get_option( 'date_format' ); 
  377.  
  378. $result = self::get_date_time_value( $format, strtotime( $date ), true, true ); 
  379.  
  380. return apply_filters( 
  381. 'ms_format_date',  
  382. $result,  
  383. $date,  
  384. $format 
  385. ); 
  386.  
  387. public static function get_date_time_value( $format = null, $timestamp = false, $date = true, $time = false, $gmt = true, $zone = false ) { 
  388. $res = ''; 
  389.  
  390. if ( empty( $format ) ) { 
  391. $format = get_option( 'date_format' ); 
  392.  
  393. if ( $timestamp == false ) { 
  394. $str = current_time( 'timestamp' ); 
  395.  
  396. if ( $date ) { 
  397. $res .= date_i18n( $format, $timestamp ); 
  398.  
  399. if ( $time ) { 
  400. $zone_setting = floatval( get_option( 'gmt_offset' ) ); 
  401.  
  402. if ( $gmt ) { 
  403. $gm_offset = $zone_setting * 3600; 
  404. } else { 
  405. $gm_offset = 0; 
  406. $res .= ' ' . date_i18n( get_option( 'time_format' ), $timestamp + $gm_offset ); 
  407.  
  408. if ( $zone ) { 
  409. if ( $zone_setting ) { 
  410. $res .= ' UTC'; 
  411. } else { 
  412. $res .= ' UTC ' . ( $zone_setting > 0 ? '+ ' : '- ' ) . $zone_setting; 
  413.  
  414. return $res; 
.