form.php 13.9 KB
Newer Older
Taylor Otwell committed
1
<?php namespace Laravel;
2 3 4 5

class Form {

	/**
Taylor Otwell committed
6 7
	 * All of the label names that have been created.
	 *
8 9
	 * @var array
	 */
10
	public static $labels = array();
11 12
	
	/**
13
	 * The registered custom macros.
14 15 16
	 *
	 * @var array
	 */
17
	public static $macros = array();
18

19 20 21 22 23 24 25 26
    /**
     * Registers a custom macro.
     *
     * @param  string   $name
     * @param  Closure  $input
     * @return void
     */
	public static function macro($name, $macro)
27
	{
28
		static::$macros[$name] = $macro;
29
	}
30 31

	/**
32 33
	 * Open a HTML form.
	 *
34 35 36 37 38 39 40 41 42 43 44 45 46
	 * <code>
	 *		// Open a "POST" form to the current request URI
	 *		echo Form::open();
	 *
	 *		// Open a "POST" form to a given URI
	 *		echo Form::open('user/profile');
	 *
	 *		// Open a "PUT" form to a given URI
	 *		echo Form::open('user/profile', 'put');
	 *
	 *		// Open a form that has HTML attributes
	 *		echo Form::open('user/profile', 'post', array('class' => 'profile'));
	 * </code>
Taylor Otwell committed
47
	 *
48 49 50 51
	 * @param  string   $action
	 * @param  string   $method
	 * @param  array    $attributes
	 * @param  bool     $https
52
	 * @return string
53
	 */
54
	public static function open($action = null, $method = 'POST', $attributes = array(), $https = false)
55
	{
56 57
		$method = strtoupper($method);

58
		$attributes['method'] =  static::method($method);
59 60
		
		$attributes['action'] = static::action($action, $https);
61

62 63 64
		// If a character encoding has not been specified in the attributes, we will
		// use the default encoding as specified in the application configuration
		// file for the "accept-charset" attribute.
65 66
		if ( ! array_key_exists('accept-charset', $attributes))
		{
67
			$attributes['accept-charset'] = Config::get('application.encoding');
68 69
		}

Taylor Otwell committed
70 71
		$append = '';

72 73
		// Since PUT and DELETE methods are not actually supported by HTML forms,
		// we'll create a hidden input element that contains the request method
74
		// and set the actual request method variable to POST.
Taylor Otwell committed
75 76 77 78
		if ($method == 'PUT' or $method == 'DELETE')
		{
			$append = static::hidden(Request::spoofer, $method);
		}
79

80
		return '<form'.HTML::attributes($attributes).'>'.$append;
Taylor Otwell committed
81 82 83 84 85 86 87 88
	}

	/**
	 * Determine the appropriate request method to use for a form.
	 *
	 * @param  string  $method
	 * @return string
	 */
89
	protected static function method($method)
Taylor Otwell committed
90
	{
91
		return ($method !== 'GET') ? 'POST' : $method;
Taylor Otwell committed
92
	}
93

Taylor Otwell committed
94 95 96 97 98
	/**
	 * Determine the appropriate action parameter to use for a form.
	 *
	 * If no action is specified, the current request URI will be used.
	 *
99 100
	 * @param  string   $action
	 * @param  bool     $https
Taylor Otwell committed
101 102
	 * @return string
	 */
103
	protected static function action($action, $https)
Taylor Otwell committed
104
	{
105 106 107
		$uri = (is_null($action)) ? URI::current() : $action;

		return HTML::entities(URL::to($uri, $https));
108 109 110
	}

	/**
Taylor Otwell committed
111
	 * Open a HTML form with a HTTPS action URI.
112 113 114 115 116 117
	 *
	 * @param  string  $action
	 * @param  string  $method
	 * @param  array   $attributes
	 * @return string
	 */
118
	public static function open_secure($action = null, $method = 'POST', $attributes = array())
119
	{
120
		return static::open($action, $method, $attributes, true);
121 122 123
	}

	/**
124 125 126 127 128
	 * Open a HTML form that accepts file uploads.
	 *
	 * @param  string  $action
	 * @param  string  $method
	 * @param  array   $attributes
129
	 * @param  bool    $https
130 131
	 * @return string
	 */	
132
	public static function open_for_files($action = null, $method = 'POST', $attributes = array(), $https = false)
133 134 135
	{
		$attributes['enctype'] = 'multipart/form-data';

136
		return static::open($action, $method, $attributes, $https);
137 138 139
	}

