Issues (144)

src/Middleware/InitStateMiddleware.php (2 issues)

1
<?php
2
3
namespace SilverStripe\Subsites\Middleware;
4
5
use SilverStripe\Admin\AdminRootController;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverStripe\Control\Middleware\HTTPMiddleware;
8
use SilverStripe\Core\Config\Configurable;
9
use SilverStripe\Core\Injector\Injector;
10
use SilverStripe\ORM\Connect\DatabaseException;
11
use SilverStripe\Subsites\Model\Subsite;
12
use SilverStripe\Subsites\State\SubsiteState;
13
14
class InitStateMiddleware implements HTTPMiddleware
15
{
16
    use Configurable;
17
18
    /**
19
     * URL paths that should be considered as admin only, i.e. not frontend
20
     *
21
     * @config
22
     * @var array
23
     */
24
    private static $admin_url_paths = [
0 ignored issues
show
The private property $admin_url_paths is not used, and could be removed.
Loading history...
25
        'dev/',
26
        'graphql/',
27
    ];
28
29
    public function process(HTTPRequest $request, callable $delegate)
30
    {
31
        try {
32
            // Initialise and register the State
33
            $state = SubsiteState::create();
34
            Injector::inst()->registerService($state);
35
36
            // Detect whether the request was made in the CMS area (or other admin-only areas)
37
            $isAdmin = $this->getIsAdmin($request);
38
            $state->setUseSessions($isAdmin);
39
40
            // Detect the subsite ID
41
            $subsiteId = $this->detectSubsiteId($request);
42
            $state->setSubsiteId($subsiteId);
43
44
            return $delegate($request);
45
        } catch (DatabaseException $ex) {
46
            $message = $ex->getMessage();
47
            if (strpos($message, 'No database selected') !== false
48
                || preg_match('/\s*(table|relation) .* does(n\'t| not) exist/i', $message)
49
            ) {
50
                // Database is not ready, ignore and continue. Either it doesn't exist or it has no tables
51
                return $delegate($request);
52
            }
53
            throw $ex;
54
        } finally {
55
            // Persist to the session if using the CMS
56
            if ($state->getUseSessions()) {
57
                $request->getSession()->set('SubsiteID', $state->getSubsiteId());
58
            }
59
        }
60
    }
61
62
    /**
63
     * Determine whether the website is being viewed from an admin protected area or not
64
     *
65
     * @param  HTTPRequest $request
66
     * @return bool
67
     */
68
    public function getIsAdmin(HTTPRequest $request)
69
    {
70
        $adminPaths = static::config()->get('admin_url_paths');
71
        $adminPaths[] = AdminRootController::admin_url();
72
        $currentPath = rtrim($request->getURL(), '/') . '/';
73
        foreach ($adminPaths as $adminPath) {
74
            if (substr($currentPath, 0, strlen($adminPath)) === $adminPath) {
75
                return true;
76
            }
77
        }
78
        return false;
79
    }
80
81
    /**
82
     * Use the given request to detect the current subsite ID
83
     *
84
     * @param  HTTPRequest $request
85
     * @return int
86
     */
87
    protected function detectSubsiteId(HTTPRequest $request)
88
    {
89
        if ($request->getVar('SubsiteID') !== null) {
90
            return (int) $request->getVar('SubsiteID');
91
        }
92
93
        if (SubsiteState::singleton()->getUseSessions() && $request->getSession()->get('SubsiteID') !== null) {
94
            return (int) $request->getSession()->get('SubsiteID');
95
        }
96
97
        $subsiteIdFromDomain = Subsite::getSubsiteIDForDomain($request->getHost());
98
        if ($subsiteIdFromDomain !== null) {
0 ignored issues
show
The condition $subsiteIdFromDomain !== null is always true.
Loading history...
99
            return (int) $subsiteIdFromDomain;
100
        }
101
102
        // Default fallback
103
        return 0;
104
    }
105
}
106