1: <?php if(!defined('APPLICATION')) exit();
2:
3:
4: 5: 6: 7: 8: 9: 10: 11:
12: class ActedModel extends Gdn_Model {
13:
14: 15: 16: 17:
18: protected $_Expiry = 600;
19:
20: 21: 22: 23: 24: 25:
26: private function _BaseSQL($Table = 'Discussion') {
27: switch($Table) {
28: case 'Comment':
29: $SQL = Gdn::SQL()->Select('c.*')
30: ->From('Comment c')
31: ->Where('c.Score is not null')
32: ->OrderBy('c.Score', 'DESC');
33: break;
34: default:
35: case 'Discussion':
36: $SQL = Gdn::SQL()->Select('d.*')
37: ->From('Discussion d')
38: ->Where('d.Score is not null')
39: ->OrderBy('d.Score', 'DESC');
40: break;
41: }
42: return $SQL;
43: }
44:
45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
55: public function Get($UserID, $ActionID, $Limit = NULL, $Offset = 0) {
56: $CacheKey = "yaga.profile.reactions.{$UserID}.{$ActionID}";
57: $Content = Gdn::Cache()->Get($CacheKey);
58:
59: if($Content == Gdn_Cache::CACHEOP_FAILURE) {
60:
61:
62: $Discussions = $this->_BaseSQL('Discussion')
63: ->Join('Reaction r', 'd.DiscussionID = r.ParentID')
64: ->Where('d.InsertUserID', $UserID)
65: ->Where('r.ActionID', $ActionID)
66: ->Where('r.ParentType', 'discussion')
67: ->OrderBy('r.DateInserted', 'DESC')
68: ->Get()->Result(DATASET_TYPE_ARRAY);
69:
70:
71: $Comments = $this->_BaseSQL('Comment')
72: ->Join('Reaction r', 'c.CommentID = r.ParentID')
73: ->Where('c.InsertUserID', $UserID)
74: ->Where('r.ActionID', $ActionID)
75: ->Where('r.ParentType', 'comment')
76: ->OrderBy('r.DateInserted', 'DESC')
77: ->Get()->Result(DATASET_TYPE_ARRAY);
78:
79: $this->JoinCategory($Comments);
80:
81:
82: $Content = $this->Union('DateInserted', array(
83: 'Discussion' => $Discussions,
84: 'Comment' => $Comments
85: ));
86: $this->Prepare($Content);
87:
88:
89: Gdn::Cache()->Store($CacheKey, $Content, array(
90: Gdn_Cache::FEATURE_EXPIRY => $this->_Expiry
91: ));
92: }
93:
94: $this->Security($Content);
95: $this->Condense($Content, $Limit, $Offset);
96:
97: return $Content;
98: }
99:
100: 101: 102: 103: 104: 105: 106: 107: 108: 109:
110: public function GetTaken($UserID, $ActionID, $Limit = NULL, $Offset = 0) {
111: $CacheKey = "yaga.profile.actions.{$UserID}.{$ActionID}";
112: $Content = Gdn::Cache()->Get($CacheKey);
113:
114: if($Content == Gdn_Cache::CACHEOP_FAILURE) {
115:
116:
117: $Discussions = $this->_BaseSQL('Discussion')
118: ->Join('Reaction r', 'd.DiscussionID = r.ParentID')
119: ->Where('r.InsertUserID', $UserID)
120: ->Where('r.ActionID', $ActionID)
121: ->Where('r.ParentType', 'discussion')
122: ->OrderBy('r.DateInserted', 'DESC')
123: ->Get()->Result(DATASET_TYPE_ARRAY);
124:
125:
126: $Comments = $this->_BaseSQL('Comment')
127: ->Join('Reaction r', 'c.CommentID = r.ParentID')
128: ->Where('r.InsertUserID', $UserID)
129: ->Where('r.ActionID', $ActionID)
130: ->Where('r.ParentType', 'comment')
131: ->OrderBy('r.DateInserted', 'DESC')
132: ->Get()->Result(DATASET_TYPE_ARRAY);
133:
134: $this->JoinCategory($Comments);
135:
136:
137: $Content = $this->Union('DateInserted', array(
138: 'Discussion' => $Discussions,
139: 'Comment' => $Comments
140: ));
141: $this->Prepare($Content);
142:
143:
144: Gdn::Cache()->Store($CacheKey, $Content, array(
145: Gdn_Cache::FEATURE_EXPIRY => $this->_Expiry
146: ));
147: }
148:
149: $this->Security($Content);
150: $this->Condense($Content, $Limit, $Offset);
151:
152: return $Content;
153: }
154:
155: 156: 157: 158: 159: 160: 161: 162: 163:
164: public function GetAction($ActionID, $Limit = NULL, $Offset = 0) {
165: $CacheKey = "yaga.best.actions.{$ActionID}";
166: $Content = Gdn::Cache()->Get($CacheKey);
167:
168: if($Content == Gdn_Cache::CACHEOP_FAILURE) {
169:
170:
171: $Discussions = $this->_BaseSQL('Discussion')
172: ->Join('Reaction r', 'd.DiscussionID = r.ParentID')
173: ->Where('r.ActionID', $ActionID)
174: ->Where('r.ParentType', 'discussion')
175: ->OrderBy('r.DateInserted', 'DESC')
176: ->Get()->Result(DATASET_TYPE_ARRAY);
177:
178:
179: $Comments = $this->_BaseSQL('Comment')
180: ->Join('Reaction r', 'c.CommentID = r.ParentID')
181: ->Where('r.ActionID', $ActionID)
182: ->Where('r.ParentType', 'comment')
183: ->OrderBy('r.DateInserted', 'DESC')
184: ->Get()->Result(DATASET_TYPE_ARRAY);
185:
186: $this->JoinCategory($Comments);
187:
188:
189: $Content = $this->Union('DateInserted', array(
190: 'Discussion' => $Discussions,
191: 'Comment' => $Comments
192: ));
193: $this->Prepare($Content);
194:
195:
196: Gdn::Cache()->Store($CacheKey, $Content, array(
197: Gdn_Cache::FEATURE_EXPIRY => $this->_Expiry
198: ));
199: }
200:
201: $this->Security($Content);
202: $this->Condense($Content, $Limit, $Offset);
203:
204: return $Content;
205: }
206:
207: 208: 209: 210: 211: 212: 213: 214:
215: public function GetBest($UserID = NULL, $Limit = NULL, $Offset = 0) {
216: $CacheKey = "yaga.profile.best.{$UserID}";
217: $Content = Gdn::Cache()->Get($CacheKey);
218:
219: if($Content == Gdn_Cache::CACHEOP_FAILURE) {
220: $SQL = $this->_BaseSQL('Discussion');
221: if(!is_null($UserID)) {
222: $SQL = $SQL->Where('d.InsertUserID', $UserID);
223: }
224: $Discussions = $SQL->Get()->Result(DATASET_TYPE_ARRAY);
225:
226: $SQL = $this->_BaseSQL('Comment');
227: if(!is_null($UserID)) {
228: $SQL = $SQL->Where('c.InsertUserID', $UserID);
229: }
230: $Comments = $SQL->Get()->Result(DATASET_TYPE_ARRAY);
231:
232: $this->JoinCategory($Comments);
233:
234:
235: $Content = $this->Union('Score', array(
236: 'Discussion' => $Discussions,
237: 'Comment' => $Comments
238: ));
239: $this->Prepare($Content);
240:
241: Gdn::Cache()->Store($CacheKey, $Content, array(
242: Gdn_Cache::FEATURE_EXPIRY => $this->_Expiry
243: ));
244: }
245:
246: $this->Security($Content);
247: $this->Condense($Content, $Limit, $Offset);
248:
249: return $Content;
250: }
251:
252: 253: 254: 255: 256: 257: 258: 259:
260: public function GetRecent($Timespan = 'week', $Limit = NULL, $Offset = 0) {
261: $CacheKey = "yaga.best.last.{$Timespan}";
262: $Content = Gdn::Cache()->Get($CacheKey);
263:
264: if($Content == Gdn_Cache::CACHEOP_FAILURE) {
265: $TargetDate = date('Y-m-d H:i:s', strtotime("1 {$Timespan} ago"));
266:
267: $SQL = $this->_BaseSQL('Discussion');
268: $Discussions = $SQL->Where('d.DateUpdated >', $TargetDate)->Get()->Result(DATASET_TYPE_ARRAY);
269:
270: $SQL = $this->_BaseSQL('Comment');
271: $Comments = $SQL->Where('c.DateUpdated >', $TargetDate)->Get()->Result(DATASET_TYPE_ARRAY);
272:
273: $this->JoinCategory($Comments);
274:
275:
276: $Content = $this->Union('Score', array(
277: 'Discussion' => $Discussions,
278: 'Comment' => $Comments
279: ));
280: $this->Prepare($Content);
281:
282: Gdn::Cache()->Store($CacheKey, $Content, array(
283: Gdn_Cache::FEATURE_EXPIRY => $this->_Expiry
284: ));
285: }
286:
287: $this->Security($Content);
288: $this->Condense($Content, $Limit, $Offset);
289:
290: return $Content;
291: }
292:
293: 294: 295: 296: 297:
298: protected function JoinCategory(&$Comments) {
299: $DiscussionIDs = array();
300:
301: foreach($Comments as &$Comment) {
302: $DiscussionIDs[$Comment['DiscussionID']] = TRUE;
303: }
304: $DiscussionIDs = array_keys($DiscussionIDs);
305:
306: $Discussions = Gdn::SQL()->Select('d.*')
307: ->From('Discussion d')
308: ->WhereIn('DiscussionID', $DiscussionIDs)
309: ->Get()->Result(DATASET_TYPE_ARRAY);
310:
311: $DiscussionsByID = array();
312: foreach($Discussions as $Discussion) {
313: $DiscussionsByID[$Discussion['DiscussionID']] = $Discussion;
314: }
315: unset($Discussions);
316:
317: foreach($Comments as &$Comment) {
318: $Comment['Discussion'] = $DiscussionsByID[$Comment['DiscussionID']];
319: $Comment['CategoryID'] = GetValueR('Discussion.CategoryID', $Comment);
320: }
321: }
322:
323: 324: 325: 326: 327: 328: 329:
330: protected function Union($Field, $Sections) {
331: if(!is_array($Sections))
332: return;
333:
334: $Interleaved = array();
335: foreach($Sections as $SectionType => $Section) {
336: if(!is_array($Section))
337: continue;
338:
339: foreach($Section as $Item) {
340: $ItemField = GetValue($Field, $Item);
341: $Interleaved[$ItemField] = array_merge($Item, array('ItemType' => $SectionType));
342:
343: ksort($Interleaved);
344: }
345: }
346:
347: $Interleaved = array_reverse($Interleaved);
348: return $Interleaved;
349: }
350:
351: 352: 353: 354: 355:
356: protected function Prepare(&$Content) {
357:
358: foreach($Content as &$ContentItem) {
359: $ContentType = GetValue('ItemType', $ContentItem);
360:
361: $Replacement = array();
362: $Fields = array('DiscussionID', 'CategoryID', 'DateInserted', 'DateUpdated', 'InsertUserID', 'Body', 'Format', 'ItemType');
363:
364: switch(strtolower($ContentType)) {
365: case 'comment':
366: $Fields = array_merge($Fields, array('CommentID'));
367:
368:
369: $Replacement['Name'] = GetValueR('Discussion.Name', $ContentItem);
370: break;
371:
372: case 'discussion':
373: $Fields = array_merge($Fields, array('Name', 'Type'));
374: break;
375: }
376:
377: $Fields = array_fill_keys($Fields, TRUE);
378: $Common = array_intersect_key($ContentItem, $Fields);
379: $Replacement = array_merge($Replacement, $Common);
380: $ContentItem = $Replacement;
381:
382:
383: $UserID = GetValue('InsertUserID', $ContentItem);
384: $User = Gdn::UserModel()->GetID($UserID);
385: $ContentItem['Author'] = $User;
386: }
387: }
388:
389: 390: 391: 392: 393:
394: protected function Security(&$Content) {
395: if(!is_array($Content))
396: return;
397: $Content = array_filter($Content, array($this, 'SecurityFilter'));
398: }
399:
400: 401: 402: 403: 404: 405:
406: protected function SecurityFilter($ContentItem) {
407: $CategoryID = GetValue('CategoryID', $ContentItem, NULL);
408: if(is_null($CategoryID) || $CategoryID === FALSE) {
409: return FALSE;
410: }
411:
412: $Category = CategoryModel::Categories($CategoryID);
413: $CanView = GetValue('PermsDiscussionsView', $Category);
414: if(!$CanView) {
415: return FALSE;
416: }
417:
418: return TRUE;
419: }
420:
421: 422: 423: 424: 425: 426: 427:
428: protected function Condense(&$Content, $Limit, $Offset) {
429: $Content = array_slice($Content, $Offset, $Limit);
430: }
431:
432: }
433: