PageRenderTime 68ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/manage/expressionengine/third_party/freeform/mod.freeform.php

https://bitbucket.org/jondaiello/h5sp-r
PHP | 4705 lines | 2723 code | 857 blank | 1125 comment | 347 complexity | 6423456dbd1584effeec738124ef821f MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception

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

  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * Freeform - User Side
  4. *
  5. * @package Solspace:Freeform
  6. * @author Solspace, Inc.
  7. * @copyright Copyright (c) 2008-2015, Solspace, Inc.
  8. * @link http://solspace.com/docs/freeform
  9. * @license http://www.solspace.com/license_agreement
  10. * @version 4.2.3
  11. * @filesource freeform/mod.freeform.php
  12. */
  13. if ( ! class_exists('Module_builder_freeform'))
  14. {
  15. require_once 'addon_builder/module_builder.php';
  16. }
  17. class Freeform extends Module_builder_freeform
  18. {
  19. /**
  20. * return data for when the constructor os only called
  21. * unused thusfar in this addon.
  22. * @var string
  23. */
  24. public $return_data = '';
  25. /**
  26. * Multipart form?
  27. * @var boolean
  28. * @see form
  29. */
  30. public $multipart = FALSE;
  31. /**
  32. * Params array storage for param
  33. * @var array
  34. * @see param
  35. */
  36. public $params = array();
  37. /**
  38. * params id for param fetch
  39. * @var integer
  40. * @see form
  41. * @see insert_params
  42. */
  43. public $params_id = 0;
  44. /**
  45. * Form ID storage
  46. * @var integer
  47. * @see form_id
  48. */
  49. public $form_id = 0;
  50. /**
  51. * Test Mode?
  52. *
  53. * @var boolean
  54. * @see do_exist
  55. */
  56. public $test_mode = FALSE;
  57. /**
  58. * Default Multipage Marker
  59. *
  60. * @var string
  61. * @see form
  62. * @see set_form_params
  63. */
  64. public $default_mp_page_marker = 'page';
  65. /**
  66. * Multipage Page Array
  67. *
  68. * @var array
  69. * @see get_mp_page_array
  70. */
  71. public $mp_page_array;
  72. /**
  73. * Prevents rerunning of set_form_params
  74. * @var boolean
  75. * @see set_form_params
  76. */
  77. public $params_ran = FALSE;
  78. /**
  79. * Form Data
  80. * @var array
  81. */
  82. public $form_data;
  83. /**
  84. * Params With Defaults
  85. * @var array
  86. * @see get_default_params
  87. */
  88. public $params_with_defaults;
  89. // --------------------------------------------------------------------
  90. /**
  91. * Constructor
  92. *
  93. * @access public
  94. * @return null
  95. */
  96. public function __construct ()
  97. {
  98. parent::__construct();
  99. // -------------------------------------
  100. // Module Installed and Up to Date?
  101. // -------------------------------------
  102. ee()->load->helper(array('text', 'form', 'url', 'string'));
  103. //avoids AR collisions
  104. $this->data->get_module_preferences();
  105. $this->data->get_global_module_preferences();
  106. $this->data->show_all_sites();
  107. }
  108. // END __construct()
  109. // --------------------------------------------------------------------
  110. /**
  111. * Form Info
  112. *
  113. * @access public
  114. * @return string parsed tagdata
  115. */
  116. public function form_info()
  117. {
  118. $form_ids = $this->form_id(TRUE, FALSE);
  119. ee()->load->model('freeform_form_model');
  120. if ($form_ids)
  121. {
  122. ee()->freeform_form_model->where_in('form_id', $form_ids);
  123. }
  124. // -------------------------------------
  125. // site ids
  126. // -------------------------------------
  127. //if its star, allow all
  128. if (ee()->TMPL->fetch_param('site_id') !== '*')
  129. {
  130. $site_id = $this->parse_numeric_array_param('site_id');
  131. //if this isn't false, its single or an array
  132. if ($site_id !== FALSE)
  133. {
  134. //no ids? exit
  135. if (empty($site_id['ids']))
  136. {
  137. ee()->freeform_form_model->reset();
  138. return $this->no_results_error();
  139. }
  140. //e.g. site_id="not 1"
  141. else if ($site_id['not'])
  142. {
  143. ee()->freeform_form_model->where_not_in(
  144. 'site_id',
  145. $site_id['ids']
  146. );
  147. }
  148. else
  149. {
  150. ee()->freeform_form_model->where_in(
  151. 'site_id',
  152. $site_id['ids']
  153. );
  154. }
  155. }
  156. //default
  157. else
  158. {
  159. ee()->freeform_form_model->where(
  160. 'site_id',
  161. ee()->config->item('site_id')
  162. );
  163. }
  164. }
  165. // -------------------------------------
  166. // form data
  167. // -------------------------------------
  168. $form_data = ee()->freeform_form_model
  169. ->select(
  170. 'form_id, site_id, ' .
  171. 'form_name, form_label, ' .
  172. 'form_description, author_id, ' .
  173. 'entry_date, edit_date'
  174. )
  175. ->order_by('form_id', 'asc')
  176. ->get();
  177. if ( ! $form_data)
  178. {
  179. return $this->no_results_error(($form_ids) ?
  180. 'invalid_form_id' :
  181. NULL
  182. );
  183. }
  184. // -------------------------------------
  185. // author data
  186. // -------------------------------------
  187. $author_ids = array();
  188. $author_data = array();
  189. foreach ($form_data as $row)
  190. {
  191. $author_ids[] = $row['author_id'];
  192. }
  193. $a_query = ee()->db->select('member_id, username, screen_name')
  194. ->from('members')
  195. ->where_in('member_id', array_unique($author_ids))
  196. ->get();
  197. if ($a_query->num_rows() > 0)
  198. {
  199. $author_data = $this->prepare_keyed_result(
  200. $a_query,
  201. 'member_id'
  202. );
  203. }
  204. // -------------------------------------
  205. // output
  206. // -------------------------------------
  207. $variables = array();
  208. ee()->load->model('freeform_entry_model');
  209. foreach ($form_data as $row)
  210. {
  211. $new_row = array();
  212. //prefix everything
  213. foreach ($row as $key => $value)
  214. {
  215. $new_row['freeform:' . $key] = $value;
  216. }
  217. //we are only counting completed entries
  218. $new_row['freeform:total_entries'] = ee()->freeform_entry_model
  219. ->id($row['form_id'])
  220. ->where('complete', 'y')
  221. ->count();
  222. $new_row['freeform:author'] = (
  223. isset($author_data[$row['author_id']]) ?
  224. (
  225. isset($author_data[$row['author_id']]['screen_name']) ?
  226. $author_data[$row['author_id']]['screen_name'] :
  227. $author_data[$row['author_id']]['username']
  228. ) :
  229. lang('n_a')
  230. );
  231. $variables[] = $new_row;
  232. }
  233. $prefixed_tags = array(
  234. 'count',
  235. 'switch',
  236. 'total_results'
  237. );
  238. $tagdata = ee()->TMPL->tagdata;
  239. $tagdata = $this->tag_prefix_replace(
  240. 'freeform:',
  241. $prefixed_tags,
  242. $tagdata
  243. );
  244. //this should handle backspacing as well
  245. $tagdata = ee()->TMPL->parse_variables($tagdata, $variables);
  246. $tagdata = $this->tag_prefix_replace(
  247. 'freeform:',
  248. $prefixed_tags,
  249. $tagdata,
  250. TRUE
  251. );
  252. return $tagdata;
  253. }
  254. //END form_info
  255. // --------------------------------------------------------------------
  256. /**
  257. * Freeform:Entries
  258. * {exp:freeform:entries}
  259. *
  260. * @access public
  261. * @return string tagdata
  262. */
  263. public function entries()
  264. {
  265. // -------------------------------------
  266. // form id
  267. // -------------------------------------
  268. $form_ids = $this->form_id(TRUE, FALSE);
  269. if ( ! $form_ids)
  270. {
  271. return $this->no_results_error('invalid_form_id');
  272. }
  273. if ( ! is_array($form_ids))
  274. {
  275. $form_ids = array($form_ids);
  276. }
  277. // -------------------------------------
  278. // libs, models, helper
  279. // -------------------------------------
  280. ee()->load->model('freeform_form_model');
  281. ee()->load->model('freeform_entry_model');
  282. ee()->load->model('freeform_field_model');
  283. ee()->load->model('freeform_file_upload_model');
  284. ee()->load->library('freeform_forms');
  285. ee()->load->library('freeform_fields');
  286. // -------------------------------------
  287. // start cache for count and result
  288. // -------------------------------------
  289. $forms_data = ee()->freeform_form_model
  290. ->key('form_id')
  291. ->get(array('form_id' => $form_ids));
  292. $statuses = array_keys($this->data->get_form_statuses());
  293. // -------------------------------------
  294. // field order ids
  295. // -------------------------------------
  296. $all_field_ids = array();
  297. $all_order_ids = array();
  298. foreach ($forms_data as $form_data)
  299. {
  300. //this should always be true, but NEVER TRUST AN ELF
  301. if (isset($form_data['field_ids']) AND
  302. is_array($form_data['field_ids']))
  303. {
  304. $all_field_ids = array_merge(
  305. $all_field_ids,
  306. $form_data['field_ids']
  307. );
  308. $all_order_ids = array_merge(
  309. $all_order_ids,
  310. $this->actions()->pipe_split($form_data['field_order'])
  311. );
  312. }
  313. }
  314. $all_field_ids = array_unique($all_field_ids);
  315. $all_order_ids = array_unique($all_order_ids);
  316. sort($all_field_ids);
  317. // -------------------------------------
  318. // get field data
  319. // -------------------------------------
  320. $all_field_data = FALSE;
  321. if ( ! empty($all_field_ids))
  322. {
  323. $all_field_data = ee()->freeform_field_model
  324. ->key('field_id')
  325. ->where_in('field_id', $all_field_ids)
  326. ->get();
  327. }
  328. $field_data = array();
  329. if ($all_field_data)
  330. {
  331. foreach ($all_field_data as $row)
  332. {
  333. $field_data[$row['field_id']] = $row;
  334. }
  335. }
  336. // -------------------------------------
  337. // set tables
  338. // -------------------------------------
  339. ee()->freeform_entry_model->id($form_ids);
  340. // -------------------------------------
  341. // replace CURRENT_USER before we get
  342. // started because the minute we don't
  343. // someone is going to figure out
  344. // a way to need it in site_id=""
  345. // -------------------------------------
  346. $this->replace_current_user();
  347. // -------------------------------------
  348. // site ids
  349. // -------------------------------------
  350. //if its star, allow all
  351. if (ee()->TMPL->fetch_param('site_id') !== '*')
  352. {
  353. $site_id = $this->parse_numeric_array_param('site_id');
  354. //if this isn't false, its single or an array
  355. if ($site_id !== FALSE)
  356. {
  357. if (empty($site_id['ids']))
  358. {
  359. ee()->freeform_entry_model->reset();
  360. return $this->no_results_error();
  361. }
  362. else if ($site_id['not'])
  363. {
  364. ee()->freeform_entry_model->where_not_in(
  365. 'site_id',
  366. $site_id['ids']
  367. );
  368. }
  369. else
  370. {
  371. ee()->freeform_entry_model->where_in(
  372. 'site_id',
  373. $site_id['ids']
  374. );
  375. }
  376. }
  377. //default
  378. else
  379. {
  380. ee()->freeform_entry_model->where(
  381. 'site_id',
  382. ee()->config->item('site_id')
  383. );
  384. }
  385. }
  386. // -------------------------------------
  387. // entry ids
  388. // -------------------------------------
  389. $entry_id = $this->parse_numeric_array_param('entry_id');
  390. if ($entry_id !== FALSE)
  391. {
  392. if (empty($entry_id['ids']))
  393. {
  394. ee()->freeform_entry_model->reset();
  395. return $this->no_results_error();
  396. }
  397. else if ($entry_id['not'])
  398. {
  399. ee()->freeform_entry_model->where_not_in(
  400. 'entry_id',
  401. $entry_id['ids']
  402. );
  403. }
  404. else
  405. {
  406. ee()->freeform_entry_model->where_in(
  407. 'entry_id',
  408. $entry_id['ids']
  409. );
  410. }
  411. }
  412. // -------------------------------------
  413. // author ids
  414. // -------------------------------------
  415. $author_id = $this->parse_numeric_array_param('author_id');
  416. if ($author_id !== FALSE)
  417. {
  418. if (empty($author_id['ids']))
  419. {
  420. ee()->freeform_entry_model->reset();
  421. return $this->no_results_error();
  422. }
  423. else if ($author_id['not'])
  424. {
  425. ee()->freeform_entry_model->where_not_in(
  426. 'author_id',
  427. $author_id['ids']
  428. );
  429. }
  430. else
  431. {
  432. ee()->freeform_entry_model->where_in(
  433. 'author_id',
  434. $author_id['ids']
  435. );
  436. }
  437. }
  438. // -------------------------------------
  439. // {freeform:all_form_fields}
  440. // -------------------------------------
  441. $tagdata = $this->replace_all_form_fields(
  442. ee()->TMPL->tagdata,
  443. $field_data,
  444. $all_order_ids
  445. );
  446. // -------------------------------------
  447. // get standard columns and labels
  448. // -------------------------------------
  449. $standard_columns = array_keys(
  450. ee()->freeform_form_model->default_form_table_columns
  451. );
  452. $standard_columns[] = 'author';
  453. $column_labels = array();
  454. //keyed labels for the front end
  455. foreach ($standard_columns as $column_name)
  456. {
  457. $column_labels[$column_name] = lang($column_name);
  458. }
  459. // -------------------------------------
  460. // available fields
  461. // -------------------------------------
  462. //this makes the keys and values the same
  463. $available_fields = array_combine(
  464. $standard_columns,
  465. $standard_columns
  466. );
  467. $custom_fields = array();
  468. $field_descriptions = array();
  469. foreach ($field_data as $field_id => $f_data)
  470. {
  471. $fid = ee()->freeform_form_model->form_field_prefix . $field_id;
  472. //field_name => field_id_1, etc
  473. $available_fields[$f_data['field_name']] = $fid;
  474. //field_id_1 => field_id_1, etc
  475. $available_fields[$fid] = $fid;
  476. $custom_fields[] = $f_data['field_name'];
  477. //labels
  478. $column_labels[$f_data['field_name']] = $f_data['field_label'];
  479. $column_labels[$fid] = $f_data['field_label'];
  480. $field_descriptions[
  481. 'freeform:description:' . $f_data['field_name']
  482. ] = $f_data['field_description'];
  483. }
  484. // -------------------------------------
  485. // search:field_name="kittens"
  486. // -------------------------------------
  487. foreach (ee()->TMPL->tagparams as $key => $value)
  488. {
  489. if (substr($key, 0, 7) == 'search:')
  490. {
  491. $search_key = substr($key, 7);
  492. if (isset($available_fields[$search_key]))
  493. {
  494. ee()->freeform_entry_model->add_search(
  495. $available_fields[$search_key],
  496. $value
  497. );
  498. }
  499. }
  500. }
  501. // -------------------------------------
  502. // date range
  503. // -------------------------------------
  504. $date_range = ee()->TMPL->fetch_param('date_range');
  505. $date_range_start = ee()->TMPL->fetch_param('date_range_start');
  506. $date_range_end = ee()->TMPL->fetch_param('date_range_end');
  507. ee()->freeform_entry_model->date_where(
  508. $date_range,
  509. $date_range_start,
  510. $date_range_end
  511. );
  512. // -------------------------------------
  513. // complete
  514. // -------------------------------------
  515. $show_incomplete = ee()->TMPL->fetch_param('show_incomplete');
  516. if ($show_incomplete === 'only')
  517. {
  518. ee()->freeform_entry_model->where('complete', 'n');
  519. }
  520. //default unless show_incomplete="y"
  521. else if ( ! $this->check_yes($show_incomplete))
  522. {
  523. ee()->freeform_entry_model->where('complete', 'y');
  524. }
  525. // -------------------------------------
  526. // status
  527. // -------------------------------------
  528. $status = ee()->TMPL->fetch_param('status', 'open');
  529. if ($status !== 'all')
  530. {
  531. //make it an array either way
  532. $status = array_map('trim', $this->actions()->pipe_split($status));
  533. $approved = array_map('strtolower', $statuses);
  534. $search_status = array();
  535. //only keep legit ones
  536. foreach($status as $potential_status)
  537. {
  538. if (in_array(strtolower($potential_status), $approved))
  539. {
  540. $search_status[] = $potential_status;
  541. }
  542. }
  543. if ( ! empty($search_status))
  544. {
  545. ee()->freeform_entry_model->where_in(
  546. 'status',
  547. $search_status
  548. );
  549. }
  550. }
  551. // -------------------------------------
  552. // orderby/sort
  553. // -------------------------------------
  554. $sort = ee()->TMPL->fetch_param('sort');
  555. $orderby = ee()->TMPL->fetch_param('orderby');
  556. if ($orderby !== FALSE AND trim($orderby) !== '')
  557. {
  558. $orderby = $this->actions()->pipe_split(strtolower(trim($orderby)));
  559. array_walk($orderby, 'trim');
  560. // -------------------------------------
  561. // sort
  562. // -------------------------------------
  563. if ($sort !== FALSE AND trim($sort) !== '')
  564. {
  565. $sort = $this->actions()->pipe_split(strtolower(trim($sort)));
  566. array_walk($sort, 'trim');
  567. //correct sorts
  568. foreach ($sort as $key => $value)
  569. {
  570. if ( ! in_array($value, array('asc', 'desc')))
  571. {
  572. $sort[$key] = 'asc';
  573. }
  574. }
  575. }
  576. else
  577. {
  578. $sort = array('asc');
  579. }
  580. // -------------------------------------
  581. // add sorts and orderbys
  582. // -------------------------------------
  583. foreach ($orderby as $key => $value)
  584. {
  585. if ($value == 'random')
  586. {
  587. ee()->freeform_entry_model->order_by('', 'random');
  588. continue;
  589. }
  590. if (isset($available_fields[$value]))
  591. {
  592. //if the sort is not set, just use the first
  593. //really this should teach people to be more specific :p
  594. $temp_sort = isset($sort[$key]) ? $sort[$key] : $sort[0];
  595. ee()->freeform_entry_model->order_by(
  596. $available_fields[$value],
  597. $temp_sort
  598. );
  599. }
  600. }
  601. }
  602. //--------------------------------------
  603. // pagination start vars
  604. //--------------------------------------
  605. $limit = ee()->TMPL->fetch_param('limit', 50);
  606. $offset = ee()->TMPL->fetch_param('offset', 0);
  607. $row_count = 0;
  608. $total_entries = ee()->freeform_entry_model->count(array(), FALSE);
  609. $current_page = 0;
  610. if ($total_entries == 0)
  611. {
  612. ee()->freeform_entry_model->reset();
  613. return $this->no_results_error();
  614. }
  615. // -------------------------------------
  616. // pagination?
  617. // -------------------------------------
  618. $prefix = stristr($tagdata, LD . 'freeform:paginate' . RD);
  619. if ($limit > 0 AND ($total_entries - $offset) > $limit)
  620. {
  621. //get pagination info
  622. $pagination_data = $this->universal_pagination(array(
  623. 'total_results' => $total_entries,
  624. 'tagdata' => $tagdata,
  625. 'limit' => $limit,
  626. 'offset' => $offset,
  627. 'uri_string' => ee()->uri->uri_string,
  628. 'prefix' => 'freeform:',
  629. 'auto_paginate' => TRUE
  630. ));
  631. //if we paginated, sort the data
  632. if ($pagination_data['paginate'] === TRUE)
  633. {
  634. $tagdata = $pagination_data['tagdata'];
  635. $current_page = $pagination_data['pagination_page'];
  636. }
  637. }
  638. else
  639. {
  640. $this->paginate = FALSE;
  641. }
  642. ee()->freeform_entry_model->limit($limit, $current_page + $offset);
  643. // -------------------------------------
  644. // get data
  645. // -------------------------------------
  646. $result_array = ee()->freeform_entry_model->get();
  647. if (empty($result_array))
  648. {
  649. ee()->freeform_entry_model->reset();
  650. return $this->no_results_error();
  651. }
  652. $output_labels = array();
  653. //column labels for output
  654. foreach ($column_labels as $key => $value)
  655. {
  656. $output_labels['freeform:label:' . $key] = $value;
  657. }
  658. $count = $row_count;
  659. $variable_rows = array();
  660. $replace_tagdata = '';
  661. // -------------------------------------
  662. // allow pre_process
  663. // -------------------------------------
  664. $entry_ids = array();
  665. foreach ($result_array as $row)
  666. {
  667. if ( ! isset($entry_ids[$row['form_id']]))
  668. {
  669. $entry_ids[$row['form_id']] = array();
  670. }
  671. $entry_ids[$row['form_id']][] = $row['entry_id'];
  672. }
  673. // -------------------------------------
  674. // preprocess items
  675. // -------------------------------------
  676. // These are separated by form id so this
  677. // is not iterating over each entry id
  678. // but rather grouped by form.
  679. // -------------------------------------
  680. foreach ($entry_ids as $f_form_id => $f_entry_ids)
  681. {
  682. ee()->freeform_fields->apply_field_method(array(
  683. 'method' => 'pre_process_entries',
  684. 'form_id' => $f_form_id,
  685. 'form_data' => $forms_data,
  686. 'entry_id' => $f_entry_ids,
  687. 'field_data' => $field_data
  688. ));
  689. }
  690. // -------------------------------------
  691. // output
  692. // -------------------------------------
  693. $to_prefix = array(
  694. 'absolute_count',
  695. 'absolute_results',
  696. 'attachment_count',
  697. 'author_id',
  698. 'author',
  699. 'complete',
  700. 'edit_date',
  701. 'entry_date',
  702. 'entry_id',
  703. 'form_id',
  704. 'form_name',
  705. 'ip_address',
  706. 'reverse_count'
  707. );
  708. $absolute_count = $current_page + $offset;
  709. $total_results = count($result_array);
  710. $count = 0;
  711. // -------------------------------------
  712. // get file attachment count for entries
  713. // -------------------------------------
  714. $att_results = ee()->freeform_file_upload_model
  715. ->select('form_id, entry_id, COUNT(*) as file_count')
  716. ->where_in('form_id', $form_ids)
  717. ->group_by('form_id, entry_id')
  718. ->get();
  719. $attached_counts = array();
  720. if ( ! empty($att_results))
  721. {
  722. foreach ($att_results as $att_row)
  723. {
  724. if ( ! isset($attached_counts[$att_row['form_id']]))
  725. {
  726. $attached_counts[$att_row['form_id']] = array();
  727. }
  728. $attached_counts[$att_row['form_id']][$att_row['entry_id']] = $att_row['file_count'];
  729. }
  730. }
  731. // -------------------------------------
  732. // build results
  733. // -------------------------------------
  734. foreach ($result_array as $row)
  735. {
  736. //apply replace tag to our field data
  737. $field_parse = ee()->freeform_fields->apply_field_method(array(
  738. 'method' => 'replace_tag',
  739. 'form_id' => $row['form_id'],
  740. 'entry_id' => $row['entry_id'],
  741. 'form_data' => $forms_data,
  742. 'field_data' => $field_data,
  743. 'field_input_data' => $row,
  744. 'tagdata' => $tagdata
  745. ));
  746. $row = array_merge(
  747. $output_labels,
  748. $field_descriptions,
  749. $row,
  750. $field_parse['variables']
  751. );
  752. $row['attachment_count'] = isset($attached_counts[$row['form_id']][$row['entry_id']]) ?
  753. $attached_counts[$row['form_id']][$row['entry_id']] :
  754. 0;
  755. if ($replace_tagdata == '')
  756. {
  757. $replace_tagdata = $field_parse['tagdata'];
  758. }
  759. $row['freeform:form_name'] = $forms_data[$row['form_id']]['form_name'];
  760. $row['freeform:form_label'] = $forms_data[$row['form_id']]['form_label'];
  761. //prefix
  762. foreach ($row as $key => $value)
  763. {
  764. if ( ! preg_match('/^freeform:/', $key))
  765. {
  766. if (in_array($key, $custom_fields) AND
  767. ! isset($row['freeform:field:' . $key]))
  768. {
  769. $row['freeform:field:' . $key] = $value;
  770. }
  771. else if ( ! isset($row['freeform:' . $key]))
  772. {
  773. $row['freeform:' . $key] = $value;
  774. }
  775. unset($row[$key]);
  776. }
  777. }
  778. // -------------------------------------
  779. // other counts
  780. // -------------------------------------
  781. $row['freeform:reverse_count'] = $total_results - $count++;
  782. $row['freeform:absolute_count'] = ++$absolute_count;
  783. $row['freeform:absolute_results'] = $total_entries;
  784. $variable_rows[] = $row;
  785. }
  786. $tagdata = $replace_tagdata;
  787. $prefixed_tags = array(
  788. 'count',
  789. 'switch',
  790. 'total_results'
  791. );
  792. $tagdata = $this->tag_prefix_replace('freeform:', $prefixed_tags, $tagdata);
  793. //this should handle backspacing as well
  794. $tagdata = ee()->TMPL->parse_variables($tagdata, $variable_rows);
  795. $tagdata = $this->tag_prefix_replace('freeform:', $prefixed_tags, $tagdata, TRUE);
  796. // -------------------------------------
  797. // add pagination
  798. // -------------------------------------
  799. //prefix or no prefix?
  800. if ($prefix)
  801. {
  802. $tagdata = $this->parse_pagination(array(
  803. 'prefix' => 'freeform:',
  804. 'tagdata' => $tagdata
  805. ));
  806. }
  807. else
  808. {
  809. $tagdata = $this->parse_pagination(array(
  810. 'tagdata' => $tagdata
  811. ));
  812. }
  813. return $tagdata;
  814. }
  815. //END entries
  816. // --------------------------------------------------------------------
  817. /**
  818. * Freeform:Form
  819. * {exp:freeform:form}
  820. *
  821. * @access public
  822. * @param bool $edit edit mode? external for security
  823. * @param bool $preview preview mode?
  824. * @param mixed $preview_fields extra preview fields?
  825. * @return string tagdata
  826. */
  827. public function form($edit = FALSE, $preview = FALSE, $preview_fields = FALSE)
  828. {
  829. if ($this->check_yes(ee()->TMPL->fetch_param('require_logged_in')) AND
  830. ee()->session->userdata['member_id'] == '0')
  831. {
  832. return $this->no_results_error('not_logged_in');
  833. }
  834. // -------------------------------------
  835. // form id
  836. // -------------------------------------
  837. $form_id = $this->form_id(FALSE, FALSE);
  838. if ( ! $form_id)
  839. {
  840. return $this->no_results_error('invalid_form_id');
  841. }
  842. // -------------------------------------
  843. // libs, helpers, etc
  844. // -------------------------------------
  845. ee()->load->model('freeform_form_model');
  846. ee()->load->model('freeform_field_model');
  847. ee()->load->library('freeform_forms');
  848. ee()->load->library('freeform_fields');
  849. ee()->load->helper('form');
  850. // -------------------------------------
  851. // build query
  852. // -------------------------------------
  853. $this->form_data = $form_data = $this->data->get_form_info($form_id);
  854. // -------------------------------------
  855. // preview fields? (composer preview)
  856. // -------------------------------------
  857. if ( ! empty($preview_fields))
  858. {
  859. ee()->load->model('freeform_field_model');
  860. $valid_preview_fields = ee()->freeform_field_model
  861. ->where_in('field_id', $preview_fields)
  862. ->key('field_id')
  863. ->get();
  864. if ($valid_preview_fields)
  865. {
  866. foreach ($valid_preview_fields as $p_field_id => $p_field_data)
  867. {
  868. $p_field_data['preview'] = TRUE;
  869. $form_data['fields'][$p_field_id] = $p_field_data;
  870. }
  871. }
  872. }
  873. // -------------------------------------
  874. // form data
  875. // -------------------------------------
  876. $this->params['form_id'] = $form_id;
  877. // -------------------------------------
  878. // edit?
  879. // -------------------------------------
  880. $entry_id = 0;
  881. $edit_data = array();
  882. $this->params['edit'] = $edit;
  883. $this->params['entry_id'] = $entry_id;
  884. // -------------------------------------
  885. // replace CURRENT_USER everywhere
  886. // -------------------------------------
  887. $this->replace_current_user();
  888. // -------------------------------------
  889. // default params
  890. // -------------------------------------
  891. $this->default_mp_page_marker = 'page';
  892. $this->set_form_params(TRUE);
  893. // ----------------------------------------
  894. // Check for duplicate
  895. // ----------------------------------------
  896. $duplicate = FALSE;
  897. //we can only prevent dupes on entry like this
  898. if ( ! $edit AND $this->params['prevent_duplicate_on'])
  899. {
  900. if ( in_array(
  901. $this->params['prevent_duplicate_on'],
  902. array('member_id', 'ip_address'),
  903. TRUE
  904. ))
  905. {
  906. $duplicate = ee()->freeform_forms->check_duplicate(
  907. $form_id,
  908. $this->params['prevent_duplicate_on'],
  909. '',
  910. $this->params['prevent_duplicate_per_site']
  911. );
  912. }
  913. }
  914. // ----------------------------------------
  915. // duplicate?
  916. // ----------------------------------------
  917. if ($duplicate)
  918. {
  919. if ($this->params['duplicate_redirect'] !== '')
  920. {
  921. ee()->functions->redirect(
  922. $this->prep_url(
  923. $this->params['duplicate_redirect'],
  924. $this->params['secure_duplicate_redirect']
  925. )
  926. );
  927. return $this->do_exit();
  928. }
  929. else if ($this->params['error_on_duplicate'])
  930. {
  931. return $this->no_results_error('no_duplicates');
  932. }
  933. /*else if (preg_match(
  934. '/' . LD . 'if freeform_duplicate' . RD . '(*?)' '/',
  935. ee()->TMPL->tagdata, ))
  936. {
  937. }*/
  938. }
  939. // -------------------------------------
  940. // check user email field
  941. // if this is from form prefs, its an ID
  942. // -------------------------------------
  943. $valid_user_email_field = FALSE;
  944. foreach ($form_data['fields'] as $field_id => $field_data)
  945. {
  946. if ($this->params['user_email_field'] == $field_data['field_name'] OR
  947. $this->params['user_email_field'] == $field_id)
  948. {
  949. $valid_user_email_field = TRUE;
  950. //in case the setting is an id
  951. $this->params['user_email_field'] = $field_data['field_name'];
  952. break;
  953. }
  954. }
  955. // if it doesn't exist in the form, lets blank it
  956. $this->params['user_email_field'] = (
  957. $valid_user_email_field ?
  958. $this->params['user_email_field'] :
  959. ''
  960. );
  961. $this->edit = $edit;
  962. // ----------------------------------------
  963. // 'freeform_module_form_begin' hook.
  964. // - This allows developers to change data before form processing.
  965. // ----------------------------------------
  966. if (ee()->extensions->active_hook('freeform_module_form_begin') === TRUE)
  967. {
  968. ee()->extensions->universal_call(
  969. 'freeform_module_form_begin',
  970. $this
  971. );
  972. if (ee()->extensions->end_script === TRUE) return;
  973. }
  974. // ----------------------------------------
  975. // -------------------------------------
  976. // start form
  977. // -------------------------------------
  978. $tagdata = ee()->TMPL->tagdata;
  979. $return = '';
  980. $hidden_fields = array();
  981. $outer_template_vars = array();
  982. $variables = array();
  983. $page_total = 1;
  984. $current_page = 0;
  985. $last_page = TRUE;
  986. $multipage = $this->params['multipage'];
  987. // -------------------------------------
  988. // check if this is multi-page
  989. // -------------------------------------
  990. $current_page = 1;
  991. // -------------------------------------
  992. // set for hooks
  993. // -------------------------------------
  994. $this->multipage = $multipage;
  995. $this->last_page = $last_page;
  996. // -------------------------------------
  997. // check again for captcha now that
  998. // tagdata has been adjusted
  999. // -------------------------------------
  1000. if ($this->params['require_captcha'])
  1001. {
  1002. $this->params['require_captcha'] = (
  1003. $this->require_captcha() &&
  1004. stristr($tagdata, LD . 'freeform:captcha' . RD) != FALSE
  1005. );
  1006. }
  1007. // -------------------------------------
  1008. // submit
  1009. // -------------------------------------
  1010. //standard submits
  1011. $variables['freeform:submit'] = form_submit('submit', lang('submit'));
  1012. //replace submit buttons that have args
  1013. $tagdata = $this->replace_submit(array(
  1014. 'tag' => 'freeform:submit',
  1015. 'pre_args' => array(
  1016. 'name' => 'submit',
  1017. 'value' => lang('submit')
  1018. ),
  1019. 'tagdata' => $tagdata
  1020. ));
  1021. // -------------------------------------
  1022. // other random vars
  1023. // -------------------------------------
  1024. $variables['freeform:submit_previous'] = '';
  1025. $variables['freeform:duplicate'] = $duplicate;
  1026. $variables['freeform:not_duplicate'] = ! $duplicate;
  1027. $variables['freeform:form_label'] = $form_data['form_label'];
  1028. $variables['freeform:form_description'] = $form_data['form_description'];
  1029. $variables['freeform:last_page'] = $last_page;
  1030. $variables['freeform:current_page'] = $current_page;
  1031. // -------------------------------------
  1032. // display fields
  1033. // -------------------------------------
  1034. $field_error_data = array();
  1035. $general_error_data = array();
  1036. $field_input_data = array();
  1037. // -------------------------------------
  1038. // inline errors?
  1039. // -------------------------------------
  1040. if ($this->params['inline_errors'] AND
  1041. $this->is_positive_intlike(
  1042. ee()->session->flashdata('freeform_errors')
  1043. )
  1044. )
  1045. {
  1046. ee()->load->model('freeform_param_model');
  1047. $error_query = ee()->freeform_param_model->get_row(
  1048. ee()->session->flashdata('freeform_errors')
  1049. );
  1050. if ($error_query !== FALSE)
  1051. {
  1052. $potential_error_data = json_decode($error_query['data'], TRUE);
  1053. //specific field errors
  1054. if (isset($potential_error_data['field_errors']))
  1055. {
  1056. $field_error_data = $potential_error_data['field_errors'];
  1057. }
  1058. //errors that aren't field based
  1059. if (isset($potential_error_data['general_errors']))
  1060. {
  1061. $general_error_data = $potential_error_data['general_errors'];
  1062. }
  1063. //gets inputs for repopulation
  1064. if (isset($potential_error_data['inputs']))
  1065. {
  1066. $field_input_data = $potential_error_data['inputs'];
  1067. }
  1068. //restore recipient_emails
  1069. if (! empty($potential_error_data['stored_data']['recipient_emails']))
  1070. {
  1071. $previous_inputs['hash_stored_data']['recipient_emails'] =
  1072. $potential_error_data['stored_data']['recipient_emails'];
  1073. }
  1074. //restore user_recipient_emails
  1075. if (! empty($potential_error_data['stored_data']['user_recipient_emails']))
  1076. {
  1077. $previous_inputs['hash_stored_data']['user_recipient_emails'] =
  1078. $potential_error_data['stored_data']['user_recipient_emails'];
  1079. }
  1080. }
  1081. }
  1082. //END if ($this->params['inline_errors']
  1083. // -------------------------------------
  1084. // build field variables
  1085. // -------------------------------------
  1086. foreach ($form_data['fields'] as $field_id => $field_data)
  1087. {
  1088. // -------------------------------------
  1089. // label?
  1090. // -------------------------------------
  1091. $error = '';
  1092. if (isset($field_error_data[$field_data['field_name']]))
  1093. {
  1094. $error = is_array($field_error_data[$field_data['field_name']]) ?
  1095. implode(', ', $field_error_data[$field_data['field_name']]) :
  1096. $field_error_data[$field_data['field_name']];
  1097. }
  1098. // -------------------------------------
  1099. // variables for later parsing
  1100. // -------------------------------------
  1101. $variables['freeform:error:' . $field_data['field_name']] = $error;
  1102. $variables['freeform:label:' . $field_data['field_name']] = $field_data['field_label'];
  1103. $variables['freeform:description:' . $field_data['field_name']] = $field_data['field_description'];
  1104. // -------------------------------------
  1105. // values?
  1106. // -------------------------------------
  1107. $col_name = ee()->freeform_form_model->form_field_prefix . $field_id;
  1108. // -------------------------------------
  1109. // multipage previous inputs?
  1110. // -------------------------------------
  1111. $possible = (
  1112. isset($previous_inputs[$col_name]) ?
  1113. $previous_inputs[$col_name] :
  1114. (
  1115. isset($previous_inputs[$field_data['field_name']]) ?
  1116. $previous_inputs[$field_data['field_name']] :
  1117. ''
  1118. )
  1119. );
  1120. $possible = $this->prep_multi_item_data($possible, $field_data['field_type']);
  1121. $variables['freeform:mp_data:' . $field_data['field_name']] = $possible;
  1122. }
  1123. //END foreach ($form_data['fields'] as $field_id => $field_data)
  1124. // -------------------------------------
  1125. // This is done after edit data in
  1126. // cause they edited data, but had an error
  1127. // in their edits and we are now in
  1128. // inline error mode
  1129. // -------------------------------------
  1130. if ( ! empty($edit_data))
  1131. {
  1132. $field_input_data = array_merge($edit_data, $field_input_data);
  1133. }
  1134. else if ( ! empty($previous_inputs))
  1135. {
  1136. $field_input_data = array_merge($previous_inputs, $field_input_data);
  1137. }
  1138. // -------------------------------------
  1139. // recipient emails from multipage?
  1140. // -------------------------------------
  1141. $variables['freeform:mp_data:user_recipient_emails'] = '';
  1142. if (isset($previous_inputs['hash_stored_data']['user_recipient_emails']) AND
  1143. is_array($previous_inputs['hash_stored_data']['user_recipient_emails']))
  1144. {
  1145. $variables['freeform:mp_data:user_recipient_emails'] = implode(
  1146. ', ',
  1147. $previous_inputs['hash_stored_data']['user_recipient_emails']
  1148. );
  1149. }
  1150. // -------------------------------------
  1151. // freeform:all_form_fields
  1152. // -------------------------------------
  1153. $tagdata = $this->replace_all_form_fields(
  1154. $tagdata,
  1155. $form_data['fields'],
  1156. $form_data['field_order'],
  1157. $field_input_data
  1158. );
  1159. // -------------------------------------
  1160. // general errors
  1161. // -------------------------------------
  1162. if ( ! empty($general_error_data))
  1163. {
  1164. //the error array might have sub arrays
  1165. //so we need to flatten
  1166. $_general_error_data = array();
  1167. foreach ($general_error_data as $error_set => $error_data)
  1168. {
  1169. if (is_array($error_data))
  1170. {
  1171. foreach ($error_data as $sub_key => $sub_error)
  1172. {
  1173. $_general_error_data[] = array(
  1174. 'freeform:error_message' => $sub_error
  1175. );
  1176. }
  1177. }
  1178. else
  1179. {
  1180. $_general_error_data[] = array(
  1181. 'freeform:error_message' => $error_data
  1182. );
  1183. }
  1184. }
  1185. $general_error_data = $_general_error_data;
  1186. }
  1187. $variables['freeform:general_errors'] = $general_error_data;
  1188. $variables['freeform:field_errors'] = ! empty($field_error_data);
  1189. //have to do this so the conditional will work,
  1190. //seems that parse variables doesn't think a non-empty array = YES
  1191. $tagdata = ee()->functions->prep_conditionals(
  1192. $tagdata,
  1193. array(
  1194. 'freeform:general_errors' => ! empty($general_error_data),
  1195. 'freeform:field_errors' => ! empty($field_error_data)
  1196. )
  1197. );
  1198. // -------------------------------------
  1199. // apply replace tag to our field data
  1200. // -------------------------------------
  1201. $field_parse = ee()->freeform_fields->apply_field_method(array(
  1202. 'method' => 'display_field',
  1203. 'form_id' => $form_id,
  1204. 'entry_id' => $entry_id,
  1205. 'form_data' => $form_data,
  1206. 'field_input_data' => $field_input_data,
  1207. 'tagdata' => $tagdata
  1208. ));
  1209. $this->multipart = $field_parse['multipart'];
  1210. $variables = array_merge($variables, $field_parse['variables']);
  1211. $tagdata = $field_parse['tagdata'];
  1212. // -------------------------------------
  1213. // dynamic recipient list
  1214. // -------------------------------------
  1215. $this->params['recipients'] = (
  1216. ! in_array(ee()->TMPL->fetch_param('recipients'), array(FALSE, ''))
  1217. );
  1218. //preload list with usable info if so
  1219. $this->params['recipients_list'] = array();
  1220. if ( $this->params['recipients'] )
  1221. {
  1222. $i = 1;
  1223. $while_limit = 1000;
  1224. $counter = 0;
  1225. while ( ! in_array(ee()->TMPL->fetch_param('recipient' . $i), array(FALSE, '')) )
  1226. {
  1227. $recipient = explode('|', ee()->TMPL->fetch_param('recipient' . $i));
  1228. //has a name?
  1229. if ( count($recipient) > 1)
  1230. {
  1231. $recipient_name = trim($recipient[0]);
  1232. $recipient_email = trim($recipient[1]);
  1233. }
  1234. //no name, we assume its just an email
  1235. //(though, this makes little sense, it needs a name to be useful)
  1236. else
  1237. {
  1238. $recipient_name = '';
  1239. $recipient_email = trim($recipient[0]);
  1240. }
  1241. $recipient_selected = FALSE;
  1242. if (isset($previous_inputs['hash_stored_data']['recipient_emails']) AND
  1243. is_array($previous_inputs['hash_stored_data']['recipient_emails']))
  1244. {
  1245. $recipient_selected = in_array(
  1246. $recipient_email,
  1247. $previous_inputs['hash_stored_data']['recipient_emails']
  1248. );
  1249. }
  1250. //add to list
  1251. $this->params['recipients_list'][$i] = array(
  1252. 'name' => $recipient_name,
  1253. 'email' => $recipient_email,
  1254. //because this wasn't being unique enough
  1255. //on stupid windows servers *sigh*
  1256. 'key' => uniqid('', true),
  1257. 'selected' => $recipient_selected
  1258. );
  1259. $i++;
  1260. //In case fetch_param ever defaults to something
  1261. //thats not falsy.
  1262. if (++$counter >= $while_limit)
  1263. {
  1264. break;
  1265. }
  1266. }
  1267. //if we end up with nothing, then lets not attempt later
  1268. if (empty($this->params['recipients_list']))
  1269. {
  1270. $this->params['recipients'] = FALSE;
  1271. }
  1272. }
  1273. // ----------------------------------------
  1274. // parse {freeform:captcha}
  1275. // ----------------------------------------
  1276. $variables['freeform:captcha'] = FALSE;
  1277. if ($this->params['require_captcha'])
  1278. {
  1279. $variables['freeform:captcha'] = ee()->functions->create_captcha();
  1280. // -------------------------------------
  1281. // IF there is no captcha present
  1282. // in this tagdata, we don't want
  1283. // to require people to input it.
  1284. // Thats asking for errors.
  1285. // Usually this occurs when someone is
  1286. // trying to force captcha but the
  1287. // member is logged in and EE wont
  1288. // output captcha for members unless
  1289. // captcha_require_members is enabled.
  1290. // -------------------------------------
  1291. if (stristr($tagdata, LD . 'freeform:captcha' . RD) == FALSE OR
  1292. empty($variables['freeform:captcha']))
  1293. {
  1294. $this->params['require_captcha'] = FALSE;
  1295. }
  1296. }
  1297. // -------------------------------------
  1298. // dynamic recipient tagdata
  1299. // -------------------------------------
  1300. if ( $this->params['recipients'] AND
  1301. count($this->params['recipients_list']) > 0)
  1302. {
  1303. $variables['freeform_recipients'] = array();
  1304. $recipient_list = $this->params['recipients_list'];
  1305. //dynamic above starts with 1, so does this
  1306. for ( $i = 1, $l = count($recipient_list); $i <= $l; $i++ )
  1307. {
  1308. $variables['freeform:recipient_name' . $i] = $recipient_list[$i]['name'];
  1309. $variables['freeform:recipient_value' . $i] = $recipient_list[$i]['key'];
  1310. $variables['freeform:recipient_selected' . $i] = $recipient_list[$i]['selected'];
  1311. $variables['freeform:recipients'][] = array(
  1312. 'freeform:recipient_name' => $recipient_list[$i]['name'],
  1313. 'freeform:recipient_value' => $recipient_list[$i]['key'],
  1314. 'freeform:recipient_count' => $i,
  1315. //selected from hash data from multipages
  1316. 'freeform:recipient_selected' => $recipient_list[$i]['selected']
  1317. );
  1318. }
  1319. }
  1320. // -------------------------------------
  1321. // status pairs
  1322. // -------------------------------------
  1323. $tagdata = $this->parse_status_tags($tagdata);
  1324. // ----------------------------------------
  1325. // 'freeform_module_pre_form_parse' hook.
  1326. // - This allows developers to change data before tagdata processing.
  1327. // ----------------------------------------
  1328. $this->variables = $variables;
  1329. if (ee()->extensions->active_hook('freeform_module_pre_form_parse') === TRUE)
  1330. {
  1331. $backup_tagdata = $tagdata;
  1332. $tagdata = ee()->extensions->universal_call(
  1333. 'freeform_module_pre_form_parse',
  1334. $tagdata,
  1335. $this
  1336. );
  1337. if (ee()->extensions->end_script === TRUE) return;
  1338. //valid data?
  1339. if ( (! is_string($tagdata) OR empty($tagdata)) AND
  1340. $this->check_yes($this->preference('hook_data_protection')))
  1341. {
  1342. $tagdata = $backup_tagdata;
  1343. }
  1344. }
  1345. // ----------------------------------------
  1346. //extra precaution in case someone hoses this
  1347. if (isset($this->variables) AND is_array($this->variables))
  1348. {
  1349. $variables = $this->variables;
  1350. }
  1351. // -------------------------------------
  1352. // parse external vars
  1353. // -------------------------------------
  1354. $outer_template_vars['freeform:form_id'] = $form_id;
  1355. $outer_template_vars['freeform:form_page'] = $current_page;
  1356. $outer_template_vars['freeform:form_page_total'] = $page_total;
  1357. $outer_template_vars['freeform:form_name'] = $form_data['form_name'];
  1358. $outer_template_vars['freeform:form_label'] = $form_data['form_label'];
  1359. ee()->TMPL->template = ee()->functions->prep_conditionals(
  1360. ee()->TMPL->template,
  1361. $outer_template_vars
  1362. );
  1363. ee()->TMPL->template = ee()->functions->var_swap(
  1364. ee()->TMPL->template,
  1365. $outer_template_vars
  1366. );
  1367. // -------------------------------------
  1368. // parse all vars
  1369. // -------------------------------------
  1370. $tagdata = ee()->TMPL->parse_variables(
  1371. $tagdata,
  1372. array(array_merge($outer_template_vars,$variables))
  1373. );
  1374. // -------------------------------------
  1375. // This doesn't force an ajax request
  1376. // but instead forces it _not_ to be
  1377. // if the ajax param = 'no'.
  1378. // $this->params['ajax'] defaults to
  1379. // boolean true, so this will only
  1380. // happen if someone adds ajax="no".
  1381. // -------------------------------------
  1382. if ( ! $this->params['ajax'])
  1383. {
  1384. $hidden_fields['ajax_request'] = 'no';
  1385. }
  1386. //-------------------------------------
  1387. // build form
  1388. //-------------------------------------
  1389. $return .= $this->build_form(array(
  1390. 'action' => $this->get_action_url('save_form'),
  1391. 'method' => 'post',
  1392. 'hidden_fields' => array_merge($hidden_fields, array(
  1393. // no more params can be set after this
  1394. 'params_id' => $this->insert_params(),
  1395. )),
  1396. 'tagdata' => $tagdata
  1397. ));
  1398. // ----------------------------------------
  1399. // 'freeform_module_form_end' hook.
  1400. // - This allows developers to change the form before output.
  1401. // ----------------------------------------
  1402. if (ee()->extensions->active_hook('freeform_module_form_end') === TRUE)
  1403. {
  1404. $backup_return = $return;
  1405. $return = ee()->extensions->universal_call(
  1406. 'freeform_module_form_end',
  1407. $return,
  1408. $this
  1409. );
  1410. if (ee()->extensions->end_script === TRUE) return;
  1411. //valid data?
  1412. if ( (! is_string($return) OR empty($return)) AND
  1413. $this->check_yes($this->preference('hook_data_protection')))
  1414. {
  1415. $return = $backup_return;
  1416. }
  1417. }
  1418. // ----------------------------------------
  1419. return $return;
  1420. }
  1421. //END form
  1422. // -------------------------------------
  1423. // action requests
  1424. // -------------------------------------
  1425. // --------------------------------------------------------------------
  1426. /**
  1427. * ajax_validate
  1428. *
  1429. * does a save form that stops after validation
  1430. *
  1431. * @access public
  1432. * @return mixed ajax request
  1433. */
  1434. public function ajax_validate_form()
  1435. {
  1436. return $this->save_form(TRUE);
  1437. }
  1438. //END ajax_validate
  1439. // --------------------------------------------------------------------
  1440. /**
  1441. * save_form
  1442. *
  1443. * form save from front_end/action request
  1444. *
  1445. * @access public
  1446. * @param bool validate only
  1447. * @return null
  1448. */
  1449. public function save_form($validate_only = FALSE)
  1450. {
  1451. if ( ! $validate_only AND REQ !== 'ACTION' AND ! $this->test_mode)
  1452. {
  1453. return;
  1454. }
  1455. ee()->load->library('freeform_forms');
  1456. ee()->load->library('freeform_fields');
  1457. ee()->load->model('freeform_form_model');
  1458. if (ee()->input->get_post('params_id') === FALSE)
  1459. {
  1460. return $this->pre_validation_error(
  1461. lang('missing_post_data') . ' - params_id'
  1462. );
  1463. }
  1464. // -------------------------------------
  1465. // require logged in?
  1466. // -------------------------------------
  1467. if ($this->param('require_logged_in') AND
  1468. ee()->session->userdata['member_id'] == '0')
  1469. {
  1470. return $this->pre_validation_error(
  1471. lang('not_authorized') . ' - ' .
  1472. lang('not_logged_in')
  1473. );
  1474. }
  1475. // -------------------------------------
  1476. // blacklist, banned
  1477. // -------------------------------------
  1478. if (ee()->session->userdata['is_banned'] OR (
  1479. $this->check_yes(ee()->blacklist->blacklisted) AND
  1480. $this->check_no(ee()->blacklist->whitelisted)
  1481. )
  1482. )
  1483. {
  1484. return $this->pre_validation_error(
  1485. lang('not_authorized') . ' - ' .
  1486. lang('reason_banned')
  1487. );
  1488. }
  1489. // -------------------------------------
  1490. // require ip? (except admin)
  1491. // -------------------------------------
  1492. if ($this->param('require_ip'))
  1493. {
  1494. if (ee()->input->ip_address() == '0.0.0.0')
  1495. {
  1496. return $this->pre_validation_error(
  1497. lang('not_authorized') . ' - ' .
  1498. lang('reason_ip_required')
  1499. );
  1500. }
  1501. }
  1502. // -------------------------------------
  1503. // Is the nation of the user banned?
  1504. // -------------------------------------
  1505. if ($this->nation_ban_check(FALSE))
  1506. {
  1507. return $this->pre_validation_error(
  1508. lang('not_authorized') . ' - ' .
  1509. ee()->config->item('ban_message')
  1510. );
  1511. }
  1512. // -------------------------------------
  1513. // valid form id
  1514. // -------------------------------------
  1515. $form_id = $this->form_id(FALSE, FALSE);
  1516. if ( ! $form_id)
  1517. {
  1518. return $this->pre_validation_error(lang('invalid_form_id'));
  1519. }
  1520. // -------------------------------------
  1521. // is this an edit? entry_id
  1522. // -------------------------------------
  1523. $entry_id = $this->entry_id();
  1524. $edit = $this->is_positive_intlike($entry_id);
  1525. // -------------------------------------
  1526. // for multipage check later
  1527. // -------------------------------------
  1528. $multipage = $this->param('multipage');
  1529. $current_page = $this->param('current_page');
  1530. $last_page = $this->param('last_page');
  1531. $previous_inputs = array();
  1532. // -------------------------------------
  1533. // form data
  1534. // -------------------------------------
  1535. $this->form_data = $form_data = $this->data->get_form_info($form_id);
  1536. $field_labels = array();
  1537. $valid_fields = array();
  1538. $column_names = array();
  1539. foreach ( $form_data['fields'] as $row)
  1540. {
  1541. $field_labels[$row['field_name']] = $row['field_label'];
  1542. $valid_fields[] = $row['field_name'];
  1543. //fill previous inputs names correctly
  1544. $column_name = 'form_field_' . $row['field_id'];
  1545. if (isset($previous_inputs[$column_name]))
  1546. {
  1547. $previous_inputs[$row['field_name']] = $previous_inputs[$column_name];
  1548. }
  1549. $column_names[$row['field_name']] = $column_name;
  1550. }
  1551. // -------------------------------------
  1552. // for hooks
  1553. // -------------------------------------
  1554. $this->edit = $edit;
  1555. $this->multipage = $multipage;
  1556. $this->last_page = $last_page;
  1557. // -------------------------------------
  1558. // user email max/spam count
  1559. // -------------------------------------
  1560. ee()->load->library('freeform_notifications');
  1561. if ($last_page AND ($this->param('recipient_user_input') OR
  1562. $this->param('recipients')) AND
  1563. ee()->freeform_notifications->check_spam_interval($form_id)
  1564. )
  1565. {
  1566. return $this->pre_validation_error(
  1567. lang('not_authorized') . ' - ' .
  1568. lang('email_limit_exceeded')
  1569. );
  1570. }
  1571. // -------------------------------------
  1572. // Check for duplicate
  1573. // -------------------------------------
  1574. $duplicate = FALSE;
  1575. if ($this->param('prevent_duplicate_on'))
  1576. {
  1577. $duplicate = ee()->freeform_forms->check_duplicate(
  1578. $form_id,
  1579. $this->param('prevent_duplicate_on'),
  1580. ee()->input->get_post(
  1581. $this->param('prevent_duplicate_on'),
  1582. TRUE
  1583. ),
  1584. $this->param('prevent_duplicate_per_site')
  1585. );
  1586. }
  1587. if ($duplicate)
  1588. {
  1589. return $this->pre_validation_error(lang('no_duplicates'));
  1590. }
  1591. // -------------------------------------
  1592. // pre xid check
  1593. // -------------------------------------
  1594. // we aren't going to delete just yet
  1595. // because if they have input errors
  1596. // then we want to keep this xid for a bit
  1597. // and only delete xid on success
  1598. // -------------------------------------
  1599. // EE 2.7+ does this automatically for
  1600. // all POSTS front end and back now
  1601. // so this is going to cause errors
  1602. // if we check it there.
  1603. // -------------------------------------
  1604. if (version_compare($this->ee_version, '2.7.0', '<') &&
  1605. ! ee()->security->check_xid(ee()->input->post('XID')))
  1606. {
  1607. return $this->pre_validation_error(
  1608. lang('not_authorized') . ' - ' .
  1609. lang('reason_secure_form_timeout')
  1610. );
  1611. }
  1612. // -------------------------------------
  1613. // pre-validate hook
  1614. // -------------------------------------
  1615. $errors = array();
  1616. //have to do this weird for backward compat
  1617. $this->field_errors = array();
  1618. if (ee()->extensions->active_hook('freeform_module_validate_begin') === TRUE)
  1619. {
  1620. $backup_errors = $errors;
  1621. $errors = ee()->extensions->universal_call(
  1622. 'freeform_module_validate_begin',
  1623. $errors,
  1624. $this
  1625. );
  1626. if (ee()->extensions->end_script === TRUE) return;
  1627. //valid data?
  1628. if ( ! is_array($errors) AND
  1629. $this->check_yes($this->preference('hook_data_protection')))
  1630. {
  1631. $errors = $backup_errors;
  1632. }
  1633. }
  1634. // -------------------------------------
  1635. // require fields
  1636. // -------------------------------------
  1637. if ($this->param('required'))
  1638. {
  1639. $required = $this->actions()->pipe_split($this->param('required'));
  1640. foreach ($required as $required_field)
  1641. {
  1642. //require need to work for recipients and recipient email user
  1643. $valid_require = array_merge(
  1644. $valid_fields,
  1645. array('recipient_email_user', 'recipient_email')
  1646. );
  1647. $require_labels = $field_labels;
  1648. $require_labels['recipient_email_user'] = lang('user_recipients');
  1649. $require_labels['recipient_email'] = lang('dynamic_recipients');
  1650. //just in case someone misspelled a require
  1651. //or removes a field after making the require list
  1652. if ( ! in_array($required_field, $valid_require))
  1653. {
  1654. continue;
  1655. }
  1656. $gp_value = ee()->input->get_post($required_field);
  1657. if ( (
  1658. //empty array
  1659. (is_array($gp_value) AND count($gp_value) < 1) OR
  1660. //empty …

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