1: <?php
2:
3: namespace Zippy\Html;
4:
5: use Zippy\WebApplication;
6: use Zippy\Exception as ZE;
7: use Zippy\Interfaces\Requestable;
8:
9: /**
10: * Базовый компонент контейнера для других компонентов
11: *
12: */
13: abstract class HtmlContainer extends HtmlComponent implements Requestable
14: {
15: protected $components = array();
16:
17: /**
18: * @see HtmlComponent
19: */
20: public function __construct($id) {
21: parent::__construct($id);
22: }
23:
24: /**
25: * Добавляет компонент к списку дочерних
26: * Иерархия компонентов должна строго соответствовать иерархии
27: * вложеных тэгов (с аттрибутами zippy) в HTML шаблоне
28: */
29: public function add(HtmlComponent $component) {
30: if (isset($this->components[$component->id])) {
31: throw new ZE(sprintf(ERROR_COMPONENT_ALREADY_EXISTS, $component->id, $this->id));
32: }
33: if (property_exists($this, $component->id)) {
34: $id = strlen($this->id) > 0 ? $this->id : get_class($this);
35: throw new ZE(sprintf(ERROR_COMPONENT_AS_PROPERTY, $component->id, $id));
36: }
37:
38: $this->components[$component->id] = $component;
39: $component->setOwner($this);
40: $component->onAdded();
41: return $component;
42: }
43:
44: /**
45: * Получить дочерний компонент
46: *
47: * @param string ID компонента
48: * @param boolean Если false - искать только непосредственнно вложенных
49: * @return HtmlComponent
50: */
51: public function getComponent($id, $desc = true) {
52: if ($desc == false) {
53: return $this->components[$id];
54: } else {
55: if (isset($this->components[$id])) {
56: return $this->components[$id];
57: }
58:
59: foreach ($this->components as $component) {
60: if ($component instanceof HtmlContainer === false) {
61: continue;
62: }
63:
64: $tmp = $component->getComponent($id);
65:
66: if ($tmp != null) {
67: return $tmp;
68: }
69: }
70: return null;
71: }
72: }
73:
74: /**
75: * Перегрузка данного метода позволяет
76: * получить доступ к дочернему компоненту как к полю объекта
77: *
78: * $this->add(new Label('msg'));
79: * ...
80: * $this->msg->setValue();
81: *
82: *
83: * @param string ID компонента
84: * @return HtmlComponent *
85: */
86: final public function __get($id) {
87:
88: if (!isset($this->components[$id])) {
89: $m = sprintf(ERROR_NOT_FOUND_CHILD, get_class($this), $this->id, $id);
90: throw new ZE($m);
91: };
92:
93: return $this->components[$id];
94: }
95:
96: /**
97: * Возвращает (для дочерних) формируемый иерархией компонентов
98: * HTTP адрес, добавляя собственный ID
99: */
100: public function getURLNode() {
101: return $this->owner->getURLNode() . "::" . $this->id;
102: }
103:
104: /**
105: * Имплементация рендеринга
106: * Вызывает методы для рендеринга вложеных компонентов
107: */
108: protected function RenderImpl() {
109:
110: // $this->beforeRender();
111: //$keys = array_keys($this->components);
112: foreach ($this->components as $component) {
113:
114:
115: if ($component->isVisible()) {
116: $component->Render();
117: } else {
118: $component->getTag()->destroy();
119: $label = $component->getLabelTag();
120:
121: foreach ($label as $l) {
122: $l->destroy();
123: }
124:
125: $label = $component->getLabelTagFor();
126:
127: foreach ($label as $l) {
128: $l->destroy();
129: }
130:
131: }
132: }
133: // $this->afterRender();
134: }
135:
136: /**
137: * Обработка HTTP запроса
138: * отделяет собственный ID с запроса и передает дочернему элементу
139: * которому предназначен запрос
140: */
141: public function RequestHandle() {
142: if ($this->visible == false) {
143: return;
144: }
145:
146: $child = next(WebApplication::getApplication()->getRequest()->request_c);
147:
148: if ($child != false && ($this->components[$child] ??null) instanceof Requestable) {
149: $this->components[$child]->RequestHandle();
150: } else {
151: if($this instanceof \Zippy\Html\WebPage || $this instanceof \Zippy\Html\PageFragment) { //ищем метод
152: if(method_exists($this, $child)) {
153: $this->RequestMethod($child); //webpage methos
154:
155: }
156: }
157: }
158:
159:
160:
161: }
162:
163: /**
164: * Возвращает массив вложенных компонентов
165: * @param boolean Если true, возвращает со всех уровней вложения
166: */
167: public function getChildComponents($all = false) {
168: if ($all == false) {
169: return $this->components;
170: }
171:
172: $list = array();
173: foreach ($this->components as $component) {
174: $list[] = $component;
175:
176: if ($component instanceof HtmlContainer) {
177: $childs = $component->getChildComponents(true);
178: foreach ($childs as $child) {
179: $list[] = $child;
180: }
181: //array_push($list,$component->getChildComponents(true));
182: }
183: }
184: return $list;
185: }
186:
187: }
188: