1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Icybee;
13
14 use ICanBoogie\Event;
15 use ICanBoogie\Exception;
16 use ICanBoogie\HTTP\ForceRedirect;
17 use ICanBoogie\HTTP\HTTPError;
18 use ICanBoogie\I18n;
19 use ICanBoogie\Operation;
20 use ICanBoogie\Route;
21
22 use Brickrouge\A;
23 use Brickrouge\Button;
24 use Brickrouge\Element;
25 use Brickrouge\Form;
26 use Brickrouge\SplitButton;
27
28 use Icybee\Element\ActionbarToolbar;
29
30 31 32
33 class EditBlock extends FormBlock
34 {
35 static protected function add_assets(\Brickrouge\Document $document)
36 {
37 parent::add_assets($document);
38
39 $document->js->add('edit.js');
40 }
41
42 43 44 45 46
47 protected $key;
48
49 50 51 52 53 54 55
56 public function __construct(Module $module, array $attributes=array(), array $params=array())
57 {
58 $key = isset($params[0]) ? $params[0] : null;
59
60 $this->key = $key;
61
62 parent::__construct($module, $attributes);
63 }
64
65 66 67
68 protected function alter(array $params)
69 {
70 return parent::alter
71 (
72 $params + array
73 (
74 'key' => $this->key,
75 'record' => $this->record
76 )
77 );
78 }
79
80 81 82 83
84 public function render()
85 {
86 $module = $this->module;
87 $key = $this->key;
88
89 if ($key)
90 {
91 $locked = $module->lock_entry($key, $lock);
92
93 $this->locked = $locked;
94
95 if (!$locked)
96 {
97 return new InterlockBlock($module, array(), array('lock' => $lock));
98 }
99 }
100
101 I18n::push_scope($module->flat_id . '.edit');
102
103 try
104 {
105 $element = parent::render();
106 $this->element->save();
107
108 I18n::pop_scope();
109
110 return $element;
111 }
112 catch (\Exception $e)
113 {
114 I18n::pop_scope();
115
116 throw $e;
117 }
118 }
119
120 protected function get_permission()
121 {
122 global $core;
123
124 $user = $core->user;
125 $permission = $user->has_permission(Module::PERMISSION_CREATE, $this->module);
126
127
128
129
130
131 $record = $this->record;
132
133 if ($record && isset($record->uid))
134 {
135 $permission = $user->has_ownership($this->module, $record);
136 }
137
138 return $permission;
139 }
140
141 protected function access_control()
142 {
143 global $core;
144
145 $key = $this->key;
146 $module_id = $this->module->id;
147
148 if (!$key && !$this->permission)
149 {
150 throw new HTTPError(\ICanBoogie\format("You don't have permission to create records in the %id module.", array('id' => $module_id)), 403);
151 }
152
153
154
155
156
157
158 $record = $this->record;
159
160 if ($record && !($record instanceof \Icybee\Modules\Sites\Site)
161 && !empty($record->siteid) && $record->siteid != $core->site_id)
162 {
163 $url = $core->models['sites'][$record->siteid]->url;
164
165 throw new ForceRedirect("$url/admin/$module_id/$key/edit");
166 }
167 }
168
169 170 171 172 173
174 protected function lazy_get_record()
175 {
176 return $this->key ? $this->module->model[$this->key] : null;
177 }
178
179 180 181
182
183 184 185 186 187 188 189
190 protected function lazy_get_attributes()
191 {
192 return \ICanBoogie\array_merge_recursive
193 (
194 parent::lazy_get_attributes(), array
195 (
196 Form::HIDDENS => array
197 (
198 Operation::NAME => 'save',
199 Operation::KEY => $this->key
200 ),
201
202 Element::GROUPS => array
203 (
204 'admin' => array
205 (
206 'title' => 'Admin',
207 'weight' => 1000
208 )
209 )
210 )
211 );
212 }
213
214 215 216
217 protected function fire_before_alter_attributes(array $properties)
218 {
219 new EditBlock\BeforeAlterAttributesEvent($this, $properties);
220 }
221
222 223 224
225 protected function fire_alter_attributes(array $properties)
226 {
227 new EditBlock\AlterAttributesEvent($this, $properties);
228 }
229
230 231 232
233
234 235 236 237 238 239 240
241 protected function lazy_get_values()
242 {
243 global $core;
244
245 $schema = $this->module->model->extended_schema;
246 $record = $this->record;
247 $params = $core->request->request_params;
248
249 return array_merge
250 (
251 parent::lazy_get_values(),
252 $schema ? array_fill_keys(array_keys($schema['fields']), null) : array(),
253 $record ? $record->to_array() : array(),
254 $params ? $params : array()
255 );
256 }
257
258 259 260
261 protected function fire_before_alter_values(array $properties)
262 {
263 new EditBlock\BeforeAlterValuesEvent($this, $properties);
264 }
265
266 267 268
269 protected function fire_alter_values(array $properties)
270 {
271 new EditBlock\AlterValuesEvent($this, $properties);
272 }
273
274 275 276
277
278 279 280
281 protected function fire_before_alter_children(array $properties)
282 {
283 new EditBlock\BeforeAlterChildrenEvent($this, $properties);
284 }
285
286 287 288
289 protected function fire_alter_children(array $properties)
290 {
291 new EditBlock\AlterChildrenEvent($this, $properties);
292 }
293
294 295 296
297
298 299 300
301 protected function lazy_get_actions()
302 {
303 return array
304 (
305 'primary' => new Button
306 (
307 'Save', array
308 (
309 'class' => 'btn-primary',
310 'type' => 'submit',
311 'name' => false
312 )
313 )
314 );
315 }
316
317 318 319
320 protected function alter_actions(array $actions, array $params)
321 {
322 global $core;
323
324 $module = $this->module;
325 $record = $this->record;
326
327 $mode = isset($core->session->operation_save_mode[$module->id]) ? $core->session->operation_save_mode[$module->id] : OPERATION_SAVE_MODE_LIST;
328
329 $save_mode_options = array
330 (
331 OPERATION_SAVE_MODE_LIST => I18n\t('save_mode_list', array(), array('scope' => 'option')),
332 OPERATION_SAVE_MODE_CONTINUE => I18n\t('save_mode_continue', array(), array('scope' => 'option')),
333 OPERATION_SAVE_MODE_NEW => I18n\t('save_mode_new', array(), array('scope' => 'option')),
334 );
335
336 try
337 {
338 $core->views["{$module->id}/view"];
339 $save_mode_options[OPERATION_SAVE_MODE_DISPLAY] = I18n\t('save_mode_display', array(), array('scope' => 'option'));
340 }
341 catch (\Icybee\Modules\Views\Collection\ViewNotDefined $e)
342 {
343 if ($record instanceof \ICanBoogie\Object && $record->has_property('url'))
344 {
345 $url = $record->url;
346
347 if ($url)
348 {
349 $save_mode_options[OPERATION_SAVE_MODE_DISPLAY] = I18n\t('save_mode_display', array(), array('scope' => 'option'));
350 }
351 }
352 }
353
354 if (empty($save_mode_options[$mode]))
355 {
356 $mode = key($save_mode_options);
357 }
358
359 $key = $this->key;
360 $block = $this;
361
362 $core->events->attach(function(ActionbarToolbar\CollectEvent $event, ActionbarToolbar $sender) use($record, $module, $key, $save_mode_options, $mode, $block)
363 {
364 global $core;
365
366 if ($record)
367 {
368 try
369 {
370 $url = $record->url;
371
372 if ($url[0] != '#')
373 {
374 $event->buttons[] = '<a href="' . $record->url . '" class="actionbar-link">' . I18n\t('View', array(), array('scope' => 'button')) . '</a>';
375 }
376 }
377 catch (\Exception $e) {}
378 }
379
380 $locked = true;
381
382 if ($key)
383 {
384 $locked = $module->lock_entry($key, $lock);
385 }
386
387 if (!$locked)
388 {
389 return;
390 }
391
392 if ($key
393 && $core->user->has_permission(Module::PERMISSION_MANAGE, $module)
394 && $core->user->has_ownership($module, $record))
395 {
396 $event->buttons[] = new A
397 (
398 I18n\t('Delete', array(), array('scope' => 'button')), \ICanBoogie\Routing\contextualize('/admin/' . $module . '/' . $key . '/delete'), array
399 (
400 'class' => 'btn btn-danger'
401 )
402 );
403 }
404
405 if (isset($block->actions[OPERATION_SAVE_MODE]))
406 {
407 $event->buttons[] = new SplitButton
408 (
409 $save_mode_options[$mode], array
410 (
411 Element::OPTIONS => $save_mode_options,
412
413 'value' => $mode,
414 'class' => 'btn-primary record-save-mode'
415 )
416 );
417 }
418 });
419
420 return array_merge
421 (
422 array
423 (
424 OPERATION_SAVE_MODE => new Element
425 (
426 Element::TYPE_RADIO_GROUP, array
427 (
428 Element::GROUP => 'save',
429 Element::OPTIONS => $save_mode_options,
430
431 'value' => $mode,
432 'class' => 'inputs-list save-mode'
433 )
434 )
435 ),
436
437 $actions
438 );
439 }
440
441 442 443
444 protected function fire_before_alter_actions(array $properties)
445 {
446 new EditBlock\BeforeAlterActionsEvent($this, $properties);
447 }
448
449 450 451
452 protected function fire_alter_actions(array $properties)
453 {
454 new EditBlock\AlterActionsEvent($this, $properties);
455 }
456
457 458 459 460
461 protected function alter_element(Form $element, array $params)
462 {
463 global $core;
464
465 $element = parent::alter_element($element, $params);
466
467 if (!$this->permission)
468 {
469 $element[Form::ACTIONS] = null;
470 $element[Form::DISABLED] = true;
471 }
472
473 $language = $core->site->language;
474
475 foreach ($element as $control)
476 {
477 if ($control->tag_name != 'textarea')
478 {
479 continue;
480 }
481
482 $control['lang'] = $language;
483 }
484
485 return $element;
486 }
487 }
488
489 namespace Icybee\EditBlock;
490
491 492 493 494 495
496 abstract class AlterEvent extends \Icybee\FormBlock\AlterEvent
497 {
498 499 500 501 502
503 public $key;
504
505 506 507 508 509
510 public $record;
511 }
512
513 514 515
516 class BeforeAlterAttributesEvent extends AlterEvent
517 {
518 519 520 521 522 523
524 public function __construct(\Icybee\EditBlock $target, array $properties)
525 {
526 parent::__construct($target, 'alter_attributes:before', $properties);
527 }
528 }
529
530 531 532
533 class AlterAttributesEvent extends AlterEvent
534 {
535 536 537 538 539 540
541 public function __construct(\Icybee\EditBlock $target, array $properties)
542 {
543 parent::__construct($target, 'alter_attributes', $properties);
544 }
545 }
546
547 548 549
550 class BeforeAlterValuesEvent extends AlterEvent
551 {
552 553 554 555 556 557
558 public function __construct(\Icybee\EditBlock $target, array $properties)
559 {
560 parent::__construct($target, 'alter_values:before', $properties);
561 }
562 }
563
564 565 566
567 class AlterValuesEvent extends AlterEvent
568 {
569 570 571 572 573 574
575 public function __construct(\Icybee\EditBlock $target, array $properties)
576 {
577 parent::__construct($target, 'alter_values', $properties);
578 }
579 }
580
581 582 583
584 class BeforeAlterChildrenEvent extends AlterEvent
585 {
586 587 588 589 590 591
592 public function __construct(\Icybee\EditBlock $target, array $properties)
593 {
594 parent::__construct($target, 'alter_children:before', $properties);
595 }
596 }
597
598 599 600
601 class AlterChildrenEvent extends AlterEvent
602 {
603 604 605 606 607 608
609 public function __construct(\Icybee\EditBlock $target, array $properties)
610 {
611 parent::__construct($target, 'alter_children', $properties);
612 }
613 }
614
615 616 617
618 class BeforeAlterActionsEvent extends AlterEvent
619 {
620 621 622 623 624 625
626 public function __construct(\Icybee\EditBlock $target, array $properties)
627 {
628 parent::__construct($target, 'alter_actions:before', $properties);
629 }
630 }
631
632 633 634
635 class AlterActionsEvent extends AlterEvent
636 {
637 638 639 640 641 642
643 public function __construct(\Icybee\EditBlock $target, array $properties)
644 {
645 parent::__construct($target, 'alter_actions', $properties);
646 }
647 }