Open Monograph Press  1.1
 All Classes Namespaces Functions Variables Groups Pages
Form.inc.php
1 <?php
2 
23 import('lib.pkp.classes.form.FormError');
24 import('lib.pkp.classes.form.FormBuilderVocabulary');
25 
26 // Import all form validators for convenient use in sub-classes
27 import('lib.pkp.classes.form.validation.FormValidatorAlphaNum');
28 import('lib.pkp.classes.form.validation.FormValidatorArray');
29 import('lib.pkp.classes.form.validation.FormValidatorArrayCustom');
30 import('lib.pkp.classes.form.validation.FormValidatorBoolean');
31 import('lib.pkp.classes.form.validation.FormValidatorControlledVocab');
32 import('lib.pkp.classes.form.validation.FormValidatorCustom');
33 import('lib.pkp.classes.form.validation.FormValidatorReCaptcha');
34 import('lib.pkp.classes.form.validation.FormValidatorEmail');
35 import('lib.pkp.classes.form.validation.FormValidatorInSet');
36 import('lib.pkp.classes.form.validation.FormValidatorLength');
37 import('lib.pkp.classes.form.validation.FormValidatorListbuilder');
38 import('lib.pkp.classes.form.validation.FormValidatorLocale');
39 import('lib.pkp.classes.form.validation.FormValidatorLocaleEmail');
40 import('lib.pkp.classes.form.validation.FormValidatorPost');
41 import('lib.pkp.classes.form.validation.FormValidatorRegExp');
42 import('lib.pkp.classes.form.validation.FormValidatorUri');
43 import('lib.pkp.classes.form.validation.FormValidatorUrl');
44 import('lib.pkp.classes.form.validation.FormValidatorLocaleUrl');
45 import('lib.pkp.classes.form.validation.FormValidatorISSN');
46 
47 class Form {
48 
51 
53  var $_data;
54 
56  var $_checks;
57 
59  var $_errors;
60 
63 
66 
69 
72 
74  var $requiredLocale;
75 
78 
83  function Form($template = null, $callHooks = true, $requiredLocale = null, $supportedLocales = null) {
84 
86  $this->requiredLocale = $requiredLocale;
88  $this->supportedLocales = $supportedLocales;
89 
90  $this->_template = $template;
91  $this->_data = array();
92  $this->_checks = array();
93  $this->_errors = array();
94  $this->errorsArray = array();
95  $this->errorFields = array();
96  $this->formSectionErrors = array();
97 
98  if ($callHooks === true) {
99  // Call hooks based on the calling entity, assuming
100  // this method is only called by a subclass. Results
101  // in hook calls named e.g. "papergalleyform::Constructor"
102  // Note that class names are always lower case.
103  HookRegistry::call(strtolower_codesafe(get_class($this)) . '::Constructor', array($this, &$template));
104  }
105  }
106 
107 
108  //
109  // Setters and Getters
110  //
115  function setTemplate($template) {
116  $this->_template = $template;
117  }
118 
123  function getTemplate() {
124  return $this->_template;
125  }
126 
132  function getRequiredLocale() {
133  return $this->requiredLocale;
134  }
135 
136  //
137  // Public Methods
138  //
145  function display($request = null, $template = null) {
146  $this->fetch($request, $template, true);
147  }
148 
157  function fetch($request, $template = null, $display = false) {
158  // Set custom template.
159  if (!is_null($template)) $this->_template = $template;
160 
161  // Call hooks based on the calling entity, assuming
162  // this method is only called by a subclass. Results
163  // in hook calls named e.g. "papergalleyform::display"
164  // Note that class names are always lower case.
165  $returner = null;
166  if (HookRegistry::call(strtolower_codesafe(get_class($this)) . '::display', array($this, &$returner))) {
167  return $returner;
168  }
169 
170  $templateMgr = TemplateManager::getManager($request);
171  $templateMgr->setCacheability(CACHEABILITY_NO_STORE);
172 
173 
174  // Attach this form object to the Form Builder Vocabulary for validation to work
175  $fbv = $templateMgr->getFBV();
176  $fbv->setForm($this);
177 
178  $templateMgr->assign($this->_data);
179  $templateMgr->assign('isError', !$this->isValid());
180  $templateMgr->assign('errors', $this->getErrorsArray());
181 
182  $templateMgr->register_function('form_language_chooser', array($this, 'smartyFormLanguageChooser'));
183  $templateMgr->assign('formLocales', $this->supportedLocales);
184 
185  // Determine the current locale to display fields with
186  $templateMgr->assign('formLocale', $this->getFormLocale());
187 
188  // N.B: We have to call $templateMgr->display instead of ->fetch($display)
189  // in order for the TemplateManager::display hook to be called
190  $returner = $templateMgr->display($this->_template, null, null, $display);
191 
192  // Need to reset the FBV's form in case the template manager does another fetch on a template that is not within a form.
193  $nullVar = null;
194  $fbv->setForm($nullVar);
195 
196  return $returner;
197  }
198 
204  function getData($key) {
205  return isset($this->_data[$key]) ? $this->_data[$key] : null;
206  }
207 
213  function setData($key, $value) {
214  if (is_string($value)) $value = Core::cleanVar($value);
215  $this->_data[$key] = $value;
216  }
217 
221  function initData() {
222  // Call hooks based on the calling entity, assuming
223  // this method is only called by a subclass. Results
224  // in hook calls named e.g. "papergalleyform::initData"
225  // Note that class and function names are always lower
226  // case.
227  HookRegistry::call(strtolower_codesafe(get_class($this) . '::initData'), array($this));
228  }
229 
234  function readInputData() {
235  // Default implementation does nothing.
236  }
237 
241  function validate($callHooks = true) {
242  if (!isset($this->errorsArray)) {
243  $this->getErrorsArray();
244  }
245 
246  foreach ($this->_checks as $check) {
247  if (!isset($this->errorsArray[$check->getField()]) && !$check->isValid()) {
248  if (method_exists($check, 'getErrorFields') && method_exists($check, 'isArray') && call_user_func(array(&$check, 'isArray'))) {
249  $errorFields = call_user_func(array(&$check, 'getErrorFields'));
250  for ($i=0, $count=count($errorFields); $i < $count; $i++) {
251  $this->addError($errorFields[$i], $check->getMessage());
252  $this->errorFields[$errorFields[$i]] = 1;
253  }
254  } else {
255  $this->addError($check->getField(), $check->getMessage());
256  $this->errorFields[$check->getField()] = 1;
257  }
258  }
259  }
260 
261  if ($callHooks === true) {
262  // Call hooks based on the calling entity, assuming
263  // this method is only called by a subclass. Results
264  // in hook calls named e.g. "papergalleyform::validate"
265  // Note that class and function names are always lower
266  // case.
267  $value = null;
268  if (HookRegistry::call(strtolower_codesafe(get_class($this) . '::validate'), array($this, &$value))) {
269  return $value;
270  }
271  }
272 
273  if (!defined('SESSION_DISABLE_INIT')) {
274  $application = PKPApplication::getApplication();
275  $request = $application->getRequest();
276  $user = $request->getUser();
277 
278  if (!$this->isValid() && $user) {
279  // Create a form error notification.
280  import('classes.notification.NotificationManager');
281  $notificationManager = new NotificationManager();
282  $notificationManager->createTrivialNotification(
283  $user->getId(), NOTIFICATION_TYPE_FORM_ERROR, array('contents' => $this->getErrorsArray())
284  );
285  }
286  }
287 
288  return $this->isValid();
289  }
290 
297  function execute($object = null) {
298  // Call hooks based on the calling entity, assuming
299  // this method is only called by a subclass. Results
300  // in hook calls named e.g. "papergalleyform::execute"
301  // Note that class and function names are always lower
302  // case.
303  HookRegistry::call(strtolower_codesafe(get_class($this) . '::execute'), array($this, &$object));
304  return $object;
305  }
306 
311  function getLocaleFieldNames() {
312  // Call hooks based on the calling entity, assuming
313  // this method is only called by a subclass. Results
314  // in hook calls named e.g. "papergalleyform::getLocaleFieldNames"
315  // Note that class and function names are always lower
316  // case.
317  $returner = array();
318  HookRegistry::call(strtolower_codesafe(get_class($this) . '::getLocaleFieldNames'), array($this, &$returner));
319  return $returner;
320  }
321 
327  function isLocaleResubmit() {
328  $formLocale = Request::getUserVar('formLocale');
329  return (!empty($formLocale));
330  }
331 
336  function getDefaultFormLocale() {
337  $formLocale = AppLocale::getLocale();
338  if (!isset($this->supportedLocales[$formLocale])) $formLocale = $this->requiredLocale;
339  return $formLocale;
340  }
341 
346  function getFormLocale() {
347  $formLocale = Request::getUserVar('formLocale');
348  if (!$formLocale || !isset($this->supportedLocales[$formLocale])) {
349  $formLocale = $this->getDefaultFormLocale();
350  }
351  return $formLocale;
352  }
353 
358  function readUserVars($vars) {
359  // Call hooks based on the calling entity, assuming
360  // this method is only called by a subclass. Results
361  // in hook calls named e.g. "papergalleyform::readUserVars"
362  // Note that class and function names are always lower
363  // case.
364  HookRegistry::call(strtolower_codesafe(get_class($this) . '::readUserVars'), array($this, &$vars));
365  foreach ($vars as $k) {
366  $this->setData($k, Request::getUserVar($k));
367  }
368  }
369 
374  function readUserDateVars($vars) {
375  // Call hooks based on the calling entity, assuming
376  // this method is only called by a subclass. Results
377  // in hook calls named e.g. "papergalleyform::readUserDateVars"
378  // Note that class and function names are always lower
379  // case.
380  HookRegistry::call(strtolower_codesafe(get_class($this) . '::readUserDateVars'), array($this, &$vars));
381  foreach ($vars as $k) {
382  $this->setData($k, Request::getUserDateVar($k));
383  }
384  }
385 
390  function addCheck($formValidator) {
391  $this->_checks[] =& $formValidator;
392  }
393 
399  function addError($field, $message) {
400  $this->_errors[] = new FormError($field, $message);
401  }
402 
407  function addErrorField($field) {
408  $this->errorFields[$field] = 1;
409  }
410 
415  function isValid() {
416  return empty($this->_errors);
417  }
418 
424  function getErrorsArray() {
425  $this->errorsArray = array();
426  foreach ($this->_errors as $error) {
427  if (!isset($this->errorsArray[$error->getField()])) {
428  $this->errorsArray[$error->getField()] = $error->getMessage();
429  }
430  }
431  return $this->errorsArray;
432  }
433 
440  function smartyFormLanguageChooser($params, &$smarty) {
441  $returner = '';
442 
443  // Print back all non-current language field values so that they
444  // are not lost.
445  $formLocale = $this->getFormLocale();
446  foreach ($this->getLocaleFieldNames() as $field) {
447  $values = $this->getData($field);
448  if (!is_array($values)) continue;
449  foreach ($values as $locale => $value) {
450  if ($locale != $formLocale) $returner .= $this->_decomposeArray($field, $value, array($locale));
451  }
452  }
453 
454  // Display the language selector widget.
455  $returner .= '<div id="languageSelector"><select size="1" name="formLocale" id="formLocale" onchange="changeFormAction(\'' . htmlentities($params['form'], ENT_COMPAT, LOCALE_ENCODING) . '\', \'' . htmlentities($params['url'], ENT_QUOTES, LOCALE_ENCODING) . '\')" class="selectMenu">';
456  foreach ($this->supportedLocales as $locale => $name) {
457  $returner .= '<option ' . ($locale == $formLocale?'selected="selected" ':'') . 'value="' . htmlentities($locale, ENT_COMPAT, LOCALE_ENCODING) . '">' . htmlentities($name, ENT_COMPAT, LOCALE_ENCODING) . '</option>';
458  }
459  $returner .= '</select></div>';
460  return $returner;
461  }
462 
463  //
464  // Private helper methods
465  //
474  function _decomposeArray($name, $value, $stack) {
475  $returner = '';
476  if (is_array($value)) {
477  foreach ($value as $key => $subValue) {
478  $newStack = $stack;
479  $newStack[] = $key;
480  $returner .= $this->_decomposeArray($name, $subValue, $newStack);
481  }
482  } else {
483  $name = htmlentities($name, ENT_COMPAT, LOCALE_ENCODING);
484  $value = htmlentities($value, ENT_COMPAT, LOCALE_ENCODING);
485  $returner .= '<input type="hidden" name="' . $name;
486  while (($item = array_shift($stack)) !== null) {
487  $item = htmlentities($item, ENT_COMPAT, LOCALE_ENCODING);
488  $returner .= '[' . $item . ']';
489  }
490  $returner .= '" value="' . $value . "\" />\n";
491  }
492  return $returner;
493  }
494 }
495 
496 ?>
addCheck($formValidator)
Definition: Form.inc.php:396
setData($key, $value)
Definition: Form.inc.php:219
Class to represent a form validation error.
$_data
Definition: Form.inc.php:53
getTemplate()
Definition: Form.inc.php:129
isLocaleResubmit()
Definition: Form.inc.php:333
$cssValidation
Definition: Form.inc.php:71
static getPrimaryLocale()
$_template
Definition: Form.inc.php:50
getFormLocale()
Definition: Form.inc.php:352
fetch($request, $template=null, $display=false)
Definition: Form.inc.php:163
readUserVars($vars)
Definition: Form.inc.php:364
Class defining basic operations for handling HTML forms.
Definition: Form.inc.php:47
readUserDateVars($vars)
Definition: Form.inc.php:380
Form($template=null, $callHooks=true, $requiredLocale=null, $supportedLocales=null)
Definition: Form.inc.php:89
initData()
Definition: Form.inc.php:227
addError($field, $message)
Definition: Form.inc.php:405
isValid()
Definition: Form.inc.php:421
getErrorsArray()
Definition: Form.inc.php:430
getData($key)
Definition: Form.inc.php:210
getRequiredLocale()
Definition: Form.inc.php:138
getLocaleFieldNames()
Definition: Form.inc.php:317
static getLocale()
validate($callHooks=true)
Definition: Form.inc.php:247
$errorFields
Definition: Form.inc.php:65
getUserDateVar($prefix, $defaultDay=null, $defaultMonth=null, $defaultYear=null, $defaultHour=0, $defaultMinute=0, $defaultSecond=0)
display($request=null, $template=null)
Definition: Form.inc.php:151
static call($hookName, $args=null)
_decomposeArray($name, $value, $stack)
Definition: Form.inc.php:480
smartyFormLanguageChooser($params, &$smarty)
Definition: Form.inc.php:446
$requiredLocale
Definition: Form.inc.php:77
$supportedLocales
Definition: Form.inc.php:83
$_errors
Definition: Form.inc.php:59
static cleanVar($var)
Definition: Core.inc.php:54
setTemplate($template)
Definition: Form.inc.php:121
$formSectionErrors
Definition: Form.inc.php:68
readInputData()
Definition: Form.inc.php:240
$errorsArray
Definition: Form.inc.php:62
addErrorField($field)
Definition: Form.inc.php:413
static getSupportedFormLocales()
getDefaultFormLocale()
Definition: Form.inc.php:342
$_checks
Definition: Form.inc.php:56
execute($object=null)
Definition: Form.inc.php:303