3
* Little Software Stats
5
* An open source program that allows developers to keep track of how their software is being used
7
* @package Little Software Stats
9
* @copyright Copyright (c) 2011, Little Apps
10
* @license http://www.gnu.org/licenses/gpl.html GNU General Public License v3
11
* @link http://little-apps.org
18
* Use to call API functions
20
* @package Little Software Stats
27
* Constructor for API class
28
* @param MySQL $sMySQL MySQL Class
30
function __construct($sMySQL) {
31
$this->sMySQL = $sMySQL;
35
* Adds information for started app
37
* @param string $sAppId Application ID
38
* @param string $sAppVer Application Version
39
* @param string $sUniqueId Unique User ID
40
* @param string $sSessionId Session ID
41
* @param int $nTimestamp Timestamp (GMT 0)
42
* @param string $sOSVer OS Version
43
* @param int $nOSServicePack OS Service Pack
44
* @param int $nOSArch OS Architecture (32 or 64 bit)
45
* @param string $sOSJavaVer Java Version
46
* @param string $sOSNET Mono/.NET Version
47
* @param int $nOSNETSP Mono/.NET Service Pack
48
* @param int $nLangId Language ID
49
* @param string $sScreenRes Screen Resolution (ie: 1024x768)
50
* @param string $sCPUName CPU Name (ie: Core i7, Pentium IV)
51
* @param string $sCPUBrand CPU Brand (ie: AMD, Intel)
52
* @param int $nCPUFreq CPU Frequency (hertz)
53
* @param int $nCPUCores CPU Cores
54
* @param int $nCPUArch CPU Architecture
55
* @param int $nMemTotal Total Memory (bytes)
56
* @param int $nMemFree Free Memory (bytes)
57
* @param int $nDiskTotal Total Disk Space (bytes)
58
* @param int $nDiskFree Free Disk Space (bytes)
60
public function StartApp($sAppId, $sAppVer, $sUniqueId, $sSessionId, $nTimestamp,
61
$sOSVer, $nOSServicePack, $nOSArch, $sOSJavaVer, $sOSNET, $nOSNETSP,
62
$nLangId, $sScreenRes, $sCPUName, $sCPUBrand, $nCPUFreq, $nCPUCores,
63
$nCPUArch, $nMemTotal, $nMemFree, $nDiskTotal, $nDiskFree) {
64
if (!IsAppIdValid($sAppId))
67
if (!IsAppVerValid($sAppVer))
70
if (!IsUserIdValid($sUniqueId) || !IsUserIdValid($sSessionId))
73
$this->sMySQL->Select("UniqueUsers", array("UniqueUserId" => $sUniqueId), '', '0,1');
75
// Get ip address + info
76
$sIPAddress = $_REQUEST['REMOTE_ADDR'];
77
$sCountry = $sLongitude = $sLatitude = "Unknown";
79
$aLocation = GetIPLocation($sIPAddress);
81
$sCountry = $aLocation['country'];
82
$sLongitude = $aLocation['longitude'];
83
$sLatitude = $aLocation['latitude'];
88
if ($this->sMySQL->iRecords == 0)
89
$this->sMySQL->Insert(array("UniqueUserId" => $sUniqueId, "Created" => $nNow,
90
"LastRecieved" => $nNow, "IPAddress" => $sIPAddress, "Longitude" => $sLongitude,
91
"Latitude" => $sLatitude, "Country" => $sCountry, "OSVersion" => $sOSVer,
92
"OSServicePack" => $nOSServicePack, "OSArchitecture" => $nOSArch, "JavaVer" => $sOSJavaVer,
93
"NetVer" => $sOSNET, "NetSP" => $nOSNETSP, "LangID" => $nLangId, "ScreenRes" => $sScreenRes,
94
"CPUName" => $sCPUName, "CPUBrand" => $sCPUBrand, "CPUFreq" => $nCPUFreq, "CPUCores" => $nCPUCores,
95
"CPUArch" => $nCPUArch, "MemTotal" => $nMemTotal, "MemFree" => $nMemFree,
96
"DiskTotal" => $nDiskTotal, "DiskFree" => $nDiskFree), "UniqueUsers");
98
$this->sMySQL->Update ("UniqueUsers", array("LastRecieved" => $nNow, "IPAddress" => $sIPAddress,
99
"Longitude" => $sLongitude, "Latitude" => $sLatitude, "Country" => $sCountry, "OSVersion" => $sOSVer,
100
"OSServicePack" => $nOSServicePack, "OSArchitecture" => $nOSArch, "JavaVer" => $sOSJavaVer,
101
"NetVer" => $sOSNET, "NetSP" => $nOSNETSP, "LangID" => $nLangId, "ScreenRes" => $sScreenRes,
102
"CPUName" => $sCPUName, "CPUBrand" => $sCPUBrand, "CPUFreq" => $nCPUFreq, "CPUCores" => $nCPUCores,
103
"CPUArch" => $nCPUArch, "MemTotal" => $nMemTotal, "MemFree" => $nMemFree,
104
"DiskTotal" => $nDiskTotal, "DiskFree" => $nDiskFree), array("UniqueUserId" => $sUniqueId));
106
$this->sMySQL->Insert(array("SessionId" => $sSessionId, "UniqueUserId" => $sUniqueId, "StartApp" => $nTimestamp,
107
"ApplicationId" => $sAppId, "ApplicationVersion" => $sAppVer), "Sessions");
113
* Called when app is finished
115
* @param int $nTimestamp Timestamp (GMT 0)
116
* @param string $sSessionId Session ID
118
public function StopApp($nTimestamp, $sSessionId) {
119
if (!IsUserIdValid($sSessionId))
122
$this->UpdateLastRecieved($sSessionId);
124
$this->sMySQL->Update("Sessions", array("StopApp" => $nTimestamp), array("SessionId" => $sSessionId));
130
* Used to track events
132
* @param int $nTimestamp Timestamp (GMT 0)
133
* @param string $sSessionId Session ID
134
* @param string $sCategory Category
135
* @param string $sName Name
136
* @param string $sFlowId Flow ID
138
public function Event($nTimestamp, $sSessionId, $sCategory, $sName, $sFlowId) {
139
if (!IsUserIdValid($sSessionId))
142
$this->UpdateLastRecieved($sSessionId);
144
$this->sMySQL->Insert(array("EventCode" => "ev", "EventCategory" => $sCategory,
145
"EventName" => $sName, "SessionId" => $sSessionId, "UtcTimestamp" => $nTimestamp), "Events");
151
* Used to track event values
153
* @param int $nTimestamp Timestamp (GMT 0)
154
* @param string $sSessionId Session ID
155
* @param string $sCategory Category
156
* @param string $sName Name
157
* @param string $sValue Value
158
* @param string $sFlowId Flow ID
160
public function EventValue($nTimestamp, $sSessionId, $sCategory,
161
$sName, $sValue, $sFlowId) {
162
if (!IsUserIdValid($sSessionId))
165
$this->UpdateLastRecieved($sSessionId);
167
$this->sMySQL->Insert(array("EventCode" => "evV", "EventCategory" => $sCategory,
168
"EventName" => $sName, "EventValue" => $sValue, "SessionId" => $sSessionId,
169
"UtcTimestamp" => $nTimestamp), "Events");
175
* Used to track event durations
177
* @param int $nTimestamp Timestamp (GMT 0)
178
* @param string $sSessionId Session ID
179
* @param string $sCategory Category
180
* @param string $sName Name
181
* @param int $nDuration Duration (seconds)
182
* @param bool $bCompleted Completed?
183
* @param string $sFlowId Flow ID
185
public function EventPeriod($nTimestamp, $sSessionId, $sCategory,
186
$sName, $nDuration, $bCompleted, $sFlowId) {
187
if (!IsUserIdValid($sSessionId))
190
$nCompleted = ($bCompleted == true) ? (1) : (0);
192
$this->UpdateLastRecieved($sSessionId);
194
$this->sMySQL->Insert(array("EventCode" => "evV", "EventCategory" => $sCategory,
195
"EventName" => $sName, "EventDuration" => $nDuration, "EventCompleted" => $nCompleted,
196
"SessionId" => $sSessionId, "UtcTimestamp" => $nTimestamp), "Events");
200
* Simple logging utility
202
* @param int $nTimestamp Timestamp (GMT 0)
203
* @param string $sSessionId Session ID
204
* @param string $sMessage Message
205
* @param string $sFlowId Flow ID
207
public function Log($nTimestamp, $sSessionId, $sMessage, $sFlowId) {
208
if (!IsUserIdValid($sSessionId))
213
* Used for tracking specfic information
215
* @param int $nTimestamp Timestamp (GMT 0)
216
* @param string $sSessionId Session ID
217
* @param string $sName Name
218
* @param string $sValue Value
219
* @param string $sFlowId Flow ID
221
public function CustomData($nTimestamp, $sSessionId, $sName, $sValue, $sFlowId) {
222
if (!IsUserIdValid($sSessionId))
227
* Sent when an exception occurs
229
* @param int $nTimestamp Timestamp (GMT 0)
230
* @param string $sSessionId Session ID
231
* @param string $sAppVer Application Version
232
* @param string $sUniqueId Unique ID
233
* @param string $sMessage Message
234
* @param string $sStackTrace Stack Trace
235
* @param string $sSource Source
236
* @param string $sTargetSite Target Site
237
* @param string $sFlowId Flow ID
239
public function Exception($nTimestamp, $sSessionId, $sAppVer, $sUniqueId,
240
$sMessage, $sStackTrace, $sSource, $sTargetSite, $sFlowId) {
241
if (!IsUserIdValid($sSessionId))
246
* Sent when application is installed
248
* @param int $nTimestamp Timestamp (GMT 0)
249
* @param string $sSessionId Session ID
250
* @param string $sAppVer Application Version
251
* @param string $sFlowId Flow ID
253
public function Install($nTimestamp, $sSessionId, $sAppVer, $sFlowId) {
254
if (!IsAppVerValid($sAppVer))
257
if (!IsUserIdValid($sSessionId))
263
* Sent when application is uninstalled
265
* @param int $nTimestamp Timestamp (GMT 0)
266
* @param string $sSessionId Session ID
267
* @param string $sAppVer Application Version
268
* @param string $sFlowId Flow ID
270
public function Uninstall($nTimestamp, $sSessionId, $sAppVer, $sFlowId) {
271
if (!IsAppVerValid($sAppVer))
274
if (!IsUserIdValid($sSessionId))
279
* Checks if App ID is valid
281
* @param string $sAppId Application Id
282
* @return bool True if App ID is valid
284
private function IsAppIdValid($sAppId) {
285
// Make sure app id is valid format
286
if ($sAppId == '' || !preg_match("/^([a-z0-9]{33})/", $sAppId))
289
// Check if app id is in database
290
$this->sMySQL->Select("Applications", array("ApplicationId" => $sAppId), '', '0,1');
291
if ($this->sMySQL->iRecords == 0)
294
// Make sure application is recieving
295
if ($this->sMySQL->aArrayedResult['ApplicationRecieving'] == 0)
302
* Checks if App Version is valid
304
* @param string $sAppVer Application Version
305
* @return bool True if App Version is valid
307
private function IsAppVerValid($sAppVer) {
308
if ($sAppVer == '' || !preg_match("/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/", $sAppVer))
315
* Checks if user ID is valid
317
* @param string $sUserId User ID
318
* @return bool True if user ID is valid
320
private function IsUserIdValid($sUserId) {
321
if ($sUserId == '' || !preg_match("/^([A-F0-9]{32})/", $sUserId))
328
* Updates last recieved field for unique user id
330
* @param string $sSessionId Session ID
332
private function UpdateLastRecieved($sSessionId) {
333
$this->sMySQL->Select("Sessions", array("SessionId" => $sSessionId));
335
$sUniqueId = $this->sMySQL->aArrayedResult['UniqueUserId'];
337
$this->sMySQL->Update("UniqueUsers", array("LastRecieved" => "NOW()"), array("UniqueUserId" => $sUniqueId));
342
* Gets coords of ip address
344
* @param string $ip IP address
345
* @return mixed Returns location array if successful, otherwise false
347
private function GetIPLocation($ip) {
348
$content = @file_get_contents('http://api.hostip.info/?ip='.$ip);
349
if ($content != FALSE) {
350
$xml = new SimpleXmlElement($content);
351
$coordinates = $xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->ipLocation->children('gml', TRUE)->pointProperty->Point->coordinates;
352
$longlat = explode(',', $coordinates);
353
$location['longitude'] = $longlat[0];
354
$location['latitude'] = $longlat[1];
355
$location['citystate'] = '==>'.$xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->children('gml', TRUE)->name;
356
$location['country'] = '==>'.$xml->children('gml', TRUE)->featureMember->children('', TRUE)->Hostip->countryName;