1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Joomla! Statistics Server |
4
|
|
|
* |
5
|
|
|
* @copyright Copyright (C) 2013 - 2017 Open Source Matters, Inc. All rights reserved. |
6
|
|
|
* @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License Version 2 or Later |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace Joomla\StatsServer; |
10
|
|
|
|
11
|
|
|
use Joomla\Application\AbstractWebApplication; |
12
|
|
|
use Ramsey\Uuid\Uuid; |
13
|
|
|
use TheIconic\Tracking\GoogleAnalytics\Analytics; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Web application for the stats server |
17
|
|
|
*/ |
18
|
|
|
class WebApplication extends AbstractWebApplication |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* Application analytics object. |
22
|
|
|
* |
23
|
|
|
* @var Analytics |
24
|
|
|
*/ |
25
|
|
|
private $analytics; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Response mime type. |
29
|
|
|
* |
30
|
|
|
* @var string |
31
|
|
|
*/ |
32
|
|
|
public $mimeType = 'application/json'; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Application router. |
36
|
|
|
* |
37
|
|
|
* @var Router |
38
|
|
|
*/ |
39
|
|
|
private $router; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Method to run the application routines. |
43
|
|
|
* |
44
|
|
|
* @return void |
45
|
|
|
*/ |
46
|
5 |
|
protected function doExecute() |
47
|
|
|
{ |
48
|
|
|
// On a GET request to the live domain, submit analytics data |
49
|
5 |
|
if ($this->input->getMethod() === 'GET' |
50
|
5 |
|
&& strpos($this->input->server->getString('HTTP_HOST', ''), 'developer.joomla.org') === 0 |
51
|
5 |
|
&& $this->analytics) |
52
|
|
|
{ |
53
|
|
|
$this->analytics->setAsyncRequest(true) |
54
|
|
|
->setProtocolVersion('1') |
55
|
|
|
->setTrackingId('UA-544070-16') |
56
|
|
|
->setClientId(Uuid::uuid4()->toString()) |
57
|
|
|
->setDocumentPath($this->get('uri.base.path')) |
58
|
|
|
->setIpOverride($this->input->server->getString('REMOTE_ADDR', '127.0.0.1')) |
59
|
|
|
->setUserAgentOverride($this->input->server->getString('HTTP_USER_AGENT', 'JoomlaStats/1.0')); |
60
|
|
|
|
61
|
|
|
// Don't allow sending Analytics data to cause a failure |
62
|
|
|
try |
63
|
|
|
{ |
64
|
|
|
$this->analytics->sendPageview(); |
65
|
|
|
} |
66
|
|
|
catch (\Exception $e) |
67
|
|
|
{ |
68
|
|
|
// Log the error for reference |
69
|
|
|
$this->getLogger()->error( |
70
|
|
|
'Error sending analytics data.', |
71
|
|
|
['exception' => $e] |
72
|
|
|
); |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
try |
77
|
|
|
{ |
78
|
5 |
|
$this->router->getController($this->get('uri.route'))->execute(); |
|
|
|
|
79
|
|
|
} |
80
|
4 |
|
catch (\Throwable $e) |
81
|
|
|
{ |
82
|
|
|
// Log the error for reference |
83
|
4 |
|
$this->getLogger()->error( |
84
|
4 |
|
sprintf('Uncaught Throwable of type %s caught.', get_class($e)), |
85
|
4 |
|
['exception' => $e] |
86
|
|
|
); |
87
|
|
|
|
88
|
4 |
|
$this->setErrorHeader($e); |
89
|
|
|
|
90
|
|
|
$data = [ |
91
|
4 |
|
'error' => true, |
92
|
4 |
|
'message' => $e->getMessage(), |
93
|
|
|
]; |
94
|
|
|
|
95
|
4 |
|
$this->setBody(json_encode($data)); |
96
|
|
|
} |
97
|
5 |
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Set the application's analytics object. |
101
|
|
|
* |
102
|
|
|
* @param Analytics $analytics Analytics object to set. |
103
|
|
|
* |
104
|
|
|
* @return $this |
105
|
|
|
*/ |
106
|
|
|
public function setAnalytics(Analytics $analytics) : WebApplication |
107
|
|
|
{ |
108
|
|
|
$this->analytics = $analytics; |
109
|
|
|
|
110
|
|
|
return $this; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Set the HTTP Response Header for error conditions. |
115
|
|
|
* |
116
|
|
|
* @param \Throwable $exception The Throwable object to process. |
117
|
|
|
* |
118
|
|
|
* @return void |
119
|
|
|
*/ |
120
|
4 |
|
private function setErrorHeader(\Throwable $exception) |
121
|
|
|
{ |
122
|
4 |
|
switch ($exception->getCode()) |
123
|
|
|
{ |
124
|
4 |
|
case 401: |
125
|
1 |
|
$this->setHeader('HTTP/1.1 401 Unauthorized', 401, true); |
126
|
|
|
|
127
|
1 |
|
break; |
128
|
|
|
|
129
|
3 |
|
case 403: |
130
|
1 |
|
$this->setHeader('HTTP/1.1 403 Forbidden', 403, true); |
131
|
|
|
|
132
|
1 |
|
break; |
133
|
|
|
|
134
|
2 |
|
case 404: |
135
|
1 |
|
$this->setHeader('HTTP/1.1 404 Not Found', 404, true); |
136
|
|
|
|
137
|
1 |
|
break; |
138
|
|
|
|
139
|
1 |
|
case 500: |
140
|
|
|
default: |
141
|
1 |
|
$this->setHeader('HTTP/1.1 500 Internal Server Error', 500, true); |
142
|
|
|
|
143
|
1 |
|
break; |
144
|
|
|
} |
145
|
4 |
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Set the application's router. |
149
|
|
|
* |
150
|
|
|
* @param Router $router Router object to set. |
151
|
|
|
* |
152
|
|
|
* @return $this |
153
|
|
|
*/ |
154
|
1 |
|
public function setRouter(Router $router) : WebApplication |
155
|
|
|
{ |
156
|
1 |
|
$this->router = $router; |
157
|
|
|
|
158
|
1 |
|
return $this; |
159
|
|
|
} |
160
|
|
|
} |
161
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.