BxDolStudioSettings.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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 UnaStudio UNA Studio
  7. * @{
  8. */
  9. define('BX_DOL_STUDIO_STG_TYPE_SYSTEM', 'system');
  10. define('BX_DOL_STUDIO_STG_TYPE_DEFAULT', BX_DOL_STUDIO_STG_TYPE_SYSTEM);
  11. define('BX_DOL_STUDIO_STG_GROUP_SYSTEM', 'system');
  12. define('BX_DOL_STUDIO_STG_GROUP_MODULES', 'modules');
  13. define('BX_DOL_STUDIO_STG_GROUP_LANGUAGES', 'languages');
  14. define('BX_DOL_STUDIO_STG_GROUP_TEMPLATES', 'templates');
  15. define('BX_DOL_STUDIO_STG_CATEGORY_SYSTEM', 'system');
  16. define('BX_DOL_STUDIO_STG_CATEGORY_LANGUAGES', 'languages');
  17. define('BX_DOL_STUDIO_STG_CATEGORY_TEMPLATES', 'templates');
  18. define('BX_DOL_STUDIO_STG_CATEGORY_AUDIT', 'audit');
  19. define('BX_DOL_STUDIO_STG_MIX_SYSTEM', 'system');
  20. define('BX_DOL_STUDIO_STG_MIX_DEFAULT', BX_DOL_STUDIO_STG_MIX_SYSTEM);
  21. class BxDolStudioSettings extends BxTemplStudioPage
  22. {
  23. protected $sType;
  24. protected $sCategory;
  25. protected $aCategories;
  26. protected $aCustomCategories;
  27. protected $bReadOnly; //--- Enable/Disable ReadOnly mode for system settings. Note. It doesn't affect Editable mixes.
  28. protected $bMixes; //--- Enable/Disable mixes feature.
  29. protected $sMix;
  30. protected $aMix;
  31. protected $sStorage;
  32. protected $sTranscoder;
  33. protected $sErrorMessage;
  34. function __construct($sType = '', $mixedCategory = '')
  35. {
  36. parent::__construct('settings');
  37. $this->oDb = new BxDolStudioSettingsQuery();
  38. $this->sType = BX_DOL_STUDIO_STG_TYPE_DEFAULT;
  39. if(!empty($sType) && is_string($sType))
  40. $this->sType = $sType;
  41. $this->sCategory = '';
  42. if(!empty($mixedCategory)) {
  43. if(is_array($mixedCategory))
  44. $this->sCategory = $mixedCategory;
  45. else if(is_string($mixedCategory)) {
  46. $this->sCategory = json_decode($mixedCategory);
  47. if(empty($this->sCategory))
  48. $this->sCategory = $mixedCategory;
  49. }
  50. }
  51. $this->bReadOnly = false;
  52. $this->bMixes = false;
  53. $this->sMix = '';
  54. $this->aMix = array();
  55. $this->sStorage = 'sys_images_custom';
  56. $this->sTranscoder = 'sys_custom_images';
  57. $this->sErrorMessage = '';
  58. //--- Check actions ---//
  59. if(($sAction = bx_get('stg_action')) !== false) {
  60. $sAction = bx_process_input($sAction);
  61. $sValue = '';
  62. if(bx_get('stg_value') !== false)
  63. $sValue = bx_process_input(bx_get('stg_value'));
  64. $aResult = array('code' => 0, 'message' => '');
  65. if(!empty($sAction)) {
  66. switch($sAction) {
  67. case 'select-mix':
  68. $aResult = array_merge($aResult, $this->selectMix($sValue));
  69. break;
  70. case 'create-mix':
  71. $aResult = array_merge($aResult, $this->getPopupCodeCreateMix());
  72. break;
  73. case 'import-mix':
  74. $aResult = array_merge($aResult, $this->getPopupCodeImportMix());
  75. break;
  76. case 'export-mix':
  77. $aResult = array_merge($aResult, $this->exportMix((int)$sValue));
  78. break;
  79. case 'download-mix':
  80. $aResult = array_merge($aResult, $this->downloadMix((int)$sValue));
  81. break;
  82. case 'publish-mix':
  83. $aResult = array_merge($aResult, $this->publishMix((int)$sValue));
  84. break;
  85. case 'hide-mix':
  86. $aResult = array_merge($aResult, $this->hideMix((int)$sValue));
  87. break;
  88. case 'delete-mix':
  89. $aResult = array_merge($aResult, $this->deleteMix((int)$sValue));
  90. break;
  91. case 'get-page-by-type':
  92. $this->sType = $sValue;
  93. $aResult['content'] = $this->getPageCode();
  94. break;
  95. }
  96. echo json_encode($aResult);
  97. }
  98. exit;
  99. }
  100. }
  101. public function enableReadOnly($bReadOnly = true)
  102. {
  103. $this->bReadOnly = $bReadOnly;
  104. }
  105. public function enableMixes($bMixes = true)
  106. {
  107. $this->bMixes = $bMixes;
  108. }
  109. public function selectMix($sName)
  110. {
  111. $this->oDb->updateMixes(array('active' => 0), array(
  112. 'type' => $this->sType,
  113. 'category' => is_string($this->sCategory) ? $this->sCategory : '',
  114. 'active' => 1
  115. ));
  116. $aResult = array();
  117. if($sName == BX_DOL_STUDIO_STG_MIX_SYSTEM || $this->oDb->updateMixes(array('active' => 1), array('name' => $sName))) {
  118. $this->clearCache();
  119. $aResult = array('eval' => $this->getPageJsObject() . '.onMixSelect(oData);');
  120. }
  121. else
  122. $aResult = array('message' => _t('_adm_stg_err_cannot_perform'));
  123. return $aResult;
  124. }
  125. public function exportMix($iId)
  126. {
  127. $aMix = array();
  128. $this->oDb->getMixes(array('type' => 'by_id', 'value' => $iId), $aMix, false);
  129. if(empty($aMix) || !is_array($aMix))
  130. return array('message' => _t('_adm_stg_err_cannot_perform'));
  131. return array(
  132. 'url' => bx_append_url_params(BX_DOL_URL_STUDIO . 'settings.php', array(
  133. 'stg_action' => 'download-mix',
  134. 'stg_value' => $iId,
  135. )),
  136. 'eval' => $this->getPageJsObject() . '.onMixExport(oData);'
  137. );
  138. }
  139. public function downloadMix($iId)
  140. {
  141. $aMix = array();
  142. $this->oDb->getMixes(array('type' => 'by_id', 'value' => $iId), $aMix, false);
  143. if(empty($aMix) || !is_array($aMix))
  144. BxDolStudioTemplate::getInstance()->displayPageNotFound();
  145. $aOptions = array();
  146. $this->oDb->getMixesOptions(array('type' => 'by_mix_id_pair_option_value', 'value' => $iId, 'for_export' => 1), $aOptions, false);
  147. $aContent = array(
  148. 'mix' => array(
  149. 'type' => $aMix['type'],
  150. 'category' => $aMix['category'],
  151. 'name' => $aMix['name'],
  152. 'title' => $aMix['title']
  153. ),
  154. 'options' => $aOptions
  155. );
  156. $sContent = json_encode($aContent);
  157. header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  158. header("Content-type: application/json");
  159. header("Content-Length: " . strlen($sContent));
  160. header("Content-Disposition: attachment; filename=\"". strtolower($aMix['name']) . ".json\"");
  161. echo $sContent;
  162. exit;
  163. }
  164. public function publishMix($iId)
  165. {
  166. $aResult = array();
  167. if($this->oDb->updateMixes(array('published' => 1), array('id' => $iId))) {
  168. $this->clearCache();
  169. $aResult = array('eval' => $this->getPageJsObject() . '.onMixPublish(oData);');
  170. }
  171. else
  172. $aResult = array('message' => _t('_adm_stg_err_cannot_perform'));
  173. return $aResult;
  174. }
  175. public function hideMix($iId)
  176. {
  177. $aResult = array();
  178. if($this->oDb->updateMixes(array('published' => 0), array('id' => $iId))) {
  179. $this->clearCache();
  180. $aResult = array('eval' => $this->getPageJsObject() . '.onMixHide(oData);');
  181. }
  182. else
  183. $aResult = array('message' => _t('_adm_stg_err_cannot_perform'));
  184. return $aResult;
  185. }
  186. public function deleteMix($iId)
  187. {
  188. $aResult = array();
  189. if($this->oDb->deleteMixesOptions(array('mix_id' => $iId)) && $this->oDb->deleteMixes(array('id' => $iId))) {
  190. $this->clearCache();
  191. $aResult = array('eval' => $this->getPageJsObject() . '.onMixDelete(oData);');
  192. }
  193. else
  194. $aResult = array('message' => _t('_adm_stg_err_cannot_perform'));
  195. return $aResult;
  196. }
  197. function saveChanges(&$oForm)
  198. {
  199. $iMixId = $oForm->getCleanValue('mix_id');
  200. $aCategories = explode(',', $oForm->getCleanValue('categories'));
  201. $sEvalRenewToken = '$("#' . $oForm->getId() . ' input[name=csrf_token]").val("' . $oForm->getCsrfToken() . '");';
  202. foreach ($aCategories as $sCategory) {
  203. $aOptions = array();
  204. $iOptions = $this->oDb->getOptions(array('type' => 'by_category_name_full', 'value' => $sCategory), $aOptions);
  205. $aData = array();
  206. foreach($aOptions as $aOption) {
  207. $aData[$aOption['name']] = $this->getSubmittedValue($aOption, $oForm);
  208. if($aData[$aOption['name']] === false && !empty($this->sErrorMessage)) {
  209. $this->sCategory = $sCategory;
  210. return $this->getJsResult(_t('_adm_stg_err_save_error_message', _t($aOption['caption']), _t($this->sErrorMessage)), false, false, '', $sEvalRenewToken);
  211. }
  212. if(!empty($aOption['check'])) {
  213. $sCheckerHelper = '';
  214. if(!empty($aOption['type_name']) && BxDolRequest::serviceExists($aOption['type_name'], 'get_settings_checker_helper'))
  215. $sCheckerHelper = BxDolService::call($aOption['type_name'], 'get_settings_checker_helper');
  216. if($sCheckerHelper == '') {
  217. bx_import('BxDolStudioForm');
  218. $sCheckerHelper = 'BxDolStudioFormCheckerHelper';
  219. }
  220. $oChecker = new $sCheckerHelper();
  221. $aCheckFunction = array($oChecker, 'check' . bx_gen_method_name($aOption['check']));
  222. $aCheckFunctionParams = array($aData[$aOption['name']]);
  223. if(!empty($aOption['check_params']))
  224. $aCheckFunctionParams = array_merge($aCheckFunctionParams, unserialize($aOption['check_params']));
  225. if(is_callable($aCheckFunction) && !call_user_func_array($aCheckFunction, $aCheckFunctionParams)) {
  226. $this->sCategory = $sCategory;
  227. return $this->getJsResult(_t('_adm_stg_err_save_error_message', _t($aOption['caption']), _t($aOption['check_error'])), false, false, '', $sEvalRenewToken);
  228. }
  229. }
  230. if(isset($aData[$aOption['name']]))
  231. $aData[$aOption['name']] = $this->getProcessedValue($aOption, $aData[$aOption['name']]);
  232. else
  233. $aData[$aOption['name']] = $this->getEmptyValue($aOption);
  234. $mixedValue = $this->oDb->getParam($aOption['name']);
  235. if($this->oDb->setParam($aOption['name'], $aData[$aOption['name']], $iMixId)) {
  236. $aCategoryInfo = array();
  237. $this->oDb->getCategories(array('type' => 'by_name', 'value' => $sCategory), $aCategoryInfo, false);
  238. bx_alert('system', 'save_setting', 0, 0, array(
  239. 'category' => $aCategoryInfo,
  240. 'option' => $aOption['name'],
  241. 'value' => $aData[$aOption['name']],
  242. 'value_prior' => $mixedValue
  243. ));
  244. }
  245. }
  246. }
  247. return $this->getJsResult('_adm_stg_scs_save', true, false, '', $sEvalRenewToken);
  248. }
  249. protected function isReadOnly()
  250. {
  251. $bMix = !empty($this->aMix);
  252. return (!$bMix && $this->bReadOnly) || ($bMix && (int)$this->aMix['editable'] == 0);
  253. }
  254. protected function getSubmittedValue($aOption, &$oForm)
  255. {
  256. $mixedValue = '';
  257. switch($aOption['type']) {
  258. case 'image':
  259. $mixedValue = (int)getParam($aOption['name']);
  260. $aIds = $oForm->getCleanValue($aOption['name']);
  261. if(empty($aIds))
  262. break;
  263. $oStorage = BxDolStorage::getObjectInstance($this->sStorage);
  264. if(!$oStorage)
  265. break;
  266. //--- Concatenation integer values as strings is required to get unique content id
  267. $iContentId = (int)($aOption['id'] . (int)$oForm->getCleanValue('mix_id'));
  268. foreach($aIds as $iId) {
  269. $oStorage->updateGhostsContentId($iId, false, $iContentId);
  270. $mixedValue = $iId;
  271. }
  272. break;
  273. default:
  274. $mixedValue = $oForm->getCleanValue($aOption['name']);
  275. }
  276. return $mixedValue;
  277. }
  278. protected function getProcessedValue($aOption, $mixedValue)
  279. {
  280. if(is_array($mixedValue))
  281. $mixedValue = implode(',', $mixedValue);
  282. return $mixedValue;
  283. }
  284. protected function getEmptyValue($aOption)
  285. {
  286. $mixedValue = '';
  287. switch($aOption['type']) {
  288. case 'digit':
  289. $mixedValue = 0;
  290. break;
  291. case 'select':
  292. if (BxDolService::isSerializedService($aOption['extra']))
  293. $aValues = BxDolService::callSerialized($aOption['extra']);
  294. else
  295. $aValues = explode(',', $aOption['extra']);
  296. $mixedValue = $aValues[0];
  297. break;
  298. case 'text':
  299. case 'checkbox':
  300. case 'file':
  301. $mixedValue = "";
  302. break;
  303. }
  304. return $mixedValue;
  305. }
  306. protected function clearCache()
  307. {
  308. BxDolDb::getInstance()->cacheParams(true, true);
  309. $oCacheUtilities = BxDolCacheUtilities::getInstance();
  310. $oCacheUtilities->clear('db');
  311. $oCacheUtilities->clear('css');
  312. }
  313. }
  314. /** @} */