Ik wou me wat verdiepen in OOP, en nu ben ik gebotst op een 'probleem'.
Ik heb 2 volwaardig werkende, maar ongeteste, classen geschreven voor HTML-forms te generen
Maar de toepassing doet er niet echt toe, want dat is al 1000 keer gedaan.
Ga je gang mocht je toch de code willen gebruiken, er zijn wel nog een paar verbeteringen in de filter te doen.
De eerste abstract class verzorgt de nesting van elementen (zoals de php class simplexml)
De tweede class extend deze class, en override de constructor om de parameters te interpreteren voor voor het definieren van de form-elementen.
* Overiden: Conventioneel betekend dit de naam van method uit de parent class gebruiken in een child-class
Overloaden: Conventioneel betekend dit 2x dezelfde naam gebruiken in een class met andere parameters.
Ik bedoel conventioneel overriden, in PHP-context wordt dit overloaden genoemd, met overriden bedoelen zij het gebruik van de magic method __call, om een methode die niet bestaat toch aan te roepen, een soort catch-all.
Echter lijkt me dat niet een gewenste situatie, want dan moet ik in de constructor van 'class 2' parameters opnemen, die ik enkel bedoeld zijn voor de parent class.
Het alternatief is om de factory-method te overiden, en hier de filter aan toe te voegen. Dan is het nadeel, dat bij initialisatie van het moeder-object, er geen filter wordt toegepast
Dus blijft het overriden van de constructor toch een beter idee.
Tenzij, ervaren OOP-ers misschien mij iets kunnen leren?
Alle behulpzame opmerkingen over de code en codestijl zijn welkom.
Terzijde, welke naamgeving is beter voor een nieuw kind-object, 'newChild' of 'addChild' zoals in simpleXML?
Source code: sorry voor de lange lap code, was niet de bedoeling, toen ik hiermee begon te spelen
Facory
FormParser:
hier is het probleem: De methode newChild kan je verwijderen, omdat ik reeds filter in de constructor, wat mij ook logischer lijkt.
Maar hoe kan ik voorkomen dat ik de parameters van de parent class moet overnemen in de argumenten.
Generen van een demo-form
origineel
voorbeeld
demo van de code
Ik heb 2 volwaardig werkende, maar ongeteste, classen geschreven voor HTML-forms te generen
Maar de toepassing doet er niet echt toe, want dat is al 1000 keer gedaan.
Ga je gang mocht je toch de code willen gebruiken, er zijn wel nog een paar verbeteringen in de filter te doen.
De eerste abstract class verzorgt de nesting van elementen (zoals de php class simplexml)
De tweede class extend deze class, en override de constructor om de parameters te interpreteren voor voor het definieren van de form-elementen.
* Overiden: Conventioneel betekend dit de naam van method uit de parent class gebruiken in een child-class
Overloaden: Conventioneel betekend dit 2x dezelfde naam gebruiken in een class met andere parameters.
Ik bedoel conventioneel overriden, in PHP-context wordt dit overloaden genoemd, met overriden bedoelen zij het gebruik van de magic method __call, om een methode die niet bestaat toch aan te roepen, een soort catch-all.
Echter lijkt me dat niet een gewenste situatie, want dan moet ik in de constructor van 'class 2' parameters opnemen, die ik enkel bedoeld zijn voor de parent class.
Het alternatief is om de factory-method te overiden, en hier de filter aan toe te voegen. Dan is het nadeel, dat bij initialisatie van het moeder-object, er geen filter wordt toegepast
Dus blijft het overriden van de constructor toch een beter idee.
Tenzij, ervaren OOP-ers misschien mij iets kunnen leren?
Alle behulpzame opmerkingen over de code en codestijl zijn welkom.
Terzijde, welke naamgeving is beter voor een nieuw kind-object, 'newChild' of 'addChild' zoals in simpleXML?
Source code: sorry voor de lange lap code, was niet de bedoeling, toen ik hiermee begon te spelen
Facory
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
| <?php # alternative 1: http://php.net/simplexml # alternative 2 + more options: https://github.com/servo-php/fluidxml abstract class htmlfactory { public $tag; public $parameters; public $value; public $root; public $parent; public $childs; public function __construct($tag=null,$value=null,$parent=null){ // extract parameters from tag and trim if($tag != null){ $parameters = array_map('trim', explode(' ',$tag)); $this->tag = array_shift($parameters); $this->parameters = $parameters; } else{ $this->tag = null; $this->parameters = null; } $this->value = $value; // Create happy family $this->childs = array(); if($parent == null){ // i have no parent, because i'm the root $this->parent = null; $this->root = $this; } else{ // i have a parent, and his root is mine too $this->parent = $parent; $this->root = $parent->root; } } public function newChild($tag=null,$value=null){ // Late Static Bindings - factory $child = new static($tag,$value,$this); $this->childs[] = $child; return $child; } public function getChilds($debug=false){ if($debug){ list($lt,$gt,$nbsp,$br) = array('<','>',' ',"<br>\r\n"); $table = array(); }else{ list($lt,$gt,$nbsp,$br) = array('<','>',' ',"\r\n"); } $stack = array(); $allChilds = array(); $parent = null; $child = $this; do{ do{ if(isset($child)){ $element = ''; if($child->tag != null){ # add empty element in front for spacing between tag and parameters if(count($child->parameters)>0) array_unshift($child->parameters,''); $element .= $lt.$child->tag.implode(' ',$child->parameters).$gt; } if($child->value != null) $element .= $child->value; if(!empty($element)){ if(is_array($child->childs)&&count($child->childs)==0) $element .= $lt.'/'.$child->tag.$gt; $allChilds[] = str_repeat($nbsp,4*(count($stack))).$element; } if($debug) $table[] = array($child->tag,$child->value,$child->parent,$parrent->tag); if(count($child->childs)>0){ # add parent to stack! (first parent==root==null) $stack[] = $parent; $parent = $child; reset($parent->childs); } } }while(list(,$child) = each($parent->childs)); // add closing tag - first element of stack == null if($parent->tag != null && count($stack)>0) $allChilds[] = str_repeat($nbsp,4*(count($stack)-1)).$lt.'/'.$parent->tag.$gt; unset($child); }while($parent = array_pop($stack)); if($debug===1) return $table; return implode($br,$allChilds).$br; } } |
FormParser:
hier is het probleem: De methode newChild kan je verwijderen, omdat ik reeds filter in de constructor, wat mij ook logischer lijkt.
Maar hoe kan ik voorkomen dat ik de parameters van de parent class moet overnemen in de argumenten.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
| <?php class form extends htmlfactory{ // factory public $tag; public $parameters; public $value; // form public $name; public $group; public $childNumber; public $path; public function __construct($tag=null,$value=null,$parent=null){ parent::__construct($tag,$value,$parent); if($this->parent === null){ $this->group = null; $this->group = 'groupNameIsNotDefined'; $this->childNumber = '1'; $this->path = 'Path:'; } $this->parseParameters(); } public function newChild($tag=null,$value=null){ $child = parent::newChild($tag,$value); // $child->parseParameters(); return $child; } public function parseParameters(){ // parent is NULL only if method initiated by __constructor() /* PUT CODE HERE */ // parent is never NULL if method initiated by newChild() if($this->parent != null){ $parent = $this->parent; $this->childNumber = count($parent->childs)+1; if(!empty($parent->group)){ $this->group = $parent->group; if($parent->group != 'groupNameIsNotDefined') $this->path = $parent->group; } $this->path = $parent->path; } $this->path = $this->path . $this->childNumber; # just trying something $this->parameters[] = "foo='{$this->path}'"; // Get name from value if(count(explode('=',$this->value))==2){ $value = explode('=',$this->value); $this->name = array_shift($value); $this->value = array_shift($value); }else{ $this->name = null; // no name defined $this->value = $this->value; // explicit, can be null } $inputTypes = array( 'input','text','email','password','url','search','tel','number', 'time','date','week','month', 'datetime-local', 'checkbox','radio','color','range', 'file','image','submit','button','reset','hidden' ); // define HTML templates if(in_array($this->tag,$inputTypes)) $this->parseParametersInput(); elseif(in_array($this->tag,array('label','textarea','select','option','fieldset'))) $this->parseParametersDefault(); elseif($this->tag == 'plain'){ $this->tag = null; $this->childs = null; } // not used elseif($this->tag == 'group'){ $this->group = $this->value; $this->tag = null; $this->value = null; $this->childs = null; } } private function parseParametersInput(){ if($this->name==null && $this->value==null) $this->name = array_shift($this->parameters); // get input-type $type = $this->tag; if($type == 'input') // $type = array_shift($this->parameters); $type = 'text'; $parameters = array(); $parameters[] = "type='$type'"; // limitation of switch-case $group = $this->group; switch($this->tag){ case 'button': case 'submit': if($this->name != null){ $parameters[] = "id='{$this->name}'"; $parameters[] = "name='{$this->name}'"; $parameters[] = "value='{$this->value}'"; } elseif($this->value != null){ $this->parameters[] = "value='{$this->value}'"; } break; case 'checkbox': $group .= '[]'; case 'radio': $name = array_shift($this->parameters); $parameters[] = "id='$name'"; $parameters[] = "name='$group'"; $this->parameters[] = "value='{$this->value}'"; break; default: if(isset($name)){ $parameters[] = "id='$name'"; $parameters[] = "name='$name'"; if(isset($value)) $this->parameters[] = "value='{$this->value}'"; }else{ $parameters[] = "id='$value'"; $parameters[] = "name='$value'"; } } $this->parameters = array_merge($parameters,$this->parameters); $this->tag = 'input'; $this->value = null; $this->childs = null; } private function parseParametersDefault(){ $parameters = array(); switch($this->tag){ case 'label': if(is_null($this->name)) $name = array_shift($this->parameters); $parameters[] = "for='$name'"; break; case 'textarea': if(is_null($this->name)) $name = array_shift($this->parameters); $parameters[] = "name='$name'"; break; case 'select': if(is_null($this->name)) $name = array_shift($this->parameters); else $name = $this->value; $parameters[] = "name=$name"; $this->value = null; break; case 'option': if(!is_null($this->name)){ $parameters[] = "id='{$this->name}'"; $this->parameters[] = "value='{$this->name}'"; } else $this->parameters[] = "value='{$this->value}'"; break; case 'fieldset': $this->group = $this->value; $this->value = null; break; } $this->parameters = array_merge($parameters,$this->parameters); } } |
Generen van een demo-form
origineel
voorbeeld
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
| <?php $form = new form('form action="#"','<h1>anything is possible</h1>'); $header = $form->newChild('header'); $header->newChild('h2','Example Responsive Form'); $header->newChild('div','This form breaks at 600px and goes from a left-label form to a top-label form. At above 1200px, the labels align right.'); $container = $form->newChild('div'); $container->newChild('label fullname class="desc"','Full Name'); $div = $container->newChild('div'); $div->newChild('text fullname class="field text fn" size="8"'); $container = $form->newChild('div'); $container->newChild('label email class="desc"','Email'); $div = $container->newChild('div'); $div->newChild('email email spellcheck="false" maxlength="255"'); $container = $form->newChild('div'); $container->newChild('label message class="desc"','Message'); $div = $container->newChild('div'); $div->newChild('textarea message spellcheck="true" rows="10" cols="50"'); $div = $form->newChild('div'); $fieldset = $div->newChild('fieldset'); $fieldset->newChild('legend class="desc"','Select a Choice'); $container = $fieldset->newChild('div'); $container->group = 'choice'; $container->newChild('hidden choice'); $div = $container->newChild('div'); $div->newChild('radio choice1 checked="checked"',"firstChoice"); $div->newChild('label choice1 class="choice"','First choice'); $div = $container->newChild('div'); $div->newChild('radio choice2',"secondChoice"); $div->newChild('label choice2 class="choice"','Second Choice'); $div = $container->newChild('div'); $div->newChild('radio choice3',"thirdChoice"); $div->newChild('label choice3 class="choice"','Third choice'); $div = $form->newChild('div'); $fieldset = $div->newChild('fieldset'); $fieldset->newChild('legend class="desc"',' Check All That Apply'); $container = $fieldset->newChild('div'); $container->group = 'checkbox'; $container->newChild('hidden choice'); $div = $container->newChild('div'); $div->newChild('checkbox checkbox1 checked="checked"',"FirstChoice"); $div->newChild('label checkbox1 class="choice"','First choice'); $div = $container->newChild('div'); $div->newChild('checkbox checkbox2',"secondChoice"); $div->newChild('label checkbox2 class="choice"','Second choice'); $div = $container->newChild('div'); $div->newChild('checkbox checkbox3',"secondChoice"); $div->newChild('label checkbox3 class="choice"','Third choice'); $div = $form->newChild('div'); $div->newChild('label menu class="desc"','Select a Choice'); $div = $div->newChild('div'); $select = $div->newChild('select menu class="field select medium"','menu'); $select->newChild('option','first=First Choice'); $select->newChild('option','second=Second Choice'); $select->newChild('option','third=Third Choice'); $div = $form->newChild('div'); $div->newChild('submit','saveForm=submit'); $div->newChild('plain','i want some plain text'); echo $form->getChilds(); ?> |
demo van de code
[ Voor 100% gewijzigd door g4wx3 op 25-10-2018 15:31 ]