BxDolContentFilter.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. class BxDolContentFilter extends BxDolFactory implements iBxDolSingleton
  10. {
  11. protected $_oDb;
  12. protected $_sDataList;
  13. protected $_iDefaultValue;
  14. protected $_iViewerId;
  15. protected function __construct()
  16. {
  17. parent::__construct();
  18. $this->_oDb = BxDolDb::getInstance();
  19. $this->_sDataList = 'sys_content_filter';
  20. $this->_iDefaultValue = 1; //--- Means G (ID = 1) - content available to everybody
  21. $this->_iViewerId = bx_get_logged_profile_id();
  22. }
  23. public function __clone()
  24. {
  25. if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
  26. trigger_error('Clone is not allowed for the class: ' . get_class($this), E_USER_ERROR);
  27. }
  28. public static function getInstance()
  29. {
  30. if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
  31. $GLOBALS['bxDolClasses'][__CLASS__] = new BxDolContentFilter();
  32. return $GLOBALS['bxDolClasses'][__CLASS__];
  33. }
  34. public function isEnabled()
  35. {
  36. return getParam('sys_cf_enable') == 'on';
  37. }
  38. public function isEnabledForComments()
  39. {
  40. return getParam('sys_cf_enable_comments') == 'on';
  41. }
  42. public function getProhibited()
  43. {
  44. $sValues = getParam('sys_cf_prohibited');
  45. if(!$sValues)
  46. return [];
  47. $aValues = explode(',', $sValues);
  48. if(!$aValues)
  49. return [];
  50. return $aValues;
  51. }
  52. public function getDefaultValue()
  53. {
  54. return $this->_iDefaultValue;
  55. }
  56. public function getValues()
  57. {
  58. return BxDolFormQuery::getDataItems($this->_sDataList);
  59. }
  60. public function getInput($aInput, $iProfileId = 0)
  61. {
  62. return $this->_getInput('content', $aInput, $iProfileId);
  63. }
  64. public function getInputForComments($aInput, $iProfileId = 0)
  65. {
  66. return $this->_getInput('comments', $aInput, $iProfileId);
  67. }
  68. protected function _getInput($sType, $aInput, $iProfileId = 0)
  69. {
  70. if(!$this->{'isEnabled' . ($sType == 'comments' ? 'ForComments' : '')}())
  71. return array_merge($aInput, [
  72. 'type' => 'hidden',
  73. 'value' => 1
  74. ]);
  75. if(!$aInput['values'])
  76. $aInput['values'] = BxDolFormQuery::getDataItems($this->_sDataList);
  77. if(!$iProfileId)
  78. $iProfileId = bx_get_logged_profile_id();
  79. $aProfileInfo = BxDolProfileQuery::getInstance()->getInfoById($iProfileId);
  80. if(empty($aProfileInfo) || !isset($aProfileInfo['cfu_items']))
  81. return $aInput;
  82. $aCfuValues = [];
  83. foreach($aInput['values'] as $iValue => $sTitle)
  84. if((1 << ($iValue - 1)) & (int)$aProfileInfo['cfu_items'])
  85. $aCfuValues[$iValue] = $sTitle;
  86. $aInput['values'] = $aCfuValues;
  87. return $aInput;
  88. }
  89. public function isAllowed($iValue, $iViewerId = 0)
  90. {
  91. if(!$this->isAllowedBySetting($iValue))
  92. return false;
  93. if(!$this->isAllowedByViewer($iValue, $iViewerId))
  94. return false;
  95. return true;
  96. }
  97. public function isAllowedBySetting($iValue)
  98. {
  99. $aValues = $this->getProhibited();
  100. if(!$aValues)
  101. return true;
  102. return !in_array($iValue, $aValues);
  103. }
  104. public function isAllowedByViewer($iValue, $iViewerId = 0)
  105. {
  106. $iCfDefault = $this->getDefaultValue();
  107. if(!$iValue)
  108. $iValue = $iCfDefault;
  109. if(!$iViewerId)
  110. $iViewerId = $this->_iViewerId;
  111. $iCfwValue = $iCfDefault;
  112. $aViewerInfo = BxDolProfileQuery::getInstance()->getInfoById($iViewerId);
  113. if(!empty($aViewerInfo) && is_array($aViewerInfo))
  114. $iCfwValue = $aViewerInfo['cfw_value'];
  115. return (1 << ($iValue - 1)) & $iCfwValue;
  116. }
  117. public function getSQLParts($sContentTable, $sContentField, $iViewerId = 0)
  118. {
  119. $sResult = '';
  120. $aSQLParts = $this->getSettingSQLParts($sContentTable, $sContentField);
  121. if(!empty($aSQLParts['where']))
  122. $sResult .= $aSQLParts['where'];
  123. $aSQLParts = $this->getViewerSQLParts($sContentTable, $sContentField, $iViewerId);
  124. if(!empty($aSQLParts['where']))
  125. $sResult .= $aSQLParts['where'];
  126. return $sResult;
  127. }
  128. public function getSettingSQLParts($sContentTable, $sContentField)
  129. {
  130. $aValues = $this->getProhibited();
  131. if(!$aValues)
  132. return [];
  133. return [
  134. 'where' => " AND `" . $sContentTable . "`.`" . $sContentField . "` NOT IN (" . $this->_oDb->implode_escape($aValues) . ")"
  135. ];
  136. }
  137. public function getViewerSQLParts($sContentTable, $sContentField, $iViewerId = 0)
  138. {
  139. if(!$iViewerId)
  140. $iViewerId = $this->_iViewerId;
  141. $aViewerInfo = BxDolProfileQuery::getInstance()->getInfoById($iViewerId);
  142. if(empty($aViewerInfo) || !is_array($aViewerInfo))
  143. return [];
  144. return [
  145. 'where' => " AND 1 << (`" . $sContentTable . "`.`" . $sContentField . "` - 1) & " . $aViewerInfo['cfw_value']
  146. ];
  147. }
  148. public function getConditions($sContentTable, $sContentField, $iViewerId = 0)
  149. {
  150. $aResult = [];
  151. $aConditions = $this->getSettingConditions($sContentTable, $sContentField);
  152. if(!empty($aConditions) && is_array($aConditions))
  153. $aResult['cf_setting'] = $aConditions;
  154. $aConditions = $this->getViewerConditions($sContentTable, $sContentField, $iViewerId);
  155. if(!empty($aConditions) && is_array($aConditions))
  156. $aResult['cf_viewer'] = $aConditions;
  157. return $aResult;
  158. }
  159. public function getSettingConditions($sContentTable, $sContentField)
  160. {
  161. $aValues = $this->getProhibited();
  162. if(!$aValues)
  163. return [];
  164. return [
  165. 'value' => $aValues,
  166. 'field' => $sContentField,
  167. 'operator' => 'not in',
  168. 'table' => $sContentTable
  169. ];
  170. }
  171. public function getViewerConditions($sContentTable, $sContentField, $iViewerId = 0)
  172. {
  173. if(!$iViewerId)
  174. $iViewerId = $this->_iViewerId;
  175. $aViewerInfo = BxDolProfileQuery::getInstance()->getInfoById($iViewerId);
  176. if(empty($aViewerInfo) || !is_array($aViewerInfo))
  177. return;
  178. return [
  179. 'value' => $aViewerInfo['cfw_value'],
  180. 'field' => $sContentField,
  181. 'operator' => 'in_set',
  182. 'table' => $sContentTable
  183. ];
  184. }
  185. public function updateValuesByProfile($aProfile)
  186. {
  187. if(!is_array($aProfile))
  188. $aProfile = BxDolProfileQuery::getInstance()->getProfiles(['type' => 'id', 'id' => (int)$aProfile]);
  189. if(!BxDolRequest::serviceExists($aProfile['type'], 'get_info'))
  190. return;
  191. $aFilters = BxDolFormQuery::getDataItems($this->_sDataList, true, BX_DATA_VALUES_ALL);
  192. $aProfileInfo = bx_srv($aProfile['type'], 'get_info', [$aProfile['content_id'], false]);
  193. $iCfwValue = (int)$aProfile['cfw_value'];
  194. $bUpdateCfwValue = false;
  195. $iCfwItems = $iCfuItems = 0;
  196. $bUpdateCfwItems = $bUpdateCfuItems = false;
  197. foreach($aFilters as $aFilter) {
  198. $iFilter = (int)$aFilter['Value'];
  199. if(!empty($aFilter['Data'])) {
  200. $aData = unserialize($aFilter['Data']);
  201. if(empty($aData) || !is_array($aData))
  202. continue;
  203. }
  204. else
  205. $aData = [
  206. 'is_allowed_watch' => ['module' => 'system', 'method' => 'is_allowed_cfilter', 'params' => ['watch'], 'class' => 'BaseServiceProfiles'],
  207. 'is_allowed_use' => ['module' => 'system', 'method' => 'is_allowed_cfilter', 'params' => ['use'], 'class' => 'BaseServiceProfiles'],
  208. ];
  209. if(!empty($aData['is_allowed_watch'])) {
  210. $aData['is_allowed_watch']['params'] = array_merge($aData['is_allowed_watch']['params'], [$iFilter, $aProfileInfo]);
  211. $iWatch = call_user_func_array('bx_srv', array_values($aData['is_allowed_watch']));
  212. if($iWatch === false)
  213. continue;
  214. if($iWatch == 0) {
  215. $iCfwValue &= ~ (1 << ($iFilter - 1));
  216. $bUpdateCfwValue = true;
  217. }
  218. $iCfwItems |= $iWatch;
  219. $bUpdateCfwItems = true;
  220. }
  221. if(!empty($aData['is_allowed_use']) && (int)$aProfile['cfu_locked'] == 0) {
  222. $aData['is_allowed_use']['params'] = array_merge($aData['is_allowed_use']['params'], [$aFilter['Value'], $aProfileInfo]);
  223. $iUse = call_user_func_array('bx_srv', array_values($aData['is_allowed_use']));
  224. if($iUse === false)
  225. continue;
  226. $iCfuItems |= $iUse;
  227. $bUpdateCfuItems = true;
  228. }
  229. }
  230. $oProfileQuery = BxDolProfileQuery::getInstance();
  231. if($bUpdateCfwValue)
  232. $oProfileQuery->changeCfwValue($aProfile['id'], $iCfwValue);
  233. if($bUpdateCfwItems)
  234. $oProfileQuery->changeCfwItems($aProfile['id'], $iCfwItems);
  235. if($bUpdateCfuItems)
  236. $oProfileQuery->changeCfuItems($aProfile['id'], $iCfuItems);
  237. }
  238. }
  239. /** @} */