Issues (55)

src/components/DocumentComponent.php (1 issue)

Severity
1
<?php
2
3
namespace CloudControl\Cms\components {
4
5
    use CloudControl\Cms\storage\entities\Document;
6
    use CloudControl\Cms\storage\Storage;
7
8
    /**
9
     * Class DocumentComponent
10
     *
11
     * Has optional parameter `folder` to prefix the relative url with a folder
12
     * Has optional parameter `document` to select a given document
13
     * Has optional parameter `documentParameterName` to select the parametername to be used
14
     *        to set the found document to.
15
     *
16
     * @package CloudControl\Cms\components
17
     */
18
    class DocumentComponent extends NotFoundComponent
19
    {
20
        protected $documentParameterName = self::PARAMETER_DOCUMENT;
21
        private $matchIndex = '1';
22
23
        const DOCUMENT_STATE_UNPUBLISHED = 'unpublished';
24
        const DOCUMENT_STATE_PUBLISHED = 'published';
25
26
        const DOCUMENT_TYPE_FOLDER = 'folder';
27
28
        const PARAMETER_DOCUMENT = 'document';
29
        const PARAMETER_MATCH_INDEX = 'matchIndex';
30
        const PARAMETER_DOCUMENT_PARAMETER_NAME = 'documentParameterName';
31
32
33
34
35
        /**
36
         * @param Storage $storage
37
         *
38
         * @return mixed|void
39
         * @throws \Exception
40
         */
41
        public function run(Storage $storage)
42
        {
43
            parent::run($storage);
44
45
            $this->checkParameters();
46
47
            if ($this->matchedSitemapItem === null) { // If no sitemapitem, its an application component
48
                $this->runLikeApplicationComponent();
49
            } else {
50
                $this->runLikeRegularComponent();
51
            }
52
        }
53
54
        /**
55
         * Checks to see if any parameters were defined in the cms and acts according
56
         */
57
        protected function checkParameters()
58
        {
59
            if (isset($this->parameters[self::PARAMETER_DOCUMENT_PARAMETER_NAME])) {
60
                $this->documentParameterName = $this->parameters[self::PARAMETER_DOCUMENT_PARAMETER_NAME];
61
            }
62
63
            if (isset($this->parameters[self::PARAMETER_MATCH_INDEX])) {
64
                $this->matchIndex = $this->parameters[self::PARAMETER_MATCH_INDEX];
65
            }
66
        }
67
68
        /**
69
         * Run as application component
70
         *
71
         * @throws \Exception
72
         */
73
        protected function runLikeApplicationComponent()
74
        {
75
            if (isset($this->parameters[self::PARAMETER_DOCUMENT])) {
76
                $this->parameters[$this->documentParameterName] = $this->storage->getDocuments()->getDocumentBySlug($this->parameters[self::PARAMETER_DOCUMENT]);
77
                unset($this->parameters[self::PARAMETER_DOCUMENT]);
78
            } else {
79
                throw new \RuntimeException('When used as application component, you need to specify a document.');
80
            }
81
        }
82
83
        /**
84
         * Run as regular component
85
         *
86
         * @throws \Exception
87
         */
88
        protected function runLikeRegularComponent()
89
        {
90
            if ($this->matchedSitemapItem->regex === false || isset($this->parameters[self::PARAMETER_DOCUMENT])) {
91
                $this->runWithoutRegex();
92
            } else {
93
                $this->runWithRegex();
94
            }
95
        }
96
97
        /**
98
         * Run without regex
99
         *
100
         * @throws \Exception
101
         */
102
        protected function runWithoutRegex()
103
        {
104
            if (isset($this->parameters[self::PARAMETER_DOCUMENT])) {
105
                $this->runByDocumentParameter();
106
            } else {
107
                throw new \RuntimeException('When not using a regex, you need to set the parameter `document` with the path to the document in this sitemap item: ' . $this->matchedSitemapItem->title);
108
            }
109
        }
110
111
        /**
112
         * Run with regex
113
         *
114
         * @throws \Exception
115
         */
116
        protected function runWithRegex()
117
        {
118
            $relativeDocumentUri = $this->checkForSpecificFolder();
119
120
            $state = $this->getState();
121
122
            $document = $this->storage->getDocuments()->getDocumentBySlug($relativeDocumentUri, $state);
123
124
            if ($document instanceof Document && $document->state === self::DOCUMENT_STATE_PUBLISHED && $document->type !== self::DOCUMENT_TYPE_FOLDER) {
125
                $this->parameters[$this->documentParameterName] = $document;
126
            } else {
127
                $this->set404Header();
128
                $this->set404Template();
129
            }
130
        }
131
132
        /**
133
         * Run using the given `document` parameter
134
         * @throws \Exception
135
         */
136
        protected function runByDocumentParameter()
137
        {
138
            $state = $this->getState();
139
            $document = $this->storage->getDocuments()->getDocumentBySlug($this->parameters[self::PARAMETER_DOCUMENT], $state);
140
            if ($document instanceof Document) {
0 ignored issues
show
$document is always a sub-type of CloudControl\Cms\storage\entities\Document.
Loading history...
141
                $this->parameters[$this->documentParameterName] = $document;
142
            } else {
143
                $this->set404Header();
144
                $this->set404Template();
145
            }
146
        }
147
148
        /**
149
         * @return mixed|string
150
         */
151
        protected function checkForSpecificFolder()
152
        {
153
            $relativeDocumentUri = current($this->matchedSitemapItem->matches[$this->matchIndex]);
154
            if (isset($this->parameters[self::DOCUMENT_TYPE_FOLDER])) {
155
                if (substr($this->parameters[self::DOCUMENT_TYPE_FOLDER], -1) !== '/') {
156
                    $this->parameters[self::DOCUMENT_TYPE_FOLDER] .= '/';
157
                }
158
                $relativeDocumentUri = $this->parameters[self::DOCUMENT_TYPE_FOLDER] . $relativeDocumentUri;
159
            }
160
            return $relativeDocumentUri;
161
        }
162
163
        /**
164
         * @return string
165
         */
166
        protected function getState()
167
        {
168
            $state = CmsComponent::isCmsLoggedIn() ? self::DOCUMENT_STATE_UNPUBLISHED : self::DOCUMENT_STATE_PUBLISHED;
169
            return $state;
170
        }
171
    }
172
}