System update (better installation)
This commit is contained in:
parent
182d682f87
commit
c5f44f4b64
4 changed files with 202 additions and 46 deletions
|
@ -22,6 +22,7 @@ ThemeDir: system/themes/
|
|||
AssetDir: system/themes/assets/
|
||||
SnippetDir: system/themes/snippets/
|
||||
TemplateDir: system/themes/templates/
|
||||
TrashDir: system/trash/
|
||||
MediaDir: media/
|
||||
ImageDir: media/images/
|
||||
StaticDir: cache/
|
||||
|
|
|
@ -177,17 +177,17 @@ class YellowCommandline
|
|||
++$this->errors;
|
||||
echo "ERROR building location '$location', ".$this->yellow->page->getStatusCode(true)."\n";
|
||||
}
|
||||
if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStaticFile status:$statusCode location:$location\n";
|
||||
if(defined("DEBUG") && DEBUG>=1) echo "YellowCommandline::buildStaticFile status:$statusCode location:$location<br/>\n";
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Analyse static file, detect locations with arguments
|
||||
function analyseStaticFile($text)
|
||||
function analyseStaticFile($rawData)
|
||||
{
|
||||
$serverName = $this->yellow->config->get("serverName");
|
||||
$serverBase = $this->yellow->config->get("serverBase");
|
||||
$pagination = $this->yellow->config->get("contentPagination");
|
||||
preg_match_all("/<(.*?)href=\"([^\"]+)\"(.*?)>/i", $text, $matches);
|
||||
preg_match_all("/<(.*?)href=\"([^\"]+)\"(.*?)>/i", $rawData, $matches);
|
||||
foreach($matches[2] as $match)
|
||||
{
|
||||
if(preg_match("/^(.*?)#(.*)$/", $match, $tokens)) $match = $tokens[1];
|
||||
|
@ -205,14 +205,14 @@ class YellowCommandline
|
|||
if(is_null($this->locationsArgs[$location]))
|
||||
{
|
||||
$this->locationsArgs[$location] = $location;
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticFile detected location:$location\n";
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticFile detected location:$location<br/>\n";
|
||||
}
|
||||
} else {
|
||||
$location = rtrim($location, "0..9");
|
||||
if(is_null($this->locationsArgsPagination[$location]))
|
||||
{
|
||||
$this->locationsArgsPagination[$location] = $location;
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticFile detected location:$location\n";
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowCommandline::analyseStaticFile detected location:$location<br/>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ class YellowCore
|
|||
$this->config->setDefault("assetDir", "system/themes/assets/");
|
||||
$this->config->setDefault("snippetDir", "system/themes/snippets/");
|
||||
$this->config->setDefault("templateDir", "system/themes/templates/");
|
||||
$this->config->setDefault("trashDir", "system/trash/");
|
||||
$this->config->setDefault("mediaDir", "media/");
|
||||
$this->config->setDefault("imageDir", "media/images/");
|
||||
$this->config->setDefault("staticDir", "cache/");
|
||||
|
@ -175,7 +176,7 @@ class YellowCore
|
|||
}
|
||||
|
||||
// Read page
|
||||
function readPage($serverScheme, $serverName, $base, $location, $fileName, $cacheable, $statusCode, $pageError = "")
|
||||
function readPage($serverScheme, $serverName, $base, $location, $fileName, $cacheable, $statusCode, $pageError)
|
||||
{
|
||||
if($statusCode >= 400)
|
||||
{
|
||||
|
@ -261,13 +262,13 @@ class YellowCore
|
|||
}
|
||||
}
|
||||
$this->toolbox->timerStop($time);
|
||||
if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::command time:$time ms<br/>\n";
|
||||
if($statusCode == 0)
|
||||
{
|
||||
$statusCode = 400;
|
||||
list($name, $command) = func_get_args();
|
||||
list($command) = func_get_args();
|
||||
echo "Yellow $command: Command not found\n";
|
||||
}
|
||||
if(defined("DEBUG") && DEBUG>=1) echo "YellowCore::command time:$time ms<br/>\n";
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
|
@ -332,7 +333,7 @@ class YellowCore
|
|||
// Return static file from cache if available
|
||||
function getStaticFileFromCache($location, $fileName, $cacheable)
|
||||
{
|
||||
if(PHP_SAPI!="cli" && is_readable($fileName) && $cacheable)
|
||||
if(is_readable($fileName) && $cacheable && PHP_SAPI!="cli")
|
||||
{
|
||||
$location .= $this->toolbox->getLocationArgs();
|
||||
$fileNameStatic = rtrim($this->config->get("staticDir"), '/').$location;
|
||||
|
@ -1868,10 +1869,7 @@ class YellowText
|
|||
{
|
||||
if(preg_match("/^\#/", $line)) continue;
|
||||
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
||||
if(empty($language))
|
||||
{
|
||||
if(lcfirst($matches[1])=="language" && !strempty($matches[2])) $language = $matches[2];
|
||||
}
|
||||
if(lcfirst($matches[1])=="language" && !strempty($matches[2])) $language = $matches[2];
|
||||
if(!empty($language) && !empty($matches[1]) && !strempty($matches[2]))
|
||||
{
|
||||
$this->setText($matches[1], $matches[2], $language);
|
||||
|
@ -2399,6 +2397,17 @@ class YellowLookup
|
|||
for($i=1; $i<count($tokens); ++$i) $string .= '/'.$this->normaliseName($tokens[$i]);
|
||||
return $location == $string;
|
||||
}
|
||||
|
||||
// Check if file is valid
|
||||
function isValidFile($fileName)
|
||||
{
|
||||
$contentDirLength = strlenu($this->yellow->config->get("contentDir"));
|
||||
$mediaDirLength = strlenu($this->yellow->config->get("mediaDir"));
|
||||
$systemDirLength = strlenu($this->yellow->config->get("systemDir"));
|
||||
return substru($fileName, 0, $contentDirLength) == $this->yellow->config->get("contentDir") ||
|
||||
substru($fileName, 0, $mediaDirLength) == $this->yellow->config->get("mediaDir") ||
|
||||
substru($fileName, 0, $systemDirLength) == $this->yellow->config->get("systemDir");
|
||||
}
|
||||
}
|
||||
|
||||
// Yellow toolbox with helpers
|
||||
|
@ -2448,26 +2457,7 @@ class YellowToolbox
|
|||
$location = rawurldecode(($pos = strposu($location, '?')) ? substru($location, 0, $pos) : $location);
|
||||
if($filterStrict)
|
||||
{
|
||||
$locationFiltered = "";
|
||||
if($location[0] != '/') $location = '/'.$location;
|
||||
for($pos=0; $pos<strlenb($location); ++$pos)
|
||||
{
|
||||
if($location[$pos] == '/')
|
||||
{
|
||||
if($location[$pos+1] == '/') continue;
|
||||
if($location[$pos+1] == '.')
|
||||
{
|
||||
$posNew = $pos+1; while($location[$posNew] == '.') ++$posNew;
|
||||
if($location[$posNew]=='/' || $location[$posNew]=='')
|
||||
{
|
||||
$pos = $posNew-1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$locationFiltered .= $location[$pos];
|
||||
}
|
||||
$location = $locationFiltered;
|
||||
$location = $this->normaliseTokens($location, true);
|
||||
$separator = $this->getLocationArgsSeparator();
|
||||
if(preg_match("/^(.*?\/)([^\/]+$separator.*)$/", $location, $matches))
|
||||
{
|
||||
|
@ -2596,6 +2586,31 @@ class YellowToolbox
|
|||
}
|
||||
}
|
||||
|
||||
// Normalise path or location, take care of relative path tokens
|
||||
function normaliseTokens($text, $prependSlash = false)
|
||||
{
|
||||
$textFiltered = "";
|
||||
if($prependSlash && $text[0]!='/') $textFiltered .= '/';
|
||||
for($pos=0; $pos<strlenb($text); ++$pos)
|
||||
{
|
||||
if($text[$pos]=='/' || $pos==0)
|
||||
{
|
||||
if($text[$pos+1] == '/') continue;
|
||||
if($text[$pos+1] == '.')
|
||||
{
|
||||
$posNew = $pos+1; while($text[$posNew] == '.') ++$posNew;
|
||||
if($text[$posNew]=='/' || $text[$posNew]=='')
|
||||
{
|
||||
$pos = $posNew-1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$textFiltered .= $text[$pos];
|
||||
}
|
||||
return $textFiltered;
|
||||
}
|
||||
|
||||
// Normalise location arguments
|
||||
function normaliseArgs($text, $appendSlash = true, $filterStrict = true)
|
||||
{
|
||||
|
@ -2823,9 +2838,19 @@ class YellowToolbox
|
|||
}
|
||||
|
||||
// Delete file
|
||||
function deleteFile($fileName)
|
||||
function deleteFile($fileName, $pathTrash = "")
|
||||
{
|
||||
return @unlink($fileName);
|
||||
if(empty($pathTrash))
|
||||
{
|
||||
$ok = @unlink($fileName);
|
||||
} else {
|
||||
$fileNameDest = $pathTrash;
|
||||
$fileNameDest .= pathinfo($fileName, PATHINFO_FILENAME);
|
||||
$fileNameDest .= "-".str_replace(array(" ", ":"), "-", date("Y-m-d H:i:s", filemtime($fileName)));
|
||||
$fileNameDest .= ".".pathinfo($fileName, PATHINFO_EXTENSION);
|
||||
$ok = $this->renameFile($fileName, $fileNameDest, true);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
|
||||
// Return lines from text string
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
// Update plugin
|
||||
class YellowUpdate
|
||||
{
|
||||
const Version = "0.6.1";
|
||||
const Version = "0.6.2";
|
||||
var $yellow; //access to API
|
||||
|
||||
// Handle initialisation
|
||||
|
@ -15,7 +15,7 @@ class YellowUpdate
|
|||
$this->yellow->config->setDefault("updatePluginsUrl", "https://github.com/datenstrom/yellow-plugins");
|
||||
$this->yellow->config->setDefault("updateThemesUrl", "https://github.com/datenstrom/yellow-themes");
|
||||
$this->yellow->config->setDefault("updateVersionFile", "version.ini");
|
||||
$this->yellow->config->setDefault("updateFile", "update.ini");
|
||||
$this->yellow->config->setDefault("updateInformationFile", "update.ini");
|
||||
}
|
||||
|
||||
// Handle request
|
||||
|
@ -49,7 +49,7 @@ class YellowUpdate
|
|||
return "update [FEATURE]";
|
||||
}
|
||||
|
||||
// Update plugins and themes
|
||||
// Show software updates
|
||||
function updateCommand($args)
|
||||
{
|
||||
$statusCode = 0;
|
||||
|
@ -69,22 +69,138 @@ class YellowUpdate
|
|||
echo "Yellow $command: $updates update".($updates==1 ? "":"s")." available\n";
|
||||
} else {
|
||||
echo "Yellow $command: No updates available\n";
|
||||
|
||||
}
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Update software
|
||||
function update()
|
||||
{
|
||||
$statusCode = 0;
|
||||
$path = $this->yellow->config->get("pluginDir");
|
||||
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry)
|
||||
{
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::update file:$entry<br/>\n";
|
||||
$statusCode = max($statusCode, $this->updateSoftwareArchive($entry));
|
||||
}
|
||||
$path = $this->yellow->config->get("themeDir");
|
||||
foreach($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry)
|
||||
{
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::update file:$entry<br/>\n";
|
||||
$statusCode = max($statusCode, $this->updateSoftwareArchive($entry));
|
||||
}
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Process request to update software
|
||||
// Update software from archive
|
||||
function updateSoftwareArchive($path)
|
||||
{
|
||||
$statusCode = 0;
|
||||
$zip = new ZipArchive();
|
||||
if($zip->open($path) === true)
|
||||
{
|
||||
$fileNameInformation = $this->yellow->config->get("updateInformationFile");
|
||||
for($i=0; $i<$zip->numFiles; ++$i)
|
||||
{
|
||||
$fileName = $zip->getNameIndex($i);
|
||||
if(empty($pathBase) && substru($fileName, -1, 1)=="/") $pathBase = $fileName;
|
||||
if($fileName == $pathBase.$fileNameInformation)
|
||||
{
|
||||
$fileData = $zip->getFromIndex($i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
foreach($this->yellow->toolbox->getTextLines($fileData) as $line)
|
||||
{
|
||||
if(preg_match("/^\#/", $line)) continue;
|
||||
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
||||
if(lcfirst($matches[1])=="plugin" || lcfirst($matches[1])=="theme") $software = $matches[2];
|
||||
if(!empty($software) && !empty($matches[1]) && !empty($matches[2]))
|
||||
{
|
||||
list($fileName, $flags) = explode(',', $matches[2], 2);
|
||||
$modified = $zip->statName($pathBase.$fileName)["mtime"];
|
||||
$rawData = $zip->getFromName($pathBase.$fileName);
|
||||
$statusCode = $this->updateSoftwareFile($matches[1], $modified, $rawData, $flags, $software);
|
||||
if($statusCode != 200) break;
|
||||
}
|
||||
}
|
||||
$zip->close();
|
||||
if($statusCode==200 && !$this->yellow->toolbox->deleteFile($path))
|
||||
{
|
||||
$statusCode = 500;
|
||||
$this->yellow->page->error($statusCode, "Can't delete file '$path'!");
|
||||
|
||||
}
|
||||
}
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Update software file
|
||||
function updateSoftwareFile($fileName, $modified, $rawData, $flags, $software)
|
||||
{
|
||||
$statusCode = 200;
|
||||
$fileName = $this->yellow->toolbox->normaliseTokens($fileName);
|
||||
if($this->yellow->lookup->isValidFile($fileName) && !empty($flags))
|
||||
{
|
||||
$create = $update = $delete = false;
|
||||
if(preg_match("/create/i", $flags) && !empty($rawData)) $create = true;
|
||||
if(preg_match("/update/i", $flags) && !empty($rawData)) $update = true;
|
||||
if(preg_match("/delete/i", $flags)) $delete = true;
|
||||
if(preg_match("/optional/i", $flags) && $this->isSoftware($software)) $create = $update = $delete = false;
|
||||
if($create && !is_file($fileName))
|
||||
{
|
||||
if(!$this->yellow->toolbox->createFile($fileName, $rawData, true) ||
|
||||
!$this->yellow->toolbox->modifyFile($fileName, $modified))
|
||||
{
|
||||
$statusCode = 500;
|
||||
$this->yellow->page->error($statusCode, "Can't create file '$fileName'!");
|
||||
}
|
||||
}
|
||||
if($update && is_file($fileName))
|
||||
{
|
||||
if(!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir")) ||
|
||||
!$this->yellow->toolbox->createFile($fileName, $rawData) ||
|
||||
!$this->yellow->toolbox->modifyFile($fileName, $modified))
|
||||
{
|
||||
$statusCode = 500;
|
||||
$this->yellow->page->error($statusCode, "Can't update file '$fileName'!");
|
||||
}
|
||||
}
|
||||
if($delete && is_file($fileName))
|
||||
{
|
||||
if(!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir")))
|
||||
{
|
||||
$statusCode = 500;
|
||||
$this->yellow->page->error($statusCode, "Can't delete file '$fileName'!");
|
||||
}
|
||||
}
|
||||
if(defined("DEBUG") && DEBUG>=3) echo "YellowUpdate::updateSoftwareFile file:$fileName flags:$flags<br/>\n";
|
||||
}
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Process request to install updates
|
||||
function processRequestUpdate($serverScheme, $serverName, $base, $location, $fileName)
|
||||
{
|
||||
return 0;
|
||||
$statusCode = 0;
|
||||
if($this->isContentFile($fileName))
|
||||
{
|
||||
$statusCode = $this->update();
|
||||
if($statusCode == 200)
|
||||
{
|
||||
$statusCode = 303;
|
||||
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
|
||||
$this->yellow->sendStatus($statusCode, $location);
|
||||
}
|
||||
}
|
||||
return $statusCode;
|
||||
}
|
||||
|
||||
// Process request to install website
|
||||
function processRequestInstallation($serverScheme, $serverName, $base, $location, $fileName)
|
||||
{
|
||||
$statusCode = 0;
|
||||
if(!$this->yellow->isStaticFile($location, $fileName, false))
|
||||
if($this->isContentFile($fileName))
|
||||
{
|
||||
$fileName = $this->yellow->lookup->findFileNew($fileName,
|
||||
$this->yellow->config->get("webinterfaceNewFile"), $this->yellow->config->get("configDir"), "installation");
|
||||
|
@ -230,7 +346,7 @@ class YellowUpdate
|
|||
curl_close($curlHandle);
|
||||
if($statusCode == 200)
|
||||
{
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::getSoftwareVersion location:$urlVersion\n";
|
||||
if(defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::getSoftwareVersionFromUrl location:$url\n";
|
||||
foreach($this->yellow->toolbox->getTextLines($rawData) as $line)
|
||||
{
|
||||
preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
|
||||
|
@ -238,7 +354,7 @@ class YellowUpdate
|
|||
{
|
||||
list($version, $url) = explode(',', $matches[2]);
|
||||
$data[$matches[1]] = $version;
|
||||
if(defined("DEBUG") && DEBUG>=3) echo "YellowUpdate::getSoftwareVersion $matches[1]:$version\n";
|
||||
if(defined("DEBUG") && DEBUG>=3) echo "YellowUpdate::getSoftwareVersionFromUrl $matches[1]:$version\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,10 +367,24 @@ class YellowUpdate
|
|||
return array($statusCode, $data);
|
||||
}
|
||||
|
||||
// Return if installation is necessary
|
||||
// Check if software exists
|
||||
function isSoftware($software)
|
||||
{
|
||||
$data = $this->yellow->plugins->getData();
|
||||
return !is_null($data[$software]);
|
||||
}
|
||||
|
||||
// Check if installation requested
|
||||
function isInstallation()
|
||||
{
|
||||
return PHP_SAPI!="cli" && $this->yellow->config->get("installationMode");
|
||||
return $this->yellow->config->get("installationMode") && PHP_SAPI!="cli";
|
||||
}
|
||||
|
||||
// Check if content file
|
||||
function isContentFile($fileName)
|
||||
{
|
||||
$contentDirLength = strlenu($this->yellow->config->get("contentDir"));
|
||||
return substru($fileName, 0, $contentDirLength) == $this->yellow->config->get("contentDir");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue