Overview

Namespaces

  • rsanchez
    • Deep
      • App
        • EE
        • Laravel
          • Facade
      • Collection
      • Hydrator
      • Model
      • Plugin
      • Relations
      • Repository

Classes

  • AbstractEntity
  • AbstractField
  • AbstractProperty
  • Asset
  • Category
  • CategoryField
  • CategoryPosts
  • Channel
  • Comment
  • Entry
  • Field
  • Fieldtype
  • File
  • GridCol
  • GridRow
  • JoinableScope
  • MatrixCol
  • MatrixRow
  • Member
  • MemberField
  • PlayaEntry
  • RelationshipEntry
  • Site
  • Title
  • UploadPref

Interfaces

  • FileInterface

Traits

  • GlobalAttributeVisibilityTrait
  • JoinableTrait
  • Overview
  • Namespace
  • Class
  • Tree
   1: <?php
   2: 
   3: /**
   4:  * Deep
   5:  *
   6:  * @package      rsanchez\Deep
   7:  * @author       Rob Sanchez <info@robsanchez.com>
   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:  * Model for the channel_titles table
  30:  */
  31: class Title extends AbstractEntity
  32: {
  33:     use JoinableTrait, GlobalAttributeVisibilityTrait;
  34: 
  35:     /**
  36:      * {@inheritdoc}
  37:      *
  38:      * @var string
  39:      */
  40:     protected $table = 'channel_titles';
  41: 
  42:     /**
  43:      * {@inheritdoc}
  44:      *
  45:      * @var string
  46:      */
  47:     protected $primaryKey = 'entry_id';
  48: 
  49:     /**
  50:      * The attributes that should be hidden for arrays.
  51:      *
  52:      * @var array
  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:      * The attributes that should be visible in arrays.
  65:      *
  66:      * @var array
  67:      */
  68:     protected static $globalVisible = [];
  69: 
  70:     /**
  71:      * The class used when creating a new Collection
  72:      * @var string
  73:      */
  74:     protected $collectionClass = '\\rsanchez\\Deep\\Collection\\TitleCollection';
  75: 
  76:     /**
  77:      * Global Channel Repository
  78:      * @var \rsanchez\Deep\Repository\ChannelRepository
  79:      */
  80:     protected static $channelRepository;
  81: 
  82:     /**
  83:      * Global Site Repository
  84:      * @var \rsanchez\Deep\Repository\SiteRepository
  85:      */
  86:     protected static $siteRepository;
  87: 
  88:     /**
  89:      * Hydrator Factory
  90:      * @var \rsanchez\Deep\Hydrator\Factory
  91:      */
  92:     public static $hydratorFactory;
  93: 
  94:     /**
  95:      * List of extra hydrators to load (e.g. parents or siblings)
  96:      * @var array
  97:      */
  98:     protected $extraHydrators = array();
  99: 
 100:     /**
 101:      * When extending this class, set this property to automatically
 102:      * load from the specified channel
 103:      * @var string|null
 104:      */
 105:     protected $defaultChannelName;
 106: 
 107:     /**
 108:      * Define the Author Eloquent relationship
 109:      * @return \Illuminate\Database\Eloquent\Relations\HasOne
 110:      */
 111:     public function author()
 112:     {
 113:         return $this->hasOne('\\rsanchez\\Deep\\Model\\Member', 'member_id', 'author_id');
 114:     }
 115: 
 116:     /**
 117:      * Define the Categories Eloquent relationship
 118:      * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
 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:      * Define the Channel Eloquent relationship
 127:      * @return \rsanchez\Deep\Relations\HasOneFromRepository
 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:      * Define the Comments Eloquent relationship
 142:      * @return \Illuminate\Database\Eloquent\Relations\HasMany
 143:      */
 144:     public function comments()
 145:     {
 146:         return $this->hasMany('\\rsanchez\\Deep\\Model\\Comment', 'entry_id', 'entry_id');
 147:     }
 148: 
 149:     /**
 150:      * {@inheritdoc}
 151:      *
 152:      * Invoke any invokeable attributes
 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:      * {@inheritdoc}
 165:      */
 166:     public function getId()
 167:     {
 168:         return $this->entry_id;
 169:     }
 170: 
 171:     /**
 172:      * {@inheritdoc}
 173:      */
 174:     public function getType()
 175:     {
 176:         return 'entry';
 177:     }
 178: 
 179:     /**
 180:      * Alias chan to channel
 181:      * @var \rsanchez\Deep\Model\Channel
 182:      */
 183:     public function getChannelAttribute()
 184:     {
 185:         return $this->chan;
 186:     }
 187: 
 188:     /**
 189:      * Set the global ChannelRepository
 190:      * @param  \rsanchez\Deep\Repository\ChannelRepository $channelRepository
 191:      * @return void
 192:      */
 193:     public static function setChannelRepository(ChannelRepository $channelRepository)
 194:     {
 195:         self::$channelRepository = $channelRepository;
 196:     }
 197: 
 198:     /**
 199:      * Set the global SiteRepository
 200:      * @param  \rsanchez\Deep\Repository\SiteRepository $siteRepository
 201:      * @return void
 202:      */
 203:     public static function setSiteRepository(SiteRepository $siteRepository)
 204:     {
 205:         self::$siteRepository = $siteRepository;
 206:     }
 207: 
 208:     /**
 209:      * Set the global HydratorFactory
 210:      * @param  \rsanchez\Deep\Repository\HydratorFactory $hydratorFactory
 211:      * @return void
 212:      */
 213:     public static function setHydratorFactory(HydratorFactory $hydratorFactory)
 214:     {
 215:         self::$hydratorFactory = $hydratorFactory;
 216:     }
 217: 
 218:     /**
 219:      * {@inheritdoc}
 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:      * {@inheritdoc}
 235:      *
 236:      * Joins with the channel data table, and eager load channels, fields and fieldtypes
 237:      *
 238:      * @param  boolean                               $excludeDeleted
 239:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * {@inheritdoc}
 254:      *
 255:      * Hydrate the collection after creation
 256:      *
 257:      * @param  array                                     $models
 258:      * @return \rsanchez\Deep\Collection\TitleCollection
 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:      * Loop through all the hydrators to set Entry custom field attributes
 275:      * @param  \rsanchez\Deep\Collection\TitleCollection $collection
 276:      * @return void
 277:      */
 278:     public function hydrateCollection(AbstractTitleCollection $collection)
 279:     {
 280:         if ($hydrators = self::$hydratorFactory->getHydrators($collection, $this->extraHydrators)) {
 281:             // loop through the hydrators for preloading
 282:             foreach ($hydrators as $hydrator) {
 283:                 $hydrator->preload($collection->getEntryIds());
 284:             }
 285: 
 286:             // loop again to actually hydrate
 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:      * {@inheritdoc}
 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:      * Get the entry_date column as a Carbon object
 329:      *
 330:      * @param  int            $value unix time
 331:      * @return \Carbon\Carbon
 332:      */
 333:     public function getEntryDateAttribute($value)
 334:     {
 335:         return Carbon::createFromFormat('U', $value);
 336:     }
 337: 
 338:     /**
 339:      * Get the expiration_date column as a Carbon object, or null if there is no expiration date
 340:      *
 341:      * @param  int                 $value unix time
 342:      * @return \Carbon\Carbon|null
 343:      */
 344:     public function getExpirationDateAttribute($value)
 345:     {
 346:         return $value ? Carbon::createFromFormat('U', $value) : null;
 347:     }
 348: 
 349:     /**
 350:      * Get the comment_expiration_date column as a Carbon object, or null if there is no expiration date
 351:      *
 352:      * @param  int                 $value unix time
 353:      * @return \Carbon\Carbon|null
 354:      */
 355:     public function getCommentExpirationDateAttribute($value)
 356:     {
 357:         return $value ? Carbon::createFromFormat('U', $value) : null;
 358:     }
 359: 
 360:     /**
 361:      * Get the recent_comment_date column as a Carbon object, or null if there is no expiration date
 362:      *
 363:      * @param  int                 $value unix time
 364:      * @return \Carbon\Carbon|null
 365:      */
 366:     public function getRecentCommentDateAttribute($value)
 367:     {
 368:         return $value ? Carbon::createFromFormat('U', $value) : null;
 369:     }
 370: 
 371:     /**
 372:      * Get the edit_date column as a Carbon object
 373:      *
 374:      * @param  int            $value unix time
 375:      * @return \Carbon\Carbon
 376:      */
 377:     public function getEditDateAttribute($value)
 378:     {
 379:         return Carbon::createFromFormat('YmdHis', $value);
 380:     }
 381: 
 382:     /**
 383:      * Get the page_uri of the entry
 384:      *
 385:      * @return string|null
 386:      */
 387:     public function getPageUriAttribute()
 388:     {
 389:         return self::$siteRepository->getPageUri($this->entry_id);
 390:     }
 391: 
 392:     /**
 393:      * Get the channel_name of the entry's channel
 394:      *
 395:      * @return string
 396:      */
 397:     public function getChannelNameAttribute()
 398:     {
 399:         return $this->channel->channel_name;
 400:     }
 401: 
 402:     /**
 403:      * Get the channel_name of the entry's channel
 404:      *
 405:      * @return string
 406:      */
 407:     public function getChannelShortNameAttribute()
 408:     {
 409:         return $this->channel->channel_name;
 410:     }
 411: 
 412:     /**
 413:      * Get the username of the entry's author
 414:      *
 415:      * @return string
 416:      */
 417:     public function getUsernameAttribute()
 418:     {
 419:         return $this->author->username;
 420:     }
 421: 
 422:     /**
 423:      * Save the entry (not yet supported)
 424:      *
 425:      * @param  array $options
 426:      * @return void
 427:      */
 428:     public function save(array $options = array())
 429:     {
 430:         throw new \Exception('Saving is not supported');
 431:     }
 432: 
 433:     /**
 434:      * Filter by Category ID
 435:      *
 436:      * @param  \Illuminate\Database\Eloquent\Builder $query
 437:      * @param  dynamic  string                       $categoryId
 438:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Get entries that are share one or more categories with the specified entry ID
 451:      *
 452:      * @param  \Illuminate\Database\Eloquent\Builder $query
 453:      * @param  int                                   $entryId
 454:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Get entries that are share one or more categories with the specified entry url title
 470:      *
 471:      * @param  \Illuminate\Database\Eloquent\Builder $query
 472:      * @param  string                                $urlTitle
 473:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter out entries without all Category IDs
 490:      *
 491:      * @param  \Illuminate\Database\Eloquent\Builder $query
 492:      * @param  dynamic  string                       $categoryId
 493:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter out entries without all Category IDs
 512:      *
 513:      * @param  \Illuminate\Database\Eloquent\Builder $query
 514:      * @param  dynamic  string                       $categoryId
 515:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by not Category ID
 534:      *
 535:      * @param  \Illuminate\Database\Eloquent\Builder $query
 536:      * @param  dynamic  string                       $categoryId
 537:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Category Name
 550:      *
 551:      * @param  \Illuminate\Database\Eloquent\Builder $query
 552:      * @param  dynamic  string                       $categoryName
 553:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by not Category Name
 566:      *
 567:      * @param  \Illuminate\Database\Eloquent\Builder $query
 568:      * @param  dynamic  string                       $categoryName
 569:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Category Group
 582:      *
 583:      * @param  \Illuminate\Database\Eloquent\Builder $query
 584:      * @param  dynamic  string                       $groupId
 585:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Not Category Group
 598:      *
 599:      * @param  \Illuminate\Database\Eloquent\Builder $query
 600:      * @param  dynamic  string                       $groupId
 601:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Channel Name
 614:      *
 615:      * @param  \Illuminate\Database\Eloquent\Builder $query
 616:      * @param  dynamic  string                       $channelName
 617:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by not Channel Name
 642:      *
 643:      * @param  \Illuminate\Database\Eloquent\Builder $query
 644:      * @param  dynamic  string                       $channelName
 645:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Channel ID
 670:      *
 671:      * @param  \Illuminate\Database\Eloquent\Builder $query
 672:      * @param  dynamic  int                          $channelId
 673:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by not Channel ID
 684:      *
 685:      * @param  \Illuminate\Database\Eloquent\Builder $query
 686:      * @param  dynamic  int                          $channelId
 687:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Author ID
 698:      *
 699:      * @param  \Illuminate\Database\Eloquent\Builder $query
 700:      * @param  dynamic  int                          $authorId
 701:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by not Author ID
 712:      *
 713:      * @param  \Illuminate\Database\Eloquent\Builder $query
 714:      * @param  dynamic  int                          $authorId
 715:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter out Expired Entries
 726:      *
 727:      * @param  \Illuminate\Database\Eloquent\Builder $query
 728:      * @param  bool                                  $showExpired
 729:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter out Future Entries
 745:      *
 746:      * @param  \Illuminate\Database\Eloquent\Builder $query
 747:      * @param  bool                                  $showFutureEntries
 748:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by site ID
 761:      *
 762:      * @param  \Illuminate\Database\Eloquent\Builder $query
 763:      * @param  int                                   $siteId
 764:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Set a Fixed Order
 775:      *
 776:      * @param  \Illuminate\Database\Eloquent\Builder $query
 777:      * @param  dynamic  int                          $fixedOrder
 778:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Set Sticky Entries to appear first
 791:      *
 792:      * @param  \Illuminate\Database\Eloquent\Builder $query
 793:      * @param  bool                                  $sticky
 794:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Entry ID
 818:      *
 819:      * @param  \Illuminate\Database\Eloquent\Builder $query
 820:      * @param  dynamic  string                       $entryId
 821:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Not Entry ID
 832:      *
 833:      * @param  \Illuminate\Database\Eloquent\Builder $query
 834:      * @param  dynamic  string                       $notEntryId
 835:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter out entries before the specified Entry ID
 846:      *
 847:      * @param  \Illuminate\Database\Eloquent\Builder $query
 848:      * @param  int                                   $entryIdFrom
 849:      * @return \Illuminate\Database\Eloquent\Builder
 850:      */
 851:     public function scopeEntryIdFrom(Builder $query, $entryIdFrom)
 852:     {
 853:         return $query->where('channel_titles.entry_id', '>=', $entryIdFrom);
 854:     }
 855: 
 856:     /**
 857:      * Filter out entries after the specified Entry ID
 858:      *
 859:      * @param  \Illuminate\Database\Eloquent\Builder $query
 860:      * @param  int                                   $entryIdTo
 861:      * @return \Illuminate\Database\Eloquent\Builder
 862:      */
 863:     public function scopeEntryIdTo(Builder $query, $entryIdTo)
 864:     {
 865:         return $query->where('channel_titles.entry_id', '<=', $entryIdTo);
 866:     }
 867: 
 868:     /**
 869:      * Filter by Member Group ID
 870:      *
 871:      * @param  \Illuminate\Database\Eloquent\Builder $query
 872:      * @param  dynamic  int                          $groupId
 873:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Not Member Group ID
 884:      *
 885:      * @param  \Illuminate\Database\Eloquent\Builder $query
 886:      * @param  dynamic  int                          $notGroupId
 887:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Limit the number of results
 898:      *
 899:      * @param  \Illuminate\Database\Eloquent\Builder $query
 900:      * @param  int                                   $limit
 901:      * @return \Illuminate\Database\Eloquent\Builder
 902:      */
 903:     public function scopeLimit(Builder $query, $limit)
 904:     {
 905:         return $query->take($limit);
 906:     }
 907: 
 908:     /**
 909:      * Offset the results
 910:      *
 911:      * @param  \Illuminate\Database\Eloquent\Builder $query
 912:      * @param  int                                   $offset
 913:      * @return \Illuminate\Database\Eloquent\Builder
 914:      */
 915:     public function scopeOffset(Builder $query, $offset)
 916:     {
 917:         return $query->skip($offset);
 918:     }
 919: 
 920:     /**
 921:      * Filter by Page
 922:      *
 923:      * @param  \Illuminate\Database\Eloquent\Builder $query
 924:      * @param  bool|string                           $showPages
 925:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Pages Only
 942:      *
 943:      * @param  \Illuminate\Database\Eloquent\Builder $query
 944:      * @param  bool|string                           $showPagesOnly
 945:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter out entries before the specified date
 962:      *
 963:      * @param  \Illuminate\Database\Eloquent\Builder $query
 964:      * @param  int|DateTime                          $startOn unix time
 965:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Entry Status
 978:      *
 979:      * @param  \Illuminate\Database\Eloquent\Builder $query
 980:      * @param  dynamic  string                       $status
 981:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter by Entry Status
 992:      *
 993:      * @param  \Illuminate\Database\Eloquent\Builder $query
 994:      * @param  dynamic  string                       $status
 995:      * @return \Illuminate\Database\Eloquent\Builder
 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:      * Filter out entries after the specified date
1006:      *
1007:      * @param  \Illuminate\Database\Eloquent\Builder $query
1008:      * @param  int|DateTime                          $stopBefore unix time
1009:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Filter by URL Title
1022:      *
1023:      * @param  \Illuminate\Database\Eloquent\Builder $query
1024:      * @param  dynamic  string                       $urlTitle
1025:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Filter by Member Username
1036:      *
1037:      * @param  \Illuminate\Database\Eloquent\Builder $query
1038:      * @param  dynamic  string                       $username
1039:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Filter by Year
1050:      *
1051:      * @param  \Illuminate\Database\Eloquent\Builder $query
1052:      * @param  int                                   $year
1053:      * @return \Illuminate\Database\Eloquent\Builder
1054:      */
1055:     public function scopeYear(Builder $query, $year)
1056:     {
1057:         return $query->where('channel_titles.year', $year);
1058:     }
1059: 
1060:     /**
1061:      * Filter by Month
1062:      *
1063:      * @param  \Illuminate\Database\Eloquent\Builder $query
1064:      * @param  string|int                            $month
1065:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Filter by Day
1074:      *
1075:      * @param  \Illuminate\Database\Eloquent\Builder $query
1076:      * @param  string|int                            $day
1077:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Call the specified scope, exploding a pipe-delimited string into an array
1086:      * Calls the not version of the scope if the string begins with not
1087:      * eg  'not 4|5|6'
1088:      *
1089:      * @param \Illuminate\Database\Eloquent\Builder $query
1090:      * @param string                                $string ex '4|5|6' 'not 4|5|6'
1091:      * @param string                                $scope  the name of the scope, ex. AuthorId
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:      * Filter by Author ID string parameter
1114:      *
1115:      * @param  \Illuminate\Database\Eloquent\Builder $query
1116:      * @param  string                                $string
1117:      * @return \Illuminate\Database\Eloquent\Builder
1118:      */
1119:     public function scopeAuthorIdString(Builder $query, $string)
1120:     {
1121:         return $this->scopeArrayFromString($query, $string, 'AuthorId');
1122:     }
1123: 
1124:     /**
1125:      * Filter by Category string parameter
1126:      *
1127:      * @param  \Illuminate\Database\Eloquent\Builder $query
1128:      * @param  string                                $string
1129:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Filter by Category Group string parameter
1154:      *
1155:      * @param  \Illuminate\Database\Eloquent\Builder $query
1156:      * @param  string                                $string
1157:      * @return \Illuminate\Database\Eloquent\Builder
1158:      */
1159:     public function scopeCategoryGroupString(Builder $query, $string)
1160:     {
1161:         return $this->scopeArrayFromString($query, $string, 'CategoryGroup');
1162:     }
1163: 
1164:     /**
1165:      * Filter by Category Name string parameter
1166:      *
1167:      * @param  \Illuminate\Database\Eloquent\Builder $query
1168:      * @param  string                                $string
1169:      * @return \Illuminate\Database\Eloquent\Builder
1170:      */
1171:     public function scopeCategoryNameString(Builder $query, $string)
1172:     {
1173:         return $this->scopeArrayFromString($query, $string, 'CategoryName');
1174:     }
1175: 
1176:     /**
1177:      * Filter by Channel string parameter
1178:      *
1179:      * @param  \Illuminate\Database\Eloquent\Builder $query
1180:      * @param  string                                $string
1181:      * @return \Illuminate\Database\Eloquent\Builder
1182:      */
1183:     public function scopeChannelString(Builder $query, $string)
1184:     {
1185:         return $this->scopeArrayFromString($query, $string, 'Channel');
1186:     }
1187: 
1188:     /**
1189:      * Filter by Entry ID string parameter
1190:      *
1191:      * @param  \Illuminate\Database\Eloquent\Builder $query
1192:      * @param  string                                $string
1193:      * @return \Illuminate\Database\Eloquent\Builder
1194:      */
1195:     public function scopeEntryIdString(Builder $query, $string)
1196:     {
1197:         return $this->scopeArrayFromString($query, $string, 'EntryId');
1198:     }
1199: 
1200:     /**
1201:      * Filter by Fixed Order string parameter
1202:      *
1203:      * @param  \Illuminate\Database\Eloquent\Builder $query
1204:      * @param  string                                $string
1205:      * @return \Illuminate\Database\Eloquent\Builder
1206:      */
1207:     public function scopeFixedOrderString(Builder $query, $string)
1208:     {
1209:         return $this->scopeArrayFromString($query, $string, 'FixedOrder');
1210:     }
1211: 
1212:     /**
1213:      * Filter by Member Group ID string parameter
1214:      *
1215:      * @param  \Illuminate\Database\Eloquent\Builder $query
1216:      * @param  string                                $string
1217:      * @return \Illuminate\Database\Eloquent\Builder
1218:      */
1219:     public function scopeGroupIdString(Builder $query, $string)
1220:     {
1221:         return $this->scopeArrayFromString($query, $string, 'GroupId');
1222:     }
1223: 
1224:     /**
1225:      * Filter by Show Expired string parameter
1226:      *
1227:      * @param  \Illuminate\Database\Eloquent\Builder $query
1228:      * @param  string                                $string
1229:      * @return \Illuminate\Database\Eloquent\Builder
1230:      */
1231:     public function scopeShowExpiredString(Builder $query, $string)
1232:     {
1233:         return $this->scopeShowExpired($query, $string === 'yes');
1234:     }
1235: 
1236:     /**
1237:      * Filter by Show Future Entries string parameter
1238:      *
1239:      * @param  \Illuminate\Database\Eloquent\Builder $query
1240:      * @param  string                                $string
1241:      * @return \Illuminate\Database\Eloquent\Builder
1242:      */
1243:     public function scopeShowFutureEntriesString(Builder $query, $string)
1244:     {
1245:         return $this->scopeShowFutureEntries($query, $string === 'yes');
1246:     }
1247: 
1248:     /**
1249:      * Filter by Show Pages string parameter
1250:      *
1251:      * @param  \Illuminate\Database\Eloquent\Builder $query
1252:      * @param  string                                $string
1253:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Filter by Status string parameter
1266:      *
1267:      * @param  \Illuminate\Database\Eloquent\Builder $query
1268:      * @param  string                                $string
1269:      * @return \Illuminate\Database\Eloquent\Builder
1270:      */
1271:     public function scopeStatusString(Builder $query, $string)
1272:     {
1273:         return $this->scopeArrayFromString($query, $string, 'Status');
1274:     }
1275: 
1276:     /**
1277:      * Filter by Sticky string parameter
1278:      *
1279:      * @param  \Illuminate\Database\Eloquent\Builder $query
1280:      * @param  string                                $string
1281:      * @return \Illuminate\Database\Eloquent\Builder
1282:      */
1283:     public function scopeStickyString(Builder $query, $string)
1284:     {
1285:         return $this->scopeSticky($query, $string === 'yes');
1286:     }
1287: 
1288:     /**
1289:      * Filter by URL Title string parameter
1290:      *
1291:      * @param  \Illuminate\Database\Eloquent\Builder $query
1292:      * @param  string                                $string
1293:      * @return \Illuminate\Database\Eloquent\Builder
1294:      */
1295:     public function scopeUrlTitleString(Builder $query, $string)
1296:     {
1297:         return $this->scopeArrayFromString($query, $string, 'UrlTitle');
1298:     }
1299: 
1300:     /**
1301:      * Filter by Username string parameter
1302:      *
1303:      * @param  \Illuminate\Database\Eloquent\Builder $query
1304:      * @param  string                                $string
1305:      * @return \Illuminate\Database\Eloquent\Builder
1306:      */
1307:     public function scopeUsernameString(Builder $query, $string)
1308:     {
1309:         return $this->scopeArrayFromString($query, $string, 'Username');
1310:     }
1311: 
1312:     /**
1313:      * Eager load categories
1314:      *
1315:      * @param  \Illuminate\Database\Eloquent\Builder $query
1316:      * @param  Closure|null                          $callback eager load constraint
1317:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Eager load categories with custom fields
1328:      *
1329:      * @param  \Illuminate\Database\Eloquent\Builder $query
1330:      * @param  Closure|null                          $callback eager load constraint
1331:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Eager load author
1346:      *
1347:      * @param  \Illuminate\Database\Eloquent\Builder $query
1348:      * @param  Closure|null                          $callback eager load constraint
1349:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Eager load author with custom fields
1360:      *
1361:      * @param  \Illuminate\Database\Eloquent\Builder $query
1362:      * @param  Closure|null                          $callback eager load constraint
1363:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Eager load author
1378:      *
1379:      * @param  \Illuminate\Database\Eloquent\Builder $query
1380:      * @param  Closure|null                          $callback eager load constraint
1381:      * @return \Illuminate\Database\Eloquent\Builder
1382:      */
1383:     public function scopeWithComments(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:      * Dynamically apply scopes
1396:      *
1397:      * @param  \Illuminate\Database\Eloquent\Builder $query
1398:      * @param  array                                 $allowedParameters list of keys to pull from $request
1399:      * @param  array                                 $request           array of request variables, for instance $_REQUEST
1400:      * @return \Illuminate\Database\Eloquent\Builder
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:      * Hydrate the parents property
1415:      *
1416:      * @param  \Illuminate\Database\Eloquent\Builder $query
1417:      * @return \Illuminate\Database\Eloquent\Builder
1418:      */
1419:     public function scopeWithParents(Builder $query)
1420:     {
1421:         $this->extraHydrators[] = 'parents';
1422: 
1423:         return $query;
1424:     }
1425: 
1426:     /**
1427:      * Hydrate the siblings property
1428:      *
1429:      * @param  \Illuminate\Database\Eloquent\Builder $query
1430:      * @return \Illuminate\Database\Eloquent\Builder
1431:      */
1432:     public function scopeWithSiblings(Builder $query)
1433:     {
1434:         $this->extraHydrators[] = 'siblings';
1435: 
1436:         return $query;
1437:     }
1438: 
1439:     /**
1440:      * Apply a single parameter
1441:      *
1442:      * @param  \Illuminate\Database\Eloquent\Builder $query
1443:      * @param  string                                $key   snake_cased parameter name
1444:      * @param  string                                $value scope parameters in string form, eg. 1|2|3
1445:      * @return \Illuminate\Database\Eloquent\Builder
1446:      */
1447:     public function scopeTagparam(Builder $query, $key, $value)
1448:     {
1449:         /**
1450:          * A map of parameter names => model scopes
1451:          * @var array
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:             //'uncategorized_entries' => 'uncategorizedEntries',//bool
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:      * Apply an array of parameters
1494:      *
1495:      * @param  \Illuminate\Database\Eloquent\Builder $query
1496:      * @param  array                                 $parameters
1497:      * @param  array                                 $request    array of request variables, for instance $_REQUEST
1498:      * @return \Illuminate\Database\Eloquent\Builder
1499:      */
1500:     public function scopeTagparams(Builder $query, array $parameters, array $request = array())
1501:     {
1502:         // because you're so special
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: 
API documentation generated by ApiGen 2.8.0