1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Ui;
6:
7: use Atk4\Core\AppScopeTrait;
8: use Atk4\Core\ContainerTrait;
9: use Atk4\Core\InitializerTrait;
10: use Atk4\Core\NameTrait;
11: use Atk4\Core\StaticAddToTrait;
12: use Atk4\Core\TrackableTrait;
13:
14: /**
15: * Abstract view tree item (used only for View and Callback, you want probably to extend one of these).
16: *
17: * @property array<string, AbstractView> $elements
18: *
19: * @method View getOwner()
20: */
21: abstract class AbstractView
22: {
23: use AppScopeTrait;
24: use ContainerTrait {
25: add as private _add;
26: }
27: use InitializerTrait {
28: init as private _init;
29: }
30: use NameTrait;
31: use StaticAddToTrait;
32: use TrackableTrait;
33:
34: /**
35: * If add() method is called, but current view is not part of render tree yet,
36: * then arguments to add() are simply stored in this array. When the view is
37: * initialized by calling init() or adding into App or another initialized View,
38: * then add() will be re-invoked with the contents of this array.
39: *
40: * @var array<int, array{self, array}>|null
41: */
42: protected ?array $_addLater = [];
43:
44: /** Will be set to true after rendered. This is so that we don't render view twice. */
45: protected bool $_rendered = false;
46:
47: /**
48: * Called when view becomes part of render tree. You can override it but avoid
49: * placing any "heavy processing" here.
50: */
51: protected function init(): void
52: {
53: if ($this->name === null) {
54: $this->name = 'atk';
55: }
56:
57: $this->_init();
58:
59: if ($this->_addLater !== null) {
60: foreach ($this->_addLater as [$object, $args]) {
61: $this->add($object, $args);
62: }
63: $this->_addLater = null;
64: }
65: }
66:
67: /**
68: * @return ($object is View ? View : self)
69: */
70: public function add(self $object, array $args = []): self
71: {
72: if ($this->_rendered) {
73: throw new Exception('You cannot add anything into the view after it was rendered');
74: }
75:
76: if (!$this->issetApp()) {
77: $this->_addLater[] = [$object, $args];
78:
79: return $object;
80: }
81:
82: // will call init() of the object
83: $this->_add($object, $args);
84:
85: return $object;
86: }
87: }
88: