272 lines
7.6 KiB
PHP
272 lines
7.6 KiB
PHP
<?php
|
|
|
|
class Updater {
|
|
|
|
function handleCommand($command) {
|
|
if (!self::isUserAlreadyLoggedInAndAdmin()) {
|
|
echo json_encode(array("status" => "ERROR", "msg" => "Not authorized"));
|
|
} else {
|
|
$pdo = DbUtils::openDbAndReturnPdoStatic();
|
|
if ($command == 'getAvailableVersion') {
|
|
echo json_encode(self::getAvailableVersion($pdo));
|
|
} else if ($command == 'updatecheck') {
|
|
echo json_encode(self::updatecheck($pdo));
|
|
} else if ($command == 'replace') {
|
|
echo json_encode(self::replace($pdo,$_GET["fileindex"],$_GET["totalLines"]));
|
|
}
|
|
else {
|
|
echo "Kommando nicht unterstuetzt.";
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function isUserAlreadyLoggedInAndAdmin() {
|
|
if(session_id() == '') {
|
|
session_start();
|
|
}
|
|
if (!isset($_SESSION['angemeldet']) || !$_SESSION['angemeldet']) {
|
|
return false;
|
|
} else {
|
|
return ($_SESSION['is_admin']);
|
|
}
|
|
}
|
|
|
|
private static function getFile($url,$file,$asArray = false,$timeout = 200) {
|
|
$ctx = stream_context_create(array('http' =>
|
|
array(
|
|
'timeout' => $timeout, // seconds
|
|
)
|
|
));
|
|
|
|
$url = $url . "/downloader.php?file=" . $file;
|
|
|
|
try {
|
|
$infoFile = file_get_contents($url, false, $ctx);
|
|
$test = substr($infoFile, 1,50);
|
|
if ($infoFile != FALSE) {
|
|
if ($asArray) {
|
|
$retArr = array();
|
|
$lines = explode("\n", $infoFile);
|
|
|
|
foreach($lines as $aLine) {
|
|
$l = trim($aLine);
|
|
if ($l != '') {
|
|
$retArr[] = $l;
|
|
}
|
|
}
|
|
return array("status" => "OK","msg" => $retArr);
|
|
} else {
|
|
return array("status" => "OK","msg" => $infoFile);
|
|
}
|
|
} else {
|
|
return array("status" => "ERROR","msg" => "File to replace not found ($url)");
|
|
}
|
|
} catch (Exception $ex) {
|
|
return array("status" => "ERROR","msg" => $ex->getMessage());
|
|
}
|
|
}
|
|
private static function getInfoFile($url,$file,$asArray = false,$timeout = 200) {
|
|
$ctx = stream_context_create(array('http' =>
|
|
array(
|
|
'timeout' => $timeout, // seconds
|
|
)
|
|
));
|
|
|
|
$url = $url . "/" . $file;
|
|
|
|
try {
|
|
$infoFile = @file_get_contents($url, false, $ctx);
|
|
|
|
if ($infoFile != FALSE) {
|
|
if ($asArray) {
|
|
$retArr = array();
|
|
$lines = explode("\n", $infoFile);
|
|
|
|
if (count($lines) < 1) {
|
|
return array("status" => "ERROR","msg" => "Info file not valid");
|
|
}
|
|
$versionMatch = '/^[0-9]*\.[0-9]*\.[0-9]*/';
|
|
$ret = preg_match($versionMatch, $lines[0]);
|
|
if ($ret == 0) {
|
|
return array("status" => "ERROR","msg" => "Info file has no version info.");
|
|
}
|
|
|
|
foreach($lines as $aLine) {
|
|
$l = trim($aLine);
|
|
if ($l != '') {
|
|
$retArr[] = $l;
|
|
}
|
|
}
|
|
return array("status" => "OK","msg" => $retArr);
|
|
} else {
|
|
return array("status" => "OK","msg" => $infoFile);
|
|
}
|
|
} else {
|
|
return array("status" => "ERROR","msg" => "File to replace not found ($url)");
|
|
}
|
|
} catch (Exception $ex) {
|
|
return array("status" => "ERROR","msg" => $ex->getMessage());
|
|
}
|
|
}
|
|
private static function getAvailableVersion($pdo) {
|
|
$url = CommonUtils::getConfigValue($pdo, "updateurl", '');
|
|
$installedVersion = CommonUtils::getConfigValue($pdo, "version", '');
|
|
$infoFile = self::getInfoFile($url,'updateinfo.txt',true,3);
|
|
if ($infoFile["status"] != "OK") {
|
|
return array("status" => "ERROR","msg" => "could not get info file: " . $infoFile["msg"],"url" => $url);
|
|
}
|
|
$infoFileLines = $infoFile["msg"];
|
|
|
|
if (count($infoFileLines) > 1) {
|
|
$checkIfNewerVersion = self::isV2Newer($installedVersion,trim($infoFileLines[0]));
|
|
return array("status" => "OK","msg" => $infoFileLines[0],"url" => $url,"neweravailable" => ($checkIfNewerVersion ? 1 : 0));
|
|
} else {
|
|
return array("status" => "ERROR","msg" => "Info file not valid","url" => $url);
|
|
}
|
|
}
|
|
|
|
private static function isV2Newer($v1,$v2) {
|
|
if (is_null($v1) || is_null($v2)) {
|
|
return false;
|
|
}
|
|
$v1key = self::genVerKey($v1);
|
|
$v2key = self::genVerKey($v2);
|
|
|
|
if (is_null($v1key) || is_null($v2key)) {
|
|
return false;
|
|
}
|
|
|
|
if ($v1key < $v2key) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static function genVerKey($v) {
|
|
$vparts = explode('.',$v);
|
|
$len = count($vparts);
|
|
$key = 0;
|
|
try {
|
|
for ($i=0;$i<$len;$i++) {
|
|
$key += intval($vparts[$i]) * pow(1000,2-$i);
|
|
}
|
|
return $key;
|
|
} catch (Exception $e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
private static function doCheck($lineArr) {
|
|
if (count($lineArr) < 2) {
|
|
return array("status" => "OK","msg" => '');
|
|
}
|
|
|
|
for ($i=1;$i<count($lineArr);$i++) {
|
|
if (trim($lineArr[$i]) == '') {
|
|
continue;
|
|
}
|
|
$aLine = "../" . $lineArr[$i];
|
|
$basename = basename($aLine);
|
|
$dirname = dirname($aLine);
|
|
|
|
$isDirExists = file_exists($dirname);
|
|
|
|
if (!$isDirExists) {
|
|
$ret = self::createSubDir($dirname);
|
|
if ($ret["status"] != "OK") {
|
|
return $ret;
|
|
}
|
|
}
|
|
|
|
$isFileExists = file_exists($aLine);
|
|
$isDirWritable = is_writable($dirname);
|
|
$isFileWritable = is_writable($aLine);
|
|
|
|
if ($isFileExists) {
|
|
if (!$isFileWritable) {
|
|
return array("status" => "ERROR","msg" => $aLine . " cannot be overwritten");
|
|
}
|
|
} else {
|
|
// file does not exist, but can it be created?
|
|
if (!$isDirWritable) {
|
|
return array("status" => "ERROR","msg" => $basename . " cannot be written into $dirname with this path: " . $aLine);
|
|
}
|
|
}
|
|
|
|
}
|
|
return array("status" => "OK","msg" => "");
|
|
}
|
|
|
|
private static function createSubDir($dirname) {
|
|
if (!is_writable("..")) {
|
|
return array("status" => "ERROR","msg" => "Root directory not writable. But this is necessary to create and delete install directory.");
|
|
}
|
|
|
|
if (!file_exists($dirname)) {
|
|
if (!mkdir($dirname, 0777)) {
|
|
return array("status" => "ERROR","msg" => "$dirname directory could not be created.");
|
|
}
|
|
} else {
|
|
if (!is_writable($dirname)) {
|
|
return array("status" => "ERROR","msg" => "Cannot write into $dirname directory.");
|
|
}
|
|
}
|
|
return array("status" => "OK");
|
|
}
|
|
|
|
public static function updatecheck($pdo) {
|
|
$res = DbUtils::checkForInstallUpdateDbRights($pdo);
|
|
if ($res["status"] != "OK") {
|
|
return array("status" => "ERROR","msg" => $res["msg"]);
|
|
}
|
|
if ($res["ok"] == 0) {
|
|
return array("status" => "ERROR","msg" => "Fehlende DB-Rechte: " . join(",",$res["msg"]));
|
|
}
|
|
|
|
$url = CommonUtils::getConfigValue($pdo, "updateurl", '');
|
|
|
|
$infoFile = self::getInfoFile($url,'updateinfo.txt',true,3);
|
|
if ($infoFile["status"] != "OK") {
|
|
return array("status" => "ERROR","msg" => "could not get info file: " . $infoFile["msg"]);
|
|
}
|
|
$infoFileLines = $infoFile["msg"];
|
|
|
|
$check = self::doCheck($infoFileLines);
|
|
if ($check["status"] != "OK") {
|
|
$ret = array("status" => "ERROR","msg" => "Check returned: " . $check["msg"]);
|
|
} else {
|
|
$ret = array("status" => "OK","msg" => $infoFileLines);
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
public static function replace($pdo,$fileindex,$totallines) {
|
|
$url = CommonUtils::getConfigValue($pdo, "updateurl", '');
|
|
$infoFile = self::getInfoFile($url,'updateinfo.txt',true,3);
|
|
if ($infoFile["status"] != "OK") {
|
|
return array("status" => "ERROR","msg" => "could not get file: " . $infoFile["msg"]);
|
|
}
|
|
$lineArr = $infoFile["msg"];
|
|
|
|
try {
|
|
$fileToRead = $lineArr[intval($fileindex) + 1];
|
|
|
|
if (trim($fileToRead) != '') {
|
|
$targetFile = "../" . $fileToRead;
|
|
$fileContent = self::getFile($url, $fileToRead);
|
|
if ($fileContent["status"] == "OK") {
|
|
file_put_contents($targetFile, $fileContent["msg"]);
|
|
} else {
|
|
return array("status" => "ERROR","msg" => "$targetFile cannot be fetched from update server.");
|
|
}
|
|
}
|
|
} catch (Exception $ex) {
|
|
return array("status" => "ERROR","msg" => $ex->getMessage());
|
|
}
|
|
|
|
return array("status" => "OK","msg" => array("index" => $fileindex,"file" => $fileToRead,"totalLines" => $totallines));
|
|
}
|
|
} |