Passed
Push — master ( 7e659e...584353 )
by Andreas
19:32
created

prepare_request_data()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 8
nop 1
dl 0
loc 25
ccs 17
cts 17
cp 1
crap 5
rs 9.4222
c 0
b 0
f 0
1
<?php
2
use Symfony\Component\HttpFoundation\Request;
3
4
/**
5
 * @package midcom.services.rcs
6
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
7
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
8
 */
9
10
/**
11
 * @package midcom.services.rcs
12
 */
13
abstract class midcom_services_rcs_handler extends midcom_baseclasses_components_handler
14
{
15
    /**
16
     * RCS backend
17
     *
18
     * @var midcom_services_rcs_backend
19
     */
20
    private $backend;
21
22
    /**
23
     * Pointer to midgard object
24
     *
25
     * @var midcom_core_dbaobject
26
     */
27
    protected $object;
28
29
    protected $style_prefix = '';
30
31
    protected $url_prefix = '';
32
33
    abstract protected function get_object_url() : string;
34
35
    abstract protected function handler_callback($handler_id);
36
37
    abstract protected function get_breadcrumbs();
38
39 6
    protected function resolve_object_title()
40
    {
41 6
        return midcom_helper_reflector::get($this->object)->get_object_label($this->object);
42
    }
43
44
    /**
45
     * Load the object and the rcs backend
46
     */
47 6
    private function load_object(string $guid)
48
    {
49 6
        $this->object = midcom::get()->dbfactory->get_object_by_guid($guid);
50
51 6
        if (   !midcom::get()->config->get('midcom_services_rcs_enable')
52 6
            || !$this->object->_use_rcs) {
53
            throw new midcom_error_notfound("Revision control not supported for " . get_class($this->object) . ".");
54
        }
55
56 6
        $this->backend = midcom::get()->rcs->load_backend($this->object);
57 6
    }
58
59
    /**
60
     * Prepare version control toolbar
61
     */
62 6
    private function rcs_toolbar($current = null, $diff_view = false)
63
    {
64 6
        $this->add_stylesheet(MIDCOM_STATIC_URL . "/midcom.services.rcs/rcs.css");
65 6
        $prefix = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX) . $this->url_prefix;
0 ignored issues
show
Bug introduced by
Are you sure midcom_core_context::get...M_CONTEXT_ANCHORPREFIX) of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

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

65
        $prefix = /** @scrutinizer ignore-type */ midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX) . $this->url_prefix;
Loading history...
66
67 6
        $this->_request_data['rcs_toolbar'] = new midcom_helper_toolbar();
68
69 6
        $last = $this->build_rcs_toolbar($this->_request_data['rcs_toolbar'], $current, $diff_view);
70
71
        // RCS functional toolbar
72 6
        $this->_request_data['rcs_toolbar_2'] = new midcom_helper_toolbar();
73
        $buttons = [
74
            [
75 6
                MIDCOM_TOOLBAR_URL => "{$prefix}{$this->object->guid}/",
76 6
                MIDCOM_TOOLBAR_LABEL => $this->_l10n->get('show history'),
77 6
                MIDCOM_TOOLBAR_GLYPHICON => 'history',
78
            ]
79
        ];
80
81 6
        if (!empty($current)) {
82 4
            $buttons[] = [
83 4
                MIDCOM_TOOLBAR_URL => "{$prefix}restore/{$this->object->guid}/{$current}/",
84 4
                MIDCOM_TOOLBAR_LABEL => sprintf($this->_l10n->get('restore version %s'), $current),
85 4
                MIDCOM_TOOLBAR_GLYPHICON => 'recycle',
86 4
                MIDCOM_TOOLBAR_ENABLED => ($current !== $last),
87
            ];
88
        }
89 6
        $this->_request_data['rcs_toolbar_2']->add_items($buttons);
90 6
    }
91
92 6
    private function build_rcs_toolbar(midcom_helper_toolbar $toolbar, $current, bool $diff_view)
93
    {
94 6
        $keys = array_keys($this->backend->list_history());
95 6
        if (!isset($keys[0])) {
96 2
            return;
97
        }
98 6
        $prefix = midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX) . $this->url_prefix;
0 ignored issues
show
Bug introduced by
Are you sure midcom_core_context::get...M_CONTEXT_ANCHORPREFIX) of type false|mixed can be used in concatenation? ( Ignorable by Annotation )

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

98
        $prefix = /** @scrutinizer ignore-type */ midcom_core_context::get()->get_key(MIDCOM_CONTEXT_ANCHORPREFIX) . $this->url_prefix;
Loading history...
99 6
        $first = end($keys);
100 6
        $last = $keys[0];
101
102
        $buttons = [[
103 6
            MIDCOM_TOOLBAR_URL => "{$prefix}preview/{$this->object->guid}/{$first}",
104 6
            MIDCOM_TOOLBAR_LABEL => $first,
105 6
            MIDCOM_TOOLBAR_GLYPHICON => 'fast-backward',
106 6
            MIDCOM_TOOLBAR_ENABLED => ($current !== $first || $diff_view),
107
        ]];
108
109 6
        if (!empty($current)) {
110 4
            $previous = $this->backend->get_prev_version($current);
111 4
            if (!$previous) {
112 2
                $previous = $first;
113
            }
114
115 4
            $next = $this->backend->get_next_version($current);
116 4
            if (!$next) {
117 2
                $next = $last;
118
            }
119
120 4
            $buttons[] = [
121 4
                MIDCOM_TOOLBAR_URL => "{$prefix}preview/{$this->object->guid}/{$previous}",
122 4
                MIDCOM_TOOLBAR_LABEL => $previous,
123 4
                MIDCOM_TOOLBAR_GLYPHICON => 'backward',
124 4
                MIDCOM_TOOLBAR_ENABLED => ($current !== $first || $diff_view),
125
            ];
126
127 4
            $buttons[] = [
128 4
                MIDCOM_TOOLBAR_URL => "{$prefix}diff/{$this->object->guid}/{$current}/{$previous}/",
129 4
                MIDCOM_TOOLBAR_LABEL => $this->_l10n->get('show differences'),
130 4
                MIDCOM_TOOLBAR_GLYPHICON => 'step-backward',
131 4
                MIDCOM_TOOLBAR_ENABLED => ($current !== $first),
132
            ];
133
134 4
            $buttons[] = [
135 4
                MIDCOM_TOOLBAR_URL => "{$prefix}preview/{$current}/{$current}/",
136 4
                MIDCOM_TOOLBAR_LABEL => sprintf($this->_l10n->get('version %s'), $current),
137 4
                MIDCOM_TOOLBAR_GLYPHICON => 'file-o',
138
                MIDCOM_TOOLBAR_ENABLED => false,
139
            ];
140
141 4
            $buttons[] = [
142 4
                MIDCOM_TOOLBAR_URL => "{$prefix}diff/{$this->object->guid}/{$current}/{$next}/",
143 4
                MIDCOM_TOOLBAR_LABEL => $this->_l10n->get('show differences'),
144 4
                MIDCOM_TOOLBAR_GLYPHICON => 'step-forward',
145 4
                MIDCOM_TOOLBAR_ENABLED => ($current !== $last),
146
            ];
147
148 4
            $buttons[] = [
149 4
                MIDCOM_TOOLBAR_URL => "{$prefix}preview/{$this->object->guid}/{$next}",
150 4
                MIDCOM_TOOLBAR_LABEL => $next,
151 4
                MIDCOM_TOOLBAR_GLYPHICON => 'forward',
152 4
                MIDCOM_TOOLBAR_ENABLED => ($current !== $last || $diff_view),
153
            ];
154
        }
155
156 6
        $buttons[] = [
157 6
            MIDCOM_TOOLBAR_URL => "{$prefix}preview/{$this->object->guid}/{$last}",
158 6
            MIDCOM_TOOLBAR_LABEL => $last,
159 6
            MIDCOM_TOOLBAR_GLYPHICON => 'fast-forward',
160 6
            MIDCOM_TOOLBAR_ENABLED => ($current !== $last || $diff_view),
161
        ];
162
163 6
        $toolbar->add_items($buttons);
164 6
        return $last;
165
    }
166
167 6
    private function prepare_request_data(string $view_title)
168
    {
169 6
        $breadcrumbs = $this->get_breadcrumbs();
170 6
        if (!empty($breadcrumbs)) {
171 6
            foreach ($breadcrumbs as $item) {
172 6
                $this->add_breadcrumb($item[MIDCOM_NAV_URL], $item[MIDCOM_NAV_NAME]);
173
            }
174
        }
175 6
        $this->add_breadcrumb($this->url_prefix . "{$this->object->guid}/", $this->_l10n->get('show history'));
176
177 6
        if (!empty($this->_request_data['latest_revision'])) {
178 4
            $this->add_breadcrumb(
179 4
                $this->url_prefix . "preview/{$this->object->guid}/{$this->_request_data['latest_revision']}/",
180 4
                sprintf($this->_l10n->get('version %s'), $this->_request_data['latest_revision'])
181
            );
182
        }
183 6
        if (!empty($this->_request_data['compare_revision'])) {
184 2
            $this->add_breadcrumb(
185 2
                $this->url_prefix . "diff/{$this->object->guid}/{$this->_request_data['compare_revision']}/{$this->_request_data['latest_revision']}/",
186 2
                sprintf($this->_l10n->get('differences between %s and %s'), $this->_request_data['compare_revision'], $this->_request_data['latest_revision'])
187
            );
188
        }
189 6
        $this->_request_data['handler'] = $this;
190 6
        $this->_request_data['view_title'] = $view_title;
191 6
        midcom::get()->head->set_pagetitle($view_title);
192 6
    }
193
194 2
    public function translate($string) : string
195
    {
196 2
        $translated = $string;
197 2
        $component = midcom::get()->dbclassloader->get_component_for_class($this->object->__midcom_class_name__);
198 2
        if (midcom::get()->componentloader->is_installed($component)) {
199 2
            $translated = midcom::get()->i18n->get_l10n($component)->get($string);
200
        }
201 2
        if ($translated === $string) {
202 2
            $translated = $this->_l10n->get($string);
203 2
            if ($translated === $string) {
204 2
                $translated = $this->_l10n_midcom->get($string);
205
            }
206
        }
207 2
        return $translated;
208
    }
209
210
    /**
211
     * Show the changes done to the object
212
     */
213 2
    public function _handler_history(Request $request, string $handler_id, array $args)
214
    {
215
        // Check if the comparison request is valid
216 2
        $first = $request->query->get('first');
217 2
        $last = $request->query->get('last');
218 2
        if ($first && $last && $first != $last) {
219
            return new midcom_response_relocate($this->url_prefix . "diff/{$args[0]}/{$first}/{$last}/");
220
        }
221
222 2
        $this->load_object($args[0]);
223 2
        $view_title = sprintf($this->_l10n->get('revision history of %s'), $this->resolve_object_title());
224
225 2
        $this->rcs_toolbar();
226 2
        $this->prepare_request_data($view_title);
227 2
        return $this->handler_callback($handler_id);
228
    }
229
230
    /**
231
     * @param mixed $handler_id The ID of the handler.
232
     * @param array $data The local request data.
233
     */
234 2
    public function _show_history($handler_id, array &$data)
235
    {
236 2
        $data['history'] = $this->backend->list_history();
237 2
        $data['guid'] = $this->object->guid;
238 2
        midcom_show_style($this->style_prefix . 'history');
239 2
    }
240
241
    /**
242
     * Show a diff between two versions
243
     */
244 2
    public function _handler_diff(string $handler_id, array $args, array &$data)
245
    {
246 2
        $this->load_object($args[0]);
247
248 2
        if (   !$this->backend->version_exists($args[1])
249 2
            || !$this->backend->version_exists($args[2])) {
250
            throw new midcom_error_notfound("One of the revisions {$args[1]} or {$args[2]} does not exist.");
251
        }
252
253 2
        $data['diff'] = $this->backend->get_diff($args[1], $args[2]);
254 2
        $data['comment'] = $this->backend->get_comment($args[2]);
255
256
        // Set the version numbers
257 2
        $data['compare_revision'] = $args[1];
258 2
        $data['latest_revision'] = $args[2];
259 2
        $data['guid'] = $args[0];
260
261 2
        $view_title = sprintf($this->_l10n->get('changes done in revision %s to %s'), $data['latest_revision'], $this->resolve_object_title());
262
263
        // Load the toolbars
264 2
        $this->rcs_toolbar($args[2], true);
265 2
        $this->prepare_request_data($view_title);
266 2
        return $this->handler_callback($handler_id);
267
    }
268
269
    /**
270
     * Show the differences between the versions
271
     */
272 2
    public function _show_diff()
273
    {
274 2
        midcom_show_style($this->style_prefix . 'diff');
275 2
    }
276
277
    /**
278
     * View previews
279
     */
280 2
    public function _handler_preview(string $handler_id, array $args, array &$data)
281
    {
282 2
        $revision = $args[1];
283 2
        $data['latest_revision'] = $revision;
284 2
        $data['guid'] = $args[0];
285
286 2
        $this->load_object($args[0]);
287 2
        $data['preview'] = $this->backend->get_revision($revision);
288
289 2
        $this->_view_toolbar->hide_item($this->url_prefix . "preview/{$this->object->guid}/{$revision}/");
290
291 2
        $view_title = sprintf($this->_l10n->get('viewing version %s of %s'), $revision, $this->resolve_object_title());
292
        // Load the toolbars
293 2
        $this->rcs_toolbar($revision);
294 2
        $this->prepare_request_data($view_title);
295 2
        return $this->handler_callback($handler_id);
296
    }
297
298 2
    public function _show_preview()
299
    {
300 2
        midcom_show_style($this->style_prefix . 'preview');
301 2
    }
302
303
    /**
304
     * Restore to diff
305
     */
306
    public function _handler_restore(array $args)
307
    {
308
        $this->load_object($args[0]);
309
310
        $this->object->require_do('midgard:update');
311
        // TODO: set another privilege for restoring?
312
313
        if (   $this->backend->version_exists($args[1])
314
            && $this->backend->restore_to_revision($args[1])) {
315
            midcom::get()->uimessages->add($this->_l10n->get('midcom.admin.rcs'), sprintf($this->_l10n->get('restore to version %s successful'), $args[1]));
316
            return new midcom_response_relocate($this->get_object_url());
317
        }
318
        throw new midcom_error(sprintf($this->_l10n->get('restore to version %s failed, reason %s'), $args[1], midcom_connection::get_error_string()));
319
    }
320
}
321