Advertisement
Guest User

Untitled

a guest
Jan 31st, 2014
239
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 154.42 KB | None | 0 0
  1. <?php
  2.  
  3. require_once(ABSPATH . "/wp-includes/post.php");
  4.  
  5. define("GFORMS_MAX_FIELD_LENGTH", 200);
  6.  
  7. class GFFormsModel {
  8.  
  9. public static $uploaded_files = array();
  10. public static $unique_ids = array();
  11.  
  12. private static $_confirmations = array();
  13. private static $_current_forms = array();
  14. private static $_current_lead = null;
  15.  
  16. public static function flush_current_forms(){
  17. self::$_current_forms = null;
  18. }
  19.  
  20. public static function flush_current_lead(){
  21. self::$_current_lead = null;
  22. }
  23.  
  24. public static function flush_confirmations(){
  25. self::$_confirmations = null;
  26. }
  27.  
  28. public static function get_form_table_name(){
  29. global $wpdb;
  30. return $wpdb->prefix . "rg_form";
  31. }
  32.  
  33. public static function get_meta_table_name(){
  34. global $wpdb;
  35. return $wpdb->prefix . "rg_form_meta";
  36. }
  37.  
  38. public static function get_form_view_table_name(){
  39. global $wpdb;
  40. return $wpdb->prefix . "rg_form_view";
  41. }
  42.  
  43. public static function get_lead_table_name(){
  44. global $wpdb;
  45. return $wpdb->prefix . "rg_lead";
  46. }
  47.  
  48. public static function get_lead_meta_table_name(){
  49. global $wpdb;
  50. return $wpdb->prefix . "rg_lead_meta";
  51. }
  52.  
  53. public static function get_lead_notes_table_name(){
  54. global $wpdb;
  55. return $wpdb->prefix . "rg_lead_notes";
  56. }
  57.  
  58. public static function get_lead_details_table_name(){
  59. global $wpdb;
  60. return $wpdb->prefix . "rg_lead_detail";
  61. }
  62.  
  63. public static function get_lead_details_long_table_name(){
  64. global $wpdb;
  65. return $wpdb->prefix . "rg_lead_detail_long";
  66. }
  67.  
  68. public static function get_lead_view_name(){
  69. global $wpdb;
  70. return $wpdb->prefix . "rg_lead_view";
  71. }
  72.  
  73. public static function get_forms($is_active = null, $sort="title ASC"){
  74. global $wpdb;
  75. $form_table_name = self::get_form_table_name();
  76. $lead_table_name = self::get_lead_table_name();
  77. $view_table_name = self::get_form_view_table_name();
  78.  
  79. $active_clause = $is_active !== null ? $wpdb->prepare("WHERE is_active=%d", $is_active) : "";
  80. $order_by = !empty($sort) ? "ORDER BY $sort" : "";
  81.  
  82. $sql = "SELECT f.id, f.title, f.date_created, f.is_active, 0 as lead_count, 0 view_count
  83. FROM $form_table_name f
  84. $active_clause
  85. $order_by";
  86.  
  87. //Getting all forms
  88. $forms = $wpdb->get_results($sql);
  89.  
  90. //Getting entry count per form
  91. $sql = "SELECT form_id, count(id) as lead_count FROM $lead_table_name l WHERE status='active' GROUP BY form_id";
  92. $entry_count = $wpdb->get_results($sql);
  93.  
  94. //Getting view count per form
  95. $sql = "SELECT form_id, sum(count) as view_count FROM $view_table_name GROUP BY form_id";
  96. $view_count = $wpdb->get_results($sql);
  97.  
  98. //Adding entry counts and to form array
  99. foreach($forms as &$form){
  100. foreach($view_count as $count){
  101. if($count->form_id == $form->id){
  102. $form->view_count = $count->view_count;
  103. break;
  104. }
  105. }
  106.  
  107. foreach($entry_count as $count){
  108. if($count->form_id == $form->id){
  109. $form->lead_count = $count->lead_count;
  110. break;
  111. }
  112. }
  113. }
  114.  
  115. return $forms;
  116. }
  117.  
  118. public static function get_forms_by_id($ids){
  119. _deprecated_function('get_forms_by_id', '1.7', 'get_form_meta_by_id');
  120. return self::get_form_meta_by_id($ids);
  121. }
  122.  
  123. public static function get_form_payment_totals($form_id){
  124. global $wpdb;
  125. $lead_table_name = self::get_lead_table_name();
  126.  
  127. $sql = $wpdb->prepare(" SELECT sum(payment_amount) revenue, count(l.id) orders
  128. FROM $lead_table_name l
  129. WHERE form_id=%d AND payment_amount IS NOT null", $form_id);
  130.  
  131. $totals = $wpdb->get_row($sql, ARRAY_A);
  132.  
  133. $active = $wpdb->get_var($wpdb->prepare(" SELECT count(id) as active
  134. FROM $lead_table_name
  135. WHERE form_id=%d AND payment_status='Active'", $form_id));
  136.  
  137. if(empty($active))
  138. $active = 0;
  139.  
  140. $totals["active"] = $active;
  141.  
  142. return $totals;
  143. }
  144.  
  145. public static function get_form_counts($form_id){
  146. global $wpdb;
  147. $lead_table_name = self::get_lead_table_name();
  148. $sql = $wpdb->prepare(
  149. "SELECT
  150. (SELECT count(0) FROM $lead_table_name WHERE form_id=%d AND status='active') as total,
  151. (SELECT count(0) FROM $lead_table_name WHERE is_read=0 AND status='active' AND form_id=%d) as unread,
  152. (SELECT count(0) FROM $lead_table_name WHERE is_starred=1 AND status='active' AND form_id=%d) as starred,
  153. (SELECT count(0) FROM $lead_table_name WHERE status='spam' AND form_id=%d) as spam,
  154. (SELECT count(0) FROM $lead_table_name WHERE status='trash' AND form_id=%d) as trash",
  155. $form_id, $form_id, $form_id, $form_id, $form_id);
  156.  
  157. $results = $wpdb->get_results($sql, ARRAY_A);
  158.  
  159. return $results[0];
  160.  
  161. }
  162.  
  163. public static function get_form_summary(){
  164. global $wpdb;
  165. $form_table_name = self::get_form_table_name();
  166. $lead_table_name = self::get_lead_table_name();
  167.  
  168. $sql = "SELECT l.form_id, count(l.id) as unread_count
  169. FROM $lead_table_name l
  170. WHERE is_read=0 AND status='active'
  171. GROUP BY form_id";
  172.  
  173. //getting number of unread and total leads for all forms
  174. $unread_results = $wpdb->get_results($sql, ARRAY_A);
  175.  
  176. $sql = "SELECT l.form_id, max(l.date_created) as last_lead_date, count(l.id) as total_leads
  177. FROM $lead_table_name l
  178. WHERE status='active'
  179. GROUP BY form_id";
  180.  
  181. $lead_date_results = $wpdb->get_results($sql, ARRAY_A);
  182.  
  183. $sql = "SELECT id, title, '' as last_lead_date, 0 as unread_count
  184. FROM $form_table_name
  185. WHERE is_active=1
  186. ORDER BY title";
  187.  
  188. $forms = $wpdb->get_results($sql, ARRAY_A);
  189.  
  190.  
  191. for($i=0; $count = sizeof($forms), $i<$count; $i++){
  192. if(is_array($unread_results)){
  193. foreach($unread_results as $unread_result){
  194. if($unread_result["form_id"] == $forms[$i]["id"]){
  195. $forms[$i]["unread_count"] = $unread_result["unread_count"];
  196. break;
  197. }
  198. }
  199. }
  200.  
  201. if(is_array($lead_date_results)){
  202. foreach($lead_date_results as $lead_date_result){
  203. if($lead_date_result["form_id"] == $forms[$i]["id"]){
  204. $forms[$i]["last_lead_date"] = $lead_date_result["last_lead_date"];
  205. $forms[$i]["total_leads"] = $lead_date_result["total_leads"];
  206. break;
  207. }
  208. }
  209. }
  210.  
  211. }
  212.  
  213. return $forms;
  214. }
  215.  
  216. public static function get_form_count(){
  217. global $wpdb;
  218. $form_table_name = self::get_form_table_name();
  219. $results = $wpdb->get_results("SELECT count(0) as count FROM $form_table_name UNION ALL SELECT count(0) as count FROM $form_table_name WHERE is_active=1 ");
  220. return array( "total" => intval($results[0]->count),
  221. "active" => intval($results[1]->count),
  222. "inactive" => intval($results[0]->count) - intval($results[1]->count)
  223. );
  224. }
  225.  
  226. public static function get_form_id($form_title){
  227. $forms = self::get_forms();
  228. foreach($forms as $form){
  229. $sanitized_name = str_replace("[", "", str_replace("]","", $form->title));
  230. if($form->title == $form_title || $sanitized_name == $form_title)
  231. return $form->id;
  232. }
  233. return 0;
  234. }
  235.  
  236. public static function get_form($form_id){
  237. global $wpdb;
  238. $table_name = self::get_form_table_name();
  239. $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE id=%d", $form_id));
  240. return $results[0];
  241. }
  242.  
  243. public static function get_form_meta($form_id){
  244. global $wpdb;
  245.  
  246. // return cached version if form meta has been previously retrieved for this form
  247. if(isset(self::$_current_forms[$form_id])){
  248. return self::$_current_forms[$form_id];
  249. }
  250.  
  251. $table_name = self::get_meta_table_name();
  252. $form_row = $wpdb->get_row($wpdb->prepare("SELECT display_meta, notifications FROM {$table_name} WHERE form_id=%d", $form_id), ARRAY_A);
  253.  
  254. //loading main form object
  255. $form = maybe_unserialize($form_row["display_meta"]);
  256. if(!$form)
  257. return null;
  258.  
  259. //loading notifications
  260. $form["notifications"] = maybe_unserialize($form_row["notifications"]);
  261.  
  262. //copying some form variables down to fields for easier access
  263. $page_number = 1;
  264. $description_placement = rgar($form, "descriptionPlacement") == "above" ? "above" : "below";
  265. if(is_array(rgar($form,"fields"))){
  266. foreach($form["fields"] as &$field){
  267. $field["label"] = !isset($field["label"]) ? "" : $field["label"];
  268. $field["formId"] = $form["id"];
  269. $field["pageNumber"] = $page_number;
  270. $field["descriptionPlacement"] = $description_placement;
  271. if($field["type"] == "page"){
  272. $page_number++;
  273. $field["pageNumber"] = $page_number;
  274. }
  275. }
  276. }
  277.  
  278. // loading confirmations from legacy structure into new structure
  279. $form = self::load_confirmations($form);
  280.  
  281. //only migrate legacy notification if there isn't any notification configured in new structure
  282. if(!isset($form["notifications"])){
  283. $form = self::load_notifications_from_legacy($form); //moving notification data from legacy structure into new "notifications" array
  284. }
  285.  
  286. //load notifications to legacy structure to maintain backward compatibility with legacy hooks and functions
  287. $form = self::load_notifications_to_legacy($form);
  288.  
  289. // cached form meta for cheaper retrieval on subsequent requests
  290. self::$_current_forms[$form_id] = $form;
  291.  
  292. return $form;
  293. }
  294.  
  295. public static function get_form_meta_by_id($ids){
  296. global $wpdb;
  297. $form_table_name = self::get_form_table_name();
  298. $meta_table_name = self::get_meta_table_name();
  299.  
  300. if(is_array($ids))
  301. $ids = implode(",", array_map('intval', $ids ) );
  302. else
  303. $ids = intval($ids);
  304.  
  305. $results = $wpdb->get_results(" SELECT display_meta, confirmations, notifications FROM {$form_table_name} f
  306. INNER JOIN {$meta_table_name} m ON f.id = m.form_id
  307. WHERE id in({$ids})", ARRAY_A);
  308.  
  309. foreach ($results as &$result) {
  310. $form = maybe_unserialize($result["display_meta"]);
  311. $form['confirmations'] = maybe_unserialize($result["confirmations"]);
  312. $form['notifications'] = maybe_unserialize($result["notifications"]);
  313. $result = $form;
  314. }
  315.  
  316. return $results;
  317.  
  318. }
  319.  
  320. private static function load_notifications_to_legacy($form){
  321. if(!is_array(rgar($form, "notifications")))
  322. return $form;
  323.  
  324. foreach($form["notifications"] as $notification){
  325. if(!in_array(rgar($notification,"type"), array("user", "admin")))
  326. continue;
  327.  
  328. $legacy_notification = $notification;
  329.  
  330. if($notification["toType"] == "field"){
  331. $legacy_notification["toField"] = $notification["to"];
  332. unset($legacy_notification["to"]);
  333. }
  334.  
  335. //unsetting new properties
  336. unset($legacy_notification["toType"]);
  337. unset($legacy_notification["id"]);
  338. unset($legacy_notification["event"]);
  339. unset($legacy_notification["name"]);
  340. if(isset($legacy_notification["type"]))
  341. unset($legacy_notification["type"]);
  342.  
  343. //saving into form object
  344. $property = $notification["type"] == "user" ? "autoResponder" : "notification";
  345. $form[$property] = $legacy_notification;
  346. }
  347.  
  348. return $form;
  349. }
  350.  
  351. private static function load_notifications_from_legacy($form){
  352.  
  353. $form["notifications"] = array();
  354. if(GFCommon::has_admin_notification($form)){
  355. $admin_notification = $form["notification"];
  356.  
  357. //if there is a fromField configured, move it to "from" as a merge tag
  358. $admin_notification = self::convert_property_to_merge_tag($form, $form["notification"], "from", "fromField");
  359.  
  360. //if there is a fromNameField configured, move it to "fromName" as a merge tag
  361. $admin_notification = self::convert_property_to_merge_tag($form, $form["notification"], "fromName", "fromNameField");
  362.  
  363. //if there is a replyToField configured, move it to "replyTo" as a merge tag
  364. $admin_notification = self::convert_property_to_merge_tag($form, $form["notification"], "replyTo", "replyToField");
  365.  
  366. //if routing is configured, set toType to routing, otherwise, set it to email
  367. $admin_notification["toType"] = !rgempty("routing", $admin_notification) ? "routing" : "email";
  368.  
  369. $notification_id = uniqid();
  370.  
  371. //assigning this notification to the form_submission action
  372. $admin_notification["event"] = "form_submission";
  373. $admin_notification["name"] = __("Admin Notification", "gravityforms");
  374. $admin_notification["type"] = "admin";
  375. $admin_notification["id"] = $notification_id;
  376.  
  377. //copying admin notification as an item in the new notifications array
  378. $form["notifications"][$notification_id] = $admin_notification;
  379. }
  380.  
  381. if(GFCommon::has_user_notification($form)){
  382.  
  383. $user_notification = $form["autoResponder"];
  384.  
  385. //if there is a toField configured, set toType to field, if not, set it toemail
  386. $to_field = rgar($user_notification, "toField");
  387. if(!empty($to_field)){
  388. $user_notification["toType"] = "field";
  389. $user_notification["to"] = $to_field;
  390. }
  391. else{
  392. $user_notification["toType"] = "email";
  393. }
  394.  
  395. $notification_id = uniqid();
  396. //assigning this notification to the form_submission action
  397. $user_notification["event"] = "form_submission";
  398. $user_notification["name"] = __("User Notification", "gravityforms");
  399. $user_notification["type"] = "user";
  400. $user_notification["id"] = $notification_id;
  401.  
  402. //copying user notification as an item in the new notifications array
  403. $form["notifications"][$notification_id] = $user_notification;
  404. }
  405.  
  406. self::save_form_notifications($form["id"], $form["notifications"]);
  407.  
  408. return $form;
  409. }
  410.  
  411. private static function convert_property_to_merge_tag($form, $array, $target_property, $source_property){
  412. $merge_tag = self::get_field_merge_tag($form, rgar($array, $source_property));
  413. if($merge_tag){
  414. $array[$target_property] = $merge_tag;
  415. unset($array[$source_property]);
  416. }
  417.  
  418. return $array;
  419. }
  420.  
  421. private static function get_field_merge_tag($form, $field_id){
  422. $field = self::get_field($form, $field_id);
  423. if(!$field)
  424. return false;
  425.  
  426. return "{" . GFCommon::get_label($field, $field_id) . ":" . $field_id . "}";
  427. }
  428.  
  429. public static function add_default_properties($form){
  430. if(is_array(rgar($form,"fields"))){
  431. $all_fields = array("adminLabel"=>"","adminOnly"=>"","allowsPrepopulate"=>"","defaultValue"=>"","description"=>"","content"=>"","cssClass"=>"",
  432. "errorMessage"=>"","id"=>"","inputName"=>"","isRequired"=>"","label"=>"","noDuplicates"=>"",
  433. "size"=>"","type"=>"","postCustomFieldName"=>"","displayAllCategories"=>"","displayCaption"=>"","displayDescription"=>"",
  434. "displayTitle"=>"","inputType"=>"","rangeMin"=>"","rangeMax"=>"","calendarIconType"=>"",
  435. "calendarIconUrl"=>"", "dateType"=>"","dateFormat"=>"","phoneFormat"=>"","addressType"=>"","defaultCountry"=>"","defaultProvince"=>"",
  436. "defaultState"=>"","hideAddress2"=>"","hideCountry"=>"","hideState"=>"","inputs"=>"","nameFormat"=>"","allowedExtensions"=>"",
  437. "captchaType"=>"","pageNumber"=>"","captchaTheme"=>"","simpleCaptchaSize"=>"","simpleCaptchaFontColor"=>"","simpleCaptchaBackgroundColor"=>"",
  438. "failed_validation"=>"", "productField" => "", "enablePasswordInput" => "", "maxLength" => "", "enablePrice" => "", "basePrice" => "");
  439.  
  440. foreach($form["fields"] as &$field)
  441. $field = wp_parse_args($field, $all_fields);
  442. }
  443. return $form;
  444. }
  445.  
  446. public static function get_grid_column_meta($form_id){
  447. global $wpdb;
  448.  
  449. $table_name = self::get_meta_table_name();
  450. return maybe_unserialize($wpdb->get_var($wpdb->prepare("SELECT entries_grid_meta FROM $table_name WHERE form_id=%d", $form_id)));
  451. }
  452.  
  453. public static function update_grid_column_meta($form_id, $columns){
  454. global $wpdb;
  455.  
  456. $table_name = self::get_meta_table_name();
  457. $meta = maybe_serialize(stripslashes_deep($columns) );
  458. $wpdb->query( $wpdb->prepare("UPDATE $table_name SET entries_grid_meta=%s WHERE form_id=%d", $meta, $form_id) );
  459. }
  460.  
  461. public static function get_lead_detail_id($current_fields, $field_number){
  462. foreach($current_fields as $field)
  463. if($field->field_number == $field_number)
  464. return $field->id;
  465.  
  466. return 0;
  467. }
  468.  
  469. public static function update_form_active($form_id, $is_active){
  470. global $wpdb;
  471. $form_table = self::get_form_table_name();
  472. $sql = $wpdb->prepare("UPDATE $form_table SET is_active=%d WHERE id=%d", $is_active, $form_id);
  473. $wpdb->query($sql);
  474. }
  475.  
  476. public static function update_forms_active($forms, $is_active){
  477. foreach($forms as $form_id)
  478. self::update_form_active($form_id, $is_active);
  479. }
  480.  
  481. public static function update_leads_property($leads, $property_name, $property_value){
  482. foreach($leads as $lead)
  483. self::update_lead_property($lead, $property_name, $property_value);
  484. }
  485.  
  486. public static function update_lead_property($lead_id, $property_name, $property_value, $update_akismet=true, $disable_hook=false){
  487. global $wpdb;
  488. $lead_table = self::get_lead_table_name();
  489.  
  490. $lead = self::get_lead($lead_id);
  491.  
  492. //marking entry as "spam" or "not spam" with Akismet if the plugin is installed
  493. if($update_akismet && GFCommon::akismet_enabled($lead["form_id"]) && $property_name == "status" && in_array($property_value, array("active", "spam"))){
  494.  
  495. $current_status = $lead["status"];
  496. if($current_status == "spam" && $property_value == "active"){
  497. $form = self::get_form_meta($lead["form_id"]);
  498. GFCommon::mark_akismet_spam($form, $lead, false);
  499. }
  500. else if($current_status == "active" && $property_value == "spam"){
  501. $form = self::get_form_meta($lead["form_id"]);
  502. GFCommon::mark_akismet_spam($form, $lead, true);
  503. }
  504. }
  505.  
  506. //updating lead
  507. $wpdb->update($lead_table, array($property_name => $property_value ), array("id" => $lead_id));
  508.  
  509. if(!$disable_hook){
  510.  
  511. $previous_value = rgar($lead, $property_name);
  512.  
  513. if($previous_value != $property_value) {
  514.  
  515. // if property is status, prev value is spam and new value is active
  516. if($property_name == 'status' && $previous_value == 'spam' && $property_value == 'active' && !rgar($lead, 'post_id')) {
  517. $lead[$property_name] = $property_value;
  518. $lead['post_id'] = GFCommon::create_post($form, $lead);
  519. }
  520.  
  521. do_action("gform_update_{$property_name}", $lead_id, $property_value, $previous_value);
  522. }
  523. }
  524.  
  525. }
  526.  
  527. public static function update_lead($lead){
  528. global $wpdb;
  529. $lead_table = self::get_lead_table_name();
  530.  
  531. $payment_date = strtotime(rgar($lead,"payment_date")) ? "'" . gmdate( 'Y-m-d H:i:s', strtotime("{$lead["payment_date"]}") ) . "'" : "NULL";
  532. $payment_amount = !rgblank(rgar($lead, "payment_amount")) ? (float) rgar($lead, "payment_amount") : "NULL";
  533. $transaction_type = !rgempty("transaction_type", $lead) ? intval($lead["transaction_type"]) : "NULL";
  534.  
  535. $status = !rgempty("status", $lead) ? $lead["status"] : "active";
  536. $source_url = self::truncate(rgar($lead,"source_url"), 200);
  537. $user_agent = self::truncate(rgar($lead,"user_agent"), 250);
  538.  
  539. $sql = $wpdb->prepare("UPDATE $lead_table SET
  540. form_id=%d,
  541. post_id=%d,
  542. is_starred=%d,
  543. is_read=%d,
  544. ip=%s,
  545. source_url=%s,
  546. user_agent=%s,
  547. currency=%s,
  548. payment_status=%s,
  549. payment_date={$payment_date},
  550. payment_amount={$payment_amount},
  551. transaction_id=%s,
  552. is_fulfilled=%d,
  553. transaction_type={$transaction_type},
  554. status='{$status}'
  555. WHERE id=%d", rgar($lead,"form_id"), rgar($lead,"post_id"), rgar($lead,"is_starred"), rgar($lead,"is_read"), rgar($lead,"ip"), $source_url, $user_agent,
  556. rgar($lead,"currency"), rgar($lead,"payment_status"), rgar($lead,"transaction_id"), rgar($lead,"is_fulfilled"), rgar($lead,"id"));
  557. $wpdb->query($sql);
  558.  
  559. self::set_current_lead($lead);
  560. }
  561.  
  562. private static function truncate($str, $length){
  563. if(strlen($str) > $length){
  564. $str = substr($str, 0, $length);
  565. }
  566. return $str;
  567. }
  568.  
  569. public static function delete_leads($leads){
  570. foreach($leads as $lead_id)
  571. self::delete_lead($lead_id);
  572. }
  573.  
  574. public static function delete_forms($forms){
  575. foreach($forms as $form_id)
  576. self::delete_form($form_id);
  577. }
  578.  
  579. public static function delete_leads_by_form($form_id, $status=""){
  580. global $wpdb;
  581.  
  582. if(!GFCommon::current_user_can_any("gravityforms_delete_entries"))
  583. die(__("You don't have adequate permission to delete entries.", "gravityforms"));
  584.  
  585. $lead_table = self::get_lead_table_name();
  586. $lead_notes_table = self::get_lead_notes_table_name();
  587. $lead_detail_table = self::get_lead_details_table_name();
  588. $lead_detail_long_table = self::get_lead_details_long_table_name();
  589.  
  590. //deleting uploaded files
  591. self::delete_files_by_form($form_id, $status);
  592.  
  593. $status_filter = empty($status) ? "" : $wpdb->prepare("AND status=%s", $status);
  594.  
  595. //Delete from detail long
  596. $sql = $wpdb->prepare(" DELETE FROM $lead_detail_long_table
  597. WHERE lead_detail_id IN(
  598. SELECT ld.id FROM $lead_detail_table ld
  599. INNER JOIN $lead_table l ON l.id = ld.lead_id
  600. WHERE l.form_id=%d AND ld.form_id=%d {$status_filter}
  601. )", $form_id, $form_id);
  602. $wpdb->query($sql);
  603.  
  604. //Delete from lead details
  605. $sql = $wpdb->prepare(" DELETE FROM $lead_detail_table
  606. WHERE lead_id IN (
  607. SELECT id FROM $lead_table WHERE form_id=%d {$status_filter}
  608. )", $form_id);
  609. $wpdb->query($sql);
  610.  
  611. //Delete from lead notes
  612. $sql = $wpdb->prepare(" DELETE FROM $lead_notes_table
  613. WHERE lead_id IN (
  614. SELECT id FROM $lead_table WHERE form_id=%d {$status_filter}
  615. )", $form_id);
  616. $wpdb->query($sql);
  617.  
  618. //Delete from lead
  619. $sql = $wpdb->prepare("DELETE FROM $lead_table WHERE form_id=%d {$status_filter}", $form_id);
  620. $wpdb->query($sql);
  621. }
  622.  
  623. public static function delete_views($form_id){
  624. global $wpdb;
  625.  
  626. $form_view_table = self::get_form_view_table_name();
  627.  
  628. //Delete form view
  629. $sql = $wpdb->prepare("DELETE FROM $form_view_table WHERE form_id=%d", $form_id);
  630. $wpdb->query($sql);
  631. }
  632.  
  633. public static function delete_form($form_id){
  634. global $wpdb;
  635.  
  636. if(!GFCommon::current_user_can_any("gravityforms_delete_forms"))
  637. die(__("You don't have adequate permission to delete forms.", "gravityforms"));
  638.  
  639. do_action("gform_before_delete_form", $form_id);
  640.  
  641. $form_meta_table = self::get_meta_table_name();
  642. $form_table = self::get_form_table_name();
  643.  
  644. //Deleting form Entries
  645. self::delete_leads_by_form($form_id);
  646.  
  647. //Delete form meta
  648. $sql = $wpdb->prepare("DELETE FROM $form_meta_table WHERE form_id=%d", $form_id);
  649. $wpdb->query($sql);
  650.  
  651. //Deleting form Views
  652. self::delete_views($form_id);
  653.  
  654. //Delete form
  655. $sql = $wpdb->prepare("DELETE FROM $form_table WHERE id=%d", $form_id);
  656. $wpdb->query($sql);
  657.  
  658. do_action("gform_after_delete_form", $form_id);
  659. }
  660.  
  661. public static function duplicate_form($form_id){
  662. global $wpdb;
  663.  
  664. if(!GFCommon::current_user_can_any("gravityforms_create_form"))
  665. die(__("You don't have adequate permission to create forms.", "gravityforms"));
  666.  
  667. //finding unique title
  668. $form = self::get_form($form_id);
  669. $count = 2;
  670. $title = $form->title . " - Copy 1";
  671. while(!self::is_unique_title($title)){
  672. $title = $form->title . " - Copy $count";
  673. $count++;
  674. }
  675.  
  676. //creating new form
  677. $new_id = self::insert_form($title);
  678.  
  679. //copying form meta
  680. $meta = self::get_form_meta($form_id);
  681. $meta["title"] = $title;
  682. $meta["id"] = $new_id;
  683.  
  684. $notifications = $meta["notifications"];
  685. $confirmations = $meta["confirmations"];
  686. unset($meta["notifications"]);
  687. unset($meta["confirmations"]);
  688. self::update_form_meta($new_id, $meta);
  689.  
  690. //copying notification meta
  691. self::update_form_meta($new_id, $notifications, "notifications");
  692.  
  693. //copying confirmation meta
  694. self::update_form_meta($new_id, $confirmations, "confirmations");
  695. return $new_id;
  696. }
  697.  
  698. public static function is_unique_title($title){
  699. $forms = self::get_forms();
  700. foreach($forms as $form){
  701. if(strtolower($form->title) == strtolower($title))
  702. return false;
  703. }
  704.  
  705. return true;
  706. }
  707.  
  708. public static function ensure_tables_exist(){
  709. global $wpdb;
  710. $form_table_name = self::get_form_table_name();
  711. $form_count = $wpdb->get_var("SELECT count(0) FROM {$form_table_name}");
  712. if($wpdb->last_error){
  713. GFCommon::log_debug("Blog " . get_current_blog_id() . " - Form database table does not exist. Forcing database setup.");
  714. GFForms::setup_site();
  715. }
  716. }
  717.  
  718. public static function insert_form($form_title){
  719. global $wpdb;
  720. $form_table_name = $wpdb->prefix . "rg_form";
  721.  
  722. //creating new form
  723. $wpdb->query($wpdb->prepare("INSERT INTO $form_table_name(title, date_created) VALUES(%s, utc_timestamp())", $form_title));
  724.  
  725. //returning newly created form id
  726. return $wpdb->insert_id;
  727.  
  728. }
  729.  
  730. public static function update_form_meta($form_id, $form_meta, $meta_name="display_meta"){
  731. global $wpdb;
  732. $meta_table_name = self::get_meta_table_name();
  733. $form_meta = maybe_serialize($form_meta);
  734.  
  735. if(intval($wpdb->get_var($wpdb->prepare("SELECT count(0) FROM $meta_table_name WHERE form_id=%d", $form_id))) > 0)
  736. $result = $wpdb->query( $wpdb->prepare("UPDATE $meta_table_name SET $meta_name=%s WHERE form_id=%d", $form_meta, $form_id) );
  737. else
  738. $result = $wpdb->query( $wpdb->prepare("INSERT INTO $meta_table_name(form_id, $meta_name) VALUES(%d, %s)", $form_id, $form_meta ) );
  739.  
  740. self::$_current_forms[$form_id] = null;
  741.  
  742. return $result;
  743. }
  744.  
  745. public static function delete_files($lead_id, $form=null){
  746. $lead = self::get_lead($lead_id);
  747.  
  748. if($form == null)
  749. $form = self::get_form_meta($lead["form_id"]);
  750.  
  751. $fields = GFCommon::get_fields_by_type($form, array("fileupload", "post_image"));
  752. if(is_array($fields)){
  753. foreach($fields as $field){
  754. $value = self::get_lead_field_value($lead, $field);
  755. self::delete_physical_file($value);
  756. }
  757. }
  758. }
  759.  
  760. public static function delete_files_by_form($form_id, $status=""){
  761. global $wpdb;
  762. $form = self::get_form_meta($form_id);
  763. $fields = GFCommon::get_fields_by_type($form, array("fileupload", "post_image"));
  764. if(empty($fields))
  765. return;
  766.  
  767. $status_filter = empty($status) ? "" : $wpdb->prepare("AND status=%s", $status);
  768. $results = $wpdb->get_results($wpdb->prepare("SELECT id FROM {$wpdb->prefix}rg_lead WHERE form_id=%d {$status_filter}", $form_id), ARRAY_A);
  769.  
  770. foreach($results as $result){
  771. self::delete_files($result["id"], $form);
  772. }
  773. }
  774.  
  775. public static function delete_file($lead_id, $field_id){
  776. global $wpdb;
  777.  
  778. if($lead_id == 0 || $field_id == 0)
  779. return;
  780.  
  781. $lead_detail_table = self::get_lead_details_table_name();
  782.  
  783. //Deleting file
  784. $sql = $wpdb->prepare("SELECT value FROM $lead_detail_table WHERE lead_id=%d AND field_number BETWEEN %s AND %s", $lead_id, doubleval($field_id) - 0.001, doubleval($field_id) + 0.001);
  785. $file_path = $wpdb->get_var($sql);
  786.  
  787. self::delete_physical_file($file_path);
  788.  
  789. //Delete from lead details
  790. $sql = $wpdb->prepare("DELETE FROM $lead_detail_table WHERE lead_id=%d AND field_number BETWEEN %s AND %s", $lead_id, doubleval($field_id) - 0.001, doubleval($field_id) + 0.001);
  791. $wpdb->query($sql);
  792. }
  793.  
  794. private static function delete_physical_file($file_url){
  795. $ary = explode("|:|", $file_url);
  796. $url = rgar($ary,0);
  797. if(empty($url))
  798. return;
  799.  
  800. //Convert from url to physical path
  801. if (is_multisite()) {
  802. $file_path = preg_replace("|^(.*?)/files/gravity_forms/|", BLOGUPLOADDIR . "gravity_forms/", $url);
  803. }
  804. else {
  805. $file_path = str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $url);
  806. }
  807.  
  808. if(file_exists($file_path)){
  809. unlink($file_path);
  810. }
  811. }
  812.  
  813. public static function delete_field($form_id, $field_id){
  814. global $wpdb;
  815.  
  816. if($form_id == 0)
  817. return;
  818.  
  819. do_action("gform_before_delete_field", $form_id, $field_id);
  820.  
  821. $lead_table = self::get_lead_table_name();
  822. $lead_detail_table = self::get_lead_details_table_name();
  823. $lead_detail_long_table = self::get_lead_details_long_table_name();
  824.  
  825.  
  826. $form = self::get_form_meta($form_id);
  827.  
  828. $field_type = "";
  829.  
  830. //Deleting field from form meta
  831. $count = sizeof($form["fields"]);
  832. for($i = $count-1; $i >= 0; $i--){
  833. $field = $form["fields"][$i];
  834.  
  835. //Deleting associated conditional logic rules
  836. if(!empty($field["conditionalLogic"])){
  837. $rule_count = sizeof($field["conditionalLogic"]["rules"]);
  838. for($j = $rule_count-1; $j >= 0; $j--){
  839. if($field["conditionalLogic"]["rules"][$j]["fieldId"] == $field_id){
  840. unset($form["fields"][$i]["conditionalLogic"]["rules"][$j]);
  841. }
  842. }
  843. $form["fields"][$i]["conditionalLogic"]["rules"] = array_values($form["fields"][$i]["conditionalLogic"]["rules"]);
  844.  
  845. //If there aren't any rules, remove the conditional logic
  846. if(sizeof($form["fields"][$i]["conditionalLogic"]["rules"]) == 0){
  847. $form["fields"][$i]["conditionalLogic"] = false;
  848. }
  849. }
  850.  
  851. //Deleting field from form meta
  852. if($field["id"] == $field_id){
  853. $field_type = $field["type"];
  854. unset($form["fields"][$i]);
  855. }
  856.  
  857. }
  858.  
  859. //removing post content and title template if the field being deleted is a post content field or post title field
  860. if($field_type == "post_content"){
  861. $form["postContentTemplateEnabled"] = false;
  862. $form["postContentTemplate"] = "";
  863. }
  864. else if($field_type == "post_title"){
  865. $form["postTitleTemplateEnabled"] = false;
  866. $form["postTitleTemplate"] = "";
  867. }
  868.  
  869. //Deleting associated routing rules
  870. if(!empty($form["notification"]["routing"])){
  871. $routing_count = sizeof($form["notification"]["routing"]);
  872. for($j = $routing_count-1; $j >= 0; $j--){
  873. if(intval($form["notification"]["routing"][$j]["fieldId"]) == $field_id){
  874. unset($form["notification"]["routing"][$j]);
  875. }
  876. }
  877. $form["notification"]["routing"] = array_values($form["notification"]["routing"]);
  878.  
  879. //If there aren't any routing, remove it
  880. if(sizeof($form["notification"]["routing"]) == 0){
  881. $form["notification"]["routing"] = null;
  882. }
  883. }
  884.  
  885. $form["fields"] = array_values($form["fields"]);
  886. self::update_form_meta($form_id, $form);
  887.  
  888. //Delete from grid column meta
  889. $columns = self::get_grid_column_meta($form_id);
  890. $count = sizeof($columns);
  891. for($i = $count -1; $i >=0; $i--)
  892. {
  893. if(intval(rgar($columns,$i)) == intval($field_id)){
  894. unset($columns[$i]);
  895. }
  896. }
  897. self::update_grid_column_meta($form_id, $columns);
  898.  
  899. //Delete from detail long
  900. $sql = $wpdb->prepare(" DELETE FROM $lead_detail_long_table
  901. WHERE lead_detail_id IN(
  902. SELECT id FROM $lead_detail_table WHERE form_id=%d AND field_number >= %d AND field_number < %d
  903. )", $form_id, $field_id, $field_id + 1);
  904. $wpdb->query($sql);
  905.  
  906. //Delete from lead details
  907. $sql = $wpdb->prepare("DELETE FROM $lead_detail_table WHERE form_id=%d AND field_number >= %d AND field_number < %d", $form_id, $field_id, $field_id + 1);
  908. $wpdb->query($sql);
  909.  
  910. //Delete leads with no details
  911. $sql = $wpdb->prepare(" DELETE FROM $lead_table
  912. WHERE form_id=%d
  913. AND id NOT IN(
  914. SELECT DISTINCT(lead_id) FROM $lead_detail_table WHERE form_id=%d
  915. )", $form_id, $form_id);
  916. $wpdb->query($sql);
  917.  
  918. do_action("gform_after_delete_field", $form_id, $field_id);
  919. }
  920.  
  921. public static function delete_lead($lead_id){
  922. global $wpdb;
  923.  
  924. if(!GFCommon::current_user_can_any("gravityforms_delete_entries"))
  925. die(__("You don't have adequate permission to delete entries.", "gravityforms"));
  926.  
  927. do_action("gform_delete_lead", $lead_id);
  928.  
  929. $lead_table = self::get_lead_table_name();
  930. $lead_notes_table = self::get_lead_notes_table_name();
  931. $lead_detail_table = self::get_lead_details_table_name();
  932. $lead_detail_long_table = self::get_lead_details_long_table_name();
  933.  
  934. //deleting uploaded files
  935. self::delete_files($lead_id);
  936.  
  937. //Delete from detail long
  938. $sql = $wpdb->prepare(" DELETE FROM $lead_detail_long_table
  939. WHERE lead_detail_id IN(
  940. SELECT id FROM $lead_detail_table WHERE lead_id=%d
  941. )", $lead_id);
  942. $wpdb->query($sql);
  943.  
  944. //Delete from lead details
  945. $sql = $wpdb->prepare("DELETE FROM $lead_detail_table WHERE lead_id=%d", $lead_id);
  946. $wpdb->query($sql);
  947.  
  948. //Delete from lead notes
  949. $sql = $wpdb->prepare("DELETE FROM $lead_notes_table WHERE lead_id=%d", $lead_id);
  950. $wpdb->query($sql);
  951.  
  952. //Delete from lead meta
  953. gform_delete_meta($lead_id);
  954.  
  955. //Delete from lead
  956. $sql = $wpdb->prepare("DELETE FROM $lead_table WHERE id=%d", $lead_id);
  957. $wpdb->query($sql);
  958.  
  959. }
  960.  
  961. public static function add_note($lead_id, $user_id, $user_name, $note){
  962. global $wpdb;
  963.  
  964. $table_name = self::get_lead_notes_table_name();
  965. $sql = $wpdb->prepare("INSERT INTO $table_name(lead_id, user_id, user_name, value, date_created) values(%d, %d, %s, %s, utc_timestamp())", $lead_id, $user_id, $user_name, $note);
  966.  
  967. $wpdb->query($sql);
  968. }
  969.  
  970. public static function delete_note($note_id){
  971. global $wpdb;
  972.  
  973. if(!GFCommon::current_user_can_any("gravityforms_edit_entry_notes"))
  974. die(__("You don't have adequate permission to delete notes.", "gravityforms"));
  975.  
  976. $table_name = self::get_lead_notes_table_name();
  977. $sql = $wpdb->prepare("DELETE FROM $table_name WHERE id=%d", $note_id);
  978. $wpdb->query($sql);
  979. }
  980.  
  981. public static function delete_notes($notes){
  982. if(!is_array($notes))
  983. return;
  984.  
  985. foreach($notes as $note_id){
  986. self::delete_note($note_id);
  987. }
  988. }
  989.  
  990. public static function get_ip(){
  991. $ip = rgget("HTTP_X_FORWARDED_FOR", $_SERVER);
  992. if (!$ip)
  993. $ip = rgget("REMOTE_ADDR", $_SERVER);
  994.  
  995. $ip_array = explode(",", $ip); //HTTP_X_FORWARDED_FOR can return a comma separated list of IPs. Using the first one.
  996. return $ip_array[0];
  997. }
  998.  
  999. public static function save_lead($form, &$lead){
  1000. global $wpdb;
  1001.  
  1002. GFCommon::log_debug("Saving entry.");
  1003.  
  1004. if(IS_ADMIN && !GFCommon::current_user_can_any("gravityforms_edit_entries"))
  1005. die(__("You don't have adequate permission to edit entries.", "gravityforms"));
  1006.  
  1007. $lead_detail_table = self::get_lead_details_table_name();
  1008.  
  1009. //Inserting lead if null
  1010. if($lead == null){
  1011. global $current_user;
  1012. $user_id = $current_user && $current_user->ID ? $current_user->ID : 'NULL';
  1013.  
  1014. $lead_table = RGFormsModel::get_lead_table_name();
  1015. $user_agent = self::truncate($_SERVER["HTTP_USER_AGENT"], 250);
  1016. $currency = GFCommon::get_currency();
  1017. $source_url = self::truncate(self::get_current_page_url(), 200);
  1018.  
  1019. $wpdb->query($wpdb->prepare("INSERT INTO $lead_table(form_id, ip, source_url, date_created, user_agent, currency, created_by) VALUES(%d, %s, %s, utc_timestamp(), %s, %s, {$user_id})", $form["id"], self::get_ip(), $source_url, $user_agent, $currency));
  1020.  
  1021.  
  1022. //reading newly created lead id
  1023. $lead_id = $wpdb->insert_id;
  1024. $lead = array("id" => $lead_id);
  1025.  
  1026. GFCommon::log_debug("Entry record created in the database. ID: {$lead_id}");
  1027. }
  1028.  
  1029. $current_fields = $wpdb->get_results($wpdb->prepare("SELECT id, field_number FROM $lead_detail_table WHERE lead_id=%d", $lead["id"]));
  1030. $original_post_id = rgget("post_id", $lead);
  1031.  
  1032. $total_field = null;
  1033. $calculation_fields = array();
  1034. $recalculate_total = false;
  1035.  
  1036. GFCommon::log_debug("Saving entry fields.");
  1037.  
  1038. foreach($form["fields"] as $field){
  1039.  
  1040. //Ignore fields that are marked as display only
  1041. if(rgget("displayOnly", $field) && $field["type"] != "password"){
  1042. continue;
  1043. }
  1044.  
  1045. //ignore pricing fields in the entry detail
  1046. if(RG_CURRENT_VIEW == "entry" && GFCommon::is_pricing_field($field["type"])){
  1047. continue;
  1048. }
  1049.  
  1050.  
  1051. //process total field after all fields have been saved
  1052. if($field["type"] == "total"){
  1053. $total_field = $field;
  1054. continue;
  1055. }
  1056.  
  1057. //only save fields that are not hidden (except on entry screen)
  1058. if(RG_CURRENT_VIEW == "entry" || !RGFormsModel::is_field_hidden($form, $field, array()) ){
  1059.  
  1060. // process calculation fields after all fields have been saved (moved after the is hidden check)
  1061. if( GFCommon::has_field_calculation($field) ) {
  1062. $calculation_fields[] = $field;
  1063. continue;
  1064. }
  1065.  
  1066. GFCommon::log_debug("Saving field {$field["label"]}");
  1067.  
  1068. if($field['type'] == 'post_category')
  1069. $field = GFCommon::add_categories_as_choices($field, '');
  1070.  
  1071. if(isset($field["inputs"]) && is_array($field["inputs"])){
  1072.  
  1073. foreach($field["inputs"] as $input)
  1074. self::save_input($form, $field, $lead, $current_fields, $input["id"]);
  1075. }
  1076. else{
  1077. self::save_input($form, $field, $lead, $current_fields, $field["id"]);
  1078. }
  1079. }
  1080. }
  1081.  
  1082. if(!empty($calculation_fields)) {
  1083. foreach($calculation_fields as $calculation_field) {
  1084.  
  1085. GFCommon::log_debug("Saving calculated field {$calculation_field["label"]}");
  1086.  
  1087. if(isset($calculation_field["inputs"]) && is_array($calculation_field["inputs"])){
  1088. foreach($calculation_field["inputs"] as $input) {
  1089. self::save_input($form, $calculation_field, $lead, $current_fields, $input["id"]);
  1090. self::refresh_lead_field_value($lead["id"], $input["id"]);
  1091. }
  1092. }
  1093. else{
  1094. self::save_input($form, $calculation_field, $lead, $current_fields, $calculation_field["id"]);
  1095. self::refresh_lead_field_value($lead["id"], $calculation_field["id"]);
  1096. }
  1097.  
  1098. }
  1099. self::refresh_product_cache($form, $lead = RGFormsModel::get_lead($lead['id']));
  1100. }
  1101.  
  1102. //saving total field as the last field of the form.
  1103. if($total_field) {
  1104. GFCommon::log_debug("Saving total field.");
  1105. self::save_input($form, $total_field, $lead, $current_fields, $total_field["id"]);
  1106. }
  1107.  
  1108. }
  1109.  
  1110. public static function create_lead($form) {
  1111. global $current_user;
  1112.  
  1113. $calculation_fields = array();
  1114.  
  1115. $lead = array();
  1116. $lead['id'] = null;
  1117. $lead['post_id'] = null;
  1118. $lead['date_created'] = null;
  1119. $lead['form_id'] = $form['id'];
  1120. $lead['ip'] = self::get_ip();
  1121. $lead['source_url'] = self::truncate(self::get_current_page_url(), 200);
  1122. $lead['user_agent'] = strlen($_SERVER['HTTP_USER_AGENT']) > 250 ? substr($_SERVER['HTTP_USER_AGENT'], 0, 250) : $_SERVER['HTTP_USER_AGENT'];
  1123. $lead['currency'] = GFCommon::get_currency();
  1124. $lead['created_by'] = $current_user && $current_user->ID ? $current_user->ID : 'NULL';
  1125.  
  1126. foreach($form['fields'] as $field) {
  1127.  
  1128. // ignore fields that are marked as display only
  1129. if(rgget('displayOnly', $field) && $field['type'] != 'password'){
  1130. continue;
  1131. }
  1132.  
  1133. // process total field after all fields have been saved
  1134. if($field['type'] == 'total'){
  1135. $total_field = $field;
  1136. continue;
  1137. }
  1138.  
  1139. // process calculation fields after all fields have been saved
  1140. if(GFCommon::has_field_calculation($field)) {
  1141. $calculation_fields[] = $field;
  1142. continue;
  1143. }
  1144.  
  1145. // only save fields that are not hidden
  1146. if(!RGFormsModel::is_field_hidden($form, $field, array()) ){
  1147.  
  1148. if($field['type'] == 'post_category')
  1149. $field = GFCommon::add_categories_as_choices($field, '');
  1150.  
  1151. if(isset($field['inputs']) && is_array($field['inputs'])){
  1152. foreach($field['inputs'] as $input) {
  1153. $lead[(string)$input['id']] = self::get_prepared_input_value($form, $field, $lead, $input["id"]);
  1154. }
  1155. }
  1156. else {
  1157. $lead[$field['id']] = self::get_prepared_input_value($form, $field, $lead, $field["id"]);
  1158. }
  1159. }
  1160. }
  1161.  
  1162. if(!empty($calculation_fields)) {
  1163. foreach($calculation_fields as $field) {
  1164.  
  1165. // only save fields that are not hidden
  1166. if(RGFormsModel::is_field_hidden($form, $field, array()) )
  1167. continue;
  1168.  
  1169. if(isset($field["inputs"]) && is_array($field["inputs"])){
  1170. foreach($field["inputs"] as $input) {
  1171. $lead[(string)$input['id']] = self::get_prepared_input_value($form, $field, $lead, $input["id"]);
  1172. }
  1173. }
  1174. else{
  1175. $lead[$field['id']] = self::get_prepared_input_value($form, $field, $lead, $field["id"]);
  1176. }
  1177.  
  1178. }
  1179. self::refresh_product_cache($form, $lead);
  1180. }
  1181.  
  1182. // saving total field as the last field of the form.
  1183. if(isset($total_field)) {
  1184. $lead[$total_field['id']] = self::get_prepared_input_value($form, $total_field, $lead, $total_field["id"]);
  1185. }
  1186.  
  1187. return $lead;
  1188. }
  1189.  
  1190. public static function get_prepared_input_value($form, $field, $lead, $input_id) {
  1191.  
  1192. $input_name = "input_" . str_replace('.', '_', $input_id);
  1193. $value = rgpost($input_name);
  1194.  
  1195. if(empty($value) && rgar($field, "adminOnly") && !IS_ADMIN){
  1196. $value = self::get_default_value($field, $input_id);
  1197. }
  1198.  
  1199. switch(self::get_input_type($field)) {
  1200.  
  1201. case "post_image":
  1202. $file_info = self::get_temp_filename($form['id'], $input_name);
  1203. $file_path = self::get_file_upload_path($form['id'], $file_info["uploaded_filename"]);
  1204. $url = $file_path['url'];
  1205.  
  1206. $image_title = isset($_POST["{$input_name}_1"]) ? strip_tags($_POST["{$input_name}_1"]) : "";
  1207. $image_caption = isset($_POST["{$input_name}_4"]) ? strip_tags($_POST["{$input_name}_4"]) : "";
  1208. $image_description = isset($_POST["{$input_name}_7"]) ? strip_tags($_POST["{$input_name}_7"]) : "";
  1209.  
  1210. $value = !empty($url) ? $url . "|:|" . $image_title . "|:|" . $image_caption . "|:|" . $image_description : "";
  1211. break;
  1212.  
  1213. case "fileupload" :
  1214. $file_info = self::get_temp_filename($form['id'], $input_name);
  1215. $file_path = self::get_file_upload_path($form['id'], $file_info["uploaded_filename"]);
  1216. $value = $file_path['url'];
  1217. break;
  1218.  
  1219. default:
  1220.  
  1221. // processing values so that they are in the correct format for each input type
  1222. $value = self::prepare_value($form, $field, $value, $input_name, rgar($lead, 'id'), $lead);
  1223.  
  1224. }
  1225.  
  1226. return apply_filters("gform_save_field_value", $value, $lead, $field, $form);
  1227. }
  1228.  
  1229. public static function refresh_product_cache($form, $lead, $use_choice_text = false, $use_admin_label = false) {
  1230.  
  1231. $cache_options = array(
  1232. array(false, false),
  1233. array(false, true),
  1234. array(true, false),
  1235. array(true, true)
  1236. );
  1237.  
  1238. foreach($form["fields"] as $field){
  1239. if(GFCommon::has_field_calculation($field)){
  1240. //deleting field value cache for calculated fields
  1241. $cache_key = "GFFormsModel::get_lead_field_value_" . $lead["id"] . "_" . $field["id"];
  1242. GFCache::delete($cache_key);
  1243. }
  1244. }
  1245.  
  1246. foreach($cache_options as $cache_option) {
  1247. list($use_choice_text, $use_admin_label) = $cache_option;
  1248. if( gform_get_meta( rgar($lead,'id'), "gform_product_info_{$use_choice_text}_{$use_admin_label}") ) {
  1249. gform_delete_meta(rgar($lead,'id'), "gform_product_info_{$use_choice_text}_{$use_admin_label}");
  1250. GFCommon::get_product_fields($form, $lead, $use_choice_text, $use_admin_label);
  1251. }
  1252. }
  1253.  
  1254. }
  1255.  
  1256. /**
  1257. * Check whether a field is hidden via conditional logic.
  1258. *
  1259. * @param array $form Form object.
  1260. * @param array $field Field object.
  1261. * @param array $field_values Default field values for this form. Used when form has not yet been submitted. Pass an array if no default field values are avilable/required.
  1262. * @return array $lead Optional, default is null. If lead object is available, pass the lead.
  1263. */
  1264. public static function is_field_hidden($form, $field, $field_values, $lead=null){
  1265.  
  1266. $cache_key = "GFFormsModel::is_field_hidden_" . $form["id"] . "_" . $field["id"];
  1267. $display = GFCache::get($cache_key);
  1268. if($display !== false)
  1269. return $display;
  1270.  
  1271. $section = self::get_section($form, $field["id"]);
  1272. $section_display = self::get_field_display($form, $section, $field_values, $lead);
  1273.  
  1274. //if section is hidden, hide field no matter what. if section is visible, see if field is supposed to be visible
  1275. if($section_display == "hide"){
  1276. $display = "hide";
  1277. }
  1278. else if(self::is_page_hidden($form, rgar($field,"pageNumber"), $field_values, $lead)){
  1279. $display = "hide";
  1280. }
  1281. else{
  1282. $display = self::get_field_display($form, $field, $field_values, $lead);
  1283. return $display == "hide";
  1284. }
  1285.  
  1286. GFCache::set($cache_key, $display);
  1287.  
  1288. return $display == "hide";
  1289. }
  1290.  
  1291. public static function is_page_hidden($form, $page_number, $field_values, $lead=null){
  1292. $page = self::get_page_by_number($form, $page_number);
  1293.  
  1294. if(!$page)
  1295. return false;
  1296.  
  1297. $display = self::get_field_display($form, $page, $field_values, $lead);
  1298. return $display == "hide";
  1299. }
  1300.  
  1301. public static function get_page_by_number($form, $page_number){
  1302. foreach($form["fields"] as $field){
  1303. if($field["type"] == "page" && $field["pageNumber"] == $page_number)
  1304. return $field;
  1305. }
  1306. return null;
  1307. }
  1308.  
  1309. public static function get_page_by_field($form, $field){
  1310. return get_page_by_number($field["pageNumber"]);
  1311. }
  1312.  
  1313. //gets the section that the specified field belongs to, or null if none
  1314. public static function get_section($form, $field_id){
  1315. $current_section = null;
  1316. foreach($form["fields"] as $field){
  1317. if($field["type"] == "section")
  1318. $current_section = $field;
  1319.  
  1320. //stop section at a page break (sections don't go cross page)
  1321. if($field["type"] == "page")
  1322. $current_section = null;
  1323.  
  1324. if($field["id"] == $field_id)
  1325. return $current_section;
  1326. }
  1327.  
  1328. return null;
  1329. }
  1330.  
  1331. public static function is_value_match( $field_value, $target_value, $operation="is", $source_field = null, $rule = null ){
  1332.  
  1333. $is_match = false;
  1334.  
  1335. if($source_field && $source_field["type"] == "post_category")
  1336. $field_value = GFCommon::prepare_post_category_value($field_value, $source_field, "conditional_logic");
  1337.  
  1338. if (!empty($field_value) && !is_array($field_value) && $source_field["type"] == "multiselect")
  1339. $field_value = explode(",", $field_value); // convert the comma-delimited string into an array
  1340.  
  1341. if(is_array($field_value)){
  1342. $field_value = array_values($field_value); //returning array values, ignoring keys if array is associative
  1343. $match_count = 0;
  1344. foreach($field_value as $val){
  1345. if(self::matches_operation(GFCommon::get_selection_value($val), $target_value, $operation)){
  1346. $match_count++;
  1347. }
  1348. }
  1349. // if operation is Is Not, none of the values in the array can match the target value.
  1350. $is_match = $operation == "isnot" ? $match_count == count($field_value) : $match_count > 0;
  1351. }
  1352. else if(self::matches_operation(GFCommon::get_selection_value($field_value), $target_value, $operation)){
  1353. $is_match = true;
  1354. }
  1355.  
  1356. return apply_filters( 'gform_is_value_match', $is_match, $field_value, $target_value, $operation, $source_field, $rule );
  1357. }
  1358.  
  1359. private static function try_convert_float($text){
  1360. global $wp_locale;
  1361. $number_format = $wp_locale->number_format['decimal_point'] == "," ? "decimal_comma" : "decimal_dot";
  1362.  
  1363. if(GFCommon::is_numeric($text, $number_format))
  1364. return GFCommon::clean_number($text, $number_format);
  1365.  
  1366. return $text;
  1367. }
  1368.  
  1369. public static function matches_operation($val1, $val2, $operation){
  1370.  
  1371. $val1 = !rgblank($val1) ? strtolower($val1) : "";
  1372. $val2 = !rgblank($val2) ? strtolower($val2) : "";
  1373.  
  1374. switch($operation){
  1375. case "is" :
  1376. return $val1 == $val2;
  1377. break;
  1378.  
  1379. case "isnot" :
  1380. return $val1 != $val2;
  1381. break;
  1382.  
  1383. case "greater_than":
  1384. case ">" :
  1385. $val1 = self::try_convert_float($val1);
  1386. $val2 = self::try_convert_float($val2);
  1387.  
  1388. return $val1 > $val2;
  1389. break;
  1390.  
  1391. case "less_than":
  1392. case "<" :
  1393. $val1 = self::try_convert_float($val1);
  1394. $val2 = self::try_convert_float($val2);
  1395.  
  1396. return $val1 < $val2;
  1397. break;
  1398.  
  1399. case "contains" :
  1400. return !empty($val2) && strpos($val1, $val2) !== false;
  1401. break;
  1402.  
  1403. case "starts_with" :
  1404. return !empty($val2) && strpos($val1, $val2) === 0;
  1405. break;
  1406.  
  1407. case "ends_with" :
  1408. $start = strlen($val1) - strlen($val2);
  1409. if($start < 0)
  1410. return false;
  1411.  
  1412. $tail = substr($val1, $start);
  1413. return $val2 == $tail;
  1414. break;
  1415. }
  1416.  
  1417.  
  1418. return false;
  1419. }
  1420.  
  1421. private static function get_field_display($form, $field, $field_values, $lead=null){
  1422.  
  1423. $logic = rgar($field, "conditionalLogic");
  1424.  
  1425. //if this field does not have any conditional logic associated with it, it won't be hidden
  1426. if(empty($logic))
  1427. return "show";
  1428.  
  1429. $match_count = 0;
  1430. foreach($logic["rules"] as $rule){
  1431. $source_field = RGFormsModel::get_field($form, $rule["fieldId"]);
  1432. $field_value = empty($lead) ? self::get_field_value($source_field, $field_values) : self::get_lead_field_value($lead, $source_field);
  1433.  
  1434. $is_value_match = self::is_value_match($field_value, $rule["value"], $rule["operator"], $source_field);
  1435.  
  1436. if($is_value_match)
  1437. $match_count++;
  1438. }
  1439.  
  1440. $do_action = ($logic["logicType"] == "all" && $match_count == sizeof($logic["rules"]) ) || ($logic["logicType"] == "any" && $match_count > 0);
  1441. $is_hidden = ($do_action && $logic["actionType"] == "hide") || (!$do_action && $logic["actionType"] == "show");
  1442.  
  1443. return $is_hidden ? "hide" : "show";
  1444. }
  1445.  
  1446. public static function get_custom_choices(){
  1447. $choices = get_option("gform_custom_choices");
  1448. if(!$choices)
  1449. $choices = array();
  1450.  
  1451. return $choices;
  1452. }
  1453.  
  1454. public static function delete_custom_choice($name){
  1455. $choices = self::get_custom_choices();
  1456. if(array_key_exists($name, $choices))
  1457. unset($choices[$name]);
  1458.  
  1459. update_option("gform_custom_choices", $choices);
  1460. }
  1461.  
  1462. public static function save_custom_choice($previous_name, $new_name, $choices){
  1463. $all_choices = self::get_custom_choices();
  1464.  
  1465. if(array_key_exists($previous_name, $all_choices))
  1466. unset($all_choices[$previous_name]);
  1467.  
  1468. $all_choices[$new_name] = $choices;
  1469.  
  1470. update_option("gform_custom_choices", $all_choices);
  1471. }
  1472.  
  1473. public static function get_field_value(&$field, $field_values = array(), $get_from_post=true){
  1474.  
  1475. if($field['type'] == 'post_category')
  1476. $field = GFCommon::add_categories_as_choices($field, '');
  1477.  
  1478. $value = array();
  1479. switch(RGFormsModel::get_input_type($field)){
  1480. case "post_image" :
  1481. $value[$field["id"] . ".1"] = self::get_input_value($field, "input_" . $field["id"] . "_1", $get_from_post);
  1482. $value[$field["id"] . ".4"] = self::get_input_value($field, "input_" . $field["id"] . "_4", $get_from_post);
  1483. $value[$field["id"] . ".7"] = self::get_input_value($field, "input_" . $field["id"] . "_7", $get_from_post);
  1484. break;
  1485. case "checkbox" :
  1486. $parameter_values = self::get_parameter_value($field["inputName"], $field_values, $field);
  1487. if(!empty($parameter_values) && !is_array($parameter_values)){
  1488. $parameter_values = explode(",", $parameter_values);
  1489. }
  1490.  
  1491. if(!is_array($field["inputs"]))
  1492. return "";
  1493.  
  1494. $choice_index = 0;
  1495. foreach($field["inputs"] as $input){
  1496. if(!empty($_POST["is_submit_" . $field["formId"]]) && $get_from_post){
  1497. $value[strval($input["id"])] = rgpost("input_" . str_replace('.', '_', strval($input["id"])));
  1498. }
  1499. else{
  1500. if(is_array($parameter_values)){
  1501. foreach($parameter_values as $item){
  1502. $item = trim($item);
  1503. if(self::choice_value_match($field, $field["choices"][$choice_index], $item))
  1504. {
  1505. $value[$input["id"] . ""] = $item;
  1506. break;
  1507. }
  1508. }
  1509. }
  1510. }
  1511. $choice_index++;
  1512. }
  1513.  
  1514. break;
  1515.  
  1516. case "list" :
  1517. $value = self::get_input_value($field, "input_" . $field["id"], rgar($field, "inputName"), $field_values, $get_from_post);
  1518. $value = self::create_list_array($field, $value);
  1519. break;
  1520.  
  1521. case "number" :
  1522. $value = self::get_input_value($field, "input_" . $field["id"], rgar($field, "inputName"), $field_values, $get_from_post);
  1523. $value = trim($value);
  1524. break;
  1525.  
  1526. default:
  1527.  
  1528. if(isset($field["inputs"]) && is_array($field["inputs"])){
  1529. foreach($field["inputs"] as $input){
  1530. $value[strval($input["id"])] = self::get_input_value($field, "input_" . str_replace('.', '_', strval($input["id"])), RGForms::get("name", $input), $field_values, $get_from_post);
  1531. }
  1532. }
  1533. else{
  1534. $value = self::get_input_value($field, "input_" . $field["id"], rgar($field, "inputName"), $field_values, $get_from_post);
  1535. }
  1536. break;
  1537. }
  1538.  
  1539. return $value;
  1540. }
  1541.  
  1542. private static function get_input_value($field, $standard_name, $custom_name = "", $field_values=array(), $get_from_post=true){
  1543. if(!empty($_POST["is_submit_" . rgar($field,"formId")]) && $get_from_post){
  1544. return rgpost($standard_name);
  1545. }
  1546. else if(rgar($field, "allowsPrepopulate")){
  1547. return self::get_parameter_value($custom_name, $field_values, $field);
  1548. }
  1549. }
  1550.  
  1551. public static function get_parameter_value($name, $field_values, $field){
  1552. $value = stripslashes(rgget($name));
  1553. if(empty($value))
  1554. $value = rgget($name, $field_values);
  1555.  
  1556. //converting list format
  1557. if(RGFormsModel::get_input_type($field) == "list"){
  1558.  
  1559. //transforms this: col1|col2,col1b|col2b into this: col1,col2,col1b,col2b
  1560. $column_count = count(rgar($field,"choices"));
  1561.  
  1562. $rows = explode(",", $value);
  1563. $ary_rows = array();
  1564. if(!empty($rows)){
  1565. foreach($rows as $row)
  1566. $ary_rows = array_merge($ary_rows, rgexplode("|", $row, $column_count));
  1567.  
  1568. $value = $ary_rows;
  1569. }
  1570. }
  1571.  
  1572. return apply_filters("gform_field_value_$name", $value);
  1573. }
  1574.  
  1575. public static function get_default_value($field, $input_id){
  1576. if(!is_array(rgar($field,"choices"))){
  1577. if(is_array(rgar($field, "inputs"))){
  1578. $input = RGFormsModel::get_input($field, $input_id);
  1579. return rgar($input, "defaultValue");
  1580. }
  1581. else{
  1582. return IS_ADMIN ? $field["defaultValue"] : GFCommon::replace_variables_prepopulate($field["defaultValue"]);
  1583. }
  1584. }
  1585. else if($field["type"] == "checkbox"){
  1586. for($i=0, $count=sizeof($field["inputs"]); $i<$count; $i++){
  1587. $input = $field["inputs"][$i];
  1588. $choice = $field["choices"][$i];
  1589. if($input["id"] == $input_id && $choice["isSelected"]){
  1590. return $choice["value"];
  1591. }
  1592. }
  1593. return "";
  1594. }
  1595. else{
  1596. foreach($field["choices"] as $choice){
  1597. if(rgar($choice,"isSelected") || $field["type"] == "post_category")
  1598. return $choice["value"];
  1599. }
  1600. return "";
  1601. }
  1602.  
  1603. }
  1604.  
  1605. public static function get_input_type($field){
  1606. return empty($field["inputType"]) ? rgar($field,"type") : $field["inputType"];
  1607. }
  1608.  
  1609. private static function get_post_field_value($field, $lead){
  1610.  
  1611. if(is_array($field["inputs"])){
  1612. $value = array();
  1613. foreach($field["inputs"] as $input){
  1614. $val = isset($lead[strval($input["id"])]) ? $lead[strval($input["id"])] : "";
  1615. if(!empty($val)) {
  1616.  
  1617. // replace commas in individual values to prevent individual value from being split into multiple values (checkboxes, multiselects)
  1618. if( in_array(RGFormsModel::get_input_type($field), array('checkbox', 'multiselect')) )
  1619. $val = str_replace(',', '&#44;', $val);
  1620.  
  1621. $value[] = $val;
  1622. }
  1623. }
  1624. $value = implode(",", $value);
  1625. }
  1626. else{
  1627. $value = isset($lead[$field["id"]]) ? $lead[$field["id"]] : "";
  1628. }
  1629. return $value;
  1630. }
  1631.  
  1632. private static function get_post_fields($form, $lead) {
  1633.  
  1634. $post_data = array();
  1635. $post_data["post_custom_fields"] = array();
  1636. $post_data["tags_input"] = array();
  1637. $categories = array();
  1638. $images = array();
  1639.  
  1640. foreach($form["fields"] as $field){
  1641.  
  1642. if($field['type'] == 'post_category')
  1643. $field = GFCommon::add_categories_as_choices($field, '');
  1644.  
  1645. $value = self::get_post_field_value($field, $lead);
  1646.  
  1647. switch($field["type"]){
  1648. case "post_title" :
  1649. case "post_excerpt" :
  1650. case "post_content" :
  1651. $post_data[$field["type"]] = $value;
  1652. break;
  1653.  
  1654. case "post_tags" :
  1655. $tags = explode(",", $value);
  1656. if(is_array($tags) && sizeof($tags) > 0)
  1657. $post_data["tags_input"] = array_merge($post_data["tags_input"], $tags) ;
  1658. break;
  1659.  
  1660. case "post_custom_field" :
  1661. $meta_name = $field["postCustomFieldName"];
  1662. if(!isset($post_data["post_custom_fields"][$meta_name])){
  1663. $post_data["post_custom_fields"][$meta_name] = $value;
  1664. }
  1665. else if(!is_array($post_data["post_custom_fields"][$meta_name])){
  1666. $post_data["post_custom_fields"][$meta_name] = array($post_data["post_custom_fields"][$meta_name], $value);
  1667. }
  1668. else{
  1669. $post_data["post_custom_fields"][$meta_name][] = $value;
  1670. }
  1671.  
  1672. break;
  1673.  
  1674. case "post_category" :
  1675. foreach(explode(',', $value) as $cat_string) {
  1676. list($cat_name, $cat_id) = rgexplode(":", $cat_string, 2);
  1677. array_push($categories, $cat_id);
  1678. }
  1679. break;
  1680.  
  1681. case "post_image" :
  1682. $ary = !empty($value) ? explode("|:|", $value) : array();
  1683. $url = count($ary) > 0 ? $ary[0] : "";
  1684. $title = count($ary) > 1 ? $ary[1] : "";
  1685. $caption = count($ary) > 2 ? $ary[2] : "";
  1686. $description = count($ary) > 3 ? $ary[3] : "";
  1687.  
  1688. array_push($images, array("field_id" => $field["id"], "url" => $url, "title" => $title, "description" => $description, "caption" => $caption));
  1689. break;
  1690. }
  1691. }
  1692.  
  1693. $post_data["post_status"] = rgar($form, "postStatus");
  1694. $post_data["post_category"] = !empty($categories) ? $categories : array(rgar($form, 'postCategory'));
  1695. $post_data["images"] = $images;
  1696.  
  1697. //setting current user as author depending on settings
  1698. $post_data["post_author"] = $form["useCurrentUserAsAuthor"] && !empty($lead["created_by"]) ? $lead["created_by"] : $form["postAuthor"];
  1699.  
  1700. return $post_data;
  1701. }
  1702.  
  1703. public static function get_custom_field_names(){
  1704. global $wpdb;
  1705. $keys = $wpdb->get_col( "
  1706. SELECT meta_key
  1707. FROM $wpdb->postmeta
  1708. WHERE meta_key NOT LIKE '\_%'
  1709. GROUP BY meta_key
  1710. ORDER BY meta_id DESC");
  1711.  
  1712. if ( $keys )
  1713. natcasesort($keys);
  1714.  
  1715. return $keys;
  1716. }
  1717.  
  1718. public static function get_input_masks(){
  1719.  
  1720. $masks = array(
  1721. 'US Phone' => '(999) 999-9999',
  1722. 'US Phone + Ext' => '(999) 999-9999? x99999',
  1723. 'Date' => '99/99/9999',
  1724. 'Tax ID' => '99-9999999',
  1725. 'SSN' => '999-99-9999',
  1726. 'Zip Code' => '99999',
  1727. 'Full Zip Code' => '99999?-9999'
  1728. );
  1729.  
  1730. return apply_filters('gform_input_masks', $masks);
  1731. }
  1732.  
  1733. private static function get_default_post_title(){
  1734. global $wpdb;
  1735. $title = "Untitled";
  1736. $count = 1;
  1737.  
  1738. $titles = $wpdb->get_col("SELECT post_title FROM $wpdb->posts WHERE post_title like '%Untitled%'");
  1739. $titles = array_values($titles);
  1740. while(in_array($title, $titles)){
  1741. $title = "Untitled_$count";
  1742. $count++;
  1743. }
  1744. return $title;
  1745. }
  1746.  
  1747. public static function prepare_date($date_format, $value){
  1748. $format = empty($date_format) ? "mdy" : $date_format;
  1749. $date_info = GFCommon::parse_date($value, $format);
  1750. if(!empty($date_info) && !GFCommon::is_empty_array($date_info))
  1751. $value = sprintf("%s-%02d-%02d", $date_info["year"], $date_info["month"], $date_info["day"]);
  1752. else
  1753. $value = "";
  1754.  
  1755. return $value;
  1756. }
  1757.  
  1758. /**
  1759. * Prepare the value before saving it to the lead.
  1760. *
  1761. * @param mixed $form
  1762. * @param mixed $field
  1763. * @param mixed $value
  1764. * @param mixed $input_name
  1765. * @param mixed $lead_id the current lead ID, used for fields that are processed after other fields have been saved (ie Total, Calculations)
  1766. * @param mixed $lead passed by the RGFormsModel::create_lead() method, lead ID is not available for leads created by this function
  1767. */
  1768. public static function prepare_value($form, $field, $value, $input_name, $lead_id, $lead = array()){
  1769. $form_id = $form["id"];
  1770.  
  1771. $input_type = self::get_input_type($field);
  1772. switch($input_type)
  1773. {
  1774. case "total" :
  1775. $lead = empty($lead) ? RGFormsModel::get_lead($lead_id) : $lead;
  1776. $value = GFCommon::get_order_total($form, $lead);
  1777. break;
  1778.  
  1779. case "calculation" :
  1780. // ignore submitted value and recalculate price in backend
  1781. list(,,$input_id) = rgexplode("_", $input_name, 3);
  1782. if($input_id == 2) {
  1783. require_once(GFCommon::get_base_path() . '/currency.php');
  1784. $currency = new RGCurrency(GFCommon::get_currency());
  1785. $lead = empty($lead) ? RGFormsModel::get_lead($lead_id) : $lead;
  1786. $value = $currency->to_money(GFCommon::calculate($field, $form, $lead));
  1787. }
  1788. break;
  1789.  
  1790. case "phone" :
  1791. if($field["phoneFormat"] == "standard" && preg_match('/^\D?(\d{3})\D?\D?(\d{3})\D?(\d{4})$/', $value, $matches))
  1792. $value = sprintf("(%s)%s-%s", $matches[1], $matches[2], $matches[3]);
  1793. break;
  1794.  
  1795. case "time":
  1796.  
  1797. if(!is_array($value) && !empty($value)){
  1798. preg_match('/^(\d*):(\d*) ?(.*)$/', $value, $matches);
  1799. $value = array();
  1800. $value[0] = $matches[1];
  1801. $value[1] = $matches[2];
  1802. $value[2] = rgar($matches,3);
  1803. }
  1804.  
  1805. $hour = empty($value[0]) ? "0" : strip_tags($value[0]);
  1806. $minute = empty($value[1]) ? "0" : strip_tags($value[1]);
  1807. $ampm = strip_tags(rgar($value,2));
  1808. if(!empty($ampm))
  1809. $ampm = " $ampm";
  1810.  
  1811. if(!(empty($hour) && empty($minute)))
  1812. $value = sprintf("%02d:%02d%s", $hour, $minute, $ampm);
  1813. else
  1814. $value = "";
  1815.  
  1816. break;
  1817.  
  1818. case "date" :
  1819. $value = self::prepare_date($field["dateFormat"], $value);
  1820.  
  1821. break;
  1822.  
  1823. case "post_image":
  1824. $url = self::get_fileupload_value($form_id, $input_name);
  1825. $image_title = isset($_POST["{$input_name}_1"]) ? strip_tags($_POST["{$input_name}_1"]) : "";
  1826. $image_caption = isset($_POST["{$input_name}_4"]) ? strip_tags($_POST["{$input_name}_4"]) : "";
  1827. $image_description = isset($_POST["{$input_name}_7"]) ? strip_tags($_POST["{$input_name}_7"]) : "";
  1828.  
  1829. $value = !empty($url) ? $url . "|:|" . $image_title . "|:|" . $image_caption . "|:|" . $image_description : "";
  1830. break;
  1831.  
  1832. case "fileupload" :
  1833. $value = self::get_fileupload_value($form_id, $input_name);
  1834. break;
  1835.  
  1836. case "number" :
  1837. $is_hidden = RGFormsModel::is_field_hidden($form, $field, array());
  1838. $lead = empty($lead) ? RGFormsModel::get_lead($lead_id) : $lead;
  1839. $value = GFCommon::has_field_calculation($field) ? GFCommon::round_number(GFCommon::calculate($field, $form, $lead), rgar($field, "calculationRounding")) : GFCommon::clean_number($value, rgar($field, "numberFormat"));
  1840. //return the value as a string when it is zero and a calc so that the "==" comparison done when checking if the field has changed isn't treated as false
  1841. if (GFCommon::has_field_calculation($field) && $value == 0){
  1842. $value = "0";
  1843. }
  1844. break;
  1845.  
  1846. case "website" :
  1847. if($value == "http://")
  1848. $value = "";
  1849. break;
  1850.  
  1851. case "list" :
  1852. if(GFCommon::is_empty_array($value))
  1853. $value = "";
  1854. else{
  1855. $value = self::create_list_array($field, $value);
  1856. $value = serialize($value);
  1857. }
  1858. break;
  1859.  
  1860. case "radio" :
  1861. if(rgar($field, 'enableOtherChoice') && $value == 'gf_other_choice')
  1862. $value = rgpost("input_{$field['id']}_other");
  1863. break;
  1864.  
  1865. case "multiselect" :
  1866. $value = empty($value) ? "" : implode(",", $value);
  1867. break;
  1868.  
  1869. case "creditcard" :
  1870. //saving last 4 digits of credit card
  1871. list($input_token, $field_id_token, $input_id) = rgexplode("_", $input_name, 3);
  1872. if($input_id == "1"){
  1873. $value = str_replace(" ", "", $value);
  1874. $card_number_length = strlen($value);
  1875. $value = substr($value, -4, 4);
  1876. $value = str_pad($value, $card_number_length, "X", STR_PAD_LEFT);
  1877. }
  1878. else if($input_id == "4")
  1879. {
  1880. $card_number = rgpost("input_{$field_id_token}_1");
  1881. $card_type = GFCommon::get_card_type($card_number);
  1882. $value = $card_type ? $card_type["name"] : "";
  1883. }
  1884. else{
  1885. $value = "";
  1886. }
  1887.  
  1888. break;
  1889.  
  1890. default:
  1891.  
  1892. //allow HTML for certain field types
  1893. $allow_html = in_array($field["type"], array("post_custom_field", "post_title", "post_content", "post_excerpt", "post_tags")) || in_array($input_type, array("checkbox", "radio")) ? true : false;
  1894. $allowable_tags = apply_filters("gform_allowable_tags_{$form_id}", apply_filters("gform_allowable_tags", $allow_html, $field, $form_id), $field, $form_id);
  1895.  
  1896. if($allowable_tags !== true)
  1897. $value = strip_tags($value, $allowable_tags);
  1898.  
  1899. break;
  1900. }
  1901.  
  1902. // special format for Post Category fields
  1903. if($field['type'] == 'post_category') {
  1904.  
  1905. $full_values = array();
  1906.  
  1907. if(!is_array($value))
  1908. $value = explode(',', $value);
  1909.  
  1910. foreach($value as $cat_id) {
  1911. $cat = get_term($cat_id, 'category');
  1912. $full_values[] = !is_wp_error($cat) && is_object($cat) ? $cat->name . ":" . $cat_id : "";
  1913. }
  1914.  
  1915. $value = implode(',', $full_values);
  1916. }
  1917.  
  1918. //do not save price fields with blank price
  1919. if(rgar($field, "enablePrice")){
  1920. $ary = explode("|", $value);
  1921. $label = count($ary) > 0 ? $ary[0] : "";
  1922. $price = count($ary) > 1 ? $ary[1] : "";
  1923.  
  1924. $is_empty = (strlen(trim($price)) <= 0);
  1925. if($is_empty)
  1926. $value = "";
  1927. }
  1928.  
  1929. return $value;
  1930. }
  1931.  
  1932. private static function create_list_array($field, $value){
  1933. if(!rgar($field,"enableColumns")){
  1934. return $value;
  1935. }
  1936. else{
  1937. $col_count = count(rgar($field, "choices"));
  1938. $rows = array();
  1939.  
  1940. $row_count = count($value)/$col_count;
  1941.  
  1942. $col_index = 0;
  1943. for($i=0; $i<$row_count; $i++){
  1944. $row = array();
  1945. foreach($field["choices"] as $column){
  1946. $row[$column["text"]] = rgar($value,$col_index);
  1947. $col_index++;
  1948. }
  1949. $rows[] = $row;
  1950. }
  1951. return $rows;
  1952. }
  1953. }
  1954.  
  1955. private static function get_fileupload_value($form_id, $input_name){
  1956. global $_gf_uploaded_files;
  1957. if(empty($_gf_uploaded_files))
  1958. $_gf_uploaded_files = array();
  1959.  
  1960. if(!isset($_gf_uploaded_files[$input_name])){
  1961.  
  1962. //check if file has already been uploaded by previous step
  1963. $file_info = self::get_temp_filename($form_id, $input_name);
  1964. $temp_filepath = self::get_upload_path($form_id) . "/tmp/" . $file_info["temp_filename"];
  1965. if($file_info && file_exists($temp_filepath)){
  1966. $_gf_uploaded_files[$input_name] = self::move_temp_file($form_id, $file_info);
  1967. }
  1968. else if (!empty($_FILES[$input_name]["name"])){
  1969. $_gf_uploaded_files[$input_name] = self::upload_file($form_id, $_FILES[$input_name]);
  1970. }
  1971. }
  1972.  
  1973. return rgget($input_name, $_gf_uploaded_files);
  1974. }
  1975.  
  1976. public static function get_form_unique_id($form_id) {
  1977. $unique_id = "";
  1978. if (rgpost("gform_submit") == $form_id) {
  1979. $posted_uid = rgpost("gform_unique_id");
  1980. if (false === empty($posted_uid)) {
  1981. $unique_id = $posted_uid;
  1982. self::$unique_ids[$form_id] = $unique_id;
  1983. } elseif (isset(self::$unique_ids[$form_id])) {
  1984. $unique_id = self::$unique_ids[$form_id];
  1985. } else {
  1986. $unique_id = uniqid();
  1987. self::$unique_ids[$form_id] = $unique_id;
  1988. }
  1989. }
  1990.  
  1991. return $unique_id;
  1992. }
  1993.  
  1994. public static function get_temp_filename($form_id, $input_name){
  1995.  
  1996. $uploaded_filename = !empty($_FILES[$input_name]["name"]) ? $_FILES[$input_name]["name"] : "";
  1997.  
  1998. if(empty($uploaded_filename) && isset(self::$uploaded_files[$form_id]))
  1999. $uploaded_filename = rgget($input_name, self::$uploaded_files[$form_id]);
  2000.  
  2001. if(empty($uploaded_filename))
  2002. return false;
  2003.  
  2004. $form_unique_id = self::get_form_unique_id($form_id);
  2005. $pathinfo = pathinfo($uploaded_filename);
  2006. return array("uploaded_filename" => $uploaded_filename, "temp_filename" => "{$form_unique_id}_{$input_name}.{$pathinfo["extension"]}");
  2007.  
  2008. }
  2009.  
  2010. public static function get_choice_text($field, $value, $input_id=0){
  2011. if(!is_array(rgar($field, "choices")))
  2012. return $value;
  2013.  
  2014. foreach($field["choices"] as $choice){
  2015. if(is_array($value) && self::choice_value_match($field, $choice, $value[$input_id])){
  2016. return $choice["text"];
  2017. }
  2018. else if(!is_array($value) && self::choice_value_match($field, $choice, $value)){
  2019. return $choice["text"];
  2020. }
  2021. }
  2022. return is_array($value) ? "" : $value;
  2023. }
  2024.  
  2025.  
  2026. public static function choice_value_match($field, $choice, $value){
  2027.  
  2028. if($choice["value"] == $value){
  2029. return true;
  2030. }
  2031. else if(rgget("enablePrice", $field)){
  2032. $ary = explode("|", $value);
  2033. $val = count($ary) > 0 ? $ary[0] : "";
  2034. $price = count($ary) > 1 ? $ary[1] : "";
  2035.  
  2036. if($val == $choice["value"])
  2037. return true;
  2038. }
  2039. // add support for prepopulating multiselects @alex
  2040. else if(RGFormsModel::get_input_type($field) == 'multiselect') {
  2041. $values = explode(',', $value);
  2042. if(in_array($choice['value'], $values))
  2043. return true;
  2044. }
  2045. return false;
  2046. }
  2047.  
  2048. public static function choices_value_match($field, $choices, $value) {
  2049. foreach($choices as $choice){
  2050. if(self::choice_value_match($field, $choice, $value))
  2051. return true;
  2052. }
  2053.  
  2054. return false;
  2055. }
  2056.  
  2057. public static function create_post($form, &$lead){
  2058.  
  2059. $has_post_field = false;
  2060. foreach($form["fields"] as $field){
  2061. $is_hidden = self::is_field_hidden($form, $field, array(), $lead);
  2062. if(!$is_hidden && in_array($field["type"], array("post_category","post_title","post_content","post_excerpt","post_tags","post_custom_field","post_image"))){
  2063. $has_post_field = true;
  2064. break;
  2065. }
  2066. }
  2067.  
  2068. //if this form does not have any post fields, don't create a post
  2069. if(!$has_post_field)
  2070. return $lead;
  2071.  
  2072. //processing post fields
  2073. $post_data = self::get_post_fields($form, $lead);
  2074.  
  2075. //allowing users to change post fields before post gets created
  2076. $post_data = apply_filters("gform_post_data_{$form["id"]}", apply_filters("gform_post_data", $post_data , $form, $lead), $form, $lead);
  2077.  
  2078. //adding default title if none of the required post fields are in the form (will make sure wp_insert_post() inserts the post)
  2079. if(empty($post_data["post_title"]) && empty($post_data["post_content"]) && empty($post_data["post_excerpt"])){
  2080. $post_data["post_title"] = self::get_default_post_title();
  2081. }
  2082.  
  2083. // remove original post status and save it for later
  2084. $post_status = $post_data['post_status'];
  2085.  
  2086. // replace original post status with 'draft' so other plugins know this post is not fully populated yet
  2087. $post_data['post_status'] = 'draft';
  2088.  
  2089. // inserting post
  2090. $post_id = wp_insert_post( $post_data );
  2091.  
  2092. //adding form id and entry id hidden custom fields
  2093. add_post_meta($post_id, "_gform-form-id", $form["id"]);
  2094. add_post_meta($post_id, "_gform-entry-id", $lead["id"]);
  2095.  
  2096. //creating post images
  2097. $post_images = array();
  2098. foreach($post_data["images"] as $image){
  2099. $image_meta= array( "post_excerpt" => $image["caption"],
  2100. "post_content" => $image["description"]);
  2101.  
  2102. //adding title only if it is not empty. It will default to the file name if it is not in the array
  2103. if(!empty($image["title"]))
  2104. $image_meta["post_title"] = $image["title"];
  2105.  
  2106. if(!empty($image["url"])){
  2107. $media_id = self::media_handle_upload($image["url"], $post_id, $image_meta);
  2108.  
  2109. if($media_id){
  2110.  
  2111. //save media id for post body/title template variable replacement (below)
  2112. $post_images[$image["field_id"]] = $media_id;
  2113. $lead[$image["field_id"]] .= "|:|$media_id";
  2114.  
  2115. // set featured image
  2116. $field = RGFormsModel::get_field($form, $image["field_id"]);
  2117. if(rgar($field, 'postFeaturedImage'))
  2118. set_post_thumbnail($post_id, $media_id);
  2119. }
  2120. }
  2121. }
  2122.  
  2123. //adding custom fields
  2124. foreach($post_data["post_custom_fields"] as $meta_name => $meta_value) {
  2125. if(!is_array($meta_value))
  2126. $meta_value = array($meta_value);
  2127.  
  2128. $meta_index = 0;
  2129. foreach($meta_value as $value){
  2130. $custom_field = self::get_custom_field($form, $meta_name, $meta_index);
  2131.  
  2132. //replacing template variables if template is enabled
  2133. if($custom_field && rgget("customFieldTemplateEnabled", $custom_field)){
  2134. //replacing post image variables
  2135. $value = GFCommon::replace_variables_post_image($custom_field["customFieldTemplate"], $post_images, $lead);
  2136.  
  2137. //replacing all other variables
  2138. $value = GFCommon::replace_variables($value, $form, $lead, false, false, false);
  2139.  
  2140. // replace conditional shortcodes
  2141. $value = do_shortcode($value);
  2142. }
  2143. switch(RGFormsModel::get_input_type($custom_field)){
  2144. case "list" :
  2145. $value = maybe_unserialize($value);
  2146. if(is_array($value)){
  2147. foreach($value as $item){
  2148. if(is_array($item))
  2149. $item = implode("|", $item);
  2150.  
  2151. if(!rgblank($item))
  2152. add_post_meta($post_id, $meta_name, $item);
  2153. }
  2154. }
  2155. break;
  2156.  
  2157. case "multiselect" :
  2158. case "checkbox" :
  2159. $value = explode(",", $value);
  2160. if(is_array($value)){
  2161. foreach($value as $item){
  2162. if(!rgblank($item)) {
  2163. // add post meta and replace HTML symbol in $item with real comma
  2164. add_post_meta($post_id, $meta_name, str_replace('&#44;', ',', $item));
  2165. }
  2166. }
  2167. }
  2168. break;
  2169.  
  2170. case "date" :
  2171. $value = GFCommon::date_display($value, rgar($custom_field, "dateFormat"));
  2172. if(!rgblank($value))
  2173. add_post_meta($post_id, $meta_name, $value);
  2174. break;
  2175.  
  2176. default :
  2177. if(!rgblank($value))
  2178. add_post_meta($post_id, $meta_name, $value);
  2179. break;
  2180. }
  2181.  
  2182. $meta_index++;
  2183. }
  2184. }
  2185.  
  2186. $has_content_field = sizeof(GFCommon::get_fields_by_type($form, array("post_content"))) > 0;
  2187. $has_title_field = sizeof(GFCommon::get_fields_by_type($form, array("post_title"))) > 0;
  2188. $post = false;
  2189.  
  2190. //if a post field was configured with a content or title template, process template
  2191. if( (rgar($form, "postContentTemplateEnabled") && $has_content_field) || (rgar($form, "postTitleTemplateEnabled") && $has_title_field) ){
  2192.  
  2193. $post = get_post($post_id);
  2194.  
  2195. if($form["postContentTemplateEnabled"] && $has_content_field){
  2196.  
  2197. //replacing post image variables
  2198. $post_content = GFCommon::replace_variables_post_image($form["postContentTemplate"], $post_images, $lead);
  2199.  
  2200. //replacing all other variables
  2201. $post_content = GFCommon::replace_variables($post_content, $form, $lead, false, false, false);
  2202.  
  2203. //updating post content
  2204. $post->post_content = $post_content;
  2205. }
  2206.  
  2207. if($form["postTitleTemplateEnabled"] && $has_title_field){
  2208.  
  2209. //replacing post image variables
  2210. $post_title = GFCommon::replace_variables_post_image($form["postTitleTemplate"], $post_images, $lead);
  2211.  
  2212. //replacing all other variables
  2213. $post_title = GFCommon::replace_variables($post_title, $form, $lead, false, false, false);
  2214.  
  2215. // replace conditional shortcodes
  2216. $post_title = do_shortcode($post_title);
  2217.  
  2218. //updating post
  2219. $post->post_title = $post_title;
  2220.  
  2221. $post->post_name = $post_title;
  2222. }
  2223.  
  2224. }
  2225.  
  2226. // update post status back to origional status (if not draft)
  2227. if( $post_status != 'draft' ) {
  2228. $post = is_object( $post ) ? $post : get_post( $post_id );
  2229. $post->post_status = $post_status;
  2230. }
  2231.  
  2232. // if post has been modified since creation, save updates
  2233. if( is_object( $post ) )
  2234. wp_update_post($post);
  2235.  
  2236. //adding post format
  2237. if(current_theme_supports('post-formats') && rgar($form, 'postFormat')) {
  2238.  
  2239. $formats = get_theme_support('post-formats');
  2240. $post_format = rgar($form, 'postFormat');
  2241.  
  2242. if(is_array($formats)) {
  2243. $formats = $formats[0];
  2244. if(in_array( $post_format, $formats)) {
  2245. set_post_format($post_id, $post_format);
  2246. } else if('0' == $post_format) {
  2247. set_post_format($post_id, false);
  2248. }
  2249. }
  2250.  
  2251. }
  2252.  
  2253. //update post_id field if a post was created
  2254. $lead["post_id"] = $post_id;
  2255. self::update_lead($lead);
  2256.  
  2257. do_action( 'gform_after_create_post', $post_id );
  2258.  
  2259. return $post_id;
  2260. }
  2261.  
  2262. private static function get_custom_field($form, $meta_name, $meta_index){
  2263. $custom_fields = GFCommon::get_fields_by_type($form, array("post_custom_field"));
  2264.  
  2265. $index = 0;
  2266. foreach($custom_fields as $field){
  2267. if($field["postCustomFieldName"] == $meta_name){
  2268. if($meta_index == $index){
  2269. return $field;
  2270. }
  2271. $index++;
  2272. }
  2273. }
  2274. return false;
  2275. }
  2276.  
  2277. private static function copy_post_image($url, $post_id){
  2278. $time = current_time('mysql');
  2279.  
  2280. if ( $post = get_post($post_id) ) {
  2281. if ( substr( $post->post_date, 0, 4 ) > 0 )
  2282. $time = $post->post_date;
  2283. }
  2284.  
  2285. //making sure there is a valid upload folder
  2286. if ( ! ( ( $uploads = wp_upload_dir($time) ) && false === $uploads['error'] ) )
  2287. return false;
  2288.  
  2289. $name = basename($url);
  2290.  
  2291. $filename = wp_unique_filename($uploads['path'], $name);
  2292.  
  2293. // Move the file to the uploads dir
  2294. $new_file = $uploads['path'] . "/$filename";
  2295.  
  2296. $uploaddir = wp_upload_dir();
  2297. $path = str_replace($uploaddir["baseurl"], $uploaddir["basedir"], $url);
  2298.  
  2299. if(!copy($path, $new_file))
  2300. return false;
  2301.  
  2302. // Set correct file permissions
  2303. $stat = stat( dirname( $new_file ));
  2304. $perms = $stat['mode'] & 0000666;
  2305. @ chmod( $new_file, $perms );
  2306.  
  2307. // Compute the URL
  2308. $url = $uploads['url'] . "/$filename";
  2309.  
  2310. if ( is_multisite() )
  2311. delete_transient( 'dirsize_cache' );
  2312.  
  2313. $type = wp_check_filetype($new_file);
  2314. return array("file" => $new_file, "url" => $url, "type" => $type["type"]);
  2315.  
  2316. }
  2317.  
  2318. private static function media_handle_upload($url, $post_id, $post_data = array()) {
  2319.  
  2320. //WordPress Administration API required for the media_handle_upload() function
  2321. require_once(ABSPATH . 'wp-admin/includes/image.php');
  2322.  
  2323. $name = basename($url);
  2324.  
  2325. $file = self::copy_post_image($url, $post_id);
  2326.  
  2327. if(!$file)
  2328. return false;
  2329.  
  2330. $name_parts = pathinfo($name);
  2331. $name = trim( substr( $name, 0, -(1 + strlen($name_parts['extension'])) ) );
  2332.  
  2333. $url = $file['url'];
  2334. $type = $file['type'];
  2335. $file = $file['file'];
  2336. $title = $name;
  2337. $content = '';
  2338.  
  2339. // use image exif/iptc data for title and caption defaults if possible
  2340. if ( $image_meta = @wp_read_image_metadata($file) ) {
  2341. if ( trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) )
  2342. $title = $image_meta['title'];
  2343. if ( trim( $image_meta['caption'] ) )
  2344. $content = $image_meta['caption'];
  2345. }
  2346.  
  2347. // Construct the attachment array
  2348. $attachment = array_merge( array(
  2349. 'post_mime_type' => $type,
  2350. 'guid' => $url,
  2351. 'post_parent' => $post_id,
  2352. 'post_title' => $title,
  2353. 'post_content' => $content,
  2354. ), $post_data );
  2355.  
  2356. // Save the data
  2357. $id = wp_insert_attachment($attachment, $file, $post_id);
  2358. if ( !is_wp_error($id) ) {
  2359. wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
  2360. }
  2361.  
  2362. return $id;
  2363. }
  2364.  
  2365. public static function save_input($form, $field, &$lead, $current_fields, $input_id){
  2366. global $wpdb;
  2367.  
  2368. $lead_detail_table = self::get_lead_details_table_name();
  2369. $lead_detail_long_table = self::get_lead_details_long_table_name();
  2370.  
  2371. $input_name = "input_" . str_replace('.', '_', $input_id);
  2372. $value = rgpost($input_name);
  2373.  
  2374. //ignore file upload when nothing was sent in the admin
  2375. //ignore post fields in the admin
  2376. if(RG_CURRENT_VIEW == "entry" && self::get_input_type($field) == "fileupload" && empty($_FILES[$input_name]["name"]))
  2377. return;
  2378. else if(RG_CURRENT_VIEW == "entry" && in_array($field["type"], array("post_category","post_title","post_content","post_excerpt","post_tags","post_custom_field","post_image")))
  2379. return;
  2380.  
  2381.  
  2382. if(empty($value) && rgar($field, "adminOnly") && !IS_ADMIN){
  2383. $value = self::get_default_value($field, $input_id);
  2384. }
  2385.  
  2386. //processing values so that they are in the correct format for each input type
  2387. $value = self::prepare_value($form, $field, $value, $input_name, rgar($lead, "id"));
  2388.  
  2389. //ignore fields that have not changed
  2390. if($lead != null && $value == rgget($input_id, $lead)){
  2391. return;
  2392. }
  2393.  
  2394. if(!empty($value) || $value === "0"){
  2395.  
  2396. $value = apply_filters("gform_save_field_value", $value, $lead, $field, $form);
  2397. $truncated_value = substr($value, 0, GFORMS_MAX_FIELD_LENGTH);
  2398.  
  2399. $lead_detail_id = self::get_lead_detail_id($current_fields, $input_id);
  2400. if($lead_detail_id > 0){
  2401.  
  2402. $wpdb->update($lead_detail_table, array("value" => $truncated_value), array("id" => $lead_detail_id), array("%s"), array("%d"));
  2403.  
  2404. //insert, update or delete long value
  2405. $sql = $wpdb->prepare("SELECT count(0) FROM $lead_detail_long_table WHERE lead_detail_id=%d", $lead_detail_id);
  2406. $has_long_field = intval($wpdb->get_var($sql)) > 0;
  2407.  
  2408. //delete long field if value has been shortened
  2409. if($has_long_field && strlen($value) <= GFORMS_MAX_FIELD_LENGTH){
  2410. $sql = $wpdb->prepare("DELETE FROM $lead_detail_long_table WHERE lead_detail_id=%d", $lead_detail_id);
  2411. $wpdb->query($sql);
  2412. }
  2413. //update long field
  2414. else if($has_long_field){
  2415. $wpdb->update($lead_detail_long_table, array("value" => $value), array("lead_detail_id" => $lead_detail_id), array("%s"), array("%d"));
  2416. }
  2417. //insert long field (value has been increased)
  2418. else if(strlen($value) > GFORMS_MAX_FIELD_LENGTH){
  2419. $wpdb->insert($lead_detail_long_table, array("lead_detail_id" => $lead_detail_id, "value" => $value), array("%d", "%s"));
  2420. }
  2421.  
  2422. }
  2423. else{
  2424. $wpdb->insert($lead_detail_table, array("lead_id" => $lead["id"], "form_id" => $form["id"], "field_number" => $input_id, "value" => $truncated_value), array("%d", "%d", "%F", "%s"));
  2425.  
  2426. if(strlen($value) > GFORMS_MAX_FIELD_LENGTH){
  2427.  
  2428. //read newly created lead detal id
  2429. $lead_detail_id = $wpdb->insert_id;
  2430.  
  2431. //insert long value
  2432. $wpdb->insert($lead_detail_long_table, array("lead_detail_id" => $lead_detail_id, "value" => $value), array("%d", "%s"));
  2433. }
  2434. }
  2435. }
  2436. else{
  2437. //Deleting long field if there is one
  2438. $sql = $wpdb->prepare("DELETE FROM $lead_detail_long_table
  2439. WHERE lead_detail_id IN(
  2440. SELECT id FROM $lead_detail_table WHERE lead_id=%d AND field_number BETWEEN %s AND %s
  2441. )",
  2442. $lead["id"], doubleval($input_id) - 0.001, doubleval($input_id) + 0.001);
  2443. $wpdb->query($sql);
  2444.  
  2445. //Deleting details for this field
  2446. $sql = $wpdb->prepare("DELETE FROM $lead_detail_table WHERE lead_id=%d AND field_number BETWEEN %s AND %s ", $lead["id"], doubleval($input_id) - 0.001, doubleval($input_id) + 0.001);
  2447. $wpdb->query($sql);
  2448. }
  2449. }
  2450.  
  2451. private static function move_temp_file($form_id, $tempfile_info){
  2452.  
  2453. $target = self::get_file_upload_path($form_id, $tempfile_info["uploaded_filename"]);
  2454. $source = self::get_upload_path($form_id) . "/tmp/" . $tempfile_info["temp_filename"];
  2455.  
  2456. if(rename($source, $target["path"])){
  2457. self::set_permissions($target["path"]);
  2458. return $target["url"];
  2459. }
  2460. else{
  2461. return "FAILED (Temporary file could not be moved.)";
  2462. }
  2463. }
  2464.  
  2465. private static function set_permissions($path){
  2466.  
  2467. $permission = apply_filters("gform_file_permission", 0644, $path);
  2468. if($permission){
  2469. chmod($path, $permission);
  2470. }
  2471. }
  2472.  
  2473. public static function upload_file($form_id, $file){
  2474.  
  2475. $target = self::get_file_upload_path($form_id, $file["name"]);
  2476. if(!$target)
  2477. return "FAILED (Upload folder could not be created.)";
  2478.  
  2479. if(move_uploaded_file($file['tmp_name'], $target["path"])){
  2480. self::set_permissions($target["path"]);
  2481. return $target["url"];
  2482. }
  2483. else{
  2484. return "FAILED (Temporary file could not be copied.)";
  2485. }
  2486. }
  2487.  
  2488.  
  2489. public static function get_upload_root(){
  2490. $dir = wp_upload_dir();
  2491.  
  2492. if($dir["error"])
  2493. return null;
  2494.  
  2495. return $dir["basedir"] . "/gravity_forms/";
  2496. }
  2497.  
  2498. public static function get_upload_url_root(){
  2499. $dir = wp_upload_dir();
  2500.  
  2501. if($dir["error"])
  2502. return null;
  2503.  
  2504. return $dir["baseurl"] . "/gravity_forms/";
  2505. }
  2506.  
  2507. public static function get_upload_path($form_id){
  2508. return self::get_upload_root() . $form_id . "-" . wp_hash($form_id);
  2509. }
  2510.  
  2511. public static function get_upload_url($form_id){
  2512. $dir = wp_upload_dir();
  2513. return $dir["baseurl"] . "/gravity_forms/$form_id" . "-" . wp_hash($form_id);
  2514. }
  2515.  
  2516. public static function get_file_upload_path($form_id, $file_name){
  2517. if (get_magic_quotes_gpc())
  2518. $file_name = stripslashes($file_name);
  2519.  
  2520. // Where the file is going to be placed
  2521. // Generate the yearly and monthly dirs
  2522. $time = current_time( 'mysql' );
  2523. $y = substr( $time, 0, 4 );
  2524. $m = substr( $time, 5, 2 );
  2525. $target_root = self::get_upload_path($form_id) . "/$y/$m/";
  2526. $target_root_url = self::get_upload_url($form_id) . "/$y/$m/";
  2527.  
  2528. //adding filter to upload root path and url
  2529. $upload_root_info = array("path" => $target_root, "url" => $target_root_url);
  2530. $upload_root_info = apply_filters("gform_upload_path_{$form_id}", apply_filters("gform_upload_path", $upload_root_info, $form_id), $form_id);
  2531.  
  2532. $target_root = $upload_root_info["path"];
  2533. $target_root_url = $upload_root_info["url"];
  2534.  
  2535. if(!is_dir($target_root)){
  2536. if(!wp_mkdir_p($target_root))
  2537. return false;
  2538.  
  2539. //adding index.html files to all subfolders
  2540. if(!file_exists(self::get_upload_root() . "/index.html")){
  2541. GFCommon::recursive_add_index_file(self::get_upload_root());
  2542. }
  2543. else if(!file_exists(self::get_upload_path($form_id) . "/index.html")){
  2544. GFCommon::recursive_add_index_file(self::get_upload_path($form_id));
  2545. }
  2546. else if(!file_exists(self::get_upload_path($form_id) . "/$y/index.html")){
  2547. GFCommon::recursive_add_index_file(self::get_upload_path($form_id) . "/$y");
  2548. }
  2549. else{
  2550. GFCommon::recursive_add_index_file(self::get_upload_path($form_id) . "/$y/$m");
  2551. }
  2552.  
  2553. }
  2554.  
  2555. //Add the original filename to our target path.
  2556. //Result is "uploads/filename.extension"
  2557. $file_info = pathinfo($file_name);
  2558. $extension = rgar($file_info, 'extension');
  2559. $file_name = basename($file_info["basename"], "." . $extension);
  2560.  
  2561. $file_name = sanitize_file_name($file_name);
  2562.  
  2563. $counter = 1;
  2564. $target_path = $target_root . $file_name . "." . $extension;
  2565. while(file_exists($target_path)){
  2566. $target_path = $target_root . $file_name . "$counter" . "." . $extension;
  2567. $counter++;
  2568. }
  2569.  
  2570. //creating url
  2571. $target_url = str_replace($target_root, $target_root_url, $target_path);
  2572.  
  2573. return array("path" => $target_path, "url" => $target_url);
  2574. }
  2575.  
  2576. public static function get_tables() {
  2577. return array(
  2578. self::get_lead_details_long_table_name(),
  2579. self::get_lead_notes_table_name(),
  2580. self::get_lead_details_table_name(),
  2581. self::get_lead_table_name(),
  2582. self::get_form_view_table_name(),
  2583. self::get_meta_table_name(),
  2584. self::get_form_table_name(),
  2585. self::get_lead_meta_table_name()
  2586. );
  2587. }
  2588.  
  2589. public static function drop_tables(){
  2590. global $wpdb;
  2591. foreach(self::get_tables() as $table) {
  2592. $wpdb->query("DROP TABLE IF EXISTS $table");
  2593. }
  2594. }
  2595.  
  2596. public static function mu_drop_tables($drop_tables) {
  2597. return array_merge($drop_tables, self::get_tables());
  2598. }
  2599.  
  2600. public static function insert_form_view($form_id, $ip){
  2601. global $wpdb;
  2602. $table_name = self::get_form_view_table_name();
  2603.  
  2604. $sql = $wpdb->prepare(" SELECT id FROM $table_name
  2605. WHERE form_id=%d
  2606. AND year(date_created) = year(utc_timestamp())
  2607. AND month(date_created) = month(utc_timestamp())
  2608. AND day(date_created) = day(utc_timestamp())
  2609. AND hour(date_created) = hour(utc_timestamp())", $form_id);
  2610.  
  2611. $id = $wpdb->get_var($sql, 0, 0);
  2612.  
  2613. if(empty($id))
  2614. $wpdb->query($wpdb->prepare("INSERT INTO $table_name(form_id, date_created, ip) values(%d, utc_timestamp(), %s)", $form_id, $ip));
  2615. else
  2616. $wpdb->query($wpdb->prepare("UPDATE $table_name SET count = count+1 WHERE id=%d", $id));
  2617. }
  2618.  
  2619. public static function is_duplicate($form_id, $field, $value){
  2620. global $wpdb;
  2621. $lead_detail_table_name = self::get_lead_details_table_name();
  2622. $lead_table_name = self::get_lead_table_name();
  2623. $sql_comparison = "ld.value=%s";
  2624.  
  2625. switch(RGFormsModel::get_input_type($field)){
  2626. case "time" :
  2627. $value = sprintf("%02d:%02d %s", $value[0], $value[1], $value[2]);
  2628. break;
  2629. case "date" :
  2630. $value = self::prepare_date(rgar($field, "dateFormat"), $value);
  2631. break;
  2632. case "number" :
  2633. $value = GFCommon::clean_number($value, rgar($field, 'numberFormat'));
  2634. break;
  2635. case "phone" :
  2636. $value = str_replace(array(")", "(", "-", " "), array("", "", "", ""), $value);
  2637. $sql_comparison = 'replace(replace(replace(replace(ld.value, ")", ""), "(", ""), "-", ""), " ", "") = %s';
  2638. break;
  2639. }
  2640.  
  2641.  
  2642. $inner_sql_template = " SELECT %s as input, ld.lead_id
  2643. FROM $lead_detail_table_name ld
  2644. INNER JOIN $lead_table_name l ON l.id = ld.lead_id
  2645. WHERE l.form_id=%d AND ld.form_id=%d
  2646. AND ld.field_number between %s AND %s
  2647. AND status='active' AND {$sql_comparison}";
  2648.  
  2649. $sql = "SELECT count(distinct input) as match_count FROM ( ";
  2650.  
  2651. $input_count = 1;
  2652. if(is_array($field["inputs"])){
  2653. $input_count = sizeof($field["inputs"]);
  2654. foreach($field["inputs"] as $input){
  2655. $union = empty($inner_sql) ? "" : " UNION ALL ";
  2656. $inner_sql .= $union . $wpdb->prepare($inner_sql_template, $input["id"], $form_id, $form_id, $input["id"] - 0.001, $input["id"] + 0.001, $value[$input["id"]]);
  2657. }
  2658. }
  2659. else{
  2660. $inner_sql = $wpdb->prepare($inner_sql_template, $field["id"], $form_id, $form_id, doubleval($field["id"]) - 0.001, doubleval($field["id"]) + 0.001, $value);
  2661. }
  2662.  
  2663. $sql .= $inner_sql . "
  2664. ) as count
  2665. GROUP BY lead_id
  2666. ORDER BY match_count DESC";
  2667.  
  2668. $count = apply_filters("gform_is_duplicate_{$form_id}", apply_filters('gform_is_duplicate', $wpdb->get_var($sql), $form_id, $field, $value), $form_id, $field, $value);
  2669.  
  2670. return $count != null && $count >= $input_count;
  2671. }
  2672.  
  2673. public static function get_lead($lead_id){
  2674. global $wpdb;
  2675. $lead_detail_table_name = self::get_lead_details_table_name();
  2676. $lead_table_name = self::get_lead_table_name();
  2677.  
  2678. $results = $wpdb->get_results($wpdb->prepare(" SELECT l.*, field_number, value
  2679. FROM $lead_table_name l
  2680. INNER JOIN $lead_detail_table_name ld ON l.id = ld.lead_id
  2681. WHERE l.id=%d", $lead_id));
  2682.  
  2683. $leads = self::build_lead_array($results, true);
  2684. return sizeof($leads) == 1 ? $leads[0] : false;
  2685. }
  2686.  
  2687. public static function get_lead_notes($lead_id){
  2688. global $wpdb;
  2689. $notes_table = self::get_lead_notes_table_name();
  2690.  
  2691. return $wpdb->get_results($wpdb->prepare(" SELECT n.id, n.user_id, n.date_created, n.value, ifnull(u.display_name,n.user_name) as user_name, u.user_email
  2692. FROM $notes_table n
  2693. LEFT OUTER JOIN $wpdb->users u ON n.user_id = u.id
  2694. WHERE lead_id=%d ORDER BY id", $lead_id));
  2695. }
  2696.  
  2697. public static function refresh_lead_field_value($lead_id, $field_id){
  2698. $cache_key = "GFFormsModel::get_lead_field_value_" . $lead_id . "_" . $field_id;
  2699. GFCache::delete($cache_key);
  2700. }
  2701.  
  2702. public static function get_lead_field_value($lead, $field){
  2703.  
  2704. if(empty($lead))
  2705. return;
  2706.  
  2707. //returning cache entry if available
  2708. $cache_key = "GFFormsModel::get_lead_field_value_" . $lead["id"] . "_" . $field["id"];
  2709.  
  2710. $cache_value = GFCache::get($cache_key);
  2711. if($cache_value !== false)
  2712. return $cache_value;
  2713.  
  2714. $max_length = GFORMS_MAX_FIELD_LENGTH;
  2715. $value = array();
  2716. if(is_array(rgar($field, "inputs"))){
  2717. //making sure values submitted are sent in the value even if
  2718. //there isn't an input associated with it
  2719. $lead_field_keys = array_keys($lead);
  2720. foreach($lead_field_keys as $input_id){
  2721. if(is_numeric($input_id) && absint($input_id) == absint($field["id"])){
  2722. $val = $lead[$input_id];
  2723. if(strlen($val) >= ($max_length-10)) {
  2724. if(empty($form))
  2725. $form = RGFormsModel::get_form_meta($lead["form_id"]);
  2726.  
  2727. $long_choice = self::get_field_value_long($lead, $input_id, $form);
  2728. }
  2729. else{
  2730. $long_choice = $val;
  2731. }
  2732.  
  2733. $value[$input_id] = !empty($long_choice) ? $long_choice : $val;
  2734. }
  2735. }
  2736. }
  2737. else{
  2738. $val = rgget($field["id"], $lead);
  2739.  
  2740. //To save a database call to get long text, only getting long text if regular field is "somewhat" large (i.e. max - 50)
  2741. if(strlen($val) >= ($max_length - 50)){
  2742. if(empty($form))
  2743. $form = RGFormsModel::get_form_meta($lead["form_id"]);
  2744.  
  2745. $long_text = self::get_field_value_long($lead, $field["id"], $form);
  2746. }
  2747.  
  2748. $value = !empty($long_text) ? $long_text : $val;
  2749. }
  2750.  
  2751. //filtering lead value
  2752. $value = apply_filters("gform_get_field_value", $value, $lead, $field);
  2753.  
  2754. //saving value in global variable to optimize performance
  2755. GFCache::set($cache_key, $value);
  2756.  
  2757. return $value;
  2758. }
  2759.  
  2760. public static function get_field_value_long($lead, $field_number, $form, $apply_filter=true){
  2761. global $wpdb;
  2762. $detail_table_name = self::get_lead_details_table_name();
  2763. $long_table_name = self::get_lead_details_long_table_name();
  2764.  
  2765. $sql = $wpdb->prepare(" SELECT l.value FROM $detail_table_name d
  2766. INNER JOIN $long_table_name l ON l.lead_detail_id = d.id
  2767. WHERE lead_id=%d AND field_number BETWEEN %s AND %s", $lead["id"], doubleval($field_number) - 0.001, doubleval($field_number) + 0.001);
  2768.  
  2769. $val = $wpdb->get_var($sql);
  2770.  
  2771. //running aform_get_input_value when needed
  2772. if($apply_filter){
  2773. $field = RGFormsModel::get_field($form, $field_number);
  2774. $input_id = (string)$field_number == (string)$field["id"] ? "" : $field_number;
  2775. $val = apply_filters("gform_get_input_value", $val, $lead, $field, $input_id);
  2776. }
  2777.  
  2778. return $val;
  2779. }
  2780.  
  2781. public static function get_leads_by_meta($meta_key, $meta_value){
  2782. global $wpdb;
  2783.  
  2784. $sql = $wpdb->prepare( " SELECT l.*, d.field_number, d.value
  2785. FROM {$wpdb->prefix}rg_lead l
  2786. INNER JOIN {$wpdb->prefix}rg_lead_detail d ON l.id = d.lead_id
  2787. INNER JOIN {$wpdb->prefix}rg_lead_meta m ON l.id = m.lead_id
  2788. WHERE m.meta_key=%s AND m.meta_value=%s", $meta_key, $meta_value);
  2789.  
  2790. //getting results
  2791. $results = $wpdb->get_results($sql);
  2792. $leads = self::build_lead_array($results);
  2793. return $leads;
  2794. }
  2795.  
  2796. public static function get_leads($form_id, $sort_field_number=0, $sort_direction='DESC', $search='', $offset=0, $page_size=30, $star=null, $read=null, $is_numeric_sort = false, $start_date=null, $end_date=null, $status='active', $payment_status = false){
  2797. global $wpdb;
  2798.  
  2799. if(empty($sort_field_number))
  2800. $sort_field_number = "date_created";
  2801.  
  2802. if(is_numeric($sort_field_number)) {
  2803. $sql = self::sort_by_custom_field_query($form_id, $sort_field_number, $sort_direction, $search, $offset, $page_size, $star, $read, $is_numeric_sort, $status, $payment_status);
  2804. } else {
  2805. $sql = self::sort_by_default_field_query($form_id, $sort_field_number, $sort_direction, $search, $offset, $page_size, $star, $read, $is_numeric_sort, $start_date, $end_date, $status, $payment_status);
  2806. }
  2807.  
  2808. //initializing rownum
  2809. $wpdb->query("select @rownum:=0");
  2810.  
  2811. GFCommon::log_debug($sql);
  2812.  
  2813. //getting results
  2814. $results = $wpdb->get_results($sql);
  2815.  
  2816. $leads = self::build_lead_array($results);
  2817.  
  2818. return $leads;
  2819. }
  2820.  
  2821. public static function get_lead_count($form_id, $search, $star=null, $read=null, $start_date=null, $end_date=null, $status=null, $payment_status = null){
  2822. global $wpdb;
  2823.  
  2824. if(!is_numeric($form_id))
  2825. return "";
  2826.  
  2827. $detail_table_name = self::get_lead_details_table_name();
  2828. $lead_table_name = self::get_lead_table_name();
  2829.  
  2830. $where = self::get_leads_where_sql(compact('form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status', 'is_default'));
  2831.  
  2832. $sql = "SELECT count(distinct l.id)
  2833. FROM $lead_table_name l
  2834. INNER JOIN $detail_table_name ld ON l.id = ld.lead_id
  2835. $where";
  2836.  
  2837. return $wpdb->get_var($sql);
  2838. }
  2839.  
  2840. public static function get_leads_count($form_id) { }
  2841.  
  2842. private static function sort_by_custom_field_query($form_id, $sort_field_number=0, $sort_direction='DESC', $search='', $offset=0, $page_size=30, $star=null, $read=null, $is_numeric_sort = false, $status='active', $payment_status = false){
  2843. global $wpdb;
  2844. if(!is_numeric($form_id) || !is_numeric($sort_field_number)|| !is_numeric($offset)|| !is_numeric($page_size))
  2845. return "";
  2846.  
  2847. $lead_detail_table_name = self::get_lead_details_table_name();
  2848. $lead_table_name = self::get_lead_table_name();
  2849.  
  2850. $orderby = $is_numeric_sort ? "ORDER BY query, (value+0) $sort_direction" : "ORDER BY query, value $sort_direction";
  2851. $is_default = false;
  2852.  
  2853. $search_sql = self::get_leads_where_sql(compact('form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status', 'is_default'));
  2854.  
  2855. $field_number_min = $sort_field_number - 0.001;
  2856. $field_number_max = $sort_field_number + 0.001;
  2857.  
  2858. $sql = "
  2859. SELECT filtered.sort, l.*, d.field_number, d.value
  2860. FROM $lead_table_name l
  2861. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  2862. INNER JOIN (
  2863. SELECT distinct sorted.sort, l.id
  2864. FROM $lead_table_name l
  2865. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  2866. INNER JOIN (
  2867. SELECT @rownum:=@rownum+1 as sort, id FROM (
  2868. SELECT 0 as query, lead_id as id, value
  2869. FROM $lead_detail_table_name
  2870. WHERE form_id=$form_id
  2871. AND field_number between $field_number_min AND $field_number_max
  2872.  
  2873. UNION ALL
  2874.  
  2875. SELECT 1 as query, l.id, d.value
  2876. FROM $lead_table_name l
  2877. LEFT OUTER JOIN $lead_detail_table_name d ON d.lead_id = l.id AND field_number between $field_number_min AND $field_number_max
  2878. WHERE l.form_id=$form_id
  2879. AND d.lead_id IS NULL
  2880.  
  2881. ) sorted1
  2882. $orderby
  2883. ) sorted ON d.lead_id = sorted.id
  2884. $search_sql
  2885. LIMIT $offset,$page_size
  2886. ) filtered ON filtered.id = l.id
  2887. ORDER BY filtered.sort";
  2888.  
  2889. return $sql;
  2890. }
  2891.  
  2892. private static function sort_by_default_field_query($form_id, $sort_field, $sort_direction='DESC', $search='', $offset=0, $page_size=30, $star=null, $read=null, $is_numeric_sort = false, $start_date=null, $end_date=null, $status='active', $payment_status = false){
  2893. global $wpdb;
  2894.  
  2895. if(!is_numeric($form_id) || !is_numeric($offset)|| !is_numeric($page_size)){
  2896. return "";
  2897. }
  2898.  
  2899. $lead_detail_table_name = self::get_lead_details_table_name();
  2900. $lead_table_name = self::get_lead_table_name();
  2901. $lead_meta_table_name = self::get_lead_meta_table_name();
  2902.  
  2903. $where = self::get_leads_where_sql(compact('form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status'));
  2904.  
  2905. $entry_meta = self::get_entry_meta($form_id);
  2906. $entry_meta_sql_join = "";
  2907. if ( false === empty( $entry_meta ) && array_key_exists( $sort_field, $entry_meta ) ) {
  2908. $entry_meta_sql_join = $wpdb->prepare("INNER JOIN
  2909. (
  2910. SELECT
  2911. lead_id, meta_value as $sort_field
  2912. from $lead_meta_table_name
  2913. WHERE meta_key = '$sort_field'
  2914. ) lead_meta_data ON lead_meta_data.lead_id = l.id
  2915. ");
  2916. $is_numeric_sort = $entry_meta[$sort_field]['is_numeric'];
  2917. }
  2918. $grid_columns = RGFormsModel::get_grid_columns($form_id);
  2919. if ( $sort_field != "date_created" && false === array_key_exists($sort_field, $grid_columns) )
  2920. $sort_field = "date_created";
  2921. $orderby = $is_numeric_sort ? "ORDER BY ($sort_field+0) $sort_direction" : "ORDER BY $sort_field $sort_direction";
  2922.  
  2923. $sql = "
  2924. SELECT filtered.sort, l.*, d.field_number, d.value
  2925. FROM $lead_table_name l
  2926. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  2927. INNER JOIN
  2928. (
  2929. SELECT @rownum:=@rownum + 1 as sort, id
  2930. FROM
  2931. (
  2932. SELECT distinct l.id
  2933. FROM $lead_table_name l
  2934. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  2935. $entry_meta_sql_join
  2936. $where
  2937. $orderby
  2938. LIMIT $offset,$page_size
  2939. ) page
  2940. ) filtered ON filtered.id = l.id
  2941. ORDER BY filtered.sort";
  2942.  
  2943. return $sql;
  2944. }
  2945.  
  2946. public static function get_leads_where_sql($args) {
  2947. global $wpdb;
  2948.  
  2949. extract(wp_parse_args($args, array(
  2950. 'form_id' => false,
  2951. 'search' => '',
  2952. 'status' => 'active',
  2953. 'star' => null,
  2954. 'read' => null,
  2955. 'start_date' => null,
  2956. 'end_date' => null,
  2957. 'payment_status' => null,
  2958. 'is_default' => true
  2959. )));
  2960.  
  2961. $where = array();
  2962.  
  2963. if($is_default)
  2964. $where[] = "l.form_id = $form_id";
  2965.  
  2966. if($search && $is_default) {
  2967. $where[] = $wpdb->prepare("value LIKE %s", "%$search%");
  2968. } else if($search) {
  2969. $where[] = $wpdb->prepare("d.value LIKE %s", "%$search%");
  2970. }
  2971.  
  2972. if($star !== null && $status == 'active')
  2973. $where[] = $wpdb->prepare("is_starred = %d AND status = 'active'", $star);
  2974.  
  2975. if($read !== null && $status == 'active')
  2976. $where[] = $wpdb->prepare("is_read = %d AND status = 'active'", $read);
  2977.  
  2978. if($payment_status)
  2979. $where[] = $wpdb->prepare("payment_status = '%s'", $payment_status);
  2980.  
  2981. if ($status !== null)
  2982. $where[] = $wpdb->prepare("status = %s", $status);
  2983.  
  2984. if(!empty($start_date))
  2985. $where[] = "timestampdiff(SECOND, '$start_date', date_created) >= 0";
  2986.  
  2987. if(!empty($end_date))
  2988. $where[] = "timestampdiff(SECOND, '$end_date', date_created) <= 0";
  2989.  
  2990. return 'WHERE ' . implode(' AND ', $where);
  2991. }
  2992.  
  2993. public static function build_lead_array($results, $use_long_values = false){
  2994.  
  2995. $leads = array();
  2996. $lead = array();
  2997. $form_id = 0;
  2998. if(is_array($results) && sizeof($results) > 0){
  2999. $form_id = $results[0]->form_id;
  3000. $lead = array("id" => $results[0]->id, "form_id" => $results[0]->form_id, "date_created" => $results[0]->date_created, "is_starred" => intval($results[0]->is_starred), "is_read" => intval($results[0]->is_read), "ip" => $results[0]->ip, "source_url" => $results[0]->source_url, "post_id" => $results[0]->post_id, "currency" => $results[0]->currency, "payment_status" => $results[0]->payment_status, "payment_date" => $results[0]->payment_date, "transaction_id" => $results[0]->transaction_id, "payment_amount" => $results[0]->payment_amount, "is_fulfilled" => $results[0]->is_fulfilled, "created_by" => $results[0]->created_by, "transaction_type" => $results[0]->transaction_type, "user_agent" => $results[0]->user_agent, "status" => $results[0]->status);
  3001.  
  3002. $form = RGFormsModel::get_form_meta($form_id);
  3003. $prev_lead_id=0;
  3004. foreach($results as $result){
  3005. if($prev_lead_id <> $result->id && $prev_lead_id > 0){
  3006. array_push($leads, $lead);
  3007. $lead = array("id" => $result->id, "form_id" => $result->form_id, "date_created" => $result->date_created, "is_starred" => intval($result->is_starred), "is_read" => intval($result->is_read), "ip" => $result->ip, "source_url" => $result->source_url, "post_id" => $result->post_id, "currency" => $result->currency, "payment_status" => $result->payment_status, "payment_date" => $result->payment_date, "transaction_id" => $result->transaction_id, "payment_amount" => $result->payment_amount, "is_fulfilled" => $result->is_fulfilled, "created_by" => $result->created_by, "transaction_type" => $result->transaction_type, "user_agent" => $result->user_agent, "status" => $result->status);
  3008. }
  3009.  
  3010. $field_value = $result->value;
  3011. //using long values if specified
  3012. if($use_long_values && strlen($field_value) >= (GFORMS_MAX_FIELD_LENGTH-10)){
  3013. $field = RGFormsModel::get_field($form, $result->field_number);
  3014. $long_text = RGFormsModel::get_field_value_long($lead, $result->field_number, $form, false);
  3015. $field_value = !empty($long_text) ? $long_text : $field_value;
  3016. }
  3017.  
  3018. $lead[$result->field_number] = $field_value;
  3019. $prev_lead_id = $result->id;
  3020. }
  3021. }
  3022.  
  3023.  
  3024. //adding last lead.
  3025. if(sizeof($lead) > 0)
  3026. array_push($leads, $lead);
  3027.  
  3028. //running entry through gform_get_field_value filter
  3029. foreach($leads as &$lead){
  3030. foreach($form["fields"] as $field){
  3031. if(isset($field["inputs"]) && is_array($field["inputs"])){
  3032. foreach($field["inputs"] as $input){
  3033. $lead[(string)$input["id"]] = apply_filters("gform_get_input_value", rgar($lead, (string)$input["id"]), $lead, $field, $input["id"]);
  3034. }
  3035. }
  3036. else{
  3037.  
  3038. $lead[$field["id"]] = apply_filters("gform_get_input_value", rgar($lead, (string)$field["id"]), $lead, $field, "");
  3039. }
  3040. }
  3041. }
  3042.  
  3043. //add custom entry properties
  3044. $entry_ids = array();
  3045. foreach($leads as $l){
  3046. $entry_ids[] = $l["id"];
  3047. }
  3048. $entry_meta = GFFormsModel::get_entry_meta($form_id);
  3049. $meta_keys = array_keys($entry_meta);
  3050. $entry_meta_data_rows = gform_get_meta_values_for_entries($entry_ids, $meta_keys);
  3051. foreach($leads as &$lead){
  3052. foreach($entry_meta_data_rows as $entry_meta_data_row){
  3053. if($entry_meta_data_row->lead_id == $lead["id"]){
  3054. foreach($meta_keys as $meta_key){
  3055. $lead[$meta_key] = $entry_meta_data_row->$meta_key;
  3056. }
  3057. }
  3058. }
  3059. }
  3060.  
  3061. return $leads;
  3062. }
  3063.  
  3064. public static function save_key($key){
  3065. $current_key = get_option("rg_gforms_key");
  3066. if(empty($key)){
  3067. delete_option("rg_gforms_key");
  3068. }
  3069. else if($current_key != $key){
  3070. $key = trim($key);
  3071. update_option("rg_gforms_key", md5($key));
  3072. }
  3073. }
  3074.  
  3075. public static function get_lead_ids($form_id, $search, $star=null, $read=null, $start_date=null, $end_date=null, $status=null, $payment_status = null){
  3076. global $wpdb;
  3077.  
  3078. if(!is_numeric($form_id))
  3079. return "";
  3080.  
  3081. $detail_table_name = self::get_lead_details_table_name();
  3082. $lead_table_name = self::get_lead_table_name();
  3083.  
  3084. $where = self::get_leads_where_sql(compact('form_id', 'search', 'status', 'star', 'read', 'start_date', 'end_date', 'payment_status', 'is_default'));
  3085.  
  3086. $sql = "SELECT distinct l.id
  3087. FROM $lead_table_name l
  3088. INNER JOIN $detail_table_name ld ON l.id = ld.lead_id
  3089. $where";
  3090.  
  3091. $rows = $wpdb->get_results($sql);
  3092.  
  3093. if(empty($rows))
  3094. return array();
  3095.  
  3096. foreach ($rows as $row){
  3097. $lead_ids[] = $row->id;
  3098. }
  3099.  
  3100. return $lead_ids;
  3101.  
  3102. }
  3103.  
  3104. public static function get_grid_columns($form_id, $input_label_only=false){
  3105. $form = self::get_form_meta($form_id);
  3106. $field_ids = self::get_grid_column_meta($form_id);
  3107.  
  3108. if(!is_array($field_ids)){
  3109. $field_ids = array();
  3110. for($i=0, $count=sizeof($form["fields"]); $i<$count && $i<5; $i++){
  3111. $field = $form["fields"][$i];
  3112.  
  3113. //loading post category fields with choices and inputs
  3114. if($field["type"] == "post_category")
  3115. $field = GFCommon::add_categories_as_choices($field, "");
  3116.  
  3117. if(RGForms::get("displayOnly",$field) || self::get_input_type($field) == "list")
  3118. continue;
  3119.  
  3120.  
  3121. if(isset($field["inputs"]) && is_array($field["inputs"])){
  3122. if($field["type"] == "name"){
  3123. $field_ids[] = $field["id"] . '.3'; //adding first name
  3124. $field_ids[] = $field["id"] . '.6'; //adding last name
  3125. }
  3126. else{
  3127. $field_ids[] = $field["inputs"][0]["id"]; //getting first input
  3128. }
  3129. }
  3130. else{
  3131. $field_ids[] = $field["id"];
  3132. }
  3133. }
  3134. //adding default entry meta columns
  3135. $entry_metas = GFFormsModel::get_entry_meta($form_id);
  3136. foreach ($entry_metas as $key => $entry_meta){
  3137. if (rgar($entry_meta,"is_default_column"))
  3138. $field_ids[] = $key;
  3139. }
  3140. }
  3141.  
  3142. $columns = array();
  3143. $entry_meta = self::get_entry_meta($form_id);
  3144. foreach($field_ids as $field_id){
  3145.  
  3146. switch($field_id){
  3147. case "id" :
  3148. $columns[$field_id] = array("label" => "Entry Id", "type" => "id");
  3149. break;
  3150. case "ip" :
  3151. $columns[$field_id] = array("label" => "User IP", "type" => "ip");
  3152. break;
  3153. case "date_created" :
  3154. $columns[$field_id] = array("label" => "Entry Date", "type" => "date_created");
  3155. break;
  3156. case "source_url" :
  3157. $columns[$field_id] = array("label" => "Source Url", "type" => "source_url");
  3158. break;
  3159. case "payment_status" :
  3160. $columns[$field_id] = array("label" => "Payment Status", "type" => "payment_status");
  3161. break;
  3162. case "transaction_id" :
  3163. $columns[$field_id] = array("label" => "Transaction Id", "type" => "transaction_id");
  3164. break;
  3165. case "payment_date" :
  3166. $columns[$field_id] = array("label" => "Payment Date", "type" => "payment_date");
  3167. break;
  3168. case "payment_amount" :
  3169. $columns[$field_id] = array("label" => "Payment Amount", "type" => "payment_amount");
  3170. break;
  3171. case "created_by" :
  3172. $columns[$field_id] = array("label" => "User", "type" => "created_by");
  3173. break;
  3174. case ((is_string($field_id) || is_int($field_id)) && array_key_exists($field_id, $entry_meta)) :
  3175. $columns[$field_id] = array("label" => $entry_meta[$field_id]["label"], "type" => $field_id);
  3176. break;
  3177. default :
  3178. $field = self::get_field($form, $field_id);
  3179. if($field)
  3180. $columns[strval($field_id)] = array("label" => self::get_label($field, $field_id, $input_label_only), "type" => rgget("type", $field), "inputType" => rgget("inputType", $field));
  3181. }
  3182. }
  3183. return $columns;
  3184. }
  3185.  
  3186. public static function get_label($field, $input_id = 0, $input_only = false){
  3187. $field_label = (IS_ADMIN || RG_CURRENT_PAGE == "select_columns.php" || RG_CURRENT_PAGE == "print-entry.php" || rgget("gf_page", $_GET) == "select_columns" || rgget("gf_page", $_GET) == "print-entry") && !rgempty("adminLabel", $field) ? rgar($field,"adminLabel") : rgar($field,"label");
  3188. $input = self::get_input($field, $input_id);
  3189. if(rgget("type", $field) == "checkbox" && $input != null)
  3190. return $input["label"];
  3191. else if($input != null)
  3192. return $input_only ? $input["label"] : $field_label . ' (' . $input["label"] . ')';
  3193. else
  3194. return $field_label;
  3195. }
  3196.  
  3197. public static function get_input($field, $id){
  3198. if(isset($field["inputs"]) && is_array($field["inputs"])){
  3199. foreach($field["inputs"] as $input)
  3200. {
  3201. if($input["id"] == $id)
  3202. return $input;
  3203. }
  3204. }
  3205. return null;
  3206. }
  3207.  
  3208. public static function has_input($field, $input_id){
  3209. if(!is_array($field["inputs"]))
  3210. return false;
  3211. else{
  3212. foreach($field["inputs"] as $input)
  3213. {
  3214. if($input["id"] == $input_id)
  3215. return true;
  3216. }
  3217. return false;
  3218. }
  3219. }
  3220.  
  3221. public static function get_current_page_url($force_ssl=false) {
  3222. $pageURL = 'http';
  3223. if (RGForms::get("HTTPS",$_SERVER) == "on" || $force_ssl)
  3224. $pageURL .= "s";
  3225. $pageURL .= "://";
  3226.  
  3227. $pageURL .= RGForms::get("HTTP_HOST", $_SERVER) . rgget("REQUEST_URI", $_SERVER);
  3228. return $pageURL;
  3229. }
  3230.  
  3231. public static function get_submitted_fields($form_id){
  3232. global $wpdb;
  3233. $lead_detail_table_name = self::get_lead_details_table_name();
  3234. $field_list = "";
  3235. $fields = $wpdb->get_results($wpdb->prepare("SELECT DISTINCT field_number FROM $lead_detail_table_name WHERE form_id=%d", $form_id));
  3236. foreach($fields as $field)
  3237. $field_list .= intval($field->field_number) . ',';
  3238.  
  3239. if(!empty($field_list))
  3240. $field_list = substr($field_list, 0, strlen($field_list) -1);
  3241.  
  3242. return $field_list;
  3243. }
  3244.  
  3245. public static function get_field($form, $field_id){
  3246. if(is_numeric($field_id))
  3247. $field_id = intval($field_id); //removing floating part of field (i.e 1.3 -> 1) to return field by input id
  3248.  
  3249. if(!is_array($form["fields"]))
  3250. return null;
  3251.  
  3252. global $_fields;
  3253. $key = $form["id"] . "_" . $field_id;
  3254. if(!isset($_fields[$key])){
  3255. $_fields[$key] = null;
  3256. foreach($form["fields"] as $field){
  3257. if($field["id"] == $field_id){
  3258. $_fields[$key] = $field;
  3259. break;
  3260. }
  3261. }
  3262. }
  3263. return $_fields[$key];
  3264. }
  3265.  
  3266. public static function is_html5_enabled(){
  3267. return get_option("rg_gforms_enable_html5");
  3268. }
  3269.  
  3270. /**
  3271. * Return the current lead being processed. Should only be called when a form has been submitted.
  3272. * If called before the "real" lead has been saved to the database, uses self::create_lead() to create
  3273. * a temporary lead to work with.
  3274. */
  3275. public static function get_current_lead() {
  3276.  
  3277. // if a GF submission is not in process, always return false
  3278. if(!rgpost('gform_submit'))
  3279. return false;
  3280.  
  3281. if(!self::$_current_lead) {
  3282. $form = self::get_form_meta(rgpost('gform_submit'));
  3283. self::$_current_lead = self::create_lead($form);
  3284. }
  3285.  
  3286. return self::$_current_lead;
  3287. }
  3288.  
  3289. /**
  3290. * Set RGFormsModel::$lead for use in hooks where $lead is not explicitly passed.
  3291. *
  3292. * @param mixed $lead
  3293. */
  3294. public static function set_current_lead($lead) {
  3295. GFCache::flush();
  3296. self::$_current_lead = $lead;
  3297. }
  3298.  
  3299. /**
  3300. * v1.7 introduces conditional confirmations. If the form's "confirmations" key is empty, grab the existing confirmation
  3301. * and populate it in the form's "confirmations" property.
  3302. *
  3303. * @param mixed $form
  3304. */
  3305. public static function convert_confirmation($form) {
  3306.  
  3307. $id = uniqid();
  3308.  
  3309. // convert confirmation to new confirmations format
  3310. $confirmation = $form['confirmation'];
  3311. $confirmation['id'] = $id;
  3312. $confirmation['name'] = __('Default Confirmation', 'gravityforms');
  3313. $confirmation['isDefault'] = true;
  3314.  
  3315. $form['confirmations'] = array($id => $confirmation);
  3316.  
  3317. self::save_form_confirmations($form['id'], $form['confirmations']);
  3318.  
  3319. return $form;
  3320. }
  3321.  
  3322. public static function load_confirmations($form) {
  3323.  
  3324. $confirmations = self::get_form_confirmations($form['id']);
  3325.  
  3326. // if there are no confirmations, convert existing (singular) confirmation (prior to 1.7) to new (plural) confirmations format
  3327. if(empty($confirmations)) {
  3328. $form = self::convert_confirmation($form);
  3329. } else {
  3330. $form['confirmations'] = $confirmations;
  3331. }
  3332.  
  3333. return $form;
  3334. }
  3335.  
  3336. public static function get_form_confirmations($form_id) {
  3337. global $wpdb;
  3338.  
  3339. if(isset($_confirmations[$form_id]))
  3340. return $_confirmations[$form_id];
  3341.  
  3342. $tablename = GFFormsModel::get_meta_table_name();
  3343. $sql = $wpdb->prepare("SELECT confirmations FROM $tablename WHERE form_id = %d", $form_id);
  3344. $results = $wpdb->get_results($sql, ARRAY_A);
  3345. $confirmations = rgars($results, '0/confirmations');
  3346.  
  3347. self::$_confirmations[$form_id] = $confirmations ? maybe_unserialize($confirmations) : array();
  3348.  
  3349. return self::$_confirmations[$form_id];
  3350. }
  3351.  
  3352. public static function save_form_confirmations($form_id, $confirmations) {
  3353. return self::update_form_meta($form_id, $confirmations, 'confirmations');
  3354. }
  3355.  
  3356. public static function save_form_notifications($form_id, $notifications) {
  3357. return self::update_form_meta($form_id, $notifications, 'notifications');
  3358. }
  3359.  
  3360. public static function get_entry_meta($form_id){
  3361. global $_entry_meta;
  3362. if(!isset($_entry_meta[$form_id])){
  3363. $_entry_meta = array();
  3364. $_entry_meta[$form_id] = apply_filters('gform_entry_meta', array(), $form_id);
  3365. }
  3366.  
  3367. return $_entry_meta[$form_id];
  3368. }
  3369.  
  3370. public static function set_entry_meta($lead, $form){
  3371. $entry_meta = self::get_entry_meta($form["id"]);
  3372. $keys = array_keys($entry_meta);
  3373. foreach ($keys as $key){
  3374. if (isset($entry_meta[$key]['update_entry_meta_callback'])){
  3375. $callback = $entry_meta[$key]['update_entry_meta_callback'];
  3376. $value = call_user_func_array($callback, array($key, $lead, $form));
  3377. gform_update_meta($lead["id"], $key, $value);
  3378. $lead[$key] = $value;
  3379. }
  3380. }
  3381. return $lead;
  3382. }
  3383.  
  3384. /*------- search entries ----------*/
  3385. //note: current only supports combining search criteria with AND
  3386.  
  3387. //search criteria examples
  3388.  
  3389. /*
  3390. $search_criteria[] = array('type' => 'field', 'key' => "1", 'value' => "gquiz159982170");
  3391.  
  3392. //note: this won't work for checkboxes if the checboxes have been re-ordered - best to use the following example below
  3393. $search_criteria[] = array('type' => 'field', 'key' => "2.2", 'value' => "gquiz246fec995");
  3394.  
  3395. //use to search checkbox values where values are unique - avoids missing checboxes that have been re-ordered
  3396. $search_criteria[] = array('type' => 'field', 'key' => "2", 'value' => "gquiz246fec995");
  3397.  
  3398. //any valid entry meta added using the gform_entry_meta hook
  3399. $search_criteria[] = array('type' => 'meta', 'key' => "gquiz_score", 'value' => "1");
  3400. $search_criteria[] = array('type' => 'meta', 'key' => "gquiz_is_pass", 'value' => "1");
  3401.  
  3402. //any column in the main leads table
  3403. $search_criteria[] = array("type" => "info", "key" => "status", "value"=>"active");
  3404. $search_criteria[] = array("type" => "info", "key" => "currency", "value"=>"USD");
  3405.  
  3406. $search_criteria[] = array('key' => 'date_created', 'type' => 'info', 'operator' => '>=', 'value' => $start_date );
  3407. $search_criteria[] = array('key' => 'date_created', 'type' => 'info', 'operator' => '<=', 'value' => $end_date );
  3408.  
  3409. //search values of any field
  3410. $search_criteria[] = array('type' => 'free-form', 'value' => $search_value);
  3411.  
  3412. //sorting: column, field or entry meta
  3413. $sorting = array('key' => $sort_field, 'direction' => $sort_direction );
  3414.  
  3415. //paging
  3416. $paging = array('offset' => 0, 'page_size' => 20 );
  3417. */
  3418.  
  3419. public static function search_leads($form_id, $search_criteria, $sorting = null, $paging = null) {
  3420.  
  3421. global $wpdb;
  3422. $sort_field = isset($sorting["key"]) ? $sorting["key"] : "date_created"; // column, field or entry meta
  3423.  
  3424. if (is_numeric($sort_field))
  3425. $sql = self::sort_by_field_query($form_id, $search_criteria, $sorting, $paging);
  3426. else
  3427. $sql = self::sort_by_column_query($form_id, $search_criteria, $sorting, $paging);
  3428.  
  3429. //initializing rownum
  3430. $wpdb->query("select @rownum:=0");
  3431.  
  3432. //getting results
  3433. $results = $wpdb->get_results($sql);
  3434.  
  3435. $leads = GFFormsModel::build_lead_array($results);
  3436.  
  3437. return $leads;
  3438. }
  3439.  
  3440. private static function sort_by_field_query($form_id, $search_criteria, $sorting, $paging) {
  3441. global $wpdb;
  3442. $sort_field_number = rgar($sorting, "key");
  3443. $sort_direction = isset($sorting["direction"]) ? $sorting["direction"] : "DESC";
  3444.  
  3445. $is_numeric_sort = isset($sorting["is_numeric"]) ? $sorting["is_numeric"] : false;
  3446. $offset = isset($paging["offset"]) ? $paging["offset"] : 0;
  3447. $page_size = isset($paging["page_size"]) ? $paging["page_size"] : 20;
  3448.  
  3449. if (!is_numeric($sort_field_number) || !is_numeric($offset) || !is_numeric($page_size))
  3450. return "";
  3451.  
  3452. $lead_detail_table_name = GFFormsModel::get_lead_details_table_name();
  3453. $lead_table_name = GFFormsModel::get_lead_table_name();
  3454.  
  3455. $orderby = $is_numeric_sort ? "ORDER BY query, (value+0) $sort_direction" : "ORDER BY query, value $sort_direction";
  3456.  
  3457. $search_where = self::get_search_where($form_id, $search_criteria);
  3458. $info_search_where = self::get_info_search_where($search_criteria);
  3459. if(!empty($search_where))
  3460. $info_search_where = " AND " . $info_search_where;
  3461. $where = empty($where) && empty($info_search_where) ? "" : "WHERE " . $search_where . $info_search_where;
  3462.  
  3463. if(is_array($form_id)){
  3464. $in_str_arr = array_fill(0, count($form_id), '%s');
  3465. $in_str = join($in_str_arr, ",");
  3466. $form_id_where = $wpdb->prepare(" AND form_id IN ($in_str)", $form_id);
  3467. } else {
  3468. $form_id_where = $form_id > 0 ? $wpdb->prepare(" AND form_id=%d", $form_id) : "";
  3469. }
  3470.  
  3471.  
  3472.  
  3473. $field_number_min = $sort_field_number - 0.001;
  3474. $field_number_max = $sort_field_number + 0.001;
  3475.  
  3476. $sql = "
  3477. SELECT filtered.sort, l.*, d.field_number, d.value
  3478. FROM $lead_table_name l
  3479. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  3480. INNER JOIN (
  3481. SELECT distinct sorted.sort, l.id
  3482. FROM $lead_table_name l
  3483. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  3484. INNER JOIN (
  3485. SELECT @rownum:=@rownum+1 as sort, id FROM (
  3486. SELECT 0 as query, lead_id as id, value
  3487. FROM $lead_detail_table_name
  3488. WHERE field_number between $field_number_min AND $field_number_max
  3489. $form_id_where
  3490.  
  3491. UNION ALL
  3492.  
  3493. SELECT 1 as query, l.id, d.value
  3494. FROM $lead_table_name l
  3495. LEFT OUTER JOIN $lead_detail_table_name d ON d.lead_id = l.id AND field_number between $field_number_min AND $field_number_max
  3496. WHERE d.lead_id IS NULL
  3497. $form_id_where
  3498.  
  3499. ) sorted1
  3500. $orderby
  3501. ) sorted ON d.lead_id = sorted.id
  3502. $where
  3503. LIMIT $offset,$page_size
  3504. ) filtered ON filtered.id = l.id
  3505.  
  3506. ORDER BY filtered.sort";
  3507.  
  3508. return $sql;
  3509. }
  3510.  
  3511. private static function sort_by_column_query($form_id, $search_criteria, $sorting, $paging) {
  3512. global $wpdb;
  3513. $sort_field = isset($sorting["key"]) ? $sorting["key"] : "date_created";
  3514. $sort_direction = isset($sorting["direction"]) ? $sorting["direction"] : "DESC";
  3515. $is_numeric_sort = isset($sorting["is_numeric"]) ? $sorting["is_numeric"] : false;
  3516. $offset = isset($paging["offset"]) ? $paging["offset"] : 0;
  3517. $page_size = isset($paging["page_size"]) ? $paging["page_size"] : 20;
  3518.  
  3519. if (!is_numeric($offset) || !is_numeric($page_size)) {
  3520. return "";
  3521. }
  3522.  
  3523. $lead_detail_table_name = GFFormsModel::get_lead_details_table_name();
  3524. $lead_table_name = GFFormsModel::get_lead_table_name();
  3525. $lead_meta_table_name = GFFormsModel::get_lead_meta_table_name();
  3526.  
  3527. $entry_meta = GFFormsModel::get_entry_meta(is_array($form_id) ? 0 : $form_id);
  3528. $entry_meta_sql_join = "";
  3529. if (false === empty($entry_meta) && array_key_exists($sort_field, $entry_meta)) {
  3530. $entry_meta_sql_join = $wpdb->prepare("INNER JOIN
  3531. (
  3532. SELECT
  3533. lead_id, meta_value as $sort_field
  3534. from $lead_meta_table_name
  3535. WHERE meta_key=%s
  3536. ) lead_meta_data ON lead_meta_data.lead_id = l.id
  3537. ", $sort_field);
  3538. $is_numeric_sort = $entry_meta[$sort_field]['is_numeric'];
  3539. }
  3540.  
  3541. $grid_columns = is_array($form_id) || $form_id == 0 ? array() : RGFormsModel::get_grid_columns($form_id);
  3542. if ($sort_field != "date_created" && false === array_key_exists($sort_field, $grid_columns))
  3543. $sort_field = "date_created";
  3544. $orderby = $is_numeric_sort ? "ORDER BY ($sort_field+0) $sort_direction" : "ORDER BY $sort_field $sort_direction";
  3545.  
  3546. $where_arr = array();
  3547. $search_where = self::get_search_where($form_id, $search_criteria);
  3548. if (!empty($search_where))
  3549. $where_arr[]=$search_where;
  3550. $info_search_where = self::get_info_search_where($search_criteria);
  3551. if(!empty($info_search_where))
  3552. $where_arr[] = $info_search_where;
  3553.  
  3554. if(is_array($form_id)){
  3555. $in_str_arr = array_fill(0, count($form_id), '%s');
  3556. $in_str = join($in_str_arr, ",");
  3557. $form_id_where = $wpdb->prepare("l.form_id IN ($in_str)", $form_id);
  3558. } else {
  3559. $form_id_where = $form_id > 0 ? $wpdb->prepare("l.form_id=%d", $form_id) : "";
  3560. }
  3561.  
  3562.  
  3563. if(!empty($form_id_where))
  3564. $where_arr[] = $form_id_where;
  3565. $where = empty($where_arr) ? "" : "WHERE " . join($where_arr, " AND ") ;
  3566.  
  3567. $sql = "
  3568. SELECT filtered.sort, l.*, d.field_number, d.value
  3569. FROM $lead_table_name l
  3570. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  3571. INNER JOIN
  3572. (
  3573. SELECT @rownum:=@rownum + 1 as sort, id
  3574. FROM
  3575. (
  3576. SELECT distinct l.id
  3577. FROM $lead_table_name l
  3578. INNER JOIN $lead_detail_table_name d ON d.lead_id = l.id
  3579. $entry_meta_sql_join
  3580. $where
  3581. $orderby
  3582. LIMIT $offset,$page_size
  3583. ) page
  3584. ) filtered ON filtered.id = l.id
  3585.  
  3586. ORDER BY filtered.sort";
  3587.  
  3588. return $sql;
  3589. }
  3590.  
  3591. private static function get_search_where($form_id, $search_criteria) {
  3592. global $wpdb;
  3593. $sql_array = array();
  3594. $lead_details_table_name = GFFormsModel::get_lead_details_table_name();
  3595. $lead_meta_table_name = GFFormsModel::get_lead_meta_table_name();
  3596. if(is_array($form_id)){
  3597. $in_str_arr = array_fill(0, count($form_id), '%s');
  3598. $in_str = join($in_str_arr, ",");
  3599. $form_id_where = $wpdb->prepare("WHERE form_id IN ($in_str)", $form_id);
  3600. } else {
  3601. $form_id_where = $form_id > 0 ? $wpdb->prepare("WHERE form_id=%d", $form_id) : "";
  3602. }
  3603.  
  3604. foreach ($search_criteria as $search) {
  3605. $key = rgar($search, "key");
  3606. $val = rgar($search, "value");
  3607. $operator = isset($search["operator"]) ? strtolower($search["operator"]) : "=";
  3608. if("is" == $operator)
  3609. $operator = "=";
  3610. if("isnot" == $operator)
  3611. $operator = "<>";
  3612. if("contains" == $operator)
  3613. $operator = "like";
  3614.  
  3615. switch (rgar($search, "type")) {
  3616.  
  3617. case "field":
  3618. $upper_field_number_limit = (string)(int)$key === $key ? (float)$key + 0.9999 : (float)$key + 0.0001;
  3619.  
  3620. $search_term = "like" == $operator ? "%$val%" : $val;
  3621. /* doesn't support "<>" for checkboxes */
  3622. $sql_array[] = $wpdb->prepare("l.id IN
  3623. (
  3624. SELECT
  3625. lead_id
  3626. from $lead_details_table_name
  3627. $form_id_where
  3628. AND (field_number BETWEEN %s AND %s AND value $operator %s)
  3629. )
  3630. ", (float)$key - 0.0001, $upper_field_number_limit, $search_term);
  3631. /*
  3632. //supports "<>" for checkboxes but it doesn't scale
  3633. $sql_array[] = $wpdb->prepare("l.id IN
  3634. (SELECT lead_id
  3635. FROM
  3636. (
  3637. SELECT lead_id, value
  3638. FROM $lead_details_table_name
  3639. WHERE form_id = %d
  3640. AND (field_number BETWEEN %s AND %s)
  3641. GROUP BY lead_id
  3642. HAVING value $operator %s
  3643. ) ld
  3644. )
  3645. ", $form_id, (float)$key - 0.0001, $upper_field_number_limit, $val );
  3646. */
  3647. break;
  3648. case "meta":
  3649. /* doesn't support "<>" for multiple values of the same key */
  3650. $entry_meta = self::get_entry_meta(is_array($form_id) ? 0 : $form_id);
  3651. $meta = rgar($entry_meta, $key);
  3652. $placeholder = rgar($meta, "is_numeric") ? "%d" : "%s";
  3653. $search_term = "like" == $operator ? "%$val%" : $val;
  3654. $sql_array[] = $wpdb->prepare("l.id IN
  3655. (
  3656. SELECT
  3657. lead_id
  3658. FROM $lead_meta_table_name
  3659. WHERE meta_key=%s AND meta_value $operator $placeholder
  3660. )
  3661. ", $search["key"], $search_term);
  3662. break;
  3663.  
  3664. }
  3665.  
  3666. }
  3667.  
  3668. $sql = empty($sql_array) ? "" : join(" AND ", $sql_array);
  3669.  
  3670. return $sql;
  3671. }
  3672.  
  3673. private static function get_info_search_where($search_criteria) {
  3674. global $wpdb;
  3675. $where_array = array();
  3676. foreach ($search_criteria as $search) {
  3677.  
  3678. switch (rgar($search, "type")) {
  3679. case "free-form":
  3680. $val = $search["value"];
  3681. $operator = isset($search["operator"]) ? strtolower($search["operator"]) : "like";
  3682. if("contains" == $operator)
  3683. $operator = "like";
  3684. if("is" == $operator)
  3685. $operator = "=";
  3686. if("isnot" == $operator)
  3687. $operator = "<>";
  3688. $search_term = "like" == $operator ? "%$val%" : $val;
  3689. $where_array[] = $wpdb->prepare("value $operator %s", $search_term);
  3690. break;
  3691. case "info":
  3692. $col = $search["key"];
  3693. $val = $search["value"];
  3694. $operator = isset($search["operator"]) ? strtolower($search["operator"]) : "=";
  3695. if("contains" == $operator)
  3696. $operator = "like";
  3697. if("is" == $operator)
  3698. $operator = "=";
  3699. if("isnot" == $operator)
  3700. $operator = "<>";
  3701. $search_term = "like" == $operator ? "%$val%" : $val;
  3702. if ("date_created" === $col)
  3703. $where_array[] = $wpdb->prepare("datediff(date_created, %s) $operator 0", $val);
  3704. else
  3705. $where_array[] = $wpdb->prepare("{$col} $operator %s", $search_term);
  3706. break;
  3707. }
  3708. }
  3709. $sql = empty($where_array) ? "" : join(" AND ", $where_array);
  3710.  
  3711. return $sql;
  3712. }
  3713.  
  3714. public static function count_search_leads($form_id, $search_criteria) {
  3715. global $wpdb;
  3716.  
  3717. if (!is_numeric($form_id))
  3718. return "";
  3719.  
  3720. $detail_table_name = GFFormsModel::get_lead_details_table_name();
  3721. $lead_table_name = GFFormsModel::get_lead_table_name();
  3722.  
  3723. $where_arr = array();
  3724.  
  3725. $search_where = self::get_search_where($form_id, $search_criteria);
  3726. if (!empty($search_where))
  3727. $where_arr[]=$search_where;
  3728. $info_search_where = self::get_info_search_where($search_criteria);
  3729. if(!empty($info_search_where))
  3730. $where_arr[] = $info_search_where;
  3731.  
  3732. if(is_array($form_id)){
  3733. $in_str_arr = array_fill(0, count($form_id), '%s');
  3734. $in_str = join($in_str_arr, ",");
  3735. $form_id_where = $wpdb->prepare("l.form_id IN ($in_str)", $form_id);
  3736. } else {
  3737. $form_id_where = $form_id > 0 ? $wpdb->prepare("l.form_id=%d", $form_id) : "";
  3738. }
  3739.  
  3740. if(!empty($form_id_where))
  3741. $where_arr[] = $form_id_where;
  3742. $where = empty($where_arr) ? "" : "WHERE " . join($where_arr, " AND ") ;
  3743.  
  3744. $sql = "SELECT count(distinct l.id)
  3745. FROM $lead_table_name l
  3746. INNER JOIN $detail_table_name ld ON l.id = ld.lead_id
  3747. $where
  3748. ";
  3749.  
  3750. return $wpdb->get_var($sql);
  3751. }
  3752.  
  3753. }
  3754.  
  3755. class RGFormsModel extends GFFormsModel { }
  3756.  
  3757. global $_gform_lead_meta;
  3758. $_gform_lead_meta = array();
  3759.  
  3760. //functions to handle lead meta
  3761. function gform_get_meta($entry_id, $meta_key){
  3762. global $wpdb, $_gform_lead_meta;
  3763.  
  3764. //get from cache if available
  3765. $cache_key = $entry_id . "_" . $meta_key;
  3766. if(array_key_exists($cache_key, $_gform_lead_meta))
  3767. return $_gform_lead_meta[$cache_key];
  3768.  
  3769. $table_name = RGFormsModel::get_lead_meta_table_name();
  3770. $results = $wpdb->get_results($wpdb->prepare("SELECT meta_value FROM {$table_name} WHERE lead_id=%d AND meta_key=%s", $entry_id, $meta_key));
  3771. $value = isset($results[0]) ? $results[0]->meta_value : null;
  3772. $meta_value = $value == null ? false : maybe_unserialize($value);
  3773. $_gform_lead_meta[$cache_key] = $meta_value;
  3774. return $meta_value;
  3775. }
  3776.  
  3777. function gform_get_meta_values_for_entries($entry_ids, $meta_keys){
  3778. global $wpdb;
  3779.  
  3780. if (empty($meta_keys) || empty($entry_ids))
  3781. return array();
  3782.  
  3783. $table_name = RGFormsModel::get_lead_meta_table_name();
  3784. $meta_value_array = array();
  3785. $select_meta_keys = join(",", $meta_keys);
  3786. $meta_key_select_array = array();
  3787.  
  3788. foreach($meta_keys as $meta_key){
  3789. $meta_key_select_array[] = "max(case when meta_key = '$meta_key' then meta_value end) as $meta_key";
  3790. }
  3791.  
  3792. $entry_ids_str = join(",", $entry_ids);
  3793.  
  3794. $meta_key_select = join(",", $meta_key_select_array);
  3795.  
  3796. $sql_query = " SELECT
  3797. lead_id, $meta_key_select
  3798. FROM $table_name
  3799. WHERE lead_id IN ($entry_ids_str)
  3800. GROUP BY lead_id";
  3801.  
  3802. $results = $wpdb->get_results($sql_query);
  3803.  
  3804. foreach($results as $result){
  3805. foreach($meta_keys as $meta_key){
  3806. $result->$meta_key = $result->$meta_key == null ? false : maybe_unserialize($result->$meta_key);
  3807. }
  3808. }
  3809.  
  3810. $meta_value_array = $results;
  3811. return $meta_value_array;
  3812. }
  3813.  
  3814. function gform_update_meta($entry_id, $meta_key, $meta_value){
  3815. global $wpdb, $_gform_lead_meta;
  3816. $table_name = RGFormsModel::get_lead_meta_table_name();
  3817. if (false === $meta_value)
  3818. $meta_value = "0";
  3819. $meta_value = maybe_serialize($meta_value);
  3820. $meta_exists = gform_get_meta($entry_id, $meta_key) !== false;
  3821. if($meta_exists){
  3822. $wpdb->update($table_name, array("meta_value" => $meta_value), array("lead_id" => $entry_id, "meta_key" => $meta_key),array("%s"), array("%d", "%s"));
  3823. }
  3824. else{
  3825. $lead_table_name = RGFormsModel::get_lead_table_name();
  3826. $form_id = $wpdb->get_var($wpdb->prepare("SELECT form_id from $lead_table_name WHERE id=%d", $entry_id));
  3827. $wpdb->insert($table_name, array("form_id" => $form_id, "lead_id" => $entry_id, "meta_key" => $meta_key, "meta_value" => $meta_value), array("%d", "%d", "%s", "%s"));
  3828. }
  3829.  
  3830. //updates cache
  3831. $cache_key = $entry_id . "_" . $meta_key;
  3832. if(array_key_exists($cache_key, $_gform_lead_meta))
  3833. $_gform_lead_meta[$cache_key] = maybe_unserialize($meta_value);
  3834. }
  3835.  
  3836. function gform_delete_meta($entry_id, $meta_key=""){
  3837. global $wpdb, $_gform_lead_meta;
  3838. $table_name = RGFormsModel::get_lead_meta_table_name();
  3839. $meta_filter = empty($meta_key) ? "" : $wpdb->prepare("AND meta_key=%s", $meta_key);
  3840.  
  3841. $wpdb->query($wpdb->prepare("DELETE FROM {$table_name} WHERE lead_id=%d {$meta_filter}", $entry_id));
  3842.  
  3843. //clears cache.
  3844. $_gform_lead_meta = array();
  3845. }
  3846.  
  3847. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement