BxDolPrivacy.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  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. define('BX_DOL_PG_HIDDEN', '1');
  10. define('BX_DOL_PG_MEONLY', '2');
  11. define('BX_DOL_PG_ALL', '3');
  12. define('BX_DOL_PG_MEMBERS', '4');
  13. define('BX_DOL_PG_FRIENDS', '5');
  14. define('BX_DOL_PG_FRIENDS_SELECTED', '6');
  15. define('BX_DOL_PG_RELATIONS', '7');
  16. define('BX_DOL_PG_RELATIONS_SELECTED', '8');
  17. define('BX_DOL_PG_MEMBERSHIPS_SELECTED', '9');
  18. define('BX_DOL_PG_CUSTOM', '99');
  19. define('BX_DOL_PG_DEFAULT', BX_DOL_PG_ALL);
  20. /**
  21. * Privacy settings for any content.
  22. *
  23. * Integration of the content with privacy engine allows site member
  24. * to organize the access to his content.
  25. *
  26. * In addition to regular privacy groups (Public, Friends), spaces are supported.
  27. * When some space (usually some another profile) is specified as privacy,
  28. * then another profile visibility is used to check the privacy.
  29. *
  30. * Related classes:
  31. * BxDolPrivacyQuery - database queries.
  32. *
  33. * Example of usage:
  34. * 1. Register your privacy actions in `sys_privacy_actions` database table.
  35. * 2. Add one privacy field(with INT type) in the table with your items for each action.
  36. * For example, for action 'comment', the field name should be 'allow_comment_to'.
  37. * 3. Add group choosers for necessary actions in the form, which is used to add new items.
  38. * @code
  39. * $oPrivacy = new BxDolPrivacy();
  40. * $oPrivacy->getGroupChooser($iItemOwnerId, $sModuleUri, $sModuleAction);
  41. * @endcode
  42. *
  43. * 4. Check privacy when any user tries to view an item.
  44. * @code
  45. * $oPrivacy = new BxDolPrivacy($sTable, $sFieldId, $sFieldOwnerId);
  46. * if($oPrivacy->check($sAction, $iObjectId, $iViewerId)) {
  47. * //show necessary content
  48. * }
  49. * @endcode
  50. *
  51. * @see an example of integration in BoonEx modules, for example: Posts
  52. *
  53. *
  54. * Memberships/ACL:
  55. * Doesn't depend on user's membership.
  56. *
  57. *
  58. * Alerts:
  59. * no alerts available
  60. *
  61. */
  62. class BxDolPrivacy extends BxDolFactory implements iBxDolFactoryObject
  63. {
  64. protected $_oDb;
  65. protected $_sObject;
  66. protected $_aObject;
  67. protected $_aGroupsSettings;
  68. protected $_aGroupsExclude;
  69. protected $_sFormGroupCustom;
  70. protected $_sFormDisplayGcMembers;
  71. protected $_sFormDisplayGcMemberships;
  72. /**
  73. * Constructor
  74. * @param $aObject array of grid options
  75. */
  76. protected function __construct($aObject)
  77. {
  78. parent::__construct();
  79. $this->_aObject = $aObject;
  80. $this->_sObject = $aObject['object'];
  81. $this->_oDb = new BxDolPrivacyQuery();
  82. $this->_oDb->init($this->_aObject);
  83. $this->_aGroupsSettings = [
  84. BX_DOL_PG_FRIENDS_SELECTED => [
  85. 'name' => 'friends',
  86. 'is_allowed' => '',
  87. 'connection' => 'sys_profiles_friends',
  88. 'js_method_create_group' => 'selectMembers',
  89. 'db_table_items' => 'sys_privacy_groups_custom_members',
  90. 'db_field_item' => 'member_id',
  91. 'uri_get_items' => 'users_list',
  92. ],
  93. BX_DOL_PG_RELATIONS_SELECTED => [
  94. 'name' => 'relations',
  95. 'is_allowed' => '',
  96. 'connection' => 'sys_profiles_relations',
  97. 'js_method_create_group' => 'selectMembers',
  98. 'db_table_items' => 'sys_privacy_groups_custom_members',
  99. 'db_field_item' => 'member_id',
  100. 'uri_get_items' => 'users_list',
  101. ],
  102. BX_DOL_PG_MEMBERSHIPS_SELECTED => [
  103. 'name' => 'memberships',
  104. 'is_allowed' => 'isAllowedMemberships',
  105. 'connection' => '',
  106. 'js_method_create_group' => 'selectMemberships',
  107. 'db_table_items' => 'sys_privacy_groups_custom_memberships',
  108. 'db_field_item' => 'membership_id',
  109. 'uri_get_items' => 'memberships_list',
  110. ]
  111. ];
  112. $this->_aGroupsExclude = array();
  113. $this->_sFormGroupCustom = 'sys_privacy_group_custom';
  114. $this->_sFormDisplayGcMembers = 'sys_privacy_group_custom_members';
  115. $this->_sFormDisplayGcMemberships = 'sys_privacy_group_custom_memberships';
  116. }
  117. /**
  118. * Get privacy object instance by object name
  119. * @param $sObject object name
  120. * @return object instance or false on error
  121. */
  122. public static function getObjectInstance($sObject)
  123. {
  124. if(isset($GLOBALS['bxDolClasses']['BxDolPrivacy!' . $sObject]))
  125. return $GLOBALS['bxDolClasses']['BxDolPrivacy!' . $sObject];
  126. $aObject = BxDolPrivacyQuery::getPrivacyObject($sObject);
  127. if(!$aObject || !is_array($aObject))
  128. return false;
  129. $sClass = 'BxTemplPrivacy';
  130. if(!empty($aObject['override_class_name'])) {
  131. $sClass = $aObject['override_class_name'];
  132. if(!empty($aObject['override_class_file']))
  133. require_once(BX_DIRECTORY_PATH_ROOT . $aObject['override_class_file']);
  134. }
  135. $o = new $sClass($aObject);
  136. return ($GLOBALS['bxDolClasses']['BxDolPrivacy!' . $sObject] = $o);
  137. }
  138. /**
  139. * Get Select element with available groups.
  140. *
  141. * @param string $sObject privacy object name.
  142. * @param integer $iOwnerId object's owner ID.
  143. * @param array $aParams an array of custom selector's params (dynamic_groups - an array of arrays('key' => group_id, 'value' => group_title), title - the title to be used for generated field).
  144. * @return an array with Select element description.
  145. */
  146. public static function getGroupChooser($sObject, $iOwnerId = 0, $aParams = array())
  147. {
  148. $oPrivacy = BxDolPrivacy::getObjectInstance($sObject);
  149. if(empty($oPrivacy))
  150. return array();
  151. $sModule = $oPrivacy->_aObject['module'];
  152. $sAction = $oPrivacy->_aObject['action'];
  153. if($iOwnerId == 0)
  154. $iOwnerId = bx_get_logged_profile_id();
  155. $sValue = $oPrivacy->_oDb->getDefaultGroupByUser($sModule, $sAction, $iOwnerId);
  156. if(empty($sValue))
  157. $sValue = $oPrivacy->_oDb->getDefaultGroup($sModule, $sAction);
  158. $aValues = $oPrivacy->getGroups($iOwnerId, $aParams);
  159. $aValues = $oPrivacy->addDynamicGroups($aValues, $iOwnerId, $aParams);
  160. $aValues = $oPrivacy->addSpaces($aValues, $iOwnerId, $aParams);
  161. $sName = $oPrivacy->convertActionToField($sAction);
  162. $sTitle = isset($aParams['title']) && !empty($aParams['title']) ? $aParams['title'] : '';
  163. if(empty($sTitle)) {
  164. $sTitle = $oPrivacy->_oDb->getTitle($sModule, $sAction);
  165. $sTitle = _t(!empty($sTitle) ? $sTitle : '_' . $sName);
  166. }
  167. $bDynamicMode = (isset($aParams['dynamic_mode']) && (bool)$aParams['dynamic_mode'] === true) || bx_is_dynamic_request();
  168. return array(
  169. 'type' => 'select',
  170. 'name' => $sName,
  171. 'caption' => $sTitle,
  172. 'value' => $sValue,
  173. 'values' => $aValues,
  174. 'attrs' => array(
  175. 'class' => 'sys-privacy-group',
  176. 'onchange' => 'javascript: ' . $oPrivacy->getJsObjectName() . '.selectGroup(this);'
  177. ),
  178. 'checker' => array(
  179. 'func' => 'avail',
  180. 'error' => _t('_sys_ps_ferr_incorrect_select')
  181. ),
  182. 'db' => array(
  183. 'pass' => 'Int'
  184. ),
  185. 'content' => $oPrivacy->addCssJs($bDynamicMode)
  186. );
  187. }
  188. public static function initGroupChooser($sObject, $iOwnerId = 0, $aParams = array())
  189. {
  190. $sResult = '';
  191. $oPrivacy = BxDolPrivacy::getObjectInstance($sObject);
  192. if(empty($oPrivacy))
  193. return $sResult;
  194. $iOwnerId = !empty($iOwnerId) ? (int)$iOwnerId : bx_get_logged_profile_id();
  195. $iContentId = !empty($aParams['content_id']) ? (int)$aParams['content_id'] : 0;
  196. $iGroupId = !empty($aParams['group_id']) ? (int)$aParams['group_id'] : 0;
  197. $bDynamicMode = (isset($aParams['dynamic_mode']) && (bool)$aParams['dynamic_mode'] === true) || bx_is_dynamic_request();
  198. $sJsCodeAdd = '';
  199. if($oPrivacy->isGroupsCustom())
  200. $sJsCodeAdd = $oPrivacy->getLoadGroupCustom($iOwnerId, $iContentId, $iGroupId, isset($aParams['html_ids']) ? $aParams['html_ids'] : array());
  201. return $oPrivacy->getJsScript($sJsCodeAdd, $bDynamicMode);
  202. }
  203. public static function getIcon($iVisibility)
  204. {
  205. $aIcons =array(
  206. BX_DOL_PG_MEONLY => 'lock',
  207. BX_DOL_PG_ALL => 'globe',
  208. BX_DOL_PG_FRIENDS => 'user-friends',
  209. BX_DOL_PG_FRIENDS => 'user-friends'
  210. );
  211. return isset($aIcons[$iVisibility]) ? $aIcons[$iVisibility] : 'eye';
  212. }
  213. public function actionLoadGroupCustom()
  214. {
  215. $iProfileId = (int)bx_get('profile_id');
  216. $iContentId = (int)bx_get('content_id');
  217. $iGroupId = (int)bx_get('group_id');
  218. $oForm = BxDolForm::getObjectInstance($this->_sFormGroupCustom, $this->_sFormDisplayGcMembers);
  219. return echoJson(array('eval' => $this->getJsObjectName() . '.onSelectGroup(oData);', 'content' => $oForm->getElementGroupCustom(array(
  220. 'profile_id' => $iProfileId,
  221. 'content_id' => $iContentId,
  222. 'object' => $this->_sObject,
  223. 'group_id' => $iGroupId
  224. ))));
  225. }
  226. public function actionSelectMembers()
  227. {
  228. $aValues = array(
  229. 'profile_id' => (int)bx_get('profile_id'),
  230. 'content_id' => (int)bx_get('content_id'),
  231. 'object' => $this->_sObject,
  232. 'group_id' => (int)bx_get('group_id')
  233. );
  234. $aParams = array(
  235. 'popup_only' => (bool)bx_get('popup_only')
  236. );
  237. if(!isset($this->_aGroupsSettings[$aValues['group_id']]))
  238. return echoJson(array());
  239. if($aValues['profile_id'] != bx_get_logged_profile_id())
  240. return echoJson(array('msg' => _t('_sys_ps_ferr_incorrect_gc_owner')));
  241. if(($mixedResult = $this->isSelectGroupCustomUsers($aValues)) !== true)
  242. return echoJson(array('msg' => $mixedResult));
  243. return echoJson($this->getSelectGroup($aValues, $aParams));
  244. }
  245. public function actionSelectMemberships()
  246. {
  247. $aValues = array(
  248. 'profile_id' => (int)bx_get('profile_id'),
  249. 'content_id' => (int)bx_get('content_id'),
  250. 'object' => $this->_sObject,
  251. 'group_id' => (int)bx_get('group_id')
  252. );
  253. $aParams = array(
  254. 'popup_only' => (bool)bx_get('popup_only')
  255. );
  256. if(!isset($this->_aGroupsSettings[$aValues['group_id']]))
  257. return echoJson(array());
  258. if($aValues['profile_id'] != bx_get_logged_profile_id())
  259. return echoJson(array('msg' => _t('_sys_ps_ferr_incorrect_gc_owner')));
  260. if(($mixedResult = $this->isSelectGroupCustomMemberships($aValues)) !== true)
  261. return echoJson(array('msg' => $mixedResult));
  262. return echoJson($this->getSelectMemberships($aValues, $aParams));
  263. }
  264. public function actionUsersList()
  265. {
  266. $iGroup = (int)bx_get('group');
  267. if(!isset($this->_aGroupsSettings[$iGroup]))
  268. return echoJson(array());
  269. $oConnection = BxDolConnection::getObjectInstance($this->_aGroupsSettings[$iGroup]['connection']);
  270. if(!$oConnection)
  271. return echoJson(array());
  272. $iProfileId = bx_get_logged_profile_id();
  273. $aConnectedIds = $oConnection->getConnectedContent($iProfileId, true);
  274. if(empty($aConnectedIds) || !is_array($aConnectedIds))
  275. return echoJson(array());
  276. $sTerm = bx_get('term');
  277. $aProfiles = BxDolService::call('system', 'profiles_search', array($sTerm), 'TemplServiceProfiles');
  278. if(empty($aProfiles))
  279. return echoJson(array());
  280. $aResult = array();
  281. foreach($aProfiles as $aProfile)
  282. if(in_array($aProfile['value'], $aConnectedIds))
  283. $aResult[] = $aProfile;
  284. echoJson($aResult);
  285. }
  286. public function getGroupSettings($iGroup)
  287. {
  288. if(empty($this->_aGroupsSettings[$iGroup]) || !is_array($this->_aGroupsSettings[$iGroup]))
  289. return false;
  290. return $this->_aGroupsSettings[$iGroup];
  291. }
  292. public function isGroupsCustom()
  293. {
  294. $aGroups = $this->_oDb->getGroupsBy(array('type' => 'active_list'));
  295. return in_array(BX_DOL_PG_FRIENDS_SELECTED, $aGroups) || in_array(BX_DOL_PG_RELATIONS_SELECTED, $aGroups) || in_array(BX_DOL_PG_MEMBERSHIPS_SELECTED, $aGroups);
  296. }
  297. public function getGroupsBy($aParams)
  298. {
  299. return $this->_oDb->getGroupsBy($aParams);
  300. }
  301. public function getGroupCustom($aParams)
  302. {
  303. return $this->_oDb->getGroupCustom($aParams);
  304. }
  305. public function updateGroupCustom($aParamsSet, $aParamsWhere)
  306. {
  307. return $this->_oDb->updateGroupCustom($aParamsSet, $aParamsWhere);
  308. }
  309. public function deleteGroupCustom($aParamsWhere)
  310. {
  311. return $this->_oDb->deleteGroupCustom($aParamsWhere);
  312. }
  313. public function associateGroupCustomWithContent($iProfileId, $iContentId, $iGroupId)
  314. {
  315. return $this->updateGroupCustom(array('content_id' => $iContentId), array(
  316. 'profile_id' => $iProfileId,
  317. 'content_id' => 0,
  318. 'object' => $this->_sObject,
  319. 'group_id' => $iGroupId
  320. ));
  321. }
  322. public function reassociateGroupCustomWithContent($iProfileId, $iContentId, $iGroupId)
  323. {
  324. $aGroupCustom = $this->getGroupCustom(array(
  325. 'type' => 'pco',
  326. 'profile_id' => $iProfileId,
  327. 'content_id' => $iContentId,
  328. 'object' => $this->_sObject
  329. ));
  330. if(!empty($aGroupCustom) && is_array($aGroupCustom) && $aGroupCustom['group_id'] != $iGroupId) {
  331. $this->deleteGroupCustom(array('id' => $aGroupCustom['id']));
  332. $this->associateGroupCustomWithContent($iProfileId, $iContentId, $iGroupId);
  333. }
  334. }
  335. public function deleteGroupCustomByContentId($iContentId)
  336. {
  337. return $this->_oDb->deleteGroupCustom(array('content_id' => $iContentId, 'object' => $this->_sObject));
  338. }
  339. public function deleteGroupCustomByProfileId($iProfileId)
  340. {
  341. $aGroups = $this->_oDb->getGroupCustom(array('type' => 'profile_id', 'profile_id' => $iProfileId));
  342. if(empty($aGroups) || !is_array($aGroups))
  343. return true;
  344. foreach($aGroups as $aGroup)
  345. $this->_oDb->deleteGroupCustom(array('id' => $aGroup['id']));
  346. return true;
  347. }
  348. public function addDynamicGroups($aValues, $iOwnerId, $aParams)
  349. {
  350. if (isset($aParams['dynamic_groups']) && is_array($aParams['dynamic_groups']))
  351. $aValues = array_merge($aValues, $aParams['dynamic_groups']);
  352. return $aValues;
  353. }
  354. public function addSpaces($aValues, $iOwnerId, $aParams)
  355. {
  356. if (!$this->_aObject['spaces'])
  357. return $aValues;
  358. if (!($oProfile = BxDolProfile::getInstance($iOwnerId)))
  359. return $aValues;
  360. if (!($aModules = BxDolModuleQuery::getInstance()->getModules()))
  361. return $aValues;
  362. $aExcludeModules = explode(',', getParam('sys_hide_post_to_context_for_privacy'));
  363. foreach ($aModules as $aModule) {
  364. if (!$aModule['enabled'])
  365. continue;
  366. if ('all' != $this->_aObject['spaces'] && false === stripos($this->_aObject['spaces'], $aModule['name']))
  367. continue;
  368. if (!BxDolRequest::serviceExists($aModule['name'], 'act_as_profile'))
  369. continue;
  370. if (in_array($aModule['name'], $aExcludeModules))
  371. continue;
  372. $oModule = BxDolModule::getInstance($aModule['name']);
  373. $a = BxDolService::call($aModule['name'], 'get_participating_profiles', array($oProfile->id()));
  374. // for an organization we should treat the organization profile itself as a participant of itself
  375. // to be able to post into an organization's context while being logged as that organization
  376. if ($aModule['name'] == 'bx_organizations' && $oProfile->getModule() == 'bx_organizations') $a = array_merge($a, [$oProfile->id()]);
  377. $aSpaces = array();
  378. foreach ($a as $iProfileId) {
  379. if (!($o = BxDolProfile::getInstance($iProfileId)))
  380. continue;
  381. // check whether a profile is allowed to post this type of content to a context
  382. $oConnectedProfile = BxDolProfile::getInstance($iProfileId);
  383. if (bx_srv($aModule['name'], 'check_allowed_post_in_profile', array($oConnectedProfile->getContentId(), $this->_aObject['module'])) !== CHECK_ACTION_RESULT_ALLOWED)
  384. continue;
  385. $aSpaces[-$iProfileId] = array('key' => -$iProfileId, 'value' => $o->getDisplayName());
  386. }
  387. if ($aSpaces) {
  388. $aItemStart = array(array('type' => 'group_header', 'value' => mb_strtoupper(BxDolService::call($aModule['name'], 'get_space_title'))));
  389. $aItemEnd = array(array('type' => 'group_end'));
  390. $aValues = array_merge($aValues, $aItemStart, array_values($aSpaces), $aItemEnd);
  391. }
  392. }
  393. return $aValues;
  394. }
  395. /**
  396. * Get database field name for action.
  397. *
  398. * @param string $sObject privacy object name.
  399. * @param string $sAction action name.
  400. * @return string with field name.
  401. */
  402. public static function getFieldName($sObject, $sAction = '')
  403. {
  404. $oPrivacy = BxDolPrivacy::getObjectInstance($sObject);
  405. if(empty($oPrivacy))
  406. return '';
  407. if(empty($sAction))
  408. $sAction = $oPrivacy->_aObject['action'];
  409. return $oPrivacy->convertActionToField($sAction);
  410. }
  411. /**
  412. * Get necessary condition array to use privacy in search classes
  413. * @param $mixedGroupId group ID or array of group IDs
  414. * @return array of conditions, for now with 'restriction' part only is returned
  415. */
  416. public function getContentByGroupAsCondition($mixedGroupId)
  417. {
  418. $aResult = array(
  419. 'restriction' => array (
  420. 'privacy_' . $this->_sObject => array(
  421. 'value' => $mixedGroupId,
  422. 'field' => $this->convertActionToField($this->_aObject['action']),
  423. 'operator' => is_array($mixedGroupId) ? 'in' : '=',
  424. 'table' => $this->_aObject['table'],
  425. ),
  426. ),
  427. );
  428. bx_alert('system', 'privacy_condition', 0, false, array(
  429. 'group_id' => $mixedGroupId,
  430. 'field' => $this->convertActionToField($this->_aObject['action']),
  431. 'object' => $this->_aObject,
  432. 'privacy_object' => $this,
  433. 'result' => &$aResult
  434. )
  435. );
  436. return $aResult;
  437. }
  438. /**
  439. * Get necessary condition array to use privacy in search classes
  440. * @param $iProfileIdOwner owner profile ID
  441. * @return array of conditions, for now with 'restriction' part only is returned
  442. */
  443. public function getContentPublicAsCondition($iProfileIdOwner = 0, $aCustomGroups = array())
  444. {
  445. $mixedPrivacyGroups = $this->getPrivacyGroupsForContentPublic($iProfileIdOwner, $aCustomGroups);
  446. if($mixedPrivacyGroups === true)
  447. return array();
  448. return $this->getContentByGroupAsCondition($mixedPrivacyGroups);
  449. }
  450. /**
  451. * Get necessary parts of SQL query to use privacy in other queries
  452. * @param $mixedGroupId group ID or array of group IDs
  453. * @return array of SQL string parts, for now 'where' part only is returned
  454. */
  455. public function getContentByGroupAsSQLPart($mixedGroupId)
  456. {
  457. $sField = $this->convertActionToField($this->_aObject['action']);
  458. return $this->_oDb->getContentByGroupAsSQLPart($sField, $mixedGroupId);
  459. }
  460. /**
  461. * Get necessary parts of SQL query to use privacy in other queries
  462. * @param $iProfileIdOwner owner profile ID
  463. * @return array of SQL string parts, for now 'where' part only is returned
  464. */
  465. public function getContentPublicAsSQLPart($iProfileIdOwner = 0, $aCustomGroups = array())
  466. {
  467. $mixedPrivacyGroups = $this->getPrivacyGroupsForContentPublic($iProfileIdOwner, $aCustomGroups);
  468. if($mixedPrivacyGroups === true)
  469. return array();
  470. return $this->getContentByGroupAsSQLPart($mixedPrivacyGroups);
  471. }
  472. /**
  473. * Check whether the viewer can make requested action.
  474. *
  475. * @param integer $iObjectId object ID the action to be performed with.
  476. * @param integer $iViewerId viewer ID.
  477. * @return boolean result of operation.
  478. */
  479. public function check($iObjectId, $iViewerId = 0)
  480. {
  481. $aObject = $this->getObjectInfo($this->convertActionToField($this->_aObject['action']), $iObjectId);
  482. $bRv = $this->_check($iObjectId, $iViewerId, $aObject);
  483. bx_alert('system', 'check_privacy', 0, 0, array(
  484. 'object_id' => $iObjectId,
  485. 'viewer_id' => $iViewerId,
  486. 'object' => $aObject,
  487. 'object_privacy' => $this->_aObject,
  488. 'result' => &$bRv
  489. ));
  490. return $bRv;
  491. }
  492. public function checkSpace($aObject, $iViewerId)
  493. {
  494. $oProfile = BxDolProfile::getInstance(-$aObject['group_id']);
  495. if (!$oProfile)
  496. return false;
  497. return CHECK_ACTION_RESULT_ALLOWED === BxDolService::call($oProfile->getModule(), 'check_space_privacy', array($oProfile->getContentId()));
  498. }
  499. public function checkMeOnly($iOwnerId, $iViewerId)
  500. {
  501. return false;
  502. }
  503. public function checkPublic($iOwnerId, $iViewerId)
  504. {
  505. return true;
  506. }
  507. public function checkMembers($iOwnerId, $iViewerId)
  508. {
  509. return isMember();
  510. }
  511. public function checkFriends($iOwnerId, $iViewerId)
  512. {
  513. return BxDolConnection::getObjectInstance('sys_profiles_friends')->isConnected($iOwnerId, $iViewerId, true);
  514. }
  515. public function checkFriendsSelectedByObject($aObject, $iViewerId)
  516. {
  517. if(!$this->checkFriends($aObject['owner_id'], $iViewerId))
  518. return false;
  519. $aGroupCustom = $this->getGroupCustom(array(
  520. 'type' => 'pcog_ext',
  521. 'profile_id' => $aObject['owner_id'],
  522. 'content_id' => $aObject['id'],
  523. 'object' => $this->_sObject,
  524. 'group_id' => $aObject['group_id'],
  525. 'group_items_table' => $this->_aGroupsSettings[$aObject['group_id']]['db_table_items'],
  526. 'group_items_field' => $this->_aGroupsSettings[$aObject['group_id']]['db_field_item']
  527. ));
  528. return !empty($aGroupCustom['items']) && is_array($aGroupCustom['items']) && in_array($iViewerId, $aGroupCustom['items']);
  529. }
  530. public function checkRelations($iOwnerId, $iViewerId)
  531. {
  532. return BxDolConnection::getObjectInstance('sys_profiles_relations')->isConnected($iOwnerId, $iViewerId, true);
  533. }
  534. public function checkRelationsSelectedByObject($aObject, $iViewerId)
  535. {
  536. if(!$this->checkRelations($aObject['owner_id'], $iViewerId))
  537. return false;
  538. $aGroupCustom = $this->getGroupCustom(array(
  539. 'type' => 'pcog_ext',
  540. 'profile_id' => $aObject['owner_id'],
  541. 'content_id' => $aObject['id'],
  542. 'object' => $this->_sObject,
  543. 'group_id' => $aObject['group_id'],
  544. 'group_items_table' => $this->_aGroupsSettings[$aObject['group_id']]['db_table_items'],
  545. 'group_items_field' => $this->_aGroupsSettings[$aObject['group_id']]['db_field_item']
  546. ));
  547. return !empty($aGroupCustom['items']) && is_array($aGroupCustom['items']) && in_array($iViewerId, $aGroupCustom['items']);
  548. }
  549. public function checkMembershipsSelectedByObject($aObject, $iViewerId)
  550. {
  551. $aGroupCustom = $this->getGroupCustom(array(
  552. 'type' => 'pcog_ext',
  553. 'profile_id' => $aObject['owner_id'],
  554. 'content_id' => $aObject['id'],
  555. 'object' => $this->_sObject,
  556. 'group_id' => $aObject['group_id'],
  557. 'group_items_table' => $this->_aGroupsSettings[$aObject['group_id']]['db_table_items'],
  558. 'group_items_field' => $this->_aGroupsSettings[$aObject['group_id']]['db_field_item']
  559. ));
  560. return !empty($aGroupCustom['items']) && is_array($aGroupCustom['items']) && BxDolAcl::getInstance()->isMemberLevelInSet($aGroupCustom['items'], $iViewerId);
  561. }
  562. public function checkCustomByObject($aObject, $iViewerId)
  563. {
  564. return '';
  565. }
  566. public function setTableFieldAuthor($sValue)
  567. {
  568. $this->_aObject['table_field_author'] = $sValue;
  569. $this->_oDb->init($this->_aObject);
  570. }
  571. protected function getObjectInfo($sAction, $iObjectId)
  572. {
  573. return $this->_oDb->getObjectInfo($sAction, $iObjectId);
  574. }
  575. protected function getPrivacyGroupsForContentPublic($iProfileIdOwner = 0, $aCustomGroups = array())
  576. {
  577. $aGroups = array(BX_DOL_PG_ALL);
  578. if(isLogged()) {
  579. $iProfileIdLogged = bx_get_logged_profile_id();
  580. if($iProfileIdLogged == $iProfileIdOwner)
  581. return true;
  582. $aGroups[] = BX_DOL_PG_MEMBERS;
  583. if($iProfileIdOwner && $this->checkFriends($iProfileIdOwner, $iProfileIdLogged))
  584. $aGroups[] = BX_DOL_PG_FRIENDS;
  585. }
  586. return array_merge($aGroups, $aCustomGroups);
  587. }
  588. protected function getCheckMethod($s)
  589. {
  590. if(substr($s, 0, 1) != '@')
  591. return false;
  592. return bx_gen_method_name(str_replace('@', 'check_', $s));
  593. }
  594. protected function convertActionToField($sAction)
  595. {
  596. return 'allow_' . strtolower(str_replace(' ', '-', $sAction)) . '_to';
  597. }
  598. /**
  599. * Check whethere viewer is a member of dynamic group.
  600. *
  601. * @param mixed $mixedGroupId dynamic group ID.
  602. * @param integer $iObjectOwnerId object owner ID.
  603. * @param integer $iViewerId viewer ID.
  604. * @return boolean result of operation.
  605. */
  606. protected function isDynamicGroupMember($mixedGroupId, $iObjectOwnerId, $iViewerId, $iObjectId)
  607. {
  608. return false;
  609. }
  610. /**
  611. * get privacy groups for getGroupChooser
  612. */
  613. protected function getGroups($iOwnerId = 0, $aParams = [])
  614. {
  615. $aValues = array();
  616. $aGroups = $this->_oDb->getGroupsBy(array('type' => 'active'));
  617. foreach($aGroups as $aGroup) {
  618. $iGroupId = (int)$aGroup['id'];
  619. if((int)$aGroup['active'] == 0 || in_array($iGroupId, $this->_aGroupsExclude))
  620. continue;
  621. if(isset($this->_aGroupsSettings[$iGroupId]) && !empty($this->_aGroupsSettings[$iGroupId]['is_allowed'])) {
  622. $sMethodIsAllowed = $this->_aGroupsSettings[$iGroupId]['is_allowed'];
  623. if(method_exists($this, $sMethodIsAllowed) && $this->$sMethodIsAllowed($iOwnerId) !== true)
  624. continue;
  625. }
  626. $aValues[] = array('key' => $aGroup['id'], 'value' => _t($aGroup['title']));
  627. }
  628. return $aValues;
  629. }
  630. /**
  631. * Check whethere a custom group (based on users list) is allowed in current circumstances.
  632. * NOTE. Can be overwritten if it's needed.
  633. *
  634. * @param type $aParams an array of parameters.
  635. * @return boolean result of operation.
  636. */
  637. protected function isSelectGroupCustomUsers($aParams)
  638. {
  639. return true;
  640. }
  641. /**
  642. * Check whethere a custom group (based on memberships list) is allowed in current circumstances.
  643. * NOTE. Can be overwritten if it's needed.
  644. *
  645. * @param type $aParams an array of parameters.
  646. * @return boolean result of operation.
  647. */
  648. protected function isSelectGroupCustomMemberships($aParams)
  649. {
  650. return true;
  651. }
  652. public function isAllowedMemberships($iUserId)
  653. {
  654. $aCheck = checkActionModule($iUserId, 'show membership levels in privacy groups', 'system', false);
  655. return $aCheck[CHECK_ACTION_RESULT] === CHECK_ACTION_RESULT_ALLOWED;
  656. }
  657. /**
  658. * Check whether the viewer can make requested action.
  659. *
  660. * @param integer $iObjectId object ID the action to be performed with.
  661. * @param integer $iViewerId viewer ID.
  662. * @return boolean result of operation.
  663. */
  664. protected function _check($iObjectId, $iViewerId, $aObject)
  665. {
  666. if(empty($iViewerId))
  667. $iViewerId = (int)bx_get_logged_profile_id();
  668. if(empty($aObject) || !is_array($aObject))
  669. return false;
  670. if($aObject['group_id'] == BX_DOL_PG_HIDDEN)
  671. return false;
  672. $aViewer = BxDolProfileQuery::getInstance()->getInfoById($iViewerId);
  673. if(($aViewer && isAdmin($aViewer['account_id'])) || $iViewerId == $aObject['owner_id'])
  674. return true;
  675. if(strncmp($aObject['group_id'], 'ml', 2) === 0) {
  676. $iLevel = (int)substr($aObject['group_id'], 2);
  677. return (bool)BxDolAcl::getInstance()->isMemberLevelInSet(array($iLevel), $iViewerId);
  678. }
  679. if($aObject['group_id'] < 0)
  680. return $this->checkSpace($aObject, $iViewerId);
  681. $aGroup = $this->_oDb->getGroupsBy(array('type' => 'id', 'id' => $aObject['group_id']));
  682. if(!empty($aGroup) && is_array($aGroup) && (int)$aGroup['active'] == 1 && !empty($aGroup['check'])) {
  683. $sCheckMethod = $this->getCheckMethod($aGroup['check']);
  684. if(method_exists($this, $sCheckMethod) && $this->$sCheckMethod((substr($sCheckMethod, -8) == 'ByObject' ? $aObject : $aObject['owner_id']), $iViewerId))
  685. return true;
  686. }
  687. return $this->isDynamicGroupMember($aObject['group_id'], $aObject['owner_id'], $iViewerId, $iObjectId);
  688. }
  689. }
  690. /** @} */