mikuli.cz

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

commit 06c837bdae11872c46de224bcccf2b3ef25ba3ea
parent c19b21d1489431f63d1264f91071696c14555450
Author: markseu <mark2011@mayberg.se>
Date:   Mon,  2 Feb 2015 13:25:16 +0100

Core update (better change handling)

Diffstat:
MREADME.md | 2+-
Msystem/core/core.php | 146+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Msystem/snippets/navigation.php | 4+++-
3 files changed, 94 insertions(+), 58 deletions(-)

diff --git a/README.md b/README.md @@ -1,4 +1,4 @@ -Yellow 0.4.23 +Yellow 0.4.24 ============= [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/markseu/yellowcms) diff --git a/system/core/core.php b/system/core/core.php @@ -1,11 +1,11 @@ <?php -// Copyright (c) 2013-2014 Datenstrom, http://datenstrom.se +// Copyright (c) 2013-2015 Datenstrom, http://datenstrom.se // This file may be used and distributed under the terms of the public license. // Yellow main class class Yellow { - const Version = "0.4.23"; + const Version = "0.4.24"; var $page; //current page var $pages; //pages from file system var $config; //configuration @@ -169,9 +169,6 @@ class Yellow $this->page = new YellowPage($this); $this->page->setRequestInformation($serverScheme, $serverName, $base, $location, $fileName); $this->page->parseData($this->toolbox->getFileData($fileName), $cacheable, $statusCode, $pageError); - $this->page->setHeader("Content-Type", "text/html; charset=UTF-8"); - $this->page->setHeader("Last-Modified", $this->page->getModified(true)); - if(!$this->page->isCacheable()) $this->page->setHeader("Cache-Control", "no-cache, must-revalidate"); $this->text->setLanguage($this->page->get("language")); $this->page->parseContent(); return $fileName; @@ -180,43 +177,22 @@ class Yellow // Send page response function sendPage() { - $this->template($this->page->get("template")); - $fileNameTheme = $this->config->get("themeDir").$this->page->get("theme").".css"; - if(!is_file($fileNameTheme)) - { - $this->page->error(500, "Theme '".$this->page->get("theme")."' does not exist!"); - } - if(!$this->text->isLanguage($this->page->get("language"))) - { - $this->page->error(500, "Language '".$this->page->get("language")."' does not exist!"); - } - if(!is_object($this->page->parser)) + $this->page->parseResponse(); + $statusCode = $this->page->statusCode; + $lastModifiedFormatted = $this->page->getHeader("Last-Modified"); + if($statusCode==200 && $this->page->isCacheable() && $this->toolbox->isFileNotModified($lastModifiedFormatted)) { - $this->page->error(500, "Parser '".$this->page->get("parser")."' does not exist!"); + $statusCode = 304; + $this->page->clean($statusCode); } - $statusCode = $this->page->statusCode; if($statusCode==200 && $this->getRequestHandler()=="core" && $this->page->isExisting("redirect")) { $statusCode = 301; $location = $this->toolbox->normaliseLocation($this->page->get("redirect"), $this->page->base, $this->page->location); $locationHeader = $this->toolbox->getLocationHeader($this->page->serverScheme, $this->page->serverName, "", $location); $this->page->clean($statusCode, $locationHeader); - $this->page->setHeader("Last-Modified", $this->page->getModified(true)); $this->page->setHeader("Cache-Control", "no-cache, must-revalidate"); } - if($statusCode==200 && $this->page->isCacheable() && - $this->toolbox->isFileNotModified($this->page->getHeader("Last-Modified"))) - { - $statusCode = 304; - if($this->page->isHeader("Cache-Control")) $responseHeader = "Cache-Control: ".$this->page->getHeader("Cache-Control"); - $this->page->clean($statusCode, $responseHeader); - } - list($contentType) = explode(';', $this->page->getHeader("Content-Type")); - if($statusCode==200 && !$this->toolbox->isValidContentType($contentType, $this->page->getLocation())) - { - $statusCode = 500; - $this->page->error($statusCode, "Type '$contentType' does not match file name!"); - } if($this->page->isExisting("pageClean")) ob_clean(); if(PHP_SAPI != "cli") { @@ -229,6 +205,7 @@ class Yellow { foreach($this->page->headerData as $key=>$value) echo "Yellow::sendPage $key: $value<br/>\n"; $fileNameTemplate = $this->config->get("templateDir").$this->page->get("template").".php"; + $fileNameTheme = $this->config->get("themeDir").$this->page->get("theme").".css"; $parserName = $this->page->get("parser"); echo "Yellow::sendPage template:$fileNameTemplate theme:$fileNameTheme parser:$parserName<br/>\n"; } @@ -238,17 +215,18 @@ class Yellow // Send file response function sendFile($statusCode, $fileName, $cacheable) { - $lastModified = $this->toolbox->getHttpDateFormatted(filemtime($fileName)); - if($statusCode==200 && $cacheable && $this->toolbox->isFileNotModified($lastModified)) + $lastModifiedFormatted = $this->toolbox->getHttpDateFormatted(filemtime($fileName)); + if($statusCode==200 && $cacheable && $this->toolbox->isFileNotModified($lastModifiedFormatted)) { $statusCode = 304; + @header($this->toolbox->getHttpStatusFormatted($statusCode)); } else { + @header($this->toolbox->getHttpStatusFormatted($statusCode)); + if(!$cacheable) @header("Cache-Control: no-cache, must-revalidate"); + @header("Content-Type: ".$this->toolbox->getMimeContentType($fileName)); + @header("Last-Modified: ".$lastModifiedFormatted); echo $this->toolbox->getFileData($fileName); } - @header($this->toolbox->getHttpStatusFormatted($statusCode)); - @header("Content-Type: ".$this->toolbox->getMimeContentType($fileName)); - @header("Last-Modified: ".$lastModified); - if(!$cacheable) @header("Cache-Control: no-cache, must-revalidate"); return $statusCode; } @@ -261,18 +239,16 @@ class Yellow if(!$cacheable) @header("Cache-Control: no-cache, must-revalidate"); if(!empty($responseHeader)) @header($responseHeader); } else { - if(!empty($responseHeader)) - { - $this->page->header($responseHeader); - $this->page->header("Last-Modified: ".$this->toolbox->getHttpDateFormatted(time())); - if($statusCode>=301 && $statusCode<=303) $this->sendStaticRedirect(); - } + if(!empty($responseHeader)) $this->page->header($responseHeader); + if($statusCode>=301 && $statusCode<=303) $this->sendStaticRedirect(); } } // Send static redirect response function sendStaticRedirect() { + $lastModifiedFormatted = $this->toolbox->getHttpDateFormatted(time()); + if(!$this->page->isHeader("Last-Modified")) $this->page->setHeader("Last-Modified", $lastModifiedFormatted); echo "<!DOCTYPE html><html>\n<head>\n"; echo "<meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n"; echo "<meta http-equiv=\"refresh\" content=\"0;url=".htmlspecialchars($this->page->getHeader("Location"))."\" />\n"; @@ -389,6 +365,7 @@ class Yellow $fileNameTemplate = $this->config->get("templateDir")."$name.php"; if(is_file($fileNameTemplate)) { + $this->page->setLastModified(filemtime($fileNameTemplate)); global $yellow; require($fileNameTemplate); } else { @@ -399,10 +376,11 @@ class Yellow // Execute snippet function snippet($name, $args = NULL) { - $this->pages->snippetArgs = func_get_args(); $fileNameSnippet = $this->config->get("snippetDir")."$name.php"; if(is_file($fileNameSnippet)) { + $this->page->setLastModified(filemtime($fileNameSnippet)); + $this->pages->snippetArgs = func_get_args(); global $yellow; require($fileNameSnippet); } else { @@ -426,6 +404,7 @@ class YellowPage var $base; //base location var $location; //page location var $fileName; //content file name + var $lastModified; //last modification date var $rawData; //raw data of page var $metaDataOffsetBytes; //meta data offset var $metaData; //meta data @@ -458,6 +437,7 @@ class YellowPage // Parse page data function parseData($rawData, $cacheable, $statusCode = 0, $pageError = "") { + $this->lastModified = 0; $this->rawData = $rawData; $this->parserData = ""; $this->parser = NULL; @@ -517,8 +497,8 @@ class YellowPage $this->set("title", $parsed[2]); } - $shortHeader = $this->location == $this->yellow->pages->getHomeLocation($this->location); - $titleHeader = $shortHeader ? $this->get("sitename") : $this->get("title")." - ".$this->get("sitename"); + $titleHeader = ($this->location == $this->yellow->pages->getHomeLocation($this->location)) ? + $this->get("sitename") : $this->get("title")." - ".$this->get("sitename"); if($this->get("titleContent") == "-") $this->set("titleContent", ""); if(!$this->isExisting("titleContent")) $this->set("titleContent", $this->get("title")); if(!$this->isExisting("titleHeader")) $this->set("titleHeader", $titleHeader); @@ -586,6 +566,32 @@ class YellowPage return $output; } + // Parse page response + function parseResponse() + { + $this->yellow->template($this->get("template")); + if(!$this->isCacheable()) $this->setHeader("Cache-Control", "no-cache, must-revalidate"); + if(!$this->isHeader("Content-Type")) $this->setHeader("Content-Type", "text/html; charset=utf-8"); + if(!$this->isHeader("Content-Modified")) $this->setHeader("Content-Modified", $this->getModified(true)); + if(!$this->isHeader("Last-Modified")) $this->setHeader("Last-Modified", $this->getLastModified(true)); + if(!is_file($this->yellow->config->get("themeDir").$this->get("theme").".css")) + { + $this->error(500, "Theme '".$this->get("theme")."' does not exist!"); + } + if(!$this->yellow->text->isLanguage($this->get("language"))) + { + $this->error(500, "Language '".$this->get("language")."' does not exist!"); + } + if(!is_object($this->parser)) + { + $this->error(500, "Parser '".$this->get("parser")."' does not exist!"); + } + if(!$this->yellow->toolbox->isValidContentType($this->getHeader("Content-Type"), $this->getLocation())) + { + $this->error(500, "Type '".$this->getHeader("Content-Type")."' does not match file name!"); + } + } + // Set page response header function setHeader($key, $value) { @@ -691,13 +697,27 @@ class YellowPage return $this->yellow->toolbox->getUrl($this->serverScheme, $this->serverName, $this->base, $this->location); } - // Return page modification date, Unix time or HTTP format + // Return page content modification date, Unix time or HTTP format function getModified($httpFormat = false) { $modified = strtotime($this->get("modified")); return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($modified) : $modified; } + // Set last modification date, Unix time + function setLastModified($modified) + { + $this->lastModified = max($this->lastModified, $modified); + } + + // Return last modification date, Unix time or HTTP format + function getLastModified($httpFormat = false) + { + $modified = max($this->lastModified, $this->getModified(), $this->yellow->config->getModified(), + $this->yellow->text->getModified(), $this->yellow->plugins->getModified()); + return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($modified) : $modified; + } + // Return page status code, number or HTTP format function getStatusCode($httpFormat = false) { @@ -726,6 +746,7 @@ class YellowPage if(!$this->isExisting("pageClean") && $statusCode>0) { $this->statusCode = $statusCode; + $this->lastModified = 0; $this->headerData = array(); if(!empty($responseHeader)) $this->header($responseHeader); $this->set("pageClean", (string)$statusCode); @@ -942,7 +963,7 @@ class YellowPageCollection extends ArrayObject return $this->filterValue; } - // Return last modification date for page collection, Unix time or HTTP format + // Return page collection modification date, Unix time or HTTP format function getModified($httpFormat = false) { $modified = 0; @@ -1402,10 +1423,12 @@ class YellowText class YellowPlugins { var $plugins; //registered plugins + var $modified; //plugin modification date function __construct() { $this->plugins = array(); + $this->modified = 0; } // Load plugins @@ -1415,7 +1438,11 @@ class YellowPlugins $path = $yellow->config->get("coreDir"); foreach($yellow->toolbox->getDirectoryEntries($path, "/^core-.*\.php$/", true, false) as $entry) require_once($entry); $path = $yellow->config->get("pluginDir"); - foreach($yellow->toolbox->getDirectoryEntries($path, "/^.*\.php$/", true, false) as $entry) require_once($entry); + foreach($yellow->toolbox->getDirectoryEntries($path, "/^.*\.php$/", true, false) as $entry) + { + $this->modified = max($this->modified, filemtime($entry)); + require_once($entry); + } foreach($this->plugins as $key=>$value) { $this->plugins[$key]["obj"] = new $value["class"]; @@ -1441,6 +1468,12 @@ class YellowPlugins return $this->plugins[$name]["obj"]; } + // Return plugins modification date, Unix time or HTTP format + function getModified($httpFormat = false) + { + return $httpFormat ? $this->yellow->toolbox->getHttpDateFormatted($this->modified) : $this->modified; + } + // Check if plugin exists function isExisting($name) { @@ -1613,9 +1646,9 @@ class YellowToolbox } // Check if file is unmodified since last HTTP request - function isFileNotModified($lastModified) + function isFileNotModified($lastModifiedFormatted) { - return isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"]==$lastModified; + return isset($_SERVER["HTTP_IF_MODIFIED_SINCE"]) && $_SERVER["HTTP_IF_MODIFIED_SINCE"]==$lastModifiedFormatted; } // Check if clean URL is requested @@ -1629,7 +1662,8 @@ class YellowToolbox { $ok = false; $extension = ($pos = strrposu($location, '.')) ? substru($location, $pos) : ""; - if($contentType == "text/html") + $tokens = explode(';', $contentType); + if($tokens[0] == "text/html") { if($this->isFileLocation($location)) { @@ -1640,7 +1674,7 @@ class YellowToolbox } else { if($this->isFileLocation($location)) { - if(!empty($extension) && preg_match("/^.*$extension$/", $contentType)) $ok = true; + if(!empty($extension) && preg_match("/^.*$extension$/", $tokens[0])) $ok = true; } } return $ok; @@ -2043,7 +2077,7 @@ class YellowToolbox "png" => "image/png", "txt" => "text/plain", "woff" => "application/font-woff"); - $contentType = "text/html; charset=UTF-8"; + $contentType = "text/html; charset=utf-8"; $extension = ($pos = strrposu($fileName, '.')) ? substru($fileName, $pos+1) : ""; if(array_key_exists(strtoloweru($extension), $mimeTypes)) $contentType = $mimeTypes[$extension]; return $contentType; @@ -2177,7 +2211,7 @@ class YellowToolbox return @rename($fileNameSource, $fileNameDest); } - // Set file modification time, Unix time + // Set file modification date, Unix time function modifyFile($fileName, $modified) { return @touch($fileName, $modified); diff --git a/system/snippets/navigation.php b/system/snippets/navigation.php @@ -1,6 +1,8 @@ +<?php $pages = $yellow->pages->top() ?> +<?php $yellow->page->setLastModified($pages->getModified()) ?> <div class="navigation"> <ul> -<?php foreach($yellow->pages->top() as $page): ?> +<?php foreach($pages as $page): ?> <li><a<?php echo $page->isActive() ? " class=\"active\"" : "" ?> href="<?php echo $page->getLocation() ?>"><?php echo $page->getHtml("titleNavigation") ?></a></li> <?php endforeach ?> </ul>