1: <?php
2:
3: namespace Zippy\Html;
4:
5: use Zippy\WebApplication;
6: use Zippy\Interfaces\EventReceiver;
7: use Zippy\Interfaces\AjaxRender;
8:
9: /**
10: * Базовый класс для компонентов-страниц
11: * Является контейнером для всех компонентов страницы
12: *
13: */
14: abstract class WebPage extends HtmlContainer implements EventReceiver
15: {
16: public $args = '';
17: public $_title = '';
18: public $_description = '';
19: public $_keywords = '';
20: private $beforeRequestEvents = array(); //array of callbacks
21: private $afterRequestEvents = array(); //array of callbacks
22: private $_ajax;
23: private $_ankor = '';
24: public $_tvars = array(); //переменные для шаблонизатора Mustache
25: protected $_ajaxblocks = []; //список для серверного ренеринга при фофч pfghjct
26: // public $zarr = array();
27:
28: /**
29: * Конструктор
30: *
31: */
32:
33: public function __construct() {
34:
35:
36: }
37:
38: /**
39: * Вызывается из WebApplication при обработке HTTP запроса
40: *
41: * @param array Запрос ввиде массива элементов
42: * @see WebApplication
43: */
44: public function RequestHandle() {
45: $this->_ajaxblock = [];
46: $this->beforeRequest();
47:
48: parent::RequestHandle();
49:
50: $this->afterRequest();
51: }
52:
53: /**
54: * @see HtmlContainer
55: */
56: final public function getURLNode() {
57: return WebApplication::$app->getResponse()->getBaseUrl();
58: }
59:
60: /**
61: * Вызывается перед сохранением страницы в персистентной сессии
62: */
63: public function beforeSaveToSession() {
64:
65: }
66:
67: /**
68: * Вызывается после восстановлении страницы из персистентной сессии
69: */
70: public function afterRestoreFromSession() {
71:
72: }
73:
74: /**
75: * Вызывается в реализации страницы после AJAX запроса
76: * для елементов которые должны перерендерится на клиенте
77: *
78: * @param mixed id или массив id (значений атттрибута zippy) компонентов
79: * @param string Произвольный JavaScript код для выполнения на клиенте после Ajax вызова
80: *
81: * @see AjaxRender
82: */
83: protected function updateAjax($components, $js = null) {
84: $this->addAjaxResponse($js) ;
85: return;
86: if (!is_array($components)) {
87: $components = array($components);
88: }
89: if (is_array($components)) {
90: foreach ($components as $item) {
91: $this->_ajax[] = $item;
92: }
93: }
94: if (strlen($js) > 0) {
95: WebApplication::$app->getResponse()->addAjaxResponse($js);
96: }
97: }
98:
99: /**
100: * Рендерит компоненты для ajax ответа
101: * @panels рендеринг панелей
102: */
103: /*
104: public function renderAjax($panels = false) {
105: $haspanels = false;
106: if (is_array($this->_ajax)) {
107: foreach ($this->_ajax as $item) {
108: $component = $this->getComponent($item);
109:
110: if ($component instanceof Panel) {
111: $haspanels = true;
112: if ($panels == true) {
113: $responseJS = $component->AjaxAnswer();
114: WebApplication::$app->getResponse()->addAjaxResponse($responseJS);
115: continue;
116: }
117: }
118:
119: if ($component instanceof AjaxRender) {
120: if ($component instanceof Panel) {
121: continue;
122: }
123: $responseJS = $component->AjaxAnswer();
124: WebApplication::$app->getResponse()->addAjaxResponse($responseJS);
125: }
126: }
127:
128: return $haspanels;
129: }
130: }
131: */
132: /**
133: * @see HttpComponent
134: *
135: */
136: public function Render() {
137: if (strlen($this->_ankor) > 0) {
138: WebApplication::$app->getResponse()->addJavaScript("window.location='#" . $this->_ankor . "'", true);
139: $this->_ankor = '';
140: }
141: $this->beforeRender();
142:
143:
144: //$this->updateTag();
145:
146:
147: $this->RenderImpl();
148: $this->afterRender();
149:
150:
151:
152: //адрес страницы без параметров
153: $_baseurl = $this->getURLNode() ;
154: $this->_tvars['_baseurl'] = $_baseurl ;
155: WebApplication::$app->addJavaScript(" window._baseurl= '{$_baseurl}'") ;
156:
157: }
158: /*
159: public function getLoadedTag($id){
160: if(isset($this->zarr[$id])) return pq($this->zarr[$id] );
161: else return null;
162: }
163:
164: public function updateTag(){
165: $this->zarr = array();
166:
167: $z = pq('[zippy]') ;
168:
169: foreach($z->elements as $o){
170: $a = "".$o->getAttribute('zippy');
171: $this->zarr[$a] = $o ;
172: }
173: }
174: */
175: /**
176: * Добавляет обработчик на событие перед обработкой страницей HTTP запроса
177: * @param $obj Объект регистрирующий свою функцию как callback
178: * @param $func Имя функции - обработчика
179: */
180: public function addBeforeRequestEvent($obj, $func) {
181: $this->beforeRequestEvents[] = new \Zippy\Event($obj, $func);
182: }
183:
184: /**
185: * Добавляет обработчик на событие после обработки страницей HTTP запроса
186: * @param $obj Объект регистрирующий свою функцию как callback
187: * @param $func Имя функции - обработчика
188: */
189: public function addAfterRequestEvent($obj, $func) {
190: $this->afterRequestEvents[] = new \Zippy\Event($obj, $func);
191: }
192:
193: /**
194: * Вызывается перед requestHandler
195: *
196: */
197: public function beforeRequest() {
198: $this->_ajax = array();
199:
200: if (count($this->beforeRequestEvents) > 0) {
201: foreach ($this->beforeRequestEvents as $event) {
202: $event->onEvent($this);
203: }
204: }
205: }
206:
207: /**
208: * Вызывается после requestHandler
209: *
210: */
211: public function afterRequest() {
212:
213: if (count($this->afterRequestEvents) > 0) {
214: foreach ($this->afterRequestEvents as $event) {
215: $event->OnEvent($this);
216: }
217: }
218: }
219:
220: /**
221: * Переход по имени якоря (после загрузки страницы)
222: *
223: * @param mixed $name
224: */
225: protected function goAnkor($name) {
226: $this->_ankor = $name;
227: }
228:
229: public function setTitle($title) {
230: $this->_title = $title;
231: }
232:
233: public function setDescription($description) {
234: $this->_description = $description;
235: }
236:
237: public function setKeywords($keywords) {
238: $this->_keywords = $keywords;
239: }
240:
241: /**
242: * функция фонового обновления значения элемента формы
243: *
244: * @param mixed $sender
245: */
246: public function OnBackgroundUpdate($sender) {
247:
248: }
249:
250:
251: final public function RequestMethod($method) {
252: $p = WebApplication::$app->getRequest()->request_params[$method];
253: $post=null;
254: if($_SERVER["REQUEST_METHOD"]=='POST') {
255:
256: if(count($_POST)>0) {
257: $post = $_POST;
258: } else {
259: $post = file_get_contents('php://input');
260: }
261: }
262: $answer = $this->{$method}($p, $post);
263: if(strlen($answer)) {
264: WebApplication::$app->getResponse()->addAjaxResponse($answer) ;
265: }
266:
267: }
268:
269: /**
270: * добавляет яваскрипт в конец ответа на ajax запрос
271: *
272: * @param mixed $js
273: */
274: protected function addAjaxResponse($js) {
275: if (strlen($js) > 0) {
276: WebApplication::$app->getResponse()->addAjaxResponse($js);
277: }
278: }
279:
280:
281: final public function updateAjaXBlocks($a) {
282: $this->_ajaxblock = $a;
283:
284: }
285:
286: final public function updateAjaxHTML() {
287: if($this->hasAB()) {
288:
289: foreach($this->_ajaxblock as $id) {
290: $c = $this->getComponent($id,true) ;
291: if($c ==null){
292: continue;
293: }
294: $html = $c->getHTML() ;
295: if($html == null){
296: continue;
297: }
298: $html = str_replace("'","`",$html) ;
299: // $b = base64_encode($html) ;
300: $b = json_encode($html, JSON_UNESCAPED_UNICODE);
301:
302: // $js = "var hh = JSON.parse('{$b}') ";
303: $js .= "$('#{$id}').replaceWith({$b})";
304: // $js .= "$('#{$id}').replaceWith('{$html}')";
305:
306: // $js= "console.log('{$b}' )";
307:
308: $this->addAjaxResponse($js) ;
309:
310: }
311:
312: }
313: }
314:
315: final public function hasAB() {
316: return count($this->_ajaxblock);
317: }
318:
319: }
320: