From df8ec7a9cf69f22fa3cbfa31bce2acad4628e28a Mon Sep 17 00:00:00 2001 From: Mofasa Date: Sat, 15 Sep 2018 23:43:41 +0800 Subject: [PATCH 01/15] load assets from document root dir 1) if `uri` is start with `/`, it'll try to load asset from document root ```php // Register specific services for the module public function registerServices(Di $di) { $di->assets->setOptions([ 'source' => __DIR__ . '/Skin/Default/', 'target' => 'min/', 'minify' => 3 ]); } // load from module dir/Skin/Default/css/style.css $this->assets->addCss(['css/style.css']); // load from document_root/Skin/Default/css/style.css $this->assets->addCss(['/Skin/Default/css/style.css']); ``` 2) always store the min files in the document_root/target dir --- ice/assets.zep | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index d2bf8965..c26c2bbf 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -258,9 +258,19 @@ class Assets dir = dirname(uri) . DIRECTORY_SEPARATOR, file = basename(uri, "." . type), uriMin = target . dir . file . ".min." . type, - destination = source . uriMin, + destination = _SERVER["DOCUMENT_ROOT"] . uriMin, exist = false; + // there is no source dir, try to load from document root + if uri[0] != "/" && empty source { + let uri = "/" . uri; + } + + // uri is start from absolute path, try to load from document root + if uri[0] == "/" || empty source { + let source = _SERVER["DOCUMENT_ROOT"]; + } + switch minify { case self::NOT_EXIST: let minify = !file_exists(destination); @@ -313,4 +323,4 @@ class Assets return uriMin; } } -} \ No newline at end of file +} From 11b0370648932cd1ac256aefc29293101a8e4083 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Sat, 15 Sep 2018 23:52:53 +0800 Subject: [PATCH 02/15] starts_with --- ice/assets.zep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index c26c2bbf..8628f1b9 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -262,12 +262,12 @@ class Assets exist = false; // there is no source dir, try to load from document root - if uri[0] != "/" && empty source { + if !starts_with("/", uri) && empty source { let uri = "/" . uri; } // uri is start from absolute path, try to load from document root - if uri[0] == "/" || empty source { + if starts_with("/", uri) || empty source { let source = _SERVER["DOCUMENT_ROOT"]; } From 4703bc7c51d903f4e921b732838b0e7f1fac81c2 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Sun, 16 Sep 2018 13:00:38 +0800 Subject: [PATCH 03/15] target is start from absolute path place min file to document root --- ice/assets.zep | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index 8628f1b9..9661e9ae 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -258,19 +258,25 @@ class Assets dir = dirname(uri) . DIRECTORY_SEPARATOR, file = basename(uri, "." . type), uriMin = target . dir . file . ".min." . type, - destination = _SERVER["DOCUMENT_ROOT"] . uriMin, exist = false; // there is no source dir, try to load from document root - if !starts_with("/", uri) && empty source { + if uri[0] != '/' && empty source { let uri = "/" . uri; } // uri is start from absolute path, try to load from document root - if starts_with("/", uri) || empty source { + if uri[0] == '/' || empty source { let source = _SERVER["DOCUMENT_ROOT"]; } + // target is start from absolute path, place min file to document root + if target[0] == '/' { + let destination = _SERVER["DOCUMENT_ROOT"] . uriMin; + } else { + let destination = source . uriMin; + } + switch minify { case self::NOT_EXIST: let minify = !file_exists(destination); From e6e89054509934eda001eba05a81d1ac4d3e06fb Mon Sep 17 00:00:00 2001 From: Mofasa Date: Sun, 16 Sep 2018 13:15:00 +0800 Subject: [PATCH 04/15] fixed missing / for source --- ice/assets.zep | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ice/assets.zep b/ice/assets.zep index 9661e9ae..1733f81d 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -274,6 +274,9 @@ class Assets if target[0] == '/' { let destination = _SERVER["DOCUMENT_ROOT"] . uriMin; } else { + if source[-1] != '/' { + let source = source . "/"; + } let destination = source . uriMin; } From 37473fbb2788d63d80e4b95cb585f16050cc3a96 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 14:11:25 +0800 Subject: [PATCH 05/15] Auto version the uri get/set cache the prepared resources --- ice/assets.zep | 216 +++++++++++++++++++++++++------------------------ 1 file changed, 110 insertions(+), 106 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index 1733f81d..51e28977 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -1,8 +1,27 @@ namespace Ice; +use Ice\Exception; + /** * Assets helper is designed to management css/js resources. + * Tips for performance improvement if needed, export the assets files cache + * and save to disk or memcache and load it before init the assets. + * + *

