ShareDraftController   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 148
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
eloc 53
c 4
b 0
f 1
dl 0
loc 148
rs 10
wmc 11

5 Methods

Rating   Name   Duplication   Size   Complexity  
A errorPage() 0 4 1
A getIsDraftSecured() 0 9 2
A setIsDraftSecured() 0 9 2
A getControllerFor() 0 3 1
A preview() 0 65 5
1
<?php
2
3
namespace SilverStripe\ShareDraftContent\Controllers;
4
5
use BadMethodCallException;
6
use PageController;
0 ignored issues
show
Bug introduced by
The type PageController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use SilverStripe\CMS\Controllers\ContentController;
8
use SilverStripe\CMS\Controllers\ModelAsController;
9
use SilverStripe\CMS\Model\SiteTree;
10
use SilverStripe\Control\Controller;
11
use SilverStripe\Control\HTTPRequest;
12
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
13
use SilverStripe\Control\Session;
14
use SilverStripe\Core\Injector\Injector;
15
use SilverStripe\ORM\FieldType\DBHTMLText;
16
use SilverStripe\ShareDraftContent\Extensions\ShareDraftContentSiteTreeExtension;
17
use SilverStripe\ShareDraftContent\Models\ShareToken;
18
use SilverStripe\Versioned\Versioned;
19
use SilverStripe\View\ArrayData;
20
use SilverStripe\View\Requirements;
21
22
class ShareDraftController extends Controller
23
{
24
    /**
25
     * Controller for rendering draft pages.
26
     *
27
     * @config
28
     *
29
     * @var string
30
     */
31
    private static $controller = PageController::class;
0 ignored issues
show
introduced by
The private property $controller is not used, and could be removed.
Loading history...
32
33
    /**
34
     * @var array
35
     */
36
    private static $allowed_actions = array(
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
37
        'preview'
38
    );
39
40
    /**
41
     * @var array
42
     */
43
    private static $url_handlers = array(
0 ignored issues
show
introduced by
The private property $url_handlers is not used, and could be removed.
Loading history...
44
        '$Key/$Token' => 'preview'
45
    );
46
47
    /**
48
     * @param HTTPRequest $request
49
     *
50
     * @return string|DBHTMLText
51
     */
52
    public function preview(HTTPRequest $request)
53
    {
54
        // Ensure this URL doesn't get picked up by HTTP caches
55
        HTTPCacheControlMiddleware::singleton()->disableCache();
56
57
        $key = $request->param('Key');
58
        $token = $request->param('Token');
59
        try {
60
            $session = $this->getRequest()->getSession();
61
        } catch (BadMethodCallException $e) {
62
            // Create a new session
63
            $session = $this->getRequest()
64
                ->setSession(Injector::inst()->create(Session::class, []))
65
                ->getSession();
66
        }
67
        /** @var ShareToken $shareToken */
68
        $shareToken = ShareToken::get()->filter('Token', $token)->first();
69
70
        if (!$shareToken) {
0 ignored issues
show
introduced by
$shareToken is of type SilverStripe\ShareDraftContent\Models\ShareToken, thus it always evaluated to true.
Loading history...
71
            return $this->errorPage();
72
        }
73
74
        /** @var SiteTree|ShareDraftContentSiteTreeExtension $page */
75
        $page = Versioned::get_by_stage(SiteTree::class, Versioned::DRAFT)
76
            ->byID($shareToken->PageID);
77
78
        $latest = Versioned::get_latest_version(SiteTree::class, $shareToken->PageID);
79
80
        $controller = $this->getControllerFor($page);
81
82
        if (!$shareToken->isExpired() && $page->generateKey($shareToken->Token) === $key) {
83
            Requirements::css('silverstripe/sharedraftcontent: client/dist/styles/bundle-frontend.css');
84
85
            // Temporarily un-secure the draft site and switch to draft
86
            $oldSecured = $this->getIsDraftSecured($session);
87
            $oldMode = Versioned::get_reading_mode();
88
89
            // Process page inside an unsecured draft container
90
            try {
91
                $this->setIsDraftSecured($session, false);
92
                Versioned::set_stage('Stage');
93
94
                // Hack to get around ContentController::init() redirecting on home page
95
                $_FILES = array(array());
96
97
                // Create mock request; Simplify request to single top level request
98
                $pageRequest = new HTTPRequest('GET', $page->URLSegment);
99
                $pageRequest->match('$URLSegment//$Action/$ID/$OtherID', true);
100
                $pageRequest->setSession($session);
101
                $rendered = $controller->handleRequest($pageRequest);
102
103
                // Render draft heading
104
                $data = new ArrayData(array(
105
                    'Page' => $page,
106
                    'Latest' => $latest,
107
                ));
108
                $include = (string) $data->renderWith('Includes/TopBar');
109
            } finally {
110
                $this->setIsDraftSecured($session, $oldSecured);
111
                Versioned::set_reading_mode($oldMode);
112
            }
113
114
            return str_replace('</body>', $include . '</body>', (string) $rendered->getBody());
115
        } else {
116
            return $this->errorPage();
117
        }
118
    }
119
120
    /**
121
     * @return DBHTMLText
122
     */
123
    protected function errorPage()
124
    {
125
        Requirements::css('silverstripe/sharedraftcontent: client/dist/styles/bundle-frontend.css');
126
        return $this->renderWith('ShareDraftContentError');
127
    }
128
129
    /**
130
     * @param SiteTree $page
131
     * @return ContentController
132
     */
133
    protected function getControllerFor($page)
134
    {
135
        return ModelAsController::controller_for($page);
136
    }
137
138
    /**
139
     * Check if the draft site is secured
140
     *
141
     * @param Session $session
142
     * @return bool True if the draft site is secured
143
     */
144
    protected function getIsDraftSecured(Session $session)
145
    {
146
        // Versioned >=1.2
147
        if (method_exists(Versioned::class, 'get_draft_site_secured')) {
148
            return Versioned::get_draft_site_secured();
149
        }
150
151
        // Fall back to session
152
        return !$session->get('unsecuredDraftSite');
153
    }
154
155
    /**
156
     * Set draft site security
157
     *
158
     * @param Session $session
159
     * @param bool $secured True if draft site should be secured
160
     */
161
    protected function setIsDraftSecured(Session $session, $secured)
162
    {
163
        // Versioned >=1.2
164
        if (method_exists(Versioned::class, 'set_draft_site_secured')) {
165
            Versioned::set_draft_site_secured($secured);
166
        }
167
168
        // Set session variable anyway
169
        $session->set('unsecuredDraftSite', !$secured);
170
    }
171
}
172