Przeglądaj źródła

Updated setup files

markseu 6 lat temu
rodzic
commit
fbd7b799e1

+ 3 - 3
system/config/config.ini

@@ -1,7 +1,7 @@
 # Datenstrom Yellow configuration
 # Datenstrom Yellow configuration
 
 
-Sitename: Yellow
-Author: Yellow
+Sitename: Datenstrom Yellow
+Author: Datenstrom
 Email: webmaster
 Email: webmaster
 Language: en
 Language: en
 Timezone: UTC
 Timezone: UTC
@@ -52,7 +52,7 @@ Tagline:
 Parser: markdown
 Parser: markdown
 ParserSafeMode: 0
 ParserSafeMode: 0
 MultiLanguageMode: 0
 MultiLanguageMode: 0
-InstallationMode: 1
+SetupMode: 1
 BundleAndMinify: 1
 BundleAndMinify: 1
 EditLocation: /edit/
 EditLocation: /edit/
 EditUploadNewLocation: /media/@group/@filename
 EditUploadNewLocation: /media/@group/@filename

+ 4 - 5
system/plugins/core.php

@@ -77,7 +77,7 @@ class YellowCore {
         $this->config->setDefault("parser", "markdown");
         $this->config->setDefault("parser", "markdown");
         $this->config->setDefault("parserSafeMode", "0");
         $this->config->setDefault("parserSafeMode", "0");
         $this->config->setDefault("multiLanguageMode", "0");
         $this->config->setDefault("multiLanguageMode", "0");
-        $this->config->setDefault("installationMode", "0");
+        $this->config->setDefault("setupMode", "0");
     }
     }
     
     
     public function __destruct() {
     public function __destruct() {
@@ -568,10 +568,6 @@ class YellowPage {
         if ($this->yellow->lookup->isNestedLocation($this->location, $this->fileName, true)) {
         if ($this->yellow->lookup->isNestedLocation($this->location, $this->fileName, true)) {
             $this->error(500, "Folder '".dirname($this->fileName)."' may not contain subfolders!");
             $this->error(500, "Folder '".dirname($this->fileName)."' may not contain subfolders!");
         }
         }
-        if ($this->yellow->toolbox->isRequestSelf()) {
-            $serverVersion = $this->yellow->toolbox->getServerVersion(true);
-            $this->error(500, "Rewrite module not working on $serverVersion web server!");
-        }
         if ($this->yellow->getRequestHandler()=="core" && $this->isExisting("redirect") && $this->statusCode==200) {
         if ($this->yellow->getRequestHandler()=="core" && $this->isExisting("redirect") && $this->statusCode==200) {
             $location = $this->yellow->lookup->normaliseLocation($this->get("redirect"), $this->location);
             $location = $this->yellow->lookup->normaliseLocation($this->get("redirect"), $this->location);
             $location = $this->yellow->lookup->normaliseUrl($this->scheme, $this->address, "", $location);
             $location = $this->yellow->lookup->normaliseUrl($this->scheme, $this->address, "", $location);
@@ -580,6 +576,9 @@ class YellowPage {
         if ($this->yellow->getRequestHandler()=="core" && !$this->isAvailable() && $this->statusCode==200) {
         if ($this->yellow->getRequestHandler()=="core" && !$this->isAvailable() && $this->statusCode==200) {
             $this->error(404);
             $this->error(404);
         }
         }
+        if ($this->yellow->toolbox->isRequestSelf()) {
+            $this->error(404);
+        }
         if ($this->isExisting("pageClean")) $this->outputData = null;
         if ($this->isExisting("pageClean")) $this->outputData = null;
         foreach ($this->yellow->plugins->plugins as $key=>$value) {
         foreach ($this->yellow->plugins->plugins as $key=>$value) {
             if (method_exists($value["obj"], "onParsePageOutput")) {
             if (method_exists($value["obj"], "onParsePageOutput")) {

BIN
system/plugins/installation-language.zip


+ 0 - 0
system/plugins/installation-blog.zip → system/plugins/setup-blog.zip


BIN
system/plugins/setup-language.zip


+ 0 - 0
system/plugins/installation-wiki.zip → system/plugins/setup-wiki.zip


+ 299 - 0
system/plugins/setup.php

@@ -0,0 +1,299 @@
+<?php
+// Setup plugin, https://github.com/datenstrom/yellow
+// Copyright (c) 2013-2018 Datenstrom, https://datenstrom.se
+// This file may be used and distributed under the terms of the public license.
+
+class YellowSetup {
+    const VERSION = "0.7.1";
+    public $yellow;                 //access to API
+    
+    // Handle initialisation
+    public function onLoad($yellow) {
+        $this->yellow = $yellow;
+    }
+    
+    // Handle request
+    public function onRequest($scheme, $address, $base, $location, $fileName) {
+        $statusCode = 0;
+        if ($this->yellow->lookup->isContentFile($fileName) && $this->yellow->config->get("setupMode")) {
+            $server = $this->yellow->toolbox->getServerVersion(true);
+            $this->checkServerRewrite($scheme, $address, $base, $location, $fileName) || die("Datenstrom Yellow requires $server rewrite module!");
+            $this->checkServerAccess() || die("Datenstrom Yellow requires $server with read/write access!");
+            $statusCode = $this->processRequestSetup($scheme, $address, $base, $location, $fileName);
+        }
+        return $statusCode;
+    }
+    
+    // Handle command
+    public function onCommand($args) {
+        $statusCode = 0;
+        if ($this->yellow->config->get("setupMode")) {
+            $statusCode = $this->processCommandSetup();
+        }
+        return $statusCode;
+    }
+    
+    // Process command to set up website
+    public function processCommandSetup() {
+        $statusCode = $this->updateLanguage();
+        if ($statusCode==200) $statusCode = $this->updateFeature("none");
+        if ($statusCode==200) $statusCode = $this->updateConfig(array("setupMode" => "0"));
+        if ($statusCode==200) {
+            $statusCode = 0;
+        } else {
+            echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
+            echo "Your website has ".($statusCode!=200 ? "not " : "")."been updated: Please run command again\n";
+        }
+        return $statusCode;
+    }
+    
+    // Process request to set up website
+    public function processRequestSetup($scheme, $address, $base, $location, $fileName) {
+        $statusCode = 0;
+        $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"]);
+        $this->yellow->pages->pages["root/"] = array();
+        $this->yellow->page = new YellowPage($this->yellow);
+        $statusCode = $this->updateLanguage();
+        $this->yellow->page->setRequestInformation($scheme, $address, $base, $location, $fileName);
+        $this->yellow->page->parseData($this->getRawDataSetup(), false, $statusCode, $this->yellow->page->get("pageError"));
+        $this->yellow->page->parserSafeMode = false;
+        if ($status=="setup") $status = $this->updateUser($email, $password, $name, $language)==200 ? "ok" : "error";
+        if ($status=="ok") $status = $this->updateFeature($feature)==200 ? "ok" : "error";
+        if ($status=="ok") $status = $this->updateContent($language, "Home", "/")==200 ? "ok" : "error";
+        if ($status=="ok") $status = $this->updateContent($language, "About", "/about/")==200 ? "ok" : "error";
+        if ($status=="ok") $status = $this->updateConfig($this->getConfigData()) ? "done" : "error";
+        if ($status=="done") {
+            $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
+            $statusCode = $this->yellow->sendStatus(303, $location);
+        } else {
+            $statusCode = $this->yellow->sendPage();
+        }
+        return $statusCode;
+    }
+    
+    // Update language
+    public function updateLanguage() {
+        $statusCode = 200;
+        $path = $this->yellow->config->get("pluginDir")."setup-language.zip";
+        if (is_file($path) && $this->yellow->plugins->isExisting("update")) {
+            $zip = new ZipArchive();
+            if ($zip->open($path)===true) {
+                if (defined("DEBUG") && DEBUG>=2) echo "YellowSetup::updateLanguage file:$path<br/>\n";
+                $languages = $this->getLanguageData("en, de, fr");
+                if (preg_match("#^(.*\/).*?$#", $zip->getNameIndex(0), $matches)) $pathBase = $matches[1];
+                $fileData = $zip->getFromName($pathBase.$this->yellow->config->get("updateInformationFile"));
+                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], "/")) {
+                        list($dummy, $entry) = explode("/", $matches[1], 2);
+                        if (preg_match("/^language-(.*)\.txt$/", $entry, $tokens) && !is_null($languages[$tokens[1]])) {
+                            $languages[$tokens[1]] = $entry;
+                        }
+                    }
+                }
+                $languages = array_slice(array_filter($languages, "strlen"), 0, 3);
+                foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
+                    preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
+                    if (lcfirst($matches[1])=="plugin" || lcfirst($matches[1])=="theme") $software = $matches[2];
+                    if (lcfirst($matches[1])=="published") $modified = strtotime($matches[2]);
+                    if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) {
+                        list($dummy, $entry) = explode("/", $matches[1], 2);
+                        list($fileName) = explode(",", $matches[2], 2);
+                        $fileData = $zip->getFromName($pathBase.$entry);
+                        if (preg_match("/^language.php$/", $entry)) {
+                            $statusCode = $this->yellow->plugins->get("update")->updateSoftwareFile($fileName, $fileData,
+                                $modified, 0, 0, "create,update", false, $software);
+                        }
+                        if (preg_match("/^language-(.*)\.txt$/", $entry, $tokens) && !is_null($languages[$tokens[1]])) {
+                            $statusCode = $this->yellow->plugins->get("update")->updateSoftwareFile($fileName, $fileData,
+                                $modified, 0, 0, "create,update", false, $software);
+                        }
+                    }
+                }
+                $zip->close();
+                if ($statusCode==200) {
+                    $this->yellow->text->load($this->yellow->config->get("pluginDir").$this->yellow->config->get("languageFile"), "");
+                }
+                if ($statusCode==200 && !$this->yellow->toolbox->deleteFile($path)) {
+                    $statusCode = 500;
+                    $this->yellow->page->error($statusCode, "Can't delete file '$path'!");
+                }
+            } else {
+                $statusCode = 500;
+                $this->yellow->page->error(500, "Can't open file '$path'!");
+            }
+        }
+        return $statusCode;
+    }
+    
+    // Update user
+    public function updateUser($email, $password, $name, $language) {
+        $statusCode = 200;
+        if (!empty($email) && !empty($password) && $this->yellow->plugins->isExisting("edit")) {
+            $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
+            $status = $this->yellow->plugins->get("edit")->users->save($fileNameUser, $email, $password, $name, $language) ? "ok" : "error";
+            if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!");
+        }
+        return $statusCode;
+    }
+    
+    // Update feature
+    public function updateFeature($feature) {
+        $statusCode = 200;
+        $path = $this->yellow->config->get("pluginDir");
+        if (!empty($feature) && $this->yellow->plugins->isExisting("update")) {
+            foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
+                if (preg_match("/^setup-(.*?)\./", basename($entry), $matches)) {
+                    if (strtoloweru($matches[1])==strtoloweru($feature)) {
+                        $statusCode = $this->yellow->plugins->get("update")->updateSoftwareArchive($entry);
+                        break;
+                    }
+                }
+            }
+        }
+        if ($statusCode==200) {
+            foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
+                if (preg_match("/^setup-(.*?)\./", basename($entry), $matches)) {
+                    if (!$this->yellow->toolbox->deleteFile($entry)) {
+                        $statusCode = 500;
+                        $this->yellow->page->error($statusCode, "Can't delete file '$entry'!");
+                    }
+                }
+            }
+        }
+        return $statusCode;
+    }
+    
+    // Update content, convert requested location
+    public function updateContent($language, $name, $location) {
+        $statusCode = 200;
+        if ($language!="en") {
+            $titleOld = "Title: ".$this->yellow->text->getText("setup{$name}Title", "en");
+            $titleNew = "Title: ".$this->yellow->text->getText("setup{$name}Title", $language);
+            $rawDataOld = strreplaceu("\\n", "\n", $this->yellow->text->getText("setup{$name}Page", "en"));
+            $rawDataNew = strreplaceu("\\n", "\n", $this->yellow->text->getText("setup{$name}Page", $language));
+            $fileName = $this->yellow->lookup->findFileFromLocation($location);
+            $fileData = strreplaceu("\r\n", "\n", $this->yellow->toolbox->readFile($fileName));
+            $fileData = strreplaceu($titleOld, $titleNew, $fileData);
+            $fileData = strreplaceu($rawDataOld, $rawDataNew, $fileData);
+            if (!$this->yellow->toolbox->createFile($fileName, $fileData)) {
+                $statusCode = 500;
+                $this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
+            }
+        }
+        return $statusCode;
+    }
+    
+    // Update config
+    public function updateConfig($config) {
+        $statusCode = 200;
+        $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
+        if (!$this->yellow->config->save($fileNameConfig, $config)) {
+            $statusCode = 500;
+            $this->yellow->page->error($statusCode, "Can't write file '$fileNameConfig'!");
+        }
+        return $statusCode;
+    }
+    
+    // Check web server rewrite
+    public function checkServerRewrite($scheme, $address, $base, $location, $fileName) {
+        $curlHandle = curl_init();
+        $location = $this->yellow->config->get("assetLocation").$this->yellow->config->get("theme").".css";
+        $url = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
+        curl_setopt($curlHandle, CURLOPT_URL, $url);
+        curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; YellowCore/".YellowCore::VERSION).")";
+        curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 30);
+        $rawData = curl_exec($curlHandle);
+        $statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
+        curl_close($curlHandle);
+        return !empty($rawData) && $statusCode==200;
+    }
+    
+    // Check web server read/write access
+    public function checkServerAccess() {
+        $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
+        return $this->yellow->config->save($fileNameConfig, array());
+    }
+
+    // Return language data, detect browser languages
+    public function getLanguageData($languagesDefault) {
+        $data = array();
+        if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
+            foreach (preg_split("/\s*,\s*/", $_SERVER["HTTP_ACCEPT_LANGUAGE"]) as $string) {
+                list($language) = explode(";", $string);
+                if (!empty($language)) $data[$language] = "";
+            }
+        }
+        foreach (preg_split("/\s*,\s*/", $languagesDefault) as $language) {
+            if (!empty($language)) $data[$language] = "";
+        }
+        return $data;
+    }
+    
+    // Return configuration data, detect server URL
+    public function getConfigData() {
+        $data = array();
+        foreach ($_REQUEST as $key=>$value) {
+            if (!$this->yellow->config->isExisting($key)) continue;
+            $data[$key] = trim($value);
+        }
+        if ($this->yellow->config->get("sitename")=="Datenstrom Yellow") $data["sitename"] = $name;
+        $data["timezone"] = $this->yellow->toolbox->getTimezone();
+        $data["staticUrl"] = $this->yellow->toolbox->getServerUrl();
+        $data["setupMode"] = "0";
+        return $data;
+    }
+
+    // Return raw data for setup page
+    public function getRawDataSetup() {
+        $language = $this->yellow->toolbox->detectBrowserLanguage($this->yellow->text->getLanguages(), $this->yellow->config->get("language"));
+        $fileName = strreplaceu("(.*)", "setup", $this->yellow->config->get("configDir").$this->yellow->config->get("newFile"));
+        $rawData = $this->yellow->toolbox->readFile($fileName);
+        if (empty($rawData)) {
+            $this->yellow->text->setLanguage($language);
+            $rawData = "---\nTitle:".$this->yellow->text->get("setupTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
+            $rawData .= "<form class=\"setup-form\" action=\"".$this->yellow->page->getLocation(true)."\" method=\"post\">\n";
+            $rawData .= "<p><label for=\"name\">".$this->yellow->text->get("editSignupName")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"name\" id=\"name\" value=\"\"></p>\n";
+            $rawData .= "<p><label for=\"email\">".$this->yellow->text->get("editSignupEmail")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"email\" id=\"email\" value=\"\"></p>\n";
+            $rawData .= "<p><label for=\"password\">".$this->yellow->text->get("editSignupPassword")."</label><br /><input class=\"form-control\" type=\"password\" maxlength=\"64\" name=\"password\" id=\"password\" value=\"\"></p>\n";
+            if (count($this->yellow->text->getLanguages())>1) {
+                $rawData .= "<p>";
+                foreach ($this->yellow->text->getLanguages() as $language) {
+                    $checked = $language==$this->yellow->text->language ? " checked=\"checked\"" : "";
+                    $rawData .= "<label for=\"$language\"><input type=\"radio\" name=\"language\" id=\"$language\" value=\"$language\"$checked> ".$this->yellow->text->getTextHtml("languageDescription", $language)."</label><br />";
+                }
+                $rawData .= "</p>\n";
+            }
+            if (count($this->getFeaturesSetup())>1) {
+                $rawData .= "<p>".$this->yellow->text->get("setupFeature")."<p>";
+                foreach ($this->getFeaturesSetup() as $feature) {
+                    $checked = $feature=="website" ? " checked=\"checked\"" : "";
+                    $rawData .= "<label for=\"$feature\"><input type=\"radio\" name=\"feature\" id=\"$feature\" value=\"$feature\"$checked> ".ucfirst($feature)."</label><br />";
+                }
+                $rawData .= "</p>\n";
+            }
+            $rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("editOkButton")."\" />\n";
+            $rawData .= "<input type=\"hidden\" name=\"status\" value=\"setup\" />\n";
+            $rawData .= "</form>\n";
+        }
+        return $rawData;
+    }
+    
+    // Return features for setup page
+    public function getFeaturesSetup() {
+        $features = array("website");
+        $path = $this->yellow->config->get("pluginDir");
+        foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false, false) as $entry) {
+            if (preg_match("/^setup-(.*?)\./", $entry, $matches) && $matches[1]!="language") array_push($features, $matches[1]);
+        }
+        return $features;
+    }
+}
+    
+$yellow->plugins->register("setup", "YellowSetup", YellowSetup::VERSION, 1);

+ 60 - 343
system/plugins/update.php

@@ -4,7 +4,7 @@
 // This file may be used and distributed under the terms of the public license.
 // This file may be used and distributed under the terms of the public license.
 
 
 class YellowUpdate {
 class YellowUpdate {
-    const VERSION = "0.7.20";
+    const VERSION = "0.7.21";
     public $yellow;                 //access to API
     public $yellow;                 //access to API
     public $updates;                //number of updates
     public $updates;                //number of updates
     
     
@@ -44,12 +44,17 @@ class YellowUpdate {
     
     
     // Handle request
     // Handle request
     public function onRequest($scheme, $address, $base, $location, $fileName) {
     public function onRequest($scheme, $address, $base, $location, $fileName) {
-        return $this->processRequest($scheme, $address, $base, $location, $fileName);
+        $statusCode = 0;
+        if ($this->yellow->lookup->isContentFile($fileName) && $this->isSoftwarePending()) {
+            $statusCode = $this->processRequestPending($scheme, $address, $base, $location, $fileName);
+        }
+        return $statusCode;
     }
     }
     
     
     // Handle command
     // Handle command
     public function onCommand($args) {
     public function onCommand($args) {
-        $statusCode = $this->processCommand();
+        $statusCode = 0;
+        if ($this->isSoftwarePending()) $statusCode = $this->processCommandPending();
         if ($statusCode==0) {
         if ($statusCode==0) {
             list($command) = $args;
             list($command) = $args;
             switch ($command) {
             switch ($command) {
@@ -135,6 +140,24 @@ class YellowUpdate {
         }
         }
         return $statusCode;
         return $statusCode;
     }
     }
+    
+    // Process command to update website with pending software
+    public function processCommandPending() {
+        $statusCode = $this->updateSoftware();
+        if ($statusCode!=200) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
+        echo "Your website has ".($statusCode!=200 ? "not " : "")."been updated: Please run command again\n";
+        return $statusCode;
+    }
+    
+    // Process request to update website with pending software
+    public function processRequestPending($scheme, $address, $base, $location, $fileName) {
+        $statusCode = $this->updateSoftware();
+        if ($statusCode==200) {
+            $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
+            $statusCode = $this->yellow->sendStatus(303, $location);
+        }
+        return $statusCode;
+    }
 
 
     // Return install information
     // Return install information
     public function getInstallInformation($features) {
     public function getInstallInformation($features) {
@@ -231,7 +254,7 @@ class YellowUpdate {
         return array($statusCode, $data);
         return array($statusCode, $data);
     }
     }
     
     
-    // Show software features
+    // Show software
     public function showSoftware() {
     public function showSoftware() {
         list($statusCode, $dataLatest) = $this->getSoftwareVersion(true, true);
         list($statusCode, $dataLatest) = $this->getSoftwareVersion(true, true);
         foreach ($dataLatest as $key=>$value) {
         foreach ($dataLatest as $key=>$value) {
@@ -437,114 +460,6 @@ class YellowUpdate {
         return $statusCode;
         return $statusCode;
     }
     }
     
     
-    // Update installation language, install best languages
-    public function updateInstallationLanguage() {
-        $statusCode = 200;
-        $path = $this->yellow->config->get("pluginDir")."installation-language.zip";
-        if (is_file($path)) {
-            $zip = new ZipArchive();
-            if ($zip->open($path)===true) {
-                if (defined("DEBUG") && DEBUG>=2) echo "YellowUpdate::updateInstallationLanguage file:$path<br/>\n";
-                $languages = $this->getInstallationLanguages("en, de, fr");
-                if (preg_match("#^(.*\/).*?$#", $zip->getNameIndex(0), $matches)) $pathBase = $matches[1];
-                $fileData = $zip->getFromName($pathBase.$this->yellow->config->get("updateInformationFile"));
-                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], "/")) {
-                        list($dummy, $entry) = explode("/", $matches[1], 2);
-                        if (preg_match("/^language-(.*)\.txt$/", $entry, $tokens) && !is_null($languages[$tokens[1]])) {
-                            $languages[$tokens[1]] = $entry;
-                        }
-                    }
-                }
-                $languages = array_slice(array_filter($languages, "strlen"), 0, 3);
-                foreach ($this->yellow->toolbox->getTextLines($fileData) as $line) {
-                    preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
-                    if (lcfirst($matches[1])=="plugin" || lcfirst($matches[1])=="theme") $software = $matches[2];
-                    if (lcfirst($matches[1])=="published") $modified = strtotime($matches[2]);
-                    if (!empty($matches[1]) && !empty($matches[2]) && strposu($matches[1], "/")) {
-                        list($dummy, $entry) = explode("/", $matches[1], 2);
-                        list($fileName) = explode(",", $matches[2], 2);
-                        $fileData = $zip->getFromName($pathBase.$entry);
-                        if (preg_match("/^language.php$/", $entry)) {
-                            $statusCode = $this->updateSoftwareFile($fileName, $fileData, $modified, 0, 0, "create,update", false, $software);
-                        }
-                        if (preg_match("/^language-(.*)\.txt$/", $entry, $tokens) && !is_null($languages[$tokens[1]])) {
-                            $statusCode = $this->updateSoftwareFile($fileName, $fileData, $modified, 0, 0, "create,update", false, $software);
-                        }
-                    }
-                }
-                $zip->close();
-                if ($statusCode==200) {
-                    $this->yellow->text->load($this->yellow->config->get("pluginDir").$this->yellow->config->get("languageFile"), "");
-                }
-                if ($statusCode==200 && !$this->yellow->toolbox->deleteFile($path)) {
-                    $statusCode = 500;
-                    $this->yellow->page->error($statusCode, "Can't delete file '$path'!");
-                }
-            } else {
-                $statusCode = 500;
-                $this->yellow->page->error(500, "Can't open file '$path'!");
-            }
-        }
-        return $statusCode;
-    }
-    
-    // Update installation feature, install requested feature
-    public function updateInstallationFeature($feature) {
-        $statusCode = 200;
-        $path = $this->yellow->config->get("pluginDir");
-        foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
-            if (preg_match("/^installation-(.*?)\./", basename($entry), $matches)) {
-                if (strtoloweru($matches[1])==strtoloweru($feature)) {
-                    $statusCode = max($statusCode, $this->updateSoftwareArchive($entry));
-                    break;
-                }
-            }
-        }
-        if ($statusCode==200) {
-            foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false) as $entry) {
-                if (preg_match("/^installation-(.*?)\./", basename($entry), $matches)) {
-                    if (!$this->yellow->toolbox->deleteFile($entry)) {
-                        $statusCode = 500;
-                        $this->yellow->page->error($statusCode, "Can't delete file '$entry'!");
-                    }
-                }
-            }
-        }
-        return $statusCode;
-    }
-    
-    // Update installation config, disable installation mode
-    public function updateInstallationConfig() {
-        $statusCode = 200;
-        $fileNameConfig = $this->yellow->config->get("configDir").$this->yellow->config->get("configFile");
-        if(!$this->yellow->config->save($fileNameConfig, array("installationMode" => "0"))) {
-            $statusCode = 500;
-            $this->yellow->page->error($statusCode, "Can't write file '$fileNameConfig'!");
-        }
-        return $statusCode;
-    }
-    
-    // Update installation page, convert into requested language
-    public function updateInstallationPage($fileName, $name, $language) {
-        $statusCode = 200;
-        if ($language!="en") {
-            $titleOld = "Title: ".$this->yellow->text->getText("editInstallation{$name}Title", "en");
-            $titleNew = "Title: ".$this->yellow->text->getText("editInstallation{$name}Title", $language);
-            $rawDataOld = strreplaceu("\\n", "\n", $this->yellow->text->getText("editInstallation{$name}Page", "en"));
-            $rawDataNew = strreplaceu("\\n", "\n", $this->yellow->text->getText("editInstallation{$name}Page", $language));
-            $fileData = strreplaceu("\r\n", "\n", $this->yellow->toolbox->readFile($fileName));
-            $fileData = strreplaceu($titleOld, $titleNew, $fileData);
-            $fileData = strreplaceu($rawDataOld, $rawDataNew, $fileData);
-            if (!$this->yellow->toolbox->createFile($fileName, $fileData)) {
-                $statusCode = 500;
-                $this->yellow->page->error($statusCode, "Can't write file '$fileName'!");
-            }
-        }
-        return $statusCode;
-    }
-    
     // Remove software
     // Remove software
     public function removeSoftware($data) {
     public function removeSoftware($data) {
         $statusCode = 200;
         $statusCode = 200;
@@ -574,205 +489,20 @@ class YellowUpdate {
         }
         }
         return $statusCode;
         return $statusCode;
     }
     }
-
-    // Process command
-    public function processCommand() {
-        $statusCode = 0;
-        if ($this->yellow->config->get("installationMode")) {
-            $statusCode = $this->processCommandInstallationMode();
-        } elseif ($this->isSoftwarePending()) {
-            $statusCode = $this->processCommandInstallationPending();
-        }
-        return $statusCode;
-    }
-    
-    // Process command to install website
-    public function processCommandInstallationMode() {
-        $statusCode = $this->updateInstallationLanguage();
-        if ($statusCode==200) $statusCode = $this->updateInstallationFeature("none");
-        if ($statusCode==200) $statusCode = $this->updateInstallationConfig();
-        if ($statusCode!=200) echo "ERROR updating files: ".$this->yellow->page->get("pageError")."\n";
-        echo "Yellow has ".($statusCode!=200 ? "not " : "")."been installed: Please run command again\n";
-        return $statusCode;
-    }
     
     
-    // Process command to install pending software
-    public function processCommandInstallationPending() {
-        $statusCode = $this->updateSoftware();
-        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;
-    }
-    
-    // Process request
-    public function processRequest($scheme, $address, $base, $location, $fileName) {
-        $statusCode = 0;
-        if ($this->yellow->lookup->isContentFile($fileName) && !$this->yellow->isCommandLine()) {
-            if ($this->yellow->config->get("installationMode")) {
-                $statusCode = $this->processRequestInstallationMode($scheme, $address, $base, $location, $fileName);
-            } elseif ($this->isSoftwarePending()) {
-                $statusCode = $this->processRequestInstallationPending($scheme, $address, $base, $location, $fileName);
+    // Return features from commandline arguments
+    public function getCommandFeatures($args) {
+        $command = array_shift($args);
+        $features = array_unique(array_filter($args, "strlen"));
+        foreach ($features as $key=>$value) {
+            if ($value=="force") {
+                $force = true;
+                unset($features[$key]);
             }
             }
         }
         }
-        return $statusCode;
+        return array($command, $features, $force);
     }
     }
 
 
-    // Process request to install website
-    public function processRequestInstallationMode($scheme, $address, $base, $location, $fileName) {
-        $statusCode = 0;
-        $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"]);
-        $this->yellow->pages->pages["root/"] = array();
-        $this->yellow->page = new YellowPage($this->yellow);
-        $statusCode = $this->updateInstallationLanguage();
-        $this->yellow->page->setRequestInformation($scheme, $address, $base, $location, $fileName);
-        $this->yellow->page->parseData($this->getRawDataInstallation(), false, $statusCode, $this->yellow->page->get("pageError"));
-        $this->yellow->page->parserSafeMode = false;
-        if ($status=="install") {
-            $serverVersion = $this->yellow->toolbox->getServerVersion(true);
-            $status = $this->checkServerRewrite($scheme, $address, $base, $location, $fileName) ? "ok" : "error";
-            if ($status=="error") $this->yellow->page->error(500, "Rewrite module not working on $serverVersion web server!");
-        }
-        if ($status=="ok") {
-            if (!empty($email) && !empty($password) && $this->yellow->plugins->isExisting("edit")) {
-                $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile");
-                $status = $this->yellow->plugins->get("edit")->users->save($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->updateInstallationFeature($feature)==200 ? "ok" : "error";
-                if ($status=="error") $this->yellow->page->error(500, "Can't install feature '$feature'!");
-            }
-        }
-        if ($status=="ok") {
-            $fileNameHome = $this->yellow->lookup->findFileFromLocation("/");
-            $status = $this->updateInstallationPage($fileNameHome, "Home", $language)==200 ? "ok" : "error";
-            if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameHome'!");
-        }
-        if ($status=="ok") {
-            $fileNameAbout = $this->yellow->lookup->findFileFromLocation("/about/");
-            $status = $this->updateInstallationPage($fileNameAbout, "About", $language)==200 ? "ok" : "error";
-            if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameAbout'!");
-        }
-        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->save($fileNameConfig, $this->getConfigData()) ? "done" : "error";
-            if ($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameConfig'!");
-        }
-        if ($status=="done") {
-            $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
-            $statusCode = $this->yellow->sendStatus(303, $location);
-        } else {
-            $statusCode = $this->yellow->sendPage();
-        }
-        return $statusCode;
-    }
-    
-    // Process request to install pending software
-    public function processRequestInstallationPending($scheme, $address, $base, $location, $fileName) {
-        $statusCode = $this->updateSoftware();
-        if ($statusCode==200) {
-            $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
-            $statusCode = $this->yellow->sendStatus(303, $location);
-        }
-        return $statusCode;
-    }
-    
-    // Check web server rewrite
-    public function checkServerRewrite($scheme, $address, $base, $location, $fileName) {
-        $curlHandle = curl_init();
-        $location = $this->yellow->config->get("assetLocation").$this->yellow->page->get("theme").".css";
-        $url = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location);
-        curl_setopt($curlHandle, CURLOPT_URL, $url);
-        curl_setopt($curlHandle, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; YellowCore/".YellowCore::VERSION).")";
-        curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, 1);
-        curl_setopt($curlHandle, CURLOPT_CONNECTTIMEOUT, 30);
-        $rawData = curl_exec($curlHandle);
-        $statusCode = curl_getinfo($curlHandle, CURLINFO_HTTP_CODE);
-        curl_close($curlHandle);
-        return !empty($rawData) && $statusCode==200;
-    }
-    
-    // Return raw data for installation page
-    public function getRawDataInstallation() {
-        $language = $this->yellow->toolbox->detectBrowserLanguage($this->yellow->text->getLanguages(), $this->yellow->config->get("language"));
-        $fileName = strreplaceu("(.*)", "installation", $this->yellow->config->get("configDir").$this->yellow->config->get("newFile"));
-        $rawData = $this->yellow->toolbox->readFile($fileName);
-        if (empty($rawData)) {
-            $this->yellow->text->setLanguage($language);
-            $rawData = "---\nTitle:".$this->yellow->text->get("editInstallationTitle")."\nLanguage:$language\nNavigation:navigation\n---\n";
-            $rawData .= "<form class=\"installation-form\" action=\"".$this->yellow->page->getLocation(true)."\" method=\"post\">\n";
-            $rawData .= "<p><label for=\"name\">".$this->yellow->text->get("editSignupName")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"name\" id=\"name\" value=\"\"></p>\n";
-            $rawData .= "<p><label for=\"email\">".$this->yellow->text->get("editSignupEmail")."</label><br /><input class=\"form-control\" type=\"text\" maxlength=\"64\" name=\"email\" id=\"email\" value=\"\"></p>\n";
-            $rawData .= "<p><label for=\"password\">".$this->yellow->text->get("editSignupPassword")."</label><br /><input class=\"form-control\" type=\"password\" maxlength=\"64\" name=\"password\" id=\"password\" value=\"\"></p>\n";
-            if (count($this->yellow->text->getLanguages())>1) {
-                $rawData .= "<p>";
-                foreach ($this->yellow->text->getLanguages() as $language) {
-                    $checked = $language==$this->yellow->text->language ? " checked=\"checked\"" : "";
-                    $rawData .= "<label for=\"$language\"><input type=\"radio\" name=\"language\" id=\"$language\" value=\"$language\"$checked> ".$this->yellow->text->getTextHtml("languageDescription", $language)."</label><br />";
-                }
-                $rawData .= "</p>\n";
-            }
-            if (count($this->getInstallationFeatures())>1) {
-                $rawData .= "<p>".$this->yellow->text->get("editInstallationFeature")."<p>";
-                foreach ($this->getInstallationFeatures() as $feature) {
-                    $checked = $feature=="website" ? " checked=\"checked\"" : "";
-                    $rawData .= "<label for=\"$feature\"><input type=\"radio\" name=\"feature\" id=\"$feature\" value=\"$feature\"$checked> ".ucfirst($feature)."</label><br />";
-                }
-                $rawData .= "</p>\n";
-            }
-            $rawData .= "<input class=\"btn\" type=\"submit\" value=\"".$this->yellow->text->get("editOkButton")."\" />\n";
-            $rawData .= "<input type=\"hidden\" name=\"status\" value=\"install\" />\n";
-            $rawData .= "</form>\n";
-        }
-        return $rawData;
-    }
-    
-    // Return configuration data
-    public function getConfigData() {
-        $data = array();
-        foreach ($_REQUEST as $key=>$value) {
-            if (!$this->yellow->config->isExisting($key)) continue;
-            $data[$key] = trim($value);
-        }
-        $data["timezone"] = $this->yellow->toolbox->getTimezone();
-        $data["staticUrl"] = $this->yellow->toolbox->getServerUrl();
-        $data["installationMode"] = "0";
-        return $data;
-    }
-    
-    // Return installation languages
-    public function getInstallationLanguages($languagesDefault) {
-        $data = array();
-        if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
-            foreach (preg_split("/\s*,\s*/", $_SERVER["HTTP_ACCEPT_LANGUAGE"]) as $string) {
-                list($language) = explode(";", $string);
-                if (!empty($language)) $data[$language] = "";
-            }
-        }
-        foreach (preg_split("/\s*,\s*/", $languagesDefault) as $language) {
-            if (!empty($language)) $data[$language] = "";
-        }
-        return $data;
-    }
-    
-    // Return installation features
-    public function getInstallationFeatures() {
-        $data = array("website");
-        $path = $this->yellow->config->get("pluginDir");
-        foreach ($this->yellow->toolbox->getDirectoryEntries($path, "/^.*\.zip$/", true, false, false) as $entry) {
-            if (preg_match("/^installation-(.*?)\./", $entry, $matches) && $matches[1]!="language") array_push($data, $matches[1]);
-        }
-        return $data;
-    }
-    
     // Return software version
     // Return software version
     public function getSoftwareVersion($latest = false, $rawFormat = false) {
     public function getSoftwareVersion($latest = false, $rawFormat = false) {
         $data = array();
         $data = array();
@@ -797,29 +527,7 @@ class YellowUpdate {
         }
         }
         return array($statusCode, $data);
         return array($statusCode, $data);
     }
     }
