Passed
Push — master ( 459a10...bba38e )
by Andreas
20:19
created

net_nehmer_static_handler_view::_handler_index()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 39
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6.4222

Importance

Changes 0
Metric Value
cc 5
eloc 25
nc 5
nop 1
dl 0
loc 39
ccs 16
cts 26
cp 0.6153
crap 6.4222
rs 9.2088
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package net.nehmer.static
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use midcom\datamanager\datamanager;
10
use midcom\workflow\dialog;
11
use midcom\datamanager\storage;
12
13
/**
14
 * n.n.static index page handler
15
 *
16
 * @package net.nehmer.static
17
 */
18
class net_nehmer_static_handler_view extends midcom_baseclasses_components_handler
19
{
20
    private array $_index_entries = [];
21
22
    private ?midcom_db_article $_article = null;
23
24
    private datamanager $_datamanager;
25
26
    /**
27
     * Simple helper which references all important members to the request data listing
28
     * for usage within the style listing.
29
     */
30 3
    private function _prepare_request_data()
31
    {
32 3
        $this->_request_data['article'] = $this->_article;
33 3
        $this->_request_data['datamanager'] = $this->_datamanager;
34
35 3
        $buttons = [];
36 3
        $workflow = $this->get_workflow('datamanager');
37 3
        if ($this->_article->can_do('midgard:update')) {
0 ignored issues
show
Bug introduced by
The method can_do() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

37
        if ($this->_article->/** @scrutinizer ignore-call */ can_do('midgard:update')) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
38 2
            $buttons[] = $workflow->get_button($this->router->generate('edit', ['guid' => $this->_article->guid]), [
39 2
                MIDCOM_TOOLBAR_ACCESSKEY => 'e',
40 2
            ]);
41
        }
42
43 3
        if (   $this->_article->topic === $this->_topic->id
44 3
            && $this->_article->can_do('midgard:delete')) {
45 2
            $delete = $this->get_workflow('delete', ['object' => $this->_article]);
46 2
            $buttons[] = $delete->get_button($this->router->generate('delete', ['guid' => $this->_article->guid]));
47
        }
48
49 3
        $this->_view_toolbar->add_items($buttons);
50
    }
51
52
    /**
53
     * Looks up an article to display. If the handler_id is 'index', the index article is tried to be
54
     * looked up, otherwise the article name is taken from args[0]. Triggered error messages are
55
     * generated accordingly. A missing index will trigger a forbidden error, a missing regular
56
     * article a 404.
57
     *
58
     * If create privileges apply, we relocate to the index creation article
59
     */
60 2
    public function _handler_view(string $handler_id, string $name, array &$data)
61
    {
62 2
        $qb = net_nehmer_static_viewer::get_topic_qb($this->_topic->id, $this->_config->get('sort_order'));
0 ignored issues
show
Bug introduced by
It seems like $this->_config->get('sort_order') can also be of type false; however, parameter $sort_property of net_nehmer_static_viewer::get_topic_qb() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

62
        $qb = net_nehmer_static_viewer::get_topic_qb($this->_topic->id, /** @scrutinizer ignore-type */ $this->_config->get('sort_order'));
Loading history...
63 2
        $qb->add_constraint('name', '=', $name);
64 2
        $qb->add_constraint('up', '=', 0);
65 2
        $qb->set_limit(1);
66
67 2
        $this->_article = $qb->get_result(0);
68 2
        if (!$this->_article) {
69
            throw new midcom_error_notfound('Could not find ' . $name);
70
        }
71 2
        return $this->show_article($data, $handler_id == 'view_raw');
72
    }
73
74 3
    private function show_article(array &$data, bool $raw = false)
75
    {
76 3
        if ($raw) {
77
            midcom::get()->skip_page_style = true;
78
        }
79
80 3
        $this->_datamanager = new datamanager($data['schemadb']);
81 3
        $this->_datamanager->set_storage($this->_article);
82
83 3
        $arg = $this->_article->name ?: $this->_article->guid;
84 3
        if (   $arg != 'index'
85 3
            && $this->_config->get('hide_navigation')) {
86
            $this->add_breadcrumb("{$arg}/", $this->_article->title);
87
        }
88
89 3
        $this->_prepare_request_data();
90
91 3
        midcom::get()->metadata->set_request_metadata($this->_article->metadata->revised, $this->_article->guid);
92 3
        $this->bind_view_to_object($this->_article, $this->_datamanager->get_schema()->get_name());
0 ignored issues
show
Bug introduced by
It seems like $this->_article can also be of type null; however, parameter $object of midcom_baseclasses_compo...::bind_view_to_object() does only seem to accept midcom_core_dbaobject, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
        $this->bind_view_to_object(/** @scrutinizer ignore-type */ $this->_article, $this->_datamanager->get_schema()->get_name());
Loading history...
93
94 3
        if (   $this->_config->get('indexinnav')
95 3
            || $this->_config->get('autoindex')
96 3
            || $this->_article->name != 'index') {
97 2
            $this->set_active_leaf($this->_article->id);
98
        }
99
100 3
        if (   $this->_config->get('folder_in_title')
101 3
            && $this->_topic->extra != $this->_article->title) {
102
            midcom::get()->head->set_pagetitle("{$this->_topic->extra}: {$this->_article->title}");
103
        } else {
104 3
            midcom::get()->head->set_pagetitle($this->_article->title);
105
        }
106 3
        $data['view_article'] = $data['datamanager']->get_content_html();
107 3
        return $this->show('show-article');
108
    }
109
110 2
    public function _handler_index(array &$data)
111
    {
112 2
        if (!$this->_config->get('autoindex')) {
113 1
            $qb = net_nehmer_static_viewer::get_topic_qb($this->_topic->id, $this->_config->get('sort_order'));
0 ignored issues
show
Bug introduced by
It seems like $this->_config->get('sort_order') can also be of type false; however, parameter $sort_property of net_nehmer_static_viewer::get_topic_qb() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

113
            $qb = net_nehmer_static_viewer::get_topic_qb($this->_topic->id, /** @scrutinizer ignore-type */ $this->_config->get('sort_order'));
Loading history...
114 1
            $qb->add_constraint('name', '=', 'index');
115 1
            $qb->set_limit(1);
116 1
            $this->_article = $qb->get_result(0);
117
118 1
            if (empty($this->_article)) {
119
                if ($this->_topic->can_do('midgard:create')) {
120
                    // Check via non-ACLd QB that the topic really doesn't have index article before relocating
121
                    $index_qb = midcom_db_article::new_query_builder();
122
                    $index_qb->add_constraint('topic', '=', $this->_topic->id);
123
                    $index_qb->add_constraint('name', '=', 'index');
124
                    if ($index_qb->count_unchecked() == 0) {
125
                        $schema = $this->_request_data['schemadb']->get_first();
126
                        $this->_request_data['schema'] = $schema->get_name();
127
                        dialog::add_head_elements();
128
                        return $this->show('index-missing');
129
                    }
130
                }
131
132
                throw new midcom_error_forbidden('Directory index forbidden');
133
            }
134
135 1
            return $this->show_article($data);
136
        }
137
138
        // Get last modified timestamp
139 1
        $qb = net_nehmer_static_viewer::get_topic_qb($this->_topic->id);
140
141 1
        $qb->add_order('metadata.revised', 'DESC');
142 1
        $qb->set_limit(1);
143 1
        $result = $qb->execute();
144 1
        $article_time = $result[0]->metadata->revised ?? 0;
145 1
        $topic_time = $this->_topic->metadata->revised;
146 1
        midcom::get()->metadata->set_request_metadata(max($article_time, $topic_time), null);
147
148 1
        $this->_index_entries = $this->_load_autoindex_data();
149
    }
150
151
    /**
152
     * Go over the topic and load all available objects for displaying in the autoindex.
153
     *
154
     * It will populate the request data key 'create_urls' as well. See the view handler for
155
     * further details.
156
     *
157
     * The computed array has the following keys:
158
     *
159
     * - string name: The name of the object.
160
     * - string url: The full URL to the object.
161
     * - string size: The formatted size of the document. This is only populated for attachments.
162
     * - string desc: The object title/description.
163
     * - string type: The MIME Type of the object.
164
     * - string lastmod: The localized last modified date.
165
     */
166 1
    private function _load_autoindex_data() : array
167
    {
168 1
        $view = [];
169 1
        $datamanager = new datamanager($this->_request_data['schemadb']);
170 1
        $qb = net_nehmer_static_viewer::get_topic_qb($this->_topic->id, $this->_config->get('sort_order'));
0 ignored issues
show
Bug introduced by
It seems like $this->_config->get('sort_order') can also be of type false; however, parameter $sort_property of net_nehmer_static_viewer::get_topic_qb() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

170
        $qb = net_nehmer_static_viewer::get_topic_qb($this->_topic->id, /** @scrutinizer ignore-type */ $this->_config->get('sort_order'));
Loading history...
171 1
        $qb->add_order('title');
172 1
        $qb->add_order('name');
173
174 1
        foreach ($qb->execute() as $article) {
175
            try {
176 1
                $datamanager->set_storage($article);
177
            } catch (midcom_error $e) {
178
                $e->log();
179
                continue;
180
            }
181
182 1
            $this->_process_datamanager($datamanager, $article, $view);
183
        }
184
185 1
        return $view;
186
    }
187
188
    /**
189
     * Converts the main document to a view entry.
190
     */
191 1
    private function _process_datamanager(datamanager $datamanager, midcom_db_article $article, array &$view)
192
    {
193 1
        $formatter = $this->_l10n->get_formatter();
194 1
        $view_data = $datamanager->get_form()->getViewData();
195 1
        $filename = "{$article->name}/";
196
197 1
        $view[$filename]['article'] = $article;
198 1
        $view[$filename]['url'] = $this->router->generate('view', ['name' => $article->name]);
199 1
        $view[$filename]['formattedsize'] = midcom_helper_misc::filesize_to_string($article->metadata->size);
200 1
        $view[$filename]['description'] = $view_data->title;
201 1
        $view[$filename]['mimetype'] = 'text/html';
202 1
        $view[$filename]['lastmod'] = $formatter->datetime($article->metadata->revised);
203 1
        $view[$filename]['view_article'] = $datamanager->get_content_html();
204
205
        // Stop the press, if blobs should not be visible
206 1
        if (!$this->_config->get('show_blobs_in_autoindex')) {
207
            return;
208
        }
209
210 1
        foreach ($view_data as $field => $value) {
211 1
            if ($value instanceof storage\image) {
212 1
                $data = $datamanager->get_form()->get($field)->getViewData();
213 1
                if (!empty($data['main'])) {
214
                    $filename = "{$article->name}/{$data['main']['filename']}";
215
                    $data['main']['lastmod'] = $formatter->datetime($data['main']['lastmod']);
216 1
                    $view[$filename] = $data['main'];
217
                }
218 1
            } elseif ($value instanceof storage\blobs) {
219
                foreach ($datamanager->get_form()->get($field)->all() as $child) {
220
                    $data = $child->getViewData();
221
                    $data['lastmod'] = $formatter->datetime($data['lastmod']);
222
                    $filename = "{$article->name}/{$data['filename']}";
223
                    $view[$filename] = $data;
224
                }
225
            }
226
        }
227
    }
228
229
    /**
230
     * Displays the autoindex of the n.n.static. This is a list of all articles and attachments on
231
     * the current topic.
232
     */
233 1
    public function _show_index(string $handler_id, array &$data)
234
    {
235 1
        midcom_show_style('autoindex-start');
236
237 1
        if (!empty($this->_index_entries)) {
238 1
            foreach ($this->_index_entries as $filename => $thedata) {
239 1
                $data['filename'] = $filename;
240 1
                $data['data'] = $thedata;
241 1
                midcom_show_style('autoindex-item');
242
            }
243
        } else {
244
            midcom_show_style('autoindex-directory-empty');
245
        }
246
247 1
        midcom_show_style('autoindex-end');
248
    }
249
}
250