]> git.mxchange.org Git - friendica.git/blob - src/Core/System.php
Merge pull request #5907 from nupplaphil/goaway_to_redirectto
[friendica.git] / src / Core / System.php
1 <?php
2 /**
3  * @file src/Core/System.php
4  */
5 namespace Friendica\Core;
6
7 use Friendica\BaseObject;
8 use Friendica\Network\HTTPException\InternalServerErrorException;
9 use Friendica\Util\XML;
10
11 /**
12  * @file include/Core/System.php
13  *
14  * @brief Contains the class with system relevant stuff
15  */
16
17
18 /**
19  * @brief System methods
20  */
21 class System extends BaseObject
22 {
23         /**
24          * @brief Retrieves the Friendica instance base URL
25          *
26          * @param bool $ssl Whether to append http or https under SSL_POLICY_SELFSIGN
27          * @return string Friendica server base URL
28          */
29         public static function baseUrl($ssl = false)
30         {
31                 return self::getApp()->getBaseURL($ssl);
32         }
33
34         /**
35          * @brief Removes the baseurl from an url. This avoids some mixed content problems.
36          *
37          * @param string $orig_url The url to be cleaned
38          *
39          * @return string The cleaned url
40          */
41         public static function removedBaseUrl($orig_url)
42         {
43                 return self::getApp()->removeBaseURL($orig_url);
44         }
45
46         /**
47          * @brief Returns a string with a callstack. Can be used for logging.
48          * @param integer $depth optional, default 4
49          * @return string
50          */
51         public static function callstack($depth = 4)
52         {
53                 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
54
55                 // We remove the first two items from the list since they contain data that we don't need.
56                 array_shift($trace);
57                 array_shift($trace);
58
59                 $callstack = [];
60                 $counter = 0;
61                 $previous = ['class' => '', 'function' => ''];
62
63                 // The ignore list contains all functions that are only wrapper functions
64                 $ignore = ['fetchUrl', 'call_user_func_array'];
65
66                 while ($func = array_pop($trace)) {
67                         if (!empty($func['class'])) {
68                                 // Don't show multiple calls from the "dba" class to show the essential parts of the callstack
69                                 if ((($previous['class'] != $func['class']) || ($func['class'] != 'Friendica\Database\DBA')) && ($previous['function'] != 'q')) {
70                                         $classparts = explode("\\", $func['class']);
71                                         $callstack[] = array_pop($classparts).'::'.$func['function'];
72                                         $previous = $func;
73                                 }
74                         } elseif (!in_array($func['function'], $ignore)) {
75                                 $callstack[] = $func['function'];
76                                 $func['class'] = '';
77                                 $previous = $func;
78                         }
79                 }
80
81                 $callstack2 = [];
82                 while ((count($callstack2) < $depth) && (count($callstack) > 0)) {
83                         $callstack2[] = array_pop($callstack);
84                 }
85
86                 return implode(', ', $callstack2);
87         }
88
89         /**
90          * Generic XML return
91          * Outputs a basic dfrn XML status structure to STDOUT, with a <status> variable
92          * of $st and an optional text <message> of $message and terminates the current process.
93          */
94         public static function xmlExit($st, $message = '')
95         {
96                 $result = ['status' => $st];
97
98                 if ($message != '') {
99                         $result['message'] = $message;
100                 }
101
102                 if ($st) {
103                         logger('xml_status returning non_zero: ' . $st . " message=" . $message);
104                 }
105
106                 header("Content-type: text/xml");
107
108                 $xmldata = ["result" => $result];
109
110                 echo XML::fromArray($xmldata, $xml);
111
112                 killme();
113         }
114
115         /**
116          * @brief Send HTTP status header and exit.
117          *
118          * @param integer $val         HTTP status result value
119          * @param array   $description optional message
120          *                             'title' => header title
121          *                             'description' => optional message
122          */
123         public static function httpExit($val, $description = [])
124         {
125                 $err = '';
126                 if ($val >= 400) {
127                         $err = 'Error';
128                         if (!isset($description["title"])) {
129                                 $description["title"] = $err." ".$val;
130                         }
131                 }
132
133                 if ($val >= 200 && $val < 300) {
134                         $err = 'OK';
135                 }
136
137                 logger('http_status_exit ' . $val);
138                 header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $err);
139
140                 if (isset($description["title"])) {
141                         $tpl = get_markup_template('http_status.tpl');
142                         echo replace_macros($tpl, ['$title' => $description["title"],
143                                 '$description' => defaults($description, 'description', '')]);
144                 }
145
146                 exit();
147         }
148
149         /**
150          * @brief Encodes content to json.
151          *
152          * This function encodes an array to json format
153          * and adds an application/json HTTP header to the output.
154          * After finishing the process is getting killed.
155          *
156          * @param array  $x The input content.
157          * @param string $content_type Type of the input (Default: 'application/json').
158          */
159         public static function jsonExit($x, $content_type = 'application/json') {
160                 header("Content-type: $content_type");
161                 echo json_encode($x);
162                 killme();
163         }
164
165         /**
166          * Generates a random string in the UUID format
167          *
168          * @param bool|string  $prefix   A given prefix (default is empty)
169          * @return string a generated UUID
170          */
171         public static function createUUID($prefix = '')
172         {
173                 $guid = System::createGUID(32, $prefix);
174                 return substr($guid, 0, 8). '-' . substr($guid, 8, 4) . '-' . substr($guid, 12, 4) . '-' . substr($guid, 16, 4) . '-' . substr($guid, 20, 12);
175         }
176
177         /**
178          * Generates a GUID with the given parameters
179          *
180          * @param int          $size     The size of the GUID (default is 16)
181          * @param bool|string  $prefix   A given prefix (default is empty)
182          * @return string a generated GUID
183          */
184         public static function createGUID($size = 16, $prefix = '')
185         {
186                 if (is_bool($prefix) && !$prefix) {
187                         $prefix = '';
188                 } elseif (empty($prefix)) {
189                         $prefix = hash('crc32', self::getApp()->getHostName());
190                 }
191
192                 while (strlen($prefix) < ($size - 13)) {
193                         $prefix .= mt_rand();
194                 }
195
196                 if ($size >= 24) {
197                         $prefix = substr($prefix, 0, $size - 22);
198                         return str_replace('.', '', uniqid($prefix, true));
199                 } else {
200                         $prefix = substr($prefix, 0, max($size - 13, 0));
201                         return uniqid($prefix);
202                 }
203         }
204
205         /**
206          * Generates a process identifier for the logging
207          *
208          * @param string $prefix A given prefix
209          *
210          * @return string a generated process identifier
211          */
212         public static function processID($prefix)
213         {
214                 // We aren't calling any other function here.
215                 // Doing so could easily create an endless loop
216                 $trailer = $prefix . ':' . getmypid() . ':';
217                 return substr($trailer . uniqid('') . mt_rand(), 0, 26);
218         }
219
220         /**
221          * Returns the current Load of the System
222          *
223          * @return integer
224          */
225         public static function currentLoad()
226         {
227                 if (!function_exists('sys_getloadavg')) {
228                         return false;
229                 }
230
231                 $load_arr = sys_getloadavg();
232
233                 if (!is_array($load_arr)) {
234                         return false;
235                 }
236
237                 return max($load_arr[0], $load_arr[1]);
238         }
239
240         /**
241          * Redirects to an external URL (fully qualified URL)
242          * If you want to route relative to the current Friendica base, use App->internalRedirect()
243          *
244          * @param string $url The new Location to redirect
245          * @throws InternalServerErrorException If the URL is not fully qualified
246          */
247         public static function externalRedirect($url)
248         {
249                 if (!filter_var($url, FILTER_VALIDATE_URL)) {
250                         throw new InternalServerErrorException('URL is not a fully qualified URL, please use App->internalRedirect() instead');
251                 }
252
253                 header("Location: $url");
254                 exit();
255         }
256
257         /// @todo Move the following functions from boot.php
258         /*
259         function killme()
260         function local_user()
261         function public_contact()
262         function remote_user()
263         function notice($s)
264         function info($s)
265         function is_site_admin()
266         function random_digits($digits)
267         function get_server()
268         function get_temppath()
269         function get_cachefile($file, $writemode = true)
270         function get_itemcachepath()
271         function get_spoolpath()
272         */
273 }