PHPのフレームワークです。オートローディング、ルーティング、ORマッパ、フォームバリデータ、その他ユーティリティがセットになっています。
Révision | 81 (tree) |
---|---|
l'heure | 2021-01-14 15:40:03 |
Auteur | tantancode |
ViewUtilの一部メソッドを新クラスに取り出した
@@ -0,0 +1,344 @@ | ||
1 | +<?php | |
2 | + | |
3 | +/** | |
4 | + * HTMLを取り扱う処理を収めるユーティリティ。 | |
5 | + */ | |
6 | +class HtmlUtil { | |
7 | + | |
8 | + //----------------------------------------------------------------------------------------------------- | |
9 | + /** | |
10 | + * 引数に指定された情報でHTMLタグを作成する。 | |
11 | + * | |
12 | + * @param タグ名。"a" とか "hr" とか。 | |
13 | + * @param 属性名をキー、値を値とする配列。HtmlUtil::attributes() に指定できる値。 | |
14 | + * @param タグで挟みたい内容がある場合は指定する。この場合、終了タグも一緒に返される。 | |
15 | + * 省略した場合、返されるタグは閉じタグが省略されたもの( <xxxx /> の形式)になる。 | |
16 | + * 配列を指定した場合は \n で連結された文字列に変換される。 | |
17 | + * @param 第三引数がすでにHTMLエンコード済みの場合は true を指定する。 | |
18 | + * falseの場合はエンコードされる。 | |
19 | + * @return 作成したHTML。 | |
20 | + */ | |
21 | + public static function tag($tagName, $attributes = array(), $content = null, $encoded = false) { | |
22 | + | |
23 | + $tag = "<{$tagName}" . self::attributes($attributes); | |
24 | + | |
25 | + if( is_null($content) ) | |
26 | + return $tag . ' />'; | |
27 | + | |
28 | + if( is_array($content) ) | |
29 | + $content = "\n" . implode("\n", $content) . "\n"; | |
30 | + | |
31 | + if(!$encoded) | |
32 | + $content = ViewUtil::encode($content); | |
33 | + | |
34 | + return "{$tag}>{$content}</{$tagName}>"; | |
35 | + } | |
36 | + | |
37 | + //----------------------------------------------------------------------------------------------------- | |
38 | + /** | |
39 | + * 引数に指定された配列をHTMLタグの属性として展開する。 | |
40 | + * | |
41 | + * 例) | |
42 | + * $return = HtmlUtil::attributes( array('abc'=>'ABC', 'def'=>'DEF', 'ghi'=>'333') ); | |
43 | + * // $return は次のような文字列になる。 | |
44 | + * // abc="ABC" def="DEF" ghi="333" | |
45 | + * | |
46 | + * 値が真偽値の true になっている場合、XHTML向けにキーと同じ値として処理される。 | |
47 | + * また、false, null のキーは出力されない。 | |
48 | + * 例) | |
49 | + * $return = HtmlUtil::attributes( array('abc'=>true, 'def'=>true, 'ghi'=>false, 'jkl'=>null) ); | |
50 | + * // abc="abc" def="def" | |
51 | + * | |
52 | + * style の値を配列とすることもできる。その場合はCSSのキーと値の列挙として処理する。 | |
53 | + * 例) | |
54 | + * $return = HtmlUtil::attributes( array('abc'=>'ABC', 'style'=>array('def'=>'DEF', 'ghi'=>'333')) ); | |
55 | + * // abc="ABC" style="def:DEF; ghi:333;" | |
56 | + * | |
57 | + * style の配列の数値キーはそのまま追加される。 | |
58 | + * 例) | |
59 | + * $return = HtmlUtil::attributes(array( 'style'=>array('abc:ABC', 'def'=>'DEF', 'ghi'=>'333') )); | |
60 | + * // style="abc:ABC; def:DEF; ghi:333;" | |
61 | + * | |
62 | + * @param 属性として展開したい配列。 | |
63 | + * @return 属性として展開した文字列。 | |
64 | + */ | |
65 | + public static function attributes($attributes) { | |
66 | + | |
67 | + // "style" の値が配列になっている場合は文字列に直す。 | |
68 | + if( is_array(@$attributes['style']) ) { | |
69 | + | |
70 | + $style = ''; | |
71 | + foreach($attributes['style'] as $propName => $propValue) { | |
72 | + | |
73 | + if( is_null($propValue) ) | |
74 | + continue; | |
75 | + | |
76 | + if( is_int($propName) ) | |
77 | + $style .= $propValue . '; '; | |
78 | + else | |
79 | + $style .= "{$propName}:{$propValue}; "; | |
80 | + } | |
81 | + | |
82 | + $attributes['style'] = $style; | |
83 | + } | |
84 | + | |
85 | + // 戻り値初期化。 | |
86 | + $result = ''; | |
87 | + | |
88 | + // HTMLの属性として展開していく。 | |
89 | + foreach($attributes as $name => $value) { | |
90 | + | |
91 | + // 値が真偽値の true の場合、XHTML向けにキーと同じ値とする。 | |
92 | + if($value === true) | |
93 | + $value = $name; | |
94 | + | |
95 | + // null, false 以外であれば出力する。 | |
96 | + if( !(is_null($value) || $value === false) ) | |
97 | + $result .= sprintf(' %s="%s"', ViewUtil::encode($name), ViewUtil::encode($value)); | |
98 | + } | |
99 | + | |
100 | + // リターン。 | |
101 | + return $result; | |
102 | + } | |
103 | + | |
104 | + //----------------------------------------------------------------------------------------------------- | |
105 | + /** | |
106 | + * 引数に指定された情報で入力フォームの一項目を表すHTML文字列を作成する。<input> や <textarea> を始め、HtmlUtil::select() で説明されている | |
107 | + * 選択肢グループにも対応する。 | |
108 | + * | |
109 | + * @param 基本的にはHTML要素の属性だが、以下のキーは特別に処理される。 | |
110 | + * type <input> の type 属性だが、次のいずれかの場合は特別に処理される。省略時は "text"。 | |
111 | + * select <option>を含む <select> を作成する。 | |
112 | + * radios ラジオボタンのグループを作成する。 | |
113 | + * checks チェックボックスのグループを作成する。 | |
114 | + * check, checkbox | |
115 | + * 単体チェックボックスを作成する。 | |
116 | + * label も指定されている場合は <label> で囲むように生成される。 | |
117 | + * textarea <textarea> を作成する。 | |
118 | + * choice typeの値が select, radios, checks の場合に、選択肢の配列。options を指定した場合はそちらが優先される。 | |
119 | + * キーでvalueを、値で選択肢名を指定する。選択肢名は次のキーで操作することも出来る。 | |
120 | + * label-format choice の選択肢名を生成するときの sprintf フォーマット文字列。%1$ が値、%2$ がキーとなる。 | |
121 | + * 省略した場合は "%1$s"。 | |
122 | + * value typeの値が select, radios, checks の場合は、最初に選択状態になっている選択肢のキー。 | |
123 | + * textarea では最初に入力されている値。それ以外では、普通に <input> のvalue属性となる。 | |
124 | + * options choice を指定するならそちらから生成できるので省略できる。 | |
125 | + * typeの値が select の場合、一つの <option> HTML文字列を1要素とした配列。 | |
126 | + * radios, checks の場合は、一つの <input> HTML文字列を1要素とした配列。 | |
127 | + * glue typeの値が radios, checks の場合に、各選択肢をつなげるHTML。省略時は "\n"。 | |
128 | + * placeholder 普通に <input> の placeholder 属性だが、type=select の場合は一番先頭に位置 | |
129 | + * する value="" の <option> の見出し文字列となる。 | |
130 | + * @return 作成したHTML。 | |
131 | + */ | |
132 | + public static function input($attributes) { | |
133 | + | |
134 | + // 種別を取り出す。 | |
135 | + $origtype = @ArrayUtil::eject($attributes, 'type') ?: 'text'; | |
136 | + $type = strtolower($origtype); | |
137 | + | |
138 | + // 種別 select, radios, checks はこちらで処理する。 | |
139 | + if( in_array($type, ['select', 'radios', 'checks']) ) | |
140 | + return self::select($type, $attributes); | |
141 | + | |
142 | + // 日時系のコントロールを使うときに、valueをいつもの形式で指定できるように少し面倒を見てやる。 | |
143 | + switch( $type ) { | |
144 | + | |
145 | + // "datetime-local" を使うときは、valueの日付と時刻の区切り文字を "T" にする必要がある。 | |
146 | + case 'datetime-local': $attributes['value'] = preg_replace('/(?<=\d)\s+(?=\d)/', 'T', $attributes['value']); break; | |
147 | + | |
148 | + // type="date" を使うときは時刻部分があってはならない。面倒くさいなぁ… | |
149 | + case 'date': $attributes['value'] = preg_replace('/\s*\d*\s*:\s*\d*\s*/', '', $attributes['value']); break; | |
150 | + | |
151 | + // type="month" を使うときは年・月のみでなければならない。もうちょっと融通をだな… | |
152 | + case 'month': $attributes['value'] = preg_replace('/^(\d+\W\d+).*/', '$1', $attributes['value']); break; | |
153 | + } | |
154 | + | |
155 | + // 種別によって処理する。 | |
156 | + switch($type) { | |
157 | + | |
158 | + // 単体チェックボックスを作成する場合。 | |
159 | + case 'check': | |
160 | + case 'checkbox': | |
161 | + $attributes['type'] = $type; | |
162 | + return HtmlUtil::choice($attributes); | |
163 | + | |
164 | + // <textarea> を作成する場合。 | |
165 | + case 'textarea': | |
166 | + $value = @ArrayUtil::eject($attributes, 'value'); | |
167 | + return HtmlUtil::tag('textarea', $attributes, (string)$value); // stringキャストしているのは、null だったら閉じタグなしになってしまうため。 | |
168 | + | |
169 | + // それ以外では <input> を生成する。 | |
170 | + default: | |
171 | + $attributes['type'] = $origtype; | |
172 | + return HtmlUtil::tag('input', $attributes); | |
173 | + } | |
174 | + } | |
175 | + | |
176 | + //----------------------------------------------------------------------------------------------------- | |
177 | + /** | |
178 | + * 引数に指定された情報で、セレクトボックスやラジオボタンのような選択肢グループを表すHTML文字列を作成する。 | |
179 | + * | |
180 | + * @param 種別。select, radios, checks のいずれか。 | |
181 | + * @param select の場合は<select>タグの属性、radios, checks では各<input>タグの属性だが、以下のキーは特別に処理される。 | |
182 | + * choice 選択肢の配列。options を指定した場合はそちらが優先される。 | |
183 | + * キーでvalueを、値で選択肢名を指定する。選択肢名は次のキーで操作することも出来る。 | |
184 | + * label-format choice の選択肢名を生成するときの sprintf フォーマット文字列。%1$ が値、%2$ がキーとなる。 | |
185 | + * 省略した場合は "%1$s"。 | |
186 | + * value 最初に選択状態になっている選択肢のキー。 | |
187 | + * options choice を指定するならそちらから生成されるので省略できる。 | |
188 | + * select の場合は一つの <option> HTML文字列を1要素とした配列。 | |
189 | + * radios, checks の場合は一つの <input> HTML文字列を1要素とした配列。 | |
190 | + * glue radios, checks の場合に、各選択肢をつなげるHTML。省略時は "\n"。 | |
191 | + * placeholder select の場合は、一番先頭に位置する value="" の <option> の見出し文字列。 | |
192 | + * @return 作成したHTML。 | |
193 | + */ | |
194 | + public static function select($type, $attributes) { | |
195 | + | |
196 | + // 引数に指定されている choice, label-format, value, options, glue を取り出す。 | |
197 | + $value = @ArrayUtil::eject($attributes, 'value'); | |
198 | + $choices = @ArrayUtil::eject($attributes, 'choice'); | |
199 | + $format = @ArrayUtil::eject($attributes, 'label-format') ?? '%1$s'; | |
200 | + $options = @ArrayUtil::eject($attributes, 'options'); | |
201 | + $glue = @ArrayUtil::eject($attributes, 'glue') ?? "\n"; | |
202 | + | |
203 | + // 種別によって分岐。 | |
204 | + switch( strtolower($type) ) { | |
205 | + | |
206 | + case 'select': | |
207 | + | |
208 | + // options がない場合は choice や label-format などを見て生成する。 | |
209 | + if( !isset($options) ) { | |
210 | + | |
211 | + foreach($choices as $key => $label) { | |
212 | + $pars = array('type'=>'option', 'value'=>$key, 'label'=>sprintf($format, $label, $key), 'checkif'=>$value); | |
213 | + $options[] = self::choice($pars); | |
214 | + } | |
215 | + | |
216 | + // 引数に指定されている placeholder を取り出して、指定されている場合は最初の選択肢として追加する。 | |
217 | + $placeholder = @ArrayUtil::eject($attributes, 'placeholder'); | |
218 | + if( isset($placeholder) ) | |
219 | + array_unshift( $options, self::choice(array('type'=>'option', 'value'=>'', 'label'=>$placeholder)) ); | |
220 | + } | |
221 | + | |
222 | + // options を <select> で囲んでリターン。 | |
223 | + return HtmlUtil::tag('select', $attributes, $options, true); | |
224 | + | |
225 | + case 'radios': | |
226 | + | |
227 | + // options がない場合は choice や label-format などを見て生成する。 | |
228 | + if( !isset($options) ) { | |
229 | + | |
230 | + // 引数に指定されている属性を生かす形で選択肢を生成していく。 | |
231 | + $attributes['type'] = 'radio'; | |
232 | + foreach($choices as $key => $label) { | |
233 | + $attributes['value'] = $key; | |
234 | + $attributes['label'] = sprintf($format, $label, $key); | |
235 | + $attributes['checkif'] = $value; | |
236 | + $options[] = self::choice($attributes); | |
237 | + } | |
238 | + } | |
239 | + | |
240 | + // glue で接続してリターン。 | |
241 | + return implode($glue, $options); | |
242 | + | |
243 | + case 'checks': | |
244 | + | |
245 | + // options がない場合は choice や label-format などを見て生成する。 | |
246 | + if( !isset($options) ) { | |
247 | + | |
248 | + // name を少し加工して、フォーム送信時にPHPが配列として処理するようにする。 | |
249 | + if(@$attributes['name']) | |
250 | + $attributes['name'] .= '[]'; | |
251 | + | |
252 | + // 引数に指定されている属性を生かす形で選択肢を生成していく。 | |
253 | + $attributes['type'] = 'check'; | |
254 | + foreach($choices as $key => $label) { | |
255 | + $attributes['value'] = $key; | |
256 | + $attributes['label'] = sprintf($format, $label, $key); | |
257 | + $attributes['checkif'] = (array)$value; | |
258 | + $options[] = self::choice($attributes); | |
259 | + } | |
260 | + } | |
261 | + | |
262 | + // glue で接続してリターン。 | |
263 | + return implode($glue, $options); | |
264 | + | |
265 | + default: | |
266 | + throw new ErrorException("定義されていない引数値 '{$type}' です。"); | |
267 | + } | |
268 | + } | |
269 | + | |
270 | + //----------------------------------------------------------------------------------------------------- | |
271 | + /** | |
272 | + * 引数に指定された情報でセレクトボックスの <option> やチェックボックス・ラジオボタンなどの、選択肢の一つを表すHTML文字列を作成する。 | |
273 | + * チェック・ラジオでは <label> も設定される。 | |
274 | + * | |
275 | + * @param HTML要素の属性だが、以下のキーは特別に処理される。 | |
276 | + * type 以下のいずれか。省略時はラジオボタン | |
277 | + * radio ラジオボタン。デフォルト。 | |
278 | + * check チェックボックス | |
279 | + * checkbox 上と同じ | |
280 | + * option <option>タグ | |
281 | + * label 選択肢名。ラジオボタンやチェックボックスの場合に指定すると <label> タグも出力する。 | |
282 | + * checkif valueの値がここで指定した値と一致しているなら選択状態になるようにする。 | |
283 | + * 配列を指定するといずれか一つと一致すれば選択状態になる。 | |
284 | + * @return 作成したHTML。 | |
285 | + */ | |
286 | + public static function choice($attributes) { | |
287 | + | |
288 | + // 種別を取り出す。 | |
289 | + $type = @ArrayUtil::eject($attributes, 'type') ?: 'radio'; | |
290 | + | |
291 | + // "check" は "checkbox" に統一する。 | |
292 | + if($type == 'check') $type = 'checkbox'; | |
293 | + | |
294 | + // 選択肢名を取り出す。 | |
295 | + $label = @ArrayUtil::eject($attributes, 'label'); | |
296 | + | |
297 | + // value属性の値が checkif の指定に含まれるなら選択状態にする。 | |
298 | + $checkif = @ArrayUtil::eject($attributes, 'checkif'); | |
299 | + $checked = in_array(@$attributes['value'], (array)$checkif); | |
300 | + | |
301 | + // 種別に従って出力。 | |
302 | + switch( strtolower($type) ) { | |
303 | + | |
304 | + case 'radio': | |
305 | + case 'checkbox': | |
306 | + | |
307 | + // <label> でリンクするために id 属性が必要なため、指定されていない場合は作成する。 | |
308 | + // …実は、<input>を<label>で囲んでしまえば id も for も必要ないのだが、まあ一応。 | |
309 | + if( !@$attributes['id'] ) { | |
310 | + $attributes['id'] = @$attributes['name'] . '_' . @$attributes['value']; | |
311 | + if($attributes['id'] == '_') | |
312 | + $attributes['id'] = uniqid(); | |
313 | + } | |
314 | + | |
315 | + // 選択状態にするかどうかを決定。 | |
316 | + if( !isset($attributes['checked']) ) $attributes['checked'] = $checked; | |
317 | + | |
318 | + // <input> タグを作成。 | |
319 | + $attributes['type'] = $type; | |
320 | + $result = HtmlUtil::tag('input', $attributes); | |
321 | + | |
322 | + // 選択肢名があるなら <label> で囲む。 | |
323 | + if(strlen($label) > 0) { | |
324 | + | |
325 | + // <label> の for 属性も補う。 | |
326 | + // ただ、明示的に for 属性が指定されているならそちらを使う。jsでクローンするためにidやforを出したくないときなどに需要がある。 | |
327 | + $for = $attributes['for'] ?? $attributes['id']; | |
328 | + $pair = $result . ViewUtil::encode($label); | |
329 | + return HtmlUtil::tag('label', array('for'=>$for), $pair, true); | |
330 | + } | |
331 | + | |
332 | + return $result; | |
333 | + | |
334 | + case 'option': | |
335 | + | |
336 | + if( !isset($attributes['selected']) ) $attributes['selected'] = $checked; | |
337 | + | |
338 | + return HtmlUtil::tag($type, $attributes, $label); | |
339 | + | |
340 | + default: | |
341 | + trigger_error("'type' に指定された値 {$type} には対応していません。"); | |
342 | + } | |
343 | + } | |
344 | +} |
@@ -268,343 +268,6 @@ | ||
268 | 268 | |
269 | 269 | //----------------------------------------------------------------------------------------------------- |
270 | 270 | /** |
271 | - * 引数に指定された情報でHTMLタグを作成する。 | |
272 | - * | |
273 | - * @param タグ名。"a" とか "hr" とか。 | |
274 | - * @param 属性名をキー、値を値とする配列。ViewUtil::attributes() に指定できる値。 | |
275 | - * @param タグで挟みたい内容がある場合は指定する。この場合、終了タグも一緒に返される。 | |
276 | - * 省略した場合、返されるタグは閉じタグが省略されたもの( <xxxx /> の形式)になる。 | |
277 | - * 配列を指定した場合は \n で連結された文字列に変換される。 | |
278 | - * @param 第三引数がすでにHTMLエンコード済みの場合は true を指定する。 | |
279 | - * falseの場合はエンコードされる。 | |
280 | - * @return 作成したHTML。 | |
281 | - */ | |
282 | - public static function tag($tagName, $attributes = array(), $content = null, $encoded = false) { | |
283 | - | |
284 | - $tag = "<{$tagName}" . self::attributes($attributes); | |
285 | - | |
286 | - if( is_null($content) ) | |
287 | - return $tag . ' />'; | |
288 | - | |
289 | - if( is_array($content) ) | |
290 | - $content = "\n" . implode("\n", $content) . "\n"; | |
291 | - | |
292 | - if(!$encoded) | |
293 | - $content = self::encode($content); | |
294 | - | |
295 | - return "{$tag}>{$content}</{$tagName}>"; | |
296 | - } | |
297 | - | |
298 | - //----------------------------------------------------------------------------------------------------- | |
299 | - /** | |
300 | - * 引数に指定された配列をHTMLタグの属性として展開する。 | |
301 | - * | |
302 | - * 例) | |
303 | - * $return = ViewUtil::attributes( array('abc'=>'ABC', 'def'=>'DEF', 'ghi'=>'333') ); | |
304 | - * // $return は次のような文字列になる。 | |
305 | - * // abc="ABC" def="DEF" ghi="333" | |
306 | - * | |
307 | - * 値が真偽値の true になっている場合、XHTML向けにキーと同じ値として処理される。 | |
308 | - * また、false, null のキーは出力されない。 | |
309 | - * 例) | |
310 | - * $return = ViewUtil::attributes( array('abc'=>true, 'def'=>true, 'ghi'=>false, 'jkl'=>null) ); | |
311 | - * // abc="abc" def="def" | |
312 | - * | |
313 | - * style の値を配列とすることもできる。その場合はCSSのキーと値の列挙として処理する。 | |
314 | - * 例) | |
315 | - * $return = ViewUtil::attributes( array('abc'=>'ABC', 'style'=>array('def'=>'DEF', 'ghi'=>'333')) ); | |
316 | - * // abc="ABC" style="def:DEF; ghi:333;" | |
317 | - * | |
318 | - * style の配列の数値キーはそのまま追加される。 | |
319 | - * 例) | |
320 | - * $return = ViewUtil::attributes(array( 'style'=>array('abc:ABC', 'def'=>'DEF', 'ghi'=>'333') )); | |
321 | - * // style="abc:ABC; def:DEF; ghi:333;" | |
322 | - * | |
323 | - * @param 属性として展開したい配列。 | |
324 | - * @return 属性として展開した文字列。 | |
325 | - */ | |
326 | - public static function attributes($attributes) { | |
327 | - | |
328 | - // "style" の値が配列になっている場合は文字列に直す。 | |
329 | - if( is_array(@$attributes['style']) ) { | |
330 | - | |
331 | - $style = ''; | |
332 | - foreach($attributes['style'] as $propName => $propValue) { | |
333 | - | |
334 | - if( is_null($propValue) ) | |
335 | - continue; | |
336 | - | |
337 | - if( is_int($propName) ) | |
338 | - $style .= $propValue . '; '; | |
339 | - else | |
340 | - $style .= "{$propName}:{$propValue}; "; | |
341 | - } | |
342 | - | |
343 | - $attributes['style'] = $style; | |
344 | - } | |
345 | - | |
346 | - // 戻り値初期化。 | |
347 | - $result = ''; | |
348 | - | |
349 | - // HTMLの属性として展開していく。 | |
350 | - foreach($attributes as $name => $value) { | |
351 | - | |
352 | - // 値が真偽値の true の場合、XHTML向けにキーと同じ値とする。 | |
353 | - if($value === true) | |
354 | - $value = $name; | |
355 | - | |
356 | - // null, false 以外であれば出力する。 | |
357 | - if( !(is_null($value) || $value === false) ) | |
358 | - $result .= sprintf(' %s="%s"', self::encode($name), self::encode($value)); | |
359 | - } | |
360 | - | |
361 | - // リターン。 | |
362 | - return $result; | |
363 | - } | |
364 | - | |
365 | - //----------------------------------------------------------------------------------------------------- | |
366 | - /** | |
367 | - * 引数に指定された情報で入力フォームの一項目を表すHTML文字列を作成する。<input> や <textarea> を始め、ViewUtil::select() で説明されている | |
368 | - * 選択肢グループにも対応する。 | |
369 | - * | |
370 | - * @param 基本的にはHTML要素の属性だが、以下のキーは特別に処理される。 | |
371 | - * type <input> の type 属性だが、次のいずれかの場合は特別に処理される。省略時は "text"。 | |
372 | - * select <option>を含む <select> を作成する。 | |
373 | - * radios ラジオボタンのグループを作成する。 | |
374 | - * checks チェックボックスのグループを作成する。 | |
375 | - * check, checkbox | |
376 | - * 単体チェックボックスを作成する。 | |
377 | - * label も指定されている場合は <label> で囲むように生成される。 | |
378 | - * textarea <textarea> を作成する。 | |
379 | - * choice typeの値が select, radios, checks の場合に、選択肢の配列。options を指定した場合はそちらが優先される。 | |
380 | - * キーでvalueを、値で選択肢名を指定する。選択肢名は次のキーで操作することも出来る。 | |
381 | - * label-format choice の選択肢名を生成するときの sprintf フォーマット文字列。%1$ が値、%2$ がキーとなる。 | |
382 | - * 省略した場合は "%1$s"。 | |
383 | - * value typeの値が select, radios, checks の場合は、最初に選択状態になっている選択肢のキー。 | |
384 | - * textarea では最初に入力されている値。それ以外では、普通に <input> のvalue属性となる。 | |
385 | - * options choice を指定するならそちらから生成できるので省略できる。 | |
386 | - * typeの値が select の場合、一つの <option> HTML文字列を1要素とした配列。 | |
387 | - * radios, checks の場合は、一つの <input> HTML文字列を1要素とした配列。 | |
388 | - * glue typeの値が radios, checks の場合に、各選択肢をつなげるHTML。省略時は "\n"。 | |
389 | - * placeholder 普通に <input> の placeholder 属性だが、type=select の場合は一番先頭に位置 | |
390 | - * する value="" の <option> の見出し文字列となる。 | |
391 | - * @return 作成したHTML。 | |
392 | - */ | |
393 | - public static function input($attributes) { | |
394 | - | |
395 | - // 種別を取り出す。 | |
396 | - $origtype = @ArrayUtil::eject($attributes, 'type') ?: 'text'; | |
397 | - $type = strtolower($origtype); | |
398 | - | |
399 | - // 種別 select, radios, checks はこちらで処理する。 | |
400 | - if( in_array($type, ['select', 'radios', 'checks']) ) | |
401 | - return static::select($type, $attributes); | |
402 | - | |
403 | - // 日時系のコントロールを使うときに、valueをいつもの形式で指定できるように少し面倒を見てやる。 | |
404 | - switch( $type ) { | |
405 | - | |
406 | - // "datetime-local" を使うときは、valueの日付と時刻の区切り文字を "T" にする必要がある。 | |
407 | - case 'datetime-local': $attributes['value'] = preg_replace('/(?<=\d)\s+(?=\d)/', 'T', $attributes['value']); break; | |
408 | - | |
409 | - // type="date" を使うときは時刻部分があってはならない。面倒くさいなぁ… | |
410 | - case 'date': $attributes['value'] = preg_replace('/\s*\d*\s*:\s*\d*\s*/', '', $attributes['value']); break; | |
411 | - | |
412 | - // type="month" を使うときは年・月のみでなければならない。もうちょっと融通をだな… | |
413 | - case 'month': $attributes['value'] = preg_replace('/^(\d+\W\d+).*/', '$1', $attributes['value']); break; | |
414 | - } | |
415 | - | |
416 | - // 種別によって処理する。 | |
417 | - switch($type) { | |
418 | - | |
419 | - // 単体チェックボックスを作成する場合。 | |
420 | - case 'check': | |
421 | - case 'checkbox': | |
422 | - $attributes['type'] = $type; | |
423 | - return ViewUtil::choice($attributes); | |
424 | - | |
425 | - // <textarea> を作成する場合。 | |
426 | - case 'textarea': | |
427 | - $value = @ArrayUtil::eject($attributes, 'value'); | |
428 | - return ViewUtil::tag('textarea', $attributes, (string)$value); // stringキャストしているのは、null だったら閉じタグなしになってしまうため。 | |
429 | - | |
430 | - // それ以外では <input> を生成する。 | |
431 | - default: | |
432 | - $attributes['type'] = $origtype; | |
433 | - return ViewUtil::tag('input', $attributes); | |
434 | - } | |
435 | - } | |
436 | - | |
437 | - //----------------------------------------------------------------------------------------------------- | |
438 | - /** | |
439 | - * 引数に指定された情報で、セレクトボックスやラジオボタンのような選択肢グループを表すHTML文字列を作成する。 | |
440 | - * | |
441 | - * @param 種別。select, radios, checks のいずれか。 | |
442 | - * @param select の場合は<select>タグの属性、radios, checks では各<input>タグの属性だが、以下のキーは特別に処理される。 | |
443 | - * choice 選択肢の配列。options を指定した場合はそちらが優先される。 | |
444 | - * キーでvalueを、値で選択肢名を指定する。選択肢名は次のキーで操作することも出来る。 | |
445 | - * label-format choice の選択肢名を生成するときの sprintf フォーマット文字列。%1$ が値、%2$ がキーとなる。 | |
446 | - * 省略した場合は "%1$s"。 | |
447 | - * value 最初に選択状態になっている選択肢のキー。 | |
448 | - * options choice を指定するならそちらから生成されるので省略できる。 | |
449 | - * select の場合は一つの <option> HTML文字列を1要素とした配列。 | |
450 | - * radios, checks の場合は一つの <input> HTML文字列を1要素とした配列。 | |
451 | - * glue radios, checks の場合に、各選択肢をつなげるHTML。省略時は "\n"。 | |
452 | - * placeholder select の場合は、一番先頭に位置する value="" の <option> の見出し文字列。 | |
453 | - * @return 作成したHTML。 | |
454 | - */ | |
455 | - public static function select($type, $attributes) { | |
456 | - | |
457 | - // 引数に指定されている choice, label-format, value, options, glue を取り出す。 | |
458 | - $value = @ArrayUtil::eject($attributes, 'value'); | |
459 | - $choices = @ArrayUtil::eject($attributes, 'choice'); | |
460 | - $format = @ArrayUtil::eject($attributes, 'label-format') ?? '%1$s'; | |
461 | - $options = @ArrayUtil::eject($attributes, 'options'); | |
462 | - $glue = @ArrayUtil::eject($attributes, 'glue') ?? "\n"; | |
463 | - | |
464 | - // 種別によって分岐。 | |
465 | - switch( strtolower($type) ) { | |
466 | - | |
467 | - case 'select': | |
468 | - | |
469 | - // options がない場合は choice や label-format などを見て生成する。 | |
470 | - if( !isset($options) ) { | |
471 | - | |
472 | - foreach($choices as $key => $label) { | |
473 | - $pars = array('type'=>'option', 'value'=>$key, 'label'=>sprintf($format, $label, $key), 'checkif'=>$value); | |
474 | - $options[] = self::choice($pars); | |
475 | - } | |
476 | - | |
477 | - // 引数に指定されている placeholder を取り出して、指定されている場合は最初の選択肢として追加する。 | |
478 | - $placeholder = @ArrayUtil::eject($attributes, 'placeholder'); | |
479 | - if( isset($placeholder) ) | |
480 | - array_unshift( $options, self::choice(array('type'=>'option', 'value'=>'', 'label'=>$placeholder)) ); | |
481 | - } | |
482 | - | |
483 | - // options を <select> で囲んでリターン。 | |
484 | - return ViewUtil::tag('select', $attributes, $options, true); | |
485 | - | |
486 | - case 'radios': | |
487 | - | |
488 | - // options がない場合は choice や label-format などを見て生成する。 | |
489 | - if( !isset($options) ) { | |
490 | - | |
491 | - // 引数に指定されている属性を生かす形で選択肢を生成していく。 | |
492 | - $attributes['type'] = 'radio'; | |
493 | - foreach($choices as $key => $label) { | |
494 | - $attributes['value'] = $key; | |
495 | - $attributes['label'] = sprintf($format, $label, $key); | |
496 | - $attributes['checkif'] = $value; | |
497 | - $options[] = self::choice($attributes); | |
498 | - } | |
499 | - } | |
500 | - | |
501 | - // glue で接続してリターン。 | |
502 | - return implode($glue, $options); | |
503 | - | |
504 | - case 'checks': | |
505 | - | |
506 | - // options がない場合は choice や label-format などを見て生成する。 | |
507 | - if( !isset($options) ) { | |
508 | - | |
509 | - // name を少し加工して、フォーム送信時にPHPが配列として処理するようにする。 | |
510 | - if(@$attributes['name']) | |
511 | - $attributes['name'] .= '[]'; | |
512 | - | |
513 | - // 引数に指定されている属性を生かす形で選択肢を生成していく。 | |
514 | - $attributes['type'] = 'check'; | |
515 | - foreach($choices as $key => $label) { | |
516 | - $attributes['value'] = $key; | |
517 | - $attributes['label'] = sprintf($format, $label, $key); | |
518 | - $attributes['checkif'] = (array)$value; | |
519 | - $options[] = self::choice($attributes); | |
520 | - } | |
521 | - } | |
522 | - | |
523 | - // glue で接続してリターン。 | |
524 | - return implode($glue, $options); | |
525 | - | |
526 | - default: | |
527 | - throw new ErrorException("定義されていない引数値 '{$type}' です。"); | |
528 | - } | |
529 | - } | |
530 | - | |
531 | - //----------------------------------------------------------------------------------------------------- | |
532 | - /** | |
533 | - * 引数に指定された情報でセレクトボックスの <option> やチェックボックス・ラジオボタンなどの、選択肢の一つを表すHTML文字列を作成する。 | |
534 | - * チェック・ラジオでは <label> も設定される。 | |
535 | - * | |
536 | - * @param HTML要素の属性だが、以下のキーは特別に処理される。 | |
537 | - * type 以下のいずれか。省略時はラジオボタン | |
538 | - * radio ラジオボタン。デフォルト。 | |
539 | - * check チェックボックス | |
540 | - * checkbox 上と同じ | |
541 | - * option <option>タグ | |
542 | - * label 選択肢名。ラジオボタンやチェックボックスの場合に指定すると <label> タグも出力する。 | |
543 | - * checkif valueの値がここで指定した値と一致しているなら選択状態になるようにする。 | |
544 | - * 配列を指定するといずれか一つと一致すれば選択状態になる。 | |
545 | - * @return 作成したHTML。 | |
546 | - */ | |
547 | - public static function choice($attributes) { | |
548 | - | |
549 | - // 種別を取り出す。 | |
550 | - $type = @ArrayUtil::eject($attributes, 'type') ?: 'radio'; | |
551 | - | |
552 | - // "check" は "checkbox" に統一する。 | |
553 | - if($type == 'check') $type = 'checkbox'; | |
554 | - | |
555 | - // 選択肢名を取り出す。 | |
556 | - $label = @ArrayUtil::eject($attributes, 'label'); | |
557 | - | |
558 | - // value属性の値が checkif の指定に含まれるなら選択状態にする。 | |
559 | - $checkif = @ArrayUtil::eject($attributes, 'checkif'); | |
560 | - $checked = in_array(@$attributes['value'], (array)$checkif); | |
561 | - | |
562 | - // 種別に従って出力。 | |
563 | - switch( strtolower($type) ) { | |
564 | - | |
565 | - case 'radio': | |
566 | - case 'checkbox': | |
567 | - | |
568 | - // <label> でリンクするために id 属性が必要なため、指定されていない場合は作成する。 | |
569 | - // …実は、<input>を<label>で囲んでしまえば id も for も必要ないのだが、まあ一応。 | |
570 | - if( !@$attributes['id'] ) { | |
571 | - $attributes['id'] = @$attributes['name'] . '_' . @$attributes['value']; | |
572 | - if($attributes['id'] == '_') | |
573 | - $attributes['id'] = uniqid(); | |
574 | - } | |
575 | - | |
576 | - // 選択状態にするかどうかを決定。 | |
577 | - if( !isset($attributes['checked']) ) $attributes['checked'] = $checked; | |
578 | - | |
579 | - // <input> タグを作成。 | |
580 | - $attributes['type'] = $type; | |
581 | - $result = ViewUtil::tag('input', $attributes); | |
582 | - | |
583 | - // 選択肢名があるなら <label> で囲む。 | |
584 | - if(strlen($label) > 0) { | |
585 | - | |
586 | - // <label> の for 属性も補う。 | |
587 | - // ただ、明示的に for 属性が指定されているならそちらを使う。jsでクローンするためにidやforを出したくないときなどに需要がある。 | |
588 | - $for = $attributes['for'] ?? $attributes['id']; | |
589 | - $pair = $result . ViewUtil::encode($label); | |
590 | - return ViewUtil::tag('label', array('for'=>$for), $pair, true); | |
591 | - } | |
592 | - | |
593 | - return $result; | |
594 | - | |
595 | - case 'option': | |
596 | - | |
597 | - if( !isset($attributes['selected']) ) $attributes['selected'] = $checked; | |
598 | - | |
599 | - return ViewUtil::tag($type, $attributes, $label); | |
600 | - | |
601 | - default: | |
602 | - trigger_error("'type' に指定された値 {$type} には対応していません。"); | |
603 | - } | |
604 | - } | |
605 | - | |
606 | - //----------------------------------------------------------------------------------------------------- | |
607 | - /** | |
608 | 271 | * 引数に指定された文字列をエンコードして返す。 |
609 | 272 | * |
610 | 273 | * @param エンコードしたい文字列。 |