notifications.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. <?php if ( ! defined( 'ABSPATH' ) ) exit;
  2. /**
  3. * Main Notifications Class
  4. *
  5. * Adds our notifications to the form edit page.
  6. * Gets notification types
  7. * Listens for ajax commands to delete/activate/deactivate notifications
  8. * Listens for bulk actions from the notifications admin page
  9. * Adds notification types processing to the appropriate action hook
  10. *
  11. * @package Ninja Forms
  12. * @subpackage Classes/Notifications
  13. * @copyright Copyright (c) 2014, WPNINJAS
  14. * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
  15. * @since 2.8
  16. */
  17. class NF_Notifications
  18. {
  19. /**
  20. * Get things rolling
  21. *
  22. * @access public
  23. *
  24. * @since 2.8
  25. */
  26. function __construct() {
  27. global $pagenow;
  28. // Register our notification types
  29. Ninja_Forms()->notification_types['email'] = require_once( NF_PLUGIN_DIR . 'classes/notification-email.php' );
  30. Ninja_Forms()->notification_types['redirect'] = require_once( NF_PLUGIN_DIR . 'classes/notification-redirect.php' );
  31. Ninja_Forms()->notification_types['success_message'] = require_once( NF_PLUGIN_DIR . 'classes/notification-success-message.php' );
  32. Ninja_Forms()->notification_types = apply_filters( 'nf_notification_types', Ninja_Forms()->notification_types );
  33. // Register our notification tab
  34. add_action( 'admin_init', array( $this, 'register_tab' ) );
  35. // Only add these actions if we are actually on the notification tab.
  36. if ( 'admin.php' == $pagenow && isset ( $_REQUEST['page'] ) && $_REQUEST['page'] == 'ninja-forms' && isset ( $_REQUEST['tab'] ) && $_REQUEST['tab'] == 'notifications' ) {
  37. add_action( 'admin_init', array( $this, 'add_js' ) );
  38. add_action( 'admin_init', array( $this, 'add_css' ) );
  39. add_action( 'admin_init', array( $this, 'bulk_actions' ) );
  40. add_action( 'admin_init', array( $this, 'duplicate_notification' ) );
  41. add_filter( 'media_buttons_context', array( $this, 'tinymce_buttons' ) );
  42. }
  43. add_action( 'wp_ajax_nf_delete_notification', array( $this, 'delete_notification' ) );
  44. add_action( 'wp_ajax_nf_activate_notification', array( $this, 'activate_notification' ) );
  45. add_action( 'wp_ajax_nf_deactivate_notification', array( $this, 'deactivate_notification' ) );
  46. // Add our hook to add notification types processors.
  47. add_action( 'ninja_forms_post_process', array( $this, 'notification_processing' ), 999 );
  48. }
  49. /**
  50. * Register our setting tab.
  51. *
  52. * @access public
  53. *
  54. * @since 2.8
  55. * @return void
  56. */
  57. public function register_tab() {
  58. $form_id = isset ( $_REQUEST['form_id'] ) ? absint( $_REQUEST['form_id'] ) : '';
  59. $action = isset ( $_REQUEST['notification-action'] ) ? esc_html( $_REQUEST['notification-action'] ) : '';
  60. $output_form = false;
  61. $show_save = false;
  62. if ( 'edit' == $action || 'new' == $action ) {
  63. $output_form = true;
  64. $show_save = true;
  65. }
  66. $args = array(
  67. 'name' => __( 'Email & Actions', 'ninja-forms' ),
  68. 'page' => 'ninja-forms',
  69. 'display_function' => array( $this, 'output_admin' ),
  70. 'save_function' => array( $this, 'save_admin' ),
  71. 'disable_no_form_id' => true,
  72. 'show_save' => $show_save,
  73. 'tab_reload' => true,
  74. 'output_form' => $output_form,
  75. );
  76. ninja_forms_register_tab( 'notifications', $args );
  77. }
  78. /**
  79. * Enqueue JS
  80. *
  81. * @access public
  82. * @since 2.8
  83. * @return void
  84. */
  85. public function add_js() {
  86. global $ninja_forms_fields;
  87. $form_id = isset ( $_REQUEST['form_id'] ) ? absint( $_REQUEST['form_id'] ) : '';
  88. if ( empty ( $form_id ) )
  89. return false;
  90. if ( defined( 'NINJA_FORMS_JS_DEBUG' ) && NINJA_FORMS_JS_DEBUG ) {
  91. $suffix = '';
  92. $src = 'dev';
  93. } else {
  94. $suffix = '.min';
  95. $src = 'min';
  96. }
  97. wp_enqueue_script( 'nf-notifications',
  98. NF_PLUGIN_URL . 'assets/js/' . $src .'/notifications' . $suffix . '.js',
  99. array( 'jquery', 'jquery-ui-autocomplete' ) );
  100. wp_enqueue_script( 'nf-tokenize',
  101. NF_PLUGIN_URL . 'assets/js/' . $src .'/bootstrap-tokenfield' . $suffix . '.js',
  102. array( 'jquery', 'jquery-ui-autocomplete' ) );
  103. wp_enqueue_script( 'nf-combobox',
  104. NF_PLUGIN_URL . 'assets/js/' . $src .'/combobox' . $suffix . '.js',
  105. array( 'jquery', 'jquery-ui-core', 'jquery-ui-button', 'jquery-ui-autocomplete' ) );
  106. $all_fields = Ninja_Forms()->form( $form_id )->fields;
  107. $process_fields = array();
  108. $search_fields = array();
  109. $search_fields['email'] = array();
  110. $search_fields['name'] = array();
  111. $fields = array();
  112. // Generate our search fields JS var.
  113. foreach( $all_fields as $field_id => $field ) {
  114. $label = esc_attr( nf_get_field_admin_label( $field_id ) );
  115. $fields[ $field_id ] = array( 'field_id' => $field_id, 'label' => $label );
  116. if ( strlen( $label ) > 30 ) {
  117. $tmp_label = substr( $label, 0, 30 );
  118. } else {
  119. $tmp_label = $label;
  120. }
  121. $tmp_array = array( 'value' => 'field_' . $field_id, 'label' => $tmp_label . ' - ID: ' . $field_id );
  122. $admin_label = $label;
  123. $label = isset( $field['data']['label'] ) ? $field['data']['label'] : '';
  124. // Check to see if this field is supposed to be "processed"
  125. $type = $field['type'];
  126. if ( isset ( $ninja_forms_fields[ $type ]['process_field'] ) && $ninja_forms_fields[ $type ]['process_field'] ) {
  127. $process_fields[ $field_id ] = array( 'field_id' => $field_id, 'label' => $label, 'admin_label' => $admin_label );
  128. $search_fields['all'][] = $tmp_array;
  129. }
  130. if ( $field['type'] == '_text' && isset ( $field['data']['email'] ) && $field['data']['email'] == 1 ) {
  131. $search_fields['email'][] = $tmp_array;
  132. } else if ( $field['type'] == '_text' && isset ( $field['data']['first_name'] ) && $field['data']['first_name'] == 1 ) {
  133. $search_fields['name'][] = $tmp_array;
  134. } else if ( $field['type'] == '_text' && isset ( $field['data']['last_name'] ) && $field['data']['last_name'] == 1 ) {
  135. $search_fields['name'][] = $tmp_array;
  136. }
  137. }
  138. // Add our "process_fields" to our form global
  139. Ninja_Forms()->form( $form_id )->process_fields = $process_fields;
  140. $js_vars = apply_filters( 'nf_notification_admin_js_vars', array(
  141. 'activate' => __( 'Activate', 'ninja-forms' ),
  142. 'deactivate' => __( 'Deactivate', 'ninja-forms' ),
  143. 'search_fields' => $search_fields,
  144. 'tokens' => array(),
  145. 'all_fields' => $fields,
  146. 'process_fields' => $process_fields,
  147. 'filter_type' => esc_url_raw( remove_query_arg( array( 'type' ) ) ),
  148. ) );
  149. wp_localize_script( 'nf-notifications', 'nf_notifications', $js_vars );
  150. }
  151. /**
  152. * Enqueue CSS
  153. *
  154. * @access public
  155. * @since 2.8
  156. * @return void
  157. */
  158. public function add_css() {
  159. wp_enqueue_style( 'nf-notifications',
  160. NF_PLUGIN_URL . 'assets/css/notifications.css' );
  161. wp_enqueue_style( 'nf-tokenize',
  162. NF_PLUGIN_URL . 'assets/css/bootstrap-tokenfield.css' );
  163. wp_enqueue_style( 'nf-combobox',
  164. NF_PLUGIN_URL . 'assets/css/combobox.css' );
  165. // wp_enqueue_style( 'nf-bootstrap',
  166. // 'http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css' );
  167. }
  168. /**
  169. * Output our notifications admin.
  170. *
  171. * @access public
  172. *
  173. * @since 2.8
  174. * @return void
  175. */
  176. public function output_admin() {
  177. $action = isset ( $_REQUEST['notification-action'] ) ? esc_html( $_REQUEST['notification-action'] ) : '';
  178. ?>
  179. <div class="wrap">
  180. <?php
  181. if ( '' == $action ) {
  182. ?>
  183. <h2><?php _e( 'Email & Actions', 'ninja-forms' ); ?> <a href="<?php echo esc_url( add_query_arg( array( 'notification-action' => 'new' ) ) ); ?>" class="add-new-h2"><?php _e( 'Add New', 'ninja-forms' );?></a></h2>
  184. <!-- Forms are NOT created automatically, so you need to wrap the table in one to use features like bulk actions -->
  185. <form id="forms-filter" method="get">
  186. <!-- For plugins, we also need to ensure that the form posts back to our current page -->
  187. <input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
  188. <input type="hidden" name="tab" value="<?php echo esc_attr( $_REQUEST['tab'] ); ?>" />
  189. <input type="hidden" name="form_id" value="<?php echo esc_attr( $_REQUEST['form_id'] ); ?>" />
  190. <?php
  191. //Create an instance of our package class...
  192. $nf_all_forms = new NF_Notifications_List_Table();
  193. //Fetch, prepare, sort, and filter our data...
  194. $nf_all_forms->prepare_items();
  195. // Now we can render the completed list table
  196. $nf_all_forms->display();
  197. ?>
  198. </form>
  199. <?php
  200. } else {
  201. $id = isset ( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : '';
  202. if ( $id == '' ) {
  203. $id = 'new';
  204. $this_type = 'email';
  205. $title = __( 'New Action', 'ninja-forms' );
  206. } else {
  207. $this_type = Ninja_Forms()->notification( $id )->type;
  208. $title = __( 'Edit Action', 'ninja-forms' ) . ' - ID ' . $id;
  209. }
  210. ?>
  211. <h2><?php echo $title; ?> <a href="<?php echo esc_url( remove_query_arg( array( 'notification-action', 'id', 'update_message' ) ) );?>" class="button-secondary"><?php _e( 'Back To List', 'ninja-forms' );?></a></h2>
  212. <input type="hidden" id="notification_id" name="notification_id" value="<?php echo $id; ?>" />
  213. <table class="form-table">
  214. <tbody id="notification-main">
  215. <tr>
  216. <th scope="row"><label for="setting-name"><?php _e( 'Action Name', 'ninja-forms' ); ?></label></th>
  217. <td><input name="settings[name]" type="text" id="settings-name" value="<?php echo nf_get_object_meta_value( $id, 'name' ); ?>" class="regular-text"></td>
  218. </tr>
  219. <tr>
  220. <th scope="row"><label for="type"><?php _e( 'Type', 'ninja-forms' ); ?></label></th>
  221. <td>
  222. <select name="settings[type]" id="settings-type">
  223. <?php
  224. foreach ( $this->get_types() as $slug => $nicename ) {
  225. ?>
  226. <option value="<?php echo $slug; ?>" <?php selected ( $this_type, $slug ); ?>><?php echo $nicename; ?></option>
  227. <?php
  228. }
  229. ?>
  230. </select>
  231. <span class="nf-more-actions"><a href="<?php echo nf_aff_link( 'https://ninjaforms.com/extensions/?display=actions&utm_medium=plugin&utm_source=action-single&utm_campaign=Ninja+Forms+Upsell&utm_content=Ninja+Forms+Actions' ); ?>" target="_blank"><?php _e( 'Get More Actions', 'ninja-forms' ); ?> <span class="dashicons dashicons-external"></span></a></span>
  232. </td>
  233. </tr>
  234. </tbody>
  235. <?php
  236. do_action( 'nf_edit_notification_settings', $id );
  237. foreach ( $this->get_types() as $slug => $nicename ) {
  238. if ( $this_type == $slug ) {
  239. $display = '';
  240. } else {
  241. $display = 'display:none;';
  242. }
  243. ?>
  244. <tbody id="notification-<?php echo $slug; ?>" class="notification-type" style="<?php echo $display;?>">
  245. <?php
  246. // Call our type edit screen.
  247. Ninja_Forms()->notification_types[ $slug ]->edit_screen( $id );
  248. ?>
  249. </tbody>
  250. <?php
  251. }
  252. ?>
  253. </table>
  254. <?php
  255. } ?>
  256. </div>
  257. <?php
  258. }
  259. /**
  260. * Save our notifications admin.
  261. *
  262. * @access public
  263. *
  264. * @since 2.8
  265. * @return void
  266. */
  267. public function save_admin( $form_id, $data ) {
  268. if ( ! isset ( $data['notification_id'] ) || empty ( $data['notification_id'] ) )
  269. return false;
  270. $n_id = $data['notification_id'];
  271. $settings = $data['settings'];
  272. if ( 'new' == $n_id ) {
  273. $type = $settings['type'];
  274. $n_id = $this->create( $form_id );
  275. $new = true;
  276. } else {
  277. $type = Ninja_Forms()->notification( $n_id )->type;
  278. $new = false;
  279. }
  280. $data = Ninja_Forms()->notification_types[ $type ]->save_admin( $n_id, $data );
  281. foreach ( $settings as $meta_key => $meta_value ) {
  282. nf_update_object_meta( $n_id, $meta_key, nf_wp_kses_post_deep( $meta_value ) );
  283. }
  284. do_action( 'nf_save_notification', $n_id, $data, $new );
  285. if ( $new ) {
  286. $redirect = esc_url_raw( remove_query_arg( array( 'notification-action' ) ) );
  287. $redirect = esc_url_raw( add_query_arg( array( 'id' => $n_id, 'notification-action' => 'edit', 'update_message' => urlencode( __( 'Action Updated', 'ninja-forms' ) ) ), $redirect ) );
  288. wp_redirect( $redirect );
  289. die();
  290. }
  291. return __( 'Action Updated', 'ninja-forms' );
  292. }
  293. /**
  294. * Get our registered notification types
  295. *
  296. * @access public
  297. * @since 2.8
  298. * @return array $types
  299. */
  300. public function get_types() {
  301. $types = array();
  302. foreach ( Ninja_Forms()->notification_types as $slug => $object ) {
  303. $types[ $slug ] = $object->name;
  304. }
  305. return $types;
  306. }
  307. /**
  308. * Delete a notification.
  309. * Hooked into the ajax action for nf_delete_notification
  310. *
  311. * @access public
  312. * @since 2.8
  313. * @return void
  314. */
  315. public function delete_notification() {
  316. // Bail if our nonce doesn't verify.
  317. check_ajax_referer( 'nf_ajax', 'nf_ajax_nonce' );
  318. $n_id = absint( $_REQUEST['n_id'] );
  319. Ninja_Forms()->notification( $n_id )->delete();
  320. }
  321. /**
  322. * Activate a notification.
  323. * Hooked into the ajax action for nf_activate_notification
  324. *
  325. * @access public
  326. * @since 2.8
  327. * @return void
  328. */
  329. public function activate_notification() {
  330. // Bail if our nonce doesn't verify.
  331. check_ajax_referer( 'nf_ajax', 'nf_ajax_nonce' );
  332. $n_id = absint( $_REQUEST['n_id'] );
  333. Ninja_Forms()->notification( $n_id )->activate();
  334. }
  335. /**
  336. * Deactivate a notification.
  337. * Hooked into the ajax action for nf_deactivate_notification
  338. *
  339. * @access public
  340. * @since 2.8
  341. * @return void
  342. */
  343. public function deactivate_notification() {
  344. // Bail if our nonce doesn't verify.
  345. check_ajax_referer( 'nf_ajax', 'nf_ajax_nonce' );
  346. $n_id = absint( $_REQUEST['n_id'] );
  347. Ninja_Forms()->notification( $n_id )->deactivate();
  348. }
  349. /**
  350. * Duplicate our notification
  351. *
  352. * @access public
  353. * @since 2.8
  354. * @return void
  355. */
  356. public function duplicate_notification() {
  357. if ( ! isset ( $_REQUEST['notification-action'] ) || $_REQUEST['notification-action'] != 'duplicate' )
  358. return false;
  359. $n_id = isset ( $_REQUEST['id'] ) ? absint( $_REQUEST['id'] ) : '';
  360. // Bail if we don't have an ID.
  361. if ( '' === $n_id )
  362. return false;
  363. Ninja_Forms()->notification( $n_id )->duplicate();
  364. wp_redirect( esc_url_raw( remove_query_arg( array( 'notification-action' ) ) ) );
  365. die();
  366. }
  367. /**
  368. * Create a new notification
  369. *
  370. * @access public
  371. * @since 2.8
  372. * @return int $n_id
  373. */
  374. public function create( $form_id = '' ) {
  375. // Bail if we don't have a form_id
  376. if ( '' == $form_id )
  377. return false;
  378. $n_id = nf_insert_notification( $form_id );
  379. // Activate our new notification
  380. Ninja_Forms()->notification( $n_id )->activate();
  381. return $n_id;
  382. }
  383. /**
  384. * Handle bulk actions
  385. *
  386. * @access public
  387. * @since 2.8
  388. * @return void
  389. */
  390. public function bulk_actions() {
  391. $action = '';
  392. if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] )
  393. $action = esc_html( $_REQUEST['action2'] );
  394. if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )
  395. $action = esc_html( $_REQUEST['action'] );
  396. $n_ids = isset ( $_REQUEST['notification'] ) ? esc_html( $_REQUEST['notification'] ) : '';
  397. if ( ! is_array( $n_ids ) || empty( $n_ids ) )
  398. return false;
  399. if( 'delete' === $action ) {
  400. foreach ( $n_ids as $n_id ) {
  401. Ninja_Forms()->notification( $n_id )->delete();
  402. }
  403. } else if ( 'activate' === $action ) {
  404. foreach ( $n_ids as $n_id ) {
  405. Ninja_Forms()->notification( $n_id )->activate();
  406. }
  407. } else if ( 'deactivate' === $action ) {
  408. foreach ( $n_ids as $n_id ) {
  409. Ninja_Forms()->notification( $n_id )->deactivate();
  410. }
  411. }
  412. wp_redirect( esc_url_raw( remove_query_arg( array( 'notification', '_wpnonce', '_wp_http_referer', 'action', 'action2' ) ) ) );
  413. die();
  414. }
  415. /**
  416. * Output our tinyMCE field buttons
  417. *
  418. * @access public
  419. * @since 2.8
  420. * @return void
  421. */
  422. public function tinymce_buttons( $context ) {
  423. $form_id = isset ( $_REQUEST['form_id'] ) ? absint( $_REQUEST['form_id'] ) : '';
  424. if ( empty ( $form_id ) )
  425. return $context;
  426. $all_fields = Ninja_Forms()->form( $form_id )->process_fields;
  427. $first_option = __( 'Select a field or type to search', 'ninja-forms' );
  428. $fields = array();
  429. $html = '<select class="nf-fields-combobox" data-first-option="' . $first_option . '">';
  430. $html .= '<option value="">' . $first_option .'</option>';
  431. foreach( $all_fields as $field_id => $field ) {
  432. $label = esc_html( $field['label'] );
  433. if ( strlen( $label ) > 30 )
  434. $label = substr( $label, 0, 30 ) . '...';
  435. $html .= '<option value="' . $field_id . '">' . $label . ' - ID: ' . $field_id . '</option>';
  436. }
  437. $html .= '</select>';
  438. $html .= ' <a href="#" class="button-secondary nf-insert-field">' . __( 'Insert Field', 'ninja-forms' ) . '</a> <a href="#" class="button-secondary nf-insert-all-fields">' . __( 'Insert All Fields', 'ninja-forms' ) . '</a>';
  439. return $html;
  440. }
  441. /**
  442. * Loop through our notifications and add their processing functions to the appropriate hook.
  443. *
  444. * @access public
  445. * @since 2.8
  446. * @return void
  447. */
  448. public function notification_processing() {
  449. global $ninja_forms_processing;
  450. $form_id = $ninja_forms_processing->get_form_ID();
  451. $notifications = nf_get_notifications_by_form_id( $form_id, false );
  452. if ( is_array( $notifications ) ) {
  453. foreach ( $notifications as $id ) {
  454. do_action( 'nf_notification_before_process', $id );
  455. if ( Ninja_Forms()->notification( $id )->active ) {
  456. Ninja_Forms()->notification( $id )->process();
  457. }
  458. }
  459. }
  460. }
  461. }