BxDolPrivacy.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup DolphinCore Dolphin Core
  7. * @{
  8. */
  9. bx_import('BxDolPrivacyQuery');
  10. define('BX_DOL_PG_HIDDEN', '1');
  11. define('BX_DOL_PG_MEONLY', '2');
  12. define('BX_DOL_PG_ALL', '3');
  13. define('BX_DOL_PG_MEMBERS', '4');
  14. define('BX_DOL_PG_CONNECTIONS', '5');
  15. //define('BX_DOL_PG_FAVES', '6');
  16. //define('BX_DOL_PG_CONTACTS', '7');
  17. define('BX_DOL_PG_DEFAULT', BX_DOL_PG_ALL);
  18. /**
  19. * Privacy settings for any content.
  20. *
  21. * Integration of the content with privacy engine allows site member
  22. * to organize the access to his content.
  23. *
  24. * Related classes:
  25. * BxDolPrivacyQuery - database queries.
  26. *
  27. * Example of usage:
  28. * 1. Register your privacy actions in `sys_privacy_actions` database table.
  29. * 2. Add one privacy field(with INT type) in the table with your items for each action.
  30. * For example, for action 'comment', the field name should be 'allow_comment_to'.
  31. * 3. Add group choosers for necessary actions in the form, which is used to add new items.
  32. *
  33. * $oPrivacy = new BxDolPrivacy();
  34. * $oPrivacy->getGroupChooser($iItemOwnerId, $sModuleUri, $sModuleAction);
  35. *
  36. * 4. Check privacy when any user tries to view an item.
  37. *
  38. * $oPrivacy = new BxDolPrivacy($sTable, $sFieldId, $sFieldOwnerId);
  39. * if($oPrivacy->check($sAction, $iObjectId, $iViewerId)) {
  40. * //show necessary content
  41. * }
  42. *
  43. * @see an example of integration in the default Dolphin's modules(feedback, events, sites, etc)
  44. *
  45. *
  46. * Memberships/ACL:
  47. * Doesn't depend on user's membership.
  48. *
  49. *
  50. * Alerts:
  51. * no alerts available
  52. *
  53. */
  54. class BxDolPrivacy extends BxDol implements iBxDolFactoryObject
  55. {
  56. protected $_oDb;
  57. protected $_sObject;
  58. protected $_aObject;
  59. /**
  60. * Constructor
  61. * @param $aObject array of grid options
  62. */
  63. function __construct($aObject)
  64. {
  65. parent::BxDol();
  66. $this->_aObject = $aObject;
  67. $this->_sObject = $aObject['object'];
  68. $this->_oDb = new BxDolPrivacyQuery($this->_aObject);
  69. }
  70. /**
  71. * Get privacy object instance by object name
  72. * @param $sObject object name
  73. * @return object instance or false on error
  74. */
  75. public static function getObjectInstance($sObject)
  76. {
  77. if(isset($GLOBALS['bxDolClasses']['BxDolPrivacy!' . $sObject]))
  78. return $GLOBALS['bxDolClasses']['BxDolPrivacy!' . $sObject];
  79. bx_import('BxDolPrivacyQuery');
  80. $aObject = BxDolPrivacyQuery::getPrivacyObject($sObject);
  81. if(!$aObject || !is_array($aObject))
  82. return false;
  83. bx_import('BxTemplPrivacy');
  84. $sClass = 'BxTemplPrivacy';
  85. if(!empty($aObject['override_class_name'])) {
  86. $sClass = $aObject['override_class_name'];
  87. if(!empty($aObject['override_class_file']))
  88. require_once(BX_DIRECTORY_PATH_ROOT . $aObject['override_class_file']);
  89. else
  90. bx_import($sClass);
  91. }
  92. $o = new $sClass($aObject);
  93. return ($GLOBALS['bxDolClasses']['BxDolPrivacy!' . $sObject] = $o);
  94. }
  95. /**
  96. * Get Select element with available groups.
  97. *
  98. * @param string $sModule module's unique URI.
  99. * @param string $sAction action name.
  100. * @param integer $iOwnerId object's owner ID.
  101. * @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).
  102. * @return an array with Select element description.
  103. */
  104. public static function getGroupChooser($sModule, $sAction, $iOwnerId = 0, $aParams = array())
  105. {
  106. if(empty($sModule) || empty($sAction))
  107. return array();
  108. if($iOwnerId == 0)
  109. $iOwnerId = bx_get_logged_profile_id();
  110. $oDb = new BxDolPrivacyQuery();
  111. $sValue = $oDb->getDefaultGroupByUser($sModule, $sAction, $iOwnerId);
  112. if(empty($sValue))
  113. $sValue = $oDb->getDefaultGroup($sModule, $sAction);
  114. $aValues = array();
  115. $aGroups = $oDb->getGroupsBy(array('type' => 'active'));
  116. foreach($aGroups as $aGroup) {
  117. if((int)$aGroup['active'] == 0)
  118. continue;
  119. $aValues[] = array('key' => $aGroup['id'], 'value' => _t($aGroup['title']));
  120. }
  121. if(isset($aParams['dynamic_groups']) && is_array($aParams['dynamic_groups']))
  122. $aValues = array_merge($aValues, $aParams['dynamic_groups']);
  123. $sName = self::getFieldName($sAction);
  124. $sTitle = isset($aParams['title']) && !empty($aParams['title']) ? $aParams['title'] : '';
  125. if(empty($sTitle)) {
  126. $sTitle = $oDb->getTitle($sModule, $sAction);
  127. $sTitle = _t(!empty($sTitle) ? $sTitle : '_' . $sName);
  128. }
  129. return array(
  130. 'type' => 'select',
  131. 'name' => $sName,
  132. 'caption' => $sTitle,
  133. 'value' => $sValue,
  134. 'values' => $aValues,
  135. 'checker' => array(
  136. 'func' => 'avail',
  137. 'error' => _t('_ps_ferr_incorrect_select')
  138. ),
  139. 'db' => array(
  140. 'pass' => 'Int'
  141. )
  142. );
  143. }
  144. /**
  145. * Get database field name for action.
  146. *
  147. * @param string $sAction action name.
  148. * @return string with field name.
  149. */
  150. public static function getFieldName($sAction)
  151. {
  152. return 'allow_' . strtolower(str_replace(' ', '-', $sAction)) . '_to';
  153. }
  154. /**
  155. * Get necessary condition array to use privacy in search classes
  156. * @param $sAction action to be checked
  157. * @param $mixedGroupId group ID or array of group IDs
  158. * @return array of conditions, for now with 'restriction' part only is returned
  159. */
  160. public function getContentByGroupAsCondition($sAction, $mixedGroupId) {
  161. return array(
  162. 'restriction' => array (
  163. 'privacy_' . $this->_sObject => array(
  164. 'value' => $mixedGroupId,
  165. 'field' => self::getFieldName($sAction),
  166. 'operator' => is_array($mixedGroupId) ? 'in' : '=',
  167. 'table' => $this->_aObject['table'],
  168. ),
  169. ),
  170. );
  171. }
  172. /**
  173. * Get necessary parts of SQL query to use privacy in other queries
  174. * @param $sAction action to be checked
  175. * @param $mixedGroupId group ID or array of group IDs
  176. * @return array of SQL string parts, for now 'where' part only is returned
  177. */
  178. public function getContentByGroupAsSQLPart($sAction, $mixedGroupId) {
  179. $sField = self::getFieldName($sAction);
  180. return $this->_oDb->getContentByGroupAsSQLPart($sField, $mixedGroupId);
  181. }
  182. /**
  183. * Check whether the viewer can make requested action.
  184. *
  185. * @param integer $iObjectId object ID the action to be performed with.
  186. * @param integer $iViewerId viewer ID.
  187. * @return boolean result of operation.
  188. */
  189. function check($iObjectId, $iViewerId = 0)
  190. {
  191. if(empty($iViewerId))
  192. $iViewerId = bx_get_logged_profile_id();
  193. $aObject = $this->_oDb->getObjectInfo($this->getFieldName($this->_aObject['action']), $iObjectId);
  194. if(empty($aObject) || !is_array($aObject))
  195. return false;
  196. if($aObject['group_id'] == BX_DOL_PG_HIDDEN)
  197. return false;
  198. if(isAdmin() || $iViewerId == $aObject['owner_id'])
  199. return true;
  200. $aGroup = $this->_oDb->getGroupsBy(array('type' => 'id', 'id' => $aObject['group_id']));
  201. if(!empty($aGroup) && is_array($aGroup) && (int)$aGroup['active'] == 1 && !empty($aGroup['check'])) {
  202. $sCheckMethod = $this->getCheckMethod($aGroup['check']);
  203. if(method_exists($this, $sCheckMethod) && $this->$sCheckMethod($aObject['owner_id'], $iViewerId))
  204. return true;
  205. }
  206. return $this->isDynamicGroupMember($aObject['group_id'], $aObject['owner_id'], $iViewerId, $iObjectId);
  207. }
  208. public function checkMeOnly($iOwnerId, $iViewerId)
  209. {
  210. return false;
  211. }
  212. public function checkPublic($iOwnerId, $iViewerId)
  213. {
  214. return true;
  215. }
  216. public function checkMembers($iOwnerId, $iViewerId)
  217. {
  218. return isMember();
  219. }
  220. public function checkConnections($iOwnerId, $iViewerId)
  221. {
  222. bx_import('BxDolConnection');
  223. return BxDolConnection::getObjectInstance('sys_profiles_connections')->isConnected($iOwnerId, $iViewerId, true);
  224. }
  225. protected function getCheckMethod($s)
  226. {
  227. if(substr($s, 0, 1) != '@')
  228. return false;
  229. return str_replace(' ', '', ucwords(str_replace('_', ' ', str_replace('@', 'check_', $s))));
  230. }
  231. /**
  232. * Check whethere viewer is a member of dynamic group.
  233. *
  234. * @param mixed $mixedGroupId dynamic group ID.
  235. * @param integer $iObjectOwnerId object owner ID.
  236. * @param integer $iViewerId viewer ID.
  237. * @return boolean result of operation.
  238. */
  239. protected function isDynamicGroupMember($mixedGroupId, $iObjectOwnerId, $iViewerId, $iObjectId)
  240. {
  241. return false;
  242. }
  243. }