mikuli.cz

:)
git clone https://git.sr.ht/~ashymad/mikuli.cz
Log | Files | Refs

commit f52412ad6efdc2ed1764fa893bb9e4f83a1041e2
parent 0e3c7e65ffc2dcdd76aadb0a138c05101686b1ff
Author: markseu <mark2011@mayberg.se>
Date:   Tue, 11 Aug 2020 20:12:05 +0200

Updated extensions, summertime sadness remix

Diffstat:
Msystem/extensions/command.php | 9++++-----
Msystem/extensions/core.php | 348+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msystem/extensions/edit.php | 16+++++++++-------
Msystem/extensions/install-languages.zip | 0
Msystem/extensions/install.php | 122++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Asystem/extensions/update-current.ini | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msystem/extensions/update.php | 578+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msystem/settings/system.ini | 5+----
8 files changed, 709 insertions(+), 469 deletions(-)

diff --git a/system/extensions/command.php b/system/extensions/command.php @@ -2,7 +2,7 @@ // Command extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/command class YellowCommand { - const VERSION = "0.8.21"; + const VERSION = "0.8.22"; public $yellow; // access to API public $files; // number of files public $links; // number of links @@ -14,7 +14,6 @@ class YellowCommand { public function onLoad($yellow) { $this->yellow = $yellow; $this->yellow->system->setDefault("commandStaticBuildDirectory", "public/"); - $this->yellow->system->setDefault("commandStaticCacheDirectory", "cache/"); $this->yellow->system->setDefault("commandStaticDefaultFile", "index.html"); $this->yellow->system->setDefault("commandStaticErrorFile", "404.html"); } @@ -470,9 +469,9 @@ class YellowCommand { // Process request for cached files public function processRequestCache($scheme, $address, $base, $location, $fileName) { $statusCode = 0; - if (is_dir($this->yellow->system->get("commandStaticCacheDirectory"))) { + if (is_dir($this->yellow->system->get("coreCacheDirectory"))) { $location .= $this->yellow->toolbox->getLocationArguments(); - $fileName = rtrim($this->yellow->system->get("commandStaticCacheDirectory"), "/").$location; + $fileName = rtrim($this->yellow->system->get("coreCacheDirectory"), "/").$location; if (!$this->yellow->lookup->isFileLocation($location)) $fileName .= $this->yellow->system->get("commandStaticDefaultFile"); if (is_file($fileName) && is_readable($fileName) && !$this->yellow->isCommandLine()) { $statusCode = $this->yellow->sendFile(200, $fileName, true); @@ -588,7 +587,7 @@ class YellowCommand { $locations = array(); $pathIgnore = "($path/|". $this->yellow->system->get("commandStaticBuildDirectory")."|". - $this->yellow->system->get("commandStaticCacheDirectory")."|". + $this->yellow->system->get("coreCacheDirectory")."|". $this->yellow->system->get("coreContentDirectory")."|". $this->yellow->system->get("coreMediaDirectory")."|". $this->yellow->system->get("coreSystemDirectory").")"; diff --git a/system/extensions/core.php b/system/extensions/core.php @@ -2,7 +2,7 @@ // Core extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/core class YellowCore { - const VERSION = "0.8.17"; + const VERSION = "0.8.18"; const RELEASE = "0.8.15"; public $page; // current page public $content; // content files @@ -55,6 +55,7 @@ class YellowCore { $this->system->setDefault("coreLayoutDirectory", "system/layouts/"); $this->system->setDefault("coreThemeDirectory", "system/themes/"); $this->system->setDefault("coreTrashDirectory", "system/trash/"); + $this->system->setDefault("coreCacheDirectory", "cache/"); $this->system->setDefault("coreContentDirectory", "content/"); $this->system->setDefault("coreContentRootDirectory", "default/"); $this->system->setDefault("coreContentHomeDirectory", "home/"); @@ -438,7 +439,7 @@ class YellowPage { public function __construct($yellow) { $this->yellow = $yellow; - $this->metaData = new YellowDataCollection(); + $this->metaData = new YellowArray(); $this->pageCollection = new YellowPageCollection($yellow); $this->pageRelations = array(); $this->headerData = array(); @@ -478,7 +479,7 @@ class YellowPage { // Parse page meta data public function parseMeta($pageError = "") { - $this->metaData = new YellowDataCollection(); + $this->metaData = new YellowArray(); if (!is_null($this->rawData)) { $this->set("title", $this->yellow->toolbox->createTextTitle($this->location)); $this->set("language", $this->yellow->lookup->findLanguageFromFile($this->fileName, $this->yellow->system->get("language"))); @@ -966,36 +967,6 @@ class YellowPage { } } -class YellowDataCollection extends ArrayObject { - public function __construct() { - parent::__construct(array()); - } - - // Return array element - public function offsetGet($key) { - if (is_string($key)) $key = lcfirst($key); - return parent::offsetGet($key); - } - - // Set array element - public function offsetSet($key, $value) { - if (is_string($key)) $key = lcfirst($key); - parent::offsetSet($key, $value); - } - - // Remove array element - public function offsetUnset($key) { - if (is_string($key)) $key = lcfirst($key); - parent::offsetUnset($key); - } - - // Check if array element exists - public function offsetExists($key) { - if (is_string($key)) $key = lcfirst($key); - return parent::offsetExists($key); - } -} - class YellowPageCollection extends ArrayObject { public $yellow; // access to API public $filterValue; // current page filter value @@ -1563,8 +1534,8 @@ class YellowSystem { public function __construct($yellow) { $this->yellow = $yellow; $this->modified = 0; - $this->settings = new YellowDataCollection(); - $this->settingsDefaults = new YellowDataCollection(); + $this->settings = new YellowArray(); + $this->settingsDefaults = new YellowArray(); } // Load system settings from file @@ -1572,43 +1543,27 @@ class YellowSystem { if (defined("DEBUG") && DEBUG>=2) echo "YellowSystem::load file:$fileName<br/>\n"; $this->modified = $this->yellow->toolbox->getFileModified($fileName); $fileData = $this->yellow->toolbox->readFile($fileName); - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\#/", $line)) continue; - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (!empty($matches[1]) && !strempty($matches[2])) { - $this->set($matches[1], $matches[2]); - if (defined("DEBUG") && DEBUG>=3) echo "YellowSystem::load $matches[1]:$matches[2]<br/>\n"; - } + $this->settings = $this->yellow->toolbox->getTextSettings($fileData, ""); + if (defined("DEBUG") && DEBUG>=3) { + foreach ($this->settings as $key=>$value) { + echo "YellowSystem::load ".ucfirst($key).":$value<br/>\n"; } } } // Save system settings to file public function save($fileName, $settings) { - $settingsNew = new YellowDataCollection(); + $this->modified = time(); + $settingsNew = new YellowArray(); foreach ($settings as $key=>$value) { if (!empty($key) && !strempty($value)) { $this->set($key, $value); $settingsNew[$key] = $value; } } - $this->modified = time(); $fileData = $this->yellow->toolbox->readFile($fileName); - $fileDataNew = ""; - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (!empty($matches[1]) && isset($settingsNew[$matches[1]])) { - $fileDataNew .= "$matches[1]: ".$settingsNew[$matches[1]]."\n"; - unset($settingsNew[$matches[1]]); - continue; - } - } - $fileDataNew .= $line; - } - foreach ($settingsNew as $key=>$value) { - $fileDataNew .= ucfirst($key).": $value\n"; - } - return $this->yellow->toolbox->createFile($fileName, $fileDataNew); + $fileData = $this->yellow->toolbox->setTextSettings($fileData, "", "", $settingsNew); + return $this->yellow->toolbox->createFile($fileName, $fileData); } // Set default system setting @@ -1695,50 +1650,22 @@ class YellowUser { public function __construct($yellow) { $this->yellow = $yellow; $this->modified = 0; - $this->settings = array(); + $this->settings = new YellowArray(); $this->email = ""; } // Load user settings from file public function load($fileName) { if (defined("DEBUG") && DEBUG>=2) echo "YellowUser::load file:$fileName<br/>\n"; - $email = ""; $this->modified = $this->yellow->toolbox->getFileModified($fileName); $fileData = $this->yellow->toolbox->readFile($fileName); - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\#/", $line)) continue; - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (lcfirst($matches[1])=="email" && !strempty($matches[2])) { - $email = $matches[2]; - if (defined("DEBUG") && DEBUG>=3) echo "YellowUser::load email:$email<br/>\n"; - } - if (!empty($email) && !empty($matches[1]) && !strempty($matches[2])) { - $this->setUser($matches[1], $matches[2], $email); - } - } - } + $this->settings = $this->yellow->toolbox->getTextSettings($fileData, "email"); } // Save user settings to file public function save($fileName, $email, $settings) { - $scan = false; - $fileData = $this->yellow->toolbox->readFile($fileName); - $fileDataStart = $fileDataMiddle = $fileDataEnd = ""; - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (lcfirst($matches[1])=="email" && !strempty($matches[2])) { - $scan = $matches[2]==$email; - } - } - if (!$scan && empty($fileDataMiddle)) { - $fileDataStart .= $line; - } elseif ($scan) { - $fileDataMiddle .= $line; - } else { - $fileDataEnd .= $line; - } - } - $settingsNew = new YellowDataCollection(); + $this->modified = time(); + $settingsNew = new YellowArray(); $settingsNew["email"] = $email; foreach ($settings as $key=>$value) { if (!empty($key) && !strempty($value)) { @@ -1746,53 +1673,18 @@ class YellowUser { $settingsNew[$key] = $value; } } - $fileDataSettings = ""; - foreach ($this->yellow->toolbox->getTextLines($fileDataMiddle) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (!empty($matches[1]) && isset($settingsNew[$matches[1]])) { - $fileDataSettings .= "$matches[1]: ".$settingsNew[$matches[1]]."\n"; - unset($settingsNew[$matches[1]]); - continue; - } - } - $fileDataSettings .= $line; - } - foreach ($settingsNew as $key=>$value) { - $fileDataSettings .= ucfirst($key).": $value\n"; - } - if (!empty($fileDataMiddle)) { - $fileDataMiddle = rtrim($fileDataSettings)."\n"; - if (!empty($fileDataEnd)) $fileDataMiddle .= "\n"; - } else { - if (!empty($fileDataStart)) $fileDataEnd .= "\n"; - $fileDataEnd .= $fileDataSettings; - } - $fileDataNew = $fileDataStart.$fileDataMiddle.$fileDataEnd; - return $this->yellow->toolbox->createFile($fileName, $fileDataNew); + $fileData = $this->yellow->toolbox->readFile($fileName); + $fileData = $this->yellow->toolbox->setTextSettings($fileData, "email", $email, $settingsNew); + return $this->yellow->toolbox->createFile($fileName, $fileData); } - // Remove user from file + // Remove user settings from file public function remove($fileName, $email) { - $scan = false; - $fileData = $this->yellow->toolbox->readFile($fileName); - $fileDataStart = $fileDataMiddle = $fileDataEnd = ""; - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (lcfirst($matches[1])=="email" && !strempty($matches[2])) { - $scan = $matches[2]==$email; - } - } - if (!$scan && empty($fileDataMiddle)) { - $fileDataStart .= $line; - } elseif ($scan) { - $fileDataMiddle .= $line; - } else { - $fileDataEnd .= $line; - } - } + $this->modified = time(); if (isset($this->settings[$email])) unset($this->settings[$email]); - $fileDataNew = rtrim($fileDataStart.$fileDataEnd)."\n"; - return $this->yellow->toolbox->createFile($fileName, $fileDataNew); + $fileData = $this->yellow->toolbox->readFile($fileName); + $fileData = $this->yellow->toolbox->unsetTextSettings($fileData, "email", $email); + return $this->yellow->toolbox->createFile($fileName, $fileData); } // Set current email @@ -1802,7 +1694,7 @@ class YellowUser { // Set user setting public function setUser($key, $value, $email) { - if (!isset($this->settings[$email])) $this->settings[$email] = new YellowDataCollection(); + if (!isset($this->settings[$email])) $this->settings[$email] = new YellowArray(); $this->settings[$email][$key] = $value; } @@ -1852,8 +1744,8 @@ class YellowLanguage { public function __construct($yellow) { $this->yellow = $yellow; $this->modified = 0; - $this->settings = new YellowDataCollection(); - $this->settingsDefaults = new YellowDataCollection(); + $this->settings = new YellowArray(); + $this->settingsDefaults = new YellowArray(); $this->language = ""; } @@ -1863,18 +1755,15 @@ class YellowLanguage { $regex = "/^".basename($fileName)."$/"; foreach ($this->yellow->toolbox->getDirectoryEntries($path, $regex, true, false) as $entry) { if (defined("DEBUG") && DEBUG>=2) echo "YellowLanguage::load file:$entry<br/>\n"; - $language = ""; $this->modified = max($this->modified, filemtime($entry)); $fileData = $this->yellow->toolbox->readFile($entry); - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\#/", $line)) continue; - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (lcfirst($matches[1])=="language" && !strempty($matches[2])) { - $language = $matches[2]; - if (defined("DEBUG") && DEBUG>=3) echo "YellowLanguage::load language:$language<br/>\n"; - } - if (!empty($language) && !empty($matches[1]) && !strempty($matches[2])) { - $this->setText($matches[1], $matches[2], $language); + $settings = $this->yellow->toolbox->getTextSettings($fileData, "language"); + foreach($settings as $language=>$block) { + if (!isset($this->settings[$language])) { + $this->settings[$language] = $block; + } else { + foreach ($block as $key=>$value) { + $this->settings[$language][$key] = $value; } } } @@ -1893,7 +1782,7 @@ class YellowLanguage { // Set language setting public function setText($key, $value, $language) { - if (!isset($this->settings[$language])) $this->settings[$language] = new YellowDataCollection(); + if (!isset($this->settings[$language])) $this->settings[$language] = new YellowArray(); $this->settings[$language][$key] = $value; } @@ -2020,7 +1909,7 @@ class YellowExtension { // Load extensions public function load($path) { foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.php$/", true, false) as $entry) { - if (defined("DEBUG") && DEBUG>=2) echo "YellowExtension::load file:$entry<br/>\n"; + if (defined("DEBUG") && DEBUG>=3) echo "YellowExtension::load file:$entry<br/>\n"; $this->modified = max($this->modified, filemtime($entry)); require_once($entry); $name = $this->yellow->lookup->normaliseName(basename($entry), true, true); @@ -2867,6 +2756,122 @@ class YellowToolbox { return $lines; } + // Return settings from text + function getTextSettings($text, $blockStart) { + $settings = new YellowArray(); + if (empty($blockStart)) { + foreach ($this->getTextLines($text) as $line) { + if (preg_match("/^\#/", $line)) continue; + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (!empty($matches[1]) && !strempty($matches[2])) { + $settings[$matches[1]] = $matches[2]; + + } + } + } + } else { + $blockKey = ""; + foreach ($this->getTextLines($text) as $line) { + if (preg_match("/^\#/", $line)) continue; + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (lcfirst($matches[1])==$blockStart && !strempty($matches[2])) { + $blockKey = $matches[2]; + $settings[$blockKey] = new YellowArray(); + } + if (!empty($blockKey) && !empty($matches[1]) && !strempty($matches[2])) { + $settings[$blockKey][$matches[1]] = $matches[2]; + } + } + } + } + return $settings; + } + + // Set settings in text + function setTextSettings($text, $blockStart, $blockKey, $settings) { + $textNew = ""; + if (empty($blockStart)) { + foreach ($this->getTextLines($text) as $line) { + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (!empty($matches[1]) && isset($settings[$matches[1]])) { + $textNew .= "$matches[1]: ".$settings[$matches[1]]."\n"; + unset($settings[$matches[1]]); + continue; + } + } + $textNew .= $line; + } + foreach ($settings as $key=>$value) { + $textNew .= ucfirst($key).": $value\n"; + } + } else { + $scan = false; + $textStart = $textMiddle = $textEnd = ""; + foreach ($this->getTextLines($text) as $line) { + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (lcfirst($matches[1])==$blockStart && !strempty($matches[2])) { + $scan = lcfirst($matches[2])==lcfirst($blockKey); + } + } + if (!$scan && empty($textMiddle)) { + $textStart .= $line; + } elseif ($scan) { + $textMiddle .= $line; + } else { + $textEnd .= $line; + } + } + $textSettings = ""; + foreach ($this->getTextLines($textMiddle) as $line) { + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (!empty($matches[1]) && isset($settings[$matches[1]])) { + $textSettings .= "$matches[1]: ".$settings[$matches[1]]."\n"; + unset($settings[$matches[1]]); + continue; + } + $textSettings .= $line; + } + } + foreach ($settings as $key=>$value) { + $textSettings .= ucfirst($key).": $value\n"; + } + if (!empty($textMiddle)) { + $textMiddle = $textSettings; + if (!empty($textEnd)) $textMiddle .= "\n"; + } else { + if (!empty($textStart)) $textEnd .= "\n"; + $textEnd .= $textSettings; + } + $textNew = $textStart.$textMiddle.$textEnd; + } + return $textNew; + } + + // Remove settings from text + function unsetTextSettings($text, $blockStart, $blockKey) { + $textNew = ""; + if (!empty($blockStart)) { + $scan = false; + $textStart = $textMiddle = $textEnd = ""; + foreach ($this->getTextLines($text) as $line) { + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (lcfirst($matches[1])==$blockStart && !strempty($matches[2])) { + $scan = lcfirst($matches[2])==lcfirst($blockKey); + } + } + if (!$scan && empty($textMiddle)) { + $textStart .= $line; + } elseif ($scan) { + $textMiddle .= $line; + } else { + $textEnd .= $line; + } + } + $textNew = rtrim($textStart.$textEnd)."\n"; + } + return $textNew; + } + // Return attributes from text public function getTextAttributes($text) { $tokens = array(); @@ -3470,6 +3475,51 @@ class YellowExtensions { // TODO: remove later, for backwards compatibility public function getExtensions($type = "") { return array(); } public function isExisting($name) { return $this->yellow->extension->isExisting($name); } } + +class YellowArray extends ArrayObject { + public function __construct() { + parent::__construct(array()); + } + + // Set array element + public function set($key, $value) { + $this->offsetSet($key, $value); + } + + // Return array element + public function get($key) { + return $this->offsetExists($key) ? $this->offsetGet($key) : ""; + } + + // Check if array element exists + public function isExisting($key) { + return $this->offsetExists($key); + } + + // Return array element + public function offsetGet($key) { + if (is_string($key)) $key = lcfirst($key); + return parent::offsetGet($key); + } + + // Set array element + public function offsetSet($key, $value) { + if (is_string($key)) $key = lcfirst($key); + parent::offsetSet($key, $value); + } + + // Remove array element + public function offsetUnset($key) { + if (is_string($key)) $key = lcfirst($key); + parent::offsetUnset($key); + } + + // Check if array element exists + public function offsetExists($key) { + if (is_string($key)) $key = lcfirst($key); + return parent::offsetExists($key); + } +} // Make string lowercase, UTF-8 compatible function strtoloweru() { diff --git a/system/extensions/edit.php b/system/extensions/edit.php @@ -2,7 +2,7 @@ // Edit extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/edit class YellowEdit { - const VERSION = "0.8.34"; + const VERSION = "0.8.35"; public $yellow; // access to API public $response; // web response public $merge; // text merge @@ -1293,13 +1293,15 @@ class YellowEditResponse { $statusCode = 200; $rawData = ""; if ($this->yellow->extension->isExisting("update")) { - list($statusCodeCurrent, $dataCurrent) = $this->yellow->extension->get("update")->getExtensionsVersion(); - list($statusCodeLatest, $dataLatest) = $this->yellow->extension->get("update")->getExtensionsVersion(true); + list($statusCodeCurrent, $settingsCurrent) = $this->yellow->extension->get("update")->getExtensionSettings(false); + list($statusCodeLatest, $settingsLatest) = $this->yellow->extension->get("update")->getExtensionSettings(true); $statusCode = max($statusCodeCurrent, $statusCodeLatest); - foreach ($dataCurrent as $key=>$value) { - if (isset($dataLatest[$key])) { - if (strnatcasecmp($dataCurrent[$key], $dataLatest[$key])<0) { - $rawData .= htmlspecialchars(ucfirst($key)." $dataLatest[$key]")."<br />"; + foreach ($settingsCurrent as $key=>$value) { + if ($settingsLatest->isExisting($key)) { + $versionCurrent = $settingsCurrent[$key]->get("version"); + $versionLatest = $settingsLatest[$key]->get("version"); + if (strnatcasecmp($versionCurrent, $versionLatest)<0) { + $rawData .= htmlspecialchars(ucfirst($key)." $versionLatest")."<br />"; } } } diff --git a/system/extensions/install-languages.zip b/system/extensions/install-languages.zip Binary files differ. diff --git a/system/extensions/install.php b/system/extensions/install.php @@ -2,7 +2,7 @@ // Install extension, https://github.com/datenstrom/yellow class YellowInstall { - const VERSION = "0.8.33"; + const VERSION = "0.8.34"; const PRIORITY = "1"; public $yellow; // access to API @@ -33,7 +33,7 @@ class YellowInstall { $extension = trim($this->yellow->page->getRequest("extension")); $status = trim($this->yellow->page->getRequest("status")); $statusCode = $this->updateLog(); - $statusCode = max($statusCode, $this->updateLanguage()); + $statusCode = max($statusCode, $this->updateLanguages()); $this->yellow->content->pages["root/"] = array(); $this->yellow->page = new YellowPage($this->yellow); $this->yellow->page->setRequestInformation($scheme, $address, $base, $location, $fileName); @@ -60,7 +60,7 @@ class YellowInstall { // Process command to install website public function processCommandInstall() { $statusCode = $this->updateLog(); - if ($statusCode==200) $statusCode = $this->updateLanguage(); + if ($statusCode==200) $statusCode = $this->updateLanguages(); if ($statusCode==200) $statusCode = $this->updateSettings("en"); if ($statusCode==200) $statusCode = $this->removeInstall(); if ($statusCode==200) { @@ -87,57 +87,24 @@ class YellowInstall { return $statusCode; } - // Update language - public function updateLanguage() { + // Update languages + public function updateLanguages() { $statusCode = 200; $path = $this->yellow->system->get("coreExtensionDirectory")."install-languages.zip"; if (is_file($path) && $this->yellow->extension->isExisting("update")) { $zip = new ZipArchive(); if ($zip->open($path)===true) { - $languages = $this->detectBrowserLanguages("en, de, fr"); - $languagesFound = array(); - foreach ($languages as $language) $languagesFound[$language] = ""; + $pathBase = ""; if (preg_match("#^(.*\/).*?$#", $zip->getNameIndex(0), $matches)) $pathBase = $matches[1]; $fileData = $zip->getFromName($pathBase.$this->yellow->system->get("updateExtensionFile")); - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) { - list($dummy, $entry, $flags) = $this->yellow->toolbox->getTextList($matches[2], ",", 3); - $arguments = explode(",", $flags); - $language = array_pop($arguments); - if (preg_match("/^(.*)\.php$/", basename($entry), $tokens) && in_array($language, $languages)) { - $languagesFound[$language] = $tokens[1]; - } - } - } - } - $languagesFound = array_slice(array_filter($languagesFound, "strlen"), 0, 3); - $extension = $version = ""; - $modified = 0; - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (lcfirst($matches[1])=="extension") $extension = lcfirst($matches[2]); - if (lcfirst($matches[1])=="version") $version = lcfirst($matches[2]); - if (lcfirst($matches[1])=="published") $modified = strtotime($matches[2]); - if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) { - $fileName = $matches[1]; - list($dummy1, $entry, $dummy2) = $this->yellow->toolbox->getTextList($matches[2], ",", 3); - $fileData = $zip->getFromName($pathBase.basename($entry)); - if (preg_match("/^(.*)\.php$/", basename($entry), $tokens) && in_array($tokens[1], $languagesFound) && !is_file($fileName)) { - $statusCode = $this->yellow->extension->get("update")->updateExtensionFile($fileName, $fileData, $modified, 0, 0, "create", $extension); - } - if (preg_match("/^(.*)\.txt$/", basename($entry), $tokens) && in_array($tokens[1], $languagesFound) && !is_file($fileName)) { - $statusCode = $this->yellow->extension->get("update")->updateExtensionFile($fileName, $fileData, $modified, 0, 0, "create", $extension); - $this->yellow->log($statusCode==200 ? "info" : "error", "Install extension '".ucfirst($tokens[1])." $version'"); - } - if ($statusCode!=200) break; - } - } + foreach ($this->getExtensionsRequired($fileData) as $extension) { + $fileDataPhp = $zip->getFromName($pathBase."$extension/$extension.php"); + $fileDataTxt = $zip->getFromName($pathBase."$extension/$extension.txt"); + $fileDataIni = $zip->getFromName($pathBase."$extension/extension.ini"); + $statusCode = max($statusCode, $this->updateLanguageArchive($fileDataPhp, $fileDataTxt, $fileDataIni, $pathBase, "install")); } + $this->yellow->language->load($this->yellow->system->get("coreExtensionDirectory").".*\.txt"); $zip->close(); - if ($statusCode==200) { - $this->yellow->language->load($this->yellow->system->get("coreExtensionDirectory").".*\.txt"); - } } else { $statusCode = 500; $this->yellow->page->error(500, "Can't open file '$path'!"); @@ -146,19 +113,34 @@ class YellowInstall { return $statusCode; } + // Update language archive + public function updateLanguageArchive($fileDataPhp, $fileDataTxt, $fileDataIni, $pathBase, $action) { + $statusCode = 200; + if ($this->yellow->extension->isExisting("update")) { + $settings = $this->yellow->toolbox->getTextSettings($fileDataIni, ""); + $extension = lcfirst($settings->get("extension")); + $version = $settings->get("version"); + $modified = strtotime($settings->get("published")); + $fileNamePhp = $this->yellow->system->get("coreExtensionDirectory").$extension.".php"; + $fileNameTxt = $this->yellow->system->get("coreExtensionDirectory").$extension.".txt"; + if (!empty($extension) && !empty($version) && !is_file($fileNamePhp)) { + $statusCode = $this->yellow->extension->get("update")->updateExtensionSettings($extension, $settings, $action); + if ($statusCode==200) $statusCode = $this->yellow->extension->get("update")->updateExtensionFile( + $fileNamePhp, $fileDataPhp, $modified, 0, 0, "create", $extension); + if ($statusCode==200) $statusCode = $this->yellow->extension->get("update")->updateExtensionFile( + $fileNameTxt, $fileDataTxt, $modified, 0, 0, "create", $extension); + $this->yellow->log($statusCode==200 ? "info" : "error", ucfirst($action)." extension '".ucfirst($extension)." $version'"); + } + } + return $statusCode; + } + // Update extension public function updateExtension($extension) { $statusCode = 200; - $path = $this->yellow->system->get("coreExtensionDirectory"); - if (!empty($extension) && $this->yellow->extension->isExisting("update")) { - foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) { - if (preg_match("/^install-(.*?)\./", basename($entry), $matches)) { - if (strtoloweru($matches[1])==strtoloweru($extension)) { - $statusCode = $this->yellow->extension->get("update")->updateExtensionArchive($entry, "install"); - break; - } - } - } + $path = $this->yellow->system->get("coreExtensionDirectory")."install-".$extension.".zip"; + if (is_file($path) && $this->yellow->extension->isExisting("update")) { + $statusCode = $this->yellow->extension->get("update")->updateExtensionArchive($path, "install"); } return $statusCode; } @@ -221,7 +203,8 @@ class YellowInstall { } $fileName = $this->yellow->system->get("coreSettingDirectory").$this->yellow->system->get("coreLanguageFile"); $fileData = $this->yellow->toolbox->readFile($fileName); - if (strposu($rawData, "Language:")===false) { + if (strposu($fileData, "Language:")===false) { + if (!empty($fileData)) $fileData .= "\n"; $fileData .= "Language: $language\n"; $fileData .= "media/images/photo.jpg: ".$this->yellow->language->getText("installExampleImage", $language)."\n"; if (!$this->yellow->toolbox->createFile($fileName, $fileData)) { @@ -325,9 +308,10 @@ class YellowInstall { if ($key=="password" || $key=="status") continue; $data[$key] = trim($value); } - $data["coreStaticUrl"] = $this->yellow->toolbox->detectServerUrl(); $data["coreServerTimezone"] = $this->yellow->toolbox->detectServerTimezone(); + $data["coreStaticUrl"] = $this->yellow->toolbox->detectServerUrl(); if ($this->yellow->isCommandLine()) $data["coreStaticUrl"] = getenv("URL"); + if ($this->yellow->system->get("updateNotification")=="none") $data["updateNotification"] = "website/install"; return $data; } @@ -372,4 +356,28 @@ class YellowInstall { } return $extensions; } + + // Return extensions required + public function getExtensionsRequired($fileData) { + $extensions = array(); + $languages = $this->detectBrowserLanguages("en, de, fr"); + foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { + if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { + if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) { + $extension = basename($matches[1]); + $extension = $this->yellow->lookup->normaliseName($extension, true, true); + list($entry, $flags) = $this->yellow->toolbox->getTextList($matches[2], ",", 2); + if (strposu($entry, ".")===false) { + list($dummy1, $entry, $flags) = $this->yellow->toolbox->getTextList($matches[2], ",", 3); + } + $arguments = explode(",", $flags); + $language = array_pop($arguments); + if (preg_match("/^(.*)\.php$/", basename($entry)) && in_array($language, $languages)) { + array_push($extensions, $extension); + } + } + } + } + return array_slice($extensions, 0, 3); + } } diff --git a/system/extensions/update-current.ini b/system/extensions/update-current.ini @@ -0,0 +1,100 @@ +# Datenstrom Yellow update settings + +Extension: Bundle +Version: 0.8.15 +Description: Bundle website files. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/bundle +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/bundle.zip +Published: 2020-07-29 10:13:34 +Developer: Datenstrom +Tag: feature +system/extensions/bundle.php: Bundle,bundle.php,create,update + +Extension: Command +Version: 0.8.22 +Description: Command line of the website. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/command +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/command.zip +Published: 2020-08-08 16:53:28 +Developer: Datenstrom +Tag: feature +system/extensions/command.php: Command,command.php,create,update + +Extension: Core +Version: 0.8.18 +Description: Core functionality of the website. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/core +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/core.zip +Published: 2020-08-08 17:14:56 +Developer: Datenstrom +Tag: feature +system/extensions/core.php: Core,core.php,create,update + +Extension: Edit +Version: 0.8.35 +Description: Edit your website in a web browser. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/edit +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/edit.zip +Published: 2020-08-06 23:26:40 +Developer: Datenstrom +Tag: feature +system/extensions/edit.php: Edit,edit.php,create,update +system/extensions/edit.css: Edit,edit.css,create,update +system/extensions/edit.js: Edit,edit.js,create,update +system/extensions/edit.woff: Edit,edit.woff,create,update + +Extension: Image +Version: 0.8.9 +Description: Images and thumbnails. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/image +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/image.zip +Published: 2020-07-26 16:01:58 +Developer: Datenstrom +Tag: feature +system/extensions/image.php: Image,image.php,create,update + +Extension: Markdown +Version: 0.8.15 +Description: Text formatting for humans. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/markdown +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/markdown.zip +Published: 2020-07-26 16:03:56 +Developer: Datenstrom +Tag: feature +system/extensions/markdown.php: Markdown,markdown.php,create,update +system/extensions/markdownx.php: Markdown,markdownx.php,update + +Extension: Meta +Version: 0.8.14 +Description: Meta data for social media sites. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/meta +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/meta.zip +Published: 2020-07-26 16:03:37 +Developer: Datenstrom, Steffen Schultz +Tag: feature +system/extensions/meta.php: Meta,meta.php,create,update + +Extension: Stockholm +Version: 0.8.9 +Description: Stockholm is a clean theme. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/stockholm +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/stockholm.zip +Published: 2020-07-26 15:14:23 +Designer: Datenstrom +Tag: theme +system/extensions/stockholm.php: Stockholm,stockholm.php,create,update +system/themes/stockholm.css: Stockholm,stockholm.css,create,update,careful +system/themes/stockholm.png: Stockholm,stockholm.png,create +system/themes/stockholm-opensans-bold.woff: Stockholm,stockholm-opensans-bold.woff,create,update,careful +system/themes/stockholm-opensans-light.woff: Stockholm,stockholm-opensans-light.woff,create,update,careful +system/themes/stockholm-opensans-regular.woff: Stockholm,stockholm-opensans-regular.woff,create,update,careful + +Extension: Update +Version: 0.8.30 +Description: Keep your website up to date. +HelpUrl: https://github.com/datenstrom/yellow-extensions/tree/master/source/update +DownloadUrl: https://github.com/datenstrom/yellow-extensions/raw/master/zip/update.zip +Published: 2020-08-08 16:53:43 +Developer: Datenstrom +Tag: feature +system/extensions/update.php: Update,update.php,create,update diff --git a/system/extensions/update.php b/system/extensions/update.php @@ -2,7 +2,7 @@ // Update extension, https://github.com/datenstrom/yellow-extensions/tree/master/source/update class YellowUpdate { - const VERSION = "0.8.29"; + const VERSION = "0.8.30"; const PRIORITY = "2"; public $yellow; // access to API public $updates; // number of updates @@ -10,13 +10,10 @@ class YellowUpdate { // Handle initialisation public function onLoad($yellow) { $this->yellow = $yellow; - $this->yellow->system->setDefault("updateSourceCodeDirectory", "/Users/yourname/Documents/GitHub/"); $this->yellow->system->setDefault("updateExtensionUrl", "https://github.com/datenstrom/yellow-extensions"); $this->yellow->system->setDefault("updateExtensionFile", "extension.ini"); $this->yellow->system->setDefault("updateCurrentFile", "update-current.ini"); $this->yellow->system->setDefault("updateLatestFile", "update-latest.ini"); - $this->yellow->system->setDefault("updateVersionFile", "version.ini"); - $this->yellow->system->setDefault("updateWaffleFile", "waffle.ini"); $this->yellow->system->setDefault("updateNotification", "none"); } @@ -222,7 +219,7 @@ class YellowUpdate { $fileName = $this->yellow->system->get("coreSettingDirectory").$this->yellow->system->get("coreSystemFile"); $fileData = $this->yellow->toolbox->readFile($fileName); $fileDataStart = $fileDataSettings = $fileDataComments = ""; - $settings = new YellowDataCollection(); + $settings = new YellowArray(); $settings->exchangeArray($this->yellow->system->settingsDefaults->getArrayCopy()); foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); @@ -253,7 +250,7 @@ class YellowUpdate { $fileName = $this->yellow->system->get("coreSettingDirectory").$this->yellow->system->get("coreLanguageFile"); $fileData = $this->yellow->toolbox->readFile($fileName); $fileDataStart = $fileDataSettings = $language = ""; - $settings = new YellowDataCollection(); + $settings = new YellowArray(); foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); if (empty($fileDataStart) && preg_match("/^\#/", $line)) { @@ -267,7 +264,7 @@ class YellowUpdate { } } $language = $matches[2]; - $settings = new YellowDataCollection(); + $settings = new YellowArray(); $settings["language"] = $language; foreach ($this->yellow->language->settingsDefaults as $key=>$value) { if ($this->yellow->language->isText($key, $language)) { @@ -290,17 +287,67 @@ class YellowUpdate { $this->yellow->log("error", "Can't write file '$fileName'!"); } } + + // Create extension settings from scratch + public function createExtensionSettings() { + $fileNameCurrent = $this->yellow->system->get("coreExtensionDirectory").$this->yellow->system->get("updateCurrentFile"); + $fileNameLatest = $this->yellow->system->get("coreExtensionDirectory").$this->yellow->system->get("updateLatestFile"); + $url = $this->yellow->system->get("updateExtensionUrl")."/raw/master/".$this->yellow->system->get("updateLatestFile"); + list($statusCode, $fileData) = $this->getExtensionFile($url); + if ($statusCode==200) { + $fileDataCurrent = $fileDataLatest = $fileData; + $settings = $this->yellow->toolbox->getTextSettings($fileDataCurrent, "extension"); + foreach ($settings as $key=>$value) { + if ($this->yellow->extension->isExisting($key)) { + $settingsNew = new YellowArray(); + $settingsNew["extension"] = ucfirst($key); + $settingsNew["version"] = $this->yellow->extension->data[$key]["version"]; + $fileDataCurrent = $this->yellow->toolbox->setTextSettings($fileDataCurrent, "extension", $key, $settingsNew); + } else { + $fileDataCurrent = $this->yellow->toolbox->unsetTextSettings($fileDataCurrent, "extension", $key); + } + } + if(!$this->yellow->toolbox->createFile($fileNameCurrent, $fileDataCurrent)) { + $this->yellow->log("error", "Can't write file '$fileNameCurrent'!"); + } + if(!$this->yellow->toolbox->createFile($fileNameLatest, $fileDataLatest)) { + $this->yellow->log("error", "Can't write file '$fileNameLatest'!"); + } + } + return $statusCode; + } + + // Update extension settings + public function updateExtensionSettings($extension, $settings, $action) { + $statusCode = 200; + $fileNameCurrent = $this->yellow->system->get("coreExtensionDirectory").$this->yellow->system->get("updateCurrentFile"); + $fileData = $this->yellow->toolbox->readFile($fileNameCurrent); + if ($action=="install" || $action=="update") { + $settingsNew = new YellowArray(); + foreach($settings as $key=>$value) $settingsNew[$key] = $value; + $fileData = $this->yellow->toolbox->setTextSettings($fileData, "extension", $extension, $settingsNew); + } else { + $fileData = $this->yellow->toolbox->unsetTextSettings($fileData, "extension", $extension); + } + if (!$this->yellow->toolbox->createFile($fileNameCurrent, $fileData)) { + $statusCode = 500; + $this->yellow->page->error(500, "Can't write file '$fileNameCurrent'!"); + } + return $statusCode; + } // Process command to show website version and updates public function processCommandAbout($command, $text) { echo "Datenstrom Yellow ".YellowCore::RELEASE."\n"; - list($statusCode, $dataCurrent) = $this->getExtensionsVersion(); - list($statusCode, $dataLatest) = $this->getExtensionsVersion(true); - foreach ($dataCurrent as $key=>$value) { - if (!isset($dataLatest[$key]) || strnatcasecmp($dataCurrent[$key], $dataLatest[$key])>=0) { - echo ucfirst($key)." $value\n"; + list($statusCode, $settingsCurrent) = $this->getExtensionSettings(false); + list($statusCode, $settingsLatest) = $this->getExtensionSettings(true); + foreach ($settingsCurrent as $key=>$value) { + $versionCurrent = $versionLatest = $settingsCurrent[$key]->get("version"); + if ($settingsLatest->isExisting($key)) $versionLatest = $settingsLatest[$key]->get("version"); + if (strnatcasecmp($versionCurrent, $versionLatest)<0) { + echo ucfirst($key)." $versionCurrent - Update available\n"; } else { - echo ucfirst($key)." $value - Update available\n"; + echo ucfirst($key)." $versionCurrent\n"; } } if ($statusCode!=200) echo "ERROR checking updates: ".$this->yellow->page->get("pageError")."\n"; @@ -323,11 +370,11 @@ class YellowUpdate { // Process command to install extensions public function processCommandInstall($command, $text) { - $extensions = $this->getExtensions($text); + $extensions = $this->getExtensionsFromText($text); if (!empty($extensions)) { $this->updates = 0; - list($statusCode, $data) = $this->getInstallInformation($extensions); - if ($statusCode==200) $statusCode = $this->downloadExtensions($data); + list($statusCode, $settings) = $this->getExtensionInstallInformation($extensions); + if ($statusCode==200) $statusCode = $this->downloadExtensions($settings); if ($statusCode==200) $statusCode = $this->updateExtensions("install"); if ($statusCode>=400) echo "ERROR installing files: ".$this->yellow->page->get("pageError")."\n"; echo "Yellow $command: Website ".($statusCode!=200 ? "not " : "")."updated"; @@ -340,11 +387,11 @@ class YellowUpdate { // Process command to uninstall extensions public function processCommandUninstall($command, $text) { - $extensions = $this->getExtensions($text); + $extensions = $this->getExtensionsFromText($text); if (!empty($extensions)) { $this->updates = 0; - list($statusCode, $data) = $this->getUninstallInformation($extensions, "core, update"); - if ($statusCode==200) $statusCode = $this->removeExtensions($data); + list($statusCode, $settings) = $this->getExtensionUninstallInformation($extensions, "core, update"); + if ($statusCode==200) $statusCode = $this->removeExtensions($settings); if ($statusCode>=400) echo "ERROR uninstalling files: ".$this->yellow->page->get("pageError")."\n"; echo "Yellow $command: Website ".($statusCode!=200 ? "not " : "")."updated"; echo ", $this->updates extension".($this->updates!=1 ? "s" : "")." uninstalled\n"; @@ -356,11 +403,11 @@ class YellowUpdate { // Process command to update website public function processCommandUpdate($command, $text) { - $extensions = $this->getExtensions($text); - list($statusCode, $data) = $this->getUpdateInformation($extensions); - if ($statusCode!=200 || !empty($data)) { + $extensions = $this->getExtensionsFromText($text); + list($statusCode, $settings) = $this->getExtensionUpdateInformation($extensions); + if ($statusCode!=200 || !empty($settings)) { $this->updates = 0; - if ($statusCode==200) $statusCode = $this->downloadExtensions($data); + if ($statusCode==200) $statusCode = $this->downloadExtensions($settings); if ($statusCode==200) $statusCode = $this->updateExtensions("update"); if ($statusCode>=400) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n"; echo "Yellow $command: Website ".($statusCode!=200 ? "not " : "")."updated"; @@ -388,7 +435,7 @@ class YellowUpdate { } return $statusCode; } - + // Process update notification public function processUpdateNotification($extension, $action) { $statusCode = 200; @@ -408,114 +455,14 @@ class YellowUpdate { return $statusCode; } - // Return extensions from text, space separated - public function getExtensions($text) { - return array_unique(array_filter($this->yellow->toolbox->getTextArguments($text), "strlen")); - } - - // Return install information - public function getInstallInformation($extensions) { - $data = array(); - list($statusCodeCurrent, $dataCurrent) = $this->getExtensionsVersion(); - list($statusCodeLatest, $dataLatest) = $this->getExtensionsVersion(true, true); - $statusCode = max($statusCodeCurrent, $statusCodeLatest); - foreach ($extensions as $extension) { - $found = false; - foreach ($dataLatest as $key=>$value) { - if (strtoloweru($key)==strtoloweru($extension)) { - $data[$key] = $dataLatest[$key]; - $found = true; - break; - } - } - if (!$found) { - $statusCode = 500; - $this->yellow->page->error($statusCode, "Can't find extension '$extension'!"); - } - } - return array($statusCode, $data); - } - - // Return uninstall information - public function getUninstallInformation($extensions, $extensionsProtected) { - $data = array(); - list($statusCodeCurrent, $dataCurrent) = $this->getExtensionsVersion(); - list($statusCodeLatest, $dataLatest) = $this->getExtensionsVersion(true, true); - list($statusCodeRelevant, $dataRelevant) = $this->getExtensionsRelevant(); - $statusCode = max($statusCodeCurrent, $statusCodeLatest, $statusCodeRelevant); - foreach ($extensions as $extension) { - $found = false; - foreach ($dataCurrent as $key=>$value) { - if (strtoloweru($key)==strtoloweru($extension) && isset($dataLatest[$key]) && isset($dataRelevant[$key])) { - $data[$key] = $dataRelevant[$key]; - $found = true; - break; - } - } - if (!$found) { - $statusCode = 500; - $this->yellow->page->error($statusCode, "Can't find extension '$extension'!"); - } - } - $protected = preg_split("/\s*,\s*/", $extensionsProtected); - foreach ($data as $key=>$value) { - if (in_array($key, $protected)) unset($data[$key]); - } - return array($statusCode, $data); - } - - // Return update information - public function getUpdateInformation($extensions) { - $data = array(); - list($statusCodeCurrent, $dataCurrent) = $this->getExtensionsVersion(); - list($statusCodeLatest, $dataLatest) = $this->getExtensionsVersion(true, true); - $statusCode = max($statusCodeCurrent, $statusCodeLatest); - if (empty($extensions)) { - foreach ($dataCurrent as $key=>$value) { - if (isset($dataLatest[$key])) { - list($version, $dummy1, $dummy2) = $this->yellow->toolbox->getTextList($dataLatest[$key], ",", 3); - if (strnatcasecmp($dataCurrent[$key], $version)<0) $data[$key] = $dataLatest[$key]; - } - } - } else { - $force = false; - foreach ($extensions as $extension) { - $found = false; - if ($extension=="force") { $force = true; continue; } - foreach ($dataCurrent as $key=>$value) { - if (isset($dataLatest[$key])) { - list($version, $dummy1, $dummy2) = $this->yellow->toolbox->getTextList($dataLatest[$key], ",", 3); - if (!empty($version) && strtoloweru($key)==strtoloweru($extension)) { - $data[$key] = $dataLatest[$key]; - $found = true; - break; - } - } - } - if (!$found) { - $statusCode = 500; - $this->yellow->page->error($statusCode, "Can't find extension '$extension'!"); - } - } - if (!$force) { - $statusCode = 500; - $this->yellow->page->error($statusCode, "Please use 'force' to update an extension!"); - } - } - if ($statusCode==200) { - foreach ($data as $key=>$value) { - list($version, $dummy1, $dummy2) = $this->yellow->toolbox->getTextList($value, ",", 3); - echo ucfirst($key)." $version\n"; - } - } - return array($statusCode, $data); - } - // Show extensions public function showExtensions() { - list($statusCode, $dataLatest) = $this->getExtensionsVersion(true, true); - foreach ($dataLatest as $key=>$value) { - list($dummy1, $dummy2, $text) = $this->yellow->toolbox->getTextList($value, ",", 3); + list($statusCode, $settingsLatest) = $this->getExtensionSettings(true); + foreach ($settingsLatest as $key=>$value) { + $text = $description = $value->get("description"); + if ($value->isExisting("developer")) $text = "$description Developed by ".$value["developer"]."."; + if ($value->isExisting("translator")) $text = "$description Translated by ".$value["translator"]."."; + if ($value->isExisting("designer")) $text = "$description Designed by ".$value["designer"]."."; echo ucfirst($key).": $text\n"; } if ($statusCode!=200) echo "ERROR checking extensions: ".$this->yellow->page->get("pageError")."\n"; @@ -523,14 +470,13 @@ class YellowUpdate { } // Download extensions - public function downloadExtensions($data) { + public function downloadExtensions($settings) { $statusCode = 200; $path = $this->yellow->system->get("coreExtensionDirectory"); $fileExtension = $this->yellow->system->get("coreDownloadExtension"); - foreach ($data as $key=>$value) { + foreach ($settings as $key=>$value) { $fileName = $path.$this->yellow->lookup->normaliseName($key, true, false, true).".zip"; - list($dummy1, $url, $dummy2) = $this->yellow->toolbox->getTextList($value, ",", 3); - list($statusCode, $fileData) = $this->getExtensionFile($url); + list($statusCode, $fileData) = $this->getExtensionFile($value->get("downloadUrl")); if (empty($fileData) || !$this->yellow->toolbox->createFile($fileName.$fileExtension, $fileData)) { $statusCode = 500; $this->yellow->page->error($statusCode, "Can't write file '$fileName'!"); @@ -538,7 +484,7 @@ class YellowUpdate { } } if ($statusCode==200) { - foreach ($data as $key=>$value) { + foreach ($settings as $key=>$value) { $fileName = $path.$this->yellow->lookup->normaliseName($key, true, false, true).".zip"; if (!$this->yellow->toolbox->renameFile($fileName.$fileExtension, $fileName)) { $statusCode = 500; @@ -570,48 +516,43 @@ class YellowUpdate { $zip = new ZipArchive(); if ($zip->open($path)===true) { if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::updateExtensionArchive file:$path<br/>\n"; - $extension = $version = $language = ""; - $modified = $lastModified = $lastPublished = 0; + $pathBase = ""; if (preg_match("#^(.*\/).*?$#", $zip->getNameIndex(0), $matches)) $pathBase = $matches[1]; + $languages = $this->getExtensionArchiveLanguages($zip, $pathBase); $fileData = $zip->getFromName($pathBase.$this->yellow->system->get("updateExtensionFile")); - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); - if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) { - $fileName = $matches[1]; - if (is_file($fileName)) { - $lastPublished = filemtime($fileName); - break; - } - } - } - $rootPages = array(); - foreach ($this->yellow->content->scanLocation("") as $page) { - if ($page->isAvailable() && $page->isVisible()) array_push($rootPages, $page); - } - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - if (preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches)) { - if (lcfirst($matches[1])=="extension") $extension = lcfirst($matches[2]); - if (lcfirst($matches[1])=="version") $version = lcfirst($matches[2]); - if (lcfirst($matches[1])=="published") $modified = strtotime($matches[2]); - if (lcfirst($matches[1])=="language") $language = $matches[2]; - if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) { - $fileName = $matches[1]; - list($dummy, $entry, $flags) = $this->yellow->toolbox->getTextList($matches[2], ",", 3); - foreach ($rootPages as $page) { - list($fileNameSource, $fileNameDestination) = $this->getExtensionsFileNames($fileName, $entry, $flags, $language, $pathBase, $page); - $fileData = $zip->getFromName($fileNameSource); - $lastModified = $this->yellow->toolbox->getFileModified($fileNameDestination); - $statusCode = $this->updateExtensionFile($fileNameDestination, $fileData, - $modified, $lastModified, $lastPublished, $flags, $extension); + $settings = $this->yellow->toolbox->getTextSettings($fileData, ""); + list($extension, $version, $newModified, $oldModified) = $this->getExtensionInformation($settings); + if (!empty($extension) && !empty($version)) { + $statusCode = $this->updateExtensionSettings($extension, $settings, $action); + if ($statusCode==200) { + foreach ($this->getExtensionFileNames($settings) as $fileName) { + list($entry, $flags) = $this->yellow->toolbox->getTextList($settings[$fileName], ",", 2); + if (strposu($entry, ".")===false) { + list($dummy, $entry, $flags) = $this->yellow->toolbox->getTextList($settings[$fileName], ",", 3); + } + if (!$this->yellow->lookup->isContentFile($fileName)) { + $fileData = $zip->getFromName($pathBase.$entry); + $lastModified = $this->yellow->toolbox->getFileModified($fileName); + $statusCode = $this->updateExtensionFile($fileName, $fileData, + $newModified, $oldModified, $lastModified, $flags, $extension); + } else { + foreach ($this->getExtensionContentRootPages() as $page) { + list($fileNameSource, $fileNameDestination) = $this->getExtensionContentFileNames( + $fileName, $pathBase, $entry, $flags, $languages, $page); + $fileData = $zip->getFromName($fileNameSource); + $lastModified = $this->yellow->toolbox->getFileModified($fileNameDestination); + $statusCode = $this->updateExtensionFile($fileNameDestination, $fileData, + $newModified, $oldModified, $lastModified, $flags, $extension); + } } if ($statusCode!=200) break; } + $statusCode = max($statusCode, $this->processUpdateNotification($extension, $action)); } + $this->yellow->log($statusCode==200 ? "info" : "error", ucfirst($action)." extension '".ucfirst($extension)." $version'"); + ++$this->updates; } $zip->close(); - $statusCode = max($statusCode, $this->processUpdateNotification($extension, $action)); - $this->yellow->log($statusCode==200 ? "info" : "error", ucfirst($action)." extension '".ucfirst($extension)." $version'"); - ++$this->updates; } else { $statusCode = 500; $this->yellow->page->error(500, "Can't open file '$path'!"); @@ -620,19 +561,19 @@ class YellowUpdate { } // Update extension from file - public function updateExtensionFile($fileName, $fileData, $modified, $lastModified, $lastPublished, $flags, $extension) { + public function updateExtensionFile($fileName, $fileData, $newModified, $oldModified, $lastModified, $flags, $extension) { $statusCode = 200; $fileName = $this->yellow->toolbox->normaliseTokens($fileName); - if ($this->yellow->lookup->isValidFile($fileName) && !empty($extension)) { + if ($this->yellow->lookup->isValidFile($fileName)) { $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->yellow->extension->isExisting($extension)) $create = $update = $delete = false; - if (preg_match("/careful/i", $flags) && is_file($fileName) && $lastModified!=$lastPublished) $update = false; + if (preg_match("/careful/i", $flags) && is_file($fileName) && $lastModified!=$oldModified) $update = false; if ($create) { if (!$this->yellow->toolbox->createFile($fileName, $fileData, true) || - !$this->yellow->toolbox->modifyFile($fileName, $modified)) { + !$this->yellow->toolbox->modifyFile($fileName, $newModified)) { $statusCode = 500; $this->yellow->page->error($statusCode, "Can't write file '$fileName'!"); } @@ -640,7 +581,7 @@ class YellowUpdate { if ($update) { if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("coreTrashDirectory")) || !$this->yellow->toolbox->createFile($fileName, $fileData) || - !$this->yellow->toolbox->modifyFile($fileName, $modified)) { + !$this->yellow->toolbox->modifyFile($fileName, $newModified)) { $statusCode = 500; $this->yellow->page->error($statusCode, "Can't write file '$fileName'!"); } @@ -660,111 +601,254 @@ class YellowUpdate { return $statusCode; } - // Return extension file names - public function getExtensionsFileNames($fileName, $entry, $flags, $language, $pathBase, $page) { - if (preg_match("/multi-language/i", $flags)) { - $languagesAvailable = preg_split("/\s*,\s*/", $language); - $languagesWanted = array($page->get("language"), "en"); - foreach ($languagesWanted as $language) { - if (in_array($language, $languagesAvailable)) { - $languageFound = $language; - break; - } - } - $pathLanguage = $languageFound ? "$languageFound/" : ""; - $fileNameSource = $pathBase.$pathLanguage.basename($entry); - } else { - $fileNameSource = $pathBase.basename($entry); - } - if ($this->yellow->system->get("coreMultiLanguageMode") && $this->yellow->lookup->isContentFile($fileName)) { - $contentDirectoryLength = strlenu($this->yellow->system->get("coreContentDirectory")); - $fileNameDestination = $page->fileName.substru($fileName, $contentDirectoryLength); - } else { - $fileNameDestination = $fileName; + // Remove extensions + public function removeExtensions($settings) { + $statusCode = 200; + if (function_exists("opcache_reset")) opcache_reset(); + foreach ($settings as $extension=>$block) { + $statusCode = max($statusCode, $this->removeExtensionArchive($extension, $block, "uninstall")); } - return array($fileNameSource, $fileNameDestination); + return $statusCode; } - // Remove extensions - public function removeExtensions($data) { + // Remove extension archive + public function removeExtensionArchive($extension, $settings, $action) { $statusCode = 200; - if (function_exists("opcache_reset")) opcache_reset(); - foreach ($data as $key=>$value) { - foreach (preg_split("/\s*,\s*/", $value) as $fileName) { - $statusCode = max($statusCode, $this->removeExtensionsFile($fileName, $key)); + $fileNames = $this->getExtensionFileNames($settings, true); + if (count($fileNames)) { + $statusCode = max($statusCode, $this->processUpdateNotification($extension, $action)); + foreach ($fileNames as $fileName) { + $statusCode = max($statusCode, $this->removeExtensionFile($fileName)); } - $statusCode = max($statusCode, $this->processUpdateNotification($key, "uninstall")); - $version = $this->yellow->extension->isExisting($key) ? $this->yellow->extension->data[$key]["version"] : ""; - $this->yellow->log($statusCode==200 ? "info" : "error", "Uninstall extension '".ucfirst($key)." $version'"); + if ($statusCode==200) $statusCode = $this->updateExtensionSettings($extension, $settings, $action); + $version = $settings->get("version"); + $this->yellow->log($statusCode==200 ? "info" : "error", ucfirst($action)." extension '".ucfirst($extension)." $version'"); ++$this->updates; + } else { + $statusCode = 500; + $this->yellow->page->error(500, "Can't find information about extension '$extension'!"); } return $statusCode; } - - // Remove extensions file - public function removeExtensionsFile($fileName, $extension) { + + // Remove extension file + public function removeExtensionFile($fileName) { $statusCode = 200; $fileName = $this->yellow->toolbox->normaliseTokens($fileName); - if ($this->yellow->lookup->isValidFile($fileName) && !empty($extension)) { + if ($this->yellow->lookup->isValidFile($fileName) && is_file($fileName)) { if (!$this->yellow->toolbox->deleteFile($fileName, $this->yellow->system->get("coreTrashDirectory"))) { $statusCode = 500; $this->yellow->page->error($statusCode, "Can't delete file '$fileName'!"); } if (defined("DEBUG") && DEBUG>=2) { - echo "YellowUpdate::removeExtensionsFile file:$fileName action:delete<br/>\n"; + echo "YellowUpdate::removeExtensionFile file:$fileName action:delete<br/>\n"; } } return $statusCode; } - - // Return extensions version - public function getExtensionsVersion($latest = false, $rawFormat = false) { - $data = array(); - if ($latest) { - $url = $this->yellow->system->get("updateExtensionUrl")."/raw/master/".$this->yellow->system->get("updateVersionFile"); - list($statusCode, $fileData) = $this->getExtensionFile($url); - if ($statusCode==200) { - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); - if (!empty($matches[1]) && !empty($matches[2])) { - $extension = lcfirst($matches[1]); - list($version, $dummy1, $dummy2) = $this->yellow->toolbox->getTextList($matches[2], ",", 3); - $data[$extension] = $rawFormat ? $matches[2] : $version; + + // Return extensions from text, space separated + public function getExtensionsFromText($text) { + return array_unique(array_filter($this->yellow->toolbox->getTextArguments($text), "strlen")); + } + + // Return extension install information + public function getExtensionInstallInformation($extensions) { + $settings = array(); + list($statusCodeCurrent, $settingsCurrent) = $this->getExtensionSettings(false); + list($statusCodeLatest, $settingsLatest) = $this->getExtensionSettings(true); + $statusCode = max($statusCodeCurrent, $statusCodeLatest); + foreach ($extensions as $extension) { + $found = false; + foreach ($settingsLatest as $key=>$value) { + if (strtoloweru($key)==strtoloweru($extension)) { + if (!$settingsCurrent->isExisting($key)) $settings[$key] = $settingsLatest[$key]; + $found = true; + break; + } + } + if (!$found) { + $statusCode = 500; + $this->yellow->page->error($statusCode, "Can't find extension '$extension'!"); + } + } + return array($statusCode, $settings); + } + + // Return extension uninstall information + public function getExtensionUninstallInformation($extensions, $extensionsProtected) { + $settings = array(); + list($statusCode, $settingsCurrent) = $this->getExtensionSettings(false); + foreach ($extensions as $extension) { + $found = false; + foreach ($settingsCurrent as $key=>$value) { + if (strtoloweru($key)==strtoloweru($extension)) { + $settings[$key] = $settingsCurrent[$key]; + $found = true; + break; + } + } + if (!$found) { + $statusCode = 500; + $this->yellow->page->error($statusCode, "Can't find extension '$extension'!"); + } + } + $protected = preg_split("/\s*,\s*/", $extensionsProtected); + foreach ($settings as $key=>$value) { + if (in_array($key, $protected)) unset($settings[$key]); + } + return array($statusCode, $settings); + } + + // Return extension update information + public function getExtensionUpdateInformation($extensions) { + $settings = array(); + list($statusCodeCurrent, $settingsCurrent) = $this->getExtensionSettings(false); + list($statusCodeLatest, $settingsLatest) = $this->getExtensionSettings(true); + $statusCode = max($statusCodeCurrent, $statusCodeLatest); + if (empty($extensions)) { + foreach ($settingsCurrent as $key=>$value) { + if ($settingsLatest->isExisting($key)) { + $versionCurrent = $settingsCurrent[$key]->get("version"); + $versionLatest = $settingsLatest[$key]->get("version"); + if (strnatcasecmp($versionCurrent, $versionLatest)<0) { + $settings[$key] = $settingsLatest[$key]; } } } } else { - $statusCode = 200; + $force = false; + foreach ($extensions as $extension) { + $found = false; + if ($extension=="force") { $force = true; continue; } + foreach ($settingsCurrent as $key=>$value) { + if (strtoloweru($key)==strtoloweru($extension) && $settingsLatest->isExisting($key)) { + $settings[$key] = $settingsLatest[$key]; + $found = true; + break; + } + } + if (!$found) { + $statusCode = 500; + $this->yellow->page->error($statusCode, "Can't find extension '$extension'!"); + } + } + if (!$force) { + $statusCode = 500; + $this->yellow->page->error($statusCode, "Please use 'force' to update an extension!"); + } + } + if ($statusCode==200) { + foreach ($settings as $key=>$value) { + echo ucfirst($key)." ".$value->get("version")."\n"; + } + } + return array($statusCode, $settings); + } + + // Return extension settings + public function getExtensionSettings($latest) { + $statusCode = 200; + $settings = array(); + if (!$latest) { + $fileNameCurrent = $this->yellow->system->get("coreExtensionDirectory").$this->yellow->system->get("updateCurrentFile"); + if (!is_file($fileNameCurrent)) $statusCode = $this->createExtensionSettings(); + $fileData = $this->yellow->toolbox->readFile($fileNameCurrent); + $settings = $this->yellow->toolbox->getTextSettings($fileData, "extension"); foreach ($this->yellow->extension->data as $key=>$value) { - $data[$key] = $value["version"]; + if (!$settings->isExisting($key)) $settings[$key] = new YellowArray(); + $settings[$key]["extension"] = ucfirst($key); + $settings[$key]["version"] = $value["version"]; } + } else { + $fileNameLatest = $this->yellow->system->get("coreExtensionDirectory").$this->yellow->system->get("updateLatestFile"); + $expire = $this->yellow->toolbox->getFileModified($fileNameLatest) + 60*10; + if ($expire<=time()) { + $url = $this->yellow->system->get("updateExtensionUrl")."/raw/master/".$this->yellow->system->get("updateLatestFile"); + list($statusCode, $fileData) = $this->getExtensionFile($url); + if ($statusCode==200 && !$this->yellow->toolbox->createFile($fileNameLatest, $fileData)) { + $statusCode = 500; + $this->yellow->page->error($statusCode, "Can't write file '$fileNameLatest'!"); + } + } + $fileData = $this->yellow->toolbox->readFile($fileNameLatest); + $settings = $this->yellow->toolbox->getTextSettings($fileData, "extension"); } - uksort($data, "strnatcasecmp"); - return array($statusCode, $data); + $settings->uksort("strnatcasecmp"); + return array($statusCode, $settings); } - - // Return extensions relevant files - public function getExtensionsRelevant() { - $data = array(); - $url = $this->yellow->system->get("updateExtensionUrl")."/raw/master/".$this->yellow->system->get("updateWaffleFile"); - list($statusCode, $fileData) = $this->getExtensionFile($url); - if ($statusCode==200) { - foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) { - preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches); - if (!empty($matches[1]) && !empty($matches[2])) { - $fileName = $matches[1]; - list($extension, $dummy1, $dummy2) = $this->yellow->toolbox->getTextList(lcfirst($matches[2]), ",", 3); - if (!isset($data[$extension])) { - $data[$extension] = $fileName; - } else { - $data[$extension] .= ",".$fileName; - } + + // Return extension archive languages + public function getExtensionArchiveLanguages($zip, $pathBase) { + $languages = array(); + for ($index=0; $index<$zip->numFiles; ++$index) { + $entry = substru($zip->getNameIndex($index), strlenu($pathBase)); + if (preg_match("#^(.*)\/.*?$#", $entry, $matches)) { + array_push($languages, $matches[1]); + } + } + return array_unique($languages); + } + + // Return extension information + public function getExtensionInformation($settings) { + $extension = lcfirst($settings->get("extension")); + $version = $settings->get("version"); + $newModified = strtotime($settings->get("published")); + $oldModified = 0; + foreach ($settings as $key=>$value) { + if (strposu($key, "/") && is_file($key)) { + $oldModified = filemtime($key); + break; + } + } + return array($extension, $version, $newModified, $oldModified); + } + + // Return extension file names + public function getExtensionFileNames($settings, $reverse = false) { + $fileNames = array(); + foreach ($settings as $key=>$value) { + if (strposu($key, "/")) array_push($fileNames, $key); + } + if ($reverse) $fileNames = array_reverse($fileNames); + return $fileNames; + } + + // Return extension root pages for content files + public function getExtensionContentRootPages() { + $rootPages = array(); + foreach ($this->yellow->content->scanLocation("") as $page) { + if ($page->isAvailable() && $page->isVisible()) array_push($rootPages, $page); + } + return $rootPages; + } + + // Return extension files names for content files + public function getExtensionContentFileNames($fileName, $pathBase, $entry, $flags, $languages, $page) { + if (preg_match("/multi-language/i", $flags)) { + $languageFound = ""; + $languagesWanted = array($page->get("language"), "en"); + foreach ($languagesWanted as $language) { + if (in_array($language, $languages)) { + $languageFound = $language; + break; } } + $pathLanguage = $languageFound ? "$languageFound/" : ""; + $fileNameSource = $pathBase.$pathLanguage.$entry; + } else { + $fileNameSource = $pathBase.$entry; + } + if ($this->yellow->system->get("coreMultiLanguageMode")) { + $contentDirectoryLength = strlenu($this->yellow->system->get("coreContentDirectory")); + $fileNameDestination = $page->fileName.substru($fileName, $contentDirectoryLength); + } else { + $fileNameDestination = $fileName; } - return array($statusCode, $data); + return array($fileNameSource, $fileNameDestination); } - + // Return extension file public function getExtensionFile($url) { $urlRequest = $url; diff --git a/system/settings/system.ini b/system/settings/system.ini @@ -26,6 +26,7 @@ CoreSettingDirectory: system/settings/ CoreLayoutDirectory: system/layouts/ CoreThemeDirectory: system/themes/ CoreTrashDirectory: system/trash/ +CoreCacheDirectory: cache/ CoreContentDirectory: content/ CoreContentRootDirectory: default/ CoreContentHomeDirectory: home/ @@ -37,16 +38,12 @@ CoreDownloadExtension: .download CoreUserFile: user.ini CoreLanguageFile: language.ini CoreLogFile: yellow.log -UpdateSourceCodeDirectory: /Users/yourname/Documents/GitHub/ UpdateExtensionUrl: https://github.com/datenstrom/yellow-extensions UpdateExtensionFile: extension.ini UpdateCurrentFile: update-current.ini UpdateLatestFile: update-latest.ini -UpdateVersionFile: version.ini -UpdateWaffleFile: waffle.ini UpdateNotification: none CommandStaticBuildDirectory: public/ -CommandStaticCacheDirectory: cache/ CommandStaticDefaultFile: index.html CommandStaticErrorFile: 404.html EditLocation: /edit/