276 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			276 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/*****************************************************************************
 | 
						|
 * FormView.php
 | 
						|
 * Contains the form template.
 | 
						|
 *
 | 
						|
 * Kabuki CMS (C) 2013-2023, Aaron van Geffen
 | 
						|
 *****************************************************************************/
 | 
						|
 | 
						|
class FormView extends SubTemplate
 | 
						|
{
 | 
						|
	private $form;
 | 
						|
	private array $data;
 | 
						|
	private array $missing;
 | 
						|
	private $title;
 | 
						|
 | 
						|
	public function __construct(Form $form, $title = '')
 | 
						|
	{
 | 
						|
		$this->form = $form;
 | 
						|
		$this->title = $title;
 | 
						|
	}
 | 
						|
 | 
						|
	protected function html_content()
 | 
						|
	{
 | 
						|
		if (!empty($this->title))
 | 
						|
			echo '
 | 
						|
			<h1>', $this->title, '</h1>';
 | 
						|
 | 
						|
		foreach ($this->_subtemplates as $template)
 | 
						|
			$template->html_main();
 | 
						|
 | 
						|
		echo '
 | 
						|
			<form action="', $this->form->request_url, '" method="', $this->form->request_method, '" enctype="multipart/form-data">';
 | 
						|
 | 
						|
		if (isset($this->form->before_fields))
 | 
						|
			echo $this->form->before_fields;
 | 
						|
 | 
						|
		$this->missing = $this->form->getMissing();
 | 
						|
		$this->data = $this->form->getData();
 | 
						|
 | 
						|
		foreach ($this->form->getFields() as $field_id => $field)
 | 
						|
		{
 | 
						|
			$this->renderField($field_id, $field);
 | 
						|
		}
 | 
						|
 | 
						|
		if (isset($this->form->after_fields))
 | 
						|
			echo $this->form->after_fields;
 | 
						|
 | 
						|
		echo '
 | 
						|
				<input type="hidden" name="', Session::getSessionTokenKey(), '" value="', Session::getSessionToken(), '">
 | 
						|
				<div class="form-group">
 | 
						|
					<div class="offset-sm-2 col-sm-10">
 | 
						|
						<button type="submit" name="submit" class="btn btn-primary">', $this->form->getSubmitButtonCaption(), '</button>';
 | 
						|
 | 
						|
		if (isset($this->form->buttons_extra))
 | 
						|
			echo '
 | 
						|
						', $this->form->buttons_extra;
 | 
						|
 | 
						|
		echo '
 | 
						|
					</div>
 | 
						|
				</div>
 | 
						|
			</form>';
 | 
						|
	}
 | 
						|
 | 
						|
	protected function renderField($field_id, array $field)
 | 
						|
	{
 | 
						|
		if (isset($field['before_html']))
 | 
						|
			echo '
 | 
						|
				', $field['before_html'];
 | 
						|
 | 
						|
		echo '
 | 
						|
				<div class="row mb-2">';
 | 
						|
 | 
						|
		if ($field['type'] !== 'checkbox')
 | 
						|
		{
 | 
						|
			if (isset($field['label']))
 | 
						|
				echo '
 | 
						|
					<label class="col-sm-2 col-form-label" for="', $field_id, '"', in_array($field_id, $this->missing) ? ' style="color: red"' : '', '>', $field['label'], ':</label>
 | 
						|
					<div class="', isset($field['class']) ? $field['class'] : 'col-sm-6', '">';
 | 
						|
			else
 | 
						|
				echo '
 | 
						|
					<div class="offset-sm-2 ', isset($field['class']) ? $field['class'] : 'col-sm-6', '">';
 | 
						|
		}
 | 
						|
 | 
						|
		switch ($field['type'])
 | 
						|
		{
 | 
						|
			case 'select':
 | 
						|
				$this->renderSelect($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'radio':
 | 
						|
				$this->renderRadio($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'checkbox':
 | 
						|
				$this->renderCheckbox($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'textarea':
 | 
						|
				$this->renderTextArea($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'color':
 | 
						|
				$this->renderColor($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'numeric':
 | 
						|
				$this->renderNumeric($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'file':
 | 
						|
				$this->renderFile($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'captcha':
 | 
						|
				$this->renderCaptcha($field_id, $field);
 | 
						|
				break;
 | 
						|
 | 
						|
			case 'text':
 | 
						|
			case 'password':
 | 
						|
			default:
 | 
						|
				$this->renderText($field_id, $field);
 | 
						|
		}
 | 
						|
 | 
						|
		if ($field['type'] !== 'checkbox')
 | 
						|
			echo '
 | 
						|
					</div>';
 | 
						|
 | 
						|
		echo '
 | 
						|
				</div>';
 | 
						|
 | 
						|
		if (isset($field['after_html']))
 | 
						|
			echo '
 | 
						|
				', $field['after_html'];
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderCaptcha($field_id, array $field)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
						<div class="g-recaptcha" data-sitekey="', RECAPTCHA_API_KEY, '"></div>
 | 
						|
						<script src="https://www.google.com/recaptcha/api.js"></script>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderCheckbox($field_id, array $field)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
					<div class="offset-sm-2 col-sm-10">
 | 
						|
						<div class="form-check">
 | 
						|
							<input class="form-check-input" type="checkbox"', $this->data[$field_id] ? ' checked' : '', !empty($field['disabled']) ? ' disabled' : '', ' name="', $field_id, '" id="check-', $field_id, '">
 | 
						|
							<label class="form-check-label" for="check-', $field_id, '">
 | 
						|
								', $field['label'], '
 | 
						|
							</label>
 | 
						|
						</div>
 | 
						|
					</div>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderColor($field_id, array $field)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
						<input class="form-control" type="color" name="', $field_id, '" id="', $field_id, '" value="', htmlspecialchars($this->data[$field_id]), '"', !empty($field['disabled']) ? ' disabled' : '', '>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderFile($field_id, array $field)
 | 
						|
	{
 | 
						|
		if (!empty($this->data[$field_id]))
 | 
						|
			echo 'Currently using asset <tt>', $this->data[$field_id], '</tt>. Upload to overwrite.<br>';
 | 
						|
 | 
						|
		echo '
 | 
						|
						<input class="form-control" type="file" name="', $field_id, '" id="', $field_id, '"', !empty($field['disabled']) ? ' disabled' : '', '>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderNumeric($field_id, array $field)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
						<input class="form-control" type="number"',
 | 
						|
							isset($field['step']) ? ' step="' . $field['step'] . '"' : '',
 | 
						|
							' min="', isset($field['min_value']) ? $field['min_value'] : '0', '"',
 | 
						|
							' max="', isset($field['max_value']) ? $field['max_value'] : '9999', '"',
 | 
						|
							' name="', $field_id, '" id="', $field_id, '"',
 | 
						|
							isset($field['size']) ? ' size="' . $field['size'] . '"' : '',
 | 
						|
							isset($field['maxlength']) ? ' maxlength="' . $field['maxlength'] . '"' : '',
 | 
						|
							' value="', htmlspecialchars($this->data[$field_id]), '"',
 | 
						|
							!empty($field['disabled']) ? ' disabled' : '', '>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderRadio($field_id, array $field)
 | 
						|
	{
 | 
						|
		foreach ($field['options'] as $value => $option)
 | 
						|
			echo '
 | 
						|
						<div class="form-check">
 | 
						|
							<input class="form-check-input" type="radio" name="', $field_id, '" id="radio-', $field_id, '-', $value, '" value="', $value, '"', $this->data[$field_id] == $value ? ' checked' : '', !empty($field['disabled']) ? ' disabled' : '', '>
 | 
						|
							<label class="form-check-label" for="radio-', $field_id, '-', $value, '">
 | 
						|
								', htmlspecialchars($option), '
 | 
						|
							</label>
 | 
						|
						</div>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderSelect($field_id, array $field)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
						<select class="form-select" name="', $field_id, !empty($field['multiple']) ? '[]' : '',
 | 
						|
					'" id="', $field_id, '"',
 | 
						|
					!empty($field['disabled']) ? ' disabled' : '',
 | 
						|
					!empty($field['multiple']) ? ' multiple' : '',
 | 
						|
					!empty($field['size']) ? ' size="' . $field['size'] . '"' : '',
 | 
						|
					'>';
 | 
						|
 | 
						|
		if (isset($field['placeholder']))
 | 
						|
			echo '
 | 
						|
							<option value="">', $field['placeholder'], '</option>';
 | 
						|
 | 
						|
		foreach ($field['options'] as $key => $value)
 | 
						|
		{
 | 
						|
			if (is_array($value))
 | 
						|
			{
 | 
						|
				assert(empty($field['multiple']));
 | 
						|
				$this->renderSelectOptionGroup($field_id, $key, $value);
 | 
						|
			}
 | 
						|
			else
 | 
						|
				$this->renderSelectOption($field_id, $value, $key, !empty($field['multiple']));
 | 
						|
		}
 | 
						|
 | 
						|
		echo '
 | 
						|
						</select>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderSelectOption($field_id, $label, $value, $multiple = false)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
							<option value="', $value, '"',
 | 
						|
							!$multiple && $this->data[$field_id] == $value ? ' selected' : '',
 | 
						|
							$multiple && in_array($value, $this->data[$field_id]) ? ' selected' : '',
 | 
						|
							'>', htmlspecialchars($label), '</option>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderSelectOptionGroup($field_id, $label, $options)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
							<optgroup label="', $label, '">';
 | 
						|
 | 
						|
		foreach ($options as $value => $option)
 | 
						|
			$this->renderSelectOption($field_id, $option, $value);
 | 
						|
 | 
						|
		echo '
 | 
						|
							</optgroup>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderText($field_id, array $field)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
						<input class="form-control" ',
 | 
						|
						'type="', $field['type'], '" ',
 | 
						|
						'name="', $field_id, '" ',
 | 
						|
						'id="', $field_id, '"',
 | 
						|
						isset($field['size']) ? ' size="' . $field['size'] . '"' : '',
 | 
						|
						isset($field['maxlength']) ? ' maxlength="' . $field['maxlength'] . '"' : '',
 | 
						|
						isset($this->data[$field_id]) ? ' value="' . htmlspecialchars($this->data[$field_id]) . '"' : '',
 | 
						|
						isset($field['placeholder']) ? ' placeholder="' . $field['placeholder'] . '"' : '',
 | 
						|
						!empty($field['disabled']) ? ' disabled' : '',
 | 
						|
						isset($field['trigger']) ? ' class="trigger-' . $field['trigger'] . '"' : '',
 | 
						|
						'>';
 | 
						|
	}
 | 
						|
 | 
						|
	private function renderTextArea($field_id, array $field)
 | 
						|
	{
 | 
						|
		echo '
 | 
						|
						<textarea class="form-control' .
 | 
						|
							'" name="', $field_id,
 | 
						|
							'" id="', $field_id,
 | 
						|
							'" cols="', isset($field['columns']) ? $field['columns'] : 40,
 | 
						|
							'" rows="', isset($field['rows']) ? $field['rows'] : 4, '"',
 | 
						|
							isset($field['placeholder']) ? ' placeholder="' . $field['placeholder'] . '"' : '',
 | 
						|
							'"', !empty($field['disabled']) ? ' disabled' : '',
 | 
						|
							'>', $this->data[$field_id], '</textarea>';
 | 
						|
	}
 | 
						|
}
 |