PageRenderTime 66ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/system/expressionengine/third_party/freeform/mod.freeform.php

https://bitbucket.org/studiobreakfast/sync
PHP | 3621 lines | 2148 code | 670 blank | 803 comment | 272 complexity | 5d3ca1dbaaa9b76e0758cdc55ddf847f MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * Solspace - Freeform
  4. *
  5. * @package Solspace:Freeform
  6. * @author Solspace DevTeam
  7. * @copyright Copyright (c) 2008-2012, Solspace, Inc.
  8. * @link http://solspace.com/docs/addon/c/Freeform/
  9. * @version 4.0.8
  10. * @filesource ./system/expressionengine/third_party/freeform/
  11. */
  12. /**
  13. * Freeform - User Side
  14. *
  15. * @package Solspace:Freeform
  16. * @author Solspace DevTeam
  17. * @filesource ./system/expressionengine/third_party/freeform/mod.freeform.php
  18. */
  19. // EE 2.0's Wizard might not set this constant
  20. if ( ! defined('APP_VER')) define('APP_VER', '2.0');
  21. if ( ! class_exists('Module_builder_freeform'))
  22. {
  23. require_once 'addon_builder/module_builder.php';
  24. }
  25. class Freeform extends Module_builder_freeform
  26. {
  27. public $return_data = '';
  28. public $disabled = FALSE;
  29. public $multipart = FALSE;
  30. public $params = array();
  31. public $params_id = 0;
  32. public $form_id = 0;
  33. // --------------------------------------------------------------------
  34. /**
  35. * Constructor
  36. *
  37. * @access public
  38. * @return null
  39. */
  40. public function __construct ()
  41. {
  42. parent::__construct('freeform');
  43. // -------------------------------------
  44. // Module Installed and Up to Date?
  45. // -------------------------------------
  46. if ($this->database_version() == FALSE OR
  47. $this->version_compare($this->database_version(), '<', FREEFORM_VERSION)
  48. OR ! $this->extensions_enabled())
  49. {
  50. $this->disabled = TRUE;
  51. trigger_error(lang('freeform_module_disabled'), E_USER_NOTICE);
  52. }
  53. ee()->load->helper(array('text', 'form', 'url', 'string'));
  54. //avoids AR collisions
  55. $this->data->get_module_preferences();
  56. $this->data->get_global_module_preferences();
  57. $this->data->show_all_sites();
  58. }
  59. // END __construct()
  60. // --------------------------------------------------------------------
  61. /**
  62. * Form Info
  63. *
  64. * @access public
  65. * @return string parsed tagdata
  66. */
  67. public function form_info ()
  68. {
  69. $form_ids = $this->form_id(TRUE);
  70. ee()->load->model('freeform_form_model');
  71. if ($form_ids)
  72. {
  73. ee()->freeform_form_model->where_in('form_id', $form_ids);
  74. }
  75. // -------------------------------------
  76. // site ids
  77. // -------------------------------------
  78. //if its star, allow all
  79. if (ee()->TMPL->fetch_param('site_id') !== '*')
  80. {
  81. $site_id = $this->parse_numeric_array_param('site_id');
  82. //if this isn't false, its single or an array
  83. if ($site_id !== FALSE)
  84. {
  85. if (empty($site_id['ids']))
  86. {
  87. ee()->freeform_form_model->reset();
  88. return $this->no_results_error();
  89. }
  90. else if ($site_id['not'])
  91. {
  92. ee()->freeform_form_model->where_not_in('site_id', $site_id['ids']);
  93. }
  94. else
  95. {
  96. ee()->freeform_form_model->where_in('site_id', $site_id['ids']);
  97. }
  98. }
  99. //default
  100. else
  101. {
  102. ee()->freeform_form_model->where('site_id', ee()->config->item('site_id'));
  103. }
  104. }
  105. // -------------------------------------
  106. // form data
  107. // -------------------------------------
  108. $form_data = ee()->freeform_form_model
  109. ->select(
  110. 'form_id, site_id, ' .
  111. 'form_name, form_label, ' .
  112. 'form_description, author_id, ' .
  113. 'entry_date, edit_date'
  114. )
  115. ->order_by('form_id', 'asc')
  116. ->get();
  117. if ( ! $form_data)
  118. {
  119. return $this->no_results_error(($form_ids) ? 'invalid_form_id' : NULL);
  120. }
  121. // -------------------------------------
  122. // author data
  123. // -------------------------------------
  124. $author_ids = array();
  125. $author_data = array();
  126. foreach ($form_data as $row)
  127. {
  128. $author_ids[] = $row['author_id'];
  129. }
  130. $a_query = ee()->db->select('member_id, username, screen_name')
  131. ->from('members')
  132. ->where_in('member_id', array_unique($author_ids))
  133. ->get();
  134. if ($a_query->num_rows() > 0)
  135. {
  136. $author_data = $this->prepare_keyed_result(
  137. $a_query,
  138. 'member_id'
  139. );
  140. }
  141. // -------------------------------------
  142. // output
  143. // -------------------------------------
  144. $variables = array();
  145. ee()->load->model('freeform_entry_model');
  146. foreach ($form_data as $row)
  147. {
  148. $new_row = array();
  149. foreach ($row as $key => $value)
  150. {
  151. $new_row['freeform:' . $key] = $value;
  152. }
  153. $new_row['freeform:total_entries'] = ee()->freeform_entry_model
  154. ->id($row['form_id'])
  155. ->where('complete', 'y')
  156. ->count();
  157. $new_row['freeform:author'] = (
  158. isset($author_data[$row['author_id']]) ?
  159. (
  160. isset($author_data[$row['author_id']]['screen_name']) ?
  161. $author_data[$row['author_id']]['screen_name'] :
  162. $author_data[$row['author_id']]['username']
  163. ) :
  164. lang('n_a')
  165. );
  166. $variables[] = $new_row;
  167. }
  168. $prefixed_tags = array(
  169. 'count',
  170. 'switch',
  171. 'total_results'
  172. );
  173. $tagdata = ee()->TMPL->tagdata;
  174. $tagdata = $this->tag_prefix_replace('freeform:', $prefixed_tags, $tagdata);
  175. //this should handle backspacing as well
  176. $tagdata = ee()->TMPL->parse_variables($tagdata, $variables);
  177. $tagdata = $this->tag_prefix_replace('freeform:', $prefixed_tags, $tagdata, TRUE);
  178. return $tagdata;
  179. }
  180. //END form_info
  181. // --------------------------------------------------------------------
  182. /**
  183. * Freeform:Entries
  184. * {exp:freeform:entries}
  185. *
  186. * @access public
  187. * @return string tagdata
  188. */
  189. public function entries ()
  190. {
  191. // -------------------------------------
  192. // form id
  193. // -------------------------------------
  194. $form_ids = $this->form_id(TRUE);
  195. if ( ! $form_ids)
  196. {
  197. return $this->no_results_error('invalid_form_id');
  198. }
  199. if ( ! is_array($form_ids))
  200. {
  201. $form_ids = array($form_ids);
  202. }
  203. // -------------------------------------
  204. // libs, models, helper
  205. // -------------------------------------
  206. ee()->load->model('freeform_form_model');
  207. ee()->load->model('freeform_entry_model');
  208. ee()->load->model('freeform_field_model');
  209. ee()->load->library('freeform_forms');
  210. ee()->load->library('freeform_fields');
  211. // -------------------------------------
  212. // start cache for count and result
  213. // -------------------------------------
  214. $forms_data = ee()->freeform_form_model
  215. ->key('form_id')
  216. ->get(array('form_id' => $form_ids));
  217. $statuses = array_keys($this->data->get_form_statuses());
  218. // -------------------------------------
  219. // field data
  220. // -------------------------------------
  221. $all_field_ids = array();
  222. $all_order_ids = array();
  223. foreach ($forms_data as $form_data)
  224. {
  225. //this should always be true, but NEVER TRUST AN ELF
  226. if (isset($form_data['field_ids']) AND
  227. is_array($form_data['field_ids']))
  228. {
  229. $all_field_ids = array_merge($all_field_ids, $form_data['field_ids']);
  230. $all_order_ids = array_merge(
  231. $all_order_ids,
  232. $this->actions()->pipe_split($form_data['field_order'])
  233. );
  234. }
  235. }
  236. $all_field_ids = array_unique($all_field_ids);
  237. $all_order_ids = array_unique($all_order_ids);
  238. sort($all_field_ids);
  239. // -------------------------------------
  240. // get field data
  241. // -------------------------------------
  242. $all_field_data = FALSE;
  243. if ( ! empty($all_field_ids))
  244. {
  245. $all_field_data = ee()->freeform_field_model
  246. ->key('field_id')
  247. ->where_in('field_id', $all_field_ids)
  248. ->get();
  249. }
  250. $field_data = array();
  251. if ($all_field_data)
  252. {
  253. foreach ($all_field_data as $row)
  254. {
  255. $field_data[$row['field_id']] = $row;
  256. }
  257. }
  258. // -------------------------------------
  259. // set tables
  260. // -------------------------------------
  261. ee()->freeform_entry_model->id($form_ids);
  262. // -------------------------------------
  263. // replace CURRENT_USER before we get
  264. // started because the minute we don't
  265. // someone is going to figure out
  266. // a way to need it in site_id=""
  267. // -------------------------------------
  268. $this->replace_current_user();
  269. // -------------------------------------
  270. // site ids
  271. // -------------------------------------
  272. //if its star, allow all
  273. if (ee()->TMPL->fetch_param('site_id') !== '*')
  274. {
  275. $site_id = $this->parse_numeric_array_param('site_id');
  276. //if this isn't false, its single or an array
  277. if ($site_id !== FALSE)
  278. {
  279. if (empty($site_id['ids']))
  280. {
  281. ee()->freeform_entry_model->reset();
  282. return $this->no_results_error();
  283. }
  284. else if ($site_id['not'])
  285. {
  286. ee()->freeform_entry_model->where_not_in('site_id', $site_id['ids']);
  287. }
  288. else
  289. {
  290. ee()->freeform_entry_model->where_in('site_id', $site_id['ids']);
  291. }
  292. }
  293. //default
  294. else
  295. {
  296. ee()->freeform_entry_model->where('site_id', ee()->config->item('site_id'));
  297. }
  298. }
  299. // -------------------------------------
  300. // entry ids
  301. // -------------------------------------
  302. $entry_id = $this->parse_numeric_array_param('entry_id');
  303. if ($entry_id !== FALSE)
  304. {
  305. if (empty($entry_id['ids']))
  306. {
  307. ee()->freeform_entry_model->reset();
  308. return $this->no_results_error();
  309. }
  310. else if ($entry_id['not'])
  311. {
  312. ee()->freeform_entry_model->where_not_in('entry_id', $entry_id['ids']);
  313. }
  314. else
  315. {
  316. ee()->freeform_entry_model->where_in('entry_id', $entry_id['ids']);
  317. }
  318. }
  319. // -------------------------------------
  320. // author ids
  321. // -------------------------------------
  322. $author_id = $this->parse_numeric_array_param('author_id');
  323. if ($author_id !== FALSE)
  324. {
  325. if (empty($author_id['ids']))
  326. {
  327. ee()->freeform_entry_model->reset();
  328. return $this->no_results_error();
  329. }
  330. else if ($author_id['not'])
  331. {
  332. ee()->freeform_entry_model->where_not_in('author_id', $author_id['ids']);
  333. }
  334. else
  335. {
  336. ee()->freeform_entry_model->where_in('author_id', $author_id['ids']);
  337. }
  338. }
  339. // -------------------------------------
  340. // freeform:all_form_fields
  341. // -------------------------------------
  342. $tagdata = $this->replace_all_form_fields(
  343. ee()->TMPL->tagdata,
  344. $field_data,
  345. $all_order_ids
  346. );
  347. // -------------------------------------
  348. // get standard columns and labels
  349. // -------------------------------------
  350. $standard_columns = array_keys(
  351. ee()->freeform_form_model->default_form_table_columns
  352. );
  353. $standard_columns[] = 'author';
  354. $column_labels = array();
  355. //keyed labels for the front end
  356. foreach ($standard_columns as $column_name)
  357. {
  358. $column_labels[$column_name] = lang($column_name);
  359. }
  360. // -------------------------------------
  361. // available fields
  362. // -------------------------------------
  363. //this makes the keys and values the same
  364. $available_fields = array_combine($standard_columns, $standard_columns);
  365. $custom_fields = array();
  366. $field_descriptions = array();
  367. foreach ($field_data as $field_id => $f_data)
  368. {
  369. $fid = ee()->freeform_form_model->form_field_prefix . $field_id;
  370. //field_name => field_id_1, etc
  371. $available_fields[$f_data['field_name']] = $fid;
  372. //field_id_1 => field_id_1, etc
  373. $available_fields[$fid] = $fid;
  374. $custom_fields[] = $f_data['field_name'];
  375. //labels
  376. $column_labels[$f_data['field_name']] = $f_data['field_label'];
  377. $column_labels[$fid] = $f_data['field_label'];
  378. $field_descriptions[
  379. 'freeform:description:' . $f_data['field_name']
  380. ] = $f_data['field_description'];
  381. }
  382. // -------------------------------------
  383. // search:field_name="kittens"
  384. // -------------------------------------
  385. foreach (ee()->TMPL->tagparams as $key => $value)
  386. {
  387. if (substr($key, 0, 7) == 'search:')
  388. {
  389. $search_key = substr($key, 7);
  390. if (isset($available_fields[$search_key]))
  391. {
  392. ee()->freeform_entry_model->add_search(
  393. $available_fields[$search_key],
  394. $value
  395. );
  396. }
  397. }
  398. }
  399. // -------------------------------------
  400. // date range
  401. // -------------------------------------
  402. $date_range = ee()->TMPL->fetch_param('date_range');
  403. $date_range_start = ee()->TMPL->fetch_param('date_range_start');
  404. $date_range_end = ee()->TMPL->fetch_param('date_range_end');
  405. ee()->freeform_entry_model->date_where(
  406. $date_range,
  407. $date_range_start,
  408. $date_range_end
  409. );
  410. // -------------------------------------
  411. // complete
  412. // -------------------------------------
  413. $show_incomplete = ee()->TMPL->fetch_param('show_incomplete');
  414. if ($show_incomplete === 'only')
  415. {
  416. ee()->freeform_entry_model->where('complete', 'n');
  417. }
  418. else if ( ! $this->check_yes($show_incomplete))
  419. {
  420. ee()->freeform_entry_model->where('complete', 'y');
  421. }
  422. // -------------------------------------
  423. // status
  424. // -------------------------------------
  425. $status = ee()->TMPL->fetch_param('status', 'open');
  426. if ($status !== 'all')
  427. {
  428. if (in_array($status, $statuses))
  429. {
  430. ee()->freeform_entry_model->where('status', $status);
  431. }
  432. }
  433. // -------------------------------------
  434. // orderby/sort
  435. // -------------------------------------
  436. $sort = ee()->TMPL->fetch_param('sort');
  437. $orderby = ee()->TMPL->fetch_param('orderby');
  438. if ($orderby !== FALSE AND trim($orderby) !== '')
  439. {
  440. $orderby = $this->actions()->pipe_split(strtolower(trim($orderby)));
  441. array_walk($orderby, 'trim');
  442. // -------------------------------------
  443. // sort
  444. // -------------------------------------
  445. if ($sort !== FALSE AND trim($sort) !== '')
  446. {
  447. $sort = $this->actions()->pipe_split(strtolower(trim($sort)));
  448. array_walk($sort, 'trim');
  449. //correct sorts
  450. foreach ($sort as $key => $value)
  451. {
  452. if ( ! in_array($value, array('asc', 'desc')))
  453. {
  454. $sort[$key] = 'asc';
  455. }
  456. }
  457. }
  458. else
  459. {
  460. $sort = array('asc');
  461. }
  462. // -------------------------------------
  463. // add sorts and orderbys
  464. // -------------------------------------
  465. foreach ($orderby as $key => $value)
  466. {
  467. if (isset($available_fields[$value]))
  468. {
  469. //if the sort is not set, just use the first
  470. //really this should teach people to be more specific :p
  471. $temp_sort = isset($sort[$key]) ? $sort[$key] : $sort[0];
  472. ee()->freeform_entry_model->order_by(
  473. $available_fields[$value],
  474. $temp_sort
  475. );
  476. }
  477. }
  478. }
  479. //--------------------------------------
  480. // pagination start vars
  481. //--------------------------------------
  482. $limit = ee()->TMPL->fetch_param('limit', 50);
  483. $offset = ee()->TMPL->fetch_param('offset', 0);
  484. $row_count = 0;
  485. $total_entries = ee()->freeform_entry_model->count(array(), FALSE);
  486. $current_page = 0;
  487. if ($total_entries == 0)
  488. {
  489. ee()->freeform_entry_model->reset();
  490. return $this->no_results_error();
  491. }
  492. // -------------------------------------
  493. // pagination?
  494. // -------------------------------------
  495. $prefix = stristr($tagdata, LD . 'freeform:paginate' . RD);
  496. if ($limit > 0 AND ($total_entries - $offset) > $limit)
  497. {
  498. //get pagination info
  499. $pagination_data = $this->universal_pagination(array(
  500. 'total_results' => $total_entries,
  501. 'tagdata' => $tagdata,
  502. 'limit' => $limit,
  503. 'offset' => $offset,
  504. 'uri_string' => ee()->uri->uri_string,
  505. 'prefix' => 'freeform:',
  506. 'auto_paginate' => TRUE
  507. ));
  508. //if we paginated, sort the data
  509. if ($pagination_data['paginate'] === TRUE)
  510. {
  511. $tagdata = $pagination_data['tagdata'];
  512. $current_page = $pagination_data['pagination_page'];
  513. }
  514. }
  515. else
  516. {
  517. $this->paginate = FALSE;
  518. }
  519. ee()->freeform_entry_model->limit($limit, $current_page + $offset);
  520. // -------------------------------------
  521. // get data
  522. // -------------------------------------
  523. $result_array = ee()->freeform_entry_model->get();
  524. if (empty($result_array))
  525. {
  526. ee()->freeform_entry_model->reset();
  527. return $this->no_results_error();
  528. }
  529. $output_labels = array();
  530. //column labels for output
  531. foreach ($column_labels as $key => $value)
  532. {
  533. $output_labels['freeform:label:' . $key] = $value;
  534. }
  535. $count = $row_count;
  536. $variable_rows = array();
  537. $replace_tagdata = '';
  538. // -------------------------------------
  539. // allow pre_process
  540. // -------------------------------------
  541. $entry_ids = array();
  542. foreach ($result_array as $row)
  543. {
  544. if ( ! isset($entry_ids[$row['form_id']]))
  545. {
  546. $entry_ids[$row['form_id']] = array();
  547. }
  548. $entry_ids[$row['form_id']][] = $row['entry_id'];
  549. }
  550. foreach ($entry_ids as $f_form_id => $f_entry_ids)
  551. {
  552. ee()->freeform_fields->apply_field_method(array(
  553. 'method' => 'pre_process_entries',
  554. 'form_id' => $f_form_id,
  555. 'form_data' => $forms_data,
  556. 'entry_id' => $f_entry_ids,
  557. 'field_data' => $field_data
  558. ));
  559. }
  560. // -------------------------------------
  561. // output
  562. // -------------------------------------
  563. $to_prefix = array(
  564. 'absolute_count',
  565. 'absolute_results',
  566. 'author_id',
  567. 'author',
  568. 'complete',
  569. 'edit_date',
  570. 'entry_date',
  571. 'entry_id',
  572. 'form_id',
  573. 'form_name',
  574. 'ip_address',
  575. 'reverse_count'
  576. );
  577. $absolute_count = $current_page + $offset;
  578. $total_results = count($result_array);
  579. $count = 0;
  580. foreach ($result_array as $row)
  581. {
  582. //apply replace tag to our field data
  583. $field_parse = ee()->freeform_fields->apply_field_method(array(
  584. 'method' => 'replace_tag',
  585. 'form_id' => $row['form_id'],
  586. 'entry_id' => $row['entry_id'],
  587. 'form_data' => $forms_data,
  588. 'field_data' => $field_data,
  589. 'field_input_data' => $row,
  590. 'tagdata' => $tagdata
  591. ));
  592. $row = array_merge(
  593. $output_labels,
  594. $field_descriptions,
  595. $row,
  596. $field_parse['variables']
  597. );
  598. if ($replace_tagdata == '')
  599. {
  600. $replace_tagdata = $field_parse['tagdata'];
  601. }
  602. $row['freeform:form_name'] = $forms_data[$row['form_id']]['form_name'];
  603. $row['freeform:form_label'] = $forms_data[$row['form_id']]['form_label'];
  604. //prefix
  605. foreach ($row as $key => $value)
  606. {
  607. if ( ! preg_match('/^freeform:/', $key))
  608. {
  609. if (in_array($key, $custom_fields) AND
  610. ! isset($row['freeform:field:' . $key]))
  611. {
  612. $row['freeform:field:' . $key] = $value;
  613. }
  614. else if ( ! isset($row['freeform:' . $key]))
  615. {
  616. $row['freeform:' . $key] = $value;
  617. }
  618. unset($row[$key]);
  619. }
  620. }
  621. // -------------------------------------
  622. // other counts
  623. // -------------------------------------
  624. $row['freeform:reverse_count'] = $total_results - $count++;
  625. $row['freeform:absolute_count'] = ++$absolute_count;
  626. $row['freeform:absolute_results'] = $total_entries;
  627. $variable_rows[] = $row;
  628. }
  629. $tagdata = $replace_tagdata;
  630. $prefixed_tags = array(
  631. 'count',
  632. 'switch',
  633. 'total_results'
  634. );
  635. $tagdata = $this->tag_prefix_replace('freeform:', $prefixed_tags, $tagdata);
  636. //this should handle backspacing as well
  637. $tagdata = ee()->TMPL->parse_variables($tagdata, $variable_rows);
  638. $tagdata = $this->tag_prefix_replace('freeform:', $prefixed_tags, $tagdata, TRUE);
  639. // -------------------------------------
  640. // add pagination
  641. // -------------------------------------
  642. //prefix or no prefix?
  643. if ($prefix)
  644. {
  645. $tagdata = $this->parse_pagination(array(
  646. 'prefix' => 'freeform:',
  647. 'tagdata' => $tagdata
  648. ));
  649. }
  650. else
  651. {
  652. $tagdata = $this->parse_pagination(array(
  653. 'tagdata' => $tagdata
  654. ));
  655. }
  656. return $tagdata;
  657. }
  658. //END entries
  659. // --------------------------------------------------------------------
  660. /**
  661. * Freeform:Form
  662. * {exp:freeform:form}
  663. *
  664. * @access public
  665. * @param bool $edit edit mode? external for security
  666. * @param bool $preview preview mode?
  667. * @param mixed $preview_fields extra preview fields?
  668. * @return string tagdata
  669. */
  670. public function form ( $edit = FALSE, $preview = FALSE, $preview_fields = FALSE)
  671. {
  672. if ($this->check_yes(ee()->TMPL->fetch_param('require_logged_in')) AND
  673. ee()->session->userdata['member_id'] == '0')
  674. {
  675. return $this->no_results_error('not_logged_in');
  676. }
  677. // -------------------------------------
  678. // form id
  679. // -------------------------------------
  680. $form_id = $this->form_id();
  681. if ( ! $form_id)
  682. {
  683. return $this->no_results_error('invalid_form_id');
  684. }
  685. // -------------------------------------
  686. // libs, helpers, etc
  687. // -------------------------------------
  688. ee()->load->model('freeform_form_model');
  689. ee()->load->model('freeform_field_model');
  690. ee()->load->library('freeform_forms');
  691. ee()->load->library('freeform_fields');
  692. ee()->load->helper('form');
  693. // -------------------------------------
  694. // get prefs early to avoid query mess
  695. // -------------------------------------
  696. $this->data->get_module_preferences();
  697. $this->data->get_global_module_preferences();
  698. // -------------------------------------
  699. // build query
  700. // -------------------------------------
  701. $form_data = $this->data->get_form_info($form_id);
  702. // -------------------------------------
  703. // preview fields? (composer preview)
  704. // -------------------------------------
  705. if ( ! empty($preview_fields))
  706. {
  707. ee()->load->model('freeform_field_model');
  708. $valid_preview_fields = ee()->freeform_field_model
  709. ->where_in('field_id', $preview_fields)
  710. ->key('field_id')
  711. ->get();
  712. if ($valid_preview_fields)
  713. {
  714. foreach ($valid_preview_fields as $p_field_id => $p_field_data)
  715. {
  716. $p_field_data['preview'] = TRUE;
  717. $form_data['fields'][$p_field_id] = $p_field_data;
  718. }
  719. }
  720. }
  721. // -------------------------------------
  722. // form data
  723. // -------------------------------------
  724. $this->params['form_id'] = $form_id;
  725. // -------------------------------------
  726. // edit?
  727. // -------------------------------------
  728. $entry_id = 0;
  729. $edit_data = array();
  730. $this->params['edit'] = $edit;
  731. $this->params['entry_id'] = $entry_id;
  732. // -------------------------------------
  733. // replace CURRENT_USER everywhere
  734. // -------------------------------------
  735. $this->replace_current_user();
  736. // -------------------------------------
  737. // default params
  738. // -------------------------------------
  739. $default_mp_page_marker = 'page';
  740. $params_with_defaults = array(
  741. //security
  742. 'secure_action' => FALSE,
  743. 'secure_return' => FALSE,
  744. 'require_captcha' => (
  745. $this->check_yes(ee()->config->item('captcha_require_members')) OR
  746. (
  747. $this->check_no(ee()->config->item('captcha_require_members')) AND
  748. ee()->session->userdata('member_id') == 0
  749. )
  750. ),
  751. 'require_ip' => ! $this->check_no(
  752. ee()->config->item("require_ip_for_posting")
  753. ),
  754. 'return' => ee()->uri->uri_string,
  755. 'inline_error_return' => ee()->uri->uri_string,
  756. 'error_page' => '',
  757. 'ajax' => TRUE,
  758. 'restrict_edit_to_author' => TRUE,
  759. 'inline_errors' => FALSE,
  760. //dupe prevention
  761. 'prevent_duplicate_on' => '',
  762. 'prevent_duplicate_per_site' => FALSE,
  763. 'secure_duplicate_redirect' => FALSE,
  764. 'duplicate_redirect' => '',
  765. 'error_on_duplicate' => FALSE,
  766. //required or matching fields
  767. 'required' => '',
  768. 'matching_fields' => '',
  769. //multipage
  770. 'last_page' => TRUE,
  771. 'multipage' => FALSE,
  772. 'redirect_on_timeout' => TRUE,
  773. 'redirect_on_timeout_to' => '',
  774. 'page_marker' => $default_mp_page_marker,
  775. 'multipage_page' => '',
  776. 'paging_url' => '',
  777. 'multipage_page_names' => '',
  778. //notifications
  779. 'admin_notify' => $form_data['admin_notification_email'],
  780. 'admin_cc_notify' => '',
  781. 'admin_bcc_notify' => '',
  782. 'notify_user' => $this->check_yes($form_data['notify_user']),
  783. 'notify_admin' => $this->check_yes($form_data['notify_admin']),
  784. 'notify_on_edit' => FALSE,
  785. 'user_email_field' => $form_data['user_email_field'],
  786. //dynamic_recipients
  787. 'recipients' => FALSE,
  788. 'recipients_limit' => '3',
  789. //user inputted recipients
  790. 'recipient_user_input' => FALSE,
  791. 'recipient_user_limit' => '3',
  792. //templates
  793. 'recipient_template' => "",
  794. 'recipient_user_template' => "",
  795. 'admin_notification_template' => $form_data['admin_notification_id'],
  796. 'user_notification_template' => $form_data['user_notification_id'],
  797. 'status' => $form_data['default_status'],
  798. 'allow_status_edit' => FALSE,
  799. );
  800. foreach ($params_with_defaults as $p_name => $p_default)
  801. {
  802. //if the default is a boolean value
  803. if ( is_bool($p_default))
  804. {
  805. //and if there is a template param version of the param
  806. if (ee()->TMPL->fetch_param($p_name) !== FALSE)
  807. {
  808. //and if the default is boolean true
  809. if ($p_default === TRUE)
  810. {
  811. //and if the template param uses an indicator of the
  812. //'false' variety, we want to override the default
  813. //of TRUE and set FALSE.
  814. $this->params[$p_name] = ! $this->check_no(
  815. ee()->TMPL->fetch_param($p_name)
  816. );
  817. }
  818. //but if the default is boolean false
  819. else
  820. {
  821. //and the template param is trying to turn the feature
  822. //on through a 'y', 'yes', or 'on' value, then we want
  823. //to convert the FALSE to a TRUE
  824. $this->params[$p_name] = $this->check_yes(
  825. ee()->TMPL->fetch_param($p_name)
  826. );
  827. }
  828. }
  829. //there is no template param version of this default so the default stands
  830. else
  831. {
  832. $this->params[$p_name] = $p_default;
  833. }
  834. }
  835. //other wise check for the param or fallback on default
  836. else
  837. {
  838. $this->params[$p_name] = trim(
  839. ee()->TMPL->fetch_param($p_name, $p_default)
  840. );
  841. }
  842. }
  843. // ----------------------------------------
  844. // Check for duplicate
  845. // ----------------------------------------
  846. $duplicate = FALSE;
  847. //we can only prevent dupes on entry like this
  848. if ( ! $edit AND $this->params['prevent_duplicate_on'])
  849. {
  850. if ( in_array(
  851. $this->params['prevent_duplicate_on'],
  852. array('member_id', 'ip_address'),
  853. TRUE
  854. ))
  855. {
  856. $duplicate = ee()->freeform_forms->check_duplicate(
  857. $form_id,
  858. $this->params['prevent_duplicate_on'],
  859. '',
  860. $this->params['prevent_duplicate_per_site']
  861. );
  862. }
  863. }
  864. // ----------------------------------------
  865. // duplicate?
  866. // ----------------------------------------
  867. if ($duplicate)
  868. {
  869. if ($this->params['duplicate_redirect'] !== '')
  870. {
  871. ee()->functions->redirect(
  872. $this->prep_url(
  873. $this->params['duplicate_redirect'],
  874. $this->params['secure_duplicate_redirect']
  875. )
  876. );
  877. exit();
  878. }
  879. else if ($this->params['error_on_duplicate'])
  880. {
  881. return $this->no_results_error('no_duplicates');
  882. }
  883. /*else if (preg_match(
  884. '/' . LD . 'if freeform_duplicate' . RD . '(*?)' '/',
  885. ee()->TMPL->tagdata, ))
  886. {
  887. }*/
  888. }
  889. // -------------------------------------
  890. // check user email field
  891. // if this is from form prefs, its an ID
  892. // -------------------------------------
  893. $valid_user_email_field = FALSE;
  894. foreach ($form_data['fields'] as $field_id => $field_data)
  895. {
  896. if ($this->params['user_email_field'] == $field_data['field_name'] OR
  897. $this->params['user_email_field'] == $field_id)
  898. {
  899. $valid_user_email_field = TRUE;
  900. //in case the setting is an id
  901. $this->params['user_email_field'] = $field_data['field_name'];
  902. break;
  903. }
  904. }
  905. // if it doesn't exist in the form, lets blank it
  906. $this->params['user_email_field'] = (
  907. $valid_user_email_field ?
  908. $this->params['user_email_field'] :
  909. ''
  910. );
  911. // ----------------------------------------
  912. // 'freeform_module_form_begin' hook.
  913. // - This allows developers to change data before form processing.
  914. // ----------------------------------------
  915. if (ee()->extensions->active_hook('freeform_module_form_begin') === TRUE)
  916. {
  917. $edata = ee()->extensions->universal_call(
  918. 'freeform_module_form_begin',
  919. $this
  920. );
  921. if (ee()->extensions->end_script === TRUE) return;
  922. }
  923. // ----------------------------------------
  924. // -------------------------------------
  925. // start form
  926. // -------------------------------------
  927. $tagdata = ee()->TMPL->tagdata;
  928. $return = '';
  929. $hidden_fields = array();
  930. $outer_template_vars = array();
  931. $variables = array();
  932. $multipage = $this->params['multipage'];
  933. $last_page = TRUE;
  934. $page_total = 1;
  935. $current_page = 0;
  936. // -------------------------------------
  937. // check if this is multi-page
  938. // -------------------------------------
  939. $current_page = 1;
  940. // -------------------------------------
  941. // check again for captcha now that
  942. // tagdata has been adjusted
  943. // -------------------------------------
  944. if ($this->params['require_captcha'])
  945. {
  946. $this->params['require_captcha'] = (stristr($tagdata, LD . 'freeform:captcha' . RD) != FALSE);
  947. }
  948. // -------------------------------------
  949. // other random vars
  950. // -------------------------------------
  951. $variables['freeform:submit'] = form_submit('submit', lang('submit'));
  952. $variables['freeform:duplicate'] = $duplicate;
  953. $variables['freeform:not_duplicate'] = ! $duplicate;
  954. $variables['freeform:form_label'] = $form_data['form_label'];
  955. $variables['freeform:form_description'] = $form_data['form_description'];
  956. // -------------------------------------
  957. // recipient emails from multipage?
  958. // -------------------------------------
  959. $variables['freeform:mp_data:user_recipient_emails'] = '';
  960. if (isset($previous_inputs['hash_stored_data']['user_recipient_emails']) AND
  961. is_array($previous_inputs['hash_stored_data']['user_recipient_emails']))
  962. {
  963. $variables['freeform:mp_data:user_recipient_emails'] = implode(
  964. ', ',
  965. $previous_inputs['hash_stored_data']['user_recipient_emails']
  966. );
  967. }
  968. // -------------------------------------
  969. // display fields
  970. // -------------------------------------
  971. $field_error_data = array();
  972. $general_error_data = array();
  973. $field_input_data = array();
  974. // -------------------------------------
  975. // inline errors?
  976. // -------------------------------------
  977. if ($this->params['inline_errors'] AND
  978. $this->is_positive_intlike(ee()->session->flashdata('freeform_errors')))
  979. {
  980. ee()->load->model('freeform_param_model');
  981. $error_query = ee()->freeform_param_model->get_row(
  982. ee()->session->flashdata('freeform_errors')
  983. );
  984. if ($error_query !== FALSE)
  985. {
  986. $potential_error_data = json_decode($error_query['data'], TRUE);
  987. if (isset($potential_error_data['field_errors']))
  988. {
  989. $field_error_data = $potential_error_data['field_errors'];
  990. }
  991. if (isset($potential_error_data['general_errors']))
  992. {
  993. $general_error_data = $potential_error_data['general_errors'];
  994. }
  995. if (isset($potential_error_data['inputs']))
  996. {
  997. $field_input_data = $potential_error_data['inputs'];
  998. }
  999. }
  1000. }
  1001. foreach ($form_data['fields'] as $field_id => $field_data)
  1002. {
  1003. // -------------------------------------
  1004. // label?
  1005. // -------------------------------------
  1006. $error = '';
  1007. if (isset($field_error_data[$field_data['field_name']]))
  1008. {
  1009. $error = is_array($field_error_data[$field_data['field_name']]) ?
  1010. implode(', ', $field_error_data[$field_data['field_name']]) :
  1011. $field_error_data[$field_data['field_name']];
  1012. }
  1013. $variables['freeform:error:' . $field_data['field_name']] = $error;
  1014. $variables['freeform:label:' . $field_data['field_name']] = $field_data['field_label'];
  1015. $variables['freeform:description:' . $field_data['field_name']] = $field_data['field_description'];
  1016. // -------------------------------------
  1017. // values?
  1018. // -------------------------------------
  1019. $col_name = ee()->freeform_form_model->form_field_prefix . $field_id;
  1020. // -------------------------------------
  1021. // multipage previous inputs?
  1022. // -------------------------------------
  1023. $variables['freeform:mp_data:' . $field_data['field_name']] = (
  1024. isset($previous_inputs[$col_name]) ?
  1025. $previous_inputs[$col_name] :
  1026. (
  1027. isset($previous_inputs[$field_data['field_name']]) ?
  1028. $previous_inputs[$field_data['field_name']] :
  1029. ''
  1030. )
  1031. );
  1032. }
  1033. //END foreach ($form_data['fields'] as $field_id => $field_data)
  1034. if ( ! empty($edit_data))
  1035. {
  1036. $field_input_data = $edit_data;
  1037. }
  1038. else if ( ! empty($previous_inputs))
  1039. {
  1040. $field_input_data = $previous_inputs;
  1041. }
  1042. // -------------------------------------
  1043. // freeform:all_form_fields
  1044. // -------------------------------------
  1045. $tagdata = $this->replace_all_form_fields(
  1046. $tagdata,
  1047. $form_data['fields'],
  1048. $form_data['field_order'],
  1049. $field_input_data
  1050. );
  1051. // -------------------------------------
  1052. // general errors
  1053. // -------------------------------------
  1054. if ( ! empty($general_error_data))
  1055. {
  1056. //the error array might have sub arrays
  1057. //so we need to flatten
  1058. $_general_error_data = array();
  1059. foreach ($general_error_data as $error_set => $error_data)
  1060. {
  1061. if (is_array($error_data))
  1062. {
  1063. foreach ($error_data as $sub_key => $sub_error)
  1064. {
  1065. $_general_error_data[] = array('freeform:error_message' => $sub_error);
  1066. }
  1067. }
  1068. else
  1069. {
  1070. $_general_error_data[] = array('freeform:error_message' => $error_data);
  1071. }
  1072. }
  1073. $general_error_data = $_general_error_data;
  1074. }
  1075. $variables['freeform:general_errors'] = $general_error_data;
  1076. //have to do this so the conditional will work,
  1077. //seems that parse variables doesn't think a non-empty array = YES
  1078. $tagdata = ee()->functions->prep_conditionals(
  1079. $tagdata,
  1080. array('freeform:general_errors' => ! empty($general_error_data))
  1081. );
  1082. // -------------------------------------
  1083. // apply replace tag to our field data
  1084. // -------------------------------------
  1085. $field_parse = ee()->freeform_fields->apply_field_method(array(
  1086. 'method' => 'display_field',
  1087. 'form_id' => $form_id,
  1088. 'entry_id' => $entry_id,
  1089. 'form_data' => $form_data,
  1090. 'field_input_data' => $field_input_data,
  1091. 'tagdata' => $tagdata
  1092. ));
  1093. $this->multipart = $field_parse['multipart'];
  1094. $variables = array_merge($variables, $field_parse['variables']);
  1095. $tagdata = $field_parse['tagdata'];
  1096. // -------------------------------------
  1097. // dynamic recipient list
  1098. // -------------------------------------
  1099. $this->params['recipients'] = (
  1100. ! in_array(ee()->TMPL->fetch_param('recipients'), array(FALSE, ''))
  1101. );
  1102. //preload list with usable info if so
  1103. $this->params['recipients_list'] = array();
  1104. if ( $this->params['recipients'] )
  1105. {
  1106. $i = 1;
  1107. $while_limit = 1000;
  1108. $counter = 0;
  1109. while ( ! in_array(ee()->TMPL->fetch_param('recipient' . $i), array(FALSE, '')) )
  1110. {
  1111. $recipient = explode('|', ee()->TMPL->fetch_param('recipient' . $i));
  1112. //has a name?
  1113. if ( count($recipient) > 1)
  1114. {
  1115. $recipient_name = trim($recipient[0]);
  1116. $recipient_email = trim($recipient[1]);
  1117. }
  1118. //no name, we assume its just an email
  1119. //(though, this makes little sense, it needs a name to be useful)
  1120. else
  1121. {
  1122. $recipient_name = '';
  1123. $recipient_email = trim($recipient[0]);
  1124. }
  1125. $recipient_selected = FALSE;
  1126. if (isset($previous_inputs['hash_stored_data']['recipient_emails']) AND
  1127. is_array($previous_inputs['hash_stored_data']['recipient_emails']))
  1128. {
  1129. $recipient_selected = in_array(
  1130. $recipient_email,
  1131. $previous_inputs['hash_stored_data']['recipient_emails']
  1132. );
  1133. }
  1134. //add to list
  1135. $this->params['recipients_list'][$i] = array(
  1136. 'name' => $recipient_name,
  1137. 'email' => $recipient_email,
  1138. 'key' => uniqid(),
  1139. 'selected' => $recipient_selected
  1140. );
  1141. $i++;
  1142. //extra protection because while loops are scary
  1143. if (++$counter >= $while_limit)
  1144. {
  1145. break;
  1146. }
  1147. }
  1148. //if we end up with nothing, then lets not attempt later
  1149. if (empty($this->params['recipients_list']))
  1150. {
  1151. $this->params['recipients'] = FALSE;
  1152. }
  1153. }
  1154. // ----------------------------------------
  1155. // parse {captcha}
  1156. // ----------------------------------------
  1157. $variables['freeform:captcha'] = FALSE;
  1158. if ($this->params['require_captcha'])
  1159. {
  1160. $variables['freeform:captcha'] = ee()->functions->create_captcha();
  1161. }
  1162. // -------------------------------------
  1163. // dynamic recipient tagdata
  1164. // -------------------------------------
  1165. if ( $this->params['recipients'] AND
  1166. count($this->params['recipients_list']) > 0)
  1167. {
  1168. $variables['freeform_recipients'] = array();
  1169. $recipient_list = $this->params['recipients_list'];
  1170. //dynamic above starts with 1, so does this
  1171. for ( $i = 1, $l = count($recipient_list); $i <= $l; $i++ )
  1172. {
  1173. $variables['freeform:recipient_name' . $i] = $recipient_list[$i]['name'];
  1174. $variables['freeform:recipient_value' . $i] = $recipient_list[$i]['key'];
  1175. $variables['freeform:recipient_selected' . $i] = $recipient_list[$i]['selected'];
  1176. $variables['freeform:recipients'][] = array(
  1177. 'freeform:recipient_name' => $recipient_list[$i]['name'],
  1178. 'freeform:recipient_value' => $recipient_list[$i]['key'],
  1179. 'freeform:recipient_count' => $i,
  1180. //selected from hash data from multipages
  1181. 'freeform:recipient_selected' => $recipient_list[$i]['selected']
  1182. );
  1183. }
  1184. }
  1185. // -------------------------------------
  1186. // status pairs
  1187. // -------------------------------------
  1188. $tagdata = $this->parse_status_tags($tagdata);
  1189. // ----------------------------------------
  1190. // 'freeform_module_pre_form_parse' hook.
  1191. // - This allows developers to change data before tagdata processing.
  1192. // ----------------------------------------
  1193. $this->variables = $variables;
  1194. if (ee()->extensions->active_hook('freeform_module_pre_form_parse') === TRUE)
  1195. {
  1196. $tagdata = ee()->extensions->universal_call(
  1197. 'freeform_module_pre_form_parse',
  1198. $tagdata,
  1199. $this
  1200. );
  1201. if (ee()->extensions->end_script === TRUE) return;
  1202. }
  1203. // ----------------------------------------
  1204. //extra precaution in case someone hoses this
  1205. if (isset($this->variables) AND is_array($this->variables))
  1206. {
  1207. $variables = $this->variables;
  1208. }
  1209. // -------------------------------------
  1210. // parse external vars
  1211. // -------------------------------------
  1212. $outer_template_vars['freeform:form_page'] = $current_page;
  1213. $outer_template_vars['freeform:form_page_total'] = $page_total;
  1214. $outer_template_vars['freeform:form_name'] = $form_data['form_name'];
  1215. $outer_template_vars['freeform:form_label'] = $form_data['form_label'];
  1216. ee()->TMPL->template = ee()->functions->prep_conditionals(
  1217. ee()->TMPL->template,
  1218. $outer_template_vars
  1219. );
  1220. ee()->TMPL->template = ee()->functions->var_swap(
  1221. ee()->TMPL->template,
  1222. $outer_template_vars
  1223. );
  1224. // -------------------------------------
  1225. // parse all vars
  1226. // -------------------------------------
  1227. $tagdata = ee()->TMPL->parse_variables(
  1228. $tagdata,
  1229. array(array_merge($outer_template_vars,$variables))
  1230. );
  1231. // -------------------------------------
  1232. // this doesn't force ana ajax request
  1233. // but instead forces it _not_ to be
  1234. // if the ajax param = 'no'
  1235. // -------------------------------------
  1236. if ( ! $this->params['ajax'])
  1237. {
  1238. $hidden_fields['ajax_request'] = 'no';
  1239. }
  1240. //-------------------------------------
  1241. // build form
  1242. //-------------------------------------
  1243. $return .= $this->build_form(array(
  1244. 'action' => $this->get_action_url('save_form'),
  1245. 'method' => 'POST',
  1246. 'hidden_fields' => array_merge($hidden_fields, array(
  1247. // no more params can be set after this
  1248. 'params_id' => $this->insert_params(),
  1249. )),
  1250. 'tagdata' => $tagdata
  1251. ));
  1252. // ----------------------------------------
  1253. // 'freeform_module_form_end' hook.
  1254. // - This allows developers to change the form before output.
  1255. // ----------------------------------------
  1256. if (ee()->extensions->active_hook('freeform_module_form_end') === TRUE)
  1257. {
  1258. $return = ee()->extensions->universal_call(
  1259. 'freeform_module_form_end',
  1260. $return,
  1261. $this
  1262. );
  1263. if (ee()->extensions->end_script === TRUE) return;
  1264. }
  1265. // ----------------------------------------
  1266. return $return;
  1267. }
  1268. //END form
  1269. // -------------------------------------
  1270. // action requests
  1271. // -------------------------------------
  1272. // --------------------------------------------------------------------
  1273. /**
  1274. * ajax_validate
  1275. *
  1276. * does a save form that stops after validation
  1277. *
  1278. * @access public
  1279. * @return mixed ajax request
  1280. */
  1281. public function ajax_validate_form ()
  1282. {
  1283. return $this->save_form(TRUE);
  1284. }
  1285. //END ajax_validate
  1286. // --------------------------------------------------------------------
  1287. /**
  1288. * save_form
  1289. *
  1290. * form save from front_end/action request
  1291. *
  1292. * @access public
  1293. * @param bool validate only
  1294. * @return null
  1295. */
  1296. public function save_form ($validate_only = FALSE)
  1297. {
  1298. if ( ! $validate_only AND REQ !== 'ACTION')
  1299. {
  1300. return;
  1301. }
  1302. ee()->load->library('freeform_forms');
  1303. ee()->load->library('freeform_fields');
  1304. ee()->load->model('freeform_form_model');
  1305. // -------------------------------------
  1306. // require logged in?
  1307. // -------------------------------------
  1308. if ($this->param('require_logged_in') AND
  1309. ee()->session->userdata['member_id'] == '0')
  1310. {
  1311. $this->pre_validation_error(
  1312. lang('not_authorized') . ' - ' .
  1313. lang('not_logged_in')
  1314. );
  1315. }
  1316. // -------------------------------------
  1317. // blacklist, banned
  1318. // -------------------------------------
  1319. if (ee()->session->userdata['is_banned'] OR (
  1320. $this->check_yes(ee()->blacklist->blacklisted) AND
  1321. $this->check_no(ee()->blacklist->whitelisted)
  1322. )
  1323. )
  1324. {
  1325. $this->pre_validation_error(
  1326. lang('not_authorized') . ' - ' .
  1327. lang('reason_banned')
  1328. );
  1329. }
  1330. // -------------------------------------
  1331. // require ip? (except admin)
  1332. // -------------------------------------
  1333. if ($this->param('require_ip'))
  1334. {
  1335. if (ee()->input->ip_address() == '0.0.0.0')
  1336. {
  1337. $this->pre_validation_error(
  1338. lang('not_authorized') . ' - ' .
  1339. lang('reason_ip_required')
  1340. );
  1341. }
  1342. }
  1343. // -------------------------------------
  1344. // Is the nation of the user banned?
  1345. // -------------------------------------
  1346. if ($this->nation_ban_check(FALSE))
  1347. {
  1348. $this->pre_validation_error(
  1349. lang('not_authorized') . ' - ' .
  1350. ee()->config->item('ban_message')
  1351. );
  1352. }
  1353. // -------------------------------------
  1354. // valid form id
  1355. // -------------------------------------
  1356. $form_id = $this->form_id();
  1357. if ( ! $form_id)
  1358. {
  1359. $this->pre_validation_error(lang('invalid_form_id'));
  1360. }
  1361. // -------------------------------------
  1362. // is this an edit? entry_id
  1363. // -------------------------------------
  1364. $entry_id = $this->entry_id();
  1365. $edit = ($entry_id AND $entry_id != 0);
  1366. // -------------------------------------
  1367. // for multipage check later
  1368. // -------------------------------------
  1369. $multipage = $this->param('multipage');
  1370. $current_page = $this->param('current_page');
  1371. $last_page = $this->param('last_page');
  1372. $previous_inputs = array();
  1373. // -------------------------------------
  1374. // form data
  1375. // -------------------------------------
  1376. $form_data = $this->data->get_form_info($form_id);
  1377. $field_labels = array();
  1378. $valid_fields = array();
  1379. foreach ( $form_data['fields'] as $row)
  1380. {
  1381. $field_labels[$row['field_name']] = $row['field_label'];
  1382. $valid_fields[] = $row['field_name'];
  1383. }
  1384. // -------------------------------------
  1385. // for hooks
  1386. // -------------------------------------
  1387. $this->edit = $edit;
  1388. $this->multipage = $multipage;
  1389. $this->last_page = $last_page;
  1390. // -------------------------------------
  1391. // user email max/spam count
  1392. // -------------------------------------
  1393. ee()->load->library('freeform_notifications');
  1394. if ($last_page AND ($this->param('recipient_user_input') OR
  1395. $this->param('recipients')) AND
  1396. ee()->freeform_notifications->check_spam_interval($form_id)
  1397. )
  1398. {
  1399. $this->pre_validation_error(
  1400. lang('not_authorized') . ' - ' .
  1401. lang('email_limit_exceeded')
  1402. );
  1403. }
  1404. // -------------------------------------
  1405. // Check for duplicate
  1406. // -------------------------------------
  1407. $duplicate = FALSE;
  1408. if ($this->param('prevent_duplicate_on') AND
  1409. ! in_array(
  1410. $this->param('prevent_duplicate_on'),
  1411. array('member_id', 'ip_address'),
  1412. TRUE
  1413. ))
  1414. {
  1415. $duplicate = ee()->freeform_forms->check_duplicate(
  1416. $form_id,
  1417. $this->param('prevent_duplicate_on'),
  1418. ee()->input->get_post(
  1419. $this->param('prevent_duplicate_on'),
  1420. TRUE
  1421. ),
  1422. $this->param('prevent_duplicate_per_site')
  1423. );
  1424. }
  1425. if ($duplicate)
  1426. {
  1427. $this->pre_validation_error(lang('no_duplicates'));
  1428. }
  1429. // -------------------------------------
  1430. // pre xid check
  1431. // -------------------------------------
  1432. // we aren't going to delete just yet
  1433. // because if they have input errors
  1434. // then we want to keep this xid for a bit
  1435. // and only delete xid on success
  1436. // -------------------------------------
  1437. if ( $this->check_yes(ee()->config->item('secure_forms')) )
  1438. {
  1439. ee()->db->from('security_hashes');
  1440. ee()->db->where(array(
  1441. 'hash' => ee()->input->post('XID'),
  1442. 'ip_address' => ee()->input->ip_address(),
  1443. 'date >' => ee()->localize->now - 7200
  1444. ));
  1445. if (ee()->db->count_all_results() == 0)
  1446. {
  1447. $this->pre_validation_error(
  1448. lang('not_authorized') . ' - ' .
  1449. lang('reason_secure_form_timeout')
  1450. );
  1451. }
  1452. }
  1453. // -------------------------------------
  1454. // pre-validate hook
  1455. // -------------------------------------
  1456. $errors = array();
  1457. //have to do this weird for backward compat
  1458. $this->field_errors = array();
  1459. if (ee()->extensions->active_hook('freeform_module_validate_begin') === TRUE)
  1460. {
  1461. $errors = ee()->extensions->universal_call(
  1462. 'freeform_module_validate_begin',
  1463. $errors,
  1464. $this
  1465. );
  1466. if (ee()->extensions->end_script === TRUE) return;
  1467. }
  1468. // -------------------------------------
  1469. // require fields
  1470. // -------------------------------------
  1471. if ($this->param('required'))
  1472. {
  1473. $required = $this->actions()->pipe_split($this->param('required'));
  1474. foreach ($required as $required_field)
  1475. {
  1476. //just in case someone misspelled a require
  1477. //or removes a field after making the require list
  1478. if ( ! in_array($required_field, $valid_fields))
  1479. {
  1480. continue;
  1481. }
  1482. if ( (
  1483. (
  1484. is_array( ee()->input->get_post($required_field) ) AND
  1485. count(ee()->input->get_post($required_field)) < 1
  1486. ) OR
  1487. trim((string) ee()->input->get_post($required_field)) === ''
  1488. )
  1489. //required field could be a file
  1490. AND ! isset($_FILES[$required_field])
  1491. )
  1492. {
  1493. $this->field_errors[
  1494. $required_field
  1495. ] = lang('required_field_missing');
  1496. //only want the postfixing of errors
  1497. //if we are sending to general errors screen
  1498. //or an error page
  1499. //the second conditional is for people requesting
  1500. //the custom error page via ajax
  1501. if ( ! $this->param('inline_errors') AND
  1502. ! ($this->is_ajax_request() AND
  1503. ! trim($this->param('error_page'))))
  1504. {
  1505. $this->field_errors[$required_field] .= ': '.
  1506. $field_labels[$required_field];
  1507. }
  1508. }
  1509. }
  1510. }
  1511. // -------------------------------------
  1512. // matching fields
  1513. // -------------------------------------
  1514. if ($this->param('matching_fields'))
  1515. {
  1516. $matching_fields = $this->actions()->pipe_split($this->param('matching_fields'));
  1517. foreach ($matching_fields as $match_field)
  1518. {
  1519. //just in case someone misspelled a require
  1520. //or removes a field after making the require list
  1521. if ( ! in_array($match_field, $valid_fields))
  1522. {
  1523. continue;
  1524. }
  1525. //array comparison is correct in PHP and this should work
  1526. //no matter what.
  1527. //normal validation will fix other issues
  1528. if ( ee()->input->get_post($match_field) == FALSE OR
  1529. ee()->input->get_post($match_field . '_confirm') == FALSE OR
  1530. ee()->input->get_post($match_field) !==
  1531. ee()->input->get_post($match_field . '_confirm')
  1532. )
  1533. {
  1534. $this->field_errors[$match_field] = lang('fields_do_not_match') .
  1535. $field_labels[$match_field] .
  1536. ' | ' .
  1537. $field_labels[$match_field] .
  1538. ' ' .
  1539. lang('confirm');
  1540. }
  1541. }
  1542. }
  1543. // -------------------------------------
  1544. // validate dynamic recipients
  1545. // no actual validation errors
  1546. // will throw here, but in case we do
  1547. // in the future
  1548. // -------------------------------------
  1549. $recipient_emails = array();
  1550. if ($this->param('recipients'))
  1551. {
  1552. $recipient_email_input = ee()->input->get_post('recipient_email');
  1553. if ( ! in_array($recipient_email_input, array(FALSE, ''), TRUE))
  1554. {
  1555. if ( ! is_array($recipient_email_input))
  1556. {
  1557. $recipient_email_input = array($recipient_email_input);
  1558. }
  1559. // recipients are encoded, so lets check for keys
  1560. // since dynamic recipients are dev inputted
  1561. // we aren't going to error on invalid ones
  1562. // but rather just accept if present, and move on if not
  1563. $recipients_list = $this->param('recipients_list');
  1564. $field_out = '';
  1565. foreach($recipients_list as $i => $r_data)
  1566. {
  1567. if (in_array($r_data['key'], $recipient_email_input))
  1568. {
  1569. $recipient_emails[] = $r_data['email'];
  1570. $field_out .= $r_data['name'] . ' <' . $r_data['email'] . '>' . "\n";
  1571. }
  1572. }
  1573. //THE ENGLISH ARE TOO MANY!
  1574. if (count($recipient_emails) > $this->param('recipients_limit'))
  1575. {
  1576. $errors['recipient_email'] = lang('over_recipient_limit');
  1577. }
  1578. //does the user have a recipient_email custom field?
  1579. else if (in_array('recipient_email', $valid_fields))
  1580. {
  1581. $_POST['recipient_email'] = trim($field_out);
  1582. }
  1583. }
  1584. //if there is previous recipient emails
  1585. if (empty($recipient_emails) AND
  1586. isset($previous_inputs['hash_stored_data']['recipient_emails']))
  1587. {
  1588. $recipient_emails = $previous_inputs['hash_stored_data']['recipient_emails'];
  1589. }
  1590. }
  1591. // -------------------------------------
  1592. // validate user inputted emails
  1593. // -------------------------------------
  1594. $user_recipient_emails = array();
  1595. if ($this->param('recipient_user_input'))
  1596. {
  1597. $user_recipient_email_input = ee()->input->get_post('recipient_email_user');
  1598. if ( ! in_array($user_recipient_email_input, array(FALSE, ''), TRUE))
  1599. {
  1600. $user_recipient_emails = $this->validate_emails($user_recipient_email_input);
  1601. $user_recipient_emails = $user_recipient_emails['good'];
  1602. //if we are here that means we submitted at least something
  1603. //but nothing passed
  1604. if (empty($user_recipient_emails))
  1605. {
  1606. $errors['recipient_user_input'] = lang('no_valid_recipient_emails');
  1607. }
  1608. else if (count($user_recipient_emails) > $this->param('recipient_user_limit'))
  1609. {
  1610. $errors['recipient_email_user'] = lang('over_recipient_user_limit');
  1611. }
  1612. }
  1613. //if there is previous user recipient emails
  1614. if (empty($user_recipient_emails) AND
  1615. isset($previous_inputs['hash_stored_data']['user_recipient_emails']))
  1616. {
  1617. $user_recipient_emails = $previous_inputs['hash_stored_data']['user_recipient_emails'];
  1618. }
  1619. }
  1620. // -------------------------------------
  1621. // validate status
  1622. // -------------------------------------
  1623. $status = $form_data['default_status'];
  1624. $input_status = ee()->input->post('status', TRUE);
  1625. $param_status = $this->param('status');
  1626. $available_statuses = $this->data->get_form_statuses();
  1627. //user status input
  1628. if ($this->param('allow_status_edit') AND
  1629. $input_status !== FALSE AND
  1630. array_key_exists($input_status, $available_statuses))
  1631. {
  1632. $status = $input_status;
  1633. }
  1634. //status param
  1635. else if ($param_status !== $status AND
  1636. array_key_exists($param_status, $available_statuses))
  1637. {
  1638. $status = $param_status;
  1639. }
  1640. // -------------------------------------
  1641. // validate
  1642. // -------------------------------------
  1643. $field_input_data = array();
  1644. $field_list = array();
  1645. foreach ($form_data['fields'] as $field_id => $field_data)
  1646. {
  1647. $field_list[$field_data['field_name']] = $field_data['field_label'];
  1648. $field_post = ee()->input->post($field_data['field_name'], TRUE);
  1649. //if it's not even in $_POST or $_GET, lets skip input
  1650. //unless its an uploaded file, then we'll send false anyway
  1651. //because its field type will handle the rest of that work
  1652. if ($field_post !== FALSE OR
  1653. isset($_FILES[$field_data['field_name']]))
  1654. {
  1655. $field_input_data[$field_data['field_name']] = $field_post;
  1656. }
  1657. }
  1658. //form fields do their own validation,
  1659. //so lets just get results! (sexy results?)
  1660. $this->field_errors = array_merge(
  1661. $this->field_errors,
  1662. ee()->freeform_fields->validate(
  1663. $form_id,
  1664. $field_input_data,
  1665. ! ($this->is_ajax_request() OR $this->param('inline_errors'))
  1666. )
  1667. );
  1668. // -------------------------------------
  1669. // post validate hook
  1670. // -------------------------------------
  1671. if (ee()->extensions->active_hook('freeform_module_validate_end') === TRUE)
  1672. {
  1673. $errors = ee()->extensions->universal_call(
  1674. 'freeform_module_validate_end',
  1675. $errors,
  1676. $this
  1677. );
  1678. if (ee()->extensions->end_script === TRUE) return;
  1679. }
  1680. // -------------------------------------
  1681. // captcha
  1682. // -------------------------------------
  1683. if ( ! $validate_only AND
  1684. ee()->input->get_post('validate_only') === FALSE AND
  1685. $last_page AND
  1686. $this->param('require_captcha'))
  1687. {
  1688. if ( trim(ee()->input->post('captcha')) == '')
  1689. {
  1690. $errors[] = lang('captcha_required');
  1691. }
  1692. else
  1693. {
  1694. ee()->db->from('captcha');
  1695. ee()->db->where(array(
  1696. 'word' => ee()->input->post('captcha'),
  1697. 'ip_address' => ee()->input->ip_address(),
  1698. 'date >' => ee()->localize->now - 7200
  1699. ));
  1700. if (ee()->db->count_all_results() == 0)
  1701. {
  1702. $errors[] = lang('captcha_required');
  1703. }
  1704. }
  1705. }
  1706. $all_errors = array_merge($errors, $this->field_errors);
  1707. // -------------------------------------
  1708. // halt on errors
  1709. // -------------------------------------
  1710. if (count($all_errors) > 0)
  1711. {
  1712. if ($this->param('inline_errors'))
  1713. {
  1714. ee()->load->model('freeform_param_model');
  1715. $error_param_id = ee()->freeform_param_model->insert_params(
  1716. array(
  1717. 'general_errors' => $errors,
  1718. 'field_errors' => $this->field_errors,
  1719. 'inputs' => $field_input_data
  1720. )
  1721. );
  1722. ee()->session->set_flashdata('freeform_errors', $error_param_id);
  1723. ee()->functions->redirect(
  1724. $this->prep_url(
  1725. $this->param('inline_error_return'),
  1726. $this->param('secure_return')
  1727. )
  1728. );
  1729. exit();
  1730. }
  1731. $this->actions()->full_stop($all_errors);
  1732. }
  1733. //send ajax response exists
  1734. //but this is in case someone is using a replacer
  1735. //that uses
  1736. if ($validate_only OR ee()->input->get_post('validate_only') !== FALSE)
  1737. {
  1738. if ($this->is_ajax_request())
  1739. {
  1740. $this->send_ajax_response(array(
  1741. 'success' => TRUE,
  1742. 'errors' => array()
  1743. ));
  1744. }
  1745. exit();
  1746. }
  1747. // -------------------------------------
  1748. // status
  1749. // -------------------------------------
  1750. $field_input_data['status'] = $status;
  1751. // -------------------------------------
  1752. // entry insert begin hook
  1753. // -------------------------------------
  1754. $backup_data = $field_input_data;
  1755. if (ee()->extensions->active_hook('freeform_module_insert_begin') === TRUE)
  1756. {
  1757. $field_input_data = ee()->extensions->universal_call(
  1758. 'freeform_module_insert_begin',
  1759. $field_input_data,
  1760. $entry_id,
  1761. $form_id,
  1762. $this
  1763. );
  1764. if (ee()->extensions->end_script === TRUE)
  1765. {
  1766. return;
  1767. }
  1768. // -------------------------------------
  1769. // if some butthead doesn't return
  1770. // the array from their extension
  1771. // we need a backup here or everything
  1772. // busts.
  1773. // -------------------------------------
  1774. if ( ! is_array($field_input_data))
  1775. {
  1776. $field_input_data = $backup_data;
  1777. }
  1778. }
  1779. // -------------------------------------
  1780. // insert/update data into db
  1781. // -------------------------------------
  1782. $entry_id = ee()->freeform_forms->insert_new_entry(
  1783. $form_id,
  1784. $field_input_data
  1785. );
  1786. // -------------------------------------
  1787. // entry insert end hook
  1788. // -------------------------------------
  1789. if (ee()->extensions->active_hook('freeform_module_insert_end') === TRUE)
  1790. {
  1791. ee()->extensions->universal_call(
  1792. 'freeform_module_insert_end',
  1793. $field_input_data,
  1794. $entry_id,
  1795. $form_id,
  1796. $this
  1797. );
  1798. if (ee()->extensions->end_script === TRUE)
  1799. {
  1800. return;
  1801. }
  1802. }
  1803. // -------------------------------------
  1804. // delete xid and captcha
  1805. // -------------------------------------
  1806. // wait this late because we dont
  1807. // want to remove before a custom field
  1808. // has a chance to throw an error
  1809. // on one of its actions, like file
  1810. // upload
  1811. // -------------------------------------
  1812. if ($last_page AND $this->param('require_captcha'))
  1813. {
  1814. ee()->db->where(array(
  1815. 'word' => ee()->input->post('captcha'),
  1816. 'ip_address' => ee()->input->ip_address()
  1817. ));
  1818. ee()->db->or_where('date <', ee()->localize->now - 7200);
  1819. ee()->db->delete('captcha');
  1820. }
  1821. if ($this->check_yes(ee()->config->item('secure_forms')) )
  1822. {
  1823. ee()->db->where(array(
  1824. 'hash' => ee()->input->post('XID'),
  1825. 'ip_address' => ee()->input->ip_address()
  1826. ));
  1827. ee()->db->or_where('date <', ee()->localize->now - 7200);
  1828. ee()->db->delete('security_hashes');
  1829. }
  1830. // -------------------------------------
  1831. // if we are multi-paging, move on
  1832. // -------------------------------------
  1833. if ($multipage AND ! $last_page)
  1834. {
  1835. ee()->functions->redirect(
  1836. $this->prep_url(
  1837. $this->param('multipage_next_page'),
  1838. $this->param('secure_return')
  1839. )
  1840. );
  1841. exit();
  1842. }
  1843. // -------------------------------------
  1844. // previous inputs need their real names
  1845. // -------------------------------------
  1846. foreach ($form_data['fields'] as $field_id => $field_data)
  1847. {
  1848. if (is_array($previous_inputs))
  1849. {
  1850. $fid = ee()->freeform_form_model->form_field_prefix . $field_id;
  1851. if (isset($previous_inputs[$fid]))
  1852. {
  1853. $previous_inputs[$field_data['field_name']] = $previous_inputs[$fid];
  1854. }
  1855. }
  1856. }
  1857. $field_input_data = array_merge(
  1858. (is_array($previous_inputs) ? $previous_inputs : array()),
  1859. array('entry_id' => $entry_id),
  1860. $field_input_data
  1861. );
  1862. // -------------------------------------
  1863. // do notifications
  1864. // -------------------------------------
  1865. if ( ! $edit OR $this->param('notify_on_edit'))
  1866. {
  1867. if ($this->param('notify_admin'))
  1868. {
  1869. ee()->freeform_notifications->send_notification(array(
  1870. 'form_id' => $form_id,
  1871. 'entry_id' => $entry_id,
  1872. 'notification_type' => 'admin',
  1873. 'recipients' => $this->param('admin_notify'),
  1874. 'form_input_data' => $field_input_data,
  1875. 'cc_recipients' => $this->param('admin_cc_notify'),
  1876. 'bcc_recipients' => $this->param('admin_bcc_notify'),
  1877. 'template' => $this->param('admin_notification_template')
  1878. ));
  1879. }
  1880. //this is a custom field named by the user
  1881. //notifications does its own validation
  1882. //so if someone puts a non-validated input field
  1883. //then notifications will just silently fail
  1884. //because it wont be a user input problem
  1885. //but rather a dev implementation problem
  1886. if ($this->param('notify_user') AND
  1887. $this->param('user_email_field') AND
  1888. isset($field_input_data[$this->param('user_email_field')]))
  1889. {
  1890. ee()->freeform_notifications->send_notification(array(
  1891. 'form_id' => $form_id,
  1892. 'entry_id' => $entry_id,
  1893. 'notification_type' => 'user',
  1894. 'recipients' => $field_input_data[$this->param('user_email_field')],
  1895. 'form_input_data' => $field_input_data,
  1896. 'template' => $this->param('user_notification_template'),
  1897. 'enable_spam_log' => FALSE
  1898. ));
  1899. }
  1900. //recipients
  1901. if ( ! empty($recipient_emails))
  1902. {
  1903. ee()->freeform_notifications->send_notification(array(
  1904. 'form_id' => $form_id,
  1905. 'entry_id' => $entry_id,
  1906. 'notification_type' => 'user_recipient',
  1907. 'recipients' => $recipient_emails,
  1908. 'form_input_data' => $field_input_data,
  1909. 'template' => $this->param('recipient_template')
  1910. ));
  1911. }
  1912. //user inputted recipients
  1913. if ( ! empty($user_recipient_emails))
  1914. {
  1915. ee()->freeform_notifications->send_notification(array(
  1916. 'form_id' => $form_id,
  1917. 'entry_id' => $entry_id,
  1918. 'notification_type' => 'user_recipient',
  1919. 'recipients' => $user_recipient_emails,
  1920. 'form_input_data' => $field_input_data,
  1921. 'template' => $this->param('recipient_user_template')
  1922. ));
  1923. }
  1924. }
  1925. // -------------------------------------
  1926. // return
  1927. // -------------------------------------
  1928. $return_url = $this->param('return');
  1929. if (ee()->input->post('return') !== FALSE)
  1930. {
  1931. $return_url = ee()->input->post('return');
  1932. }
  1933. $return = str_replace(
  1934. //because. Shut up.
  1935. array(
  1936. '%%form_entry_id%%',
  1937. '%%entry_id%%',
  1938. '%form_entry_id%',
  1939. '%entry_id%'
  1940. ),
  1941. $entry_id,
  1942. $this->prep_url(
  1943. $return_url,
  1944. $this->param('secure_return')
  1945. )
  1946. );
  1947. //detergent?
  1948. if ($this->is_ajax_request())
  1949. {
  1950. $this->send_ajax_response(array(
  1951. 'success' => TRUE,
  1952. 'entry_id' => $entry_id,
  1953. 'form_id' => $form_id,
  1954. 'return' => $return
  1955. ));
  1956. }
  1957. else
  1958. {
  1959. ee()->functions->redirect($return);
  1960. }
  1961. }
  1962. //END save_form
  1963. // --------------------------------------------------------------------
  1964. // private! No looky!
  1965. // --------------------------------------------------------------------
  1966. // --------------------------------------------------------------------
  1967. /**
  1968. * Pre-Validation Errors that are deal breakers
  1969. *
  1970. * @access protected
  1971. * @param mixed $errors error string or array of errors
  1972. * @return null exits
  1973. */
  1974. protected function pre_validation_error ($errors)
  1975. {
  1976. if ($this->param('inline_errors'))
  1977. {
  1978. ee()->load->model('freeform_param_model');
  1979. $error_param_id = ee()->freeform_param_model->insert_params(
  1980. array(
  1981. 'general_errors' => is_array($errors) ? $errors : array($errors),
  1982. 'field_errors' => array(),
  1983. 'inputs' => array()
  1984. )
  1985. );
  1986. ee()->session->set_flashdata('freeform_errors', $error_param_id);
  1987. ee()->functions->redirect(
  1988. $this->prep_url(
  1989. $this->param('inline_error_return'),
  1990. $this->param('secure_return')
  1991. )
  1992. );
  1993. exit();
  1994. }
  1995. return $this->actions()->full_stop($errors);
  1996. }
  1997. //END pre_validation_error
  1998. // --------------------------------------------------------------------
  1999. /**
  2000. * build_form
  2001. *
  2002. * builds a form based on passed data
  2003. *
  2004. * @access private
  2005. * @
  2006. * @return mixed boolean false if not found else id
  2007. */
  2008. private function build_form ( $data )
  2009. {
  2010. // -------------------------------------
  2011. // prep input data
  2012. // -------------------------------------
  2013. //set defaults for optional items
  2014. $input_defaults = array(
  2015. 'action' => '/',
  2016. 'hidden_fields' => array(),
  2017. 'tagdata' => ee()->TMPL->tagdata,
  2018. );
  2019. //array2 overwrites any duplicate key from array1
  2020. $data = array_merge($input_defaults, $data);
  2021. //xid? xid
  2022. if ( $this->check_yes(ee()->config->item('secure_forms')) )
  2023. {
  2024. $data['hidden_fields']['XID'] = $this->create_xid();
  2025. }
  2026. // --------------------------------------------
  2027. // HTTPS URLs?
  2028. // --------------------------------------------
  2029. $data['action'] = $this->prep_url(
  2030. $data['action'],
  2031. (
  2032. isset($this->params['secure_action']) AND
  2033. $this->params['secure_action']
  2034. )
  2035. );
  2036. foreach(array('return', 'RET') as $return_field)
  2037. {
  2038. if (isset($data['hidden_fields'][$return_field]))
  2039. {
  2040. $data['hidden_fields'][$return_field] = $this->prep_url(
  2041. $data['hidden_fields'][$return_field],
  2042. (
  2043. isset($this->params['secure_return']) AND
  2044. $this->params['secure_return']
  2045. )
  2046. );
  2047. }
  2048. }
  2049. // --------------------------------------------
  2050. // Override Form Attributes with form:xxx="" parameters
  2051. // --------------------------------------------
  2052. $form_attributes = array();
  2053. if (is_object(ee()->TMPL) AND ! empty(ee()->TMPL->tagparams))
  2054. {
  2055. foreach(ee()->TMPL->tagparams as $key => $value)
  2056. {
  2057. if (strncmp($key, 'form:', 5) == 0)
  2058. {
  2059. //allow action override.
  2060. if (substr($key, 5) == 'action')
  2061. {
  2062. $data['action'] = $value;
  2063. }
  2064. else
  2065. {
  2066. $form_attributes[substr($key, 5)] = $value;
  2067. }
  2068. }
  2069. }
  2070. }
  2071. // --------------------------------------------
  2072. // Create and Return Form
  2073. // --------------------------------------------
  2074. //have to have this for file uploads
  2075. if ($this->multipart)
  2076. {
  2077. $form_attributes['enctype'] = 'multipart/form-data';
  2078. }
  2079. $form_attributes['method'] = $data['method'];
  2080. $return = form_open(
  2081. $data['action'],
  2082. $form_attributes,
  2083. $data['hidden_fields']
  2084. );
  2085. $return .= stripslashes($data['tagdata']);
  2086. $return .= "</form>";
  2087. return $return;
  2088. }
  2089. //END build_form
  2090. // --------------------------------------------------------------------
  2091. /**
  2092. * form_id - finds form id the best it can
  2093. *
  2094. * @access private
  2095. * @param bool $allow_multiple allow multiple input?
  2096. * @return mixed boolean false if not found else id
  2097. */
  2098. private function form_id ($allow_multiple = FALSE)
  2099. {
  2100. if ($this->form_id)
  2101. {
  2102. return $this->form_id;
  2103. }
  2104. $form_id = FALSE;
  2105. $possible_name = FALSE;
  2106. $possible_label = FALSE;
  2107. $possible_id = FALSE;
  2108. $tmpl_available = (isset(ee()->TMPL) AND is_object(ee()->TMPL));
  2109. // -------------------------------------
  2110. // by direct param first
  2111. // -------------------------------------
  2112. if ($tmpl_available)
  2113. {
  2114. $possible_id = ee()->TMPL->fetch_param('form_id');
  2115. }
  2116. // -------------------------------------
  2117. // by name param
  2118. // -------------------------------------
  2119. if ( ! $possible_id AND $tmpl_available)
  2120. {
  2121. $possible_name = ee()->TMPL->fetch_param('form_name');
  2122. }
  2123. // -------------------------------------
  2124. // by label (with legacy for collection)
  2125. // -------------------------------------
  2126. if ($tmpl_available AND ! $possible_id AND ! $possible_name)
  2127. {
  2128. $possible_label = ee()->TMPL->fetch_param('form_label');
  2129. if ( ! $possible_label)
  2130. {
  2131. $possible_label = ee()->TMPL->fetch_param('collection');
  2132. }
  2133. }
  2134. // -------------------------------------
  2135. // params id
  2136. // -------------------------------------
  2137. if ( ! $possible_id AND
  2138. ! $possible_name AND
  2139. ! $possible_label AND
  2140. $this->param('form_id'))
  2141. {
  2142. $possible_id = $this->param('form_id');
  2143. }
  2144. // -------------------------------------
  2145. // params name
  2146. // -------------------------------------
  2147. if ( ! $possible_id AND
  2148. ! $possible_name AND
  2149. ! $possible_label AND
  2150. $this->param('form_name'))
  2151. {
  2152. $possible_name = $this->param('form_name');
  2153. }
  2154. // -------------------------------------
  2155. // get post id
  2156. // -------------------------------------
  2157. if ( ! $possible_id AND
  2158. ! $possible_name AND
  2159. ! $possible_label)
  2160. {
  2161. $possible_id = ee()->input->get_post('form_id');
  2162. }
  2163. // -------------------------------------
  2164. // get post name
  2165. // -------------------------------------
  2166. if ( ! $possible_id AND
  2167. ! $possible_name AND
  2168. ! $possible_label)
  2169. {
  2170. $possible_name = ee()->input->get_post('form_name');
  2171. }
  2172. // -------------------------------------
  2173. // check possibles
  2174. // -------------------------------------
  2175. if ($possible_id)
  2176. {
  2177. //if multiple and match pattern...
  2178. if ($allow_multiple AND preg_match('/^[\d\|]+$/', $possible_id))
  2179. {
  2180. $ids = $this->actions()->pipe_split($possible_id);
  2181. ee()->load->model('freeform_form_model');
  2182. $result = ee()->freeform_form_model->select('form_id')
  2183. ->get(array('form_id' => $ids));
  2184. //we only want results, not everything
  2185. if ($result !== FALSE)
  2186. {
  2187. $form_id = array();
  2188. foreach ($result as $row)
  2189. {
  2190. $form_id[] = $row['form_id'];
  2191. }
  2192. }
  2193. }
  2194. else if ($this->is_positive_intlike($possible_id) AND
  2195. $this->data->is_valid_form_id($possible_id))
  2196. {
  2197. $form_id = $possible_id;
  2198. }
  2199. }
  2200. if ( ! $form_id AND $possible_name)
  2201. {
  2202. //if multiple and pipe
  2203. if ($allow_multiple AND stristr($possible_name, '|'))
  2204. {
  2205. $names = $this->actions()->pipe_split($possible_name);
  2206. ee()->load->model('freeform_form_model');
  2207. $result = ee()->freeform_form_model->select('form_id')
  2208. ->get(array('form_name' => $names));
  2209. //we only want results, not everything
  2210. if ($result !== FALSE)
  2211. {
  2212. $form_id = array();
  2213. foreach ($result as $row)
  2214. {
  2215. $form_id[] = $row['form_id'];
  2216. }
  2217. }
  2218. }
  2219. else
  2220. {
  2221. $possible_id = $this->data->get_form_id_by_name($possible_name);
  2222. if ($possible_id !== FALSE AND $possible_id > 0)
  2223. {
  2224. $form_id = $possible_id;
  2225. }
  2226. }
  2227. }
  2228. if ( ! $form_id AND $possible_label)
  2229. {
  2230. ee()->load->model('freeform_form_model');
  2231. //if multiple and pipe
  2232. if ($allow_multiple AND stristr($possible_label, '|'))
  2233. {
  2234. $names = $this->actions()->pipe_split($possible_label);
  2235. $result = ee()->freeform_form_model
  2236. ->select('form_id')
  2237. ->get(array('form_label' => $names));
  2238. //we only want results, not everything
  2239. if ($result !== FALSE)
  2240. {
  2241. $form_id = array();
  2242. foreach ($result as $row)
  2243. {
  2244. $form_id[] = $row['form_id'];
  2245. }
  2246. }
  2247. }
  2248. else
  2249. {
  2250. $possible_id = ee()->freeform_form_model
  2251. ->select('form_id')
  2252. ->get_row(array('form_label' => $possible_label));
  2253. if ($possible_id !== FALSE)
  2254. {
  2255. $form_id = $possible_id['form_id'];
  2256. }
  2257. }
  2258. }
  2259. // -------------------------------------
  2260. // store if good
  2261. // -------------------------------------
  2262. if ($form_id AND $form_id > 0)
  2263. {
  2264. $this->form_id = $form_id;
  2265. }
  2266. return $form_id;
  2267. }
  2268. //END form_id
  2269. // --------------------------------------------------------------------
  2270. /**
  2271. * entry_id - finds entry id the best it can
  2272. *
  2273. * @access private
  2274. * @return mixed boolean false if not found else id
  2275. */
  2276. private function entry_id ()
  2277. {
  2278. $form_id = $this->form_id();
  2279. if ( ! $form_id)
  2280. {
  2281. return FALSE;
  2282. }
  2283. if (isset($this->entry_id) AND $this->entry_id)
  2284. {
  2285. return $this->entry_id;
  2286. }
  2287. $entry_id = FALSE;
  2288. // -------------------------------------
  2289. // by direct param first
  2290. // -------------------------------------
  2291. if (isset(ee()->TMPL) AND is_object(ee()->TMPL))
  2292. {
  2293. $entry_id_param = ee()->TMPL->fetch_param('entry_id');
  2294. if ( $this->is_positive_intlike($entry_id_param) AND
  2295. $this->data->is_valid_entry_id($entry_id_param, $form_id))
  2296. {
  2297. $entry_id = $entry_id_param;
  2298. }
  2299. }
  2300. // -------------------------------------
  2301. // params id
  2302. // -------------------------------------
  2303. if ( ! $entry_id AND $this->param('entry_id'))
  2304. {
  2305. $entry_id_param = $this->param('entry_id');
  2306. if ( $this->is_positive_intlike($entry_id_param) AND
  2307. $this->data->is_valid_entry_id($entry_id_param, $form_id))
  2308. {
  2309. $entry_id = $entry_id_param;
  2310. }
  2311. }
  2312. // -------------------------------------
  2313. // get post id
  2314. // -------------------------------------
  2315. if ( ! $entry_id AND ee()->input->get_post('entry_id'))
  2316. {
  2317. $entry_id_param = ee()->input->get_post('entry_id');
  2318. if ( $this->is_positive_intlike($entry_id_param) AND
  2319. $this->data->is_valid_entry_id($entry_id_param, $form_id))
  2320. {
  2321. $entry_id = $entry_id_param;
  2322. }
  2323. }
  2324. // -------------------------------------
  2325. // store if good
  2326. // -------------------------------------
  2327. if ($entry_id AND $entry_id > 0)
  2328. {
  2329. $this->entry_id = $entry_id;
  2330. }
  2331. return $entry_id;
  2332. }
  2333. //END entry_id
  2334. // --------------------------------------------------------------------
  2335. /**
  2336. * param - gets stored paramaters
  2337. *
  2338. * @access private
  2339. * @param string $which which param needed
  2340. * @param string $type type of param
  2341. * @return bool $which was empty
  2342. */
  2343. private function param ( $which = '', $type = 'all' )
  2344. {
  2345. // ----------------------------------------
  2346. // Params set?
  2347. // ----------------------------------------
  2348. if ( count( $this->params ) == 0 )
  2349. {
  2350. ee()->load->model('freeform_param_model');
  2351. // ----------------------------------------
  2352. // Empty id?
  2353. // ----------------------------------------
  2354. $params_id = ee()->input->get_post('params_id', TRUE);
  2355. if ( ! $this->is_positive_intlike($params_id) )
  2356. {
  2357. return FALSE;
  2358. }
  2359. $this->params_id = $params_id;
  2360. // -------------------------------------
  2361. // pre-clean so cache can keep
  2362. // -------------------------------------
  2363. ee()->freeform_param_model->cleanup();
  2364. // ----------------------------------------
  2365. // Select from DB
  2366. // ----------------------------------------
  2367. $data = ee()->freeform_param_model->select('data')
  2368. ->get_row($this->params_id);
  2369. // ----------------------------------------
  2370. // Empty?
  2371. // ----------------------------------------
  2372. if ( ! $data )
  2373. {
  2374. return FALSE;
  2375. }
  2376. // ----------------------------------------
  2377. // Unserialize
  2378. // ----------------------------------------
  2379. $this->params = json_decode( $data['data'], TRUE );
  2380. $this->params = is_array($this->params) ? $this->params : array();
  2381. $this->params['set'] = TRUE;
  2382. }
  2383. //END if ( count( $this->params ) == 0 )
  2384. // ----------------------------------------
  2385. // Fetch from params array
  2386. // ----------------------------------------
  2387. if ( isset( $this->params[$which] ) )
  2388. {
  2389. $return = str_replace( "&#47;", "/", $this->params[$which] );
  2390. return $return;
  2391. }
  2392. // ----------------------------------------
  2393. // Fetch TMPL
  2394. // ----------------------------------------
  2395. if ( isset( ee()->TMPL ) AND
  2396. is_object(ee()->TMPL) AND
  2397. ee()->TMPL->fetch_param($which) )
  2398. {
  2399. return ee()->TMPL->fetch_param($which);
  2400. }
  2401. // ----------------------------------------
  2402. // Return (if which is blank, we are just getting data)
  2403. // else if we are looking for something that doesn't exist...
  2404. // ----------------------------------------
  2405. return ($which === '');
  2406. }
  2407. //End param
  2408. // --------------------------------------------------------------------
  2409. /**
  2410. * insert_params - adds multiple params to stored params
  2411. *
  2412. * @access private
  2413. * @param array $param sassociative array of params to send
  2414. * @return mixed insert id or false
  2415. */
  2416. private function insert_params ( $params = array() )
  2417. {
  2418. ee()->load->model('freeform_param_model');
  2419. if (empty($params) AND isset($this->params))
  2420. {
  2421. $params = $this->params;
  2422. }
  2423. return ee()->freeform_param_model->insert_params($params);
  2424. }
  2425. // End insert params
  2426. // --------------------------------------------------------------------
  2427. /**
  2428. * prep_url
  2429. *
  2430. * checks a url for {path} or url creation needs with https replacement
  2431. *
  2432. * @access private
  2433. * @param string url to be prepped
  2434. * @param bool replace http with https?
  2435. * @return string url prepped with https or not
  2436. */
  2437. private function prep_url ($url, $https = FALSE)
  2438. {
  2439. $return = trim($url);
  2440. $return = ($return !== '') ? $return : ee()->config->item('site_url');
  2441. if ( preg_match( "/".LD."\s*path=(.*?)".RD."/", $return, $match ) > 0 )
  2442. {
  2443. $return = ee()->functions->create_url( $match['1'] );
  2444. }
  2445. elseif ( ! preg_match('/^http[s]?:\/\//', $return) )
  2446. {
  2447. $return = ee()->functions->create_url( $return );
  2448. }
  2449. if ($https)
  2450. {
  2451. $return = preg_replace('/^http:\/\//', 'https://', $return);
  2452. }
  2453. return $return;
  2454. }
  2455. //end prep_url
  2456. // --------------------------------------------------------------------
  2457. /**
  2458. * nation ban check
  2459. *
  2460. * sessions built in nation ban check doesn't properly
  2461. * return a bool if show errors are off
  2462. * and we want ajax responses with this
  2463. *
  2464. * @access private
  2465. * @param bool show fatal errors instead of returning bool true
  2466. * @return bool is banned or now
  2467. */
  2468. private function nation_ban_check ($show_error = TRUE)
  2469. {
  2470. if ( ! $this->check_yes(ee()->config->item('require_ip_for_posting')) OR
  2471. ! $this->check_yes(ee()->config->item('ip2nation')) OR
  2472. ! ee()->db->table_exists('exp_ip2nation'))
  2473. {
  2474. return FALSE;
  2475. }
  2476. //2.5.2 has a different table and ipv6 support
  2477. if (APP_VER < '2.5.2')
  2478. {
  2479. ee()->db->select("country");
  2480. ee()->db->where('ip <', ip2long(ee()->input->ip_address()));
  2481. ee()->db->order_by('ip', 'desc');
  2482. $query = ee()->db->get('ip2nation', 1);
  2483. }
  2484. else
  2485. {
  2486. // all IPv4 go to IPv6 mapped
  2487. $addr = $this->EE->input->ip_address();
  2488. if (strpos($addr, ':') === FALSE AND
  2489. strpos($addr, '.') !== FALSE)
  2490. {
  2491. $addr = '::'.$addr;
  2492. }
  2493. $addr = inet_pton($addr);
  2494. $query = $this->EE->db
  2495. ->select('country')
  2496. ->where("ip_range_low <= '".$addr."'", '', FALSE)
  2497. ->where("ip_range_high >= '".$addr."'", '', FALSE)
  2498. ->order_by('ip_range_low', 'desc')
  2499. ->limit(1, 0)
  2500. ->get('ip2nation');
  2501. }
  2502. if ($query->num_rows() == 1)
  2503. {
  2504. $ip2_query = ee()->db->get_where(
  2505. 'ip2nation_countries',
  2506. array(
  2507. 'code' => $query->row('country'),
  2508. 'banned' => 'y'
  2509. )
  2510. );
  2511. if ($ip2_query->num_rows() > 0)
  2512. {
  2513. if ($show_error == TRUE)
  2514. {
  2515. return ee()->output->fatal_error(
  2516. ee()->config->item('ban_message'),
  2517. 0
  2518. );
  2519. }
  2520. else
  2521. {
  2522. return TRUE;
  2523. }
  2524. }
  2525. }
  2526. return FALSE;
  2527. }
  2528. //END nation_ban_check
  2529. // --------------------------------------------------------------------
  2530. /**
  2531. * Parse Numeric Array Param
  2532. *
  2533. * checks template param for item like 'not 1|2|3'
  2534. *
  2535. * @access private
  2536. * @param string name of param to parse
  2537. * @return mixed false if not set, array if set
  2538. */
  2539. private function parse_numeric_array_param ($name = '')
  2540. {
  2541. $return = array();
  2542. if (trim($name) == '')
  2543. {
  2544. return FALSE;
  2545. }
  2546. $name_id = ee()->TMPL->fetch_param($name);
  2547. if ($name_id == FALSE)
  2548. {
  2549. return FALSE;
  2550. }
  2551. $name_id = trim(strtolower($name_id));
  2552. $not = FALSE;
  2553. if (substr($name_id, 0, 3) == 'not')
  2554. {
  2555. $not = TRUE;
  2556. $name_id = preg_replace('/^not[\s]*/', '', $name_id);
  2557. }
  2558. $clean_ids = array();
  2559. if ($name_id !== '')
  2560. {
  2561. $name_id = str_replace(
  2562. 'CURRENT_USER',
  2563. ee()->session->userdata('member_id'),
  2564. $name_id
  2565. );
  2566. if (stristr($name_id, '|'))
  2567. {
  2568. $name_id = $this->actions()->pipe_split($name_id);
  2569. }
  2570. if ( ! is_array($name_id))
  2571. {
  2572. $name_id = array($name_id);
  2573. }
  2574. foreach ($name_id as $value)
  2575. {
  2576. $value = trim($value);
  2577. if ($this->is_positive_intlike($value))
  2578. {
  2579. $clean_ids[] = $value;
  2580. }
  2581. }
  2582. }
  2583. return array(
  2584. 'not' => $not,
  2585. 'ids' => $clean_ids
  2586. );
  2587. }
  2588. //END parse_numeric_array_param
  2589. // --------------------------------------------------------------------
  2590. /**
  2591. * Tag Prefix replace
  2592. *
  2593. * Takes a set of tags and removes unprefixed tags then removes the
  2594. * prefixes from the prefixed ones. Sending reverse true re-instates the
  2595. * unprefixed items
  2596. *
  2597. * @param string $prefix prefix for tags
  2598. * @param array $tags array of tags to look for prefixes with
  2599. * @param string $tagdata incoming tagdata to replace on
  2600. * @param boolean $reverse reverse the replacements?
  2601. * @return string tagdata with replacements
  2602. */
  2603. public function tag_prefix_replace ($prefix = '', $tags = array(),
  2604. $tagdata = '', $reverse = FALSE)
  2605. {
  2606. if ($prefix == '' OR ! is_array($tags) OR empty($tags))
  2607. {
  2608. return $tagdata;
  2609. }
  2610. //allowing ':' in a prefix
  2611. if (substr($prefix, -1, 1) !== ':')
  2612. {
  2613. $prefix = rtrim($prefix, '_') . '_';
  2614. }
  2615. $hash = '02be645684a54f45f08d0b1dbadf78e1a3a9f2ee';
  2616. $find = array();
  2617. $hash_replace = array();
  2618. $prefix_replace = array();
  2619. $length = count($tags);
  2620. foreach ($tags as $key => $item)
  2621. {
  2622. $nkey = $key + $length;
  2623. //if there is nothing prefixed, we don't want to do anything datastardly
  2624. if ( ! $reverse AND
  2625. strpos($tagdata, LD . $prefix . $item) === FALSE)
  2626. {
  2627. continue;
  2628. }
  2629. //this is terse, but it ensures that we
  2630. //find any an all tag pairs if they occur
  2631. $find[$key] = $item;
  2632. $find[$nkey] = T_SLASH . $item;
  2633. $hash_replace[$key] = $hash . $item;
  2634. $hash_replace[$nkey] = T_SLASH . $hash . $item;
  2635. $prefix_replace[$key] = $prefix . $item;
  2636. $prefix_replace[$nkey] = T_SLASH . $prefix . $item;
  2637. }
  2638. //prefix standard and replace prefixes
  2639. if ( ! $reverse)
  2640. {
  2641. foreach ($find as $key => $value)
  2642. {
  2643. $tagdata = preg_replace(
  2644. '/(?<![:_])\b(' . preg_quote($value, '/') . ')\b(?![:_])/ms',
  2645. $hash_replace[$key],
  2646. $tagdata
  2647. );
  2648. }
  2649. foreach ($prefix_replace as $key => $value)
  2650. {
  2651. $tagdata = preg_replace(
  2652. '/(?<![:_])\b(' . preg_quote($value, '/') . ')\b(?![:_])/ms',
  2653. $find[$key],
  2654. $tagdata
  2655. );
  2656. }
  2657. //$tagdata = str_replace($find, $hash_replace, $tagdata);
  2658. //$tagdata = str_replace($prefix_replace, $find, $tagdata);
  2659. }
  2660. //we are on the return, fix the hashed ones
  2661. else
  2662. {
  2663. //$tagdata = str_replace($hash_replace, $find, $tagdata);
  2664. foreach ($hash_replace as $key => $value)
  2665. {
  2666. $tagdata = preg_replace(
  2667. '/(?<![:_])\b(' . preg_quote($value, '/') . ')\b(?![:_])/ms',
  2668. $find[$key],
  2669. $tagdata
  2670. );
  2671. }
  2672. }
  2673. return $tagdata;
  2674. }
  2675. //END tag_prefix_replace
  2676. // --------------------------------------------------------------------
  2677. /**
  2678. * Checks first for an error block if present
  2679. *
  2680. * @access protected
  2681. * @param string $line error line
  2682. * @return string parsed html tagdata
  2683. */
  2684. protected function no_results_error ($line = '')
  2685. {
  2686. if ($line != '' AND
  2687. preg_match(
  2688. "/".LD."if " .preg_quote($this->lower_name).":error" .
  2689. RD."(.*?)".LD.preg_quote(T_SLASH, '/')."if".RD."/s",
  2690. ee()->TMPL->tagdata,
  2691. $match
  2692. )
  2693. )
  2694. {
  2695. $error_tag = $this->lower_name . "_error";
  2696. return ee()->TMPL->parse_variables(
  2697. $match[1],
  2698. array(array(
  2699. $error_tag => $line,
  2700. 'error_message' => lang($line)
  2701. ))
  2702. );
  2703. }
  2704. else if ( preg_match(
  2705. "/".LD."if " .preg_quote($this->lower_name).":no_results" .
  2706. RD."(.*?)".LD.preg_quote(T_SLASH, '/')."if".RD."/s",
  2707. ee()->TMPL->tagdata,
  2708. $match
  2709. )
  2710. )
  2711. {
  2712. return $match[1];
  2713. }
  2714. else
  2715. {
  2716. return ee()->TMPL->no_results();
  2717. }
  2718. }
  2719. //END no_results_error
  2720. // --------------------------------------------------------------------
  2721. /**
  2722. * Replaces CURRENT_USER in tag params
  2723. *
  2724. * @access protected
  2725. * @return null
  2726. */
  2727. protected function replace_current_user ()
  2728. {
  2729. if (isset(ee()->TMPL) AND is_object(ee()->TMPL))
  2730. {
  2731. foreach (ee()->TMPL->tagparams as $key => $value)
  2732. {
  2733. if (stristr($value, 'CURRENT_USER'))
  2734. {
  2735. ee()->TMPL->tagparams[$key] = preg_replace(
  2736. '/(?<![:_])\b(CURRENT_USER)\b(?![:_])/ms',
  2737. ee()->session->userdata('member_id'),
  2738. $value
  2739. );
  2740. }
  2741. }
  2742. }
  2743. }
  2744. //END replace_current_user
  2745. // --------------------------------------------------------------------
  2746. /**
  2747. * Replace all form fields tags in the {freeform:all_form_fields} loop
  2748. *
  2749. * @access protected
  2750. * @param string $tagdata incoming tagdata
  2751. * @param array $fields field_id => field_data array
  2752. * @param array $field_order order of field by field id (optional)
  2753. * @param array $field_input_data field input data (optional)
  2754. * @return string transformed output data
  2755. */
  2756. protected function replace_all_form_fields ($tagdata, $fields, $field_order = array(), $field_input_data = array())
  2757. {
  2758. // -------------------------------------
  2759. // all form fields loop
  2760. // -------------------------------------
  2761. // this can be used to build normal output
  2762. // or custom output for edit.
  2763. // -------------------------------------
  2764. if (preg_match_all(
  2765. '/' . LD . 'freeform:all_form_fields.*?' . RD .
  2766. '(.*?)' .
  2767. LD . '\/freeform:all_form_fields' . RD . '/ms',
  2768. $tagdata,
  2769. $matches,
  2770. PREG_SET_ORDER
  2771. ))
  2772. {
  2773. $all_field_replace_data = array();
  2774. $field_loop_ids = array_keys($fields);
  2775. // -------------------------------------
  2776. // order ids?
  2777. // -------------------------------------
  2778. if ( ! is_array($field_order) AND is_string($field_order))
  2779. {
  2780. $field_order = $this->actions()->pipe_split($field_order);
  2781. }
  2782. $order_ids = array();
  2783. if (is_array($field_order))
  2784. {
  2785. $order_ids = array_filter($field_order, array($this, 'is_positive_intlike'));
  2786. }
  2787. if ( ! empty($order_ids))
  2788. {
  2789. //this makes sure that any fields in 'fields' are in the
  2790. //order set as well. Will add missing at the end like this
  2791. $field_loop_ids = array_merge(
  2792. $order_ids,
  2793. array_diff($field_loop_ids, $order_ids)
  2794. );
  2795. }
  2796. //build variables
  2797. ee()->load->model('freeform_form_model');
  2798. foreach ($field_loop_ids as $field_id)
  2799. {
  2800. if ( ! isset($fields[$field_id]))
  2801. {
  2802. continue;
  2803. }
  2804. $field_data = $fields[$field_id];
  2805. // -------------------------------------
  2806. // get previous data
  2807. // -------------------------------------
  2808. $col_name = ee()->freeform_form_model->form_field_prefix . $field_id;
  2809. $display_field_data = '';
  2810. if (isset($field_input_data[$field_data['field_name']]))
  2811. {
  2812. $display_field_data = $field_input_data[$field_data['field_name']];
  2813. }
  2814. else if (isset($field_input_data[$col_name]))
  2815. {
  2816. $display_field_data = $field_input_data[$col_name];
  2817. }
  2818. // -------------------------------------
  2819. // load field data
  2820. // -------------------------------------
  2821. $all_field_replace_data[] = array(
  2822. 'freeform:field_id' => $field_id,
  2823. 'freeform:field_data' => $display_field_data,
  2824. 'freeform:field_name' => $field_data['field_name'],
  2825. 'freeform:field_type' => $field_data['field_type'],
  2826. 'freeform:field_label' => LD . 'freeform:label:' .
  2827. $field_data['field_name'] . RD,
  2828. 'freeform:field_output' => LD . 'freeform:field:' .
  2829. $field_data['field_name'] . RD
  2830. );
  2831. }
  2832. foreach ($matches as $match)
  2833. {
  2834. $tagdata_replace = ee()->TMPL->parse_variables(
  2835. $match[1],
  2836. $all_field_replace_data
  2837. );
  2838. $tagdata = str_replace($match[0], $tagdata_replace, $tagdata);
  2839. }
  2840. }
  2841. return $tagdata;
  2842. }
  2843. //END replace_all_form_fields
  2844. // --------------------------------------------------------------------
  2845. /**
  2846. * Parse Status Tags
  2847. *
  2848. * Parses:
  2849. * {freeform:statuses status="not closed|open"}
  2850. * {status_name} {status_value}
  2851. * {/freeform:statuses}
  2852. *
  2853. * @access protected
  2854. * @param string $tagdata tagdata to be parsed
  2855. * @return string adjusted tagdata with status pairs parsed
  2856. */
  2857. protected function parse_status_tags ($tagdata)
  2858. {
  2859. $matches = array();
  2860. $tag = 'freeform:statuses';
  2861. $statuses = $this->data->get_form_statuses();
  2862. preg_match_all(
  2863. '/' . LD . $tag . '.*?' . RD .
  2864. '(.*?)' .
  2865. LD . '\/' . $tag . RD . '/ms',
  2866. $tagdata,
  2867. $matches,
  2868. PREG_SET_ORDER
  2869. );
  2870. if ($matches AND
  2871. isset($matches[0]) AND
  2872. ! empty($matches[0]))
  2873. {
  2874. foreach ($matches as $key => $value)
  2875. {
  2876. $replace_with = '';
  2877. $tdata = $value[1];
  2878. //no need for an if. if we are here, this matched before
  2879. preg_match(
  2880. '/' . LD . $tag . '.*?' . RD . '/',
  2881. $value[0],
  2882. $sub_matches
  2883. );
  2884. // Checking for variables/tags embedded within tags
  2885. // {exp:channel:entries channel="{master_channel_name}"}
  2886. if (stristr(substr($sub_matches[0], 1), LD) !== FALSE)
  2887. {
  2888. $sub_matches[0] = ee()->functions->full_tag(
  2889. $sub_matches[0],
  2890. $value[0]
  2891. );
  2892. // -------------------------------------
  2893. // fix local tagdata
  2894. // -------------------------------------
  2895. preg_match(
  2896. '/' . preg_quote($sub_matches[0]) .
  2897. '(.*?)' .
  2898. LD . '\/' . $tag . RD . '/ms',
  2899. $value[0],
  2900. $tdata_matches
  2901. );
  2902. if (isset($tdata_matches[1]))
  2903. {
  2904. $tdata = $tdata_matches[1];
  2905. }
  2906. }
  2907. $tag_params = ee()->functions->assign_parameters(
  2908. $sub_matches[0]
  2909. );
  2910. $out_status = $statuses;
  2911. if (isset($tag_params['status']))
  2912. {
  2913. $names = strtolower($tag_params['status']);
  2914. $not = FALSE;
  2915. if (preg_match("/^not\s+/s", $names))
  2916. {
  2917. $names = preg_replace('/^not\s+/s', '', $names);
  2918. $not = TRUE;
  2919. }
  2920. $names = preg_split(
  2921. '/\|/s',
  2922. trim($names),
  2923. -1,
  2924. PREG_SPLIT_NO_EMPTY
  2925. );
  2926. foreach ($out_status as $status_name => $status_value)
  2927. {
  2928. if (in_array(strtolower($status_name), $names) == $not)
  2929. {
  2930. unset($out_status[$status_name]);
  2931. }
  2932. }
  2933. }
  2934. foreach ($out_status as $out_name => $out_value)
  2935. {
  2936. $replace_with .= str_replace(
  2937. array(LD . 'status_name' . RD, LD . 'status_label' . RD),
  2938. array($out_name, $out_value),
  2939. $tdata
  2940. );
  2941. }
  2942. //remove
  2943. $tagdata = str_replace($value[0], $replace_with, $tagdata);
  2944. }
  2945. }
  2946. return $tagdata;
  2947. }
  2948. //END parse_status_tags
  2949. }
  2950. // END CLASS Freeform