BxTimelineDb.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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 Timeline Timeline
  7. * @ingroup DolphinModules
  8. *
  9. * @{
  10. */
  11. bx_import('BxDolModuleDb');
  12. class BxTimelineDb extends BxDolModuleDb
  13. {
  14. var $_oConfig;
  15. var $_sTable;
  16. var $_sTableHandlers;
  17. var $_sTablesShareTrack;
  18. /*
  19. * Constructor.
  20. */
  21. function __construct(&$oConfig)
  22. {
  23. parent::__construct($oConfig);
  24. $this->_oConfig = $oConfig;
  25. $this->_sTable = $this->_sPrefix . 'events';
  26. $this->_sTableHandlers = $this->_sPrefix . 'handlers';
  27. $this->_sTableSharesTrack = $this->_sPrefix . 'shares_track';
  28. }
  29. public function getAlertHandlerId()
  30. {
  31. $sQuery = $this->prepare("SELECT `id` FROM `sys_alerts_handlers` WHERE `name`=? LIMIT 1", $this->_oConfig->getSystemName('alert'));
  32. return (int)$this->getOne($sQuery);
  33. }
  34. public function insertData($aData)
  35. {
  36. foreach($aData['handlers'] as $aHandler) {
  37. //--- Delete module related events ---//
  38. $this->deleteEvent(array('type' => $aHandler['alert_unit'], 'action' => $aHandler['alert_action']));
  39. $sContent = '';
  40. if($aHandler['type'] == BX_TIMELINE_HANDLER_TYPE_INSERT)
  41. $sContent = serialize(array(
  42. 'module_name' => $aHandler['module_name'],
  43. 'module_method' => $aHandler['module_method'],
  44. 'module_params' => $aHandler['module_params'],
  45. 'module_class' => $aHandler['module_class'],
  46. 'groupable' => $aHandler['groupable'],
  47. 'group_by' => $aHandler['group_by']
  48. ));
  49. //--- Update Timeline Handlers ---//
  50. $sQuery = $this->prepare("INSERT INTO
  51. `{$this->_sTableHandlers}`
  52. SET
  53. `type`=?,
  54. `alert_unit`=?,
  55. `alert_action`=?,
  56. `content`=?", $aHandler['type'], $aHandler['alert_unit'], $aHandler['alert_action'], $sContent);
  57. $this->query($sQuery);
  58. }
  59. //--- Update System Alerts ---//
  60. $iHandlerId = $this->getAlertHandlerId();
  61. foreach($aData['alerts'] as $aAlert) {
  62. $sQuery = $this->prepare("INSERT INTO
  63. `sys_alerts`
  64. SET
  65. `unit`=?,
  66. `action`=?,
  67. `handler_id`=?", $aAlert['unit'], $aAlert['action'], $iHandlerId);
  68. $this->query($sQuery);
  69. }
  70. }
  71. public function deleteData($aData)
  72. {
  73. foreach($aData['handlers'] as $aHandler) {
  74. //--- Delete module related events ---//
  75. $this->deleteEvent(array('type' => $aHandler['alert_unit'], 'action' => $aHandler['alert_action']));
  76. //--- Update Wall Handlers ---//
  77. $sQuery = $this->prepare("DELETE FROM
  78. `{$this->_sTableHandlers}`
  79. WHERE
  80. `alert_unit`=? AND
  81. `alert_action`=?
  82. LIMIT 1", $aHandler['alert_unit'], $aHandler['alert_action']);
  83. $this->query($sQuery);
  84. }
  85. //--- Update System Alerts ---//
  86. $iHandlerId = $this->getAlertHandlerId();
  87. foreach($aData['alerts'] as $aAlert) {
  88. $sQuery = $this->prepare("DELETE FROM
  89. `sys_alerts`
  90. WHERE
  91. `unit`=? AND
  92. `action`=? AND
  93. `handler_id`=?
  94. LIMIT 1", $aAlert['unit'], $aAlert['action'], $iHandlerId);
  95. $this->query($sQuery);
  96. }
  97. }
  98. public function getHandlers($aParams = array())
  99. {
  100. $sMethod = 'getAll';
  101. $sWhereClause = '';
  102. if(!empty($aParams))
  103. switch($aParams['type']) {}
  104. $sSql = "SELECT
  105. `id` AS `id`,
  106. `type` AS `type`,
  107. `alert_unit` AS `alert_unit`,
  108. `alert_action` AS `alert_action`,
  109. `content` AS `content`
  110. FROM `{$this->_sTableHandlers}`
  111. WHERE 1 AND `alert_unit` NOT LIKE ('" . $this->_oConfig->getPrefix('common_post') . "%')" . $sWhereClause;
  112. return $this->$sMethod($sSql);
  113. }
  114. public function insertEvent($aParamsSet)
  115. {
  116. if(empty($aParamsSet))
  117. return 0;
  118. $aSet = array();
  119. foreach($aParamsSet as $sKey => $sValue)
  120. $aSet[] = $this->prepare("`" . $sKey . "`=?", $sValue);
  121. if((int)$this->query("INSERT INTO `{$this->_sTable}` SET " . implode(", ", $aSet) . ", `date`=UNIX_TIMESTAMP()") <= 0)
  122. return 0;
  123. return (int)$this->lastId();
  124. }
  125. public function updateEvent($aParamsSet, $aParamsWhere)
  126. {
  127. if(empty($aParamsSet) || empty($aParamsWhere))
  128. return false;
  129. $aSet = array();
  130. foreach($aParamsSet as $sKey => $sValue)
  131. $aSet[] = $this->prepare("`" . $sKey . "`=?", $sValue);
  132. $aWhere = array();
  133. foreach($aParamsWhere as $sKey => $sValue)
  134. $aWhere[] = $this->prepare("`" . $sKey . "`=?", $sValue);
  135. $sSql = "UPDATE `{$this->_sTable}` SET " . implode(", ", $aSet) . " WHERE " . implode(" AND ", $aWhere);
  136. return $this->query($sSql);
  137. }
  138. public function deleteEvent($aParams, $sWhereAddon = "")
  139. {
  140. $aWhere = array();
  141. foreach($aParams as $sKey => $sValue)
  142. $aWhere[] = $this->prepare("`" . $sKey . "`=?", $sValue);
  143. $sSql = "DELETE FROM `{$this->_sTable}` WHERE " . implode(" AND ", $aWhere) . $sWhereAddon;
  144. return $this->query($sSql);
  145. }
  146. public function getEvents($aParams)
  147. {
  148. $sMethod = 'getAll';
  149. $sJoinClause = $sWhereClause = $sOrderClause = $sLimitClause = "";
  150. switch($aParams['browse']) {
  151. case 'id':
  152. $sMethod = 'getRow';
  153. $sWhereClause = $this->prepare("AND `{$this->_sTable}`.`id`=? ", $aParams['value']);
  154. $sLimitClause = "LIMIT 1";
  155. break;
  156. case 'descriptor':
  157. $sMethod = 'getRow';
  158. $sWhereClause = $this->prepare("AND `{$this->_sTable}`.`type`=? AND `{$this->_sTable}`.`action`=? AND `{$this->_sTable}`.`object_id`=? ", $aParams['type'], $aParams['action'], $aParams['object_id']);
  159. $sLimitClause = "LIMIT 1";
  160. break;
  161. case 'last':
  162. case 'list':
  163. //--- Apply filter
  164. if(isset($aParams['filter']))
  165. $sWhereClause .= $this->_getFilterAddon($aParams['owner_id'], $aParams['filter']);
  166. //--- Apply timeline
  167. if(isset($aParams['timeline']) && !empty($aParams['timeline'])) {
  168. $iYear = (int)$aParams['timeline'];
  169. $sWhereClause .= $this->prepare("AND `date`<=? ", mktime(23, 59, 59, 12, 31, $iYear));
  170. }
  171. //--- Apply modules or handlers filter
  172. $sWhereModuleFilter = '';
  173. if(isset($aParams['modules']) && !empty($aParams['modules']) && is_array($aParams['modules']))
  174. $sWhereModuleFilter = "AND `type` IN (" . $this->implode_escape($aParams['modules']) . ") ";
  175. if($sWhereModuleFilter == '') {
  176. $aHidden = $this->_oConfig->getHandlersHidden();
  177. $sWhereModuleFilter = is_array($aHidden) && !empty($aHidden) ? "AND `th`.`id` NOT IN (" . $this->implode_escape($aHidden) . ") " : "";
  178. }
  179. if($sWhereModuleFilter == '')
  180. $sWhereClause .= $sWhereModuleFilter;
  181. //--- Check type
  182. if(!empty($aParams['owner_id']))
  183. switch($aParams['type']) {
  184. case BX_TIMELINE_TYPE_OWNER:
  185. $sWhereClause .= $this->prepare("AND `{$this->_sTable}`.`owner_id`=? ", $aParams['owner_id']);
  186. break;
  187. case BX_TIMELINE_TYPE_CONNECTIONS:
  188. bx_import('BxDolConnection');
  189. $oConnection = BxDolConnection::getObjectInstance($this->_oConfig->getObject('conn_subscriptions'));
  190. $aQueryParts = $oConnection->getConnectedContentAsSQLParts($this->_sPrefix . "events", 'owner_id', $aParams['owner_id']);
  191. $sJoinClause .= ' ' . $aQueryParts['join'];
  192. $iUserId = bx_get_logged_profile_id();
  193. $sCommonPostPrefix = $this->_oConfig->getPrefix('common_post');
  194. $sWhereClause .= "AND IF(SUBSTRING(`{$this->_sTable}`.`type`, 1, " . strlen($sCommonPostPrefix) . ") = '" . $sCommonPostPrefix . "', `{$this->_sTable}`.`object_id` <> " . $iUserId . ", 1)";
  195. break;
  196. }
  197. switch($aParams['browse']) {
  198. case 'last':
  199. $sMethod = 'getRow';
  200. $sOrderClause = "ORDER BY `{$this->_sTable}`.`date` ASC";
  201. $sLimitClause = "LIMIT 1";
  202. break;
  203. case 'list':
  204. $sOrderClause = "ORDER BY `{$this->_sTable}`.`date` DESC";
  205. $sLimitClause = isset($aParams['per_page']) ? "LIMIT " . $aParams['start'] . ", " . $aParams['per_page'] : "";
  206. break;
  207. }
  208. break;
  209. }
  210. $sSql = "SELECT
  211. `{$this->_sTable}`.`id` AS `id`,
  212. `{$this->_sTable}`.`owner_id` AS `owner_id`,
  213. `{$this->_sTable}`.`type` AS `type`,
  214. `{$this->_sTable}`.`action` AS `action`,
  215. `{$this->_sTable}`.`object_id` AS `object_id`,
  216. `{$this->_sTable}`.`content` AS `content`,
  217. `{$this->_sTable}`.`rate` AS `rate`,
  218. `{$this->_sTable}`.`votes` AS `votes`,
  219. `{$this->_sTable}`.`comments` AS `comments`,
  220. `{$this->_sTable}`.`title` AS `title`,
  221. `{$this->_sTable}`.`description` AS `description`,
  222. `{$this->_sTable}`.`shares` AS `shares`,
  223. `{$this->_sTable}`.`date` AS `date`,
  224. YEAR(FROM_UNIXTIME(`{$this->_sTable}`.`date`)) AS `year`,
  225. DAYOFYEAR(FROM_UNIXTIME(`{$this->_sTable}`.`date`)) AS `day_date`,
  226. DAYOFYEAR(NOW()) AS `day_now`,
  227. (UNIX_TIMESTAMP() - `{$this->_sTable}`.`date`)/86400 AS `ago_days`
  228. FROM `{$this->_sTable}`
  229. LEFT JOIN `{$this->_sTableHandlers}` ON `{$this->_sTable}`.`type`=`{$this->_sTableHandlers}`.`alert_unit` AND `{$this->_sTable}`.`action`=`{$this->_sTableHandlers}`.`alert_action` " . $sJoinClause . "
  230. WHERE 1 " . $sWhereClause . " " . $sOrderClause . " " . $sLimitClause;
  231. return $this->$sMethod($sSql);
  232. }
  233. public function getMaxDuration($aParams)
  234. {
  235. $aParams['browse'] = 'last';
  236. if(isset($aParams['timeline']))
  237. unset($aParams['timeline']);
  238. $aEvent = $this->getEvents($aParams);
  239. if(empty($aEvent) || !is_array($aEvent))
  240. return 0;
  241. $iNowYear = date('Y', time());
  242. return (int)$aEvent['year'] < $iNowYear ? (int)$aEvent['year'] : 0;
  243. }
  244. //--- Share related methods ---//
  245. public function insertShareTrack($iEventId, $iAuthorId, $sAuthorIp, $iSharedId)
  246. {
  247. $iAuthorNip = ip2long($sAuthorIp);
  248. $sQuery = $this->prepare("INSERT INTO `{$this->_sTableSharesTrack}` SET `event_id` = ?, `author_id` = ?, `author_nip` = ?, `shared_id` = ?, `date` = UNIX_TIMESTAMP()", $iEventId, $iAuthorId, $iAuthorNip, $iSharedId);
  249. return (int)$this->query($sQuery) > 0;
  250. }
  251. public function deleteShareTrack($iEventId)
  252. {
  253. $sQuery = $this->prepare("DELETE FROM `{$this->_sTableSharesTrack}` WHERE `event_id` = ?", $iEventId);
  254. return (int)$this->query($sQuery) > 0;
  255. }
  256. public function updateShareCounter($iId, $iCounter, $iIncrement = 1)
  257. {
  258. return (int)$this->updateEvent(array('shares' => (int)$iCounter + $iIncrement), array('id' => $iId)) > 0;
  259. }
  260. public function getShared($sType, $sAction, $iObjectId)
  261. {
  262. if($this->_oConfig->isSystem($sType, $sAction))
  263. $aParams = array('browse' => 'descriptor', 'type' => $sType, 'action' => $sAction, 'object_id' => $iObjectId);
  264. else
  265. $aParams = array('browse' => 'id', 'value' => $iObjectId);
  266. return $this->getEvents($aParams);
  267. }
  268. function getSharedBy($iSharedId)
  269. {
  270. $sQuery = $this->prepare("SELECT `author_id` FROM `{$this->_sTableSharesTrack}` WHERE `shared_id`=?", $iSharedId);
  271. return $this->getColumn($sQuery);
  272. }
  273. //--- Photo uploader related methods ---//
  274. public function savePhoto($iEventId, $iPhId, $sPhTitle = '', $sPhText = '')
  275. {
  276. $sQuery = $this->prepare("INSERT INTO `" . $this->_sPrefix . "photos2events` SET `event_id`=?, `photo_id`=?, `title`=?, `text`=?", $iEventId, $iPhId, $sPhTitle, $sPhText);
  277. return (int)$this->query($sQuery) > 0;
  278. }
  279. public function deletePhotos($iEventId)
  280. {
  281. $sQuery = $this->prepare("DELETE FROM `" . $this->_sPrefix . "photos2events` WHERE `event_id` = ?", $iEventId);
  282. return (int)$this->query($sQuery) > 0;
  283. }
  284. public function getPhotos($iEventId)
  285. {
  286. $sQuery = $this->prepare("SELECT
  287. `tpe`.`photo_id` AS `id`,
  288. `tpe`.`title` AS `title`,
  289. `tpe`.`text` AS `text`
  290. FROM `" . $this->_sPrefix . "photos2events` AS `tpe`
  291. LEFT JOIN `" . $this->_sPrefix . "photos` AS `tp` ON `tpe`.`photo_id` = `tp`.`id`
  292. WHERE `tpe`.`event_id` = ?", $iEventId);
  293. return $this->getAll($sQuery);
  294. }
  295. protected function _getFilterAddon($iOwnerId, $sFilter)
  296. {
  297. switch($sFilter) {
  298. case BX_TIMELINE_FILTER_OWNER:
  299. $sFilterAddon = " AND `te`.`action`='' AND `te`.`object_id`='" . $iOwnerId . "' ";
  300. break;
  301. case BX_TIMELINE_FILTER_OTHER:
  302. $sFilterAddon = " AND `te`.`action`='' AND `te`.`object_id`<>'" . $iOwnerId . "' ";
  303. break;
  304. case BX_TIMELINE_FILTER_ALL:
  305. default:
  306. $sFilterAddon = "";
  307. }
  308. return $sFilterAddon;
  309. }
  310. function updateSimilarObject($iId, &$oAlert, $sDuration = 'day')
  311. {
  312. $sType = $oAlert->sUnit;
  313. $sAction = $oAlert->sAction;
  314. //Check handler
  315. $aHandler = $this->_oConfig->getHandlers($sType . '_' . $sAction);
  316. if(empty($aHandler) || !is_array($aHandler) || (int)$aHandler['groupable'] != 1)
  317. return false;
  318. //Check content's extra values
  319. if(isset($aHandler['group_by']) && !empty($aHandler['group_by']) && (!isset($oAlert->aExtras[$aHandler['group_by']]) || empty($oAlert->aExtras[$aHandler['group_by']])))
  320. return false;
  321. $sWhereClause = "";
  322. switch($sDuration) {
  323. case 'day':
  324. $iDayStart = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
  325. $iDayEnd = mktime(23, 59, 59, date('m'), date('d'), date('Y'));
  326. $sWhereClause .= "AND `date`>" . $iDayStart . " AND `date`<" . $iDayEnd . " ";
  327. break;
  328. }
  329. if(isset($aHandler['group_by']))
  330. $sWhereClause .= "AND `content` LIKE '%" . $oAlert->aExtras[$aHandler['group_by']] . "%' ";
  331. $sSql = "UPDATE `{$this->_sTable}`
  332. SET
  333. `object_id`=CONCAT(`object_id`, '," . $oAlert->iObject . "'),
  334. `title`='',
  335. `description`='',
  336. `date`=UNIX_TIMESTAMP()
  337. WHERE
  338. `id`<>'" . $iId . "' AND
  339. `owner_id`='" . $oAlert->iSender . "' AND
  340. `type`='" . $sType . "' AND
  341. `action`='" . $sAction . "' " . $sWhereClause;
  342. $mixedResult = $this->query($sSql);
  343. if((int)$mixedResult > 0)
  344. $this->deleteEvent(array('id' => $iId));
  345. return $mixedResult;
  346. }
  347. }
  348. /** @} */