BxDolContentFilter.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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 getUnauthenticated()
  53. {
  54. $sValues = getParam('sys_cf_unauthenticated');
  55. if(!$sValues)
  56. return [];
  57. $aValues = explode(',', $sValues);
  58. if(!$aValues)
  59. return [];
  60. return $aValues;
  61. }
  62. public function getDefaultValue()
  63. {
  64. return $this->_iDefaultValue;
  65. }
  66. public function getDefaultValueUnauthenticated()
  67. {
  68. $aFilters = $this->getUnauthenticated();
  69. $iCfwValue = 0;
  70. foreach($aFilters as $iFilter)
  71. $iCfwValue |= (1 << ($iFilter - 1));
  72. return $iCfwValue;
  73. }
  74. public function getValues()
  75. {
  76. return BxDolFormQuery::getDataItems($this->_sDataList);
  77. }
  78. public function getInput($aInput, $iProfileId = 0)
  79. {
  80. return $this->_getInput('content', $aInput, $iProfileId);
  81. }
  82. public function getInputForComments($aInput, $iProfileId = 0)
  83. {
  84. return $this->_getInput('comments', $aInput, $iProfileId);
  85. }
  86. protected function _getInput($sType, $aInput, $iProfileId = 0)
  87. {
  88. if(!$this->{'isEnabled' . ($sType == 'comments' ? 'ForComments' : '')}())
  89. return array_merge($aInput, [
  90. 'type' => 'hidden',
  91. 'value' => 1
  92. ]);
  93. if(!$aInput['values'])
  94. $aInput['values'] = BxDolFormQuery::getDataItems($this->_sDataList);
  95. if(!$iProfileId)
  96. $iProfileId = bx_get_logged_profile_id();
  97. $aProfileInfo = BxDolProfileQuery::getInstance()->getInfoById($iProfileId);
  98. if(empty($aProfileInfo) || !isset($aProfileInfo['cfu_items']))
  99. return $aInput;
  100. $aCfuValues = [];
  101. foreach($aInput['values'] as $iValue => $sTitle)
  102. if((1 << ($iValue - 1)) & (int)$aProfileInfo['cfu_items'])
  103. $aCfuValues[$iValue] = $sTitle;
  104. $aInput['values'] = $aCfuValues;
  105. return $aInput;
  106. }
  107. public function isAllowed($iValue, $iViewerId = 0)
  108. {
  109. if(!$this->isAllowedBySetting($iValue))
  110. return false;
  111. if(!$this->isAllowedByViewer($iValue, $iViewerId))
  112. return false;
  113. return true;
  114. }
  115. public function isAllowedBySetting($iValue)
  116. {
  117. $aValues = $this->getProhibited();
  118. if(!$aValues)
  119. return true;
  120. return !in_array($iValue, $aValues);
  121. }
  122. public function isAllowedByViewer($iValue, $iViewerId = 0)
  123. {
  124. $iCfDefault = $this->getDefaultValue();
  125. if(!$iValue)
  126. $iValue = $iCfDefault;
  127. if(!$iViewerId)
  128. $iViewerId = $this->_iViewerId;
  129. $iCfwValue = $iCfDefault;
  130. $aViewerInfo = BxDolProfileQuery::getInstance()->getInfoById($iViewerId);
  131. if(is_array($aViewerInfo) && isset($aViewerInfo['cfw_value']))
  132. $iCfwValue = $aViewerInfo['cfw_value'];
  133. else
  134. $iCfwValue = $this->getDefaultValueUnauthenticated();
  135. return (1 << ($iValue - 1)) & $iCfwValue;
  136. }
  137. public function getSQLParts($sContentTable, $sContentField, $iViewerId = 0)
  138. {
  139. $sResult = '';
  140. $aSQLParts = $this->getSettingSQLParts($sContentTable, $sContentField);
  141. if(!empty($aSQLParts['where']))
  142. $sResult .= $aSQLParts['where'];
  143. $aSQLParts = $this->getViewerSQLParts($sContentTable, $sContentField, $iViewerId);
  144. if(!empty($aSQLParts['where']))
  145. $sResult .= $aSQLParts['where'];
  146. return $sResult;
  147. }
  148. public function getSettingSQLParts($sContentTable, $sContentField)
  149. {
  150. $aValues = $this->getProhibited();
  151. if(!$aValues)
  152. return [];
  153. return [
  154. 'where' => " AND `" . $sContentTable . "`.`" . $sContentField . "` NOT IN (" . $this->_oDb->implode_escape($aValues) . ")"
  155. ];
  156. }
  157. public function getViewerSQLParts($sContentTable, $sContentField, $iViewerId = 0)
  158. {
  159. if(!$iViewerId)
  160. $iViewerId = $this->_iViewerId;
  161. $aViewerInfo = BxDolProfileQuery::getInstance()->getInfoById($iViewerId);
  162. if(is_array($aViewerInfo) && isset($aViewerInfo['cfw_value']))
  163. $iViewerCfwValue = $aViewerInfo['cfw_value'];
  164. else
  165. $iViewerCfwValue = $this->getDefaultValueUnauthenticated();
  166. return [
  167. 'where' => " AND 1 << (`" . $sContentTable . "`.`" . $sContentField . "` - 1) & " . $iViewerCfwValue
  168. ];
  169. }
  170. public function getConditions($sContentTable, $sContentField, $iViewerId = 0)
  171. {
  172. $aResult = [];
  173. $aConditions = $this->getSettingConditions($sContentTable, $sContentField);
  174. if(!empty($aConditions) && is_array($aConditions))
  175. $aResult['cf_setting'] = $aConditions;
  176. $aConditions = $this->getViewerConditions($sContentTable, $sContentField, $iViewerId);
  177. if(!empty($aConditions) && is_array($aConditions))
  178. $aResult['cf_viewer'] = $aConditions;
  179. return $aResult;
  180. }
  181. public function getSettingConditions($sContentTable, $sContentField)
  182. {
  183. $aValues = $this->getProhibited();
  184. if(!$aValues)
  185. return [];
  186. return [
  187. 'value' => $aValues,
  188. 'field' => $sContentField,
  189. 'operator' => 'not in',
  190. 'table' => $sContentTable
  191. ];
  192. }
  193. public function getViewerConditions($sContentTable, $sContentField, $iViewerId = 0)
  194. {
  195. if(!$iViewerId)
  196. $iViewerId = $this->_iViewerId;
  197. $aViewerInfo = BxDolProfileQuery::getInstance()->getInfoById($iViewerId);
  198. if(is_array($aViewerInfo) && isset($aViewerInfo['cfw_value']))
  199. $iViewerCfwValue = $aViewerInfo['cfw_value'];
  200. else
  201. $iViewerCfwValue = $this->getDefaultValueUnauthenticated();
  202. return [
  203. 'value' => $iViewerCfwValue,
  204. 'field' => $sContentField,
  205. 'operator' => 'in_set',
  206. 'table' => $sContentTable
  207. ];
  208. }
  209. public function updateValuesByProfile($aProfile)
  210. {
  211. if(!is_array($aProfile))
  212. $aProfile = BxDolProfileQuery::getInstance()->getProfiles(['type' => 'id', 'id' => (int)$aProfile]);
  213. if(!BxDolRequest::serviceExists($aProfile['type'], 'get_info'))
  214. return;
  215. $aFilters = BxDolFormQuery::getDataItems($this->_sDataList, true, BX_DATA_VALUES_ALL);
  216. $aProfileInfo = bx_srv($aProfile['type'], 'get_info', [$aProfile['content_id'], false]);
  217. $iCfwValue = (int)$aProfile['cfw_value'];
  218. $bUpdateCfwValue = false;
  219. $iCfwItems = $iCfuItems = 0;
  220. $bUpdateCfwItems = $bUpdateCfuItems = false;
  221. foreach($aFilters as $aFilter) {
  222. $iFilter = (int)$aFilter['Value'];
  223. if(!empty($aFilter['Data'])) {
  224. $aData = unserialize($aFilter['Data']);
  225. if(empty($aData) || !is_array($aData))
  226. continue;
  227. }
  228. else
  229. $aData = [
  230. 'is_allowed_watch' => ['module' => 'system', 'method' => 'is_allowed_cfilter', 'params' => ['watch'], 'class' => 'BaseServiceProfiles'],
  231. 'is_allowed_use' => ['module' => 'system', 'method' => 'is_allowed_cfilter', 'params' => ['use'], 'class' => 'BaseServiceProfiles'],
  232. ];
  233. if(!empty($aData['is_allowed_watch'])) {
  234. $aData['is_allowed_watch']['params'] = array_merge($aData['is_allowed_watch']['params'], [$iFilter, $aProfileInfo]);
  235. $iWatch = call_user_func_array('bx_srv', array_values($aData['is_allowed_watch']));
  236. if($iWatch === false)
  237. continue;
  238. if($iWatch == 0) {
  239. $iCfwValue &= ~ (1 << ($iFilter - 1));
  240. $bUpdateCfwValue = true;
  241. }
  242. $iCfwItems |= $iWatch;
  243. $bUpdateCfwItems = true;
  244. }
  245. if(!empty($aData['is_allowed_use']) && (int)$aProfile['cfu_locked'] == 0) {
  246. $aData['is_allowed_use']['params'] = array_merge($aData['is_allowed_use']['params'], [$aFilter['Value'], $aProfileInfo]);
  247. $iUse = call_user_func_array('bx_srv', array_values($aData['is_allowed_use']));
  248. if($iUse === false)
  249. continue;
  250. $iCfuItems |= $iUse;
  251. $bUpdateCfuItems = true;
  252. }
  253. }
  254. $oProfileQuery = BxDolProfileQuery::getInstance();
  255. if($bUpdateCfwValue)
  256. $oProfileQuery->changeCfwValue($aProfile['id'], $iCfwValue);
  257. if($bUpdateCfwItems)
  258. $oProfileQuery->changeCfwItems($aProfile['id'], $iCfwItems);
  259. if($bUpdateCfuItems)
  260. $oProfileQuery->changeCfuItems($aProfile['id'], $iCfuItems);
  261. }
  262. }
  263. /** @} */