	/**
Taylor Otwell committed
140
	 * Open a HTML form that accepts file uploads with a HTTPS action URI.
141 142 143 144 145 146
	 *
	 * @param  string  $action
	 * @param  string  $method
	 * @param  array   $attributes
	 * @return string
	 */	
147
	public static function open_secure_for_files($action = null, $method = 'POST', $attributes = array())
148
	{
149
		return static::open_for_files($action, $method, $attributes, true);
150 151 152
	}

	/**
Taylor Otwell committed
153 154 155 156
	 * Close a HTML form.
	 *
	 * @return string
	 */
157
	public static function close()
Taylor Otwell committed
158 159 160 161 162
	{
		return '</form>';
	}

	/**
163 164 165 166
	 * Generate a hidden field containing the current CSRF token.
	 *
	 * @return string
	 */
167
	public static function token()
168
	{
169
		return static::input('hidden', Session::csrf_token, Session::token());
170 171 172 173
	}

	/**
	 * Create a HTML label element.
Taylor Otwell committed
174
	 *
175 176 177 178 179
	 * <code>
	 *		// Create a label for the "email" input element
	 *		echo Form::label('email', 'E-Mail Address');
	 * </code>
	 *
180 181 182 183 184
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
	 */		
185
	public static function label($name, $value, $attributes = array())
186
	{
187
		static::$labels[] = $name;
Taylor Otwell committed
188

Taylor Otwell committed
189 190 191 192
		$attributes = HTML::attributes($attributes);

		$value = HTML::entities($value);

193
		return '<label for="'.$name.'"'.$attributes.'>'.$value.'</label>';
194 195 196
	}

	/**
Taylor Otwell committed
197
	 * Create a HTML input element.
198
	 *
199 200 201 202 203 204 205 206
	 * <code>
	 *		// Create a "text" input element named "email"
	 *		echo Form::input('text', 'email');
	 *
	 *		// Create an input element with a specified default value
	 *		echo Form::input('text', 'email', 'example@gmail.com');
	 * </code>
	 *
Phill Sparks committed
207
	 * @param  string  $type
208
	 * @param  string  $name
Taylor Otwell committed
209
	 * @param  mixed   $value
210 211 212
	 * @param  array   $attributes
	 * @return string
	 */		
213
	public static function input($type, $name, $value = null, $attributes = array())
214
	{
215 216
		$name = (isset($attributes['name'])) ? $attributes['name'] : $name;

217
		$id = static::id($name, $attributes);
218

219 220
		$attributes = array_merge($attributes, compact('type', 'name', 'value', 'id'));

221
		return '<input'.HTML::attributes($attributes).'>';
222 223 224
	}

	/**
225 226 227 228 229 230 231
	 * Create a HTML text input element.
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
	 */
232
	public static function text($name, $value = null, $attributes = array())
233
	{
234
		return static::input('text', $name, $value, $attributes);
235 236 237
	}

	/**
238 239 240 241 242
	 * Create a HTML password input element.
	 *
	 * @param  string  $name
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
243
	 */		
244
	public static function password($name, $attributes = array())
245
	{
246
		return static::input('password', $name, null, $attributes);
247 248 249
	}

	/**
250 251 252 253 254 255 256
	 * Create a HTML hidden input element.
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
	 */
257
	public static function hidden($name, $value = null, $attributes = array())
258
	{
259
		return static::input('hidden', $name, $value, $attributes);
260 261 262
	}

	/**
263 264 265 266 267 268
	 * Create a HTML search input element.
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
269
	 */		
270
	public static function search($name, $value = null, $attributes = array())
271
	{
272
		return static::input('search', $name, $value, $attributes);
273 274 275
	}

	/**
276
	 * Create a HTML email input element.
277 278 279 280 281
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
282
	 */		
283
	public static function email($name, $value = null, $attributes = array())
284
	{
285
		return static::input('email', $name, $value, $attributes);
286 287 288
	}

	/**
289
	 * Create a HTML telephone input element.
290 291 292 293 294
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
295
	 */
296
	public static function telephone($name, $value = null, $attributes = array())
297
	{
298
		return static::input('tel', $name, $value, $attributes);
299 300 301
	}

	/**
302
	 * Create a HTML URL input element.
303 304 305 306 307
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
308
	 */		
309
	public static function url($name, $value = null, $attributes = array())
310
	{
311
		return static::input('url', $name, $value, $attributes);
312 313 314
	}

