BxDolEmbed.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. /**
  10. * Embed provider.
  11. *
  12. * Create an embed from a link.
  13. *
  14. * @section embed_provider_create Creating the Editor object:
  15. *
  16. *
  17. * Add record to 'sys_objects_embeds' table:
  18. *
  19. * - object: name of the embed object, in the format: vendor prefix, underscore, module prefix, underscore, internal identifier or nothing
  20. * - title: title of the embed provider, dmay be isplayed in the Studio.
  21. * - override_class_name: user defined class name which is derived from one of base embed provider classes.
  22. * - override_class_file: the location of the user defined class, leave it empty if class is located in system folders.
  23. *
  24. *
  25. * @section example Example of usage
  26. *
  27. * Generate HTML for a link which will be converted to an embed later:
  28. *
  29. * @code
  30. * $oEmbed = BxDolEmbed::getObjectInstance(); // get default embed object instance
  31. * if ($oEmbed) // check if embed provider is available for using
  32. * echo $oEmbed->getLinkHTML ('https://una.io', 'UNA.IO'); // output HTML which will be automatically converted into embed upon page load
  33. * else
  34. * echo '<a href="https://una.io">UNA.IO</a>';
  35. * @endcode
  36. *
  37. */
  38. class BxDolEmbed extends BxDolFactoryObject
  39. {
  40. protected $_bAsync = false;
  41. protected $_sSocketName = 'sys_embed';
  42. protected $_sTableData = '';
  43. protected $_iLifetime;
  44. protected $_bCssJsAdded = false;
  45. public function __construct ($aObject, $oTemplate = null)
  46. {
  47. parent::__construct($aObject, $oTemplate, 'BxDolEmbedQuery');
  48. $this->_oDb->setParams([
  49. 'table_data' => $this->_sTableData
  50. ]);
  51. $this->_iLifetime = 86400 * (int)getParam('sys_embed_lifetime');
  52. }
  53. /**
  54. * Get embed provider object instance by object name
  55. * @param $sObject object name
  56. * @return object instance or false on error
  57. */
  58. static public function getObjectInstance($sObject = false, $oTemplate = false)
  59. {
  60. if (!$sObject)
  61. $sObject = getParam('sys_embed_default');
  62. return parent::getObjectInstanceByClassNames($sObject, $oTemplate, 'BxDolEmbed', 'BxDolEmbedQuery');
  63. }
  64. /**
  65. * Print HTML which will be automatically converted into embed upon page load
  66. * @param $sLink - link
  67. * @param $sTitle - title or use link for the title if omitted
  68. * @param $sMaxWidth - try to restrict max width of embed (works in supported embed providers only)
  69. */
  70. public function getLinkHTML ($sLink, $sTitle = '', $sMaxWidth = '')
  71. {
  72. // override this function in particular embed provider class
  73. }
  74. /**
  75. * Execute an initialization JS code
  76. */
  77. public function addProcessLinkMethod ()
  78. {
  79. // override this function in particular embed provider class
  80. return '';
  81. }
  82. /**
  83. * Add css/js files which are needed for embed display and functionality.
  84. */
  85. public function addJsCss ()
  86. {
  87. // override this function in particular embed provider class
  88. }
  89. public function getData ($sUrl, $sTheme, $bForcedly = false)
  90. {
  91. $sUrl = $this->cleanYoutubeUrl($sUrl);
  92. if($this->_sTableData) {
  93. $aLocal = $this->_oDb->getLocalInfo($sUrl, $sTheme);
  94. $bRevalidate = false;
  95. if($this->_iLifetime && (int)$aLocal['added'] + $this->_iLifetime < time()) {
  96. $this->_oDb->deleteLocal([
  97. 'url' => $sUrl,
  98. 'theme' => $sTheme
  99. ]);
  100. $bRevalidate = true;
  101. }
  102. $sData = false;
  103. if($bRevalidate || (($sKey = 'data') && !($sData = $aLocal[$sKey] ?? false)))
  104. $sData = $this->{'_getData' . ($sData !== false ? 'Empty' : ($this->_bAsync && !$bForcedly ? 'Async' : ''))}($sUrl, $sTheme);
  105. }
  106. else
  107. $sData = $this->_getData($sUrl, $sTheme);
  108. return json_decode($sData, true);
  109. }
  110. public function getDataFromApi ($sUrl, $sTheme)
  111. {
  112. // override this function in particular embed provider class
  113. }
  114. public function process ()
  115. {
  116. $aEmbeds = $this->_oDb->getLocalUnprocessed();
  117. if(empty($aEmbeds) || !is_array($aEmbeds))
  118. return;
  119. $oSockets = BxDolSockets::getInstance();
  120. $bSockets = $oSockets->isEnabled();
  121. foreach($aEmbeds as $aEmbed)
  122. if(($sData = $this->getDataFromApi($aEmbed['url'], $aEmbed['theme']))) {
  123. $this->_oDb->updateLocal(['data' => $sData], ['id' => $aEmbed['id']]);
  124. if($bSockets)
  125. $oSockets->sendEvent($this->_sSocketName, $aEmbed['id'], 'processed', $sData);
  126. }
  127. }
  128. public function cleanYoutubeUrl($url)
  129. {
  130. $parsedUrl = parse_url($url);
  131. if (isset($parsedUrl['host']) && $parsedUrl['host'] === 'youtu.be') {
  132. if (isset($parsedUrl['query'])) {
  133. parse_str($parsedUrl['query'], $queryParams);
  134. if (isset($queryParams['si'])) {
  135. unset($queryParams['si']);
  136. }
  137. $queryString = http_build_query($queryParams);
  138. $cleanUrl = $parsedUrl['scheme'] . '://' . $parsedUrl['host'] . $parsedUrl['path'];
  139. if (!empty($queryString)) {
  140. $cleanUrl .= '?' . $queryString;
  141. }
  142. return $cleanUrl;
  143. }
  144. return $url;
  145. }
  146. return $url;
  147. }
  148. protected function _getData($sUrl, $sTheme)
  149. {
  150. $sData = $this->getDataFromApi($sUrl, $sTheme);
  151. if($sData)
  152. $this->_oDb->insertLocal($sUrl, $sTheme, $sData);
  153. return $sData;
  154. }
  155. protected function _getDataAsync($sUrl, $sTheme)
  156. {
  157. $iId = $this->_oDb->insertLocal($sUrl, $sTheme);
  158. if(($sName = 'bx_embed_processing') && ($oCronQuery = BxDolCronQuery::getInstance()) && !$oCronQuery->isTransientJobService($sName))
  159. $oCronQuery->addTransientJobService($sName, ['system', 'process_embed', [], 'TemplServices']);
  160. return $this->_getDataEmpty($sUrl, $sTheme, [
  161. 'id' => $iId,
  162. 'processing' => true
  163. ]);
  164. }
  165. protected function _getDataEmpty($sUrl, $sTheme, $aAddons = [])
  166. {
  167. return json_encode(array_merge([
  168. 'url' => $sUrl,
  169. 'domain' => parse_url($sUrl, PHP_URL_HOST),
  170. ], $aAddons));
  171. }
  172. }
  173. /** @} */