Submissions.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <?php if ( ! defined( 'ABSPATH' ) ) exit;
  2. /**
  3. * Class NF_Admin_Menus_Submissions
  4. */
  5. final class NF_Admin_Menus_Submissions extends NF_Abstracts_Submenu
  6. {
  7. /**
  8. * @var string
  9. */
  10. public $parent_slug = 'ninja-forms';
  11. /**
  12. * @var string
  13. */
  14. public $page_title = 'Submissions';
  15. /**
  16. * @var string
  17. */
  18. public $menu_slug = 'edit.php?post_type=nf_sub';
  19. /**
  20. * @var null
  21. */
  22. public $function = NULL;
  23. /**
  24. * Constructor
  25. */
  26. public function __construct()
  27. {
  28. parent::__construct();
  29. add_filter( 'manage_nf_sub_posts_columns', array( $this, 'change_columns' ) );
  30. add_action( 'manage_posts_custom_column', array( $this, 'custom_columns' ), 10, 2 );
  31. add_filter('months_dropdown_results', array( $this, 'remove_filter_show_all_dates' ), 9999 );
  32. add_action( 'restrict_manage_posts', array( $this, 'add_filters' ) );
  33. add_filter( 'parse_query', array( $this, 'table_filter' ) );
  34. add_filter( 'posts_clauses', array( $this, 'search' ), 20, 1 );
  35. add_filter( 'bulk_actions-edit-nf_sub', array( $this, 'remove_bulk_edit' ) );
  36. add_action( 'admin_footer-edit.php', array( $this, 'bulk_admin_footer' ) );
  37. add_action( 'load-edit.php', array( $this, 'export_listen' ) );
  38. add_action('admin_head', array( $this, 'hide_page_title_action' ) );
  39. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
  40. // This will only run on our post type.
  41. add_action( 'views_edit-nf_sub', array( $this, 'change_views' ) );
  42. }
  43. /**
  44. * Change Views
  45. * WordPress hook that modifies the links on our submissions CPT to allow
  46. * users to switch between completed and trashed submissions.
  47. * @since 3.2.17
  48. *
  49. * @param $views The views that are associated with this CPT.
  50. * $views[ 'view' ]
  51. * @return array Returns modified views to allow our users access to the trash.
  52. */
  53. public function change_views( $views )
  54. {
  55. // Remove our unused views.
  56. unset( $views[ 'mine' ] );
  57. unset( $views[ 'publish' ] );
  58. // If the Form ID is not empty...
  59. if( ! empty( $_GET[ 'form_id' ] ) ) {
  60. // ...populate the rest of the query string.
  61. $form_id = '&form_id=' . $_GET[ 'form_id' ] . '&nf_form_filter&paged=1';
  62. } else {
  63. // ...otherwise send in an empty string.
  64. $form_id = '';
  65. }
  66. // Build our new views.
  67. $views[ 'all' ] = '<a href="' . admin_url( 'edit.php?post_status=all&post_type=nf_sub' ) . $form_id . '">'
  68. . __( 'Completed', 'ninja-forms' ) . '</a>';
  69. $views[ 'trash' ] = '<a href="' . admin_url( 'edit.php?post_status=trash&post_type=nf_sub' ) . $form_id . '">'
  70. . __( 'Trashed', 'ninja-forms' ) . '</a>';
  71. // Checks to make sure we have a post status.
  72. if( ! empty( $_GET[ 'post_status' ] ) ) {
  73. // Depending on the domain set the value to plain text.
  74. if ( 'all' == $_GET[ 'post_status' ] ) {
  75. $views[ 'all' ] = __( 'Completed', 'ninja-forms' );
  76. } else if ( 'trash' == $_GET[ 'post_status' ] ) {
  77. $views[ 'trash' ] = __( 'Trashed', 'ninja-forms' );
  78. }
  79. }
  80. return $views;
  81. }
  82. public function get_page_title()
  83. {
  84. return __( 'Submissions', 'ninja-forms' );
  85. }
  86. /**
  87. * Display
  88. */
  89. public function display()
  90. {
  91. // This section intentionally left blank.
  92. }
  93. /**
  94. * enqueue scripts here
  95. */
  96. public function enqueue_scripts() {
  97. // let's check and make sure we're on the submissions page.
  98. $test = strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php' );
  99. if( isset( $_GET[ 'post_type' ] ) && 'nf_sub' == $_GET[ 'post_type' ]
  100. && -1 < strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php' )
  101. ) {
  102. wp_enqueue_style( 'nf-admin-settings', Ninja_Forms::$url . 'assets/css/admin-settings.css' );
  103. wp_register_script( 'ninja_forms_admin_submissions',
  104. Ninja_Forms::$url . 'assets/js/admin-submissions.js', array( 'jquery' ), false, true );
  105. wp_enqueue_script( 'ninja_forms_admin_submissions' );
  106. }
  107. }
  108. /**
  109. * Change Columns
  110. *
  111. * @return array
  112. */
  113. public function change_columns()
  114. {
  115. $form_id = ( isset( $_GET['form_id'] ) ) ? $_GET['form_id'] : FALSE;
  116. if( ! $form_id ) return array();
  117. static $cols;
  118. if( $cols ) return $cols;
  119. $cols = array(
  120. 'cb' => '<input type="checkbox" />',
  121. 'seq_num' => __( '#', 'ninja-forms' ),
  122. );
  123. $fields = Ninja_Forms()->form( $form_id )->get_fields();
  124. $hidden_field_types = apply_filters( 'ninja_forms_sub_hidden_field_types', array() );
  125. foreach( $fields as $field ){
  126. if ( is_null( $field ) ) continue;
  127. if( in_array( $field->get_setting( 'type' ), $hidden_field_types ) ) continue;
  128. if ( $field->get_setting( 'admin_label' ) ) {
  129. $cols[ 'field_' . $field->get_id() ] = $field->get_setting( 'admin_label' );
  130. } else {
  131. $cols[ 'field_' . $field->get_id() ] = $field->get_setting( 'label' );
  132. }
  133. }
  134. $cols[ 'sub_date' ] = __( 'Date', 'ninja-forms' );
  135. return $cols;
  136. }
  137. /**
  138. * Custom Columns
  139. *
  140. * @param $column
  141. * @param $sub_id
  142. */
  143. public function custom_columns( $column, $sub_id )
  144. {
  145. $sub = Ninja_Forms()->form()->get_sub( $sub_id );
  146. switch( $column ){
  147. case 'seq_num':
  148. echo $this->custom_columns_seq_num( $sub );
  149. break;
  150. case 'sub_date':
  151. echo $this->custom_columns_sub_date( $sub );
  152. break;
  153. default:
  154. echo $this->custom_columns_field( $sub, $column );
  155. }
  156. }
  157. /**
  158. * Remove Filter: Show All Dates
  159. *
  160. * @param $months
  161. * @return array
  162. */
  163. public function remove_filter_show_all_dates( $months )
  164. {
  165. if( ! isset( $_GET[ 'post_type' ] ) || 'nf_sub' != $_GET[ 'post_type' ] ) return $months;
  166. // Returning an empty array should hide the dropdown.
  167. return array();
  168. }
  169. /**
  170. * Add Filters
  171. *
  172. * @return bool
  173. */
  174. public function add_filters()
  175. {
  176. global $typenow;
  177. // Bail if we aren't in our submission custom post type.
  178. if ( $typenow != 'nf_sub' ) return false;
  179. $forms = Ninja_Forms()->form()->get_forms();
  180. $form_options = array();
  181. foreach( $forms as $form ){
  182. $form_options[ $form->get_id() ] = $form->get_setting( 'title' );
  183. }
  184. $form_options = apply_filters( 'ninja_forms_submission_filter_form_options', $form_options );
  185. asort($form_options);
  186. if( isset( $_GET[ 'form_id' ] ) ) {
  187. $form_selected = $_GET[ 'form_id' ];
  188. } else {
  189. $form_selected = 0;
  190. }
  191. if( isset( $_GET[ 'begin_date' ] ) ) {
  192. $begin_date = $_GET[ 'begin_date' ];
  193. } else {
  194. $begin_date = '';
  195. }
  196. if( isset( $_GET[ 'end_date' ] ) ) {
  197. $end_date = $_GET[ 'end_date' ];
  198. } else {
  199. $end_date = '';
  200. }
  201. Ninja_Forms::template( 'admin-menu-subs-filter.html.php', compact( 'form_options', 'form_selected', 'begin_date', 'end_date' ) );
  202. wp_enqueue_script('jquery-ui-datepicker');
  203. wp_enqueue_style( 'jquery-ui-datepicker', Ninja_Forms::$url .'deprecated/assets/css/jquery-ui-fresh.min.css' );
  204. }
  205. public function table_filter( $query )
  206. {
  207. global $pagenow;
  208. if( $pagenow != 'edit.php' || ! is_admin() || ! isset( $query->query['post_type'] ) || 'nf_sub' != $query->query['post_type'] || ! is_main_query() ) return;
  209. $vars = &$query->query_vars;
  210. $form_id = ( ! empty( $_GET['form_id'] ) ) ? $_GET['form_id'] : 0;
  211. $vars = $this->table_filter_by_form( $vars, $form_id );
  212. $vars = $this->table_filter_by_date( $vars );
  213. $vars = apply_filters( 'ninja_forms_sub_table_qv', $vars, $form_id );
  214. }
  215. public function search( $pieces ) {
  216. global $typenow;
  217. // filter to select search query
  218. if ( is_search() && is_admin() && $typenow == 'nf_sub' && isset ( $_GET['s'] ) ) {
  219. global $wpdb;
  220. $keywords = explode(' ', get_query_var('s'));
  221. $query = "";
  222. foreach ($keywords as $word) {
  223. $query .= " (mypm1.meta_value LIKE '%{$word}%') OR ";
  224. }
  225. if (!empty($query)) {
  226. // Escape place holders for the where clause.
  227. $pieces[ 'where' ] = $wpdb->remove_placeholder_escape( $pieces[ 'where' ] );
  228. // add to where clause
  229. $pieces[ 'where' ] = str_replace("((({$wpdb->posts}.post_title LIKE '%", "({$query}(({$wpdb->posts}.post_title LIKE '%", $pieces[ 'where' ]);
  230. $pieces[ 'join' ] = $pieces[ 'join' ] . " INNER JOIN {$wpdb->postmeta} AS mypm1 ON ({$wpdb->posts}.ID = mypm1.post_id)";
  231. }
  232. }
  233. return ( $pieces );
  234. }
  235. public function remove_bulk_edit( $actions ) {
  236. unset( $actions['edit'] );
  237. return $actions;
  238. }
  239. public function bulk_admin_footer() {
  240. global $post_type;
  241. if ( ! is_admin() )
  242. return false;
  243. if( $post_type == 'nf_sub' && isset ( $_REQUEST['post_status'] ) && $_REQUEST['post_status'] == 'all' ) {
  244. ?>
  245. <script type="text/javascript">
  246. jQuery(document).ready(function() {
  247. jQuery('<option>').val('export').text('<?php _e('Export', 'ninja-forms')?>').appendTo("select[name='action']");
  248. jQuery('<option>').val('export').text('<?php _e('Export', 'ninja-forms')?>').appendTo("select[name='action2']");
  249. <?php
  250. if ( ( isset ( $_POST['action'] ) && $_POST['action'] == 'export' ) || ( isset ( $_POST['action2'] ) && $_POST['action2'] == 'export' ) ) {
  251. ?>
  252. setInterval(function(){
  253. jQuery( "select[name='action'" ).val( '-1' );
  254. jQuery( "select[name='action2'" ).val( '-1' );
  255. jQuery( '#posts-filter' ).submit();
  256. },5000);
  257. <?php
  258. }
  259. if ( isset ( $_REQUEST['form_id'] ) && ! empty ( $_REQUEST['form_id'] ) ) {
  260. $redirect = urlencode( remove_query_arg( array( 'download_all', 'download_file' ) ) );
  261. $url = admin_url( 'admin.php?page=nf-processing&action=download_all_subs&form_id=' . absint( $_REQUEST['form_id'] ) . '&redirect=' . $redirect );
  262. $url = esc_url( $url );
  263. ?>
  264. var button = '<a href="<?php echo $url; ?>" class=<?php __( "button-secondary nf-download-all", 'ninja-forms' ) ;?> . '>' . <?php echo __( 'Download All Submissions', 'ninja-forms' ); ?></a>';
  265. // jQuery( '#doaction2' ).after( button );
  266. <?php
  267. }
  268. if ( isset ( $_REQUEST['download_all'] ) && $_REQUEST['download_all'] != '' ) {
  269. $redirect = esc_url_raw( add_query_arg( array( 'download_file' => esc_html( $_REQUEST['download_all'] ) ) ) );
  270. $redirect = remove_query_arg( array( 'download_all' ), $redirect );
  271. ?>
  272. document.location.href = "<?php echo $redirect; ?>";
  273. <?php
  274. }
  275. ?>
  276. });
  277. </script>
  278. <?php
  279. }
  280. }
  281. public function export_listen()
  282. {
  283. // Bail if we aren't in the admin
  284. if (!is_admin())
  285. return false;
  286. if (!isset ($_REQUEST['form_id']) || empty ($_REQUEST['form_id'])) {
  287. return false;
  288. }
  289. if (isset ($_REQUEST['export_single']) && !empty($_REQUEST['export_single'])) {
  290. Ninja_Forms()->sub(esc_html($_REQUEST['export_single']))->export();
  291. }
  292. if ((isset ($_REQUEST['action']) && $_REQUEST['action'] == 'export') || (isset ($_REQUEST['action2']) && $_REQUEST['action2'] == 'export')) {
  293. $sub_ids = array();
  294. if (isset($_REQUEST['post'])) {
  295. $sub_ids = WPN_Helper::esc_html($_REQUEST['post']);
  296. }
  297. Ninja_Forms()->form( $_REQUEST['form_id'] )->export_subs( $sub_ids );
  298. }
  299. if (isset ($_REQUEST['download_file']) && !empty($_REQUEST['download_file'])) {
  300. // Open our download all file
  301. $filename = esc_html($_REQUEST['download_file']);
  302. $upload_dir = wp_upload_dir();
  303. $file_path = trailingslashit($upload_dir['path']) . $filename . '.csv';
  304. if (file_exists($file_path)) {
  305. $myfile = file_get_contents($file_path);
  306. } else {
  307. $redirect = esc_url_raw(remove_query_arg(array('download_file', 'download_all')));
  308. wp_redirect($redirect);
  309. die();
  310. }
  311. unlink($file_path);
  312. $form_name = Ninja_Forms()->form(absint($_REQUEST['form_id']))->get()->get_setting('title');
  313. $form_name = sanitize_title($form_name);
  314. $today = date('Y-m-d', current_time('timestamp'));
  315. $filename = apply_filters('ninja_forms_download_all_filename', $form_name . '-all-subs-' . $today);
  316. header('Content-type: application/csv');
  317. header('Content-Disposition: attachment; filename="' . $filename . '.csv"');
  318. header('Pragma: no-cache');
  319. header('Expires: 0');
  320. echo $myfile;
  321. die();
  322. }
  323. }
  324. public function hide_page_title_action()
  325. {
  326. // If we are on our the nf_sub post type then....
  327. if( ( isset( $_GET[ 'post_type' ] ) && 'nf_sub' == $_GET[ 'post_type'] ) ||
  328. 'nf_sub' == get_post_type() ) {
  329. // ...then hiding the "Add New" button on the CPT page.
  330. echo '<style type="text/css">.page-title-action, .view-mode{display: none;}</style>';
  331. }
  332. }
  333. /*
  334. * PRIVATE METHODS
  335. */
  336. /**
  337. * Custom Columns: ID
  338. *
  339. * @param $sub
  340. * @return mixed
  341. */
  342. private function custom_columns_seq_num( $sub )
  343. {
  344. return $sub->get_seq_num();
  345. }
  346. /**
  347. * Custom Columns: Submission Date
  348. *
  349. * @param $sub
  350. * @return mixed
  351. */
  352. private function custom_columns_sub_date( $sub )
  353. {
  354. // Grab the date and time format options
  355. $date_format = get_option( 'date_format' );
  356. $time_format = get_option( 'time_format' );
  357. // Get the sub dates using the date and time formats.
  358. return $sub->get_sub_date( $date_format . ' ' . $time_format );
  359. }
  360. /**
  361. * Custom Columns: Field
  362. *
  363. * @param $sub
  364. * @param $column
  365. * @return bool
  366. */
  367. private function custom_columns_field( $sub, $column )
  368. {
  369. if( FALSE === strpos( $column, 'field_' ) ) return FALSE;
  370. $field_id = str_replace( 'field_', '', $column );
  371. return $sub->get_field_value( $field_id );
  372. }
  373. private function table_filter_by_form( $vars, $form_id )
  374. {
  375. if ( ! isset ( $vars['meta_query'] ) ) {
  376. $vars['meta_query'] = array(
  377. array(
  378. 'key' => '_form_id',
  379. 'value' => $form_id,
  380. 'compare' => '=',
  381. ),
  382. );
  383. }
  384. return $vars;
  385. }
  386. private function table_filter_by_date( $vars )
  387. {
  388. if( empty( $_GET[ 'begin_date' ] ) || empty( $_GET[ 'end_date' ] ) ) return $vars;
  389. $begin_date = $_GET[ 'begin_date' ];
  390. $end_date = $_GET[ 'end_date' ];
  391. // Include submissions on the end_date.
  392. $end_date = date( 'm/d/Y', strtotime( '+1 day', strtotime( $end_date ) ) );
  393. if ( ! isset ( $vars['date_query'] ) ) {
  394. $vars['date_query'] = array(
  395. 'after' => $begin_date,
  396. 'before' => $end_date,
  397. 'inclusive' => true,
  398. );
  399. }
  400. return $vars;
  401. }
  402. public function get_capability()
  403. {
  404. return apply_filters( 'ninja_forms_admin_submissions_capabilities', $this->capability );
  405. }
  406. }