PageRenderTime 95ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/vanilla/applications/dashboard/models/class.messagemodel.php

https://bitbucket.org/manvir96/vanilla-forum-sail-community
PHP | 306 lines | 194 code | 35 blank | 77 comment | 49 complexity | 19650f201b5f27bad7725bf33f797cd4 MD5 | raw file
Possible License(s): LGPL-3.0, AGPL-1.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, CC-BY-SA-3.0, GPL-2.0, MIT
  1. <?php
  2. /**
  3. * Message model.
  4. *
  5. * @copyright 2009-2016 Vanilla Forums Inc.
  6. * @license http://www.opensource.org/licenses/gpl-2.0.php GNU GPL v2
  7. * @package Dashboard
  8. * @since 2.0
  9. */
  10. /**
  11. * Handles message data.
  12. */
  13. class MessageModel extends Gdn_Model {
  14. /** @var array Non-standard message location allowed. */
  15. private $_SpecialLocations = array('[Base]', '[NonAdmin]');
  16. /** @var array Current message data. */
  17. protected static $Messages;
  18. /**
  19. * Class constructor. Defines the related database table name.
  20. */
  21. public function __construct() {
  22. parent::__construct('Message');
  23. }
  24. /**
  25. * Delete a message.
  26. *
  27. * @param array|int $where The where clause to delete or an integer value.
  28. * @param array|true $options An array of options to control the delete.
  29. * @return bool Returns **true** on success or **false** on failure.
  30. */
  31. public function delete($where = [], $options = []) {
  32. $result = parent::delete($where, $options);
  33. self::messages(null);
  34. return $result;
  35. }
  36. /**
  37. * Returns a single message object for the specified id or FALSE if not found.
  38. *
  39. * @param int $messageID The MessageID to filter to.
  40. * @param string|false $datasetType The format of the message.
  41. * @param array $options Options to modify the behavior of the get.
  42. * @return array Requested message.
  43. */
  44. public function getID($messageID, $datasetType = false, $options = array()) {
  45. if (Gdn::cache()->activeEnabled()) {
  46. $message = self::messages($messageID);
  47. if (!$message) {
  48. return $message;
  49. }
  50. if ($message instanceof Gdn_DataSet) {
  51. $message->datasetType($datasetType);
  52. } elseif ($datasetType === DATASET_TYPE_OBJECT) {
  53. return (object)$message;
  54. } else {
  55. return (array)$message;
  56. }
  57. } else {
  58. return parent::getID($messageID, $datasetType, $options);
  59. }
  60. }
  61. /**
  62. * Build the Message's Location property and add it.
  63. *
  64. * @param array|object $Message Message data.
  65. * @return array|object Message data with Location property/key added.
  66. */
  67. public function defineLocation($Message) {
  68. $Controller = val('Controller', $Message);
  69. $Application = val('Application', $Message);
  70. $Method = val('Method', $Message);
  71. if (in_array($Controller, $this->_SpecialLocations)) {
  72. setValue('Location', $Message, $Controller);
  73. } else {
  74. setValue('Location', $Message, $Application);
  75. if (!stringIsNullOrEmpty($Controller)) {
  76. setValue('Location', $Message, val('Location', $Message).'/'.$Controller);
  77. }
  78. if (!stringIsNullOrEmpty($Method)) {
  79. setValue('Location', $Message, val('Location', $Message).'/'.$Method);
  80. }
  81. }
  82. return $Message;
  83. }
  84. /**
  85. * Whether we are in (or optionally below) a category.
  86. *
  87. * @param int $NeedleCategoryID
  88. * @param int $HaystackCategoryID
  89. * @param bool $IncludeSubcategories
  90. * @return bool
  91. */
  92. protected static function inCategory($NeedleCategoryID, $HaystackCategoryID, $IncludeSubcategories = false) {
  93. if (!$HaystackCategoryID) {
  94. return true;
  95. }
  96. if ($NeedleCategoryID == $HaystackCategoryID) {
  97. return true;
  98. }
  99. if ($IncludeSubcategories) {
  100. $Cat = CategoryModel::categories($NeedleCategoryID);
  101. for ($i = 0; $i < 10; $i++) {
  102. if (!$Cat) {
  103. break;
  104. }
  105. if ($Cat['CategoryID'] == $HaystackCategoryID) {
  106. return true;
  107. }
  108. $Cat = CategoryModel::categories($Cat['ParentCategoryID']);
  109. }
  110. }
  111. return false;
  112. }
  113. /**
  114. * Get what messages are active for a template location.
  115. *
  116. * @param $Location
  117. * @param array $Exceptions
  118. * @param null $CategoryID
  119. * @return array|null
  120. */
  121. public function getMessagesForLocation($Location, $Exceptions = array('[Base]'), $CategoryID = null) {
  122. $Session = Gdn::session();
  123. $Prefs = $Session->getPreference('DismissedMessages', array());
  124. if (count($Prefs) == 0) {
  125. $Prefs[] = 0;
  126. }
  127. $category = null;
  128. if (!empty($CategoryID)) {
  129. $categoryModel = new CategoryModel();
  130. $category = $categoryModel->getID($CategoryID, DATASET_TYPE_ARRAY);
  131. }
  132. $Exceptions = array_map('strtolower', $Exceptions);
  133. list($Application, $Controller, $Method) = explode('/', strtolower($Location));
  134. if (Gdn::cache()->activeEnabled()) {
  135. // Get the messages from the cache.
  136. $Messages = self::messages();
  137. $Result = array();
  138. foreach ($Messages as $MessageID => $Message) {
  139. if (in_array($MessageID, $Prefs) || !$Message['Enabled']) {
  140. continue;
  141. }
  142. $MApplication = strtolower($Message['Application']);
  143. $MController = strtolower($Message['Controller']);
  144. $MMethod = strtolower($Message['Method']);
  145. $Visible = false;
  146. if (in_array($MController, $Exceptions)) {
  147. $Visible = true;
  148. } elseif ($MApplication == $Application && $MController == $Controller && $MMethod == $Method) {
  149. $Visible = true;
  150. }
  151. $Visible = $Visible && self::inCategory($CategoryID, val('CategoryID', $Message), val('IncludeSubcategories', $Message));
  152. if ($category !== null) {
  153. $Visible = $Visible && $Session->checkPermission('Vanilla.Discussions.View', true, 'Category', $category['PermissionCategoryID']);
  154. }
  155. if ($Visible) {
  156. $Result[] = $Message;
  157. }
  158. }
  159. return $Result;
  160. }
  161. $Result = $this->SQL
  162. ->select()
  163. ->from('Message')
  164. ->where('Enabled', '1')
  165. ->beginWhereGroup()
  166. ->whereIn('Controller', $Exceptions)
  167. ->orOp()
  168. ->beginWhereGroup()
  169. ->orWhere('Application', $Application)
  170. ->where('Controller', $Controller)
  171. ->where('Method', $Method)
  172. ->endWhereGroup()
  173. ->endWhereGroup()
  174. ->whereNotIn('MessageID', $Prefs)
  175. ->orderBy('Sort', 'asc')
  176. ->get()->resultArray();
  177. $Result = array_filter($Result, function($Message) use ($Session, $category) {
  178. $visible = MessageModel::inCategory(val('CategoryID', $category, null), val('CategoryID', $Message), val('IncludeSubcategories', $Message));
  179. if ($category !== null) {
  180. $visible = $visible && $Session->checkPermission('Vanilla.Discussions.View', true, 'Category', $category['PermissionCategoryID']);
  181. }
  182. return $visible;
  183. });
  184. return $Result;
  185. }
  186. /**
  187. * Returns a distinct array of controllers that have enabled messages.
  188. *
  189. * @return array Locations with enabled messages.
  190. */
  191. public function getEnabledLocations() {
  192. $Data = $this->SQL
  193. ->select('Application,Controller,Method')
  194. ->from('Message')
  195. ->where('Enabled', '1')
  196. ->groupBy('Application,Controller,Method')
  197. ->get();
  198. $Locations = array();
  199. foreach ($Data as $Row) {
  200. if (in_array($Row->Controller, $this->_SpecialLocations)) {
  201. $Locations[] = $Row->Controller;
  202. } else {
  203. $Location = $Row->Application;
  204. if ($Row->Controller != '') {
  205. $Location .= '/'.$Row->Controller;
  206. }
  207. if ($Row->Method != '') {
  208. $Location .= '/'.$Row->Method;
  209. }
  210. $Locations[] = $Location;
  211. }
  212. }
  213. return $Locations;
  214. }
  215. /**
  216. * Get all messages or one message.
  217. *
  218. * @param int|bool $ID ID of message to get.
  219. * @return array|null
  220. */
  221. public static function messages($ID = false) {
  222. if ($ID === null) {
  223. Gdn::cache()->remove('Messages');
  224. return;
  225. }
  226. $Messages = Gdn::cache()->get('Messages');
  227. if ($Messages === Gdn_Cache::CACHEOP_FAILURE) {
  228. $Messages = Gdn::sql()->get('Message', 'Sort')->resultArray();
  229. $Messages = Gdn_DataSet::index($Messages, array('MessageID'));
  230. Gdn::cache()->store('Messages', $Messages);
  231. }
  232. if ($ID === false) {
  233. return $Messages;
  234. } else {
  235. return val($ID, $Messages);
  236. }
  237. }
  238. /**
  239. * Save a message.
  240. *
  241. * @param array $FormPostValues Message data.
  242. * @param bool $Settings
  243. * @return int The MessageID.
  244. */
  245. public function save($FormPostValues, $Settings = false) {
  246. // The "location" is packed into a single input with a / delimiter. Need to explode it into three different fields for saving
  247. $Location = val('Location', $FormPostValues, '');
  248. if ($Location != '') {
  249. $Location = explode('/', $Location);
  250. $Application = val(0, $Location, '');
  251. if (in_array($Application, $this->_SpecialLocations)) {
  252. $FormPostValues['Application'] = null;
  253. $FormPostValues['Controller'] = $Application;
  254. $FormPostValues['Method'] = null;
  255. } else {
  256. $FormPostValues['Application'] = $Application;
  257. $FormPostValues['Controller'] = val(1, $Location, '');
  258. $FormPostValues['Method'] = val(2, $Location, '');
  259. }
  260. }
  261. Gdn::cache()->remove('Messages');
  262. return parent::save($FormPostValues, $Settings);
  263. }
  264. /**
  265. * Save our current message locations in the config.
  266. */
  267. public function setMessageCache() {
  268. // Retrieve an array of all controllers that have enabled messages associated
  269. saveToConfig('Garden.Messages.Cache', $this->getEnabledLocations());
  270. }
  271. }