	/**
Taylor Otwell committed
315
	 * Create a HTML number input element.
316 317 318 319 320
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
321
	 */		
322
	public static function number($name, $value = null, $attributes = array())
323
	{
324
		return static::input('number', $name, $value, $attributes);
325
	}
326 327 328 329 330 331 332 333 334 335 336 337 338
	
	/**
	 * Create a HTML date input element.
	 *
	 * @param  string  $name
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
	 */		
	public static function date($name, $value = null, $attributes = array())
	{
		return static::input('date', $name, $value, $attributes);
	}
339 340

	/**
341 342 343 344 345 346
	 * Create a HTML file input element.
	 *
	 * @param  string  $name
	 * @param  array   $attributes
	 * @return string
	 */			
347
	public static function file($name, $attributes = array())
348
	{
349
		return static::input('file', $name, null, $attributes);
350 351 352
	}

	/**
Taylor Otwell committed
353
	 * Create a HTML textarea element.
354
	 *
Taylor Otwell committed
355
	 * @param  string  $name
356
	 * @param  string  $value
357 358 359
	 * @param  array   $attributes
	 * @return string
	 */
360
	public static function textarea($name, $value = '', $attributes = array())
361
	{
Taylor Otwell committed
362 363 364
		$attributes['name'] = $name;

		$attributes['id'] = static::id($name, $attributes);
365

366
		if ( ! isset($attributes['rows'])) $attributes['rows'] = 10;
367

368
		if ( ! isset($attributes['cols'])) $attributes['cols'] = 50;
Taylor Otwell committed
369

370
		return '<textarea'.HTML::attributes($attributes).'>'.HTML::entities($value).'</textarea>';
371 372 373
	}

	/**
Taylor Otwell committed
374
	 * Create a HTML select element.
375
	 *
376 377 378 379 380 381 382 383
	 * <code>
	 *		// Create a HTML select element filled with options
	 *		echo Form::select('sizes', array('S' => 'Small', 'L' => 'Large'));
	 *
	 *		// Create a select element with a default selected value
	 *		echo Form::select('sizes', array('S' => 'Small', 'L' => 'Large'), 'L');
	 * </code>
	 *
384
	 * @param  string  $name
Taylor Otwell committed
385 386
	 * @param  array   $options
	 * @param  string  $selected
387 388
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
389
	 */	
390
	public static function select($name, $options = array(), $selected = null, $attributes = array())
391
	{
392 393 394
		$attributes['id'] = static::id($name, $attributes);
		
		$attributes['name'] = $name;
Taylor Otwell committed
395 396 397 398 399

		$html = array();

		foreach ($options as $value => $display)
		{
400
			$html[] = static::option($value, $display, $selected);
Taylor Otwell committed
401 402
		}

403
		return '<select'.HTML::attributes($attributes).'>'.implode('', $html).'</select>';
404 405 406
	}

	/**
407 408 409 410
	 * Create a HTML select element option.
	 *
	 * @param  string  $value
	 * @param  string  $display
Phill Sparks committed
411
	 * @param  string  $selected
412 413 414 415
	 * @return string
	 */
	protected static function option($value, $display, $selected)
	{
416 417 418 419 420 421 422 423
		if (is_array($selected))
		{
			$selected = (in_array($value, $selected)) ? 'selected' : null;
		}
		else
		{
			$selected = ($value == $selected) ? 'selected' : null;
		}
424 425 426 427 428 429 430

		$attributes = array('value' => HTML::entities($value), 'selected' => $selected);

		return '<option'.HTML::attributes($attributes).'>'.HTML::entities($display).'</option>';
	}

	/**
431 432
	 * Create a HTML checkbox input element.
	 *
433 434 435 436 437 438 439 440
	 * <code>
	 *		// Create a checkbox element
	 *		echo Form::checkbox('terms', 'yes');
	 *
	 *		// Create a checkbox that is selected by default
	 *		echo Form::checkbox('terms', 'yes', true);
	 * </code>
	 *
441 442 443 444 445 446
	 * @param  string  $name
	 * @param  string  $value
	 * @param  bool    $checked
	 * @param  array   $attributes
	 * @return string
	 */
447
	public static function checkbox($name, $value = 1, $checked = false, $attributes = array())
448
	{
449
		return static::checkable('checkbox', $name, $value, $checked, $attributes);
450 451 452 453 454
	}

