]> git.mxchange.org Git - friendica.git/blob - src/App/Arguments.php
Merge pull request #1 from friendica/develop
[friendica.git] / src / App / Arguments.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
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 /**
25  * Determine all arguments of the current call, including
26  * - The whole querystring (except the pagename/q parameter)
27  * - The command
28  * - The arguments (C-Style based)
29  * - The count of arguments
30  */
31 class Arguments
32 {
33         /**
34          * @var string The complete query string
35          */
36         private $queryString;
37         /**
38          * @var string The current Friendica command
39          */
40         private $command;
41         /**
42          * @var array The arguments of the current execution
43          */
44         private $argv;
45         /**
46          * @var int The count of arguments
47          */
48         private $argc;
49
50         public function __construct(string $queryString = '', string $command = '', array $argv = [Module::DEFAULT], int $argc = 1)
51         {
52                 $this->queryString = $queryString;
53                 $this->command     = $command;
54                 $this->argv        = $argv;
55                 $this->argc        = $argc;
56         }
57
58         /**
59          * @return string The whole query string of this call
60          */
61         public function getQueryString()
62         {
63                 return $this->queryString;
64         }
65
66         /**
67          * @return string The whole command of this call
68          */
69         public function getCommand()
70         {
71                 return $this->command;
72         }
73
74         /**
75          * @return array All arguments of this call
76          */
77         public function getArgv()
78         {
79                 return $this->argv;
80         }
81
82         /**
83          * @return int The count of arguments of this call
84          */
85         public function getArgc()
86         {
87                 return $this->argc;
88         }
89
90         /**
91          * Returns the value of a argv key
92          * @todo there are a lot of $a->argv usages in combination with ?? which can be replaced with this method
93          *
94          * @param int   $position the position of the argument
95          * @param mixed $default  the default value if not found
96          *
97          * @return mixed returns the value of the argument
98          */
99         public function get(int $position, $default = '')
100         {
101                 return $this->has($position) ? $this->argv[$position] : $default;
102         }
103
104         /**
105          * @param int $position
106          *
107          * @return bool if the argument position exists
108          */
109         public function has(int $position)
110         {
111                 return array_key_exists($position, $this->argv);
112         }
113
114         /**
115          * Determine the arguments of the current call
116          *
117          * @param array $server The $_SERVER variable
118          * @param array $get    The $_GET variable
119          *
120          * @return Arguments The determined arguments
121          */
122         public function determine(array $server, array $get)
123         {
124                 $queryString = '';
125
126                 if (!empty($server['QUERY_STRING']) && strpos($server['QUERY_STRING'], 'pagename=') === 0) {
127                         $queryString = urldecode(substr($server['QUERY_STRING'], 9));
128                 } elseif (!empty($server['QUERY_STRING']) && strpos($server['QUERY_STRING'], 'q=') === 0) {
129                         $queryString = urldecode(substr($server['QUERY_STRING'], 2));
130                 }
131
132                 // eventually strip ZRL
133                 $queryString = $this->stripZRLs($queryString);
134
135                 // eventually strip OWT
136                 $queryString = $this->stripQueryParam($queryString, 'owt');
137
138                 // removing trailing / - maybe a nginx problem
139                 $queryString = ltrim($queryString, '/');
140
141                 if (!empty($get['pagename'])) {
142                         $command = trim($get['pagename'], '/\\');
143                 } elseif (!empty($get['q'])) {
144                         $command = trim($get['q'], '/\\');
145                 } else {
146                         $command = Module::DEFAULT;
147                 }
148
149
150                 // fix query_string
151                 if (!empty($command)) {
152                         $queryString = str_replace(
153                                 $command . '&',
154                                 $command . '?',
155                                 $queryString
156                         );
157                 }
158
159                 // unix style "homedir"
160                 if (substr($command, 0, 1) === '~') {
161                         $command = 'profile/' . substr($command, 1);
162                 }
163
164                 // Diaspora style profile url
165                 if (substr($command, 0, 2) === 'u/') {
166                         $command = 'profile/' . substr($command, 2);
167                 }
168
169                 /*
170                  * Break the URL path into C style argc/argv style arguments for our
171                  * modules. Given "http://example.com/module/arg1/arg2", $this->argc
172                  * will be 3 (integer) and $this->argv will contain:
173                  *   [0] => 'module'
174                  *   [1] => 'arg1'
175                  *   [2] => 'arg2'
176                  *
177                  *
178                  * There will always be one argument. If provided a naked domain
179                  * URL, $this->argv[0] is set to "home".
180                  */
181
182                 $argv = explode('/', $command);
183                 $argc = count($argv);
184
185
186                 return new Arguments($queryString, $command, $argv, $argc);
187         }
188
189         /**
190          * Strip zrl parameter from a string.
191          *
192          * @param string $queryString The input string.
193          *
194          * @return string The zrl.
195          */
196         public function stripZRLs(string $queryString)
197         {
198                 return preg_replace('/[?&]zrl=(.*?)(&|$)/ism', '$2', $queryString);
199         }
200
201         /**
202          * Strip query parameter from a string.
203          *
204          * @param string $queryString The input string.
205          * @param string $param
206          *
207          * @return string The query parameter.
208          */
209         public function stripQueryParam(string $queryString, string $param)
210         {
211                 return preg_replace('/[?&]' . $param . '=(.*?)(&|$)/ism', '$2', $queryString);
212         }
213 }