From: Raphaël Barrois Date: Mon, 25 Jan 2010 15:18:22 +0000 (+0100) Subject: Create class UserFilterBuilder X-Git-Tag: xorg/1.0.0~332^2~265 X-Git-Url: http://git.polytechnique.org/?a=commitdiff_plain;h=d9b3d71282439b9b7cdf79af8f98e255cf694ddd;p=platal.git Create class UserFilterBuilder Used to create (basic) UserFilter, reading values from Get/Post Should evolve into a much more powerful tool later... Signed-off-by: Raphaël Barrois --- diff --git a/include/ufbuilder.php b/include/ufbuilder.php new file mode 100644 index 0000000..528759a --- /dev/null +++ b/include/ufbuilder.php @@ -0,0 +1,320 @@ +fields = $fields; + $this->envprefix = $envprefix; + } + + /** Builds the UFC; returns as soon as a field says it is invalid + */ + private function buildUFC() + { + if ($this->ufc != null) { + return; + } + $this->ufc = new PFC_And(); + + foreach ($this->fields as $field) { + $this->valid = $field->apply(&$this); + if (!$this->valid) { + return; + } + } + } + + public function addCond(PlFilterCondition &$cond) + { + $this->ufc->addChild($cond); + } + + public function isValid() + { + $this->buildUFC(); + return $this->valid; + } + + /** Returns the built UFC + * @return The UFC, or PFC_False() if an error happened + */ + public function &getUFC() + { + $this->buildUFC(); + if ($this->valid) { + return $this->ufc; + } else { + return new PFC_False(); + } + } + + /** Wrappers around Env::i/s/..., to add envprefix + */ + public function s($key, $def) { + return trim(Env::s($this->envprefix . $key, $def)); + } + + public function i($key, $def) { + return intval(trim(Env::i($this->envprefix . $key, $def))); + } + + public function v($key, $def) { + return Env::v($this->envprefix . $key, $def); + } + + public function has($key) { + return Env::has($this->envprefix . $key); + } +} + +abstract class UFB_Field +{ + protected $envfield; + protected $formtext; + + protected $empty = false; + protected $val = null; + + /** Constructor + * @param $envfield Name of the field in the environment + * @param $formtext User-friendly name of that field + */ + public function __construct($envfield, $formtext = '') + { + $this->envfield = $envfield; + if ($formtext != '') { + $this->formtext = $formtext; + } else { + $formtext = ucfirst($envfield); + } + } + + /** Prints the given error message to the user, and returns false + * in order to be used as return $this->raise('ERROR'); + * + * All %s in the $msg will be replaced with the formtext. + */ + protected function raise($msg) + { + Platal::page()->trigError(str_replace('%s', $this->formtext, $msg)); + return false; + } + + public function apply(UserFilterBuilder &$ufb) { + if (!$this->check($ufb)) { + return false; + } + + if (!$this->empty) { + $ufc = $this->buildUFC($ufb); + if ($ufc != null) { + $ufb->addCond($ufc); + } + } + return true; + } + + /** Create the UFC associated to the field; won't be called + * if the field is "empty" + * @param &$ufb UFB to which fields must be added + * @return UFC + */ + abstract protected function buildUFC(UserFilterBuilder &$ufb); + + /** This function is intended to run consistency checks on the value + * @return boolean Whether the input is valid + */ + abstract protected function check(UserFilterBuilder &$ufb); +} + +abstract class UFBF_Text extends UFB_Field +{ + private $forbiddenchars; + private $minlength; + private $maxlength; + + public function __construct($envfield, $formtext = '', $forbiddenchars = '', $minlength = 2, $maxlength = 255) + { + parent::__construct($envfield, $formtext); + $this->forbiddenchars = $forbiddenchars; + $this->minlength = $minlength; + $this->maxlength = $maxlength; + } + + protected function check(UserFilterBuilder &$ufb) + { + if (!$ufb->has($this->envfield)) { + $this->empty = true; + return true; + } + + $this->val = $ufb->s($this->envfield); + if (strlen($this->val) < $this->minlength) { + return $this->raise("Le champ %s est trop court (minimum {$this->minlength})."); + } else if (strlen($this->val) > $this->maxlength) { + return $this->raise("Le champ %s est trop long (maximum {$this->maxlength})."); + } + return true; + } +} + +/** Subclass to use for fields which only allow integers within a range + */ +abstract class UFBF_Range extends UFB_Field +{ + + private $min; + private $max; + + public function __construct($envfield, $formtext = '', $min = 0, $max = 65535) + { + parent::__construct($envfield, $formtext); + $this->min = $min; + $this->max = $max; + } + + protected function check(UserFilterBuilder &$ufb) + { + if (!$ufb->has($this->envfield)) { + $this->empty = true; + return true; + } + + $this->val = $ufb->i($this->envfield); + if ($this->val < $this->min) { + return $this->raise("Le champs %s est inférieur au minimum ({$this->min})."); + } else if ($this->val > $this->max) { + return $this->raise("Le champ %s est supérieur au maximum ({$this->max})."); + } + return true; + } +} + +/** Subclass to use for indexed fields + */ +abstract class UFBF_Index extends UFB_Field +{ + protected function check(UserFilterBuilder &$ufb) + { + if (!$ufb->has($this->envfield)) { + $this->empty = true; + } + return true; + } +} + +/** Subclass to use for fields whose value must belong to a specific set of values + */ +abstract class UFBF_Enum extends UFB_Field +{ + public function __construct($envfield, $formtext = '', $allowedvalues = array()) + { + parent::__construct($envfield, $formtext); + $this->allowedvalues = $allowedvalues; + } + + protected function check(UserFilterBuilder &$ufb) + { + if (!$ufb->has($this->envfield)) { + $this->empty = true; + return true; + } + + $this->val = $ufb->v($this->envfield); + if (! in_array($this->val, $this->allowedvalues)) { + return $this->raise("La valeur {$this->val} n'est pas valide pour le champ %s."); + } + return true; + } +} + +class UFBF_Name extends UFBF_Text +{ + private $type; + + public function __construct($envfield, $type, $formtext = '', $forbiddenchars = '', $minlength = 2, $maxlength = 255) + { + parent::__construct($envfield, $formtext, $forbiddenchars, $minlength, $maxlength); + $this->type = $type; + } + + protected function buildUFC(UserFilterBuilder &$ufb) + { + if ($ufb->i('exact')) { + return new UFC_Name($this->type, $this->val, UFC_Name::VARIANTS); + } else { + return new UFC_Name($this->type, $this->val, UFC_Name::VARIANTS | UFC_Name::CONTAINS); + } + } +} + +class UFBF_Promo extends UFB_Field +{ + private static $validcomps = array('<', '<=', '=', '>=', '>'); + private $comp; + private $envfieldcomp; + + public function __construct($envfield, $fromtext = '', $envfieldcomp) + { + parent::__construct($envfield, $fromtext); + $this->envfieldcomp = $envfieldcomp; + } + + protected function check(UserFilterBuilder &$ufb) + { + if (!$ufb->has($this->envfield) || !$ufb->has($this->envfieldcomp)) { + $this->empty = true; + return true; + } + + $this->val = $ubf->i($this->envfield); + $this->comp = $ubf->v($this->envfieldcomp); + + if (!in_array($this->comp, self::$validcomps)) { + return $this->raise("Le critère {$this->comp} n'est pas valide pour le champ %s"); + } + + if (preg_match('/^[0-9]{2}$/', $this->val)) { + $this->val += 1900; + } + if ($this->val < 1900 || $this->val > 9999) { + return $this->raise("Le champ %s doit être une année à 4 chiffres."); + } + return true; + } + + protected function buildUFC(UserFilterBuilder &$ufb) { + return new UFC_Promo($this->comp, UserFilter::DISPLAY, 'X' . $this->val); + } +} + +?>