BxVideosFormEntry.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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 Videos Videos
  7. * @ingroup UnaModules
  8. *
  9. * @{
  10. */
  11. /**
  12. * Create/Edit entry form
  13. */
  14. class BxVideosFormEntry extends BxBaseModTextFormEntry
  15. {
  16. protected $_sGhostTemplateVideo = 'form_ghost_template_video.html';
  17. public function __construct($aInfo, $oTemplate = false)
  18. {
  19. $this->MODULE = 'bx_videos';
  20. parent::__construct($aInfo, $oTemplate);
  21. $CNF = &$this->_oModule->_oConfig->CNF;
  22. if (isset($this->aInputs[$CNF['FIELD_VIDEOS']])) {
  23. $this->aInputs[$CNF['FIELD_VIDEOS']]['storage_object'] = $CNF['OBJECT_STORAGE_VIDEOS'];
  24. $this->aInputs[$CNF['FIELD_VIDEOS']]['uploaders'] = !empty($this->aInputs[$CNF['FIELD_VIDEOS']]['value']) ? unserialize($this->aInputs[$CNF['FIELD_VIDEOS']]['value']) : $CNF['OBJECT_UPLOADERS'];
  25. $this->aInputs[$CNF['FIELD_VIDEOS']]['upload_buttons_titles'] = _t('_bx_videos_form_entry_input_videos_upload');
  26. $this->aInputs[$CNF['FIELD_VIDEOS']]['images_transcoder'] = $CNF['OBJECT_VIDEOS_TRANSCODERS']['poster_preview'];
  27. $this->aInputs[$CNF['FIELD_VIDEOS']]['storage_private'] = 0;
  28. $this->aInputs[$CNF['FIELD_VIDEOS']]['multiple'] = false;
  29. $this->aInputs[$CNF['FIELD_VIDEOS']]['content_id'] = 0;
  30. $this->aInputs[$CNF['FIELD_VIDEOS']]['ghost_template'] = '';
  31. }
  32. }
  33. public function initChecker ($aValues = array (), $aSpecificValues = array())
  34. {
  35. $CNF = &$this->_oModule->_oConfig->CNF;
  36. if (isset($this->aInputs[$CNF['FIELD_VIDEOS']])) {
  37. $aContentInfo = false;
  38. if ($aValues && !empty($aValues['id'])) {
  39. $aContentInfo = $this->_oModule->_oDb->getContentInfoById ($aValues['id']);
  40. $this->aInputs[$CNF['FIELD_VIDEOS']]['content_id'] = $aValues['id'];
  41. }
  42. $this->aInputs[$CNF['FIELD_VIDEOS']]['ghost_template'] = $this->_oModule->_oTemplate->parseHtmlByName($this->_sGhostTemplateVideo, $this->_getVideoGhostTmplVars($aContentInfo));
  43. }
  44. return parent::initChecker($aValues, $aSpecificValues);
  45. }
  46. public function insert ($aValsToAdd = array(), $isIgnore = false)
  47. {
  48. $CNF = &$this->_oModule->_oConfig->CNF;
  49. $aValsToAdd[$CNF['FIELD_VIDEO']] = isset($_POST[$CNF['FIELD_VIDEO']]) ? bx_process_input($_POST[$CNF['FIELD_VIDEO']], BX_DATA_INT) : 0;
  50. if(!empty($CNF['FIELD_POSTER']) && $this->_oModule->checkAllowedSetThumb() === CHECK_ACTION_RESULT_ALLOWED) {
  51. $aPoster = isset($_POST[$CNF['FIELD_POSTER']]) ? bx_process_input ($_POST[$CNF['FIELD_POSTER']], BX_DATA_INT) : false;
  52. $aValsToAdd[$CNF['FIELD_POSTER']] = 0;
  53. if(!empty($aPoster) && is_array($aPoster) && ($iFilePoster = array_pop($aPoster)))
  54. $aValsToAdd[$CNF['FIELD_POSTER']] = $iFilePoster;
  55. }
  56. if (bx_get('video_source') == 'embed') {
  57. $aEmbedData = $this->_oModule->parseEmbedLink($this->getCleanValue('video_embed'));
  58. if ($aEmbedData)
  59. $aValsToAdd['video_embed_data'] = serialize($aEmbedData);
  60. //if poster is not set then set it implicitly by using the embed poster link
  61. if (!bx_get($CNF['FIELD_THUMB']) && $aEmbedData && $aEmbedData['thumb']) {
  62. $oPhotosStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
  63. $iFile = $oPhotosStorage->storeFileFromUrl($aEmbedData['thumb'], false, bx_get_logged_profile_id());
  64. bx_set($CNF['FIELD_THUMB'], [$iFile], 'get');
  65. bx_set($CNF['FIELD_THUMB'], [$iFile], 'post');
  66. bx_set($CNF['FIELD_PHOTO'], [$iFile], 'get');
  67. bx_set($CNF['FIELD_PHOTO'], [$iFile], 'post');
  68. }
  69. }
  70. $iContentId = parent::insert ($aValsToAdd, $isIgnore);
  71. if(!empty($iContentId))
  72. $this->processFiles($CNF['FIELD_VIDEOS'], $iContentId, true);
  73. return $iContentId;
  74. }
  75. public function update ($iContentId, $aValsToAdd = array(), &$aTrackTextFieldsChanges = null)
  76. {
  77. $CNF = &$this->_oModule->_oConfig->CNF;
  78. $aValsToAdd[$CNF['FIELD_VIDEO']] = isset($_POST[$CNF['FIELD_VIDEO']]) ? bx_process_input($_POST[$CNF['FIELD_VIDEO']], BX_DATA_INT) : 0;
  79. if(!empty($CNF['FIELD_POSTER']) && $this->_oModule->checkAllowedSetThumb($iContentId) === CHECK_ACTION_RESULT_ALLOWED && isset($CNF['FIELD_PHOTO']) && isset($this->aInputs[$CNF['FIELD_PHOTO']])) {
  80. $aPoster = bx_process_input (bx_get($CNF['FIELD_POSTER']), BX_DATA_INT);
  81. $aValsToAdd[$CNF['FIELD_POSTER']] = 0;
  82. if(!empty($aPoster) && is_array($aPoster) && ($iFilePoster = array_pop($aPoster)))
  83. $aValsToAdd[$CNF['FIELD_POSTER']] = $iFilePoster;
  84. }
  85. if (bx_get('video_source') == 'embed') {
  86. $aValsToAdd[$CNF['FIELD_STATUS']] = 'active'; //no need to keep awaiting if we've switched to embed
  87. $aEmbedData = $this->_oModule->parseEmbedLink($this->getCleanValue('video_embed'));
  88. if ($aEmbedData)
  89. $aValsToAdd['video_embed_data'] = serialize($aEmbedData);
  90. //if poster is not set then set it implicitly by using the embed poster link
  91. if (!bx_get($CNF['FIELD_THUMB']) && $aEmbedData && $aEmbedData['thumb']) {
  92. $oPhotosStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE']);
  93. $iFile = $oPhotosStorage->storeFileFromUrl($aEmbedData['thumb'], false, bx_get_logged_profile_id(), $iContentId);
  94. bx_set($CNF['FIELD_THUMB'], [$iFile], 'get');
  95. bx_set($CNF['FIELD_THUMB'], [$iFile], 'post');
  96. bx_set($CNF['FIELD_PHOTO'], [$iFile], 'get');
  97. bx_set($CNF['FIELD_PHOTO'], [$iFile], 'post');
  98. }
  99. } else {
  100. $aValsToAdd['video_embed_data'] = '';
  101. $aValsToAdd['video_embed'] = '';
  102. }
  103. $iRet = parent::update ($iContentId, $aValsToAdd, $aTrackTextFieldsChanges);
  104. $this->processFiles($CNF['FIELD_VIDEOS'], $iContentId, false);
  105. return $iRet;
  106. }
  107. public function processFiles ($sFieldFile, $iContentId = 0, $isAssociateWithContent = false)
  108. {
  109. $CNF = &$this->_oModule->_oConfig->CNF;
  110. if ($sFieldFile == $CNF['FIELD_VIDEOS'] && bx_get('video_source') == 'embed') {
  111. // delete video files in case the embed link has been provided
  112. if ($iContentId) {
  113. if (!isset($this->aInputs[$sFieldFile]))
  114. return true;
  115. $mixedFileIds = $this->getCleanValue($sFieldFile);
  116. if (!$mixedFileIds)
  117. return true;
  118. $oStorage = BxDolStorage::getObjectInstance($this->aInputs[$sFieldFile]['storage_object']);
  119. if (!$oStorage)
  120. return false;
  121. $iProfileId = $this->getContentOwnerProfileId($iContentId);
  122. $aGhostFiles = $oStorage->getGhosts($iProfileId, $isAssociateWithContent ? 0 : $iContentId, true, $this->_isAdmin($iContentId));
  123. if (!$aGhostFiles)
  124. return true;
  125. foreach ($aGhostFiles as $aFile) {
  126. if (is_array($mixedFileIds) && !in_array($aFile['id'], $mixedFileIds))
  127. continue;
  128. $oStorage->deleteFile($aFile['id'], bx_get_logged_profile_id());
  129. }
  130. }
  131. } else {
  132. return parent::processFiles($sFieldFile, $iContentId, $isAssociateWithContent);
  133. }
  134. }
  135. function delete ($iContentId, $aContentInfo = array())
  136. {
  137. $CNF = &$this->_oModule->_oConfig->CNF;
  138. $bResult = parent::delete($iContentId, $aContentInfo);
  139. if(!$bResult)
  140. return $bResult;
  141. // delete associated files
  142. if (!empty($CNF['OBJECT_STORAGE_VIDEOS'])) {
  143. $oStorage = BxDolStorage::getObjectInstance($CNF['OBJECT_STORAGE_VIDEOS']);
  144. if($oStorage)
  145. $oStorage->queueFilesForDeletionFromGhosts($aContentInfo[$CNF['FIELD_AUTHOR']], $iContentId);
  146. }
  147. return $bResult;
  148. }
  149. protected function genCustomViewRowValueDuration(&$aInput)
  150. {
  151. if (!$aInput['value']) return null;
  152. return _t_format_duration($aInput['value']);
  153. }
  154. protected function _getPhotoGhostTmplVars($aContentInfo = array())
  155. {
  156. $CNF = &$this->_oModule->_oConfig->CNF;
  157. $aResult = parent::_getPhotoGhostTmplVars($aContentInfo);
  158. $bPoster = !empty($CNF['FIELD_POSTER']) && $this->_oModule->checkAllowedSetThumb($this->aInputs[$CNF['FIELD_PHOTO']]['content_id']) === CHECK_ACTION_RESULT_ALLOWED;
  159. $aTmplVarsSetPoster = array();
  160. $aTmplVarsInitPoster = array();
  161. if($bPoster) {
  162. $aTmplVarsSetPoster = array (
  163. 'name_poster' => $CNF['FIELD_POSTER'],
  164. 'txt_pict_use_as_poster' => _t(!empty($CNF['T']['txt_pict_use_as_poster']) ? $CNF['T']['txt_pict_use_as_poster'] : '_sys_txt_form_entry_input_picture_use_as_thumb')
  165. );
  166. $aTmplVarsInitPoster = array(
  167. 'poster_id' => isset($aContentInfo[$CNF['FIELD_POSTER']]) ? $aContentInfo[$CNF['FIELD_POSTER']] : 0
  168. );
  169. }
  170. $aResult = array_merge($aResult, array(
  171. 'bx_if:set_poster' => array (
  172. 'condition' => $bPoster,
  173. 'content' => $aTmplVarsSetPoster
  174. ),
  175. 'bx_if:init_poster' => array(
  176. 'condition' => $bPoster,
  177. 'content' => $aTmplVarsInitPoster
  178. )
  179. ));
  180. return $aResult;
  181. }
  182. protected function _getVideoGhostTmplVars($aContentInfo = array())
  183. {
  184. $CNF = &$this->_oModule->_oConfig->CNF;
  185. return array (
  186. 'name' => $this->aInputs[$CNF['FIELD_VIDEOS']]['name'],
  187. 'name_thumb' => isset($CNF['FIELD_VIDEO']) ? $CNF['FIELD_VIDEO'] : '',
  188. 'content_id' => $this->aInputs[$CNF['FIELD_VIDEOS']]['content_id'],
  189. );
  190. }
  191. public function genCustomRowVideoEmbed(&$aInput)
  192. {
  193. $sSource = isset($this->aInputs['video_source']) && $this->aInputs['video_source']['value'] == 'embed' ? 'embed' : 'upload';
  194. if ($sSource != 'embed') {
  195. if (!is_array($aInput['tr_attrs']))
  196. $aInput['tr_attrs'] = [];
  197. $aInput['tr_attrs']['style'] = 'display:none';
  198. }
  199. return $this->genRowStandard($aInput);
  200. }
  201. public function genCustomRowVideos(&$aInput)
  202. {
  203. $sSource = isset($this->aInputs['video_source']) && $this->aInputs['video_source']['value'] == 'embed' ? 'embed' : 'upload';
  204. if ($sSource != 'upload') $aInput['tr_attrs']['style'] = 'display:none';
  205. return $this->genRowCustom($aInput, 'genInputFiles');
  206. }
  207. public function genCustomInputVideoEmbed(&$aInput)
  208. {
  209. $aEmbedInput = [
  210. 'type' => 'text',
  211. 'name' => $aInput['name'],
  212. 'value' => isset($aInput['value']) ? $aInput['value'] : '',
  213. 'attrs' => [
  214. 'id' => 'bx-video-embed-link',
  215. 'onchange' => $this->_oModule->_oConfig->getJsObject('embeds').'.onNewEmbedCode()',
  216. 'onpaste' => $this->_oModule->_oConfig->getJsObject('embeds').'.onNewEmbedCodeTyping(100)', //the reason is that on this event the value has not been update yet
  217. 'onkeydown' => $this->_oModule->_oConfig->getJsObject('embeds').'.onNewEmbedCodeTyping(500)',
  218. ],
  219. ];
  220. if($this->_bIsApi) {
  221. $aEmbedInput['type'] = 'embed';
  222. return $aEmbedInput;
  223. }
  224. $sEmbedCode = '';
  225. if (isset($aInput['value']) && !empty($aInput['value']) && $aEmbed = $this->_oModule->parseEmbedLink($aInput['value'])) {
  226. $sEmbedCode = $aEmbed['embed'];
  227. }
  228. return $this->_oModule->_oTemplate->parseHtmlByName('form_field_embed.html', [
  229. 'input' => $this->genInputStandard($aEmbedInput),
  230. 'bx_if:noembed_code' => [
  231. 'condition' => empty($sEmbedCode),
  232. 'content' => [],
  233. ],
  234. 'embed_code' => $sEmbedCode,
  235. ]);
  236. }
  237. public function genInput(&$aInput)
  238. {
  239. if($this->_bIsApi)
  240. return parent::genInput($aInput);
  241. $sJsCode = '';
  242. if ($aInput['name'] == 'video_source' && $aInput['type'] == 'radio_set') {
  243. if (!is_array($aInput['attrs']))
  244. $aInput['attrs'] = [];
  245. $aInput['attrs']['onchange'] = $this->_oModule->_oConfig->getJsObject('embeds').'.changeVideoSource(this);';
  246. $sJsCode = '';
  247. if ($this->_bDynamicMode) {
  248. $sJsCode .= $this->_oModule->_oTemplate->addJs('embeds.js', true);
  249. $sJsCode .= $this->_oModule->_oTemplate->addCss('embeds.css', true);
  250. } else {
  251. $this->_oModule->_oTemplate->addJs('embeds.js', false);
  252. $this->_oModule->_oTemplate->addCss('embeds.css', false);
  253. }
  254. $sJsCode .= $this->_oModule->_oTemplate->getJsCode('embeds');
  255. }
  256. return parent::genInput($aInput).$sJsCode;
  257. }
  258. }
  259. class BxVideosFormCheckerHelper extends BxDolFormCheckerHelper {
  260. static public function checkUploadVideoAvail ($s)
  261. {
  262. $sSource = bx_get('video_source');
  263. if ($sSource != 'embed') $sSource = 'upload';
  264. if ($sSource == 'embed') return true; //if we are embedding then skip uploads check
  265. return parent::checkAvail($s);
  266. }
  267. static public function checkEmbedVideoAvail ($s)
  268. {
  269. $sSource = bx_get('video_source');
  270. if ($sSource != 'embed') $sSource = 'upload';
  271. if ($sSource == 'upload') return true; //if we are uploading then skip embed check
  272. if (!parent::checkAvail($s)) return false;
  273. $oModule = BxDolModule::getInstance('bx_videos');
  274. if (!$oModule->parseEmbedLink($s)) return false;
  275. return true;
  276. }
  277. }
  278. /** @} */