1: <?php
2:
3: 4: 5: 6: 7: 8:
9:
10: namespace rsanchez\Deep\Model;
11:
12: use Illuminate\Database\Eloquent\Model;
13: use Illuminate\Database\Eloquent\Builder;
14: use rsanchez\Deep\Model\Channel;
15: use rsanchez\Deep\Model\AbstractEntity;
16: use rsanchez\Deep\Model\JoinableTrait;
17: use rsanchez\Deep\Repository\ChannelRepository;
18: use rsanchez\Deep\Repository\SiteRepository;
19: use rsanchez\Deep\Collection\TitleCollection;
20: use rsanchez\Deep\Collection\AbstractTitleCollection;
21: use rsanchez\Deep\Hydrator\HydratorFactory;
22: use rsanchez\Deep\Relations\HasOneFromRepository;
23: use rsanchez\Deep\Model\GlobalAttributeVisibilityTrait;
24: use Carbon\Carbon;
25: use Closure;
26: use DateTime;
27:
28: 29: 30:
31: class Title extends AbstractEntity
32: {
33: use JoinableTrait, GlobalAttributeVisibilityTrait;
34:
35: 36: 37: 38: 39:
40: protected $table = 'channel_titles';
41:
42: 43: 44: 45: 46:
47: protected $primaryKey = 'entry_id';
48:
49: 50: 51: 52: 53:
54: protected static $globalHidden = [
55: 'chan',
56: 'site_id',
57: 'forum_topic_id',
58: 'ip_address',
59: 'versioning_enabled',
60: 'comments',
61: ];
62:
63: 64: 65: 66: 67:
68: protected static $globalVisible = [];
69:
70: 71: 72: 73:
74: protected $collectionClass = '\\rsanchez\\Deep\\Collection\\TitleCollection';
75:
76: 77: 78: 79:
80: protected static $channelRepository;
81:
82: 83: 84: 85:
86: protected static $siteRepository;
87:
88: 89: 90: 91:
92: public static $hydratorFactory;
93:
94: 95: 96: 97:
98: protected = array();
99:
100: 101: 102: 103: 104:
105: protected $defaultChannelName;
106:
107: 108: 109: 110:
111: public function author()
112: {
113: return $this->hasOne('\\rsanchez\\Deep\\Model\\Member', 'member_id', 'author_id');
114: }
115:
116: 117: 118: 119:
120: public function categories()
121: {
122: return $this->hasManyThrough('\\rsanchez\\Deep\\Model\\Category', '\\rsanchez\\Deep\\Model\\CategoryPosts', 'entry_id', 'cat_id');
123: }
124:
125: 126: 127: 128:
129: public function chan()
130: {
131: return new HasOneFromRepository(
132: self::$channelRepository->getModel()->newQuery(),
133: $this,
134: 'channels.channel_id',
135: 'channel_id',
136: self::$channelRepository
137: );
138: }
139:
140: 141: 142: 143:
144: public function ()
145: {
146: return $this->hasMany('\\rsanchez\\Deep\\Model\\Comment', 'entry_id', 'entry_id');
147: }
148:
149: 150: 151: 152: 153:
154: public function __call($name, $args)
155: {
156: if (isset($this->attributes[$name]) && is_callable($this->attributes[$name])) {
157: return call_user_func_array($this->attributes[$name], $args);
158: }
159:
160: return parent::__call($name, $args);
161: }
162:
163: 164: 165:
166: public function getId()
167: {
168: return $this->entry_id;
169: }
170:
171: 172: 173:
174: public function getType()
175: {
176: return 'entry';
177: }
178:
179: 180: 181: 182:
183: public function getChannelAttribute()
184: {
185: return $this->chan;
186: }
187:
188: 189: 190: 191: 192:
193: public static function setChannelRepository(ChannelRepository $channelRepository)
194: {
195: self::$channelRepository = $channelRepository;
196: }
197:
198: 199: 200: 201: 202:
203: public static function setSiteRepository(SiteRepository $siteRepository)
204: {
205: self::$siteRepository = $siteRepository;
206: }
207:
208: 209: 210: 211: 212:
213: public static function setHydratorFactory(HydratorFactory $hydratorFactory)
214: {
215: self::$hydratorFactory = $hydratorFactory;
216: }
217:
218: 219: 220:
221: protected static function joinTables()
222: {
223: return array(
224: 'members' => function ($query) {
225: $query->join('members', 'members.member_id', '=', 'channel_titles.author_id');
226: },
227: 'category_posts' => function ($query) {
228: $query->join('category_posts', 'category_posts.entry_id', '=', 'channel_titles.entry_id');
229: },
230: );
231: }
232:
233: 234: 235: 236: 237: 238: 239: 240:
241: public function newQuery($excludeDeleted = true)
242: {
243: $query = parent::newQuery($excludeDeleted);
244:
245: if ($this->defaultChannelName) {
246: $this->scopeChannel($query, $this->defaultChannelName);
247: }
248:
249: return $query;
250: }
251:
252: 253: 254: 255: 256: 257: 258: 259:
260: public function newCollection(array $models = array())
261: {
262: $method = "{$this->collectionClass}::create";
263:
264: $collection = call_user_func($method, $models, self::$channelRepository);
265:
266: if ($models) {
267: $this->hydrateCollection($collection);
268: }
269:
270: return $collection;
271: }
272:
273: 274: 275: 276: 277:
278: public function hydrateCollection(AbstractTitleCollection $collection)
279: {
280: if ($hydrators = self::$hydratorFactory->getHydrators($collection, $this->extraHydrators)) {
281:
282: foreach ($hydrators as $hydrator) {
283: $hydrator->preload($collection->getEntryIds());
284: }
285:
286:
287: foreach ($collection as $entry) {
288: foreach ($entry->channel->fields as $field) {
289: if (isset($hydrators[$field->getType()])) {
290: $hydrators[$field->getType()]->hydrate($entry, $field);
291: } else {
292: $entry->setAttribute($field->field_name, $entry->getAttribute('field_id_'.$field->field_id));
293: }
294:
295: if ($field->hasRows()) {
296: foreach ($entry->getAttribute($field->field_name) as $row) {
297: foreach ($row->getCols() as $col) {
298: if (isset($hydrators[$col->getType()])) {
299: $hydrators[$col->getType()]->hydrate($row, $col);
300: } else {
301: $row->setAttribute($col->getName(), $row->getAttribute($col->getIdentifier()));
302: }
303: }
304: }
305: }
306: }
307: }
308: }
309: }
310:
311: 312: 313:
314: public function attributesToArray()
315: {
316: $attributes = parent::attributesToArray();
317:
318: foreach (array('entry_date', 'edit_date', 'expiration_date', 'comment_expiration_date', 'recent_comment_date') as $key) {
319: if (isset($attributes[$key]) && $attributes[$key] instanceof Carbon) {
320: $attributes[$key] = (string) $attributes[$key];
321: }
322: }
323:
324: return $attributes;
325: }
326:
327: 328: 329: 330: 331: 332:
333: public function getEntryDateAttribute($value)
334: {
335: return Carbon::createFromFormat('U', $value);
336: }
337:
338: 339: 340: 341: 342: 343:
344: public function getExpirationDateAttribute($value)
345: {
346: return $value ? Carbon::createFromFormat('U', $value) : null;
347: }
348:
349: 350: 351: 352: 353: 354:
355: public function ($value)
356: {
357: return $value ? Carbon::createFromFormat('U', $value) : null;
358: }
359:
360: 361: 362: 363: 364: 365:
366: public function ($value)
367: {
368: return $value ? Carbon::createFromFormat('U', $value) : null;
369: }
370:
371: 372: 373: 374: 375: 376:
377: public function getEditDateAttribute($value)
378: {
379: return Carbon::createFromFormat('YmdHis', $value);
380: }
381:
382: 383: 384: 385: 386:
387: public function getPageUriAttribute()
388: {
389: return self::$siteRepository->getPageUri($this->entry_id);
390: }
391:
392: 393: 394: 395: 396:
397: public function getChannelNameAttribute()
398: {
399: return $this->channel->channel_name;
400: }
401:
402: 403: 404: 405: 406:
407: public function getChannelShortNameAttribute()
408: {
409: return $this->channel->channel_name;
410: }
411:
412: 413: 414: 415: 416:
417: public function getUsernameAttribute()
418: {
419: return $this->author->username;
420: }
421:
422: 423: 424: 425: 426: 427:
428: public function save(array $options = array())
429: {
430: throw new \Exception('Saving is not supported');
431: }
432:
433: 434: 435: 436: 437: 438: 439:
440: public function scopeCategory(Builder $query, $categoryId)
441: {
442: $categoryIds = is_array($categoryId) ? $categoryId : array_slice(func_get_args(), 1);
443:
444: return $query->whereHas('categories', function ($q) use ($categoryIds) {
445: $q->whereIn('categories.cat_id', $categoryIds);
446: });
447: }
448:
449: 450: 451: 452: 453: 454: 455:
456: public function scopeRelatedCategories(Builder $query, $entryId)
457: {
458: $connection = $query->getQuery()->getConnection();
459: $tablePrefix = $connection->getTablePrefix();
460:
461: return $this->requireTable($query, 'category_posts')
462: ->join($connection->raw("`{$tablePrefix}category_posts` AS `{$tablePrefix}category_posts_2`"), 'category_posts_2.cat_id', '=', 'category_posts.cat_id')
463: ->where('category_posts_2.entry_id', $entryId)
464: ->where('channel_titles.entry_id', '!=', $entryId)
465: ->groupBy('channel_titles.entry_id');
466: }
467:
468: 469: 470: 471: 472: 473: 474:
475: public function scopeRelatedCategoriesUrlTitle(Builder $query, $urlTitle)
476: {
477: $connection = $query->getQuery()->getConnection();
478: $tablePrefix = $connection->getTablePrefix();
479:
480: return $this->requireTable($query, 'category_posts')
481: ->join($connection->raw("`{$tablePrefix}category_posts` AS `{$tablePrefix}category_posts_2`"), 'category_posts_2.cat_id', '=', 'category_posts.cat_id')
482: ->join($connection->raw("`{$tablePrefix}channel_titles` AS `{$tablePrefix}channel_titles_2`"), 'channel_titles_2.entry_id', '=', 'category_posts_2.entry_id')
483: ->where('channel_titles_2.url_title', $urlTitle)
484: ->where('channel_titles.url_title', '!=', $urlTitle)
485: ->groupBy('channel_titles.entry_id');
486: }
487:
488: 489: 490: 491: 492: 493: 494:
495: public function scopeAllCategories(Builder $query, $categoryId)
496: {
497: $categoryIds = is_array($categoryId) ? $categoryId : array_slice(func_get_args(), 1);
498:
499: return $query->whereHas('categories', function ($q) use ($categoryIds) {
500:
501: $q->where(function($qq) use ($categoryIds) {
502: foreach ($categoryIds as $categoryId) {
503: $qq->orWhere('categories.cat_id', $categoryId);
504: }
505: });
506:
507: }, '>=', count($categoryIds));
508: }
509:
510: 511: 512: 513: 514: 515: 516:
517: public function scopeNotAllCategories(Builder $query, $categoryId)
518: {
519: $categoryIds = is_array($categoryId) ? $categoryId : array_slice(func_get_args(), 1);
520:
521: return $query->whereHas('categories', function ($q) use ($categoryIds) {
522:
523: $q->where(function($qq) use ($categoryIds) {
524: foreach ($categoryIds as $categoryId) {
525: $qq->orWhere('categories.cat_id', $categoryId);
526: }
527: });
528:
529: }, '<', count($categoryIds));
530: }
531:
532: 533: 534: 535: 536: 537: 538:
539: public function scopeNotCategory(Builder $query, $categoryId)
540: {
541: $categoryIds = is_array($categoryId) ? $categoryId : array_slice(func_get_args(), 1);
542:
543: return $query->whereHas('categories', function ($q) use ($categoryIds) {
544: $q->whereIn('categories.cat_id', $categoryIds);
545: }, '=', 0);
546: }
547:
548: 549: 550: 551: 552: 553: 554:
555: public function scopeCategoryName(Builder $query, $categoryName)
556: {
557: $categoryNames = is_array($categoryName) ? $categoryName : array_slice(func_get_args(), 1);
558:
559: return $query->whereHas('categories', function ($q) use ($categoryNames) {
560: $q->whereIn('categories.cat_url_title', $categoryNames);
561: });
562: }
563:
564: 565: 566: 567: 568: 569: 570:
571: public function scopeNotCategoryName(Builder $query, $categoryName)
572: {
573: $categoryNames = is_array($categoryName) ? $categoryName : array_slice(func_get_args(), 1);
574:
575: return $query->whereHas('categories', function ($q) use ($categoryNames) {
576: $q->whereIn('categories.cat_url_title', $categoryNames);
577: }, '=', 0);
578: }
579:
580: 581: 582: 583: 584: 585: 586:
587: public function scopeCategoryGroup(Builder $query, $groupId)
588: {
589: $groupIds = is_array($groupId) ? $groupId : array_slice(func_get_args(), 1);
590:
591: return $query->whereHas('categories', function ($q) use ($groupIds) {
592: $q->whereIn('categories.group_id', $groupIds);
593: });
594: }
595:
596: 597: 598: 599: 600: 601: 602:
603: public function scopeNotCategoryGroup(Builder $query, $groupId)
604: {
605: $groupIds = is_array($groupId) ? $groupId : array_slice(func_get_args(), 1);
606:
607: return $query->whereHas('categories', function ($q) use ($groupIds) {
608: $q->whereIn('categories.group_id', $groupIds);
609: }, '=', 0);
610: }
611:
612: 613: 614: 615: 616: 617: 618:
619: public function scopeChannel(Builder $query, $channelName)
620: {
621: $channelNames = is_array($channelName) ? $channelName : array_slice(func_get_args(), 1);
622:
623: $channels = self::$channelRepository->getChannelsByName($channelNames);
624:
625: $channelIds = array();
626:
627: $channels->each(function ($channel) use (&$channelIds) {
628: $channelIds[] = $channel->channel_id;
629: });
630:
631: if ($channelIds) {
632: array_unshift($channelIds, $query);
633:
634: call_user_func_array(array($this, 'scopeChannelId'), $channelIds);
635: }
636:
637: return $query;
638: }
639:
640: 641: 642: 643: 644: 645: 646:
647: public function scopeNotChannel(Builder $query, $channelName)
648: {
649: $channelNames = is_array($channelName) ? $channelName : array_slice(func_get_args(), 1);
650:
651: $channels = self::$channelRepository->getChannelsByName($channelNames);
652:
653: $channelIds = array();
654:
655: $channels->each(function ($channel) use (&$channelIds) {
656: $channelIds[] = $channel->channel_id;
657: });
658:
659: if ($channelIds) {
660: array_unshift($channelIds, $query);
661:
662: call_user_func_array(array($this, 'scopeNotChannelId'), $channelIds);
663: }
664:
665: return $query;
666: }
667:
668: 669: 670: 671: 672: 673: 674:
675: public function scopeChannelId(Builder $query, $channelId)
676: {
677: $channelIds = is_array($channelId) ? $channelId : array_slice(func_get_args(), 1);
678:
679: return $query->whereIn('channel_titles.channel_id', $channelIds);
680: }
681:
682: 683: 684: 685: 686: 687: 688:
689: public function scopeNotChannelId(Builder $query, $channelId)
690: {
691: $channelIds = is_array($channelId) ? $channelId : array_slice(func_get_args(), 1);
692:
693: return $query->whereNotIn('channel_titles.channel_id', $channelIds);
694: }
695:
696: 697: 698: 699: 700: 701: 702:
703: public function scopeAuthorId(Builder $query, $authorId)
704: {
705: $authorIds = is_array($authorId) ? $authorId : array_slice(func_get_args(), 1);
706:
707: return $query->whereIn('channel_titles.author_id', $authorIds);
708: }
709:
710: 711: 712: 713: 714: 715: 716:
717: public function scopeNotAuthorId(Builder $query, $authorId)
718: {
719: $authorIds = is_array($authorId) ? $authorId : array_slice(func_get_args(), 1);
720:
721: return $query->whereNotIn('channel_titles.author_id', $authorIds);
722: }
723:
724: 725: 726: 727: 728: 729: 730:
731: public function scopeShowExpired(Builder $query, $showExpired = true)
732: {
733: if (! $showExpired) {
734: $query->where(function ($query) {
735: return $query->where('expiration_date', '')
736: ->orWhere('expiration_date', '>', time());
737: });
738: }
739:
740: return $query;
741: }
742:
743: 744: 745: 746: 747: 748: 749:
750: public function scopeShowFutureEntries(Builder $query, $showFutureEntries = true)
751: {
752: if (! $showFutureEntries) {
753: $query->where('channel_titles.entry_date', '<=', time());
754: }
755:
756: return $query;
757: }
758:
759: 760: 761: 762: 763: 764: 765:
766: public function scopeSiteId(Builder $query, $siteId)
767: {
768: $siteIds = is_array($siteId) ? $siteId : array_slice(func_get_args(), 1);
769:
770: return $query->whereIn('channel_titles.site_id', $siteIds);
771: }
772:
773: 774: 775: 776: 777: 778: 779:
780: public function scopeFixedOrder(Builder $query, $fixedOrder)
781: {
782: $fixedOrder = is_array($fixedOrder) ? $fixedOrder : array_slice(func_get_args(), 1);
783:
784: call_user_func_array(array($this, 'scopeEntryId'), func_get_args());
785:
786: return $query->orderBy('FIELD('.implode(', ', $fixedOrder).')', 'asc');
787: }
788:
789: 790: 791: 792: 793: 794: 795:
796: public function scopeSticky(Builder $query, $sticky = true)
797: {
798: if ($sticky) {
799: $orders =& $query->getQuery()->orders;
800:
801: $order = array(
802: 'column' => 'channel_titles.sticky',
803: 'direction' => 'desc',
804: );
805:
806: if ($orders) {
807: array_unshift($orders, $order);
808: } else {
809: $orders = array($order);
810: }
811: }
812:
813: return $query;
814: }
815:
816: 817: 818: 819: 820: 821: 822:
823: public function scopeEntryId(Builder $query, $entryId)
824: {
825: $entryIds = is_array($entryId) ? $entryId : array_slice(func_get_args(), 1);
826:
827: return $query->whereIn('channel_titles.entry_id', $entryIds);
828: }
829:
830: 831: 832: 833: 834: 835: 836:
837: public function scopeNotEntryId(Builder $query, $notEntryId)
838: {
839: $notEntryIds = is_array($notEntryId) ? $notEntryId : array_slice(func_get_args(), 1);
840:
841: return $query->whereNotIn('channel_titles.entry_id', $notEntryIds);
842: }
843:
844: 845: 846: 847: 848: 849: 850:
851: public function scopeEntryIdFrom(Builder $query, $entryIdFrom)
852: {
853: return $query->where('channel_titles.entry_id', '>=', $entryIdFrom);
854: }
855:
856: 857: 858: 859: 860: 861: 862:
863: public function scopeEntryIdTo(Builder $query, $entryIdTo)
864: {
865: return $query->where('channel_titles.entry_id', '<=', $entryIdTo);
866: }
867:
868: 869: 870: 871: 872: 873: 874:
875: public function scopeGroupId(Builder $query, $groupId)
876: {
877: $groupIds = is_array($groupId) ? $groupId : array_slice(func_get_args(), 1);
878:
879: return $this->requireTable($query, 'members')->whereIn('members.group_id', $groupIds);
880: }
881:
882: 883: 884: 885: 886: 887: 888:
889: public function scopeNotGroupId(Builder $query, $notGroupId)
890: {
891: $notGroupIds = is_array($notGroupId) ? $notGroupId : array_slice(func_get_args(), 1);
892:
893: return $this->requireTable($query, 'members')->whereNotIn('members.group_id', $notGroupIds);
894: }
895:
896: 897: 898: 899: 900: 901: 902:
903: public function scopeLimit(Builder $query, $limit)
904: {
905: return $query->take($limit);
906: }
907:
908: 909: 910: 911: 912: 913: 914:
915: public function scopeOffset(Builder $query, $offset)
916: {
917: return $query->skip($offset);
918: }
919:
920: 921: 922: 923: 924: 925: 926:
927: public function scopeShowPages(Builder $query, $showPages = true)
928: {
929: if (! $showPages) {
930: $args = self::$siteRepository->getPageEntryIds();
931:
932: array_unshift($args, $query);
933:
934: call_user_func_array(array($this, 'scopeNotEntryId'), $args);
935: }
936:
937: return $query;
938: }
939:
940: 941: 942: 943: 944: 945: 946:
947: public function scopeShowPagesOnly(Builder $query, $showPagesOnly = true)
948: {
949: if ($showPagesOnly) {
950: $args = self::$siteRepository->getPageEntryIds();
951:
952: array_unshift($args, $query);
953:
954: call_user_func_array(array($this, 'scopeEntryId'), $args);
955: }
956:
957: return $query;
958: }
959:
960: 961: 962: 963: 964: 965: 966:
967: public function scopeStartOn(Builder $query, $startOn)
968: {
969: if ($startOn instanceof DateTime) {
970: $startOn = $startOn->format('U');
971: }
972:
973: return $query->where('channel_titles.entry_date', '>=', $startOn);
974: }
975:
976: 977: 978: 979: 980: 981: 982:
983: public function scopeStatus(Builder $query, $status)
984: {
985: $statuses = is_array($status) ? $status : array_slice(func_get_args(), 1);
986:
987: return $query->whereIn('channel_titles.status', $statuses);
988: }
989:
990: 991: 992: 993: 994: 995: 996:
997: public function scopeNotStatus(Builder $query, $status)
998: {
999: $statuses = is_array($status) ? $status : array_slice(func_get_args(), 1);
1000:
1001: return $query->whereNotIn('channel_titles.status', $statuses);
1002: }
1003:
1004: 1005: 1006: 1007: 1008: 1009: 1010:
1011: public function scopeStopBefore(Builder $query, $stopBefore)
1012: {
1013: if ($stopBefore instanceof DateTime) {
1014: $stopBefore = $stopBefore->format('U');
1015: }
1016:
1017: return $query->where('channel_titles.entry_date', '<', $stopBefore);
1018: }
1019:
1020: 1021: 1022: 1023: 1024: 1025: 1026:
1027: public function scopeUrlTitle(Builder $query, $urlTitle)
1028: {
1029: $urlTitles = is_array($urlTitle) ? $urlTitle : array_slice(func_get_args(), 1);
1030:
1031: return $query->whereIn('channel_titles.url_title', $urlTitles);
1032: }
1033:
1034: 1035: 1036: 1037: 1038: 1039: 1040:
1041: public function scopeUsername(Builder $query, $username)
1042: {
1043: $usernames = is_array($username) ? $username : array_slice(func_get_args(), 1);
1044:
1045: return $this->requireTable($query, 'members')->whereIn('members.username', $usernames);
1046: }
1047:
1048: 1049: 1050: 1051: 1052: 1053: 1054:
1055: public function scopeYear(Builder $query, $year)
1056: {
1057: return $query->where('channel_titles.year', $year);
1058: }
1059:
1060: 1061: 1062: 1063: 1064: 1065: 1066:
1067: public function scopeMonth(Builder $query, $month)
1068: {
1069: return $query->where('channel_titles.month', str_pad($month, 2, '0', STR_PAD_LEFT));
1070: }
1071:
1072: 1073: 1074: 1075: 1076: 1077: 1078:
1079: public function scopeDay(Builder $query, $day)
1080: {
1081: return $query->where('channel_titles.day', str_pad($day, 2, '0', STR_PAD_LEFT));
1082: }
1083:
1084: 1085: 1086: 1087: 1088: 1089: 1090: 1091: 1092:
1093: protected function scopeArrayFromString(Builder $query, $string, $scope)
1094: {
1095: if ($not = strncmp($string, 'not ', 4) === 0) {
1096: $string = substr($string, 4);
1097: }
1098:
1099: $args = explode('|', $string);
1100:
1101: $method = 'scope'.$scope;
1102:
1103: if ($not && method_exists($this, 'scopeNot'.$scope)) {
1104: $method = 'scopeNot'.$scope;
1105: }
1106:
1107: array_unshift($args, $query);
1108:
1109: return call_user_func_array(array($this, $method), $args);
1110: }
1111:
1112: 1113: 1114: 1115: 1116: 1117: 1118:
1119: public function scopeAuthorIdString(Builder $query, $string)
1120: {
1121: return $this->scopeArrayFromString($query, $string, 'AuthorId');
1122: }
1123:
1124: 1125: 1126: 1127: 1128: 1129: 1130:
1131: public function scopeCategoryString(Builder $query, $string)
1132: {
1133: if ($not = strncmp($string, 'not ', 4) === 0) {
1134: $string = substr($string, 4);
1135: }
1136:
1137: $type = strpos($string, '&') !== false ? '&' : '|';
1138:
1139: $args = explode($type, $string);
1140:
1141: if ($type === '&') {
1142: $method = $not ? 'scopeNotAllCategories' : 'scopeAllCategories';
1143: } else {
1144: $method = $not ? 'scopeNotCategory' : 'scopeCategory';
1145: }
1146:
1147: array_unshift($args, $query);
1148:
1149: return call_user_func_array(array($this, $method), $args);
1150: }
1151:
1152: 1153: 1154: 1155: 1156: 1157: 1158:
1159: public function scopeCategoryGroupString(Builder $query, $string)
1160: {
1161: return $this->scopeArrayFromString($query, $string, 'CategoryGroup');
1162: }
1163:
1164: 1165: 1166: 1167: 1168: 1169: 1170:
1171: public function scopeCategoryNameString(Builder $query, $string)
1172: {
1173: return $this->scopeArrayFromString($query, $string, 'CategoryName');
1174: }
1175:
1176: 1177: 1178: 1179: 1180: 1181: 1182:
1183: public function scopeChannelString(Builder $query, $string)
1184: {
1185: return $this->scopeArrayFromString($query, $string, 'Channel');
1186: }
1187:
1188: 1189: 1190: 1191: 1192: 1193: 1194:
1195: public function scopeEntryIdString(Builder $query, $string)
1196: {
1197: return $this->scopeArrayFromString($query, $string, 'EntryId');
1198: }
1199:
1200: 1201: 1202: 1203: 1204: 1205: 1206:
1207: public function scopeFixedOrderString(Builder $query, $string)
1208: {
1209: return $this->scopeArrayFromString($query, $string, 'FixedOrder');
1210: }
1211:
1212: 1213: 1214: 1215: 1216: 1217: 1218:
1219: public function scopeGroupIdString(Builder $query, $string)
1220: {
1221: return $this->scopeArrayFromString($query, $string, 'GroupId');
1222: }
1223:
1224: 1225: 1226: 1227: 1228: 1229: 1230:
1231: public function scopeShowExpiredString(Builder $query, $string)
1232: {
1233: return $this->scopeShowExpired($query, $string === 'yes');
1234: }
1235:
1236: 1237: 1238: 1239: 1240: 1241: 1242:
1243: public function scopeShowFutureEntriesString(Builder $query, $string)
1244: {
1245: return $this->scopeShowFutureEntries($query, $string === 'yes');
1246: }
1247:
1248: 1249: 1250: 1251: 1252: 1253: 1254:
1255: public function scopeShowPagesString(Builder $query, $string)
1256: {
1257: if ($string === 'only') {
1258: return $this->scopeShowPagesOnly($query);
1259: }
1260:
1261: return $this->scopeShowPages($query, $string === 'yes');
1262: }
1263:
1264: 1265: 1266: 1267: 1268: 1269: 1270:
1271: public function scopeStatusString(Builder $query, $string)
1272: {
1273: return $this->scopeArrayFromString($query, $string, 'Status');
1274: }
1275:
1276: 1277: 1278: 1279: 1280: 1281: 1282:
1283: public function scopeStickyString(Builder $query, $string)
1284: {
1285: return $this->scopeSticky($query, $string === 'yes');
1286: }
1287:
1288: 1289: 1290: 1291: 1292: 1293: 1294:
1295: public function scopeUrlTitleString(Builder $query, $string)
1296: {
1297: return $this->scopeArrayFromString($query, $string, 'UrlTitle');
1298: }
1299:
1300: 1301: 1302: 1303: 1304: 1305: 1306:
1307: public function scopeUsernameString(Builder $query, $string)
1308: {
1309: return $this->scopeArrayFromString($query, $string, 'Username');
1310: }
1311:
1312: 1313: 1314: 1315: 1316: 1317: 1318:
1319: public function scopeWithCategories(Builder $query, Closure $callback = null)
1320: {
1321: $with = $callback ? array('categories' => $callback) : 'categories';
1322:
1323: return $query->with($with);
1324: }
1325:
1326: 1327: 1328: 1329: 1330: 1331: 1332:
1333: public function scopeWithCategoryFields(Builder $query, Closure $callback = null)
1334: {
1335: return $this->scopeWithCategories($query, function ($query) use ($callback) {
1336: if ($callback) {
1337: $callback($query);
1338: }
1339:
1340: return $query->withFields();
1341: });
1342: }
1343:
1344: 1345: 1346: 1347: 1348: 1349: 1350:
1351: public function scopeWithAuthor(Builder $query, Closure $callback = null)
1352: {
1353: $with = $callback ? array('author' => $callback) : 'author';
1354:
1355: return $query->with($with);
1356: }
1357:
1358: 1359: 1360: 1361: 1362: 1363: 1364:
1365: public function scopeWithAuthorFields(Builder $query, Closure $callback = null)
1366: {
1367: return $this->scopeWithAuthor($query, function ($query) use ($callback) {
1368: if ($callback) {
1369: $callback($query);
1370: }
1371:
1372: return $query->withFields();
1373: });
1374: }
1375:
1376: 1377: 1378: 1379: 1380: 1381: 1382:
1383: public function (Builder $query, Closure $callback = null)
1384: {
1385: return $query->with(array('comments' => function ($query) use ($callback) {
1386: if ($callback) {
1387: $callback($query);
1388: }
1389:
1390: return $query->with('author');
1391: }));
1392: }
1393:
1394: 1395: 1396: 1397: 1398: 1399: 1400: 1401:
1402: public function scopeDynamicParameters(Builder $query, array $allowedParameters, array $request)
1403: {
1404: foreach ($allowedParameters as $key) {
1405: if (isset($request[$key])) {
1406: $this->scopeTagparam($query, $key, $request[$key]);
1407: }
1408: }
1409:
1410: return $query;
1411: }
1412:
1413: 1414: 1415: 1416: 1417: 1418:
1419: public function scopeWithParents(Builder $query)
1420: {
1421: $this->extraHydrators[] = 'parents';
1422:
1423: return $query;
1424: }
1425:
1426: 1427: 1428: 1429: 1430: 1431:
1432: public function scopeWithSiblings(Builder $query)
1433: {
1434: $this->extraHydrators[] = 'siblings';
1435:
1436: return $query;
1437: }
1438:
1439: 1440: 1441: 1442: 1443: 1444: 1445: 1446:
1447: public function scopeTagparam(Builder $query, $key, $value)
1448: {
1449: 1450: 1451: 1452:
1453: static $parameterMap = array(
1454: 'author_id' => 'authorIdString',
1455: 'cat_limit' => 'catLimit',
1456: 'category' => 'categoryString',
1457: 'category_name' => 'categoryNameString',
1458: 'category_group' => 'categoryGroupString',
1459: 'channel' => 'channelString',
1460: 'entry_id' => 'entryIdString',
1461: 'entry_id_from' => 'entryIdFrom',
1462: 'entry_id_fo' => 'entryIdTo',
1463: 'fixed_order' => 'fixedOrderString',
1464: 'group_id' => 'groupIdString',
1465: 'limit' => 'limit',
1466: 'offset' => 'offset',
1467: 'show_expired' => 'showExpiredString',
1468: 'show_future_entries' => 'showFutureEntriesString',
1469: 'show_pages' => 'showPagesString',
1470: 'start_day' => 'startDay',
1471: 'start_on' => 'startOn',
1472: 'status' => 'statusString',
1473: 'sticky' => 'stickyString',
1474: 'stop_before' => 'stopBefore',
1475:
1476: 'url_title' => 'urlTitleString',
1477: 'username' => 'usernameString',
1478: 'year' => 'year',
1479: 'month' => 'month',
1480: 'day' => 'day',
1481: );
1482:
1483: if (! array_key_exists($key, $parameterMap)) {
1484: return $query;
1485: }
1486:
1487: $method = 'scope'.ucfirst($parameterMap[$key]);
1488:
1489: return $this->$method($query, $value);
1490: }
1491:
1492: 1493: 1494: 1495: 1496: 1497: 1498: 1499:
1500: public function scopeTagparams(Builder $query, array $parameters, array $request = array())
1501: {
1502:
1503: if (! empty($parameters['orderby'])) {
1504: $directions = isset($parameters['sort']) ? explode('|', $parameters['sort']) : null;
1505:
1506: foreach (explode('|', $parameters['orderby']) as $i => $column) {
1507: $direction = isset($directions[$i]) ? $directions[$i] : 'asc';
1508: $query->orderBy($column, $direction);
1509: }
1510: }
1511:
1512: if (isset($parameters['dynamic_parameters'])) {
1513: $this->scopeDynamicParameters(
1514: $query,
1515: explode('|', $parameters['dynamic_parameters']),
1516: $request
1517: );
1518: }
1519:
1520: foreach ($parameters as $key => $value) {
1521: $this->scopeTagparam($query, $key, $value);
1522: }
1523:
1524: return $query;
1525: }
1526: }
1527: