Open Monograph Press  3.3.0
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.FormValidatorUsername');
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.FormValidatorLocale');
38 import('lib.pkp.classes.form.validation.FormValidatorLocaleEmail');
39 import('lib.pkp.classes.form.validation.FormValidatorCSRF');
40 import('lib.pkp.classes.form.validation.FormValidatorPost');
41 import('lib.pkp.classes.form.validation.FormValidatorRegExp');
42 import('lib.pkp.classes.form.validation.FormValidatorUrl');
43 import('lib.pkp.classes.form.validation.FormValidatorLocaleUrl');
44 import('lib.pkp.classes.form.validation.FormValidatorISSN');
45 import('lib.pkp.classes.form.validation.FormValidatorORCID');
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 
80  var $defaultLocale;
81 
86  function __construct($template = null, $callHooks = true, $requiredLocale = null, $supportedLocales = null) {
87 
89  $this->requiredLocale = $requiredLocale;
91  $this->supportedLocales = $supportedLocales;
92 
93  $this->defaultLocale = AppLocale::getLocale();
94 
95  $this->_template = $template;
96  $this->_data = array();
97  $this->_checks = array();
98  $this->_errors = array();
99  $this->errorsArray = array();
100  $this->errorFields = array();
101  $this->formSectionErrors = array();
102 
103  if ($callHooks === true) {
104  // Call hooks based on the calling entity, assuming
105  // this method is only called by a subclass. Results
106  // in hook calls named e.g. "papergalleyform::Constructor"
107  // Note that class names are always lower case.
108  HookRegistry::call(strtolower_codesafe(get_class($this)) . '::Constructor', array($this, &$template));
109  }
110  }
111 
112 
113  //
114  // Setters and Getters
115  //
120  function setTemplate($template) {
121  $this->_template = $template;
122  }
123 
128  function getTemplate() {
130  }
131 
137  function getRequiredLocale() {
138  return $this->requiredLocale;
139  }
140 
141  //
142  // Public Methods
143  //
150  function display($request = null, $template = null) {
151  $this->fetch($request, $template, true);
152  }
153 
162  function fetch($request, $template = null, $display = false) {
163  // Set custom template.
164  if (!is_null($template)) $this->_template = $template;
165 
166  // Call hooks based on the calling entity, assuming
167  // this method is only called by a subclass. Results
168  // in hook calls named e.g. "papergalleyform::display"
169  // Note that class names are always lower case.
170  $returner = null;
171  if (HookRegistry::call(strtolower_codesafe(get_class($this)) . '::display', array($this, &$returner))) {
172  return $returner;
173  }
174 
175  $templateMgr = TemplateManager::getManager($request);
176  $templateMgr->setCacheability(CACHEABILITY_NO_STORE);
177 
178 
179  // Attach this form object to the Form Builder Vocabulary for validation to work
180  $fbv = $templateMgr->getFBV();
181  $fbv->setForm($this);
182 
183  $templateMgr->assign(array_merge(
184  $this->_data,
185  array(
186  'isError' => !$this->isValid(),
187  'errors' => $this->getErrorsArray(),
188  'formLocales' => $this->supportedLocales,
189  'formLocale' => $this->getDefaultFormLocale(),
190  )
191  ));
192 
193  if ($display) {
194  $templateMgr->display($this->_template);
195  $returner = null;
196  } else {
197  $returner = $templateMgr->fetch($this->_template);
198  }
199 
200  // Reset the FBV's form in case template manager fetches another template not within a form.
201  $fbv->setForm(null);
202 
203  return $returner;
204  }
205 
211  function getData($key) {
212  return isset($this->_data[$key]) ? $this->_data[$key] : null;
213  }
214 
220  function setData($key, $value = null) {
221  if (is_array($key)) foreach($key as $aKey => $aValue) {
222  $this->setData($aKey, $aValue);
223  } else {
224  $this->_data[$key] = $value;
225  }
226  }
227 
231  function initData() {
232  // Call hooks based on the calling entity, assuming
233  // this method is only called by a subclass. Results
234  // in hook calls named e.g. "papergalleyform::initData"
235  // Note that class and function names are always lower
236  // case.
237  HookRegistry::call(strtolower_codesafe(get_class($this) . '::initData'), array($this));
238  }
239 
244  function readInputData() {
245  // Default implementation does nothing.
246  }
247 
252  function validate($callHooks = true) {
253  if (!isset($this->errorsArray)) {
254  $this->getErrorsArray();
255  }
256 
257  foreach ($this->_checks as $check) {
258  if (!isset($this->errorsArray[$check->getField()]) && !$check->isValid()) {
259  if (method_exists($check, 'getErrorFields') && method_exists($check, 'isArray') && call_user_func(array(&$check, 'isArray'))) {
260  $errorFields = call_user_func(array(&$check, 'getErrorFields'));
261  for ($i=0, $count=count($errorFields); $i < $count; $i++) {
262  $this->addError($errorFields[$i], $check->getMessage());
263  $this->errorFields[$errorFields[$i]] = 1;
264  }
265  } else {
266  $this->addError($check->getField(), $check->getMessage());
267  $this->errorFields[$check->getField()] = 1;
268  }
269  }
270  }
271 
272  if ($callHooks === true) {
273  // Call hooks based on the calling entity, assuming
274  // this method is only called by a subclass. Results
275  // in hook calls named e.g. "papergalleyform::validate"
276  // Note that class and function names are always lower
277  // case.
278  $value = null;
279  if (HookRegistry::call(strtolower_codesafe(get_class($this) . '::validate'), array($this, &$value))) {
280  return $value;
281  }
282  }
283 
284  if (!defined('SESSION_DISABLE_INIT')) {
285  $request = Application::get()->getRequest();
286  $user = $request->getUser();
287 
288  if (!$this->isValid() && $user) {
289  // Create a form error notification.
290  import('classes.notification.NotificationManager');
291  $notificationManager = new NotificationManager();
292  $notificationManager->createTrivialNotification(
293  $user->getId(), NOTIFICATION_TYPE_FORM_ERROR, array('contents' => $this->getErrorsArray())
294  );
295  }
296  }
297 
298  return $this->isValid();
299  }
300 
307  function execute(...$functionArgs) {
308  // Call hooks based on the calling entity, assuming
309  // this method is only called by a subclass. Results
310  // in hook calls named e.g. "papergalleyform::execute"
311  // Note that class and function names are always lower
312  // case.
313  $returner = null;
314  HookRegistry::call(strtolower_codesafe(get_class($this) . '::execute'), array_merge(array($this), $functionArgs, array(&$returner)));
315  return $returner;
316  }
317 
322  function getLocaleFieldNames() {
323  // Call hooks based on the calling entity, assuming
324  // this method is only called by a subclass. Results
325  // in hook calls named e.g. "papergalleyform::getLocaleFieldNames"
326  // Note that class and function names are always lower
327  // case.
328  $returner = array();
329  HookRegistry::call(strtolower_codesafe(get_class($this) . '::getLocaleFieldNames'), array($this, &$returner));
330  return $returner;
331  }
332 
337  function getDefaultFormLocale() {
338  $formLocale = $this->defaultLocale;
339  if (!isset($this->supportedLocales[$formLocale])) $formLocale = $this->requiredLocale;
340  return $formLocale;
341  }
342 
348  $this->defaultLocale = $defaultLocale;
349  }
350 
355  function addSupportedFormLocale($supportedLocale) {
356  if (!in_array($supportedLocale, $this->supportedLocales)) {
357  $site = Application::get()->getRequest()->getSite();
358  $siteSupportedLocales = $site->getSupportedLocaleNames();
359  if (array_key_exists($supportedLocale, $siteSupportedLocales)) {
360  $this->supportedLocales[$supportedLocale] = $siteSupportedLocales[$supportedLocale];
361  }
362  }
363  }
364 
369  function readUserVars($vars) {
370  // Call hooks based on the calling entity, assuming
371  // this method is only called by a subclass. Results
372  // in hook calls named e.g. "papergalleyform::readUserVars"
373  // Note that class and function names are always lower
374  // case.
375  HookRegistry::call(strtolower_codesafe(get_class($this) . '::readUserVars'), array($this, &$vars));
376  $request = Application::get()->getRequest();
377  foreach ($vars as $k) {
378  $this->setData($k, $request->getUserVar($k));
379  }
380  }
381 
386  function addCheck($formValidator) {
387  $this->_checks[] =& $formValidator;
388  }
389 
395  function addError($field, $message) {
396  $this->_errors[] = new FormError($field, $message);
397  }
398 
403  function addErrorField($field) {
404  $this->errorFields[$field] = 1;
405  }
406 
411  function isValid() {
412  return empty($this->_errors);
413  }
414 
420  function getErrorsArray() {
421  $this->errorsArray = array();
422  foreach ($this->_errors as $error) {
423  if (!isset($this->errorsArray[$error->getField()])) {
424  $this->errorsArray[$error->getField()] = $error->getMessage();
425  }
426  }
427  return $this->errorsArray;
428  }
429 
430  //
431  // Private helper methods
432  //
441  function _decomposeArray($name, $value, $stack) {
442  $returner = '';
443  if (is_array($value)) {
444  foreach ($value as $key => $subValue) {
445  $newStack = $stack;
446  $newStack[] = $key;
447  $returner .= $this->_decomposeArray($name, $subValue, $newStack);
448  }
449  } else {
450  $name = htmlentities($name, ENT_COMPAT, LOCALE_ENCODING);
451  $value = htmlentities($value, ENT_COMPAT, LOCALE_ENCODING);
452  $returner .= '<input type="hidden" name="' . $name;
453  while (($item = array_shift($stack)) !== null) {
454  $item = htmlentities($item, ENT_COMPAT, LOCALE_ENCODING);
455  $returner .= '[' . $item . ']';
456  }
457  $returner .= '" value="' . $value . "\" />\n";
458  }
459  return $returner;
460  }
461 }
462 
463 
Form\$cssValidation
$cssValidation
Definition: Form.inc.php:71
FormError
Class to represent a form validation error.
Definition: FormError.inc.php:16
Form\$_data
$_data
Definition: Form.inc.php:53
Form\getRequiredLocale
getRequiredLocale()
Definition: Form.inc.php:146
Form\$_checks
$_checks
Definition: Form.inc.php:56
Form\setData
setData($key, $value=null)
Definition: Form.inc.php:229
Form\readUserVars
readUserVars($vars)
Definition: Form.inc.php:378
Form\getData
getData($key)
Definition: Form.inc.php:220
Form\getErrorsArray
getErrorsArray()
Definition: Form.inc.php:429
Form\getLocaleFieldNames
getLocaleFieldNames()
Definition: Form.inc.php:331
Form\$defaultLocale
$defaultLocale
Definition: Form.inc.php:89
AppLocale\getPrimaryLocale
static getPrimaryLocale()
Definition: env1/MockAppLocale.inc.php:95
Form\addError
addError($field, $message)
Definition: Form.inc.php:404
Form\validate
validate($callHooks=true)
Definition: Form.inc.php:261
Form\execute
execute(... $functionArgs)
Definition: Form.inc.php:316
Form\getTemplate
getTemplate()
Definition: Form.inc.php:137
Form\isValid
isValid()
Definition: Form.inc.php:420
Form\setDefaultFormLocale
setDefaultFormLocale($defaultLocale)
Definition: Form.inc.php:356
Form\$_template
$_template
Definition: Form.inc.php:50
Form\$requiredLocale
$requiredLocale
Definition: Form.inc.php:77
Form\initData
initData()
Definition: Form.inc.php:240
Form\setTemplate
setTemplate($template)
Definition: Form.inc.php:129
Form\readInputData
readInputData()
Definition: Form.inc.php:253
Form\addSupportedFormLocale
addSupportedFormLocale($supportedLocale)
Definition: Form.inc.php:364
Form\getDefaultFormLocale
getDefaultFormLocale()
Definition: Form.inc.php:346
PKPTemplateManager\getManager
static & getManager($request=null)
Definition: PKPTemplateManager.inc.php:1239
Form\$_errors
$_errors
Definition: Form.inc.php:59
Form\$formSectionErrors
$formSectionErrors
Definition: Form.inc.php:68
Form\$errorsArray
$errorsArray
Definition: Form.inc.php:62
Form\$errorFields
$errorFields
Definition: Form.inc.php:65
strtolower_codesafe
strtolower_codesafe($str)
Definition: functions.inc.php:280
Form\display
display($request=null, $template=null)
Definition: Form.inc.php:159
Form\__construct
__construct($template=null, $callHooks=true, $requiredLocale=null, $supportedLocales=null)
Definition: Form.inc.php:95
Form\$supportedLocales
$supportedLocales
Definition: Form.inc.php:83
Form\_decomposeArray
_decomposeArray($name, $value, $stack)
Definition: Form.inc.php:450
Form\addCheck
addCheck($formValidator)
Definition: Form.inc.php:395
NotificationManager
Definition: NotificationManager.inc.php:19
Form
Class defining basic operations for handling HTML forms.
Definition: Form.inc.php:47
PKPApplication\get
static get()
Definition: PKPApplication.inc.php:235
Form\addErrorField
addErrorField($field)
Definition: Form.inc.php:412
HookRegistry\call
static call($hookName, $args=null)
Definition: HookRegistry.inc.php:86
AppLocale\getLocale
static getLocale()
Definition: env1/MockAppLocale.inc.php:40
AppLocale\getSupportedFormLocales
static getSupportedFormLocales()
Definition: env1/MockAppLocale.inc.php:124
Form\fetch
fetch($request, $template=null, $display=false)
Definition: Form.inc.php:171