1<?php
2
3/*
4 * This file is part of the TYPO3 CMS project.
5 *
6 * It is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License, either version 2
8 * of the License, or any later version.
9 *
10 * For the full copyright and license information, please read the
11 * LICENSE.txt file that was distributed with this source code.
12 *
13 * The TYPO3 project - inspiring people to share!
14 */
15
16namespace TYPO3\CMS\Core\Core;
17
18use TYPO3\CMS\Core\Exception;
19
20/**
21 * The TYPO3 Context object.
22 *
23 * A TYPO3 Application context is something like "Production", "Development",
24 * "Production/StagingSystem", and is set using the TYPO3_CONTEXT environment variable.
25 *
26 * A context can contain arbitrary sub-contexts, which are delimited with slash
27 * ("Production/StagingSystem", "Production/Staging/Server1"). The top-level
28 * contexts, however, must be one of "Testing", "Development" and "Production".
29 *
30 * Mainly, you will use $context->isProduction(), $context->isTesting() and
31 * $context->isDevelopment() inside your custom code.
32 *
33 * This class is derived from the TYPO3 Flow framework.
34 * Credits go to the respective authors.
35 */
36class ApplicationContext
37{
38    /**
39     * The (internal) context string; could be something like "Development" or "Development/MyLocalMacBook"
40     *
41     * @var string
42     */
43    protected $contextString;
44
45    /**
46     * The root context; must be one of "Development", "Testing" or "Production"
47     *
48     * @var string
49     */
50    protected $rootContextString;
51
52    /**
53     * The parent context, or NULL if there is no parent context
54     *
55     * @var \TYPO3\CMS\Core\Core\ApplicationContext|null
56     */
57    protected $parentContext;
58
59    /**
60     * Initialize the context object.
61     *
62     * @param string $contextString
63     * @throws Exception if the parent context is none of "Development", "Production" or "Testing"
64     */
65    public function __construct($contextString)
66    {
67        if (!str_contains($contextString, '/')) {
68            $this->rootContextString = $contextString;
69            $this->parentContext = null;
70        } else {
71            $contextStringParts = explode('/', $contextString);
72            $this->rootContextString = $contextStringParts[0];
73            array_pop($contextStringParts);
74            $this->parentContext = new self(implode('/', $contextStringParts));
75        }
76
77        if (!in_array($this->rootContextString, ['Development', 'Production', 'Testing'], true)) {
78            throw new Exception('The given context "' . $contextString . '" was not valid. Only allowed are Development, Production and Testing, including their sub-contexts', 1335436551);
79        }
80
81        $this->contextString = $contextString;
82    }
83
84    /**
85     * Returns the full context string, for example "Development", or "Production/LiveSystem"
86     *
87     * @return string
88     */
89    public function __toString()
90    {
91        return $this->contextString;
92    }
93
94    /**
95     * Returns TRUE if this context is the Development context or a sub-context of it
96     *
97     * @return bool
98     */
99    public function isDevelopment()
100    {
101        return $this->rootContextString === 'Development';
102    }
103
104    /**
105     * Returns TRUE if this context is the Production context or a sub-context of it
106     *
107     * @return bool
108     */
109    public function isProduction()
110    {
111        return $this->rootContextString === 'Production';
112    }
113
114    /**
115     * Returns TRUE if this context is the Testing context or a sub-context of it
116     *
117     * @return bool
118     */
119    public function isTesting()
120    {
121        return $this->rootContextString === 'Testing';
122    }
123
124    /**
125     * Returns the parent context object, if any
126     *
127     * @return \TYPO3\CMS\Core\Core\ApplicationContext|null the parent context or NULL, if there is none
128     */
129    public function getParent()
130    {
131        return $this->parentContext;
132    }
133}
134