PageRenderTime 31ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/application/helpers/customforms.php

https://github.com/yamamoto123/Ushahidi_Web
PHP | 428 lines | 271 code | 53 blank | 104 comment | 45 complexity | ecb5a36a4be2f4a138621d5c611ad719 MD5 | raw file
  1. <?php
  2. /**
  3. * Custom Forms Helper
  4. * Functions to pull in the custom form fields and display them
  5. *
  6. * @package Custom Forms
  7. * @author The Konpa Group - http://konpagroup.com
  8. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License (LGPL)
  9. */
  10. class customforms_Core {
  11. /**
  12. * Retrieve Custom Forms
  13. * @return ORM_Iterator
  14. */
  15. public static function get_custom_forms()
  16. {
  17. $custom_forms = ORM::factory('form')->find_all();
  18. return $custom_forms;
  19. }
  20. /**
  21. * Retrieve Custom Form Fields
  22. * @param bool|int $incident_id The unique incident_id of the original report
  23. * @param int $form_id The unique form_id. Uses default form (1), if none selected
  24. * @param bool $field_names_only Whether or not to include just fields names, or field names + data
  25. * @param bool $data_only Whether or not to include just data
  26. * @param string $action If this is being used to grab fields for submit or view of data
  27. */
  28. public static function get_custom_form_fields($incident_id = FALSE, $form_id = 1, $data_only = FALSE, $action = "submit")
  29. {
  30. $fields_array = array();
  31. if (!$form_id)
  32. $form_id = 1;
  33. // Validation
  34. if (!Form_Model::is_valid_form($form_id))
  35. {
  36. return $fields_array;
  37. }
  38. // Database table prefix
  39. $table_prefix = Kohana::config('database.default.table_prefix');
  40. //NOTE will probably need to add a user_level variable for non-web based requests
  41. $user_level = self::get_user_max_auth();
  42. // Get the predicates for the public state
  43. $public_state = ($action == "view") ? '<='.$user_level : ' <= '.$user_level;
  44. // Query to fetch the form fields and their responses
  45. $sql = "SELECT ff.*, '' AS form_response FROM ".$table_prefix."form_field ff WHERE 1=1 ";
  46. // Check if the provided incident exists
  47. if (Incident_Model::is_valid_incident($incident_id))
  48. {
  49. // Overwrite the previous query
  50. $sql = "SELECT ff.*, fr.form_response "
  51. . "FROM ".$table_prefix."form_field ff "
  52. . "RIGHT JOIN ".$table_prefix."form_response fr ON (fr.form_field_id = ff.id) "
  53. . "WHERE fr.incident_id = ".$incident_id." ";
  54. }
  55. $sql .= "AND ff.form_id = ".$form_id." "
  56. . "AND ff.field_ispublic_visible ".$public_state." "
  57. . "ORDER BY ff.field_position ASC";
  58. // Execute the SQL to fetch the custom form fields
  59. $form_fields = Database::instance()->query($sql);
  60. foreach ($form_fields as $custom_formfield)
  61. {
  62. if ($data_only)
  63. {
  64. // Return Data Only
  65. $fields_array[$custom_formfield->id] = $custom_formfield->form_response;
  66. }
  67. else
  68. {
  69. // Return Field Structure
  70. $fields_array[$custom_formfield->id] = array(
  71. 'field_id' => $custom_formfield->id,
  72. 'field_name' => $custom_formfield->field_name,
  73. 'field_type' => $custom_formfield->field_type,
  74. 'field_default' => $custom_formfield->field_default,
  75. 'field_required' => $custom_formfield->field_required,
  76. 'field_maxlength' => $custom_formfield->field_maxlength,
  77. 'field_height' => $custom_formfield->field_height,
  78. 'field_width' => $custom_formfield->field_width,
  79. 'field_isdate' => $custom_formfield->field_isdate,
  80. 'field_ispublic_visible' => $custom_formfield->field_ispublic_visible,
  81. 'field_ispublic_submit' => $custom_formfield->field_ispublic_submit,
  82. 'field_response' => $custom_formfield->form_response
  83. );
  84. }
  85. }
  86. // Garbage collection
  87. unset ($form_fields);
  88. // Return
  89. return $fields_array;
  90. }
  91. /**
  92. * Returns a list of the field names and values for a given userlevel
  93. *
  94. * @param int $id incident id
  95. * @param int $user_level the user's role level
  96. * @return Result
  97. */
  98. public static function view_everything($id, $user_level)
  99. {
  100. $db = new Database();
  101. $db->select('form_response.form_response', 'form_field.field_name');
  102. $db->from('form_response');
  103. $db->join('form_field','form_response.form_field_id','form_field.id');
  104. $db->where(array('form_response.incident_id'=>$id,'form_field.field_ispublic_visible <='=>$user_level));
  105. $db->orderby('form_field.field_position');
  106. return $db->get();
  107. }
  108. /**
  109. * Returns the user's maximum role id number
  110. *
  111. * @param array $user the current user object
  112. * @return int
  113. */
  114. public static function get_user_max_auth(){
  115. if( ! isset($_SESSION['auth_user']))
  116. return 0;
  117. $user = new User_Model($_SESSION['auth_user']->id);
  118. if ($user->loaded == TRUE)
  119. {
  120. $r = array();
  121. foreach($user->roles as $role)
  122. {
  123. array_push($r,$role->access_level);
  124. }
  125. return max($r);
  126. }
  127. return 0;
  128. }
  129. /**
  130. * Validate Custom Form Fields
  131. * @param array $custom_fields Array
  132. * XXX This whole function is being done backwards
  133. * Need to pull the list of custom form fields first
  134. * Then look through them to see if they're set, not the other way around.
  135. */
  136. public static function validate_custom_form_fields(&$post)
  137. {
  138. $errors = array();
  139. $custom_fields = array();
  140. if (!isset($post->custom_field))
  141. return;
  142. /* XXX Checkboxes hackery
  143. Checkboxes are submitted in the post as custom_field[field_id-boxnum]
  144. This foreach loop consolidates them into one variable separated by commas.
  145. If no checkboxes are selected then the custom_field[] for that variable is not sent
  146. To get around that the view sets a hidden custom_field[field_id-BLANKHACK] field that
  147. ensures the checkbox custom_field is there to be tested.
  148. */
  149. foreach ($post->custom_field as $field_id => $field_response)
  150. {
  151. $split = explode("-", $field_id);
  152. if (isset($split[1]))
  153. {
  154. // The view sets a hidden field for blankhack
  155. if ($split[1] == 'BLANKHACK')
  156. {
  157. if(!isset($custom_fields[$split[0]]))
  158. {
  159. // then no checkboxes were checked
  160. $custom_fields[$split[0]] = '';
  161. }
  162. // E.Kala - Removed the else {} block; either way continue is still invoked
  163. continue;
  164. }
  165. if (isset($custom_fields[$split[0]]))
  166. {
  167. $custom_fields[$split[0]] .= ",$field_response";
  168. }
  169. else
  170. {
  171. $custom_fields[$split[0]] = $field_response;
  172. }
  173. }
  174. else
  175. {
  176. $custom_fields[$split[0]] = $field_response;
  177. }
  178. }
  179. $post->custom_field = $custom_fields;
  180. // Kohana::log('debug', Kohana::debug($custom_fields));
  181. foreach ($post->custom_field as $field_id => $field_response)
  182. {
  183. $field_param = ORM::factory('form_field',$field_id);
  184. $custom_name = $field_param->field_name;
  185. // Validate that this custom field already exists
  186. if ( ! $field_param->loaded)
  187. {
  188. // Populate the error field
  189. $errors[$custom_name] = "The $custom_name field does not exist";
  190. return $errors;
  191. }
  192. $max_auth = self::get_user_max_auth();
  193. if ($field_param->field_ispublic_submit > $max_auth)
  194. {
  195. // Populate the error field
  196. $errors[$custom_name] = "The $custom_name field cannot be edited by your account";
  197. return $errors;
  198. }
  199. // Validate that the field is required
  200. if ( $field_param->field_required == 1 AND $field_response == "")
  201. {
  202. $errors[$custom_name] = "The $custom_name field is required";
  203. return $errors;
  204. }
  205. // Grab the custom field options for this field
  206. $field_options = self::get_custom_field_options($field_id);
  207. // Validate Custom fields for text boxes
  208. if ($field_param->field_type == 1 AND isset($field_options) AND $field_response != '')
  209. {
  210. foreach ($field_options as $option => $value)
  211. {
  212. if ($option == 'field_datatype')
  213. {
  214. if ($value == 'email' AND !valid::email($field_response))
  215. {
  216. $errors[$custom_name] = "The $custom_name field requires a valid email address";
  217. }
  218. if ($value == 'phonenumber' AND !valid::phone($field_response))
  219. {
  220. $errors[$custom_name] = "The $custom_name field requires a valid email address";
  221. }
  222. if ($value == 'numeric' AND !valid::numeric($field_response))
  223. {
  224. $errors[$custom_name] = "The $custom_name field must be numeric";
  225. }
  226. }
  227. }
  228. }
  229. // Validate for date
  230. if ($field_param->field_type == 3 AND $field_response != "")
  231. {
  232. $field_default = $field_param->field_default;
  233. if ( ! valid::date_mmddyyyy($field_response))
  234. {
  235. $errors[$custom_name] = "The $custom_name field is not a valid date (MM/DD/YYYY)";
  236. }
  237. }
  238. // Validate multi-value boxes only have acceptable values
  239. if ($field_param->field_type >= 5 AND $field_param->field_type <=7)
  240. {
  241. $defaults = explode('::',$field_param->field_default);
  242. $options = array();
  243. if (preg_match("/[0-9]+-[0-9]+/",$defaults[0]) AND count($defaults) == 1)
  244. {
  245. $dashsplit = explode('-',$defaults[0]);
  246. $start = $dashsplit[0];
  247. $end = $dashsplit[1];
  248. for($i = $start; $i <= $end; $i++)
  249. {
  250. array_push($options,$i);
  251. }
  252. }
  253. else
  254. {
  255. $options = explode(',',$defaults[0]);
  256. }
  257. $responses = explode(',',$field_response);
  258. foreach ($responses as $response)
  259. {
  260. if ( ! in_array($response, $options) AND $response != '')
  261. {
  262. $errors[$custom_name] = "The $custom_name field does not include $response as an option";
  263. }
  264. }
  265. }
  266. // Validate that a required checkbox is checked
  267. if ($field_param->field_type == 6 AND $field_response == 'BLANKHACK' AND $field_param->field_required == 1)
  268. {
  269. $errors[$custom_name] = "The $custom_name field is required";
  270. }
  271. }
  272. return $errors;
  273. }
  274. /**
  275. * Generate list of currently created Form Fields for the admin interface
  276. * @param int $form_id The id no. of the form
  277. * @return string
  278. */
  279. public static function get_current_fields($form_id = 0)
  280. {
  281. $form_fields = "<form action=\"\">";
  282. $form = array();
  283. $form['custom_field'] = self::get_custom_form_fields('',$form_id, true);
  284. $form['id'] = $form_id;
  285. $custom_forms = new View('reports_submit_custom_forms');
  286. $disp_custom_fields = self::get_custom_form_fields('', $form_id,false);
  287. $custom_forms->disp_custom_fields = $disp_custom_fields;
  288. $custom_forms->form = $form;
  289. $custom_forms->editor = true;
  290. $form_fields.= $custom_forms->render();
  291. $form_fields .= "</form>";
  292. return $form_fields;
  293. }
  294. /**
  295. * Generates the html that's passed back in the json switch_Action form switcher
  296. * @param int $incident_id The Incident Id
  297. * @param int $form_id Form Id
  298. * @param int $public_visible If this form should be publicly visible
  299. * @param int $pubilc_submit If this form is allowed to be submitted by anyone on the internets.
  300. * @return string
  301. */
  302. public static function switcheroo($incident_id = '', $form_id = '')
  303. {
  304. $form_fields = '';
  305. $fields_array = self::get_custom_form_fields($incident_id, $form_id, TRUE);
  306. $form = array();
  307. $form['custom_field'] = self::get_custom_form_fields($incident_id,$form_id, TRUE);
  308. $form['id'] = $form_id;
  309. $custom_forms = new View('reports_submit_custom_forms');
  310. $disp_custom_fields = self::get_custom_form_fields($incident_id,$form_id, FALSE);
  311. $custom_forms->disp_custom_fields = $disp_custom_fields;
  312. $custom_forms->form = $form;
  313. $form_fields.= $custom_forms->render();
  314. return $form_fields;
  315. }
  316. /**
  317. * Generates an array of fields that an admin can see but can't edit
  318. *
  319. * @param int $form_id The form id
  320. * @return array
  321. */
  322. public static function get_edit_mismatch($form_id = 0)
  323. {
  324. $user_level = self::get_user_max_auth();
  325. $public_state = array('field_ispublic_submit >'=>$user_level, 'field_ispublic_visible <='=>$user_level);
  326. $custom_form = ORM::factory('form', $form_id)->where($public_state)->orderby('field_position','asc');
  327. $mismatches = array();
  328. foreach ($custom_form->form_field as $custom_formfield)
  329. {
  330. $mismatches[$custom_formfield->id] = 1;
  331. }
  332. return $mismatches;
  333. }
  334. /**
  335. * Checks if a field type has multiple values
  336. *
  337. * @param array $field
  338. * @return bool
  339. */
  340. public static function field_is_multi_value($field){
  341. $is_multi = FALSE;
  342. switch ($field["field_type"])
  343. {
  344. case 5: //Radio
  345. $is_multi = TRUE;
  346. break;
  347. case 6: // Checkbox
  348. $is_multi = TRUE;
  349. break;
  350. case 7: // Dropdown
  351. $is_multi = TRUE;
  352. break;
  353. default:
  354. $is_multi = FALSE;
  355. }
  356. return $is_multi;
  357. }
  358. /**
  359. * Returns the form field options associated with this form field
  360. *
  361. * @param int $field_id The Field Id
  362. * @return array
  363. */
  364. public static function get_custom_field_options($field_id)
  365. {
  366. //XXX should be able to use the model for this, right?
  367. $field_options = array();
  368. $field_option_query = ORM::factory('form_field_option')->where('form_field_id',$field_id)->find_all();
  369. foreach($field_option_query as $option)
  370. {
  371. $field_options[$option->option_name] = $option->option_value;
  372. }
  373. return $field_options;
  374. }
  375. }