From 12a4e4d1ed827c59290838d5a11d75ad32aa28f1 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 8 May 2015 16:15:16 +0200 Subject: start of rewriting the form handling This is jsut a small beginning. Not all elements are there, yet. It's also completely untested so far. --- inc/Form/Form.php | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 inc/Form/Form.php (limited to 'inc/Form/Form.php') diff --git a/inc/Form/Form.php b/inc/Form/Form.php new file mode 100644 index 000000000..3a8b590e7 --- /dev/null +++ b/inc/Form/Form.php @@ -0,0 +1,167 @@ +attr('action')) { + $get = $_GET; + if(isset($get['id'])) unset($get['id']); + $self = wl($ID, $get); + $this->attr('action', $self); + } + + // post is default + if(!$this->attr('method')) { + $this->attr('method', 'post'); + } + + // we like UTF-8 + if(!$this->attr('accept-charset')) { + $this->attr('accept-charset', 'utf-8'); + } + + // add the security token by default + $this->setHiddenField('sectok', getSecurityToken()); + + // identify this as a form2 based form in HTML + $this->addClass('doku_form2'); + } + + /** + * Sets a hidden field + * + * @param $name + * @param $value + * @return $this + */ + public function setHiddenField($name, $value) { + $this->hidden[$name] = $value; + return $this; + } + + /** + * Adds an element to the end of the form + * + * @param Element $element + * @param int $pos 0-based position in the form, -1 for at the end + * @return Element + */ + public function addElement(Element $element, $pos = -1) { + if(is_a($element, 'Doku_Form2')) throw new \InvalidArgumentException('You can\'t add a form to a form'); + if($pos < 0) { + $this->elements[] = $element; + } else { + array_splice($this->elements, $pos, 0, array($element)); + } + return $element; + } + + /** + * Adds a text input field + * + * @param $name + * @param $label + * @param int $pos + * @return InputElement + */ + public function addTextInput($name, $label, $pos = -1) { + return $this->addElement(new InputElement('text', $name, $label), $pos); + } + + /** + * Adds a password input field + * + * @param $name + * @param $label + * @param int $pos + * @return InputElement + */ + public function addPasswordInput($name, $label, $pos = -1) { + return $this->addElement(new InputElement('password', $name, $label), $pos); + } + + /** + * Adds a radio button field + * + * @param $name + * @param $label + * @param int $pos + * @return CheckableElement + */ + public function addRadioButton($name, $label, $pos = -1) { + return $this->addElement(new CheckableElement('radio', $name, $label), $pos); + } + + /** + * Adds a checkbox field + * + * @param $name + * @param $label + * @param int $pos + * @return CheckableElement + */ + public function addCheckbox($name, $label, $pos = -1) { + return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos); + } + + /** + * Adds a textarea field + * + * @param $name + * @param $label + * @param int $pos + * @return TextareaElement + */ + public function addTextarea($name, $label, $pos = -1) { + return $this->addElement(new TextareaElement($name, $label), $pos); + } + + /** + * The HTML representation of the whole form + * + * @return string + */ + public function toHTML() { + $html = '
attrs()) . '>' . DOKU_LF; + + foreach($this->hidden as $name => $value) { + $html .= '' . DOKU_LF; + } + + foreach($this->elements as $element) { + $html .= $element->toHTML() . DOKU_LF; + } + + $html .= '
' . DOKU_LF; + + return $html; + } +} -- cgit v1.2.3 From 6d0ceaf93ca31dfb83fd4325ef2eecd9cef733c0 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 8 May 2015 17:26:11 +0200 Subject: added a first few tests. this is far from comprehensible, but should give an idea how the new library works and how to write tests --- inc/Form/Form.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'inc/Form/Form.php') diff --git a/inc/Form/Form.php b/inc/Form/Form.php index 3a8b590e7..dc502e021 100644 --- a/inc/Form/Form.php +++ b/inc/Form/Form.php @@ -34,7 +34,7 @@ class Form extends Element { if(!$this->attr('action')) { $get = $_GET; if(isset($get['id'])) unset($get['id']); - $self = wl($ID, $get); + $self = wl($ID, $get, false, '&'); //attributes are escaped later $this->attr('action', $self); } @@ -51,8 +51,8 @@ class Form extends Element { // add the security token by default $this->setHiddenField('sectok', getSecurityToken()); - // identify this as a form2 based form in HTML - $this->addClass('doku_form2'); + // identify this as a new form based form in HTML + $this->addClass('doku_form'); } /** -- cgit v1.2.3 From de19515f04567db78bd41d5bff68a88bfb8c2a22 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 8 May 2015 19:12:21 +0200 Subject: started with the compatibility layer --- inc/Form/Form.php | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'inc/Form/Form.php') diff --git a/inc/Form/Form.php b/inc/Form/Form.php index dc502e021..19cc05065 100644 --- a/inc/Form/Form.php +++ b/inc/Form/Form.php @@ -92,7 +92,7 @@ class Form extends Element { * @param int $pos * @return InputElement */ - public function addTextInput($name, $label, $pos = -1) { + public function addTextInput($name, $label = '', $pos = -1) { return $this->addElement(new InputElement('text', $name, $label), $pos); } @@ -104,7 +104,7 @@ class Form extends Element { * @param int $pos * @return InputElement */ - public function addPasswordInput($name, $label, $pos = -1) { + public function addPasswordInput($name, $label = '', $pos = -1) { return $this->addElement(new InputElement('password', $name, $label), $pos); } @@ -116,7 +116,7 @@ class Form extends Element { * @param int $pos * @return CheckableElement */ - public function addRadioButton($name, $label, $pos = -1) { + public function addRadioButton($name, $label = '', $pos = -1) { return $this->addElement(new CheckableElement('radio', $name, $label), $pos); } @@ -128,7 +128,7 @@ class Form extends Element { * @param int $pos * @return CheckableElement */ - public function addCheckbox($name, $label, $pos = -1) { + public function addCheckbox($name, $label = '', $pos = -1) { return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos); } @@ -140,16 +140,33 @@ class Form extends Element { * @param int $pos * @return TextareaElement */ - public function addTextarea($name, $label, $pos = -1) { + public function addTextarea($name, $label = '', $pos = -1) { return $this->addElement(new TextareaElement($name, $label), $pos); } + /** + * Add fixed HTML to the form + * + * @param $html + * @param int $pos + * @return Element + */ + public function addHTML($html, $pos = -1) { + return $this->addElement(new HTMLElement($html), $pos); + } + + protected function balanceFieldsets() { + //todo implement! + } + /** * The HTML representation of the whole form * * @return string */ public function toHTML() { + $this->balanceFieldsets(); + $html = '
attrs()) . '>' . DOKU_LF; foreach($this->hidden as $name => $value) { -- cgit v1.2.3 From 64744a10c5578602141ae2977274eec3fcff1f44 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Fri, 8 May 2015 20:37:06 +0200 Subject: more elements and work on the legacy support --- inc/Form/Form.php | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) (limited to 'inc/Form/Form.php') diff --git a/inc/Form/Form.php b/inc/Form/Form.php index 19cc05065..420399fb1 100644 --- a/inc/Form/Form.php +++ b/inc/Form/Form.php @@ -67,6 +67,8 @@ class Form extends Element { return $this; } + #region Element adding functions + /** * Adds an element to the end of the form * @@ -149,12 +151,73 @@ class Form extends Element { * * @param $html * @param int $pos - * @return Element + * @return HTMLElement */ public function addHTML($html, $pos = -1) { return $this->addElement(new HTMLElement($html), $pos); } + /** + * Add a closed HTML tag to the form + * + * @param $tag + * @param int $pos + * @return TagElement + */ + public function addTag($tag, $pos = -1) { + return $this->addElement(new TagElement($tag), $pos); + } + + /** + * Add an open HTML tag to the form + * + * Be sure to close it again! + * + * @param $tag + * @param int $pos + * @return TagOpenElement + */ + public function addTagOpen($tag, $pos = -1) { + return $this->addElement(new TagOpenElement($tag), $pos); + } + + /** + * Add a closing HTML tag to the form + * + * Be sure it had been opened before + * + * @param $tag + * @param int $pos + * @return TagCloseElement + */ + public function addTagClose($tag, $pos = -1) { + return $this->addElement(new TagCloseElement($tag), $pos); + } + + + /** + * Open a Fieldset + * + * @param $legend + * @param int $pos + * @return FieldsetOpenElement + */ + public function addFieldsetOpen($legend='', $pos = -1) { + return $this->addElement(new FieldsetOpenElement($legend), $pos); + } + + /** + * Close a fieldset + * + * @param int $pos + * @return TagCloseElement + */ + public function addFieldsetClose($pos = -1) { + return $this->addElement(new FieldsetCloseElement(), $pos); + } + + #endregion + protected function balanceFieldsets() { //todo implement! } -- cgit v1.2.3 From 1f5d8b65a983fe0914971ee0bb4e5e58cbf8c8a7 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 11 May 2015 20:31:16 +0200 Subject: balance fieldsets --- inc/Form/Form.php | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'inc/Form/Form.php') diff --git a/inc/Form/Form.php b/inc/Form/Form.php index 420399fb1..30e16615c 100644 --- a/inc/Form/Form.php +++ b/inc/Form/Form.php @@ -194,7 +194,6 @@ class Form extends Element { return $this->addElement(new TagCloseElement($tag), $pos); } - /** * Open a Fieldset * @@ -202,7 +201,7 @@ class Form extends Element { * @param int $pos * @return FieldsetOpenElement */ - public function addFieldsetOpen($legend='', $pos = -1) { + public function addFieldsetOpen($legend = '', $pos = -1) { return $this->addElement(new FieldsetOpenElement($legend), $pos); } @@ -218,8 +217,42 @@ class Form extends Element { #endregion + /** + * Adjust the elements so that fieldset open and closes are matching + */ protected function balanceFieldsets() { - //todo implement! + $lastclose = 0; + $isopen = false; + $len = count($this->elements); + + for($pos = 0; $pos < $len; $pos++) { + $type = $this->elements[$pos]->getType(); + if($type == 'fieldsetopen') { + if($isopen) { + //close previous feldset + $this->addFieldsetClose($pos); + $lastclose = $pos + 1; + $pos++; + $len++; + } + $isopen = true; + } else if($type == 'fieldsetclose') { + if(!$isopen) { + // make sure there was a fieldsetopen + // either right after the last close or at the begining + $this->addFieldsetOpen('', $lastclose); + $len++; + $pos++; + } + $lastclose = $pos; + $isopen = false; + } + } + + // close open fieldset at the end + if($isopen) { + $this->addFieldsetClose(); + } } /** -- cgit v1.2.3 From ef0c211b2ac87b8e3c6e85b600021389be6209bf Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 11 May 2015 20:51:58 +0200 Subject: added element query functions --- inc/Form/Form.php | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-) (limited to 'inc/Form/Form.php') diff --git a/inc/Form/Form.php b/inc/Form/Form.php index 30e16615c..2c893fbbc 100644 --- a/inc/Form/Form.php +++ b/inc/Form/Form.php @@ -67,17 +67,80 @@ class Form extends Element { return $this; } - #region Element adding functions + #region element query function + + /** + * Returns the numbers of elements in the form + * + * @return int + */ + public function elementCount() { + return count($this->elements); + } + + /** + * Returns a reference to the element at a position. + * A position out-of-bounds will return either the + * first (underflow) or last (overflow) element. + * + * @param $pos + * @return Element + */ + public function getElementAt($pos) { + if($pos < 0) $pos = count($this->elements) + $pos; + if($pos < 0) $pos = 0; + if($pos >= count($this->elements)) $pos = count($this->elements) - 1; + return $this->elements[$pos]; + } /** - * Adds an element to the end of the form + * Gets the position of the first of a type of element + * + * @param string $type Element type to look for. + * @param int $offset search from this position onward + * @return false|int position of element if found, otherwise false + */ + public function findPositionByType($type, $offset = 0) { + $len = $this->elementCount(); + for($pos = $offset; $pos < $len; $pos++) { + if($this->elements[$pos]->getType() == $type) { + return $pos; + } + } + return false; + } + + /** + * Gets the position of the first element matching the attribute + * + * @param string $name Name of the attribute + * @param string $value Value the attribute should have + * @param int $offset search from this position onward + * @return false|int position of element if found, otherwise false + */ + public function findPositionByAttribute($name, $value, $offset = 0) { + $len = $this->elementCount(); + for($pos = $offset; $pos < $len; $pos++) { + if($this->elements[$pos]->attr($name) == $value) { + return $pos; + } + } + return false; + } + + #endregion + + #region Element positioning functions + + /** + * Adds or inserts an element to the form * * @param Element $element * @param int $pos 0-based position in the form, -1 for at the end * @return Element */ public function addElement(Element $element, $pos = -1) { - if(is_a($element, 'Doku_Form2')) throw new \InvalidArgumentException('You can\'t add a form to a form'); + if(is_a($element, '\dokuwiki\Form')) throw new \InvalidArgumentException('You can\'t add a form to a form'); if($pos < 0) { $this->elements[] = $element; } else { @@ -86,6 +149,30 @@ class Form extends Element { return $element; } + /** + * Replaces an existing element with a new one + * + * @param Element $element the new element + * @param $pos 0-based position of the element to replace + */ + public function replaceElement(Element $element, $pos) { + if(is_a($element, '\dokuwiki\Form')) throw new \InvalidArgumentException('You can\'t add a form to a form'); + array_splice($this->elements, $pos, 1, array($element)); + } + + /** + * Remove an element from the form completely + * + * @param $pos 0-based position of the element to remove + */ + public function removeElement($pos) { + array_splice($this->elements, $pos, 1); + } + + #endregion + + #region Element adding functions + /** * Adds a text input field * -- cgit v1.2.3 From 80b13baa48275cef1ca6c6d3c715d21afd1138e7 Mon Sep 17 00:00:00 2001 From: Gerrit Uitslag Date: Sun, 2 Aug 2015 00:16:05 +0200 Subject: typo --- inc/Form/Form.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'inc/Form/Form.php') diff --git a/inc/Form/Form.php b/inc/Form/Form.php index 2c893fbbc..625557fa1 100644 --- a/inc/Form/Form.php +++ b/inc/Form/Form.php @@ -316,7 +316,7 @@ class Form extends Element { $type = $this->elements[$pos]->getType(); if($type == 'fieldsetopen') { if($isopen) { - //close previous feldset + //close previous fieldset $this->addFieldsetClose($pos); $lastclose = $pos + 1; $pos++; -- cgit v1.2.3