-    
-    // Return software files
-    public function getSoftwareFiles() {
-        $data = array();
-        $urlPlugins = $this->yellow->config->get("updatePluginsUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
-        $urlThemes = $this->yellow->config->get("updateThemesUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
-        list($statusCodePlugins, $fileDataPlugins) = $this->getSoftwareFile($urlPlugins);
-        list($statusCodeThemes, $fileDataThemes) = $this->getSoftwareFile($urlThemes);
-        $statusCode = max($statusCodePlugins, $statusCodeThemes);
-        if ($statusCode==200) {
-            foreach ($this->yellow->toolbox->getTextLines($fileDataPlugins."\n".$fileDataThemes) as $line) {
-                preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
-                if (!empty($matches[1]) && !empty($matches[2])) {
-                    list($software) = explode("/", $matches[1]);
-                    list($fileName) = explode(",", $matches[2], 2);
-                    if (!is_null($data[$software])) $data[$software] .= ",";
-                    $data[$software] .= $fileName;
-                }
-            }
-        }
-        return array($statusCode, $data);
-    }
-
+ 
     // Return software modification
     // Return software modification
     public function getSoftwareModified() {
     public function getSoftwareModified() {
         $data = array();
         $data = array();
@@ -852,6 +560,28 @@ class YellowUpdate {
         return array($statusCode, $data);
         return array($statusCode, $data);
     }
     }
     
     
+    // Return software files
+    public function getSoftwareFiles() {
+        $data = array();
+        $urlPlugins = $this->yellow->config->get("updatePluginsUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
+        $urlThemes = $this->yellow->config->get("updateThemesUrl")."/raw/master/".$this->yellow->config->get("updateResourceFile");
+        list($statusCodePlugins, $fileDataPlugins) = $this->getSoftwareFile($urlPlugins);
+        list($statusCodeThemes, $fileDataThemes) = $this->getSoftwareFile($urlThemes);
+        $statusCode = max($statusCodePlugins, $statusCodeThemes);
+        if ($statusCode==200) {
+            foreach ($this->yellow->toolbox->getTextLines($fileDataPlugins."\n".$fileDataThemes) as $line) {
+                preg_match("/^\s*(.*?)\s*:\s*(.*?)\s*$/", $line, $matches);
+                if (!empty($matches[1]) && !empty($matches[2])) {
+                    list($software) = explode("/", $matches[1]);
+                    list($fileName) = explode(",", $matches[2], 2);
+                    if (!is_null($data[$software])) $data[$software] .= ",";
+                    $data[$software] .= $fileName;
+                }
+            }
+        }
+        return array($statusCode, $data);
+    }
+
     // Return software file
     // Return software file
     public function getSoftwareFile($url) {
     public function getSoftwareFile($url) {
         $urlRequest = $url;
         $urlRequest = $url;
@@ -878,19 +608,6 @@ class YellowUpdate {
         return array($statusCode, $fileData);
         return array($statusCode, $fileData);
     }
     }
     
     
-    // Return command features
-    public function getCommandFeatures($args) {
-        $command = array_shift($args);
-        $features = array_unique(array_filter($args, "strlen"));
-        foreach ($features as $key=>$value) {
-            if ($value=="force") {
-                $force = true;
-                unset($features[$key]);
-            }
-        }
-        return array($command, $features, $force);
-    }
-    
     // Check if software pending
     // Check if software pending
     public function isSoftwarePending() {
     public function isSoftwarePending() {
         $path = $this->yellow->config->get("pluginDir");
         $path = $this->yellow->config->get("pluginDir");
@@ -907,4 +624,4 @@ class YellowUpdate {
     }
     }
 }
 }
     
     
-$yellow->plugins->register("update", "YellowUpdate", YellowUpdate::VERSION, 1);
+$yellow->plugins->register("update", "YellowUpdate", YellowUpdate::VERSION, 2);