api.zenflow.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. /**
  3. * Just dynamic content update abstraction layer
  4. */
  5. class ZenFlow {
  6. /**
  7. * Container refresh timeout in ms.
  8. *
  9. * @var int
  10. */
  11. protected $timeout = 3000;
  12. /**
  13. * Contains current zen-flow ID string
  14. *
  15. * @var string
  16. */
  17. protected $flowId = '';
  18. /**
  19. * Content string to render in container area
  20. *
  21. * @var string
  22. */
  23. protected $content = '';
  24. /**
  25. * Debug flag
  26. *
  27. * @var bool
  28. */
  29. protected $debug = false;
  30. /**
  31. * Contains sound path to be played if content updates
  32. *
  33. * @var string
  34. */
  35. protected $soundOnChange = '';
  36. /**
  37. * Contains some predefined routes
  38. */
  39. const ROUTE_ZENFLOW = 'zenflow';
  40. /**
  41. * Creates new Zen-flow instance
  42. *
  43. * @param string $flowId unique identifier of zen-flow instance
  44. * @param string $content some string or function which will be updated into container
  45. * @param int $timeout timeout in ms.
  46. */
  47. public function __construct($flowId, $content = '', $timeout = '') {
  48. $this->setFlowId($flowId); //set flow ID
  49. $this->setContent($content);
  50. if (!empty($timeout)) {
  51. $this->setTimeout($timeout);
  52. }
  53. $this->listener();
  54. }
  55. /**
  56. * Sets current instance flow ID
  57. *
  58. * @param string $flowId
  59. *
  60. * @return void
  61. */
  62. protected function setFlowId($flowId) {
  63. if (!empty($flowId)) {
  64. $this->flowId = 'zen' . $flowId;
  65. } else {
  66. throw new Exception('EX_EMPTY_FLOWID');
  67. }
  68. }
  69. /**
  70. * Sets instance refresh rate in ms.
  71. *
  72. * @param int $timeout
  73. *
  74. * @return void
  75. */
  76. protected function setTimeout($timeout) {
  77. $this->timeout = $timeout;
  78. }
  79. /**
  80. * Sets the debug state. Enables debug timestamp output on content update.
  81. *
  82. * @param bool $state The debug state to set. True to enable debugging, false to disable.
  83. *
  84. * @return void
  85. */
  86. public function setDebug($state) {
  87. $this->debug = $state;
  88. }
  89. /**
  90. * Set sound file path to be played on content updates
  91. *
  92. * @param string $soundOnChange
  93. *
  94. * @return void
  95. */
  96. public function setSoundOnChange($soundOnChange) {
  97. $this->soundOnChange = $soundOnChange;
  98. }
  99. /**
  100. * Puts content data from constructor into protected property.
  101. *
  102. * @param string $content
  103. *
  104. * @return void
  105. */
  106. protected function setContent($content = '') {
  107. $this->content = $content;
  108. }
  109. /**
  110. * Renders initial zen-container with some prefilled content.
  111. *
  112. * @return string
  113. */
  114. public function render() {
  115. $result = '';
  116. if (!empty($this->flowId)) {
  117. $container = 'zencontainer_' . $this->flowId;
  118. $debugArea = 'zendebug_' . $this->flowId;
  119. $epoch = 'zen' . $this->flowId . 'epoch';
  120. $epochUpd = 'zen' . $this->flowId . 'epochupd';
  121. $debugCode = '';
  122. $requestUrl = $_SERVER['REQUEST_URI'];
  123. $soundPlayback = '';
  124. if (!empty($requestUrl)) {
  125. $result .= wf_AjaxContainer($container, '', $this->content);
  126. if ($this->debug) {
  127. $result .= wf_AjaxContainer($debugArea, '', '');
  128. $debugCode .= '
  129. var debugTimestamp' . $this->flowId . ' = new Date();
  130. var debutTimeLabel' . $this->flowId . ' = debugTimestamp' . $this->flowId . '.toLocaleTimeString();
  131. $("#' . $debugArea . '").html("' . __('Changed') . ': "+debutTimeLabel' . $this->flowId . '+" ' . __('Iteration') . ': "+' . $epochUpd . '+" of "+' . $epoch . ');
  132. ';
  133. }
  134. if ($this->soundOnChange) {
  135. $soundPlayback = '
  136. if (' . $epochUpd . '>0) {
  137. var audio' . $this->flowId . ' = new Audio("' . $this->soundOnChange . '");
  138. audio' . $this->flowId . '.play();
  139. }
  140. ';
  141. }
  142. $dataUrl = $requestUrl;
  143. if (!ubRouting::checkGet(self::ROUTE_ZENFLOW)) {
  144. $dataUrl .= '&' . self::ROUTE_ZENFLOW . '=' . $this->flowId;
  145. }
  146. $result .= wf_tag('script');
  147. $result .= '$(document).ready(function() {
  148. var ' . $epoch . ' = 0;
  149. var ' . $epochUpd . ' = 0;
  150. var prevData= "";
  151. setInterval(function(){
  152. ' . $epoch . '++;
  153. $.get("' . $dataUrl . '", function(data) {
  154. //update zen-container only if data is changed
  155. if (prevData!=data) {
  156. $("#' . $container . '").html(data);
  157. prevData=data;
  158. ' . $soundPlayback . '
  159. ' . $epochUpd . '++;
  160. }
  161. ' . $debugCode . '
  162. });
  163. }, ' . $this->timeout . ');
  164. });
  165. ';
  166. $result .= wf_tag('script', true);
  167. }
  168. }
  169. return ($result);
  170. }
  171. /**
  172. * Listens for some flow callback, checks is this current instance flow and renders content.
  173. *
  174. * @return bool
  175. */
  176. protected function listener() {
  177. $result = false;
  178. if (ubRouting::checkGet(self::ROUTE_ZENFLOW)) {
  179. $requestFlow = ubRouting::get(self::ROUTE_ZENFLOW);
  180. //its my flow?
  181. if ($requestFlow == $this->flowId) {
  182. print($this->content);
  183. die();
  184. }
  185. }
  186. /**
  187. * If you heard the loud big bang
  188. * You can see it with your eyes
  189. * The eternal night breaks when
  190. * The mushroom grows into the sky
  191. */
  192. return ($result);
  193. }
  194. }