/
Version.class.php
executable file
·163 lines (137 loc) · 4.95 KB
/
Version.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<?php
/**
* @desc Version Information for the security of packaged software.
*
* @author Pierre-Henry Soria <hello@ph7cms.com>
* @copyright (c) 2012-2021, Pierre-Henry Soria. All Rights Reserved.
* @license MIT License; See PH7.LICENSE.txt and PH7.COPYRIGHT.txt in the root directory.
* @package PH7 / Framework / Security
*/
namespace PH7\Framework\Security;
defined('PH7') or exit('Restricted access');
use DOMDocument;
use DOMElement;
use PH7\Framework\Cache\Cache;
use PH7\Framework\Security\Validate\Validate;
final class Version
{
/**
* Cache lifetime set for 1 day.
*/
const CACHE_TIME = 86400;
const CACHE_GROUP = 'str/security';
const LATEST_VERSION_URL = 'https://xml.ph7builder.com/software-info.xml';
const VERSION_PATTERN = '\d{1,2}\.\d{1,2}\.\d{1,2}';
const FRAMEWORK_TAG_NAME = 'ph7';
const PACKAGE_TAG_NAME = 'ph7builder';
const UPGRADE_DOC_URL = 'https://ph7cms.com/doc/en/upgrade';
/**
* Framework Kernel.
*
* @history VERSION NAMES:
*
* 1.0, 1.1 branches were "pOH", 1.2 was "pOW", 1.3, 1.4 were "p[H]", 2.* was "H2O", 3.* was "H3O", 4.* was "HCO",
* 5.* was "pCO", 6.* was "WoW", 7.*, 8.* were "NaOH", 10.* was "pKa", 12.* was "PHS", 14.* was "pKb",
* v15.* was ABSOLUTE™, v16.* was ACIDIC, and v17.* is PURE™
*/
const KERNEL_VERSION_NAME = 'PURE™';
/**
* VERSION NUMBERS:
* MAJOR.MINOR.PATCH[.build]
*
* More details: https://ph7cms.com/new-versioning-system/
*/
const KERNEL_VERSION = '17.2.0';
const KERNEL_BUILD = '1';
const KERNEL_RELEASE_DATE = '2022-04-02';
/***** Framework Server *****/
const KERNEL_TECHNOLOGY_NAME = 'pH7Builder.com';
const KERNEL_SERVER_NAME = 'pH7WS/1.0.0';
/**
* Private constructor to prevent instantiation of class since it's a static class.
*/
private function __construct()
{
}
/**
* Gets information on the latest software version.
*
* @return array|bool Returns version information in an array or FALSE if an error occurred.
*/
public static function getLatestInfo()
{
$oCache = (new Cache)->start(self::CACHE_GROUP, 'version-info', self::CACHE_TIME);
if (!$mData = $oCache->get()) {
$mData = self::retrieveXmlInfoFromRemoteServer();
$oCache->put($mData);
}
unset($oCache);
return $mData;
}
/**
* Checks if there is an update available.
*
* @return bool Returns TRUE if a new update is available, FALSE otherwise.
*/
public static function isUpdateEligible()
{
if (!$aLatestInfo = self::getLatestInfo()) {
return false;
}
$bIsAlert = $aLatestInfo['is_alert'];
$sLastName = $aLatestInfo['name'];
$sLastVer = $aLatestInfo['version'];
$sLastBuild = $aLatestInfo['build'];
unset($aLatestInfo);
if (!$bIsAlert || !is_string($sLastName) || !preg_match('#^' . self::VERSION_PATTERN . '$#', $sLastVer)) {
return false;
}
if (version_compare(self::KERNEL_VERSION, $sLastVer, '==')) {
if (version_compare(self::KERNEL_BUILD, $sLastBuild, '<')) {
return true;
}
}
if (version_compare(self::KERNEL_VERSION, $sLastVer, '<')) {
return true;
}
return false;
}
/**
* @return array|bool Returns an array with the release details, or FALSE if cannot retrieve the remote info.
*/
private static function retrieveXmlInfoFromRemoteServer()
{
$oDom = new DOMDocument;
if (!@$oDom->load(self::LATEST_VERSION_URL)) {
return false;
}
// Set default values to variables (if nothing in foreach loop)
$bIsAlert = $sVerName = $sVerNumber = $sVerBuild = null;
/** @var DOMElement $oSoft */
foreach ($oDom->getElementsByTagName(self::FRAMEWORK_TAG_NAME) as $oSoft) {
// Get info for "ph7builder" package
$oInfo = $oSoft->getElementsByTagName(self::PACKAGE_TAG_NAME)->item(0);
$bIsAlert = self::isUpdateAlertEnabled($oInfo);
$sVerName = $oInfo->getElementsByTagName('name')->item(0)->nodeValue;
$sVerNumber = $oInfo->getElementsByTagName('version')->item(0)->nodeValue;
$sVerBuild = $oInfo->getElementsByTagName('build')->item(0)->nodeValue;
}
unset($oDom);
return [
'is_alert' => $bIsAlert,
'name' => $sVerName,
'version' => $sVerNumber,
'build' => $sVerBuild
];
}
/**
* @param DOMElement $oInfo
*
* @return bool
*/
private static function isUpdateAlertEnabled(DOMElement $oInfo)
{
// "Validate::bool()" returns TRUE for "1", "true", "on", and "yes", FALSE otherwise
return (new Validate)->bool($oInfo->getElementsByTagName('upd-alert')->item(0)->nodeValue);
}
}