1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
15:
16: 17: 18: 19: 20:
21: class PifaAjaxHandler {
22:
23: 24: 25: 26: 27:
28: const GET_FIELD_FORM = 'pifa_get_field_form';
29:
30: 31: 32: 33: 34:
35: const POST_FIELD_FORM = 'pifa_post_field_form';
36:
37: 38: 39: 40: 41:
42: const REORDER_FIELDS = 'pifa_reorder_fields';
43:
44: 45: 46: 47: 48:
49: const EXPORT_DATA = 'pifa_export_data';
50:
51: 52: 53: 54: 55:
56: const EXPORT_FORM = 'pifa_export_form';
57:
58: 59: 60: 61: 62:
63: const IMPORT_FORM = 'pifa_import_form';
64:
65: 66: 67: 68: 69:
70: const GET_FILE = 'pifa_get_file';
71:
72: 73: 74: 75: 76:
77: const DELETE_FIELD = 'pifa_delete_field';
78:
79: 80: 81: 82: 83:
84: const GET_OPTION_ROW = 'pifa_get_option_row';
85:
86: 87: 88: 89:
90: function dispatch($action) {
91: global $area;
92:
93:
94: if (!cRegistry::getPerm()->have_perm_area_action($area, $action)) {
95: $msg = Pifa::i18n('NO_PERMISSIONS');
96: throw new PifaIllegalStateException($msg);
97: }
98:
99: switch ($action) {
100:
101: case self::GET_FIELD_FORM:
102:
103: $idform = cSecurity::toInteger($_GET['idform']);
104: $idfield = cSecurity::toInteger($_GET['idfield']);
105: $fieldType = cSecurity::toInteger($_GET['field_type']);
106: $this->_getFieldForm($idform, $idfield, $fieldType);
107: break;
108:
109: case self::POST_FIELD_FORM:
110:
111: $idform = cSecurity::toInteger($_POST['idform']);
112: $idfield = cSecurity::toInteger($_POST['idfield']);
113:
114: $this->_postFieldForm($idform, $idfield);
115: break;
116:
117: case self::DELETE_FIELD:
118: $idfield = cSecurity::toInteger($_GET['idfield']);
119: $this->_deleteField($idfield);
120: break;
121:
122: case self::REORDER_FIELDS:
123: $idform = cSecurity::toInteger($_POST['idform']);
124: $idfields = implode(',', array_map('cSecurity::toInteger', explode(',', $_POST['idfields'])));
125: $this->_reorderFields($idform, $idfields);
126: break;
127:
128: case self::EXPORT_DATA:
129: $idform = cSecurity::toInteger($_GET['idform']);
130: $this->_exportData($idform);
131: break;
132:
133: case self::EXPORT_FORM:
134: $idform = cSecurity::toInteger($_POST['idform']);
135: $withData = 'on' === $_POST['with_data'];
136: $this->_exportForm($idform, $withData);
137: break;
138:
139: case self::IMPORT_FORM:
140: $xml = $_FILES['xml'];
141: $this->_importForm($xml);
142: break;
143:
144: case self::GET_FILE:
145: $name = cSecurity::toString($_GET['name']);
146: $file = cSecurity::toString($_GET['file']);
147: $this->_getFile($name, $file);
148: break;
149:
150: case self::GET_OPTION_ROW:
151: $index = cSecurity::toInteger($_GET['index']);
152: $this->_getOptionRow($index);
153: break;
154:
155: default:
156: $msg = Pifa::i18n('UNKNOWN_ACTION');
157:
158: throw new PifaException($msg);
159: }
160: }
161:
162: 163: 164: 165: 166: 167: 168: 169:
170: private function _getFieldForm($idform, $idfield, $fieldType) {
171: $cfg = cRegistry::getConfig();
172:
173:
174: if (0 < $idfield) {
175:
176: $field = new PifaField();
177: $field->loadByPrimaryKey($idfield);
178: } elseif (0 < $fieldType) {
179:
180: $field = new PifaField();
181: $field->loadByRecordSet(array(
182: 'field_type' => $fieldType
183: ));
184: } else {
185:
186:
187: $msg = Pifa::i18n('FORM_CREATE_ERROR');
188: throw new PifaException($msg);
189: }
190:
191:
192: $optionClasses = Pifa::getExtensionClasses('PifaExternalOptionsDatasourceInterface');
193: array_unshift($optionClasses, array(
194: 'value' => '',
195: 'label' => Pifa::i18n('none')
196: ));
197:
198:
199: $tpl = cSmartyBackend::getInstance(true);
200:
201:
202: $tpl->assign('trans', array(
203: 'idfield' => Pifa::i18n('ID'),
204: 'fieldRank' => Pifa::i18n('RANK'),
205: 'fieldType' => Pifa::i18n('FIELD_TYPE'),
206: 'columnName' => Pifa::i18n('COLUMN_NAME'),
207: 'label' => Pifa::i18n('LABEL'),
208: 'displayLabel' => Pifa::i18n('DISPLAY_LABEL'),
209: 'defaultValue' => Pifa::i18n('DEFAULT_VALUE'),
210: 'helpText' => Pifa::i18n('HELP_TEXT'),
211: 'rule' => Pifa::i18n('VALIDATION_RULE'),
212: 'errorMessage' => Pifa::i18n('ERROR_MESSAGE'),
213: 'database' => Pifa::i18n('DATABASE'),
214: 'options' => Pifa::i18n('OPTIONS'),
215: 'general' => Pifa::i18n('GENERAL'),
216: 'obligatory' => Pifa::i18n('OBLIGATORY'),
217: 'value' => Pifa::i18n('VALUE'),
218: 'addOption' => Pifa::i18n('ADD_OPTION'),
219: 'submitValue' => Pifa::i18n('SAVE'),
220: 'styling' => Pifa::i18n('STYLING'),
221: 'cssClass' => Pifa::i18n('CSS_CLASS'),
222: 'uri' => Pifa::i18n('URI'),
223: 'externalOptionsDatasource' => Pifa::i18n('EXTERNAL_OPTIONS_DATASOURCE')
224: ));
225:
226:
227: if (cRegistry::getPerm()->have_perm_area_action('form_ajax', self::POST_FIELD_FORM)) {
228: $tpl->assign('contenido', cRegistry::getBackendSessionId());
229: $tpl->assign('action', self::POST_FIELD_FORM);
230: $tpl->assign('idform', $idform);
231: }
232:
233:
234: $tpl->assign('field', $field);
235:
236:
237: $tpl->assign('cssClasses', explode(',', getEffectiveSetting('pifa', 'field-css-classes', 'half-row,full-row,line-bottom,line-top')));
238:
239:
240: $tpl->assign('optionClasses', $optionClasses);
241:
242:
243: if (cRegistry::getPerm()->have_perm_area_action('form_ajax', self::POST_FIELD_FORM) && cRegistry::getPerm()->have_perm_area_action('form_ajax', self::GET_OPTION_ROW)) {
244: $tpl->assign('hrefAddOption', 'main.php?' . implode('&', array(
245: 'area=form_ajax',
246: 'frame=4',
247: 'contenido=' . cRegistry::getBackendSessionId(),
248: 'action=' . PifaAjaxHandler::GET_OPTION_ROW
249: )));
250: }
251:
252:
253: $tpl->assign('partialOptionRow', $cfg['templates']['pifa_ajax_option_row']);
254:
255: $tpl->display($cfg['templates']['pifa_ajax_field_form']);
256: }
257:
258: 259: 260: 261: 262: 263: 264:
265: private function _postFieldForm($idform, $idfield) {
266: $string_cast_deep = create_function('$value', '
267: $value = cSecurity::unescapeDB($value);
268: $value = cSecurity::toString($value);
269: $value = trim($value);
270: // replace comma by comma entity
271: $value = str_replace(\',\', \',\', $value);
272: return $value;
273: ');
274:
275: global $area;
276: $cfg = cRegistry::getConfig();
277:
278:
279: if (0 < $idfield) {
280:
281: $pifaField = new PifaField($idfield);
282: if (!$pifaField->isLoaded()) {
283: $msg = Pifa::i18n('FIELD_LOAD_ERROR');
284: throw new PifaException($msg);
285: }
286: $isFieldCreated = false;
287: } else {
288:
289: $fieldType = $_POST['field_type'];
290: $fieldType = cSecurity::toInteger($fieldType);
291:
292: $collection = new PifaFieldCollection();
293: $pifaField = $collection->createNewItem(array(
294: 'idform' => $idform,
295: 'field_type' => $fieldType
296: ));
297: $isFieldCreated = true;
298: }
299:
300:
301:
302: $oldColumnName = $pifaField->get('column_name');
303:
304:
305: $fieldRank = $_POST['field_rank'];
306: $fieldRank = cSecurity::toInteger($fieldRank);
307: if ($fieldRank !== $pifaField->get('field_rank')) {
308: $pifaField->set('field_rank', $fieldRank);
309: }
310:
311: 312: 313: 314: 315: 316: 317: 318:
319:
320:
321:
322: if ($pifaField->showField('column_name')) {
323: $columnName = $_POST['column_name'];
324: $columnName = cSecurity::unescapeDB($columnName);
325: $columnName = cSecurity::toString($columnName);
326: $columnName = trim($columnName);
327: $columnName = strtolower($columnName);
328:
329:
330: $columnName = preg_replace('/[^a-z0-9_]/', '_', $columnName);
331: $columnName = substr($columnName, 0, 64);
332: if ($columnName !== $pifaField->get('column_name')) {
333: $pifaField->set('column_name', $columnName);
334: }
335: }
336:
337: if ($pifaField->showField('label')) {
338: $label = $_POST['label'];
339: $label = cSecurity::unescapeDB($label);
340: $label = cSecurity::toString($label);
341: $label = trim($label);
342: $label = substr($label, 0, 1023);
343: if ($label !== $pifaField->get('label')) {
344: $pifaField->set('label', $label);
345: }
346: }
347:
348: if ($pifaField->showField('display_label')) {
349: $displayLabel = $_POST['display_label'];
350: $displayLabel = cSecurity::unescapeDB($displayLabel);
351: $displayLabel = cSecurity::toString($displayLabel);
352: $displayLabel = trim($displayLabel);
353: $displayLabel = 'on' === $displayLabel? 1 : 0;
354: if ($displayLabel !== $pifaField->get('display_label')) {
355: $pifaField->set('display_label', $displayLabel);
356: }
357: }
358:
359: if ($pifaField->showField('uri')) {
360: $uri = $_POST['uri'];
361: $uri = cSecurity::unescapeDB($uri);
362: $uri = cSecurity::toString($uri);
363: $uri = trim($uri);
364: $uri = substr($uri, 0, 1023);
365: if ($uri !== $pifaField->get('uri')) {
366: $pifaField->set('uri', $uri);
367: }
368: }
369:
370: if ($pifaField->showField('default_value')) {
371: $defaultValue = $_POST['default_value'];
372: $defaultValue = cSecurity::unescapeDB($defaultValue);
373: $defaultValue = cSecurity::toString($defaultValue);
374: $defaultValue = trim($defaultValue);
375: $defaultValue = substr($defaultValue, 0, 1023);
376: if ($defaultValue !== $pifaField->get('default_value')) {
377: $pifaField->set('default_value', $defaultValue);
378: }
379: }
380:
381: if ($pifaField->showField('option_labels')) {
382: if (array_key_exists('option_labels', $_POST) && is_array($_POST['option_labels'])) {
383: $optionLabels = implode(',', array_map($string_cast_deep, $_POST['option_labels']));
384: $optionLabels = substr($optionLabels, 0, 1023);
385: }
386: if ($optionLabels !== $pifaField->get('option_labels')) {
387: $pifaField->set('option_labels', $optionLabels);
388: }
389: }
390:
391: if ($pifaField->showField('option_values')) {
392: if (array_key_exists('option_values', $_POST) && is_array($_POST['option_values'])) {
393: $optionValues = implode(',', array_map($string_cast_deep, $_POST['option_values']));
394: $optionValues = substr($optionValues, 0, 1023);
395: }
396: if ($optionValues !== $pifaField->get('option_values')) {
397: $pifaField->set('option_values', $optionValues);
398: }
399: }
400:
401: if ($pifaField->showField('help_text')) {
402: $helpText = $_POST['help_text'];
403: $helpText = cSecurity::unescapeDB($helpText);
404: $helpText = cSecurity::toString($helpText);
405: $helpText = trim($helpText);
406: if ($helpText !== $pifaField->get('help_text')) {
407: $pifaField->set('help_text', $helpText);
408: }
409: }
410:
411: if ($pifaField->showField('obligatory')) {
412: $obligatory = $_POST['obligatory'];
413: $obligatory = cSecurity::unescapeDB($obligatory);
414: $obligatory = cSecurity::toString($obligatory);
415: $obligatory = trim($obligatory);
416: $obligatory = 'on' === $obligatory? 1 : 0;
417: if ($obligatory !== $pifaField->get('obligatory')) {
418: $pifaField->set('obligatory', $obligatory);
419: }
420: }
421:
422: if ($pifaField->showField('rule')) {
423: $rule = $_POST['rule'];
424: $rule = cSecurity::unescapeDB($rule);
425: $rule = cSecurity::toString($rule);
426: $rule = trim($rule);
427: $rule = substr($rule, 0, 1023);
428:
429: if (0 === strlen($rule)) {
430: $pifaField->set('rule', $rule);
431: } else if (false === @preg_match($rule, 'And always remember: the world is an orange!')) {
432:
433: } else if ($rule === $pifaField->get('rule')) {
434:
435: } else {
436: $pifaField->set('rule', $rule);
437: }
438: }
439:
440: if ($pifaField->showField('error_message')) {
441: $errorMessage = $_POST['error_message'];
442: $errorMessage = cSecurity::unescapeDB($errorMessage);
443: $errorMessage = cSecurity::toString($errorMessage);
444: $errorMessage = trim($errorMessage);
445: $errorMessage = substr($errorMessage, 0, 1023);
446: if ($errorMessage !== $pifaField->get('error_message')) {
447: $pifaField->set('error_message', $errorMessage);
448: }
449: }
450:
451: if ($pifaField->showField('css_class') && array_key_exists('css_class', $_POST) && is_array($_POST['css_class'])) {
452: $cssClass = implode(',', array_map($string_cast_deep, $_POST['css_class']));
453: $cssClass = substr($cssClass, 0, 1023);
454: if ($cssClass !== $pifaField->get('css_class')) {
455: $pifaField->set('css_class', $cssClass);
456: }
457: }
458:
459: if ($pifaField->showField('option_class')) {
460: $optionClass = $_POST['option_class'];
461: $optionClass = cSecurity::unescapeDB($optionClass);
462: $optionClass = cSecurity::toString($optionClass);
463: $optionClass = trim($optionClass);
464: $optionClass = substr($optionClass, 0, 1023);
465: if ($optionClass !== $pifaField->get('option_class')) {
466: $pifaField->set('option_class', $optionClass);
467: }
468: }
469:
470:
471: $pifaForm = new PifaForm($idform);
472: try {
473: $pifaForm->storeColumn($pifaField, $oldColumnName);
474: } catch (PifaException $e) {
475:
476: if ($isFieldCreated) {
477:
478: $pifaField->delete();
479: } else {
480:
481: $pifaField->set('column_name', $oldColumnName);
482: }
483: throw $e;
484: }
485:
486:
487: if (false === $pifaField->store()) {
488: $msg = Pifa::i18n('FIELD_STORE_ERROR');
489: $msg = sprintf($msg, $pifaField->getLastError());
490: throw new PifaException($msg);
491: }
492:
493:
494:
495: if (true === $isFieldCreated) {
496:
497:
498: $sql = "-- PifaAjaxHandler->_postFieldForm()
499: UPDATE
500: " . cRegistry::getDbTableName('pifa_field') . "
501: SET
502: field_rank = field_rank + 1
503: WHERE
504: idform = " . cSecurity::toInteger($idform) . "
505: AND field_rank >= " . cSecurity::toInteger($fieldRank) . "
506: AND idfield <> " . cSecurity::toInteger($pifaField->get('idfield')) . "
507: ;";
508:
509: $db = cRegistry::getDb();
510: if (false === $db->query($sql)) {
511:
512:
513:
514: }
515: }
516:
517:
518: $editField = new cHTMLLink();
519: $editField->setCLink($area, 4, self::GET_FIELD_FORM);
520: $editField->setCustom('idform', $idform);
521: $editField = $editField->getHref();
522:
523: $deleteField = new cHTMLLink();
524: $deleteField->setCLink($area, 4, self::DELETE_FIELD);
525: $deleteField->setCustom('idform', $idform);
526: $deleteField = $deleteField->getHref();
527:
528: $tpl = cSmartyBackend::getInstance(true);
529:
530:
531: $tpl->assign('trans', array(
532: 'edit' => Pifa::i18n('EDIT'),
533: 'delete' => Pifa::i18n('DELETE'),
534: 'obligatory' => Pifa::i18n('OBLIGATORY')
535: ));
536:
537:
538: $tpl->assign('field', $pifaField);
539:
540: $tpl->assign('editField', $editField);
541: $tpl->assign('deleteField', $deleteField);
542:
543: $tpl->display($cfg['templates']['pifa_ajax_field_row']);
544: }
545:
546: 547: 548: 549: 550:
551: private function _deleteField($idfield) {
552: if (0 == $idfield) {
553: $msg = Pifa::i18n('MISSING_IDFIELD');
554: throw new PifaException($msg);
555: }
556:
557: $pifaField = new PifaField($idfield);
558: $pifaField->delete();
559: }
560:
561: 562: 563: 564: 565: 566:
567: private function _reorderFields($idform, $idfields) {
568: PifaFieldCollection::reorder($idform, $idfields);
569: }
570:
571: 572: 573: 574:
575: private function _exportData($idform) {
576:
577:
578: $pifaForm = new PifaForm($idform);
579: $filename = $pifaForm->get('data_table') . date('_Y_m_t_H_i_s') . '.csv';
580: $data = $pifaForm->getDataAsCsv();
581:
582:
583: session_cache_limiter('private');
584: session_cache_limiter('must-revalidate');
585:
586:
587: header('Pragma: cache');
588: header('Expires: 0');
589: header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
590: header('Cache-Control: private');
591: header('Content-Type: text/csv');
592: header('Content-Length: ' . strlen($data));
593: header('Content-Disposition: attachment; filename="' . $filename . '"');
594: header('Content-Transfer-Encoding: binary');
595:
596:
597: echo $data;
598: }
599:
600: 601: 602: 603: 604: 605: 606:
607: private function _exportForm($idform, $withData) {
608:
609:
610: $pifaForm = new PifaForm($idform);
611: $filename = $pifaForm->get('data_table') . date('_Y_m_t_H_i_s') . '.xml';
612:
613: $pifaExporter = new PifaExporter($pifaForm);
614: $xml = $pifaExporter->export($withData);
615:
616:
617: session_cache_limiter('private');
618: session_cache_limiter('must-revalidate');
619:
620:
621: header('Pragma: cache');
622: header('Expires: 0');
623: header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
624: header('Cache-Control: private');
625: header('Content-Type: text/xml');
626:
627: header('Content-Length: ' . strlen($data));
628: header('Content-Disposition: attachment; filename="' . $filename . '"');
629: header('Content-Transfer-Encoding: binary');
630:
631:
632: echo $xml;
633: }
634:
635: 636: 637: 638: 639:
640: private function _getFile($name, $file) {
641: $cfg = cRegistry::getConfig();
642:
643: $path = $cfg['path']['contenido_cache'] . 'form_assistant/';
644:
645: $file = basename($file);
646:
647: header('Pragma: cache');
648: header('Expires: 0');
649: header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
650: header('Cache-Control: private');
651:
652: 653: 654: 655: 656:
657: header('Content-Type: application/octet-stream');
658:
659: header('Content-Length: ' . filesize($path . $file));
660: header('Content-Disposition: attachment; filename="' . $name . '"');
661: header('Content-Transfer-Encoding: binary');
662:
663: $buffer = '';
664: $handle = fopen($path . $file, 'rb');
665: if (false === $handle) {
666: return false;
667: }
668: while (!feof($handle)) {
669: print fread($handle, 1 * (1024 * 1024));
670: ob_flush();
671: flush();
672: }
673: fclose($handle);
674: }
675:
676: 677: 678: 679:
680: private function _getOptionRow($index) {
681: $cfg = cRegistry::getConfig();
682:
683: $tpl = cSmartyBackend::getInstance(true);
684:
685:
686: $tpl->assign('trans', array(
687: 'label' => Pifa::i18n('LABEL'),
688: 'value' => Pifa::i18n('VALUE')
689: ));
690:
691: $tpl->assign('i', $index);
692:
693:
694: $tpl->assign('option', array(
695: 'label' => '',
696: 'value' => ''
697: ));
698:
699: $tpl->display($cfg['templates']['pifa_ajax_option_row']);
700: }
701: }
702:
703: ?>
704: