Completed
Pull Request — staging (#840)
by
unknown
17:14
created

FormEscapedView::render()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * YIKES Inc. Easy Forms.
4
 *
5
 * @package   YIKES\EasyForms
6
 * @author    Freddie Mixell
7
 * @license   GPL2
8
 */
9
10
namespace YIKES\EasyForms\View;
11
12
use YIKES\EasyForms\Exception\FailedToLoadView;
13
use YIKES\EasyForms\Exception\InvalidURI;
14
15
/**
16
 * Class FormEscapedView.
17
 *
18
 * This is a Decorator that decorates a given View with escaping meant for
19
 * HTML form output.
20
 *
21
 * @since   %VERSION%
22
 *
23
 * @package YIKES\EasyForms\View
24
 * @author  Freddie Mixell
25
 */
26
final class FormEscapedView implements View {
27
28
	/**
29
	 * Form tags that are allowed to be rendered.
30
	 *
31
	 * @var array
32
	 */
33
	protected $form_tags = [
34
		'form'     => [
35
			'id'                => true,
36
			'class'             => true,
37
			'action'            => true,
38
			'method'            => true,
39
			'data-attr-form-id' => true,
40
		],
41
		'input'    => [
42
			'id'          => true,
43
			'class'       => true,
44
			'type'        => true,
45
			'name'        => true,
46
			'value'       => true,
47
			'required'    => true,
48
			'maxlength'   => true,
49
			'placeholder' => true,
50
			'style'       => true,
51
		],
52
		'select'   => [
53
			'id'       => true,
54
			'class'    => true,
55
			'type'     => true,
56
			'name'     => true,
57
			'value'    => true,
58
			'required' => true,
59
		],
60
		'textarea' => [
61
			'id'       => true,
62
			'class'    => true,
63
			'type'     => true,
64
			'name'     => true,
65
			'value'    => true,
66
			'required' => true,
67
		],
68
		'option'   => [
69
			'id'       => true,
70
			'class'    => true,
71
			'type'     => true,
72
			'name'     => true,
73
			'value'    => true,
74
			'selected' => true,
75
		],
76
		'label'    => [
77
			'for' => true,
78
		],
79
		'fieldset' => [
80
			'data-add-new-label' => true,
81
		],
82
		'p'        => [
83
			'class' => true,
84
			'id'    => true,
85
		]
86
	];
87
88
	/**
89
	 * View instance to decorate.
90
	 *
91
	 * @since %VERSION%
92
	 *
93
	 * @var View
94
	 */
95
	private $view;
96
97
	/**
98
	 * Tags that are allowed to pass through the escaping function.
99
	 *
100
	 * @since %VERSION%
101
	 *
102
	 * @var array
103
	 */
104
	private $allowed_tags = [];
105
106
	/**
107
	 * Instantiate a FormEscapedView object.
108
	 *
109
	 * @since %VERSION%
110
	 *
111
	 * @param View       $view         View instance to decorate.
112
	 * @param array|null $allowed_tags Optional. Array of allowed tags to let
113
	 *                                 through escaping functions. Set to sane
114
	 *                                 defaults if none provided.
115
	 */
116
	public function __construct( View $view, $allowed_tags = null ) {
117
		$this->view         = $view;
118
		$this->allowed_tags = null === $allowed_tags
119
			? $this->prepare_allowed_tags( wp_kses_allowed_html( 'post' ) )
120
			: $allowed_tags;
121
	}
122
123
	/**
124
	 * Prepare an array of allowed tags by adding form elements to the existing
125
	 * array.
126
	 *
127
	 * This makes sure that the basic form elements always pass through the
128
	 * escaping functions.
129
	 *
130
	 * @since %VERSION%
131
	 *
132
	 * @param array $allowed_tags Allowed tags as fetched from the WordPress
133
	 *                            defaults.
134
	 *
135
	 * @return array Modified tags array.
136
	 */
137
	private function prepare_allowed_tags( $allowed_tags ) {
138
		return array_replace_recursive( $allowed_tags, $this->form_tags );
139
	}
140
141
	/**
142
	 * Render a given URI.
143
	 *
144
	 * @since %VERSION%
145
	 *
146
	 * @param array $context Context in which to render.
147
	 *
148
	 * @return string Rendered HTML.
149
	 * @throws FailedToLoadView If the View URI could not be loaded.
150
	 */
151
	public function render( array $context = [] ) {
152
		return wp_kses( $this->view->render( $context ), $this->allowed_tags );
153
	}
154
155
	/**
156
	 * Render a partial view.
157
	 *
158
	 * This can be used from within a currently rendered view, to include
159
	 * nested partials.
160
	 *
161
	 * The passed-in context is optional, and will fall back to the parent's
162
	 * context if omitted.
163
	 *
164
	 * @since %VERSION%
165
	 *
166
	 * @param string     $uri     URI of the partial to render.
167
	 * @param array|null $context Context in which to render the partial.
168
	 *
169
	 * @return string Rendered HTML.
170
	 * @throws InvalidURI If the provided URI was not valid.
171
	 * @throws FailedToLoadView If the view could not be loaded.
172
	 */
173
	public function render_partial( $uri, array $context = null ) {
174
		return wp_kses(
175
			$this->view->render_partial( $uri, $context ),
176
			$this->allowed_tags
177
		);
178
	}
179
}
180