PageRenderTime 193ms CodeModel.GetById 15ms RepoModel.GetById 6ms app.codeStats 2ms

/plugins/gravityforms/notification.php

https://github.com/ttimsmith/Anythin-Goes
PHP | 1068 lines | 832 code | 179 blank | 57 comment | 133 complexity | 5acc4b91cdd5a10f63fd4d6453cde454 MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. Class GFNotification {
  3. private static $supported_fields = array("checkbox", "radio", "select", "text", "website", "textarea", "email", "hidden", "number", "phone", "multiselect", "post_title",
  4. "post_tags", "post_custom_field", "post_content", "post_excerpt");
  5. private static function get_notification($form, $notification_id){
  6. foreach($form["notifications"] as $id => $notification){
  7. if($id == $notification_id){
  8. return $notification;
  9. }
  10. }
  11. return array();
  12. }
  13. public static function notification_page() {
  14. $form_id = rgget('id');
  15. $notification_id = rgget("nid");
  16. if(!rgblank($notification_id))
  17. self::notification_edit_page($form_id, $notification_id);
  18. else
  19. self::notification_list_page($form_id);
  20. }
  21. public static function notification_edit_page($form_id, $notification_id) {
  22. if(!rgempty("gform_notification_id"))
  23. $notification_id = rgpost("gform_notification_id");
  24. $form = RGFormsModel::get_form_meta($form_id);
  25. $notification = !$notification_id ? array() : self::get_notification($form, $notification_id);
  26. // added second condition to account for new notifications with errors as notification ID will
  27. // be available in $_POST but the notification has not actually been saved yet
  28. $is_new_notification = empty($notification_id) || empty($notification);
  29. $is_valid = true;
  30. $is_update = false;
  31. if(rgpost("save")){
  32. check_admin_referer('gforms_save_notification', 'gforms_save_notification');
  33. $is_update = true;
  34. if($is_new_notification){
  35. $notification_id = uniqid();
  36. $notification["id"] = $notification_id;
  37. }
  38. $notification["name"] = rgpost("gform_notification_name");
  39. $notification["event"] = rgpost("gform_notification_event");
  40. $notification["to"] = rgpost("gform_notification_to_type") == "field" ? rgpost("gform_notification_to_field") : rgpost("gform_notification_to_email");
  41. $notification["toType"] = rgpost("gform_notification_to_type");
  42. $notification["bcc"] = rgpost("gform_notification_bcc");
  43. $notification["subject"] = rgpost("gform_notification_subject");
  44. $notification["message"] = rgpost("gform_notification_message");
  45. $notification["from"] = rgpost("gform_notification_from");
  46. $notification["fromName"] = rgpost("gform_notification_from_name");
  47. $notification["replyTo"] = rgpost("gform_notification_reply_to");
  48. $notification["routing"] = !rgempty("gform_routing_meta") ? GFCommon::json_decode(rgpost("gform_routing_meta"), true) : null;
  49. $notification["conditionalLogic"] = !rgempty("gform_conditional_logic_meta") ? GFCommon::json_decode(rgpost("gform_conditional_logic_meta"), true) : null;
  50. $notification["disableAutoformat"] = rgpost("gform_notification_disable_autoformat");
  51. $notification = apply_filters( 'gform_pre_notification_save', apply_filters( "gform_pre_notification_save{$form['id']}", $notification, $form ), $form );
  52. //validating input...
  53. $is_valid = self::validate_notification();
  54. if($is_valid){
  55. //input valid, updating...
  56. //emptying notification email if it is supposed to be disabled
  57. if($_POST["gform_notification_to_type"] == "routing")
  58. $notification["to"] = "";
  59. else
  60. $notification["routing"] = null;
  61. $form["notifications"][$notification_id] = $notification;
  62. RGFormsModel::save_form_notifications($form_id, $form['notifications']);
  63. }
  64. }
  65. if($is_update && $is_valid){
  66. GFCommon::add_message( sprintf( __('Notification saved successfully. %sBack to notifications.%s', 'gravityforms'), '<a href="' . remove_query_arg('nid') . '">', '</a>') );
  67. }
  68. else if($is_update && !$is_valid){
  69. GFCommon::add_error_message(__('Notification could not be updated. Please enter all required information below.', 'gravityforms'));
  70. }
  71. // moved page header loading here so the admin messages can be set upon saving and available for the header to print out
  72. GFFormSettings::page_header(__('Notifications', 'gravityforms'));
  73. $notification_ui_settings = self::get_notification_ui_settings($notification);
  74. ?>
  75. <link rel="stylesheet" href="<?php echo GFCommon::get_base_url()?>/css/admin.css?ver=<?php echo GFCommon::$version ?>" />
  76. <script type="text/javascript">
  77. <?php GFCommon::gf_vars(); ?>
  78. var gform_has_unsaved_changes = false;
  79. jQuery(document).ready(function(){
  80. jQuery("#entry_form input, #entry_form textarea, #entry_form select").change(function(){
  81. gform_has_unsaved_changes = true;
  82. });
  83. window.onbeforeunload = function(){
  84. if (gform_has_unsaved_changes){
  85. return "You have unsaved changes.";
  86. }
  87. }
  88. ToggleConditionalLogic(true, 'notification');
  89. if(jQuery(document).on){
  90. jQuery(document).on('change', '.gfield_routing_value_dropdown', function(){
  91. SetRoutingValueDropDown(jQuery(this));
  92. });
  93. }
  94. else{
  95. jQuery('.gfield_routing_value_dropdown').live('change', function(){
  96. SetRoutingValueDropDown(jQuery(this));
  97. });
  98. }
  99. });
  100. <?php
  101. if(empty($form["notifications"]))
  102. $form["notifications"] = array();
  103. ?>
  104. var form = <?php echo GFCommon::json_encode($form) ?>;
  105. var current_notification = <?php echo GFCommon::json_encode($notification) ?>;
  106. function SetRoutingValueDropDown(element){
  107. //parsing ID to get routing Index
  108. var index = element.attr("id").replace("routing_value_", "");
  109. SetRouting(index);
  110. }
  111. /*
  112. REMOVE:
  113. function InsertVariable(element_id, callback, variable){
  114. if(!variable)
  115. variable = jQuery('#' + element_id + '_variable_select').val();
  116. var messageElement = jQuery("#" + element_id);
  117. if(document.selection) {
  118. // Go the IE way
  119. messageElement[0].focus();
  120. document.selection.createRange().text=variable;
  121. }
  122. else if(messageElement[0].selectionStart) {
  123. // Go the Gecko way
  124. obj = messageElement[0]
  125. obj.value = obj.value.substr(0, obj.selectionStart) + variable + obj.value.substr(obj.selectionEnd, obj.value.length);
  126. }
  127. else {
  128. messageElement.val(variable + messageElement.val());
  129. }
  130. jQuery('#' + element_id + '_variable_select')[0].selectedIndex = 0;
  131. if(callback && window[callback]){
  132. window[callback].call(null, element_id, variable);
  133. }
  134. }*/
  135. function CreateRouting(routings){
  136. var str = "";
  137. for(var i=0; i< routings.length; i++){
  138. var isSelected = routings[i].operator == "is" ? "selected='selected'" :"";
  139. var isNotSelected = routings[i].operator == "isnot" ? "selected='selected'" :"";
  140. var greaterThanSelected = routings[i].operator == ">" ? "selected='selected'" :"";
  141. var lessThanSelected = routings[i].operator == "<" ? "selected='selected'" :"";
  142. var containsSelected = routings[i].operator == "contains" ? "selected='selected'" :"";
  143. var startsWithSelected = routings[i].operator == "starts_with" ? "selected='selected'" :"";
  144. var endsWithSelected = routings[i].operator == "ends_with" ? "selected='selected'" :"";
  145. var email = routings[i]["email"] ? routings[i]["email"] : '';
  146. str += "<div style='width:99%'><?php _e("Send to", "gravityforms") ?> <input type='text' id='routing_email_" + i +"' value='" + email + "' onkeyup='SetRouting(" + i + ");'/>";
  147. str += " <?php _e("if", "gravityforms") ?> " + GetRoutingFields(i, routings[i].fieldId);
  148. str += "<select id='routing_operator_" + i + "' onchange='SetRouting(" + i + ");' class='gform_routing_operator'>";
  149. str += "<option value='is' " + isSelected + "><?php _e("is", "gravityforms") ?></option>";
  150. str += "<option value='isnot' " + isNotSelected + "><?php _e("is not", "gravityforms") ?></option>";
  151. str += "<option value='>' " + greaterThanSelected + "><?php _e("greater than", "gravityforms") ?></option>";
  152. str += "<option value='<' " + lessThanSelected + "><?php _e("less than", "gravityforms") ?></option>";
  153. str += "<option value='contains' " + containsSelected + "><?php _e("contains", "gravityforms") ?></option>";
  154. str += "<option value='starts_with' " + startsWithSelected + "><?php _e("starts with", "gravityforms") ?></option>";
  155. str += "<option value='ends_with' " + endsWithSelected + "><?php _e("ends with", "gravityforms") ?></option>";
  156. str += "</select>";
  157. str += GetRoutingValues(i, routings[i].fieldId, routings[i].value);
  158. str += "<img src='<?php echo GFCommon::get_base_url() ?>/images/add.png' class='add_field_choice' title='add another rule' alt='add another rule' style='cursor:pointer; margin:0 3px;' onclick=\"InsertRouting(" + (i+1) + ");\" />";
  159. if(routings.length > 1 )
  160. str += "<img src='<?php echo GFCommon::get_base_url() ?>/images/remove.png' title='remove this rule' alt='remove this rule' class='delete_field_choice' style='cursor:pointer;' onclick=\"DeleteRouting(" + i + ");\" /></li>";
  161. str += "</div>";
  162. }
  163. jQuery("#gform_notification_to_routing_rules").html(str);
  164. }
  165. function GetRoutingValues(index, fieldId, selectedValue){
  166. str = GetFieldValues(index, fieldId, selectedValue, 16);
  167. return str;
  168. }
  169. function GetRoutingFields(index, selectedItem){
  170. var str = "<select id='routing_field_id_" + index + "' class='gfield_routing_select' onchange='jQuery(\"#routing_value_" + index + "\").replaceWith(GetRoutingValues(" + index + ", jQuery(this).val())); SetRouting(" + index + "); '>";
  171. str += GetSelectableFields(selectedItem, 16);
  172. str += "</select>";
  173. return str;
  174. }
  175. //---------------------- generic ---------------
  176. function GetSelectableFields(selectedFieldId, labelMaxCharacters){
  177. var str = "";
  178. var inputType;
  179. for(var i=0; i<form.fields.length; i++){
  180. inputType = form.fields[i].inputType ? form.fields[i].inputType : form.fields[i].type;
  181. //see if this field type can be used for conditionals
  182. if (IsNotificationConditionalLogicField(form.fields[i])) {
  183. var selected = form.fields[i].id == selectedFieldId ? "selected='selected'" : "";
  184. str += "<option value='" + form.fields[i].id + "' " + selected + ">" + form.fields[i].label + "</option>";
  185. }
  186. }
  187. return str;
  188. }
  189. function IsNotificationConditionalLogicField(field){
  190. //this function is a duplicate of IsConditionalLogicField from form_editor.js
  191. inputType = field.inputType ? field.inputType : field.type;
  192. var supported_fields = ["checkbox", "radio", "select", "text", "website", "textarea", "email", "hidden", "number", "phone", "multiselect", "post_title",
  193. "post_tags", "post_custom_field", "post_content", "post_excerpt"];
  194. var index = jQuery.inArray(inputType, supported_fields);
  195. return index >= 0;
  196. }
  197. function GetFirstSelectableField(){
  198. var inputType;
  199. for(var i=0; i<form.fields.length; i++){
  200. inputType = form.fields[i].inputType ? form.fields[i].inputType : form.fields[i].type;
  201. if (IsNotificationConditionalLogicField(form.fields[i])){
  202. return form.fields[i].id;
  203. }
  204. }
  205. return 0;
  206. }
  207. function TruncateMiddle(text, maxCharacters){
  208. if(!text)
  209. return "";
  210. if(text.length <= maxCharacters)
  211. return text;
  212. var middle = parseInt(maxCharacters / 2);
  213. return text.substr(0, middle) + "..." + text.substr(text.length - middle, middle);
  214. }
  215. function GetFieldValues(index, fieldId, selectedValue, labelMaxCharacters){
  216. if(!fieldId)
  217. fieldId = GetFirstSelectableField();
  218. if(!fieldId)
  219. return "";
  220. var str = "";
  221. var field = GetFieldById(fieldId);
  222. var isAnySelected = false;
  223. if(!field)
  224. return "";
  225. if(field["type"] == "post_category" && field["displayAllCategories"]){
  226. var dropdown_id = "routing_value_" + index;
  227. var dropdown = jQuery('#' + dropdown_id + ".gfield_category_dropdown");
  228. //don't load category drop down if it already exists (to avoid unecessary ajax requests)
  229. if(dropdown.length > 0){
  230. var options = dropdown.html();
  231. options = options.replace("value=\"" + selectedValue + "\"", "value=\"" + selectedValue + "\" selected=\"selected\"");
  232. str = "<select id='" + dropdown_id + "' class='gfield_routing_select gfield_category_dropdown gfield_routing_value_dropdown'>" + options + "</select>";
  233. }
  234. else{
  235. //loading categories via AJAX
  236. jQuery.post(ajaxurl,{ action:"gf_get_notification_post_categories",
  237. ruleIndex: index,
  238. selectedValue: selectedValue},
  239. function(dropdown_string){
  240. if(dropdown_string){
  241. jQuery('#gfield_ajax_placeholder_' + index).replaceWith(dropdown_string.trim());
  242. }
  243. }
  244. );
  245. //will be replaced by real drop down during the ajax callback
  246. str = "<select id='gfield_ajax_placeholder_" + index + "' class='gfield_routing_select'><option><?php _e("Loading...", "gravityforms"); ?></option></select>";
  247. }
  248. }
  249. else if(field.choices){
  250. //create a drop down for fields that have choices (i.e. drop down, radio, checkboxes, etc...)
  251. str = "<select class='gfield_routing_select gfield_routing_value_dropdown' id='routing_value_" + index + "'>";
  252. for(var i=0; i<field.choices.length; i++){
  253. var choiceValue = field.choices[i].value ? field.choices[i].value : field.choices[i].text;
  254. var isSelected = choiceValue == selectedValue;
  255. var selected = isSelected ? "selected='selected'" : "";
  256. if(isSelected)
  257. isAnySelected = true;
  258. str += "<option value='" + choiceValue.replace(/'/g, "&#039;") + "' " + selected + ">" + field.choices[i].text + "</option>";
  259. }
  260. if(!isAnySelected && selectedValue){
  261. str += "<option value='" + selectedValue.replace(/'/g, "&#039;") + "' selected='selected'>" + selectedValue + "</option>";
  262. }
  263. str += "</select>";
  264. }
  265. else
  266. {
  267. selectedValue = selectedValue ? selectedValue.replace(/'/g, "&#039;") : "";
  268. //create a text field for fields that don't have choices (i.e text, textarea, number, email, etc...)
  269. str = "<input type='text' placeholder='<?php _e("Enter value", "gravityforms"); ?>' class='gfield_routing_select' id='routing_value_" + index + "' value='" + selectedValue.replace(/'/g, "&#039;") + "' onchange='SetRouting(" + index + ");' onkeyup='SetRouting(" + index + ");'>";
  270. }
  271. return str;
  272. }
  273. function GetFieldById(fieldId){
  274. for(var i=0; i<form.fields.length; i++){
  275. if(form.fields[i].id == fieldId)
  276. return form.fields[i];
  277. }
  278. return null;
  279. }
  280. //---------------------------------------------------------------------------------
  281. function InsertRouting(index){
  282. var routings = current_notification.routing;
  283. routings.splice(index, 0, new ConditionalRule());
  284. CreateRouting(routings);
  285. SetRouting(index);
  286. }
  287. function SetRouting(ruleIndex){
  288. if(!current_notification.routing && ruleIndex == 0)
  289. current_notification.routing = [new ConditionalRule()];
  290. current_notification.routing[ruleIndex]["email"] = jQuery("#routing_email_" + ruleIndex).val();
  291. current_notification.routing[ruleIndex]["fieldId"] = jQuery("#routing_field_id_" + ruleIndex).val();
  292. current_notification.routing[ruleIndex]["operator"] = jQuery("#routing_operator_" + ruleIndex).val();
  293. current_notification.routing[ruleIndex]["value"] =jQuery("#routing_value_" + ruleIndex).val();
  294. var json = jQuery.toJSON(current_notification.routing);
  295. jQuery('#gform_routing_meta').val(json);
  296. }
  297. function DeleteRouting(ruleIndex){
  298. current_notification.routing.splice(ruleIndex, 1);
  299. CreateRouting(current_notification.routing);
  300. }
  301. function SetConditionalLogic(isChecked){
  302. current_notification.conditionalLogic = isChecked ? new ConditionalLogic() : null;
  303. }
  304. function SaveJSMeta(){
  305. jQuery('#gform_routing_meta').val(jQuery.toJSON(current_notification.routing));
  306. jQuery('#gform_conditional_logic_meta').val(jQuery.toJSON(current_notification.conditionalLogic));
  307. }
  308. </script>
  309. <form method="post" id="gform_notification_form" onsubmit="gform_has_unsaved_changes = false; SaveJSMeta();">
  310. <?php wp_nonce_field('gforms_save_notification', 'gforms_save_notification') ?>
  311. <input type="hidden" id="gform_routing_meta" name="gform_routing_meta" />
  312. <input type="hidden" id="gform_conditional_logic_meta" name="gform_conditional_logic_meta" />
  313. <input type="hidden" id="gform_notification_id" name="gform_notification_id" value="<?php echo $notification_id ?>" />
  314. <table class="form-table gform_nofification_edit">
  315. <?php array_map(array('GFFormSettings', 'output'), $notification_ui_settings); ?>
  316. </table>
  317. <p class="submit">
  318. <?php
  319. $button_label = $is_new_notification ? __("Save Notification", "gravityforms") : __("Update Notification", "gravityforms");
  320. $notification_button = '<input class="button-primary" type="submit" value="' . $button_label . '" name="save"/>';
  321. echo apply_filters("gform_save_notification_button", $notification_button);
  322. ?>
  323. </p>
  324. </form>
  325. <?php
  326. }
  327. public static function notification_list_page($form_id) {
  328. // handle form actions
  329. self::maybe_process_notification_list_action();
  330. $form = RGFormsModel::get_form_meta($form_id);
  331. GFFormSettings::page_header(__('Notifications', 'gravityforms'));
  332. $add_new_url = add_query_arg(array("nid" => 0));
  333. ?>
  334. <h3><span>
  335. <?php _e("Notifications", "gravityforms") ?>
  336. <a id="add-new-confirmation" class="add-new-h2" href="<?php echo $add_new_url?>"><?php _e("Add New", "gravityforms") ?></a>
  337. </span></h3>
  338. <?php
  339. $notification_table = new GFNotificationTable($form);
  340. $notification_table->prepare_items();
  341. ?>
  342. <form id="notification_list_form" method="post">
  343. <?php $notification_table->display(); ?>
  344. <input id="action_argument" name="action_argument" type="hidden" />
  345. <input id="action" name="action" type="hidden" />
  346. <?php wp_nonce_field('gform_notification_list_action', 'gform_notification_list_action') ?>
  347. </form>
  348. <?php
  349. GFFormSettings::page_footer();
  350. }
  351. public static function maybe_process_notification_list_action() {
  352. if( empty($_POST) || !check_admin_referer('gform_notification_list_action', 'gform_notification_list_action') )
  353. return;
  354. $action = rgpost('action');
  355. $object_id = rgpost('action_argument');
  356. require_once(GFCommon::get_base_path() . '/notification.php');
  357. switch($action) {
  358. case 'delete':
  359. $notification_deleted = GFNotification::delete_notification($object_id, rgget('id'));
  360. if($notification_deleted) {
  361. GFCommon::add_message( __('Notification deleted.', 'gravityforms') );
  362. } else {
  363. GFCommon::add_error_message( __('There was an issue deleting this notification.', 'gravityforms') );
  364. }
  365. break;
  366. }
  367. }
  368. private static function get_notification_ui_settings($notification) {
  369. /**
  370. * These variables are used to convenient "wrap" child form settings in the appropriate HTML.
  371. */
  372. $subsetting_open = '
  373. <td colspan="2" class="gf_sub_settings_cell">
  374. <div class="gf_animate_sub_settings">
  375. <table>
  376. <tr>';
  377. $subsetting_close = '
  378. </tr>
  379. </table>
  380. </div>
  381. </td>';
  382. $ui_settings = array();
  383. $form_id = rgget('id');
  384. $form = RGFormsModel::get_form_meta($form_id);
  385. $form = apply_filters("gform_admin_pre_render_" . $form_id, apply_filters("gform_admin_pre_render", $form));
  386. $is_valid = empty(GFCommon::$errors);
  387. ob_start(); ?>
  388. <tr valign="top">
  389. <th scope="row">
  390. <label for="gform_notification_name">
  391. <?php _e("Name", "gravityforms"); ?>
  392. <?php gform_tooltip("notification_name") ?>
  393. </label>
  394. </th>
  395. <td>
  396. <input type="text" class="fieldwidth-2" name="gform_notification_name" id="gform_notification_name" value="<?php echo esc_attr(rgget("name", $notification)) ?>"/>
  397. </td>
  398. </tr> <!-- / name -->
  399. <?php $ui_settings['notification_name'] = ob_get_contents(); ob_clean(); ?>
  400. <?php
  401. $notification_events = apply_filters("gform_notification_events", array("form_submission" => __("Form is submitted", "gravityforms")));
  402. $event_style = count($notification_events) == 1 ? "style='display:none'" : "";
  403. ?>
  404. <tr valign="top" <?php echo $event_style ?>>
  405. <th scope="row">
  406. <label for="gform_notification_event">
  407. <?php _e("Event", "gravityforms"); ?>
  408. <?php gform_tooltip("notification_event") ?>
  409. </label>
  410. </th>
  411. <td>
  412. <select name="gform_notification_event" id="gform_notification_event">
  413. <?php
  414. foreach($notification_events as $code => $label){
  415. ?>
  416. <option value="<?php echo esc_attr($code) ?>" <?php selected( rgar( $notification, 'event' ), $code)?>><?php echo esc_html($label) ?></option>
  417. <?php
  418. }
  419. ?>
  420. </select>
  421. </td>
  422. </tr> <!-- / event -->
  423. <?php $ui_settings['notification_event'] = ob_get_contents(); ob_clean(); ?>
  424. <?php
  425. $notification_to_type = !rgempty("gform_notification_to_type") ? rgpost("gform_notification_to_type") : rgar($notification,"toType");
  426. if(empty($notification_to_type))
  427. $notification_to_type = "email";
  428. $is_invalid_email_to = !$is_valid && !self::is_valid_admin_to();
  429. $send_to_class = $is_invalid_email_to ? "gfield_error" : "";
  430. ?>
  431. <tr valign="top" class='<?php echo $send_to_class ?>'>
  432. <th scope="row">
  433. <label for="gform_notification_to_email">
  434. <?php _e("Send To", "gravityforms"); ?><span class="gfield_required">*</span>
  435. <?php gform_tooltip("notification_send_to_email") ?>
  436. </label>
  437. </th>
  438. <td>
  439. <input type="radio" id="gform_notification_to_type_email" name="gform_notification_to_type" <?php checked("email", $notification_to_type); ?> value="email" onclick="jQuery('.notification_to_container').hide(); jQuery('#gform_notification_to_email_container').show('slow');"/>
  440. <label for="gform_notification_to_type_email" class="inline">
  441. <?php _e("Enter Email", "gravityforms"); ?>
  442. </label>
  443. &nbsp;&nbsp;
  444. <input type="radio" id="gform_notification_to_type_field" name="gform_notification_to_type" <?php checked("field", $notification_to_type); ?> value="field" onclick="jQuery('.notification_to_container').hide(); jQuery('#gform_notification_to_field_container').show('slow');"/>
  445. <label for="gform_notification_to_type_field" class="inline">
  446. <?php _e("Select a Field", "gravityforms"); ?>
  447. </label>
  448. &nbsp;&nbsp;
  449. <input type="radio" id="gform_notification_to_type_routing" name="gform_notification_to_type" <?php checked("routing", $notification_to_type); ?> value="routing" onclick="jQuery('.notification_to_container').hide(); jQuery('#gform_notification_to_routing_container').show('slow');"/>
  450. <label for="gform_notification_to_type_routing" class="inline">
  451. <?php _e("Configure Routing", "gravityforms"); ?>
  452. <?php gform_tooltip("notification_send_to_routing") ?>
  453. </label>
  454. </td>
  455. </tr> <!-- / to email type -->
  456. <?php $ui_settings['notification_to_email_type'] = ob_get_contents(); ob_clean(); ?>
  457. <tr id="gform_notification_to_email_container" class="notification_to_container <?php echo $send_to_class ?>" <?php echo $notification_to_type != "email" ? "style='display:none';" : ""?>>
  458. <?php echo $subsetting_open; ?>
  459. <th scope="row"><?php _e("Send to Email", "gravityforms") ?></th>
  460. <td>
  461. <?php
  462. $to_email = rgget("toType", $notification) == "email" ? rgget("to", $notification) : "";
  463. ?>
  464. <input type="text" name="gform_notification_to_email" id="gform_notification_to_email" value="<?php echo esc_attr($to_email) ?>" class="fieldwidth-1" />
  465. <?php if(rgpost("gform_notification_to_type") == "email" && $is_invalid_email_to){ ?>
  466. <span class="validation_message"><?php _e("Please enter a valid email address", "gravityforms") ?></span>
  467. <?php } ?>
  468. </td>
  469. <?php echo $subsetting_close; ?>
  470. </tr> <!-- / to email -->
  471. <?php $ui_settings['notification_to_email'] = ob_get_contents(); ob_clean(); ?>
  472. <?php $email_fields = GFCommon::get_email_fields($form); ?>
  473. <tr id="gform_notification_to_field_container" class="notification_to_container <?php echo $send_to_class ?>" <?php echo $notification_to_type != "field" ? "style='display:none';" : ""?>>
  474. <?php echo $subsetting_open; ?>
  475. <th scope="row"><?php _e("Send to Field", "gravityforms") ?></th>
  476. <td>
  477. <?php
  478. if(!empty($email_fields)){
  479. ?>
  480. <select name="gform_notification_to_field" id="gform_notification_to_field">
  481. <option value=""><?php _e("Select an email field", "gravityforms"); ?></option>
  482. <?php
  483. $to_field = rgget("toType", $notification) == "field" ? rgget("to", $notification) : "";
  484. foreach($email_fields as $field){
  485. ?>
  486. <option value="<?php echo $field["id"]?>" <?php echo selected($field["id"], $to_field) ?>><?php echo GFCommon::get_label($field)?></option>
  487. <?php
  488. }
  489. ?>
  490. </select>
  491. <?php
  492. }
  493. else{ ?>
  494. <div class="error_base"><p><?php _e("Your form does not have an email field. Add an email field to your form and try again.", "gravityforms") ?></p></div>
  495. <?php
  496. }
  497. ?>
  498. </td>
  499. <?php echo $subsetting_close; ?>
  500. </tr> <!-- / to email field -->
  501. <?php $ui_settings['notification_to_email_field'] = ob_get_contents(); ob_clean(); ?>
  502. <tr id="gform_notification_to_routing_container" class="notification_to_container <?php echo $send_to_class ?>" <?php echo $notification_to_type != "routing" ? "style='display:none';" : ""?>>
  503. <?php echo $subsetting_open; ?>
  504. <td colspan="2">
  505. <div id="gform_notification_to_routing_rules">
  506. <?php
  507. $routing_fields = self::get_routing_fields($form,"0");
  508. if(empty($routing_fields)){//if(empty(){
  509. ?>
  510. <div class="gold_notice">
  511. <p><?php _e("To use notification routing, your form must have a field supported by conditional logic.", "gravityforms"); ?></p>
  512. </div>
  513. <?php
  514. }
  515. else {
  516. if(empty($notification["routing"]))
  517. $notification["routing"] = array(array());
  518. $count = sizeof($notification["routing"]);
  519. $routing_list = ",";
  520. for($i=0; $i<$count; $i++){
  521. $routing_list .= $i . ",";
  522. $routing = $notification["routing"][$i];
  523. $is_invalid_rule = !$is_valid && $_POST["gform_notification_to_type"] == "routing" && !self::is_valid_notification_email( rgar( $routing, 'email' ) );
  524. $class = $is_invalid_rule ? "class='grouting_rule_error'" : "";
  525. ?>
  526. <div style='width:99%' <?php echo $class ?>>
  527. <?php _e("Send to", "gravityforms") ?> <input type="text" id="routing_email_<?php echo $i?>" value="<?php echo rgar($routing,"email"); ?>" onkeyup="SetRouting(<?php echo $i ?>);"/>
  528. <?php _e("if", "gravityforms") ?> <select id="routing_field_id_<?php echo $i?>" class='gfield_routing_select' onchange='jQuery("#routing_value_<?php echo $i ?>").replaceWith(GetRoutingValues(<?php echo $i ?>, jQuery(this).val())); SetRouting(<?php echo $i ?>); '><?php echo self::get_routing_fields($form, rgar($routing,"fieldId")) ?></select>
  529. <select id="routing_operator_<?php echo $i?>" onchange="SetRouting(<?php echo $i ?>)" class="gform_routing_operator">
  530. <option value="is" <?php echo rgar($routing,"operator") == "is" ? "selected='selected'" : "" ?>><?php _e("is", "gravityforms") ?></option>
  531. <option value="isnot" <?php echo rgar($routing,"operator") == "isnot" ? "selected='selected'" : "" ?>><?php _e("is not", "gravityforms") ?></option>
  532. <option value=">" <?php echo rgar($routing,"operator") == ">" ? "selected='selected'" : "" ?>><?php _e("greater than", "gravityforms") ?></option>
  533. <option value="<" <?php echo rgar($routing,"operator") == "<" ? "selected='selected'" : "" ?>><?php _e("less than", "gravityforms") ?></option>
  534. <option value="contains" <?php echo rgar($routing,"operator") == "contains" ? "selected='selected'" : "" ?>><?php _e("contains", "gravityforms") ?></option>
  535. <option value="starts_with" <?php echo rgar($routing,"operator") == "starts_with" ? "selected='selected'" : "" ?>><?php _e("starts with", "gravityforms") ?></option>
  536. <option value="ends_with" <?php echo rgar($routing,"operator") == "ends_with" ? "selected='selected'" : "" ?>><?php _e("ends with", "gravityforms") ?></option>
  537. </select>
  538. <?php echo self::get_field_values($i, $form, rgar($routing,"fieldId"), rgar($routing,"value")) ?>
  539. <img src='<?php echo GFCommon::get_base_url()?>/images/add.png' class='add_field_choice' title='add another email routing' alt='add another email routing' style='cursor:pointer; margin:0 3px;' onclick='SetRouting(<?php echo $i ?>); InsertRouting(<?php echo $i + 1 ?>);' />
  540. <?php if($count > 1 ){ ?>
  541. <img src='<?php echo GFCommon::get_base_url()?>/images/remove.png' id='routing_delete_<?php echo $i?>' title='remove this email routing' alt='remove this email routing' class='delete_field_choice' style='cursor:pointer;' onclick='DeleteRouting(<?php echo $i ?>);' />
  542. <?php } ?>
  543. </div>
  544. <?php
  545. }
  546. if($is_invalid_rule){ ?>
  547. <span class="validation_message"><?php _e("Please enter a valid email address for all highlighted routing rules above.", "gravityforms") ?></span>
  548. <?php } ?>
  549. <input type="hidden" name="routing_count" id="routing_count" value="<?php echo $routing_list ?>"/>
  550. <?php
  551. }
  552. ?>
  553. </div>
  554. </td>
  555. <?php echo $subsetting_close; ?>
  556. </tr> <!-- / to routing -->
  557. <?php $ui_settings['notification_to_routing'] = ob_get_contents(); ob_clean(); ?>
  558. <tr valign="top">
  559. <th scope="row">
  560. <label for="gform_notification_from_name">
  561. <?php _e("From Name", "gravityforms"); ?>
  562. <?php gform_tooltip("notification_from_name") ?>
  563. </label>
  564. </th>
  565. <td>
  566. <input type="text" class="fieldwidth-2 merge-tag-support mt-position-right mt-hide_all_fields" name="gform_notification_from_name" id="gform_notification_from_name" value="<?php echo esc_attr(rgget("fromName", $notification)) ?>"/>
  567. </td>
  568. </tr> <!-- / from name -->
  569. <?php $ui_settings['notification_from_name'] = ob_get_contents(); ob_clean(); ?>
  570. <tr valign="top">
  571. <th scope="row">
  572. <label for="gform_notification_from">
  573. <?php _e("From Email", "gravityforms"); ?>
  574. <?php gform_tooltip("notification_from_email") ?>
  575. </label>
  576. </th>
  577. <td>
  578. <input type="text" class="fieldwidth-2 merge-tag-support mt-position-right mt-hide_all_fields" name="gform_notification_from" id="gform_notification_from" value="<?php echo rgempty("from", $notification) ? "{admin_email}" : esc_attr(rgget("from", $notification)) ?>"/>
  579. </td>
  580. </tr> <!-- / to from email -->
  581. <?php $ui_settings['notification_from'] = ob_get_contents(); ob_clean(); ?>
  582. <tr valign="top">
  583. <th scope="row">
  584. <label for="gform_notification_reply_to">
  585. <?php _e("Reply To", "gravityforms"); ?>
  586. <?php gform_tooltip("notification_reply_to") ?>
  587. </label>
  588. </th>
  589. <td>
  590. <input type="text" name="gform_notification_reply_to" id="gform_notification_reply_to" class="merge-tag-support mt-hide_all_fields" value="<?php echo esc_attr(rgget("replyTo", $notification)) ?>" class="fieldwidth-2" />
  591. </td>
  592. </tr> <!-- / reply to -->
  593. <?php $ui_settings['notification_reply_to'] = ob_get_contents(); ob_clean(); ?>
  594. <tr valign="top">
  595. <th scope="row">
  596. <label for="gform_notification_bcc">
  597. <?php _e("BCC", "gravityforms"); ?>
  598. <?php gform_tooltip("notification_bcc") ?>
  599. </label>
  600. </th>
  601. <td>
  602. <input type="text" name="gform_notification_bcc" id="gform_notification_bcc" value="<?php echo esc_attr(rgget("bcc", $notification)) ?>" class="fieldwidth-1" />
  603. </td>
  604. </tr> <!-- / bcc -->
  605. <?php $ui_settings['notification_bcc'] = ob_get_contents(); ob_clean(); ?>
  606. <?php
  607. $is_invalid_subject = !$is_valid && empty($_POST["gform_notification_subject"]);
  608. $subject_class = $is_invalid_subject ? "class='gfield_error'" : "";
  609. ?>
  610. <tr valign="top" <?php echo $subject_class ?>>
  611. <th scope="row">
  612. <label for="gform_notification_subject">
  613. <?php _e("Subject", "gravityforms"); ?><span class="gfield_required">*</span>
  614. </label>
  615. </th>
  616. <td>
  617. <input type="text" name="gform_notification_subject" id="gform_notification_subject" class="fieldwidth-1 merge-tag-support mt-hide_all_fields mt-position-right" value="<?php echo esc_attr(rgar($notification,"subject")) ?>" />
  618. <?php
  619. if($is_invalid_subject){?>
  620. <span class="validation_message"><?php _e("Please enter a subject for the notification email", "gravityforms") ?></span><?php
  621. }
  622. ?>
  623. </td>
  624. </tr> <!-- / subject -->
  625. <?php $ui_settings['notification_subject'] = ob_get_contents(); ob_clean(); ?>
  626. <?php
  627. $is_invalid_message = !$is_valid && empty($_POST["gform_notification_message"]);
  628. $message_class = $is_invalid_message ? "class='gfield_error'" : "";
  629. ?>
  630. <tr valign="top" <?php echo $message_class ?>>
  631. <th scope="row">
  632. <label for="gform_notification_message">
  633. <?php _e("Message", "gravityforms"); ?><span class="gfield_required">*</span>
  634. </label>
  635. </th>
  636. <td>
  637. <span class="mt-gform_notification_message"></span>
  638. <?php
  639. if(GFCommon::is_wp_version("3.3")){
  640. wp_editor( rgar( $notification, "message" ), "gform_notification_message", array( "autop" => false, "editor_class" => "merge-tag-support mt-wp_editor mt-manual_position mt-position-right" ) );
  641. }
  642. else{?>
  643. <textarea name="gform_notification_message" id="gform_notification_message" class="fieldwidth-1 fieldheight-1" ><?php echo esc_html($notification["message"]) ?></textarea><?php
  644. }
  645. if($is_invalid_message){ ?>
  646. <span class="validation_message"><?php _e("Please enter a message for the notification email", "gravityforms") ?></span><?php
  647. }
  648. ?>
  649. </td>
  650. </tr> <!-- / message -->
  651. <?php $ui_settings['notification_message'] = ob_get_contents(); ob_clean(); ?>
  652. <tr valign="top">
  653. <th scope="row">
  654. <label for="gform_notification_disable_autoformat">
  655. <?php _e("Auto-formatting", "gravityforms"); ?>
  656. <?php gform_tooltip("notification_autoformat") ?>
  657. </label>
  658. </th>
  659. <td>
  660. <input type="checkbox" name="gform_notification_disable_autoformat" id="gform_notification_disable_autoformat" value="1" <?php echo empty($notification["disableAutoformat"]) ? "" : "checked='checked'" ?>/>
  661. <label for="form_notification_disable_autoformat" class="inline">
  662. <?php _e("Disable auto-formatting", "gravityforms"); ?>
  663. <?php gform_tooltip("notification_autoformat") ?>
  664. </label>
  665. </td>
  666. </tr> <!-- / disable autoformat -->
  667. <?php $ui_settings['notification_disable_autoformat'] = ob_get_contents(); ob_clean(); ?>
  668. <tr valign="top">
  669. <th scope="row">
  670. <label for="gform_notification_conditional_logic">
  671. <?php _e("Conditional Logic", "gravityforms") ?><?php gform_tooltip("notification_conditional_logic") ?>
  672. </label>
  673. </th>
  674. <td>
  675. <input type="checkbox" id="notification_conditional_logic" onclick="SetConditionalLogic(this.checked); ToggleConditionalLogic(false, 'notification');" <?php checked(!empty($notification["conditionalLogic"]), true) ?> />
  676. <label for="notification_conditional_logic" class="inline"><?php _e("Enable conditional logic", "gravityforms") ?><?php gform_tooltip("notification_conditional_logic") ?></label>
  677. <br/>
  678. </td>
  679. </tr> <!-- / conditional logic -->
  680. <tr>
  681. <td colspan="2">
  682. <div id="notification_conditional_logic_container" class="gf_animate_sub_settings" style="padding-left:10px;">
  683. <!-- content dynamically created from form_admin.js -->
  684. </div>
  685. </td>
  686. </tr>
  687. <?php $ui_settings['notification_conditional_logic'] = ob_get_contents(); ob_clean(); ?>
  688. <?php
  689. ob_end_clean();
  690. $ui_settings = apply_filters("gform_notification_ui_settings_{$form_id}", apply_filters('gform_notification_ui_settings', $ui_settings, $notification, $form), $notification, $form );
  691. return $ui_settings;
  692. }
  693. private static function validate_notification() {
  694. $is_valid = self::is_valid_admin_to() && !rgempty("gform_notification_subject") && !rgempty("gform_notification_message");
  695. return $is_valid;
  696. }
  697. private static function is_valid_routing(){
  698. $routing = !empty($_POST["gform_routing_meta"]) ? GFCommon::json_decode(stripslashes($_POST["gform_routing_meta"]), true) : null;
  699. if(empty($routing))
  700. return false;
  701. foreach($routing as $route){
  702. if(!self::is_valid_notification_email($route["email"]))
  703. return false;
  704. }
  705. return true;
  706. }
  707. private static function is_valid_notification_email($text){
  708. if(empty($text))
  709. return false;
  710. $emails = explode(",", $text);
  711. foreach($emails as $email){
  712. $email = trim($email);
  713. $invalid_email = GFCommon::is_invalid_or_empty_email($email);
  714. $invalid_variable = !preg_match('/^({[^{]*?:(\d+(\.\d+)?)(:(.*?))?},? *)+$/', $email);
  715. if($invalid_email && $invalid_variable)
  716. return false;
  717. }
  718. return true;
  719. }
  720. private static function is_valid_admin_to(){
  721. return (rgpost('gform_notification_to_type') == "routing" && self::is_valid_routing())
  722. ||
  723. (rgpost('gform_notification_to_type') == "email" && (self::is_valid_notification_email($_POST["gform_notification_to_email"])) || $_POST["gform_notification_to_email"] == "{admin_email}")
  724. ||
  725. (rgpost('gform_notification_to_type') == "field" && (!rgempty("gform_notification_to_field")));
  726. }
  727. private static function get_first_routing_field($form){
  728. foreach($form["fields"] as $field){
  729. $input_type = RGFormsModel::get_input_type($field);
  730. if(in_array($input_type, self::$supported_fields))
  731. return $field["id"];
  732. }
  733. return 0;
  734. }
  735. private static function get_routing_fields($form, $selected_field_id){
  736. $str = "";
  737. foreach($form["fields"] as $field){
  738. $input_type = RGFormsModel::get_input_type($field);
  739. $field_label = RGFormsModel::get_label($field);
  740. if (in_array($input_type, self::$supported_fields)){
  741. $selected = $field["id"] == $selected_field_id ? "selected='selected'" : "";
  742. $str .= "<option value='" . $field["id"] . "' " . $selected . ">" . $field_label . "</option>";
  743. }
  744. }
  745. return $str;
  746. }
  747. private static function get_field_values($i, $form, $field_id, $selected_value, $max_field_length = 16){
  748. if(empty($field_id))
  749. $field_id = self::get_first_routing_field($form);
  750. if(empty($field_id))
  751. return "";
  752. $field = RGFormsModel::get_field($form, $field_id);
  753. $is_any_selected = false;
  754. $str = "";
  755. if (!$field)
  756. return "";
  757. if ($field["type"] == "post_category" && rgar($field, "displayAllCategories") == true)
  758. {
  759. $str .= wp_dropdown_categories(array("class"=>"gfield_routing_select gfield_category_dropdown gfield_routing_value_dropdown", "orderby"=> "name", "id"=> "routing_value_" . $i, "selected"=>$selected_value, "hierarchical"=>true, "hide_empty"=>0, "echo"=>false));
  760. }
  761. elseif (rgar($field,"choices")) {
  762. $str .= "<select id='routing_value_" . $i . "' class='gfield_routing_select gfield_routing_value_dropdown'>";
  763. foreach($field["choices"] as $choice){
  764. $is_selected = $choice["value"] == $selected_value;
  765. $selected = $is_selected ? "selected='selected'" : "";
  766. if($is_selected)
  767. $is_any_selected = true;
  768. $str .= "<option value='" . esc_attr($choice["value"]) . "' " . $selected . ">" . $choice["text"] . "</option>";
  769. }
  770. //adding current selected field value to the list
  771. if(!$is_any_selected && !empty($selected_value))
  772. {
  773. $str .= "<option value='" . esc_attr($selected_value) . "' selected='selected'>" . $selected_value . "</option>";
  774. }
  775. $str .= "</select>";
  776. }
  777. else
  778. {
  779. //create a text field for fields that don't have choices (i.e text, textarea, number, email, etc...)
  780. $str = "<input type='text' placeholder='" . __("Enter value", "gravityforms") . "' class='gfield_routing_select' id='routing_value_" . $i . "' value='" . esc_attr($selected_value) . "' onchange='SetRouting(" . $i . ");' onkeyup='SetRouting(" . $i . ");'>";
  781. }
  782. return $str;
  783. }
  784. public static function get_post_category_values(){
  785. $id = "routing_value_" . rgpost("ruleIndex");
  786. $selected = rgempty("selectedValue") ? 0 : rgpost("selectedValue");
  787. $dropdown = wp_dropdown_categories(array("class"=>"gfield_routing_select gfield_routing_value_dropdown gfield_category_dropdown", "orderby"=> "name", "id"=> $id, "selected"=>$selected, "hierarchical"=>true, "hide_empty"=>0, "echo"=>false));
  788. die($dropdown);
  789. }
  790. /**
  791. * Delete a form notification by ID.
  792. *
  793. * @param mixed $notification_id
  794. * @param mixed $form_id Can pass a form ID or a form object
  795. */
  796. public static function delete_notification($notification_id, $form_id) {
  797. if(!$form_id)
  798. return false;
  799. $form = !is_array($form_id) ? RGFormsModel::get_form_meta($form_id) : $form_id;
  800. unset($form['notifications'][$notification_id]);
  801. // clear form cache so next retrieval of form meta will reflect deleted notification
  802. RGFormsModel::flush_current_forms();
  803. return RGFormsModel::save_form_notifications($form['id'], $form['notifications']);
  804. }
  805. }
  806. class GFNotificationTable extends WP_List_Table {
  807. public $form;
  808. function __construct($form) {
  809. $this->form = $form;
  810. $this->_column_headers = array(
  811. array(
  812. 'name' => __('Name', 'gravityforms'),
  813. 'subject' => __('Subject', 'gravityforms')
  814. ),
  815. array(),
  816. array()
  817. );
  818. parent::__construct();
  819. }
  820. function prepare_items() {
  821. $this->items = $this->form['notifications'];
  822. }
  823. function display() {
  824. extract( $this->_args );
  825. ?>
  826. <table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
  827. <thead>
  828. <tr>
  829. <?php $this->print_column_headers(); ?>
  830. </tr>
  831. </thead>
  832. <tfoot>
  833. <tr>
  834. <?php $this->print_column_headers( false ); ?>
  835. </tr>
  836. </tfoot>
  837. <tbody id="the-list"<?php if ( $singular ) echo " class='list:$singular'"; ?>>
  838. <?php $this->display_rows_or_placeholder(); ?>
  839. </tbody>
  840. </table>
  841. <?php
  842. }
  843. function single_row( $item ) {
  844. static $row_class = '';
  845. $row_class = ( $row_class == '' ? ' class="alternate"' : '' );
  846. echo '<tr id="notification-' . $item['id'] . '" ' . $row_class . '>';
  847. echo $this->single_row_columns( $item );
  848. echo '</tr>';
  849. }
  850. function column_default($item, $column) {
  851. echo rgar($item, $column);

Large files files are truncated, but you can click here to view the full file