yellow = $yellow;
$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("updateInformationFile", "update.ini");
}
// Handle request
function onRequest($serverScheme, $serverName, $base, $location, $fileName)
{
$statusCode = 0;
if($this->isInstallation())
{
$statusCode = $this->processRequestInstallation($serverScheme, $serverName, $base, $location, $fileName);
} else {
$statusCode = $this->processRequestUpdate($serverScheme, $serverName, $base, $location, $fileName);
}
return $statusCode;
}
// Handle command
function onCommand($args)
{
list($command) = $args;
switch($command)
{
case "update": $statusCode = $this->updateCommand($args); break;
default: $statusCode = $this->updateCommandPending($args); break;
}
return $statusCode;
}
// Handle command help
function onCommandHelp()
{
return "update [FEATURE]";
}
// Update software
function updateCommand($args)
{
list($command, $feature) = $args;
list($statusCode, $data) = $this->getSoftwareUpdate($feature);
if(!empty($data))
{
foreach($data as $key=>$value)
{
list($version) = explode(',', $value);
echo "$key $version\n";
}
if($statusCode==200) $statusCode = $this->download($data);
if($statusCode==200) $statusCode = $this->update();
if($statusCode!=200) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
echo "Yellow $command: Software ".($statusCode!=200 ? "not " : "")."updated\n";
} else {
if($statusCode!=200) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
echo "Yellow $command: No updates available\n";
}
return $statusCode;
}
// Update pending software
function updateCommandPending($args)
{
$statusCode = $this->update();
if($statusCode!=0)
{
if($statusCode!=200) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
echo "Yellow has ".($statusCode!=200 ? "not " : "")."been updated: Please run command again\n";
}
return $statusCode;
}
// Download available updates
function download($data)
{
$statusCode = 0;
$path = $this->yellow->config->get("pluginDir");
$fileExtension = $this->yellow->config->get("downloadExtension");
foreach($data as $key=>$value)
{
$fileName = strtoloweru("$path$key.zip");
list($version, $url) = explode(',', $value);
list($statusCode, $fileData) = $this->getSoftwareFile($url);
if(empty($fileData) || !$this->yellow->toolbox->createFile($fileName.$fileExtension, $fileData))
{
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't download file '$fileName'!");
break;
}
}
if($statusCode==200)
{
foreach($data as $key=>$value)
{
$fileName = strtoloweru("$path$key.zip");
if(!$this->yellow->toolbox->renameFile($fileName.$fileExtension, $fileName))
{
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't create file '$fileName'!");
}
}
}
return $statusCode;
}
// Update downloaded software
function update()
{
$statusCode = 0;
foreach($this->yellow->plugins->plugins as $key=>$value)
{
if(method_exists($value["obj"], "onUpdate"))
{
$statusCode = $value["obj"]->onUpdate($this->yellow->getRequestHandler());
if($statusCode!=0) break;
}
}
if($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
\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
\n";
$statusCode = max($statusCode, $this->updateSoftwareArchive($entry));
}
}
return $statusCode;
}
// 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))
{
preg_match("#^(.*\/).*?$#", $fileName, $matches);
$pathBase = $matches[1];
}
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);
$fileData = $zip->getFromName($pathBase.$fileName);
$metaData = $zip->statName($pathBase.$fileName);
$modified = $metaData ? $metaData["mtime"] : 0;
$statusCode = $this->updateSoftwareFile($matches[1], $fileData, $modified, $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, $fileData, $modified, $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) && !is_file($fileName) && !empty($fileData)) $create = true;
if(preg_match("/update/i", $flags) && is_file($fileName) && !empty($fileData)) $update = true;
if(preg_match("/delete/i", $flags) && is_file($fileName)) $delete = true;
if(preg_match("/optional/i", $flags) && $this->isSoftware($software)) $create = $update = $delete = false;
if($create)
{
if(!$this->yellow->toolbox->createFile($fileName, $fileData, true) ||
!$this->yellow->toolbox->modifyFile($fileName, $modified))
{
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't create file '$fileName'!");
}
}
if($update)
{
if(!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir")) ||
!$this->yellow->toolbox->createFile($fileName, $fileData) ||
!$this->yellow->toolbox->modifyFile($fileName, $modified))
{
$statusCode = 500;
$this->yellow->page->error($statusCode, "Can't update file '$fileName'!");
}
}
if($delete)
{
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
\n";
}
return $statusCode;
}
// Update installation files
function updateInstallation($feature)
{
$ok = true;
$path = $this->yellow->config->get("pluginDir");
$regex = "/^.*\\".$this->yellow->config->get("downloadExtension")."$/";
foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false) as $entry)
{
if(preg_match("/$feature/i", basename($entry)))
{
if($this->updateSoftwareArchive($entry)!=200) $ok = false;
}
}
if($ok)
{
foreach($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false) as $entry)
{
$this->yellow->toolbox->deleteFile($entry);
}
}
return $ok;
}
// Process request to update software
function processRequestUpdate($serverScheme, $serverName, $base, $location, $fileName)
{
$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->isContentFile($fileName))
{
$fileName = $this->yellow->lookup->findFileNew($fileName,
$this->yellow->config->get("webinterfaceNewFile"), $this->yellow->config->get("configDir"), "installation");
$this->yellow->pages->pages["root/"] = array();
$this->yellow->page = new YellowPage($this->yellow);
$this->yellow->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName);
$this->yellow->page->parseData($this->getRawDataInstallation($fileName, $this->yellow->getRequestLanguage()), false, 404);
$this->yellow->page->parserSafeMode = false;
$this->yellow->page->parseContent();
$name = trim(preg_replace("/[^\pL\d\-\. ]/u", "-", $_REQUEST["name"]));
$email = trim($_REQUEST["email"]);
$password = trim($_REQUEST["password"]);
$language = trim($_REQUEST["language"]);
$feature = trim($_REQUEST["feature"]);
$status = trim($_REQUEST["status"]);
if($status=="install")
{
$status = "ok";
$fileNameHome = $this->yellow->lookup->findFileFromLocation("/");
$fileData = strreplaceu("\r\n", "\n", $this->yellow->toolbox->readFile($fileNameHome));
if($fileData==$this->getRawDataHome("en") && $language!="en")
{
$status = $this->yellow->toolbox->createFile($fileNameHome, $this->getRawDataHome($language)) ? "ok" : "error";
if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameHome'!");
}
}
if($status=="ok")
{
if(!empty($email) && !empty($password) && $this->yellow->plugins->isExisting("webinterface"))
{
$fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("webinterfaceUserFile");
$status = $this->yellow->plugins->get("webinterface")->users->update($fileNameUser, $email, $password, $name, $language) ? "ok" : "error";
if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
}
}
if($status=="ok")
{
if(!empty($feature))
{
$status = $this->updateInstallation($feature) ? "ok" : "error";
if($status=="error") $this->yellow->page->error(500, "Can't install feature '$feature'!");
}
}
if($status=="ok")
{
if($this->yellow->config->get("sitename")=="Yellow") $_REQUEST["sitename"] = $name;
$fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
$status = $this->yellow->config->update($fileNameConfig, $this->getConfigData()) ? "done" : "error";
if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameConfig'!");
}
if($status=="done")
{
$statusCode = 303;
$location = $this->yellow->lookup->normaliseUrl($serverScheme, $serverName, $base, $location);
$this->yellow->sendStatus($statusCode, $location);
} else {
$statusCode = $this->yellow->sendPage();
}
}
return $statusCode;
}
// Return raw data for installation page
function getRawDataInstallation($fileName, $language)
{
$rawData = $this->yellow->toolbox->readFile($fileName);
if(empty($rawData))
{
$this->yellow->text->setLanguage($language);
$rawData = "---\nTitle:".$this->yellow->text->get("webinterfaceInstallationTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
$rawData .= "