1 <?php
2 3 4 5 6 7 8 9 10
11 namespace uix\ui;
12
13 14 15 16 17 18
19 class repeat extends panel {
20
21 22 23 24 25 26 27
28 public $type = 'repeat';
29
30 31 32 33 34 35 36
37 public $instance = 0;
38
39 40 41 42 43 44 45
46 public $instances = 0;
47
48 49 50 51 52 53 54
55 public $templates = null;
56
57 58 59 60 61 62 63
64 public $button_label;
65
66
67 68 69 70 71 72
73 public function set_assets() {
74
75 $this->assets['script']['repeat'] = $this->url . 'assets/js/repeat' . UIX_ASSET_DEBUG . '.js';
76 $this->assets['style']['repeat'] = $this->url . 'assets/css/repeat' . UIX_ASSET_DEBUG . '.css';
77
78 parent::set_assets();
79 }
80
81
82 83 84 85 86 87 88 89 90
91 private function compare_var_key( $key ){
92 $id_parts = $this->id_base_parts();
93 $compare = implode('-', $id_parts ) . '-';
94 return substr( $key, 0, strlen( $compare ) ) == $compare;
95 }
96
97 98 99 100 101
102 private function push_instance_setup( $index ){
103 $this->instances = $this->instance = $index;
104 if( !isset( $this->data[ $this->instance ] ) )
105 $this->data[ $this->instance ] = array();
106
107 foreach( $this->child as $child ){
108 $child->setup();
109 $this->data[ $this->instance ] += $child->get_data();
110 }
111 }
112
113 114 115 116 117 118
119 private function build_instance_count( $key ){
120 $key_parts = explode( '-', $key );
121 $id_parts = $this->id_base_parts();
122 return (int) $key_parts[ count( $id_parts ) ];
123 }
124
125 126 127 128 129
130 private function id_base_parts(){
131 $id_parts = explode( '-', $this->id() );
132 array_pop( $id_parts );
133 return $id_parts;
134 }
135
136 137 138 139 140 141 142
143 public function prepare_data() {
144 $submit_data = uix()->request_vars( 'post' );
145 if( !empty( $submit_data ) ){
146 $instances = array_filter( array_keys( $submit_data ), array( $this, 'compare_var_key' ) );
147 $instances = array_map( array( $this, 'build_instance_count' ), $instances );
148 array_map( array( $this, 'push_instance_setup' ), array_unique( $instances ) );
149 }
150 $this->instance = 0;
151 }
152 public function setup(){
153 parent::setup();
154 $this->prepare_data();
155 }
156 157 158 159 160 161
162 public function get_data(){
163
164 if( empty( $this->data ) )
165 $this->data = $this->set_instance_data();
166
167 return $this->data;
168
169 }
170
171
172 173 174
175 public function set_instance_data(){
176 $data = array();
177 $this->instance = 0;
178 while( $this->instance < $this->instances ){
179
180 if( !isset( $data[ $this->instance ] ) )
181 $data[ $this->instance ] = array();
182
183 if( null !== $this->get_instance_data() )
184 $data[ $this->instance ] += $this->get_instance_data();
185
186 $this->instance++;
187 }
188 $this->instance = 0;
189
190 return $data;
191 }
192 193 194
195 public function get_instance_data(){
196 $data = array();
197 foreach ( $this->child as $child ){
198 if( method_exists( $child, 'get_data' ) ){
199 if( null !== $child->get_data() )
200 $data += $child->get_data();
201 }
202 }
203
204 return $data;
205 }
206
207
208 209 210 211 212 213
214 public function set_data( $data ){
215
216 $this->instance = 0;
217
218 foreach ( $data as $instance => $instance_data){
219 foreach ( $this->child as $child ){
220 $child->set_data($instance_data);
221 }
222 $this->instance++;
223 }
224 $this->instances = $this->instance;
225 $this->instance = 0;
226
227 }
228
229 230 231 232 233 234 235
236 public function id(){
237
238 return parent::id() . '-' . $this->instance;
239 }
240
241 242 243 244 245 246
247 protected function enqueue_active_assets(){
248
249 parent::enqueue_active_assets();
250
251 echo '<style type="text/css">';
252 echo '#' . $this->id() .' .uix-repeat{ box-shadow: 1px 0 0 ' . $this->base_color() . ' inset, -37px 0 0 #f5f5f5 inset, -38px 0 0 #ddd inset, 0 2px 3px rgba(0, 0, 0, 0.05); };';
253 echo '</stype>';
254 }
255
256 257 258 259 260 261 262
263 public function render(){
264
265 add_action( 'admin_footer', array( $this, 'render_repeatable_script' ) );
266 add_action( 'wp_footer', array( $this, 'render_repeatable_script' ) );
267
268 $data = $this->get_data();
269
270 $output = '<div data-uix-template="' . esc_attr( $this->id() ) . '" ' . $this->build_attributes() . '>';
271 foreach( (array) $data as $instance_id ){
272 if (!isset($this->struct['active']))
273 $this->struct['active'] = 'true';
274
275 $output .= $this->render_repeatable();
276
277 $this->instance++;
278
279 }
280 $output .= '</div>';
281
282
283 $output .= $this->render_repeatable_more();
284
285 return $output;
286 }
287
288
289 290 291 292 293 294 295
296 public function render_repeatable_more(){
297
298 $label = __( 'Add Another', 'uix' );
299
300 if( !empty( $this->struct['label'] ) )
301 $label = $this->struct['label'];
302
303 $this->instance = '{{_inst_}}';
304 $this->templates = $this->render_repeatable();
305 $this->instance = 0;
306 $output = '<div class="repeatable-footer"><button type="button" class="button" data-uix-repeat="' . esc_attr( $this->id() ) . '">' . esc_html( $label ) . '</button></div>';
307
308
309 return $output;
310
311 }
312
313 314 315 316 317 318 319
320 public function render_repeatable(){
321 $output = '<div class="uix-repeat">';
322 $output .= $this->render_template();
323 if (!empty($this->child))
324 $output .= $this->render_children();
325
326 $output .= '<button type="button" class="button button-small uix-remover"><span class="dashicons dashicons-no"></span></button> </div>';
327 return $output;
328
329 }
330
331 332 333 334 335 336 337 338
339 public function render_repeatable_script(){
340 $output = null;
341 if( !empty( $this->templates ) ){
342 $output .= '<script type="text/html" id="' . esc_attr($this->id()) . '-tmpl">';
343 $output .= $this->templates;
344 $output .= '</script>';
345 }
346
347
348 echo $output;
349 }
350
351
352 }