/class-gf-entryexpiration.php

  1. <?php 
  2.  
  3. GFForms::include_addon_framework(); 
  4.  
  5. /** 
  6. * Gravity Forms Entry Expiration. 
  7. * 
  8. * @since 1.0 
  9. * @author Travis Lopes 
  10. * @copyright Copyright (c) 2016, Travis Lopes 
  11. */ 
  12. class GFEntryExpiration extends GFAddOn { 
  13.  
  14. /** 
  15. * Contains an instance of this class, if available. 
  16. * 
  17. * @since 1.0 
  18. * @access private 
  19. * @var object $_instance If available, contains an instance of this class. 
  20. */ 
  21. private static $_instance = null; 
  22.  
  23. /** 
  24. * Defines the version of Gravity Forms Entry Expiration. 
  25. * 
  26. * @since 1.0 
  27. * @access protected 
  28. * @var string $_version Contains the version, defined from entryexpiration.php 
  29. */ 
  30. protected $_version = GF_ENTRYEXPIRATION_VERSION; 
  31.  
  32. /** 
  33. * Defines the minimum Gravity Forms version required. 
  34. * 
  35. * @since 1.0 
  36. * @access protected 
  37. * @var string $_min_gravityforms_version The minimum version required. 
  38. */ 
  39. protected $_min_gravityforms_version = '1.9.13'; 
  40.  
  41. /** 
  42. * Defines the plugin slug. 
  43. * 
  44. * @since 1.0 
  45. * @access protected 
  46. * @var string $_slug The slug used for this plugin. 
  47. */ 
  48. protected $_slug = 'gravity-forms-entry-expiration'; 
  49.  
  50. /** 
  51. * Defines the main plugin file. 
  52. * 
  53. * @since 1.0 
  54. * @access protected 
  55. * @var string $_path The path to the main plugin file, relative to the plugins folder. 
  56. */ 
  57. protected $_path = 'gravity-forms-entry-expiration/entryexpiration.php'; 
  58.  
  59. /** 
  60. * Defines the full path to this class file. 
  61. * 
  62. * @since 1.0 
  63. * @access protected 
  64. * @var string $_full_path The full path. 
  65. */ 
  66. protected $_full_path = __FILE__; 
  67.  
  68. /** 
  69. * Defines the URL where this Add-On can be found. 
  70. * 
  71. * @since 1.0 
  72. * @access protected 
  73. * @var string The URL of the Add-On. 
  74. */ 
  75. protected $_url = 'http://travislop.es/plugins/gravity-forms-entry-expiration'; 
  76.  
  77. /** 
  78. * Defines the title of this Add-On. 
  79. * 
  80. * @since 1.0 
  81. * @access protected 
  82. * @var string $_title The title of the Add-On. 
  83. */ 
  84. protected $_title = 'Gravity Forms Entry Expiration'; 
  85.  
  86. /** 
  87. * Defines the short title of the Add-On. 
  88. * 
  89. * @since 1.0 
  90. * @access protected 
  91. * @var string $_short_title The short title. 
  92. */ 
  93. protected $_short_title = 'Entry Expiration'; 
  94.  
  95. /** 
  96. * Defines the expiration time types. 
  97. * 
  98. * @since 1.0 
  99. * @access protected 
  100. * @var array $expiration_time_types Expiration time types. 
  101. */ 
  102. protected $expiration_time_types = array( 'hours', 'days', 'weeks', 'months' ); 
  103.  
  104. /** 
  105. * Get instance of this class. 
  106. * 
  107. * @since 1.0 
  108. * @access public 
  109. * @static 
  110. * 
  111. * @return $_instance 
  112. */ 
  113. public static function get_instance() { 
  114.  
  115. if ( null === self::$_instance ) { 
  116. self::$_instance = new self; 
  117.  
  118. return self::$_instance; 
  119.  
  120.  
  121. /** 
  122. * Register needed hooks. 
  123. * 
  124. * @since 1.0 
  125. * @access public 
  126. */ 
  127. public function init() { 
  128.  
  129. parent::init(); 
  130.  
  131. add_filter( 'gform_form_settings', array( $this, 'add_form_setting' ), 10, 2 ); 
  132. add_filter( 'gform_pre_form_settings_save', array( $this, 'save_form_setting' ) ); 
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139. // # PLUGIN SETTINGS ----------------------------------------------------------------------------------------------- 
  140.  
  141. /** 
  142. * Setup plugin settings fields. 
  143. * 
  144. * @since 1.0 
  145. * @access public 
  146. * 
  147. * @return array 
  148. */ 
  149. public function plugin_settings_fields() { 
  150.  
  151. return array( 
  152. array( 
  153. 'title' => '',  
  154. 'description' => '<p>' . esc_html__( 'Gravity Forms Entry Expiration reviews your forms every hour. If the form is selected for entry expiration, any entries older than the timeframe below will be deleted.', 'gravityformsentryexpiration' ) . '</p>',  
  155. 'fields' => array( 
  156. array( 
  157. 'name' => 'gf_entryexpiration_expire_time',  
  158. 'label' => __( 'Delete Entries After', 'gravityformsentryexpiration' ),  
  159. 'type' => 'expiration_time',  
  160. 'class' => 'small',  
  161. 'default_value' => array( 
  162. 'amount' => 30,  
  163. 'type' => 'days',  
  164. ),  
  165. ),  
  166. array( 
  167. 'type' => 'save',  
  168. 'messages' => array( 
  169. 'success' => __( 'Settings have been saved.', 'gravityformsentryexpiration' ),  
  170. ),  
  171. ),  
  172. ),  
  173. ),  
  174. ); 
  175.  
  176.  
  177. /** 
  178. * Entry Expiration time settings field. 
  179. * 
  180. * @since 1.0 
  181. * @access public 
  182. * @param array $field 
  183. * @param bool $echo (default: true) 
  184. * 
  185. * @return string $html 
  186. */ 
  187. public function settings_expiration_time( $field, $echo = true ) { 
  188.  
  189. // Initialize return HTML string. 
  190. $html = ''; 
  191.  
  192. // Initialize amount and type fields. 
  193. $amount_field = $type_field = $field; 
  194.  
  195. // Setup amount field attributes. 
  196. $amount_field['name'] .= '[amount]'; 
  197. $amount_field['input_type'] = 'number'; 
  198.  
  199. // Prepare type choices. 
  200. $type_choices = array(); 
  201. foreach ( $this->expiration_time_types as $type ) { 
  202. $type_choices[] = array( 
  203. 'label' => esc_html( $type ),  
  204. 'value' => esc_html( $type ),  
  205. ); 
  206.  
  207. // Setup type field attributes. 
  208. $type_field['name'] .= '[type]'; 
  209. $type_field['choices'] = $type_choices; 
  210.  
  211. // Display amount and type fields. 
  212. $html .= $this->settings_text( $amount_field, false ); 
  213. $html .= $this->settings_select( $type_field, false ); 
  214.  
  215. // If field ouput should be echoed, echo it. 
  216. if ( $echo ) { 
  217. echo $html; 
  218.  
  219. return $html; 
  220.  
  221.  
  222.  
  223.  
  224.  
  225.  
  226. // # FORM SETTINGS ------------------------------------------------------------------------------------------------- 
  227.  
  228. /** 
  229. * Add Entry Expiration form settings. 
  230. * 
  231. * @since 1.0 
  232. * @access public 
  233. * @param array $settings Form settings. 
  234. * @param array $form Current form object. 
  235. * 
  236. * @return array $settings 
  237. */ 
  238. public function add_form_setting( $settings, $form ) { 
  239.  
  240. $settings['Form Options']['gf_entryexpiration_include'] = '<tr>'; 
  241. $settings['Form Options']['gf_entryexpiration_include'] .= '<th>'; 
  242. $settings['Form Options']['gf_entryexpiration_include'] .= '<label for="gf_entryexpiration_include">'. esc_html__( 'Entry Expiration', 'gravityformsentryexpiration' ) . '</label>'; 
  243. $settings['Form Options']['gf_entryexpiration_include'] .= '<a href="#" onclick="return false;" class="gf_tooltip tooltip tooltip_form_honeypot" title="'. esc_html__( '<h6>Include Entries In Deletion</h6> Selecting this checkbox will include this form\'s entries in being deleted when all old entries are deleted.', 'gravityformsentryexpiration' ) . '"><i class="fa fa-question-circle"></i></a>'; 
  244. $settings['Form Options']['gf_entryexpiration_include'] .= '</th>'; 
  245. $settings['Form Options']['gf_entryexpiration_include'] .= '<td>'; 
  246. $settings['Form Options']['gf_entryexpiration_include'] .= '<input type="checkbox" id="gf_entryexpiration_include" name="gf_entryexpiration_include" value="1" '. checked( '1', rgar( $form, 'gf_entryexpiration_include' ), false ) .' />'; 
  247. $settings['Form Options']['gf_entryexpiration_include'] .= '<label for="gf_entryexpiration_include">'. esc_html__( 'Include entries for expiration', 'gravityformsentryexpiration' ) . '</label>'; 
  248. $settings['Form Options']['gf_entryexpiration_include'] .= '</td>'; 
  249. $settings['Form Options']['gf_entryexpiration_include'] .= '</tr>'; 
  250.  
  251. return $settings; 
  252.  
  253.  
  254. /** 
  255. * Save Entry Expiration form settings. 
  256. * 
  257. * @since 1.0 
  258. * @access public 
  259. * @param array $form Current form object. 
  260. * 
  261. * @return array $form 
  262. */ 
  263. public function save_form_setting( $form ) { 
  264.  
  265. $form['gf_entryexpiration_include'] = sanitize_text_field( rgpost( 'gf_entryexpiration_include' ) ); 
  266. return $form; 
  267.  
  268.  
  269.  
  270.  
  271.  
  272.  
  273. // # ENTRY DELETION ------------------------------------------------------------------------------------------------ 
  274.  
  275. /** 
  276. * Delete old entries. 
  277. * 
  278. * @since 1.0 
  279. * @access public 
  280. */ 
  281. public function delete_old_entries() { 
  282.  
  283. // Get plugin settings. 
  284. $settings = gf_entryexpiration()->get_plugin_settings(); 
  285.  
  286. // If plugin has not been configured yet, do not delete any entries. 
  287. if ( ! rgar( $settings, 'gf_entryexpiration_expire_time' ) ) { 
  288. $this->log_debug( __METHOD__ . '(): Skipping entry deletion because plugin is not configured.' ); 
  289. return; 
  290.  
  291. // Get expiration amount and type. 
  292. $expiration_time_amount = sanitize_text_field( $settings['gf_entryexpiration_expire_time']['amount'] ); 
  293. $expiration_time_type = sanitize_text_field( $settings['gf_entryexpiration_expire_time']['type'] ); 
  294.  
  295. // Validate expiration time type. 
  296. if ( ! in_array( $expiration_time_type, $this->expiration_time_types ) ) { 
  297. $expiration_time_type = $this->expiration_time_types[0]; 
  298.  
  299. // Create expiration time string. 
  300. $expiration_time = $expiration_time_amount . ' ' . $expiration_time_type; 
  301.  
  302. // Setup MySQL timestamp for which entries are older than. 
  303. $older_than = date( 'Y-m-d H:i:s', strtotime( '-'. $expiration_time ) ); 
  304.  
  305. // Get forms. 
  306. $forms = GFAPI::get_forms(); 
  307.  
  308. // Loop through forms. 
  309. foreach ( $forms as $form ) { 
  310.  
  311. // If entry expiration is not enabled for form, skip it. 
  312. if ( ! rgar( $form, 'gf_entryexpiration_include' ) ) { 
  313. $this->log_debug( __METHOD__ . "(): Skipping entry deletion for form #{$form['id']} because it is not enabled." ); 
  314. continue; 
  315.  
  316. /** 
  317. * Filter the entry expiration time. 
  318. * 
  319. * @since 1.2.3 
  320. * 
  321. * @param string $older_than Current entry expiration time. 
  322. * @param array $form Form object. 
  323. */ 
  324. $form_older_than = gf_apply_filters( array( 'gf_entryexpiration_older_than', $form['id'] ), $older_than, $form ); 
  325.  
  326. /** 
  327. * Set the payment status when searching for expired entries. 
  328. * 
  329. * @since 1.1 
  330. * 
  331. * @param string null Payment status. 
  332. * @param array $form Form object. 
  333. */ 
  334. $payment_status = gf_apply_filters( array( 'gf_entryexpiration_payment', $form['id'] ), null, $form ); 
  335.  
  336. // Log the entry search. 
  337. $this->log_debug( __METHOD__ . "(): Searching entries for form #{$form['id']} that were created before {$form_older_than}." ); 
  338.  
  339. // Get entry IDs for form that match search criteria. 
  340. $entry_ids = GFFormsModel::get_lead_ids( 
  341. $form['id'], // $form_id 
  342. '', // $search 
  343. null, // $star 
  344. null, // $read 
  345. null, // $start_date 
  346. $form_older_than, // $end_date 
  347. null, // $status 
  348. $payment_status // $payment_status 
  349. ); 
  350.  
  351. /** 
  352. * Set the entry deletion limit to avoid long execution times. 
  353. * 
  354. * @since 1.1 
  355. * 
  356. * @param int 1000 Entry deletion limit. 
  357. */ 
  358. $deletion_limit = apply_filters( 'gf_entryexpiration_limit', 1000 ); 
  359.  
  360. // Reduce entry IDs to entry deletion limit. 
  361. $entry_ids = array_splice( $entry_ids, 0, $deletion_limit ); 
  362.  
  363. // If entries were found, delete them. 
  364. if ( ! empty( $entry_ids ) ) { 
  365. $this->log_debug( __METHOD__ . "(): Deleting entries for form #{$form['id']}: " . implode( ', ', $entry_ids ) ); 
  366. GFFormsModel::delete_leads( $entry_ids ); 
  367. } else { 
  368. $this->log_debug( __METHOD__ . "(): No entries were found for form #{$form['id']}." ); 
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376. // # UPGRADE ------------------------------------------------------------------------------------------------------- 
  377.  
  378. /** 
  379. * Migrate needed settings. 
  380. * 
  381. * @since 1.1.0 
  382. * @access public 
  383. * @param string $previous_version Version number the plugin is upgrading from. 
  384. */ 
  385. public function upgrade( $previous_version ) { 
  386.  
  387. // Get plugin settings. 
  388. $settings = $this->get_plugin_settings(); 
  389.  
  390. // If existing scheduled event exists and is daily, remove and switch to hourly. 
  391. if ( 'daily' === wp_get_schedule( 'gf_entryexpiration_delete_old_entries' ) ) { 
  392. wp_clear_scheduled_hook( 'gf_entryexpiration_delete_old_entries' ); 
  393. wp_schedule_event( strtotime( 'midnight' ), 'hourly', 'gf_entryexpiration_delete_old_entries' ); 
  394.  
  395. // Upgrade: 1.1.0. 
  396. if ( ! empty( $previous_version ) && version_compare( $previous_version, '1.1.0', '<' ) ) { 
  397.  
  398. // Get the forms. 
  399. $forms = GFAPI::get_forms(); 
  400.  
  401. // Loop through each form and switch to include setting where needed. 
  402. foreach ( $forms as &$form ) { 
  403.  
  404. // If exclude is set, remove. Otherwise, set to include. 
  405. if ( rgar( $form, 'gf_entryexpiration_exclude' ) ) { 
  406. unset( $form['gf_entryexpiration_exclude'] ); 
  407. } else { 
  408. $form['gf_entryexpiration_include'] = '1'; 
  409.  
  410. // Save form. 
  411. GFAPI::update_form( $form ); 
  412.  
  413.  
  414.  
  415. // Upgrade: 1.2.0 
  416. if ( ! empty( $previous_version ) && version_compare( $previous_version, '1.2.0', '<' ) ) { 
  417.  
  418. // Change settings from "days" to allow hours, days, weeks and months. 
  419. $settings['gf_entryexpiration_expire_time'] = array( 
  420. 'amount' => $settings['gf_entryexpiration_days_old'],  
  421. 'type' => 'days' 
  422. ); 
  423.  
  424. // Remove days old setting. 
  425. unset( $settings['gf_entryexpiration_days_old'] ); 
  426.  
  427. // Save settings. 
  428. $this->update_plugin_settings( $settings ); 
  429.  
  430.  
  431.  
.