Minify and concatenate CSS

@param array $assets
@param string $group
@param array $attributes

@return bool|string     URL or generated content if available, else false
490450
public function renderCss($assets, $group, $attributes = [])
    {
        // temporary list of assets to pipeline
        $inline_group = false;

        if (array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline') {
            $inline_group = true;
            unset($attributes['loading']);
        }

        // Store Attributes
        $this->attributes = array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes);

        // Compute uid based on assets and timestamp
        $json_assets = json_encode($assets);
        $uid = md5($json_assets . $this->css_minify . $this->css_rewrite . $group);
        $file = $uid . '.css';
        $relative_path = "{$this->base_url}{$this->assets_url}/{$file}";

        $buffer = null;

        if (file_exists($this->assets_dir . $file)) {
            $buffer = file_get_contents($this->assets_dir . $file) . "\n";
        } else {
            //if nothing found get out of here!
            if (empty($assets)) {
                return false;
            }

            // Concatenate files
            $buffer = $this->gatherLinks($assets, self::CSS_ASSET);

            // Minify if required
            if ($this->shouldMinify('css')) {
                $minifier = new \MatthiasMullie\Minify\CSS();
                $minifier->add($buffer);
                $buffer = $minifier->minify();
            }

            // Write file
            if (trim($buffer) !== '') {
                file_put_contents($this->assets_dir . $file, $buffer);
            }
        }

        if ($inline_group) {
            $output = "<style>\n" . $buffer . "\n</style>\n";
        } else {
            $this->asset = $relative_path;
            $output = '<link href="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . ">\n";
        }

        return $output;
    }
1149495
public function attributes(array $attributes): AssetInterface
    {
        if (is_null($this->getType())) {
            throw new AssetException('The asset must have a type.');
        }

        $hook = 'script' === $this->getType() ? 'script_loader_tag' : 'style_loader_tag';
        $key = strtolower(trim($this->getHandle()));
        $attributes = $this->html->attributes($attributes);

        $this->filter->add($hook, function ($tag, $handle) use ($attributes, $key) {
            if ($key !== $handle) {
                return $tag;
            }

            return preg_replace('/(src|href)(.+>)/', $attributes.'$1$2', $tag);
        });

        return $this;
    }
32757
public function group(array $attributes, $routes)
    {
        $this->updateGroupStack($attributes);

        // Once we have updated the group stack, we'll load the provided routes and
        // merge in the group's attributes when the routes are created. After we
        // have created the routes, we will pop the attributes off the stack.
        $this->loadRoutes($routes);

        array_pop($this->groupStack);
    }
945637
public function open( $attributes = array() ) {
        $this->setAttributes( $attributes );
        $html = '<' . $this->tagName
                    . $this->renderAttributes()
                    ;
        // should we close it ?
        if( $this->closeEmpty || $this->hasChildren() ) {
            $html .= '>';
        } else {
            $html .= '/>';
        }
        return $html;
    }
1129349
protected function callHandlerIfAssigned($group, $asset)
    {
        if (!isset($this->customHandlers[$asset]) || $this->skipHandler == $asset) {
            return false;
        }

        $this->skipHandler = $asset;

        try {
            call_user_func($this->customHandlers[$asset], $this, $asset, $group);
        } finally {
            $this->skipHandler = '';
        }

        return true;
    }
185859
public static function assetgroups($config = array())
	{
		if (empty(self::$asset_groups))
		{
			$db = App::get('db');

			$query = $db->getQuery()
				->select('a.id', 'value')
				->select('a.title', 'text')
				->from('#__viewlevels', 'a')
				->group('a.id')
				->group('a.title')
				->group('a.ordering')
				->order('a.ordering', 'asc');

			$db->setQuery($query->toString());
			self::$asset_groups = $db->loadObjectList();

			// Check for a database error.
			if ($db->getErrorNum())
			{
				throw new Exception($db->getErrorMsg(), 500, E_WARNING);
				return false;
			}
		}

		return self::$asset_groups;
	}
354215
public function stylesheetLinkTag($sources = "application", $attributes = [])
    {
        // E.g. stylesheet_link_tag('app', ['media'=>'all']); => app-fa2ce4b45369a106436f229ca9e52bee.css
        $args = func_get_args();
        if (is_array(last($args))) {
            $attributes = array_pop($args);
        } else {
            $attributes = [];
        }
        $sources = is_array($sources) ? $sources : $args;
        if (empty($sources)) {
            $sources = ["application"];
        }

        $assetsOptions = ['host' => array_pull($attributes, 'host', $this->assetsHost)];

        $defaults = ['media' => 'all', 'type' => 'text/css'];
        $attributes = $attributes + $defaults;

        $stylesheet_tags = [];
        foreach ((array) $sources as $source) {
            $sourceName = "$source.css";
            $stylesheet_tags[] = app('html')->style($this->assetPath($sourceName, $assetsOptions), $attributes);
        }

        return implode($stylesheet_tags);
    }
963246
protected function updateGroupStack(array $attributes)
    {
        if (! empty($this->groupStack)) {
            $old = last($this->groupStack);

            $attributes = static::mergeGroup($attributes, $old);
        }

        $this->groupStack[] = $attributes;
    }
115048
protected function generateAttributes(array $attributes)
	{
		if (isset($attributes['style']) && is_array($attributes['style']))
		{
			$attributes['style'] = $this->generateStyle($attributes['style']);
		}

		ksort($attributes);
		$xsl = '';
		foreach ($attributes as $attrName => $attrValue)
		{
			$innerXML = (strpos($attrValue, '<xsl:') !== false) ? $attrValue : AVTHelper::toXSL($attrValue);

			$xsl .= '<xsl:attribute name="' . htmlspecialchars($attrName, ENT_QUOTES, 'UTF-8') . '">' . $innerXML . '</xsl:attribute>';
		}

		return $xsl;
	}
280992
public static function img($images = array(), $attr = array(), $group = NULL)
	{
		return static::instance()->img($images, $attr, $group);
	}
874854
public function inline($asset, $content, $group = null)
    {
        $group = $this->detectGroup($asset, $group);
        $this->lastTouchedAssets = [$asset];
        $this->lastTouchedGroup = $group;

        $this->addImportOrInline($asset, $group, $content);

        return $this;
    }
723019
public function script($url, $attributes = array())
	{
		$attributes['src'] = $this->url->asset($url);

		return '<script'.$this->attributes($attributes).'></script>'.PHP_EOL;
	}
96180
public function import($asset, $group = null)
    {
        $this->parent->import($asset, $this->mergePassedGroup($asset, $group));

        return $this;
    }
795655
protected function updateGroupStack(array $attributes)
    {
        if (! empty($this->groupStack)) {
            $attributes = $this->mergeWithLastGroup($attributes);
        }

        $this->groupStack[] = $attributes;
    }
542851
protected function renderAsset(Asset $asset, $group)
    {
        return $asset->isInline() ? $this->renderInline($asset, $group) : $this->renderExternal($asset, $group);
    }
598517
protected function asset($group, $name)
    {
        if ( ! isset($this->assets[$group][$name])) return '';

        $asset = $this->assets[$group][$name];

        // If the bundle source is not a complete URL, we will go ahead and prepend
        // the bundle's asset path to the source provided with the asset. This will
        // ensure that we attach the correct path to the asset.
        if (filter_var($asset['source'], FILTER_VALIDATE_URL) === false)
        {
            $asset['source'] = $this->path($asset['source']);
        }

        // If source is not a path to asset, render without wrap a HTML.
        if (strpos($asset['source'], '<') !== false)
        {
            return $asset['source'];
        }

        // This line fixing config path.
        $asset['source'] = $this->configAssetUrl($asset['source']);

        //return HTML::$group($asset['source'], $asset['attributes']);
        return $this->html($group, $asset['source'], $asset['attributes']);
    }
1092179
public function attributes($attributes)
    {
        if (is_array($this->attributes) and is_array($attributes)) {
            $attributes = array_merge($this->attributes, $attributes);
        }
        $this->attributes = $attributes;

        return $this;
    }