+ *     // cache should be set before addCss or addJs. getMemCache is pseudo code!
+ *     if ($cache = getMemCache('assets')) {
+ *         $di->assets->setCache($cache);
+ *     }
+ *     $assets = $di->assets->addCss(['/css/style.css'])->addJs(['/js/script.js']);
+ *     // cache should get after addCss or addJs. setMemCache is pseudo code!
+ *     if ($cache = $assets->getCache())
+ *         setMemCache($cache);
+ *     }
+ * 
+ * + * Head ups! cache content will not be updated to the lastest version automatically. + * A cache clear mechanism is required. * * @package Ice/Assets * @category Helper @@ -16,11 +35,7 @@ class Assets protected di; protected collections = [] { set, get }; protected options = [] { set }; - - const NEVER = 0; - const NOT_EXIST = 1; - const IF_CHANGE = 2; - const ALWAYS = 3; + protected cache = [] { get, set }; /** * Assets constructor. Fetch Di and set it as a property. @@ -39,32 +54,24 @@ class Assets */ public function getOption(var key, var defaultValue = null) { - var value; - - if fetch value, this->options[key] { - return value; - } - - return defaultValue; + return isset this->options[key] ? this->options[key] : defaultValue; } /** * Add resource to assets, autodetect type. * * @param mixed parameters Parameters of link/script/style - * @param string version Version appending to the uri * @param string Collection Collection name * @param mixed minify Local minify option * @return object this */ - public function add(var parameters, string version = null, string collection = null, var minify = null) + public function add(var parameters, string collection = null, var minify = null) { var content, type, link; if typeof parameters == "string" { let link = parameters, - parameters = [], - parameters[] = link; + parameters = [link]; } if !fetch content, parameters["content"] { @@ -77,12 +84,12 @@ class Assets if !collection { let collection = "css"; } - this->addCss(parameters, version, collection, minify); + this->addCss(parameters, collection, minify); } elseif ends_with(content, ".js") || type == "text/javascript" { if !collection { let collection = "js"; } - this->addJs(parameters, version, collection, minify); + this->addJs(parameters, collection, minify); } return this; @@ -92,42 +99,47 @@ class Assets * Add CSS resource to assets. * * @param array parameters Parameters of link/style - * @param string version Version appending to the uri * @param string Collection Collection name * @param mixed minify Local minify option * @return object this */ - public function addCss(array! parameters, string version = null, string collection = "css", var minify = null) + public function addCss(array! parameters, string collection = "css", var minify = null) { - - var content, local, tag; + var content, tag, local = true; let tag = this->di->get("tag"); if !fetch content, parameters["content"] { - fetch content, parameters[0]; - } - - if !fetch local, parameters["local"] { - let local = true; + if fetch content, parameters[0] { + // do not support the host of url is the same as _SERVER["HTTP_HOST"] ATM + // the url contains any host will not minify the resource + let local = empty parse_url(content, PHP_URL_HOST); + } else { + throw new Exception("There is no css content or uri in the parameters"); + } } // If local minify is not set if minify === null { // Get global minify option, default is NEVER - let minify = this->getOption("minify", self::NEVER); + let minify = this->getOption("minify", false); } // Do not minify external or minified resources if !local || ends_with(content, ".min.css") { - let minify = self::NEVER; + let minify = false; } // Check if resource is inline or in file if isset parameters["content"] { this->addToCollection(collection, tag->style(["content": minify ? this->minify(content, "css") : content])); } else { - let parameters["href"] = this->prepare(content, "css", minify) . (version ? "?v=" . version : ""); + if isset this->cache[content] { + let parameters["href"] = this->cache[content]; + } else { + let parameters["href"] = this->prepare(content, minify), + this->cache[content] = parameters["href"]; + } this->addToCollection(collection, tag->link(parameters)); } @@ -138,41 +150,47 @@ class Assets * Add JS resource to assets. * * @param array parameters Parameters of script - * @param string version Version appending to the uri * @param string Collection Collection name * @param mixed minify Local minify option * @return object this */ - public function addJs(array! parameters, string version = null, string collection = "js", var minify = null) + public function addJs(array! parameters, string collection = "js", var minify = null) { - var content, local, tag; + var content, tag, local = true; let tag = this->di->get("tag"); if !fetch content, parameters["content"] { - fetch content, parameters[0]; - } - - if !fetch local, parameters["local"] { - let local = true; + if fetch content, parameters[0] { + // do not support the host of url is the same as _SERVER["HTTP_HOST"] ATM + // the url contains any host will not minify the resource + let local = empty parse_url(content, PHP_URL_HOST); + } else { + throw new Exception("There is no js content or uri in the parameters"); + } } // If local minify is not set if minify === null { // Get global minify option, default is NEVER - let minify = this->getOption("minify", self::NEVER); + let minify = this->getOption("minify", false); } // Do not minify external or minified resources if !local || ends_with(content, ".min.js") { - let minify = self::NEVER; + let minify = false; } // Check if resource is inline or in file if isset parameters["content"] { this->addToCollection(collection, tag->script(["content": minify ? this->minify(content, "js") : content])); } else { - let parameters["src"] = this->prepare(content, "js", minify) . (version ? "?v=" . version : ""); + if isset this->cache[content] { + let parameters["src"] = this->cache[content]; + } else { + let parameters["src"] = this->prepare(content, minify), + this->cache[content] = parameters["src"]; + } this->addToCollection(collection, tag->script(parameters)); } @@ -222,11 +240,7 @@ class Assets */ public function get(string key) { - var collection; - - fetch collection, this->collections[key]; - - return collection ? collection : []; + return isset this->collections[key] ? this->collections[key] : []; } /** @@ -245,91 +259,81 @@ class Assets * Prepare resource. * * @param string uri The uri/url source path - * @param string type Type of content * @param int minify Option of minify * @return string New path to the source */ - protected function prepare(string! uri, string type, var minify) + protected function prepare(string! uri, var minify) { - var source, target, dir, file, uriMin, destination, exist, old, minified; + var source, target, file, uriMin, destination, md5Old, md5New, old, minified; let source = this->getOption("source"), target = this->getOption("target"), - dir = dirname(uri) . DIRECTORY_SEPARATOR, - file = basename(uri, "." . type), - uriMin = target . dir . file . ".min." . type, - exist = false; - - // there is no source dir, try to load from document root - if uri[0] != '/' && empty source { - let uri = "/" . uri; - } + file = pathinfo(uri, PATHINFO_FILENAME | PATHINFO_EXTENSION), + type = file["extension"], + file = file["filename"]; // uri is start from absolute path, try to load from document root if uri[0] == '/' || empty source { let source = _SERVER["DOCUMENT_ROOT"]; } - // target is start from absolute path, place min file to document root - if target[0] == '/' { - let destination = _SERVER["DOCUMENT_ROOT"] . uriMin; - } else { - if source[-1] != '/' { - let source = source . "/"; - } - let destination = source . uriMin; + if (source[-1] != '/') { + let source .= "/"; } - switch minify { - case self::NOT_EXIST: - let minify = !file_exists(destination); - break; - case self::IF_CHANGE: - if !file_exists(destination) { - let minify = true; - } else { - let minify = md5_file(destination); - } - break; - case self::ALWAYS: - let minify = true; - break; - default: // self::NEVER: - let minify = false; - - if this->getOption("forceMinified") { - let exist = file_exists(destination); - } - break; - } + let uri = ltrim(uri, "/"), + source .= uri; - if !minify { - return exist ? uriMin : uri; - } else { - let minified = this->minify(file_get_contents(source . uri), type); + if !file_exists(source) { + throw new Exception(["The request assets do not exist: %s", source]); + } - // Check if file was changed - if typeof minify == "string" { - if minify != md5(minified) { - let minify = true; - } + let uriMin = "/" . trim(target, "/") . "/" . dirname(uri) . "/"; + + // cache min files place to document root always + let destination = _SERVER["DOCUMENT_ROOT"] . uriMin, + md5file = glob(destination . file . ".????????????????????????????????." . type), + md5New = null; + + if !empty md5file { + let md5file = md5file[0], + md5Old = substr(md5file, strlen(md5file) - strlen(type) - 33, 32), + md5New = md5_file(source); + + if md5Old != md5New { + // new version found + let md5file = null; + // delete the old version + @unlink(md5file); + } else { + let uriMin .= file . "." . md5New . "." . type; + } + } + if empty md5file { + if !md5New { + let md5New = md5_file(source); } - if minify === true { + if !is_dir(destination) { + let old = umask(0); - if !is_dir(dirname(destination)) { - let old = umask(0); + mkdir(destination, 0777, true); + umask(old); + } - mkdir(dirname(destination), 0777, true); - umask(old); - } + let uriMin .= file . "." . md5New . "." . type, + destination = _SERVER["DOCUMENT_ROOT"] . uriMin; + if minify { + minified = this->minify(file_get_contents(source), type); if file_put_contents(destination, minified) === false { - throw new Exception("Directory can't be written"); + throw new Exception(["Directory can't be written: %s", destination]); + } + } elseif copy(source, destination) === false { + throw new Exception(["Directory can't be written: %s", destination]); } } - - return uriMin; } + return uriMin; } } From a0c8ff051c91e5f9960d4860e33936e6e75fd358 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 14:23:57 +0800 Subject: [PATCH 06/15] suspend error is evil --- ice/assets.zep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ice/assets.zep b/ice/assets.zep index 51e28977..708ccc72 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -304,7 +304,7 @@ class Assets // new version found let md5file = null; // delete the old version - @unlink(md5file); + unlink(md5file); } else { let uriMin .= file . "." . md5New . "." . type; } From b584ebd53462139c01037fce1b90f472fbb32d48 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 14:33:44 +0800 Subject: [PATCH 07/15] one more let --- ice/assets.zep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ice/assets.zep b/ice/assets.zep index 708ccc72..b83ab788 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -325,7 +325,7 @@ class Assets destination = _SERVER["DOCUMENT_ROOT"] . uriMin; if minify { - minified = this->minify(file_get_contents(source), type); + let minified = this->minify(file_get_contents(source), type); if file_put_contents(destination, minified) === false { throw new Exception(["Directory can't be written: %s", destination]); } From e8e63007b81ff0eb0fa03222f96a6e3d08302afb Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 14:40:50 +0800 Subject: [PATCH 08/15] Syntax error --- ice/assets.zep | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index b83ab788..520349c3 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -330,8 +330,7 @@ class Assets throw new Exception(["Directory can't be written: %s", destination]); } } elseif copy(source, destination) === false { - throw new Exception(["Directory can't be written: %s", destination]); - } + throw new Exception(["Directory can't be written: %s", destination]); } } return uriMin; From 317d02616c44b517a1bfb96a31b001dbea3cc4d3 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 14:46:28 +0800 Subject: [PATCH 09/15] undefnined variable 'type' --- ice/assets.zep | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ice/assets.zep b/ice/assets.zep index 520349c3..b94a2b87 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -264,7 +264,7 @@ class Assets */ protected function prepare(string! uri, var minify) { - var source, target, file, uriMin, destination, md5Old, md5New, old, minified; + var source, target, file, type, uriMin, destination, md5Old, md5New, old, minified; let source = this->getOption("source"), target = this->getOption("target"), From f118876b5dc0d674ebf96fe10c64b9bd707c5069 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 14:50:59 +0800 Subject: [PATCH 10/15] md5file --- ice/assets.zep | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ice/assets.zep b/ice/assets.zep index b94a2b87..7ff86ede 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -264,7 +264,8 @@ class Assets */ protected function prepare(string! uri, var minify) { - var source, target, file, type, uriMin, destination, md5Old, md5New, old, minified; + var source, target, file, type, uriMin, destination, + md5file, md5Old, md5New, old, minified; let source = this->getOption("source"), target = this->getOption("target"), From 69320ca7674043d0c6ea9c2e1ba3db7dbcc63534 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 16:46:25 +0800 Subject: [PATCH 11/15] DIRECTORY_SEPARATOR --- ice/assets.zep | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ice/assets.zep b/ice/assets.zep index 7ff86ede..6be96f30 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -268,7 +268,7 @@ class Assets md5file, md5Old, md5New, old, minified; let source = this->getOption("source"), - target = this->getOption("target"), + target = str_replace(DIRECTORY_SEPARATOR, "/", this->getOption("target")), file = pathinfo(uri, PATHINFO_FILENAME | PATHINFO_EXTENSION), type = file["extension"], file = file["filename"]; @@ -276,6 +276,8 @@ class Assets // uri is start from absolute path, try to load from document root if uri[0] == '/' || empty source { let source = _SERVER["DOCUMENT_ROOT"]; + } else { + let source = str_replace(DIRECTORY_SEPARATOR, "/", source); } if (source[-1] != '/') { From 018e8164a909a96db6f795dff77b0773d6c90059 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 16:51:21 +0800 Subject: [PATCH 12/15] make target dir equal to 'min' --- ice/assets.zep | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index 6be96f30..cc535aa6 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -268,7 +268,7 @@ class Assets md5file, md5Old, md5New, old, minified; let source = this->getOption("source"), - target = str_replace(DIRECTORY_SEPARATOR, "/", this->getOption("target")), + target = this->getOption("target"), file = pathinfo(uri, PATHINFO_FILENAME | PATHINFO_EXTENSION), type = file["extension"], file = file["filename"]; @@ -291,7 +291,13 @@ class Assets throw new Exception(["The request assets do not exist: %s", source]); } - let uriMin = "/" . trim(target, "/") . "/" . dirname(uri) . "/"; + if empty target { + let target = "min"; + } else { + let target = trim(str_replace(DIRECTORY_SEPARATOR, "/", target), "/"); + } + + let uriMin = "/" . target . "/" . dirname(uri) . "/"; // cache min files place to document root always let destination = _SERVER["DOCUMENT_ROOT"] . uriMin, From 6142fdf929f47f7e98691e6018cd3fe5da78534c Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 16:57:19 +0800 Subject: [PATCH 13/15] replace \ to / --- ice/assets.zep | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index cc535aa6..108f1afd 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -277,7 +277,7 @@ class Assets if uri[0] == '/' || empty source { let source = _SERVER["DOCUMENT_ROOT"]; } else { - let source = str_replace(DIRECTORY_SEPARATOR, "/", source); + let source = str_replace("\\", "/", source); } if (source[-1] != '/') { @@ -294,7 +294,7 @@ class Assets if empty target { let target = "min"; } else { - let target = trim(str_replace(DIRECTORY_SEPARATOR, "/", target), "/"); + let target = trim(str_replace("\\", "/", target), "/"); } let uriMin = "/" . target . "/" . dirname(uri) . "/"; From 4c0fa67c03fdbfc5a96bdce40085f0f68d8d2512 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Fri, 5 Oct 2018 22:56:50 +0800 Subject: [PATCH 14/15] if no target, place versioned file to the same dir --- ice/assets.zep | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index 108f1afd..f2e5d83c 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -291,13 +291,13 @@ class Assets throw new Exception(["The request assets do not exist: %s", source]); } - if empty target { - let target = "min"; + if !empty target { + let target = "/" . trim(str_replace("\\", "/", target), "/"); } else { - let target = trim(str_replace("\\", "/", target), "/"); + let target = ""; } - let uriMin = "/" . target . "/" . dirname(uri) . "/"; + let uriMin = target . "/" . dirname(uri) . "/"; // cache min files place to document root always let destination = _SERVER["DOCUMENT_ROOT"] . uriMin, From d31dc0ce02e6abf7b3da12dc46c69cfe3123d166 Mon Sep 17 00:00:00 2001 From: Mofasa Date: Mon, 8 Oct 2018 22:19:28 +0800 Subject: [PATCH 15/15] bugs fixed `type` parameter change from `text/css` or `text/javascript` to `css` or `js` ```php $assets->addCss(['css/style.css', 'type' => 'css']) ->addCss(['js/script.js', 'type' => 'js']) ``` but not ```php $assets->addCss(['css/style.css', 'type' => 'text/css']) ->addCss(['js/script.js', 'type' => 'text/javascript']) --- ice/assets.zep | 98 +++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 53 deletions(-) diff --git a/ice/assets.zep b/ice/assets.zep index f2e5d83c..b05fe4a3 100644 --- a/ice/assets.zep +++ b/ice/assets.zep @@ -67,28 +67,31 @@ class Assets */ public function add(var parameters, string collection = null, var minify = null) { - var content, type, link; + var type, ext = null; if typeof parameters == "string" { - let link = parameters, - parameters = [link]; + let parameters = [parameters]; + } else { + let ext = isset parameters["content"]; } - if !fetch content, parameters["content"] { - fetch content, parameters[0]; + if !ext && isset parameters[0] { + let ext = pathinfo(parameters[0], PATHINFO_EXTENSION); } fetch type, parameters["type"]; - if ends_with(content, ".css") || type == "text/css" { + if ext == "css" || type == "css" { if !collection { let collection = "css"; } + let parameters["type"] = "text/css"; this->addCss(parameters, collection, minify); - } elseif ends_with(content, ".js") || type == "text/javascript" { + } elseif ext == "js" || type == "js" { if !collection { let collection = "js"; } + let parameters["type"] = "text/javascript"; this->addJs(parameters, collection, minify); } @@ -105,42 +108,36 @@ class Assets */ public function addCss(array! parameters, string collection = "css", var minify = null) { - var content, tag, local = true; + var content, tag; let tag = this->di->get("tag"); - if !fetch content, parameters["content"] { - if fetch content, parameters[0] { - // do not support the host of url is the same as _SERVER["HTTP_HOST"] ATM - // the url contains any host will not minify the resource - let local = empty parse_url(content, PHP_URL_HOST); - } else { - throw new Exception("There is no css content or uri in the parameters"); - } - } - // If local minify is not set if minify === null { // Get global minify option, default is NEVER let minify = this->getOption("minify", false); } - // Do not minify external or minified resources - if !local || ends_with(content, ".min.css") { - let minify = false; - } - // Check if resource is inline or in file if isset parameters["content"] { + let content = parameters["content"]; this->addToCollection(collection, tag->style(["content": minify ? this->minify(content, "css") : content])); - } else { - if isset this->cache[content] { + } elseif fetch content, parameters[0] { + if isset this->cache[content] && file_exists(this->cache[content]) { let parameters["href"] = this->cache[content]; } else { + // do not support the host of url is the same as _SERVER["HTTP_HOST"] ATM + // the url contains any host will not minify the resource + if !empty parse_url(content, PHP_URL_HOST) || ends_with(content, ".min.css") { + // Do not minify external or minified resources + let minify = false; + } let parameters["href"] = this->prepare(content, minify), this->cache[content] = parameters["href"]; } this->addToCollection(collection, tag->link(parameters)); + } else { + throw new Exception("There is no css content or uri in the parameters"); } return this; @@ -156,42 +153,36 @@ class Assets */ public function addJs(array! parameters, string collection = "js", var minify = null) { - var content, tag, local = true; + var content, tag; let tag = this->di->get("tag"); - if !fetch content, parameters["content"] { - if fetch content, parameters[0] { - // do not support the host of url is the same as _SERVER["HTTP_HOST"] ATM - // the url contains any host will not minify the resource - let local = empty parse_url(content, PHP_URL_HOST); - } else { - throw new Exception("There is no js content or uri in the parameters"); - } - } - // If local minify is not set if minify === null { // Get global minify option, default is NEVER let minify = this->getOption("minify", false); } - // Do not minify external or minified resources - if !local || ends_with(content, ".min.js") { - let minify = false; - } - // Check if resource is inline or in file if isset parameters["content"] { + let content = parameters["content"]; this->addToCollection(collection, tag->script(["content": minify ? this->minify(content, "js") : content])); - } else { - if isset this->cache[content] { + } elseif fetch content, parameters[0] { + if isset this->cache[content] && file_exists(this->cache[content]) { let parameters["src"] = this->cache[content]; } else { + // do not support the host of url is the same as _SERVER["HTTP_HOST"] ATM + // the url contains any host will not minify the resource + if !empty parse_url(content, PHP_URL_HOST) || ends_with(content, ".min.js") { + // Do not minify external or minified resources + let minify = false; + } let parameters["src"] = this->prepare(content, minify), this->cache[content] = parameters["src"]; } this->addToCollection(collection, tag->script(parameters)); + } else { + throw new Exception("There is no js content or uri in the parameters"); } return this; @@ -264,12 +255,12 @@ class Assets */ protected function prepare(string! uri, var minify) { - var source, target, file, type, uriMin, destination, + var source, target, file, type, ext, uriMin, destination, md5file, md5Old, md5New, old, minified; let source = this->getOption("source"), target = this->getOption("target"), - file = pathinfo(uri, PATHINFO_FILENAME | PATHINFO_EXTENSION), + file = pathinfo(uri), type = file["extension"], file = file["filename"]; @@ -277,7 +268,7 @@ class Assets if uri[0] == '/' || empty source { let source = _SERVER["DOCUMENT_ROOT"]; } else { - let source = str_replace("\\", "/", source); + let source = rtrim(source, "/\\") . "/"; } if (source[-1] != '/') { @@ -297,25 +288,26 @@ class Assets let target = ""; } - let uriMin = target . "/" . dirname(uri) . "/"; + let uriMin = target . "/" . dirname(uri) . "/", + ext = minify ? "min." . type : type; // cache min files place to document root always let destination = _SERVER["DOCUMENT_ROOT"] . uriMin, - md5file = glob(destination . file . ".????????????????????????????????." . type), + md5file = glob(destination . file . ".????????????????????????????????." . ext), md5New = null; if !empty md5file { let md5file = md5file[0], - md5Old = substr(md5file, strlen(md5file) - strlen(type) - 33, 32), + md5Old = substr(md5file, strlen(md5file) - strlen(ext) - 33, 32), md5New = md5_file(source); if md5Old != md5New { - // new version found - let md5file = null; // delete the old version unlink(md5file); + // new version found + let md5file = null; } else { - let uriMin .= file . "." . md5New . "." . type; + let uriMin .= file . "." . md5New . "." . ext; } } if empty md5file { @@ -330,7 +322,7 @@ class Assets umask(old); } - let uriMin .= file . "." . md5New . "." . type, + let uriMin .= file . "." . md5New . "." . ext, destination = _SERVER["DOCUMENT_ROOT"] . uriMin; if minify {