]> git.mxchange.org Git - friendica.git/blob - src/App/Mode.php
API: Accept "redirect_uris" as both array and string
[friendica.git] / src / App / Mode.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\App;
23
24 use Detection\MobileDetect;
25 use Friendica\Core\Config\ValueObject\Cache;
26 use Friendica\Database\Database;
27 use Friendica\Util\BasePath;
28
29 /**
30  * Mode of the current Friendica Node
31  *
32  * @package Friendica\App
33  */
34 class Mode
35 {
36         const LOCALCONFIGPRESENT  = 1;
37         const DBAVAILABLE         = 2;
38         const DBCONFIGAVAILABLE   = 4;
39         const MAINTENANCEDISABLED = 8;
40
41         const UNDEFINED = 0;
42         const INDEX = 1;
43         const DAEMON = 2;
44         const WORKER = 3;
45
46         const BACKEND_CONTENT_TYPES = ['application/jrd+json', 'text/xml',
47                 'application/rss+xml', 'application/atom+xml', 'application/activity+json'];
48
49         /**
50          * A list of modules, which are backend methods
51          *
52          * @var array
53          */
54         const BACKEND_MODULES = [
55                 '_well_known',
56                 'api',
57                 'dfrn_notify',
58                 'feed',
59                 'fetch',
60                 'followers',
61                 'following',
62                 'hcard',
63                 'hostxrd',
64                 'inbox',
65                 'manifest',
66                 'nodeinfo',
67                 'noscrape',
68                 'objects',
69                 'outbox',
70                 'poco',
71                 'pubsub',
72                 'pubsubhubbub',
73                 'receive',
74                 'rsd_xml',
75                 'salmon',
76                 'statistics_json',
77                 'xrd',
78         ];
79
80         /***
81          * @var int The mode of this Application
82          *
83          */
84         private $mode;
85
86         /***
87          * @var int Who executes this Application
88          *
89          */
90         private $executor = self::UNDEFINED;
91
92         /**
93          * @var bool True, if the call is a backend call
94          */
95         private $isBackend;
96
97         /**
98          * @var bool True, if the call is a ajax call
99          */
100         private $isAjax;
101
102         /**
103          * @var bool True, if the call is from a mobile device
104          */
105         private $isMobile;
106
107         /**
108          * @var bool True, if the call is from a tablet device
109          */
110         private $isTablet;
111
112         public function __construct(int $mode = 0, bool $isBackend = false, bool $isAjax = false, bool $isMobile = false, bool $isTablet = false)
113         {
114                 $this->mode      = $mode;
115                 $this->isBackend = $isBackend;
116                 $this->isAjax    = $isAjax;
117                 $this->isMobile  = $isMobile;
118                 $this->isTablet  = $isTablet;
119         }
120
121         /**
122          * Sets the App mode
123          *
124          * - App::MODE_INSTALL    : Either the database connection can't be established or the config table doesn't exist
125          * - App::MODE_MAINTENANCE: The maintenance mode has been set
126          * - App::MODE_NORMAL     : Normal run with all features enabled
127          *
128          * @return Mode returns the determined mode
129          *
130          * @throws \Exception
131          */
132         public function determine(BasePath $basepath, Database $database, Cache $configCache): Mode
133         {
134                 $mode = 0;
135
136                 $basepathName = $basepath->getPath();
137
138                 if (!file_exists($basepathName . '/config/local.config.php')
139                     && !file_exists($basepathName . '/config/local.ini.php')
140                     && !file_exists($basepathName . '/.htconfig.php')) {
141                         return new Mode($mode);
142                 }
143
144                 $mode |= Mode::LOCALCONFIGPRESENT;
145
146                 if (!$database->connected()) {
147                         return new Mode($mode);
148                 }
149
150                 $mode |= Mode::DBAVAILABLE;
151
152                 if (!empty($configCache->get('system', 'maintenance'))) {
153                         return new Mode($mode);
154                 }
155
156                 $mode |= Mode::MAINTENANCEDISABLED;
157
158                 return new Mode($mode, $this->isBackend, $this->isAjax, $this->isMobile, $this->isTablet);
159         }
160
161         /**
162          * Checks if the site is called via a backend process
163          *
164          * @param bool             $isBackend    True, if the call is from a backend script (daemon, worker, ...)
165          * @param array            $server       The $_SERVER variable
166          * @param Arguments        $args         The Friendica App arguments
167          * @param MobileDetect     $mobileDetect The mobile detection library
168          *
169          * @return Mode returns the determined mode
170          */
171         public function determineRunMode(bool $isBackend, array $server, Arguments $args, MobileDetect $mobileDetect): Mode
172         {
173                 foreach (self::BACKEND_CONTENT_TYPES as $type) {
174                         if (strpos(strtolower($server['HTTP_ACCEPT'] ?? ''), $type) !== false) {
175                                 $isBackend = true;
176                         }
177                 }
178
179                 $isBackend = $isBackend || in_array($args->getModuleName(), static::BACKEND_MODULES);
180                 $isMobile  = $mobileDetect->isMobile();
181                 $isTablet  = $mobileDetect->isTablet();
182                 $isAjax    = strtolower($server['HTTP_X_REQUESTED_WITH'] ?? '') == 'xmlhttprequest';
183
184                 return new Mode($this->mode, $isBackend, $isAjax, $isMobile, $isTablet);
185         }
186
187         /**
188          * Checks, if the Friendica Node has the given mode
189          *
190          * @param int $mode A mode to test
191          *
192          * @return bool returns true, if the mode is set
193          */
194         public function has(int $mode): bool
195         {
196                 return ($this->mode & $mode) > 0;
197         }
198
199         /**
200          * Set the execution mode
201          *
202          * @param integer $executor Execution Mode
203          * @return void
204          */
205         public function setExecutor(int $executor)
206         {
207                 $this->executor = $executor;
208
209                 // Daemon and worker are always backend
210                 if (in_array($executor, [self::DAEMON, self::WORKER])) {
211                         $this->isBackend = true;
212                 }
213         }
214
215         /*isBackend = true;*
216          * get the execution mode
217          *
218          * @return int Execution Mode
219          */
220         public function getExecutor(): int
221         {
222                 return $this->executor;
223         }
224
225         /**
226          * Install mode is when the local config file is missing or the database isn't available.
227          *
228          * @return bool Whether installation mode is active (local/database configuration files present or not)
229          */
230         public function isInstall(): bool
231         {
232                 return !$this->has(Mode::LOCALCONFIGPRESENT) ||
233                        !$this->has(MODE::DBAVAILABLE);
234         }
235
236         /**
237          * Normal mode is when the local config file is set, the DB schema is installed and the maintenance mode is off.
238          *
239          * @return bool
240          */
241         public function isNormal(): bool
242         {
243                 return $this->has(Mode::LOCALCONFIGPRESENT) &&
244                        $this->has(Mode::DBAVAILABLE) &&
245                        $this->has(Mode::MAINTENANCEDISABLED);
246         }
247
248         /**
249          * Returns true, if the call is from a backend node (f.e. from a worker)
250          *
251          * @return bool Is it a backend call
252          */
253         public function isBackend(): bool
254         {
255                 return $this->isBackend;
256         }
257
258         /**
259          * Check if request was an AJAX (xmlhttprequest) request.
260          *
261          * @return bool true if it was an AJAX request
262          */
263         public function isAjax(): bool
264         {
265                 return $this->isAjax;
266         }
267
268         /**
269          * Check if request was a mobile request.
270          *
271          * @return bool true if it was an mobile request
272          */
273         public function isMobile(): bool
274         {
275                 return $this->isMobile;
276         }
277
278         /**
279          * Check if request was a tablet request.
280          *
281          * @return bool true if it was an tablet request
282          */
283         public function isTablet(): bool
284         {
285                 return $this->isTablet;
286         }
287 }