diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index b23f1465e..ce9e08af1 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -20,7 +20,6 @@ define('JS_ASSET', false); * @author RocketTheme * @license MIT */ - class Assets { use GravTrait; @@ -86,8 +85,9 @@ class Assets public function __construct(array $options = array()) { // Forward config options - if($options) + if ($options) { $this->config((array)$options); + } } /** @@ -98,7 +98,7 @@ class Assets /** @var Config $config */ $config = self::$grav['config']; $base_url = self::$grav['base_url']; - $asset_config = (array) $config->get('system.assets'); + $asset_config = (array)$config->get('system.assets'); $this->config($asset_config); $this->base_url = $base_url . '/'; @@ -118,43 +118,50 @@ class Assets public function config(array $config) { // Set pipeline modes - if(isset($config['css_pipeline'])) + if (isset($config['css_pipeline'])) { $this->css_pipeline = $config['css_pipeline']; + } - if(isset($config['js_pipeline'])) + if (isset($config['js_pipeline'])) { $this->js_pipeline = $config['js_pipeline']; + } // Pipeline requires public dir - if(($this->js_pipeline || $this->css_pipeline) && ! is_dir(ASSETS_DIR)) + if (($this->js_pipeline || $this->css_pipeline) && !is_dir(ASSETS_DIR)) { throw new \Exception('Assets: Public dir not found'); + } // Set custom pipeline fetch command - if(isset($config['fetch_command']) and ($config['fetch_command'] instanceof Closure)) + if (isset($config['fetch_command']) and ($config['fetch_command'] instanceof Closure)) { $this->fetch_command = $config['fetch_command']; + } // Set CSS Minify state - if(isset($config['css_minify'])) + if (isset($config['css_minify'])) { $this->css_minify = $config['css_minify']; + } - if(isset($config['css_minify_windows'])) + if (isset($config['css_minify_windows'])) { $this->css_minify_windows = $config['css_minify_windows']; + } - if(isset($config['css_rewrite'])) + if (isset($config['css_rewrite'])) { $this->css_rewrite = $config['css_rewrite']; + } // Set JS Minify state - if(isset($config['js_minify'])) + if (isset($config['js_minify'])) { $this->js_minify = $config['js_minify']; + } // Set collections - if(isset($config['collections']) and is_array($config['collections'])) + if (isset($config['collections']) and is_array($config['collections'])) { $this->collections = $config['collections']; + } // Autoload assets - if(isset($config['autoload']) and is_array($config['autoload'])) - { - foreach($config['autoload'] as $asset) - { + if (isset($config['autoload']) and is_array($config['autoload'])) { + foreach ($config['autoload'] as $asset) { $this->add($asset); } } @@ -168,35 +175,30 @@ class Assets * It automatically detects the asset type (JavaScript, CSS or collection). * You may add more than one asset passing an array as argument. * - * @param mixed $asset - * @param int $priority the priority, bigger comes first - * @param bool $pipeline false if this should not be pipelined + * @param mixed $asset + * @param int $priority the priority, bigger comes first + * @param bool $pipeline false if this should not be pipelined * @return $this */ public function add($asset, $priority = 10, $pipeline = true) { // More than one asset - if(is_array($asset)) - { - foreach($asset as $a) + if (is_array($asset)) { + foreach ($asset as $a) { $this->add($a, $priority, $pipeline); - } - // Collection - elseif(isset($this->collections[$asset])) - { + } + } elseif (isset($this->collections[$asset])) { $this->add($this->collections[$asset], $priority, $pipeline); - } - else - { + } else { // JavaScript or CSS $info = pathinfo($asset); - if(isset($info['extension'])) - { + if (isset($info['extension'])) { $ext = strtolower($info['extension']); - if($ext === 'css') + if ($ext === 'css') { $this->addCss($asset, $priority, $pipeline); - elseif($ext === 'js') + } elseif ($ext === 'js') { $this->addJs($asset, $priority, $pipeline); + } } } @@ -209,11 +211,12 @@ class Assets * It checks for duplicates. * For adding chunks of string-based inline CSS * - * @param mixed $asset - * @param int $priority the priority, bigger comes first + * @param mixed $asset + * @param int $priority the priority, bigger comes first * @return $this */ - public function addInlineCss($asset, $priority = 10) { + public function addInlineCss($asset, $priority = 10) + { if (is_string($asset) && !in_array($asset, $this->inline_css)) { $this->inline_css[] = $asset; @@ -228,27 +231,32 @@ class Assets * It checks for duplicates. * You may add more than one asset passing an array as argument. * - * @param mixed $asset - * @param int $priority the priority, bigger comes first - * @param bool $pipeline false if this should not be pipelined + * @param mixed $asset + * @param int $priority the priority, bigger comes first + * @param bool $pipeline false if this should not be pipelined * @return $this */ public function addCss($asset, $priority = 10, $pipeline = true) { - if(is_array($asset)) - { - foreach($asset as $a) + if (is_array($asset)) { + foreach ($asset as $a) { $this->addCss($a, $priority, $pipeline); + } return $this; } - if( !$this->isRemoteLink($asset)) { + if (!$this->isRemoteLink($asset)) { $asset = $this->buildLocalLink($asset); } - if( !array_key_exists($asset, $this->css)) { - $this->css[$asset] = ['asset'=>$asset, 'priority'=>$priority, 'order' => count($this->css), 'pipeline'=>$pipeline]; + if (!array_key_exists($asset, $this->css)) { + $this->css[$asset] = [ + 'asset' => $asset, + 'priority' => $priority, + 'order' => count($this->css), + 'pipeline' => $pipeline + ]; } return $this; @@ -260,11 +268,12 @@ class Assets * It checks for duplicates. * For adding chunks of string-based inline JS * - * @param mixed $asset - * @param int $priority the priority, bigger comes first + * @param mixed $asset + * @param int $priority the priority, bigger comes first * @return $this */ - public function addInlineJs($asset) { + public function addInlineJs($asset) + { if (is_string($asset) && !in_array($asset, $this->inline_js)) { $this->inline_js[] = $asset; @@ -279,28 +288,33 @@ class Assets * It checks for duplicates. * You may add more than one asset passing an array as argument. * - * @param mixed $asset - * @param int $priority the priority, bigger comes first - * @param bool $pipeline false if this should not be pipelined + * @param mixed $asset + * @param int $priority the priority, bigger comes first + * @param bool $pipeline false if this should not be pipelined * @return $this */ public function addJs($asset, $priority = 10, $pipeline = true) { - if(is_array($asset)) - { - foreach($asset as $a) + if (is_array($asset)) { + foreach ($asset as $a) { $this->addJs($a, $priority, $pipeline); + } return $this; } - if( !$this->isRemoteLink($asset)) { + if (!$this->isRemoteLink($asset)) { $asset = $this->buildLocalLink($asset); } - if( !array_key_exists($asset, $this->js)) { + if (!array_key_exists($asset, $this->js)) { - $this->js[$asset] = ['asset' => $asset, 'priority' => $priority, 'order' => count($this->js), 'pipeline' => $pipeline]; + $this->js[$asset] = [ + 'asset' => $asset, + 'priority' => $priority, + 'order' => count($this->js), + 'pipeline' => $pipeline + ]; } return $this; @@ -309,36 +323,37 @@ class Assets /** * Build the CSS link tags. * - * @param array $attributes + * @param array $attributes * @return string */ public function css($attributes = []) { - if( ! $this->css) + if (!$this->css) { return null; - - if (self::$grav) + } // Sort array by priorities (larger priority first) - usort($this->css, function ($a, $b) { - if ($a['priority'] == $b['priority']) { - return $b['order'] - $a['order']; - } - return $a['priority'] - $b['priority']; - }); + if (self::$grav) { + usort($this->css, function ($a, $b) { + if ($a['priority'] == $b['priority']) { + return $b['order'] - $a['order']; + } + return $a['priority'] - $b['priority']; + }); + } $this->css = array_reverse($this->css); - $attributes = $this->attributes(array_merge([ 'type' => 'text/css', 'rel' => 'stylesheet' ], $attributes)); + $attributes = $this->attributes(array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes)); $output = ''; - if($this->css_pipeline) { - $output .= ''."\n"; + if ($this->css_pipeline) { + $output .= '' . "\n"; foreach ($this->css_no_pipeline as $file) { - $output .= ''."\n"; + $output .= '' . "\n"; } } else { - foreach($this->css as $file) { + foreach ($this->css as $file) { $output .= '' . "\n"; } } @@ -346,7 +361,7 @@ class Assets // Render Inline CSS if (count($this->inline_css) > 0) { $output .= "\n"; @@ -359,13 +374,14 @@ class Assets /** * Build the JavaScript script tags. * - * @param array $attributes + * @param array $attributes * @return string */ public function js($attributes = []) { - if( ! $this->js) + if (!$this->js) { return null; + } // Sort array by priorities (larger priority first) usort($this->js, function ($a, $b) { @@ -376,16 +392,16 @@ class Assets }); $this->js = array_reverse($this->js); - $attributes = $this->attributes(array_merge([ 'type' => 'text/javascript' ], $attributes)); + $attributes = $this->attributes(array_merge(['type' => 'text/javascript'], $attributes)); $output = ''; - if($this->js_pipeline) { - $output .= ''."\n"; + if ($this->js_pipeline) { + $output .= '' . "\n"; foreach ($this->js_no_pipeline as $file) { - $output .= ''."\n"; + $output .= '' . "\n"; } } else { - foreach($this->js as $file) { + foreach ($this->js as $file) { $output .= '' . "\n"; } } @@ -393,7 +409,7 @@ class Assets // Render Inline JS if (count($this->inline_js) > 0) { $output .= "\n"; @@ -405,22 +421,26 @@ class Assets /** * Build an HTML attribute string from an array. * - * @param array $attributes + * @param array $attributes * @return string */ - protected function attributes(array $attributes){ + protected function attributes(array $attributes) + { $html = ''; - foreach ( $attributes as $key => $value) - { + foreach ($attributes as $key => $value) { // For numeric keys we will assume that the key and the value are the same // as this will convert HTML attributes such as "required" to a correct // form like required="required" instead of using incorrect numerics. - if (is_numeric($key)) $key = $value; - if (is_array($value)) $value = implode(' ', $value); + if (is_numeric($key)) { + $key = $value; + } + if (is_array($value)) { + $value = implode(' ', $value); + } - $element = $key.'="'.htmlentities($value, ENT_QUOTES, 'UTF-8', false).'"'; - $html .= ' '.$element; + $element = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"'; + $html .= ' ' . $element; } return $html; @@ -429,8 +449,8 @@ class Assets /** * Add/replace collection. * - * @param string $collectionName - * @param array $assets + * @param string $collectionName + * @param array $assets * @return $this */ public function registerCollection($collectionName, Array $assets) @@ -483,7 +503,7 @@ class Assets { /** @var Cache $cache */ $cache = self::$grav['cache']; - $key = '?'.$cache->getKey(); + $key = '?' . $cache->getKey(); if ($css) { $file = md5(json_encode($this->css) . $this->js_minify . $this->css_minify . $this->css_rewrite) . '.css'; @@ -503,12 +523,13 @@ class Assets } } - $relative_path = "{$this->base_url}".basename(ASSETS_DIR)."/{$file}"; - $absolute_path = ASSETS_DIR.$file; + $relative_path = "{$this->base_url}" . basename(ASSETS_DIR) . "/{$file}"; + $absolute_path = ASSETS_DIR . $file; // If pipeline exist return it - if(file_exists($absolute_path)) + if (file_exists($absolute_path)) { return $relative_path . $key; + } $css_minify = $this->css_minify; @@ -542,7 +563,7 @@ class Assets /** * Download and concatenate the content of several links. * - * @param array $links + * @param array $links * @return string */ protected function gatherLinks(array $links, $css = true) @@ -552,27 +573,32 @@ class Assets $buffer = ''; $local = true; - foreach($links as $asset) - { + foreach ($links as $asset) { $link = $asset['asset']; $relative_path = $link; - if($this->isRemoteLink($link)) { + if ($this->isRemoteLink($link)) { $local = false; - if('//' === substr($link, 0, 2)) + if ('//' === substr($link, 0, 2)) { $link = 'http:' . $link; + } } else { // Fix to remove relative dir if grav is in one if (($this->base_url != '/') && (strpos($this->base_url, $link) == 0)) { $relative_path = str_replace($this->base_url, '/', $link); } - $relative_dir = dirname ($relative_path); + $relative_dir = dirname($relative_path); $link = ROOT_DIR . $relative_path; } $file = ($this->fetch_command instanceof Closure) ? $this->fetch_command->__invoke($link) : file_get_contents($link); + // Double check last character being + if (!$css) { + $file = rtrim($file, ' ;') . ';'; + } + // If this is CSS + the file is local + rewrite enabled if ($css && $local && $this->css_rewrite) { $file = $this->cssRewrite($file, $relative_dir); @@ -600,7 +626,7 @@ class Assets $this->imports = array(); $file = preg_replace_callback(self::CSS_IMPORT_REGEX, - function($matches) { + function ($matches) { $this->imports[] = $matches[0]; return ''; }, @@ -612,7 +638,7 @@ class Assets /** * Finds relative CSS urls() and rewrites the URL with an absolute one - * @param string $file the css source file + * @param string $file the css source file * @param string $relative_path relative path to the css file * @return [type] [description] */ @@ -624,29 +650,31 @@ class Assets // Find any css url() elements, grab the URLs and calculate an absolute path // Then replace the old url with the new one $file = preg_replace_callback(self::CSS_URL_REGEX, - function($matches) use ($relative_path) { + function ($matches) use ($relative_path) { - $old_url = $matches[1]; + $old_url = $matches[1]; - // ensure this is not a data url - if (strpos($old_url, 'data:') === 0) return $matches[0]; + // ensure this is not a data url + if (strpos($old_url, 'data:') === 0) { + return $matches[0]; + } - $newpath = array(); - $paths = explode('/', $old_url); + $newpath = array(); + $paths = explode('/', $old_url); - foreach ($paths as $path) { - if ($path == '..') { - $relative_path = dirname($relative_path); - } else { - $newpath[] = $path; - } + foreach ($paths as $path) { + if ($path == '..') { + $relative_path = dirname($relative_path); + } else { + $newpath[] = $path; } + } - $new_url = rtrim($this->base_url,'/') . $relative_path . '/' . implode('/', $newpath); + $new_url = rtrim($this->base_url, '/') . $relative_path . '/' . implode('/', $newpath); - return str_replace($old_url, $new_url, $matches[0]); - }, - $file + return str_replace($old_url, $new_url, $matches[0]); + }, + $file ); return $file; @@ -662,7 +690,8 @@ class Assets { try { $asset = self::$grav['locator']->findResource($asset, false); - } catch (\Exception $e) {} + } catch (\Exception $e) { + } return $this->base_url . ltrim($asset, '/'); } @@ -678,7 +707,8 @@ class Assets */ protected function isRemoteLink($link) { - return ('http://' === substr($link, 0, 7) or 'https://' === substr($link, 0, 8) or '//' === substr($link, 0, 2)); + return ('http://' === substr($link, 0, 7) or 'https://' === substr($link, 0, 8) + or '//' === substr($link, 0, 2)); } /** @@ -712,41 +742,40 @@ class Assets public function addDir($directory, $pattern = self::DEFAULT_REGEX) { // Check if public_dir exists - if( ! is_dir(ASSETS_DIR)) + if (!is_dir(ASSETS_DIR)) { throw new Exception('Assets: Public dir not found'); + } // Get files $files = $this->rglob(ASSETS_DIR . DIRECTORY_SEPARATOR . $directory, $pattern, ASSETS_DIR); // No luck? Nothing to do - if( ! $files) + if (!$files) { return $this; + } // Add CSS files - if($pattern === self::CSS_REGEX) - { + if ($pattern === self::CSS_REGEX) { $this->css = array_unique(array_merge($this->css, $files)); return $this; } // Add JavaScript files - if($pattern === self::JS_REGEX) - { + if ($pattern === self::JS_REGEX) { $this->js = array_unique(array_merge($this->js, $files)); return $this; } // Unknown pattern. We must poll to know the extension :( - foreach($files as $asset) - { + foreach ($files as $asset) { $info = pathinfo($asset); - if(isset($info['extension'])) - { + if (isset($info['extension'])) { $ext = strtolower($info['extension']); - if($ext === 'css' and ! in_array($asset, $this->css)) + if ($ext === 'css' and !in_array($asset, $this->css)) { $this->css[] = $asset; - elseif($ext === 'js' and ! in_array($asset, $this->js)) + } elseif ($ext === 'js' and !in_array($asset, $this->js)) { $this->js[] = $asset; + } } } @@ -785,12 +814,14 @@ class Assets */ protected function rglob($directory, $pattern, $ltrim = null) { - $iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, FilesystemIterator::SKIP_DOTS)), $pattern); + $iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory, + FilesystemIterator::SKIP_DOTS)), $pattern); $offset = strlen($ltrim); $files = array(); - foreach($iterator as $file) + foreach ($iterator as $file) { $files[] = substr($file->getPathname(), $offset); + } return $files; } @@ -805,7 +836,8 @@ class Assets return $a ['priority'] - $b ['priority']; } - public function __toString() { + public function __toString() + { return ''; }