Overview

Namespaces

  • Charcoal
    • Admin
      • Widget
        • Cms
    • Cms
      • Config
      • Mixin
        • Traits
      • Route
      • Section
      • Service
        • Loader
        • Manager
      • ServiceProvider
      • Support
        • Helpers
        • Interfaces
        • Traits
    • Property

Classes

  • Charcoal\Admin\Widget\Cms\HierarchicalSectionTableWidget
  • Charcoal\Admin\Widget\Cms\SectionTableWidget
  • Charcoal\Cms\AbstractDocument
  • Charcoal\Cms\AbstractEvent
  • Charcoal\Cms\AbstractFaq
  • Charcoal\Cms\AbstractImage
  • Charcoal\Cms\AbstractNews
  • Charcoal\Cms\AbstractSection
  • Charcoal\Cms\AbstractText
  • Charcoal\Cms\AbstractVideo
  • Charcoal\Cms\Config
  • Charcoal\Cms\Config\CmsConfig
  • Charcoal\Cms\Config\EventConfig
  • Charcoal\Cms\Config\NewsConfig
  • Charcoal\Cms\Config\SectionConfig
  • Charcoal\Cms\Document
  • Charcoal\Cms\DocumentCategory
  • Charcoal\Cms\EmptySection
  • Charcoal\Cms\Event
  • Charcoal\Cms\EventCategory
  • Charcoal\Cms\ExternalSection
  • Charcoal\Cms\Faq
  • Charcoal\Cms\FaqCategory
  • Charcoal\Cms\Image
  • Charcoal\Cms\ImageCategory
  • Charcoal\Cms\News
  • Charcoal\Cms\NewsCategory
  • Charcoal\Cms\Route\EventRoute
  • Charcoal\Cms\Route\GenericRoute
  • Charcoal\Cms\Route\NewsRoute
  • Charcoal\Cms\Route\SectionRoute
  • Charcoal\Cms\Section
  • Charcoal\Cms\Section\BlocksSection
  • Charcoal\Cms\Section\ContentSection
  • Charcoal\Cms\Service\Loader\AbstractLoader
  • Charcoal\Cms\Service\Loader\EventLoader
  • Charcoal\Cms\Service\Loader\NewsLoader
  • Charcoal\Cms\Service\Loader\SectionLoader
  • Charcoal\Cms\Service\Manager\AbstractManager
  • Charcoal\Cms\Service\Manager\EventManager
  • Charcoal\Cms\Service\Manager\NewsManager
  • Charcoal\Cms\ServiceProvider\CmsServiceProvider
  • Charcoal\Cms\Support\Helpers\DateHelper
  • Charcoal\Cms\Tag
  • Charcoal\Cms\Text
  • Charcoal\Cms\TextCategory
  • Charcoal\Cms\Video
  • Charcoal\Cms\VideoCategory
  • Charcoal\Property\TemplateOptionsProperty
  • Charcoal\Property\TemplateProperty

Interfaces

  • Charcoal\Cms\DocumentInterface
  • Charcoal\Cms\EventInterface
  • Charcoal\Cms\FaqInterface
  • Charcoal\Cms\ImageInterface
  • Charcoal\Cms\MetatagInterface
  • Charcoal\Cms\Mixin\HasContentBlocksInterface
  • Charcoal\Cms\NewsInterface
  • Charcoal\Cms\SearchableInterface
  • Charcoal\Cms\SectionInterface
  • Charcoal\Cms\Support\Interfaces\EventManagerAwareInterface
  • Charcoal\Cms\Support\Interfaces\NewsManagerAwareInterface
  • Charcoal\Cms\Support\Interfaces\SectionLoaderAwareInterface
  • Charcoal\Cms\TemplateableInterface
  • Charcoal\Cms\TextInterface
  • Charcoal\Cms\VideoInterface

Traits

  • Charcoal\Admin\Widget\Cms\SectionTableTrait
  • Charcoal\Cms\MetatagTrait
  • Charcoal\Cms\Mixin\Traits\HasContentBlocksTrait
  • Charcoal\Cms\SearchableTrait
  • Charcoal\Cms\Support\Traits\DateHelperAwareTrait
  • Charcoal\Cms\Support\Traits\EventManagerAwareTrait
  • Charcoal\Cms\Support\Traits\NewsManagerAwareTrait
  • Charcoal\Cms\Support\Traits\SectionLoaderAwareTrait
  • Charcoal\Cms\TemplateableTrait
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: namespace Charcoal\Cms\Service\Manager;
  4: 
  5: // dependencies from `charcoal-core`
  6: use Charcoal\Model\Collection;
  7: 
  8: // dependencies from `charcoal-base`
  9: use Charcoal\Object\CategoryInterface;
 10: use Charcoal\Object\CategoryTrait;
 11: 
 12: // Local dependencies
 13: use Charcoal\Cms\Config\CmsConfig;
 14: use Charcoal\Cms\NewsInterface;
 15: use Charcoal\Cms\Service\Loader\NewsLoader;
 16: 
 17: // Psr-7 dependencies
 18: use Exception;
 19: 
 20: /**
 21:  * News manager
 22:  */
 23: class NewsManager extends AbstractManager
 24: {
 25:     use CategoryTrait;
 26: 
 27:     /** @var NewsInterface $currentNews The current news. */
 28:     protected $currentNews;
 29: 
 30:     /** @var integer $currentPage The current Page. */
 31:     protected $currentPage;
 32: 
 33:     /** @var integer $numPerPage News by page. */
 34:     protected $numPerPage = 0;
 35: 
 36:     /** @var integer $numPages How many pages. */
 37:     protected $numPages;
 38: 
 39:     /** @var boolean $pageCycle Does the pager can cycle indefinitely. */
 40:     protected $entryCycle = false;
 41: 
 42:     /** @var NewsInterface $nextNews */
 43:     protected $nextNews;
 44: 
 45:     /** @var NewsInterface $prevNews */
 46:     protected $prevNews;
 47: 
 48:     /** @var integer $page */
 49:     protected $page = 0;
 50: 
 51:     /** @var integer $category */
 52:     protected $category = 0;
 53: 
 54:     /** @var NewsInterface[] $all All the news. */
 55:     protected $all = [];
 56: 
 57:     /** @var NewsInterface[] $entries The news collection. */
 58:     protected $entries = [];
 59: 
 60:     /** @var NewsInterface[] $archive The archive news collection. */
 61:     protected $archive = [];
 62: 
 63:     /** @var NewsInterface $entry A news. */
 64:     protected $entry;
 65: 
 66:     /** @var object $objType The news object model. */
 67:     protected $objType;
 68: 
 69:     /** @var string $featIdent The config ident for featured news. */
 70:     protected $featIdent;
 71: 
 72:     /** @var NewsInterface[] $featList The config ident for featured news. */
 73:     protected $featList = [];
 74: 
 75:     /** @var NewsLoader $loader The news loader provider. */
 76:     protected $loader;
 77: 
 78:     /**
 79:      * @var array
 80:      */
 81:     protected $categoryItem = [];
 82: 
 83:     /**
 84:      * NewsManager constructor.
 85:      * @param array $data The Data.
 86:      * @throws Exception When $data index is not set.
 87:      */
 88:     public function __construct(array $data)
 89:     {
 90:         parent::__construct($data);
 91: 
 92:         if (!isset($data['news/loader'])) {
 93:             throw new Exception('News Loader must be defined in the NewsManager constructor.');
 94:         }
 95: 
 96:         $this->setLoader($data['news/loader']);
 97: 
 98:         /** @var CmsConfig $newsConfig */
 99:         $newsConfig = $this->adminConfig()->newsConfig();
100: 
101:         $this->setNumPerPage($newsConfig->get('numPerPage'));
102:         $this->setEntryCycle($newsConfig->get('entryCycle'));
103:         $this->setObjType($newsConfig->get('objType'));
104:         $this->setCategoryItemType($newsConfig->get('category'));
105:         $this->setFeatIdent($newsConfig->get('configFeatIdent'));
106:     }
107: 
108:     /**
109:      * To be displayed news list.
110:      * @return mixed The news collection.
111:      */
112:     public function entries()
113:     {
114:         $page = $this->page();
115:         $cat = $this->category();
116:         if (isset($this->entries[$cat])) {
117:             if (isset($this->entries[$cat][$page])) {
118:                 return $this->entries[$cat][$page];
119:             }
120:         }
121: 
122:         $loader = $this->entriesLoader();
123: 
124:         $this->entries[$cat][$page] = $loader->load();
125: 
126:         return $this->entries[$cat][$page];
127:     }
128: 
129:     /**
130:      * @return \Charcoal\Loader\CollectionLoader
131:      */
132:     public function entriesLoader()
133:     {
134:         $loader = $this->loader()->upcoming();
135:         $loader->addOrder('news_date', 'desc');
136: 
137:         if ($this->category()) {
138:             $loader->addFilter('category', $this->category(), [ 'operator' => 'in' ]);
139:         }
140:         if ($this->numPerPage()) {
141:             $loader->setPage($this->page());
142: 
143:             $numPerPage = !!($this->page()) ? $this->numPerPage() : 0;
144:             $loader->setNumPerPage($numPerPage);
145:         }
146: 
147:         return $loader;
148:     }
149: 
150:     /**
151:      * @param integer|null $id The news id.
152:      * @return mixed
153:      */
154:     public function entry($id = null)
155:     {
156:         if (!$id) {
157:             return $this->currentNews();
158:         }
159: 
160:         if (!isset($this->entry[$id])) {
161:             $entry = $this->modelFactory()->get($this->objType())->loadFrom('id', $id);
162:             $this->entry[$id] = $entry->id() ? $entry : $this->currentNews();
163:         }
164: 
165:         return $this->entry[$id];
166:     }
167: 
168:     /**
169:      * All available news.
170:      * @return NewsInterface[]|Collection The news collection.
171:      */
172:     public function all()
173:     {
174:         if ($this->all) {
175:             return $this->all;
176:         }
177: 
178:         $this->all = $this->loader()->all()->addOrder('news_date', 'desc')->load();
179: 
180:         return $this->all;
181:     }
182: 
183:     /**
184:      * @return CategoryInterface[]|Collection The category collection.
185:      */
186:     public function loadCategoryItems()
187:     {
188:         $proto = $this->modelFactory()->create($this->categoryItemType());
189:         $loader = $this->collectionLoader()->setModel($proto);
190:         $loader->addFilter('active', true);
191: 
192:         return $loader->load();
193:     }
194: 
195:     /**
196:      * @param integer $id The category id.
197:      * @return CategoryInterface
198:      */
199:     public function categoryItem($id)
200:     {
201:         if (isset($this->categoryItem[$id])) {
202:             return $this->categoryItem[$id];
203:         }
204:         $category = $this->modelFactory()->create($this->categoryItemType());
205: 
206:         $this->categoryItem[$id] = $category->load($id);
207: 
208:         return $this->categoryItem[$id];
209:     }
210: 
211:     /**
212:      * @return mixed
213:      * @param array $options The options for the collection loader.
214:      * @throws Exception When featured news ident is not valid.
215:      */
216:     public function featList(array $options = [])
217:     {
218:         if ($this->featList) {
219:             return $this->featList;
220:         }
221: 
222:         $loader = $this->loader()->published();
223:         $ident = $this->featIdent();
224:         $config = $this->adminConfig();
225: 
226:         if (!$ident || !method_exists($config, $ident)) {
227:             throw new Exception(sprintf(
228:                 'The featured news ident "%s" doesn\'t exist the class "%s"',
229:                 $ident,
230:                 get_class($config)
231:             ));
232:         }
233:         $ids = $config->{$ident}();
234: 
235:         if (!$ids) {
236:             return null;
237:         }
238: 
239:         $ids = explode(',', $ids);
240: 
241:         $loader->addFilter('id', $ids, [ 'operator' => 'in' ])
242:             ->addOrder('id', 'values', [ 'values' => $ids ]);
243: 
244:         if (count($options) > 0) {
245:             foreach ($options as $key => $option) {
246:                 switch ($key) {
247:                     case 'filters':
248:                         $filters = $option;
249:                         foreach ($filters as $f) {
250:                             $filter[] = $f['property'] ?: '';
251:                             $filter[] = $f['val'] ?: '';
252:                             $filter[] = $f['options'] ?: '';
253:                             $filter = join(',', $filter);
254: 
255:                             $loader->addFilter($filter);
256:                         }
257:                         break;
258:                     case 'page':
259:                         $loader->setPage($option);
260:                         break;
261:                     case 'numPerPage':
262:                         $loader->setNumPerPage($option);
263:                         break;
264:                 }
265:             }
266:         }
267: 
268:         $this->featList = $loader->load();
269: 
270:         return $this->featList;
271:     }
272: 
273:     /**
274:      * @return NewsInterface[]|Collection
275:      */
276:     public function archive()
277:     {
278:         $page = $this->page();
279:         $cat = $this->category();
280:         if (isset($this->archive[$cat])) {
281:             if (isset($this->archive[$cat][$page])) {
282:                 return $this->archive[$cat][$page];
283:             }
284:         }
285: 
286:         $loader = $this->loader()->archive();
287:         $loader->addOrder('news_date', 'desc');
288: 
289:         if ($this->category()) {
290:             $loader->addFilter('category', $this->category(), [ 'operator' => 'in' ]);
291:         }
292:         if ($this->numPerPage()) {
293:             $loader->setPage($this->page());
294:             $loader->setNumPerPage($this->numPerPage());
295:         }
296: 
297:         $this->archive[$cat][$page] = $loader->load();
298: 
299:         return $this->archive[$cat][$page];
300:     }
301: 
302:     /**
303:      * Get the latest news.
304:      * @return NewsInterface|array The latest news.
305:      */
306:     public function latest()
307:     {
308:         $entries = $this->entries();
309: 
310:         if (isset($entries[0])) {
311:             return $entries[0];
312:         } else {
313:             // NO NEWS!
314:             return [];
315:         }
316:     }
317: 
318:     /**
319:      * @return mixed The previous news
320:      */
321:     public function prev()
322:     {
323:         if ($this->prevNews) {
324:             return $this->prevNews;
325:         }
326: 
327:         return $this->setPrevNext()->prevNews;
328:     }
329: 
330:     /**
331:      * @return mixed The next news
332:      */
333:     public function next()
334:     {
335:         if ($this->nextNews) {
336:             return $this->nextNews;
337:         }
338: 
339:         return $this->setPrevNext()->nextNews;
340:     }
341: 
342:     /**
343:      * @return float|int The current news index page ident.
344:      */
345:     public function currentPage()
346:     {
347:         if ($this->currentPage) {
348:             return $this->currentPage;
349:         }
350:         if (!$this->currentNews() || !$this->currentNews()['id']) {
351:             $this->currentPage = 1;
352: 
353:             return 1;
354:         }
355:         $all = $this->all();
356:         $i = 0;
357:         foreach ($all as $news) {
358:             $i++;
359:             if ($news->id() == $this->currentNews()['id']) {
360:                 break;
361:             }
362:         }
363: 
364:         $this->currentPage = $this->numPerPage() ? ceil($i / $this->numPerPage()) : 1;
365: 
366:         return $this->currentPage;
367:     }
368: 
369:     // ==========================================================================
370:     // GETTERS
371:     // ==========================================================================
372: 
373:     /**
374:      * @return mixed
375:      */
376:     public function currentNews()
377:     {
378:         if (!$this->currentNews) {
379:             $this->currentNews = $this->latest();
380:         }
381: 
382:         return $this->currentNews;
383:     }
384: 
385:     /**
386:      * @return integer
387:      */
388:     public function numPerPage()
389:     {
390:         return $this->numPerPage;
391:     }
392: 
393:     /**
394:      * @return boolean
395:      */
396:     public function entryCycle()
397:     {
398:         return $this->entryCycle;
399:     }
400: 
401:     /**
402:      * Amount of news (total)
403:      * @return integer How many news?
404:      */
405:     public function numNews()
406:     {
407:         return !!(count($this->entries()));
408:     }
409: 
410:     /**
411:      * The total amount of pages.
412:      * @return float
413:      */
414:     public function numPages()
415:     {
416:         return ceil($this->entriesLoader()->loadCount() / $this->numPerPage());
417:     }
418: 
419:     /**
420:      * Is there a pager.
421:      * @return boolean
422:      */
423:     public function hasPager()
424:     {
425:         return ($this->numPages() > 1);
426:     }
427: 
428:     /**
429:      * @return integer
430:      */
431:     public function page()
432:     {
433:         return $this->page;
434:     }
435: 
436:     /**
437:      * @return integer
438:      */
439:     public function category()
440:     {
441:         return $this->category;
442:     }
443: 
444:     /**
445:      * @return mixed
446:      */
447:     public function objType()
448:     {
449:         return $this->objType;
450:     }
451: 
452:     /**
453:      * @return mixed
454:      */
455:     public function featIdent()
456:     {
457:         return $this->featIdent;
458:     }
459: 
460:     /**
461:      * @return NewsLoader
462:      */
463:     public function loader()
464:     {
465:         return $this->loader;
466:     }
467: 
468:     // ==========================================================================
469:     // SETTERS
470:     // ==========================================================================
471: 
472:     /**
473:      * @param mixed $currentNews The current news context.
474:      * @return self .
475:      */
476:     public function setCurrentNews($currentNews)
477:     {
478:         $this->currentNews = $currentNews;
479: 
480:         return $this;
481:     }
482: 
483:     /**
484:      * @param integer $numPerPage The number of news per page.
485:      * @return self
486:      */
487:     public function setNumPerPage($numPerPage)
488:     {
489:         $this->numPerPage = $numPerPage;
490: 
491:         return $this;
492:     }
493: 
494:     /**
495:      * @param boolean $entryCycle Next and Prev cycles indefinitely.
496:      * @return self
497:      */
498:     public function setEntryCycle($entryCycle)
499:     {
500:         $this->entryCycle = $entryCycle;
501: 
502:         return $this;
503:     }
504: 
505:     /**
506:      * @param integer $page The page number to load.
507:      * @return self
508:      */
509:     public function setPage($page)
510:     {
511:         $this->page = $page;
512: 
513:         return $this;
514:     }
515: 
516:     /**
517:      * @param integer $category The current news category.
518:      * @return self
519:      */
520:     public function setCategory($category)
521:     {
522:         $this->category = $category;
523: 
524:         return $this;
525:     }
526: 
527:     /**
528:      * @param mixed $objType The object type.
529:      * @return self
530:      */
531:     public function setObjType($objType)
532:     {
533:         $this->objType = $objType;
534: 
535:         return $this;
536:     }
537: 
538:     /**
539:      * @param mixed $featIdent The featured list ident.
540:      * @return self
541:      */
542:     public function setFeatIdent($featIdent)
543:     {
544:         $this->featIdent = $featIdent;
545: 
546:         return $this;
547:     }
548: 
549:     /**
550:      * @param NewsLoader $loader The news loader provider.
551:      * @return self
552:      */
553:     public function setLoader(NewsLoader $loader)
554:     {
555:         $this->loader = $loader;
556: 
557:         return $this;
558:     }
559: 
560:     // ==========================================================================
561:     // UTILS
562:     // ==========================================================================
563: 
564:     /**
565:      * Set the Prev and Next news
566:      * @return $this
567:      */
568:     public function setPrevNext()
569:     {
570:         if ($this->nextNews && $this->prevNews) {
571:             return $this;
572:         }
573:         $entries = $this->entries();
574: 
575:         $isPrev = false;
576:         $isNext = false;
577:         $firstNews = false;
578:         $lastNews = false;
579: 
580:         /** @var NewsInterface $news */
581:         foreach ($entries as $news) {
582:             // Obtain th first news.
583:             if (!$firstNews) {
584:                 $firstNews = $news;
585:             }
586:             $lastNews = $news;
587:             // Find the current news
588:             if ($news->id() == $this->currentNews()['id']) {
589:                 $isNext = true;
590:                 $isPrev = true;
591: 
592:                 continue;
593:             }
594:             if (!$isPrev) {
595:                 $this->prevNews = $news;
596:             }
597:             // Store the next news
598:             if ($isNext) {
599:                 $this->nextNews = $news;
600: 
601:                 $isNext = false;
602:             }
603:         }
604: 
605:         if ($this->entryCycle()) {
606:             if (!$this->nextNews) {
607:                 $this->nextNews = $firstNews;
608:             }
609: 
610:             if (!$this->prevNews) {
611:                 $this->prevNews = $lastNews;
612:             }
613:         }
614: 
615:         return $this;
616:     }
617: }
618: 
API documentation generated by ApiGen