	/**
	 * Create a HTML radio button input element.
	 *
455 456 457 458 459 460 461 462
	 * <code>
	 *		// Create a radio button element
	 *		echo Form::radio('drinks', 'Milk');
	 *
	 *		// Create a radio button that is selected by default
	 *		echo Form::radio('drinks', 'Milk', true);
	 * </code>
	 *
463 464 465 466 467 468
	 * @param  string  $name
	 * @param  string  $value
	 * @param  bool    $checked
	 * @param  array   $attributes
	 * @return string
	 */
469
	public static function radio($name, $value = null, $checked = false, $attributes = array())
470
	{
471 472
		if (is_null($value)) $value = $name;

473
		return static::checkable('radio', $name, $value, $checked, $attributes);
474 475 476 477 478 479 480 481 482 483 484 485
	}

	/**
	 * Create a checkable input element.
	 *
	 * @param  string  $type
	 * @param  string  $name
	 * @param  string  $value
	 * @param  bool    $checked
	 * @param  array   $attributes
	 * @return string
	 */
486
	protected static function checkable($type, $name, $value, $checked, $attributes)
487
	{
488 489 490
		if ($checked) $attributes['checked'] = 'checked';

		$attributes['id'] = static::id($name, $attributes);
491

492
		return static::input($type, $name, $value, $attributes);
493 494 495
	}

	/**
Taylor Otwell committed
496
	 * Create a HTML submit input element.
497 498 499 500 501
	 *
	 * @param  string  $value
	 * @param  array   $attributes
	 * @return string
	 */
502
	public static function submit($value, $attributes = array())
503
	{
504
		return static::input('submit', null, $value, $attributes);
505 506 507
	}

	/**
Taylor Otwell committed
508
	 * Create a HTML reset input element.
509
	 *
Taylor Otwell committed
510
	 * @param  string  $value
511 512
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
513
	 */
514
	public static function reset($value, $attributes = array())
515
	{
516
		return static::input('reset', null, $value, $attributes);
Taylor Otwell committed
517
	}
518

Taylor Otwell committed
519 520 521
	/**
	 * Create a HTML image input element.
	 *
522 523 524 525 526
	 * <code>
	 *		// Create an image input element
	 *		echo Form::image('img/submit.png');
	 * </code>
	 *
Taylor Otwell committed
527
	 * @param  string  $url
Phill Sparks committed
528
	 * @param  string  $name
Taylor Otwell committed
529 530 531
	 * @param  array   $attributes
	 * @return string
	 */
532
	public static function image($url, $name = null, $attributes = array())
Taylor Otwell committed
533
	{
534
		$attributes['src'] = URL::to_asset($url);
535

536
		return static::input('image', $name, null, $attributes);
537 538 539
	}

	/**
Taylor Otwell committed
540
	 * Create a HTML button element.
541
	 *
Taylor Otwell committed
542
	 * @param  string  $value
543 544
	 * @param  array   $attributes
	 * @return string
Taylor Otwell committed
545
	 */
546
	public static function button($value, $attributes = array())
547
	{
548
		return '<button'.HTML::attributes($attributes).'>'.HTML::entities($value).'</button>';
549 550
	}

551 552 553 554 555 556 557
	/**
	 * Determine the ID attribute for a form element.
	 *
	 * @param  string  $name
	 * @param  array   $attributes
	 * @return mixed
	 */
558
	protected static function id($name, $attributes)
559
	{
560 561
		// If an ID has been explicitly specified in the attributes, we will
		// use that ID. Otherwise, we will look for an ID in the array of
562
		// label names so labels and their elements have the same ID.
563 564 565 566
		if (array_key_exists('id', $attributes))
		{
			return $attributes['id'];
		}
567

568 569 570 571
		if (in_array($name, static::$labels))
		{
			return $name;
		}
572 573
	}

574 575 576 577 578 579 580 581 582
	/**
	 * Dynamically handle calls to custom macros.
	 *
	 * @param  string  $method
	 * @param  array   $parameters
	 * @return mixed
	 */
	public static function __callStatic($method, $parameters)
	{
Taylor Otwell committed
583
	    if (isset(static::$macros[$method]))
584
	    {
Taylor Otwell committed
585
	        return call_user_func_array(static::$macros[$method], $parameters);
586 587 588 589 590
	    }
	    
	    throw new \Exception("Method [$method] does not exist.");
	}

591
}