1: <?php
2:
3: namespace Charcoal\Cms\Mixin\Traits;
4:
5: // dependencies from `charcoal-translation`
6: use Charcoal\Translator\Translation;
7:
8: /**
9: * An implementation, as Trait, of the `HasContentBlocksInterface`.
10: *
11: * @uses Charcoal\Attachment\Traits\AttachmentAwareTrait
12: */
13: trait HasContentBlocksTrait
14: {
15: /**
16: * Retrieve this object's content blocks.
17: *
18: * @return Collection|Attachment[]
19: */
20: public function contentBlocks()
21: {
22: return $this->attachments('contents');
23: }
24:
25: /**
26: * Determine if this object has any content blocks.
27: *
28: * @return boolean
29: */
30: public function hasContentBlocks()
31: {
32: return !!($this->numContentBlocks());
33: }
34:
35: /**
36: * Count the number of content blocks associated to this object.
37: *
38: * @return integer
39: */
40: public function numContentBlocks()
41: {
42: return count($this->contentBlocks());
43: }
44:
45: // ==========================================================================
46: // META
47: // ==========================================================================
48:
49: /**
50: * @return Translation
51: */
52: public function defaultMetaDescription()
53: {
54: $content = $this->metaDescFromAttachments();
55:
56: if ($content === null) {
57: $content = parent::defaultMetaDescription();
58: }
59:
60: return $content;
61: }
62:
63: /**
64: * Gets the content excerpt from attachments if a text attachment is found, otherwise
65: * it return null.
66: *
67: * @return Translation|null|string|\string[] The content from attachment
68: */
69: private function metaDescFromAttachments()
70: {
71: $attachments = $this->attachments();
72:
73: if (!$attachments) {
74: return null;
75: }
76:
77: foreach ($attachments as $attachment) {
78: if ($attachment->isText()) {
79: $content = $attachment->description();
80:
81: $content = $this->ellipsis($content);
82:
83: return $content;
84: }
85: }
86:
87: return null;
88: }
89:
90: /**
91: * @param string|Translation $content The content to shorten.
92: * @param integer $length The length to shorten to. Default : 200.
93: * @return string|Translation
94: */
95: private function ellipsis($content, $length = 200)
96: {
97: if ($content instanceof Translation) {
98: $content = $content->data();
99: foreach ($content as $lang => $text) {
100: $content[$lang] = strlen($text) > $length ? substr(strip_tags($text), 0, $length).'...' : $text;
101: }
102: $content = $this->translator()->translation($content);
103: } else {
104: $content = strlen($content) > $length ? substr(strip_tags($content), 0, $length) : $content;
105: }
106:
107: return $content;
108: }
109:
110: /**
111: * Retrieve the objects associated to the current object.
112: *
113: * As defined in Charcoal\Attachment\Traits\AttachmentAwareTrait.
114: *
115: * @param string|null $group Filter the attachments by a group identifier.
116: * @param string|null $type Filter the attachments by type.
117: * @param callable|null $callback Optional routine to apply to every attachment.
118: * @throws InvalidArgumentException If the $group or $type is invalid.
119: * @return Collection|Attachment[]
120: */
121: abstract public function attachments($group = null, $type = null, callable $callback = null);
122: }
123: