Completed
Pull Request — master (#64)
by Robbie
01:34
created

ContentReviewCMSExtension::getReviewContentForm()   B

Complexity

Conditions 5
Paths 3

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.439
c 0
b 0
f 0
cc 5
eloc 17
nc 3
nop 1
1
<?php
2
3
namespace SilverStripe\ContentReview\Extensions;
4
5
use SilverStripe\Admin\LeftAndMain;
6
use SilverStripe\Admin\LeftAndMainExtension;
7
use SilverStripe\CMS\Model\SiteTree;
8
use SilverStripe\ContentReview\Forms\ReviewContentHandler;
9
use SilverStripe\Control\HTTPRequest;
10
use SilverStripe\Control\HTTPResponse;
11
use SilverStripe\Control\HTTPResponse_Exception;
12
use SilverStripe\Core\Convert;
13
use SilverStripe\Forms\Form;
14
use SilverStripe\ORM\ValidationResult;
15
use SilverStripe\Security\Security;
16
17
/**
18
 * CMSPageEditController extension to receive the additional action button from
19
 * SiteTreeContentReview::updateCMSActions()
20
 */
21
class ContentReviewCMSExtension extends LeftAndMainExtension
22
{
23
    private static $allowed_actions = [
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $allowed_actions is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
24
        'ReviewContentForm',
25
        'savereview',
26
    ];
27
28
    /**
29
     * URL handler for the "content due for review" form
30
     *
31
     * @param HTTPRequest $request
32
     * @return Form|null
33
     */
34
    public function ReviewContentForm(HTTPRequest $request)
35
    {
36
        // Get ID either from posted back value, or url parameter
37
        $id = $request->param('ID') ?: $request->postVar('ID');
38
        return $this->getReviewContentForm($id);
39
    }
40
41
    /**
42
     * Return a handler for "content due for review" forms, according to the given object ID
43
     *
44
     * @param  int $id
45
     * @return Form|null
46
     */
47
    public function getReviewContentForm($id)
48
    {
49
        $page = $this->findRecord(['ID' => $id]);
50
        if (!$page) {
51
            $this->owner->httpError(404, _t(__CLASS__ . '.ErrorNotFound', 'That object couldn\'t be found'));
52
            return null;
53
        }
54
55
        $user = Security::getCurrentUser();
56
        if (!$page->canEdit() || ($page->hasMethod('canBeReviewedBy') && !$page->canBeReviewedBy($user))) {
57
            $this->owner->httpError(403, _t(
58
                __CLASS__.'.ErrorItemPermissionDenied',
59
                'It seems you don\'t have the necessary permissions to review this content'
60
            ));
61
            return null;
62
        }
63
64
        $handler = ReviewContentHandler::create($this->owner);
65
        $form = $handler->Form($page);
66
67
        $form->setValidationResponseCallback(function (ValidationResult $errors) use ($form, $id) {
68
            $schemaId = $this->owner->join_links($this->owner->Link('schema/ReviewContentForm'), $id);
69
            return $this->owner->getSchemaResponse($schemaId, $form, $errors);
70
        });
71
72
        return $form;
73
    }
74
75
    /**
76
     * Action handler for processing the submitted content review
77
     *
78
     * @param array $data
79
     * @param Form $form
80
     * @return DBHTMLText|HTTPResponse|null
81
     */
82
    public function savereview($data, Form $form)
83
    {
84
        $page = $this->findRecord($data);
85
86
        $handler = ReviewContentHandler::create($this->owner);
87
        $results = $handler->submitReview($page, $data);
88
        if (is_null($results)) {
89
            return null;
90
        }
91
        if ($this->getSchemaRequested()) {
92
            // Send extra "message" data with schema response
93
            $extraData = ['message' => $results];
94
            $schemaId = $this->owner->join_links($this->owner->Link('schema/ReviewContentForm'), $page->ID);
95
            return $this->getSchemaResponse($schemaId, $form, null, $extraData);
96
        }
97
98
        return $results;
99
    }
100
101
    /**
102
     * Find the page this form is updating
103
     *
104
     * @param array $data Form data
105
     * @return SiteTree Record
106
     * @throws HTTPResponse_Exception
107
     */
108
    protected function findRecord($data)
109
    {
110
        if (empty($data["ID"])) {
111
            throw new HTTPResponse_Exception("No record ID", 404);
112
        }
113
        $page = null;
114
        $id = $data["ID"];
115
        if (is_numeric($id)) {
116
            $page = SiteTree::get()->byID($id);
117
        }
118
        if (!$page || !$page->ID) {
119
            throw new HTTPResponse_Exception("Bad record ID #{$id}", 404);
120
        }
121
        return $page;
122
    }
123
124
    /**
125
     * Check if the current request has a X-Formschema-Request header set.
126
     * Used by conditional logic that responds to validation results
127
     *
128
     * @todo Remove duplication. See https://github.com/silverstripe/silverstripe-admin/issues/240
129
     *
130
     * @return bool
131
     */
132
    protected function getSchemaRequested()
133
    {
134
        $parts = $this->owner->getRequest()->getHeader(LeftAndMain::SCHEMA_HEADER);
135
        return !empty($parts);
136
    }
137
138
    /**
139
     * Generate schema for the given form based on the X-Formschema-Request header value
140
     *
141
     * @todo Remove duplication. See https://github.com/silverstripe/silverstripe-admin/issues/240
142
     *
143
     * @param string $schemaID ID for this schema. Required.
144
     * @param Form $form Required for 'state' or 'schema' response
145
     * @param ValidationResult $errors Required for 'error' response
146
     * @param array $extraData Any extra data to be merged with the schema response
147
     * @return HTTPResponse
148
     */
149
    protected function getSchemaResponse($schemaID, $form = null, ValidationResult $errors = null, $extraData = [])
150
    {
151
        $parts = $this->owner->getRequest()->getHeader(LeftAndMain::SCHEMA_HEADER);
152
        $data = $this->owner
153
            ->getFormSchema()
154
            ->getMultipartSchema($parts, $schemaID, $form, $errors);
155
156
        if ($extraData) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $extraData of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
157
            $data = array_merge($data, $extraData);
158
        }
159
160
        $response = HTTPResponse::create(Convert::raw2json($data));
161
        $response->addHeader('Content-Type', 'application/json');
162
163
        return $response;
164
    }
165
}
166