From b34cdf69ff436656726636dcce36ca7373eeb12f Mon Sep 17 00:00:00 2001 From: jmversteeg Date: Sat, 28 Feb 2015 16:13:46 +0100 Subject: [PATCH] refactored everything --- src/fieldwork/components/Group.php | 13 +- .../{HTMLComponent.php => HTMLNode.php} | 4 +- src/fieldwork/core/Component.php | 153 +++++------------- src/fieldwork/core/Field.php | 27 +--- src/fieldwork/core/Node.php | 98 +++++++++++ src/fieldwork/core/Request.php | 2 +- src/fieldwork/core/Sanitizer.php | 10 +- src/fieldwork/core/Stateful.php | 80 +++++++++ src/fieldwork/core/Validatable.php | 53 ------ src/fieldwork/core/Validator.php | 4 +- src/fieldwork/sanitizers/Capitalizer.php | 15 +- src/fieldwork/sanitizers/FieldSanitizer.php | 36 +++++ .../{RegexSanitizer.php => RegexReplacer.php} | 10 +- src/fieldwork/sanitizers/StringSanitizer.php | 33 ++++ src/fieldwork/sanitizers/Uppercaser.php | 14 +- .../validators/CheckboxValidator.php | 4 +- src/fieldwork/validators/EmailValidator.php | 4 +- src/fieldwork/validators/RegexValidator.php | 4 +- .../components/HTMLComponentTest.php | 4 +- 19 files changed, 334 insertions(+), 234 deletions(-) rename src/fieldwork/components/{HTMLComponent.php => HTMLNode.php} (83%) create mode 100644 src/fieldwork/core/Node.php create mode 100644 src/fieldwork/core/Stateful.php delete mode 100644 src/fieldwork/core/Validatable.php create mode 100644 src/fieldwork/sanitizers/FieldSanitizer.php rename src/fieldwork/sanitizers/{RegexSanitizer.php => RegexReplacer.php} (88%) create mode 100644 src/fieldwork/sanitizers/StringSanitizer.php diff --git a/src/fieldwork/components/Group.php b/src/fieldwork/components/Group.php index 8a4ce76..0fe7e59 100644 --- a/src/fieldwork/components/Group.php +++ b/src/fieldwork/components/Group.php @@ -2,17 +2,17 @@ namespace fieldwork\components; -use fieldwork\core\Component; +use fieldwork\core\Node; use fieldwork\core\Field; -class Group extends Component +class Group extends Node { public function getHTML ($before = '', $after = '', $prefix = '', $suffix = '') { $html = ''; foreach ($this->children as $component) - /* @var $component Component */ + /* @var $component Node */ if ($component->isActive()) $html .= $this->renderChild($before, $after, $prefix, $suffix, $component); return $html; @@ -23,7 +23,7 @@ public function isValid (&$error = null) if (!parent::isValid($error)) return false; foreach ($this->children as $component) - /* @var $component Component */ + /* @var $component Node */ if ($component->isActive() && !$component->isValid($error)) return false; return true; @@ -34,9 +34,10 @@ public function isValid (&$error = null) * @param $after * @param $prefix * @param $suffix - * @param Component $component + * @param Node $component + * - * @return string +*@return string */ private function renderChild ($before, $after, $prefix, $suffix, $component) { diff --git a/src/fieldwork/components/HTMLComponent.php b/src/fieldwork/components/HTMLNode.php similarity index 83% rename from src/fieldwork/components/HTMLComponent.php rename to src/fieldwork/components/HTMLNode.php index 345cc64..c706a5e 100644 --- a/src/fieldwork/components/HTMLComponent.php +++ b/src/fieldwork/components/HTMLNode.php @@ -2,13 +2,13 @@ namespace fieldwork\components; -use fieldwork\core\Component; +use fieldwork\core\Node; /** * Allows adding arbitrary markup to the form * @package fieldwork\components */ -class HTMLComponent extends Component +class HTMLNode extends Node { private $html; diff --git a/src/fieldwork/core/Component.php b/src/fieldwork/core/Component.php index 30c3f45..2d85890 100644 --- a/src/fieldwork/core/Component.php +++ b/src/fieldwork/core/Component.php @@ -2,24 +2,13 @@ namespace fieldwork\core; -/** - * Represents an HTML node - * @package fieldwork\core - * @identifier fieldwork.component - */ -abstract class Component extends Validatable +abstract class Component extends Stateful { - protected $parent; + protected $parent = null; protected $children = array(); - protected $isWrapped = true; - - private $slug; - private $active = true; - private $classes = array(); - private $attributes = array(); - - const BASE_CLASS = 'fieldwork'; + protected $slug; + protected $active = true; public function __construct ($slug) { @@ -33,73 +22,25 @@ public function __construct ($slug) public function reset () { foreach ($this->getChildren(false) as $child) - /* @var $child Component */ + /* @var $child Node */ $child->reset(); return $this; } - abstract public function getHTML (); - - protected function add (Component $component) - { - $this->children[] = $component; - } - - /** - * Checks whether the component is visible on-screen and should thus be wrapped in whatever markup is provided by - * the parent component - * @return boolean - */ - public function isWrapped () - { - return $this->isWrapped; - } - /** * Adds component to given parent component * - * @param Component $parent + * @param Node $parent * * @return static */ - public function addTo (Component $parent) + public function addTo (Node $parent) { $parent->add($this); $this->parent = $parent; return $this; } - /** - * Adds class(es) to this component's node - * - * @param string|array $class - * - * @return static - */ - public function addClass ($class) - { - $targetArray = &$this->classes; - if (!is_array($class)) - $targetArray[] = $class; - else - $targetArray = array_merge($targetArray, $class); - return $this; - } - - /** - * Sets a custom attribute for this component's node - * - * @param string $attr Attribute name - * @param string|null $value Attribtue value - * - * @return static - */ - public function setAttribute ($attr, $value = null) - { - $this->attributes[$attr] = $value !== null ? $value : $attr; - return $this; - } - /** * Sets whether the component is active * @@ -134,7 +75,7 @@ public function getChildren ($recursive = true, $includeInactiveFields = false) { $children = array(); foreach ($this->children as $component) - /* @var $component Component */ + /* @var $component Node */ if ($component->isActive() || $includeInactiveFields) { array_push($children, $component); if ($recursive) @@ -151,12 +92,12 @@ public function getChildren ($recursive = true, $includeInactiveFields = false) * @param boolean $recursive * @param boolean $includeInactiveFields whether to include inactive fields * - * @return Component|null + * @return Node|null */ public function getChildBySlug ($slug, $recursive = true, $includeInactiveFields = false) { $children = $this->getChildren($recursive, $includeInactiveFields); - /* @var $child Component */ + /* @var $child Node */ foreach ($children as $child) if ($child->getGlobalSlug() == $slug) return $child; @@ -169,74 +110,68 @@ public function getChildBySlug ($slug, $recursive = true, $includeInactiveFields /** * Check if given component is child * - * @param Component $child component to search for - * @param boolean $recursive whether or not to search recursively + * @param Node $child component to search for + * @param boolean $recursive whether or not to search recursively * * @return boolean */ public function hasChild ($child, $recursive = true) { foreach ($this->children as $component) - /* @var $component Component */ + /* @var $component Node */ if ($component == $child || ($recursive && $component->hasChild($child, true))) return true; return false; } - /** - * Gets all HTML attributes - * @return array array of attributes - */ - public function getAttributes () + public function getLocalSlug () { - return array_merge( - $this->attributes, array('class' => implode(' ', $this->getClasses()))); + return $this->slug; } - /** - * Gets all HTML attributes - * @return string attributes as string - */ - public function getAttributesString () + public function getGlobalSlug () { - $attributePairs = array(); - foreach ($this->getAttributes() as $attr => $value) - $attributePairs[] = "$attr=\"" . str_replace("\"", "\\\"", $value) . "\""; - return implode(' ', $attributePairs); + if ($this->parent instanceof Node) + return $this->parent->getGlobalSlug() . '-' . $this->slug; + else + return $this->slug; } /** - * Gets HTML class attribute - * @return array array of classes + * Gets the root to this component (first element in the array of ancestors). Returns null if the component has no + * parent + * @return Node|null */ - public function getClasses () + public function getRoot () { - return array_merge(array( - self::BASE_CLASS - ), $this->classes); + $ancestors = $this->getAncestors(); + return !(count($ancestors)) ? null : $ancestors[0]; } - public function getLocalSlug () + /** + * Gets the parent to the component. Returns null if no parent is defined + * @return Node|null + */ + public function getParent () { - return $this->slug; + return $this->parent; } - public function getGlobalSlug () + /** + * Returns an array of ancestors, root-first + * @return array + */ + public function getAncestors () { - if ($this->parent instanceof Component) - return $this->parent->getGlobalSlug() . '-' . $this->slug; - else - return $this->slug; + $ancestors = []; + $component = $this; + while ($component->getParent() instanceof Node) + array_unshift($ancestors, ($component = $component->getParent())); + return $ancestors; } - /** - * @return Component - */ - public function getRoot () + protected function add (Node $component) { - if ($this->parent instanceof Component) - return $this->parent->getRoot(); - else - return $this; + $this->children[] = $component; } } \ No newline at end of file diff --git a/src/fieldwork/core/Field.php b/src/fieldwork/core/Field.php index c88e16d..8c47371 100644 --- a/src/fieldwork/core/Field.php +++ b/src/fieldwork/core/Field.php @@ -12,7 +12,7 @@ * @package fieldwork\core * @identifier field */ -abstract class Field extends Component implements EventEmitterInterface +abstract class Field extends Node implements EventEmitterInterface { use EventEmitterTrait; @@ -88,7 +88,6 @@ public function setValue ($value) return $this; } - public function getObjectData () { $validators = []; @@ -117,7 +116,6 @@ function describeObject () return 'field'; } - /** * Gets the id attribute * @return string @@ -146,19 +144,6 @@ public function getClasses () )); } - /** - * Adds sanitizer - * - * @param Sanitizer $s - * - * @return Field - */ - public function addSanitizer (Sanitizer $s) - { - $this->sanitizers[] = $s; - return $this; - } - /** * Forcibly sets this field to return false on validation * @return static @@ -168,14 +153,4 @@ public function forceInvalid () $this->forceInvalid = true; return $this; } - - /** - * Applies each of the sanitizers to the current value - */ - public function sanitize () - { - foreach ($this->sanitizers as $sanitizer) - /* @var $sanitizer Sanitizer */ - $this->value = $sanitizer->sanitize($this->value); - } } \ No newline at end of file diff --git a/src/fieldwork/core/Node.php b/src/fieldwork/core/Node.php new file mode 100644 index 0000000..9a8c43a --- /dev/null +++ b/src/fieldwork/core/Node.php @@ -0,0 +1,98 @@ +isWrapped; + } + + + /** + * Adds class(es) to this component's node + * + * @param string|array $class + * + * @return static + */ + public function addClass ($class) + { + $targetArray = &$this->classes; + if (!is_array($class)) + $targetArray[] = $class; + else + $targetArray = array_merge($targetArray, $class); + return $this; + } + + /** + * Sets a custom attribute for this component's node + * + * @param string $attr Attribute name + * @param string|null $value Attribtue value + * + * @return static + */ + public function setAttribute ($attr, $value = null) + { + $this->attributes[$attr] = $value !== null ? $value : $attr; + return $this; + } + + + /** + * Gets all HTML attributes + * @return array array of attributes + */ + public function getAttributes () + { + return array_merge( + $this->attributes, array('class' => implode(' ', $this->getClasses()))); + } + + /** + * Gets all HTML attributes + * @return string attributes as string + */ + public function getAttributesString () + { + $attributePairs = array(); + foreach ($this->getAttributes() as $attr => $value) + $attributePairs[] = "$attr=\"" . str_replace("\"", "\\\"", $value) . "\""; + return implode(' ', $attributePairs); + } + + /** + * Gets HTML class attribute + * @return array array of classes + */ + public function getClasses () + { + return array_merge(array( + self::BASE_CLASS + ), $this->classes); + } +} \ No newline at end of file diff --git a/src/fieldwork/core/Request.php b/src/fieldwork/core/Request.php index b3b4c4e..bb59111 100644 --- a/src/fieldwork/core/Request.php +++ b/src/fieldwork/core/Request.php @@ -19,7 +19,7 @@ abstract class Request extends Synchronizable * * @return string|null The value */ - public function getComponentValue (Component $component) + public function getComponentValue (Node $component) { return $this->getValue($component->getGlobalSlug()); } diff --git a/src/fieldwork/core/Sanitizer.php b/src/fieldwork/core/Sanitizer.php index acce6c8..6f2fb4b 100644 --- a/src/fieldwork/core/Sanitizer.php +++ b/src/fieldwork/core/Sanitizer.php @@ -12,10 +12,16 @@ abstract class Sanitizer extends Synchronizable { - public abstract function sanitize ($value); + /** + * Sanitizes the given object + * + * @param Stateful $object + */ + public abstract function sanitize (Stateful $object); /** - * Determines whether the sanitizion is applied directly after the user exits the fields + * Determines whether the sanitizing is applied directly after the user exits the fields (locally or through AJAX) + * If set to false, the sanitizing is applied only server-side, when the user submits the form * @return bool */ public function isLive () diff --git a/src/fieldwork/core/Stateful.php b/src/fieldwork/core/Stateful.php new file mode 100644 index 0000000..46c7e74 --- /dev/null +++ b/src/fieldwork/core/Stateful.php @@ -0,0 +1,80 @@ +validators, $offset === null ? count($this->validators) : $offset, 0, [$v]); + return $this; + } + + /** + * Adds a sanitizer to the object's validation stack + * + * @param Sanitizer $s The sanitizer to add + * @param null|int $offset If offset is null, add the sanitizer to the end of the stack (default). If offset is + * positive then the sanitizer is inserted at that offset from the beginning of the stack + * If offset is negative then it is inserted that far from the end of the stack. + * + * @return static + */ + public function addSanitizer (Sanitizer $s, $offset = null) + { + array_splice($this->sanitizers, $offset === null ? count($this->sanitizers) : $offset, 0, [$s]); + return $this; + } + + /** + * Runs through the validation stack, returning false if any of the validators evaluates to true + * + * @param string $error If provided, this variable is set to the error returned by the first validator to reject + * the value + * + * @return bool + */ + public function isValid (&$error = null) + { + foreach ($this->validators as $validator) { + /* @var $validator Validator */ + if (!$validator->isValid($this)) { + $error = $validator->getErrorMessage(); + return false; + } + } + return true; + } + + /** + * Runs through the sanitizing stack + */ + public function sanitize () + { + foreach ($this->sanitizers as $sanitizer) { + /* @var $sanitizer Sanitizer */ + $sanitizer->sanitize($this); + } + } + +} \ No newline at end of file diff --git a/src/fieldwork/core/Validatable.php b/src/fieldwork/core/Validatable.php deleted file mode 100644 index 87afd20..0000000 --- a/src/fieldwork/core/Validatable.php +++ /dev/null @@ -1,53 +0,0 @@ -validators, $v); - else - $this->validators[] = $v; - return $this; - } - - /** - * Checks whether the object is valid - * - * @param string $error If provided, this variable is set to the error returned by the first validator to reject - * the value - * - * @return bool - */ - public function isValid (&$error = null) - { - foreach ($this->validators as $validator) { - /* @var $validator Validator */ - if (!$validator->isValid($this)) { - $error = $validator->getErrorMessage(); - return false; - } - } - return true; - } - -} \ No newline at end of file diff --git a/src/fieldwork/core/Validator.php b/src/fieldwork/core/Validator.php index be81005..e635375 100644 --- a/src/fieldwork/core/Validator.php +++ b/src/fieldwork/core/Validator.php @@ -22,11 +22,11 @@ public function __construct ($errorMsg) /** * Checks whether the object is valid * - * @param Validatable $validatable + * @param Stateful $object * * @return bool */ - public abstract function isValid (Validatable $validatable); + public abstract function isValid (Stateful $object); function getObjectData () { diff --git a/src/fieldwork/sanitizers/Capitalizer.php b/src/fieldwork/sanitizers/Capitalizer.php index 3100c45..b2c8f20 100644 --- a/src/fieldwork/sanitizers/Capitalizer.php +++ b/src/fieldwork/sanitizers/Capitalizer.php @@ -2,13 +2,16 @@ namespace fieldwork\sanitizers; -use fieldwork\core\Sanitizer; use fieldwork\sanitizers; -class Capitalizer extends Sanitizer +/** + * @package fieldwork\sanitizers + * @identifier capitalizer + */ +class Capitalizer extends StringSanitizer { - public function sanitize ($value) + public function sanitizeValue ($value) { return ucwords($value); } @@ -17,10 +20,4 @@ public function isLive () { return true; } - - public function describeObject () - { - return 'capitalize'; - } - } \ No newline at end of file diff --git a/src/fieldwork/sanitizers/FieldSanitizer.php b/src/fieldwork/sanitizers/FieldSanitizer.php new file mode 100644 index 0000000..29d054a --- /dev/null +++ b/src/fieldwork/sanitizers/FieldSanitizer.php @@ -0,0 +1,36 @@ +setValue($this->sanitizeField($object)); + } +} \ No newline at end of file diff --git a/src/fieldwork/sanitizers/RegexSanitizer.php b/src/fieldwork/sanitizers/RegexReplacer.php similarity index 88% rename from src/fieldwork/sanitizers/RegexSanitizer.php rename to src/fieldwork/sanitizers/RegexReplacer.php index e56656d..bc4523b 100644 --- a/src/fieldwork/sanitizers/RegexSanitizer.php +++ b/src/fieldwork/sanitizers/RegexReplacer.php @@ -8,11 +8,10 @@ use fieldwork\util\RegExp; /** - * Class RegexReplacer * @package fieldwork\sanitizers * @identifier regex */ -class RegexSanitizer extends Sanitizer +class RegexReplacer extends StringSanitizer { protected $pcrePattern; @@ -42,7 +41,7 @@ public function getObjectData () ]; } - public function sanitize ($value) + public function sanitizeValue ($value) { return preg_replace($this->pcrePattern, $this->newValue, $value); } @@ -51,9 +50,4 @@ public function isLive () { return true; } - - public function isRealtime () - { - return false; - } } \ No newline at end of file diff --git a/src/fieldwork/sanitizers/StringSanitizer.php b/src/fieldwork/sanitizers/StringSanitizer.php new file mode 100644 index 0000000..315572e --- /dev/null +++ b/src/fieldwork/sanitizers/StringSanitizer.php @@ -0,0 +1,33 @@ +setValue($this->sanitizeValue($field->getValue())); + } + + /** + * Sanitizes a field's value + * + * @param string $value + * + * @return string + */ + abstract protected function sanitizeValue ($value); +} \ No newline at end of file diff --git a/src/fieldwork/sanitizers/Uppercaser.php b/src/fieldwork/sanitizers/Uppercaser.php index ac51800..4eef299 100644 --- a/src/fieldwork/sanitizers/Uppercaser.php +++ b/src/fieldwork/sanitizers/Uppercaser.php @@ -5,10 +5,14 @@ use fieldwork\core\Sanitizer; use fieldwork\sanitizers; -class Uppercaser extends Sanitizer +/** + * @package fieldwork\sanitizers + * @identifier uppercase + */ +class Uppercaser extends StringSanitizer { - public function sanitize ($value) + public function sanitizeValue ($value) { return strtoupper($value); } @@ -17,10 +21,4 @@ public function isLive () { return true; } - - public function describeObject () - { - return 'uppercase'; - } - } \ No newline at end of file diff --git a/src/fieldwork/validators/CheckboxValidator.php b/src/fieldwork/validators/CheckboxValidator.php index a8b8a88..a69b2f3 100644 --- a/src/fieldwork/validators/CheckboxValidator.php +++ b/src/fieldwork/validators/CheckboxValidator.php @@ -4,7 +4,7 @@ use fieldwork\components\Checkbox; use fieldwork\core\Validator; -use fieldwork\core\Validatable; +use fieldwork\core\Stateful; /** * Checkbox validator @@ -36,7 +36,7 @@ public function getObjectData () ]; } - public function isValid (Validatable $field) + public function isValid (Stateful $field) { /* @var $field Checkbox */ $checked = $field->isChecked(); diff --git a/src/fieldwork/validators/EmailValidator.php b/src/fieldwork/validators/EmailValidator.php index ee7f523..7d20e36 100644 --- a/src/fieldwork/validators/EmailValidator.php +++ b/src/fieldwork/validators/EmailValidator.php @@ -3,7 +3,7 @@ namespace fieldwork\validators; use fieldwork\core\Field; -use fieldwork\core\Validatable; +use fieldwork\core\Stateful; class EmailValidator extends RegexValidator { @@ -20,7 +20,7 @@ public function __construct ($error = null) $this->validator = new \Egulias\EmailValidator\EmailValidator(); } - public function isValid (Validatable $field) + public function isValid (Stateful $field) { /* @var $field Field */ return $this->validator->isValid($field->getValue()); diff --git a/src/fieldwork/validators/RegexValidator.php b/src/fieldwork/validators/RegexValidator.php index 7d8f602..9f5767a 100644 --- a/src/fieldwork/validators/RegexValidator.php +++ b/src/fieldwork/validators/RegexValidator.php @@ -4,7 +4,7 @@ use fieldwork\core\Field; use fieldwork\core\Validator; -use fieldwork\core\Validatable; +use fieldwork\core\Stateful; use fieldwork\util\RegExp; /** @@ -50,7 +50,7 @@ public function getObjectData () ]; } - public function isValid (Validatable $field) + public function isValid (Stateful $field) { /* @var $field Field */ return !!preg_match($this->pcrePattern, $field->getValue()); diff --git a/tests/fieldwork/components/HTMLComponentTest.php b/tests/fieldwork/components/HTMLComponentTest.php index 9d948e1..3485316 100644 --- a/tests/fieldwork/components/HTMLComponentTest.php +++ b/tests/fieldwork/components/HTMLComponentTest.php @@ -2,7 +2,7 @@ namespace test\fieldwork\components; -use fieldwork\components\HTMLComponent; +use fieldwork\components\HTMLNode; class HTMLComponentTest extends \PHPUnit_Framework_TestCase { @@ -10,7 +10,7 @@ class HTMLComponentTest extends \PHPUnit_Framework_TestCase public function testHTMLComponent () { $html = '

Hello world

'; - $component = new HTMLComponent($html); + $component = new HTMLNode($html); $this->assertEquals($html, $component->getHTML()); } } \ No newline at end of file