uawdijnntqw1x1x1
IP : 216.73.216.155
Hostname : vm5018.vps.agava.net
Kernel : Linux vm5018.vps.agava.net 3.10.0-1127.8.2.vz7.151.14 #1 SMP Tue Jun 9 12:58:54 MSK 2020 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
var
/
www
/
iplanru
/
data
/
www
/
i-plan.ru
/
administrator
/
components
/
com_widgetkit
/
helpers
/
assetfilter.php
/
/
<?php /** * @package Widgetkit * @author YOOtheme http://www.yootheme.com * @copyright Copyright (C) YOOtheme GmbH * @license http://www.gnu.org/licenses/gpl.html GNU/GPL */ /* Class: AssetFilterWidgetkitHelper Asset filter helper class, to filter assets */ class AssetFilterWidgetkitHelper extends WidgetkitHelper { /* Function: create Create filter object(s) Parameters: $filters - String|Array Returns: Mixed */ public function create($filters = array()) { $prefix = 'WidgetkitAssetFilter'; // one filter if (is_string($filters)) { $class = $prefix.$filters; return new $class(); } // multiple filter $collection = new WidgetkitAssetFilterCollection(); foreach ($filters as $name) { $class = $prefix.$name; $collection->add(new $class()); } return $collection; } } /* Interface: WidgetkitAssetFilterInterface Asset filter interface */ interface WidgetkitAssetFilterInterface { public function filterLoad($asset); public function filterContent($asset); } /* Class: WidgetkitAssetFilterCollection Asset filter collection */ class WidgetkitAssetFilterCollection implements WidgetkitAssetFilterInterface, Iterator { protected $filters; /* Function: __construct Class Constructor. */ public function __construct() { $this->filters = new SplObjectStorage(); } /* Function: filterLoad On load filter callback Parameters: $asset - Object Returns: Void */ public function filterLoad($asset) { foreach ($this->filters as $filter) { $filter->filterLoad($asset); } } /* Function: filterContent On content filter callback Parameters: $asset - Object Returns: Void */ public function filterContent($asset) { foreach ($this->filters as $filter) { $filter->filterContent($asset); } } /* Function: add Add filter to collection Parameters: $filter - Object Returns: Void */ public function add($filter) { if ($filter instanceof Traversable) { foreach ($filter as $f) { $this->add($f); } } else { $this->filters->attach($filter); } } /* Function: remove Remove filter from collection Parameters: $filter - Object Returns: Void */ public function remove($filter) { $this->filters->detach($filter); } /* Iterator interface implementation */ public function current() { return $this->filters->current(); } public function key() { return $this->filters->key(); } public function valid() { return $this->filters->valid(); } public function next() { $this->filters->next(); } public function rewind() { $this->filters->rewind(); } } /* Class: WidgetkitAssetFilterCSSImportResolver Stylesheet import resolver, replaces @imports with it's content */ class WidgetkitAssetFilterCSSImportResolver implements WidgetkitAssetFilterInterface { /* Function: filterLoad On load filter callback Parameters: $asset - Object Returns: Void */ public function filterLoad($asset) { // is file asset? if (!is_a($asset, 'WidgetkitFileAsset')) { return; } // resolve @import rules $content = $this->load($asset->getPath(), $asset->getContent()); // move unresolved @import rules to the top $regexp = '/@import[^;]+;/i'; if (preg_match_all($regexp, $content, $matches)) { $content = preg_replace($regexp, '', $content); $content = implode("\n", $matches[0])."\n".$content; } $asset->setContent($content); } /* Function: filterContent On content filter callback Parameters: $asset - Object Returns: Void */ public function filterContent($asset) {} /* Function: load Load file and get it's content Parameters: $file - String $content - String Returns: String */ protected function load($file, $content = '') { static $path; $oldpath = $path; if ($path && !strpos($file, '://')) { $file = realpath($path.'/'.$file); } $path = dirname($file); // get content from file, if not already set if (!$content && file_exists($file)) { $content = @file_get_contents($file); } // remove multiple charset declarations and resolve @imports to its actual content if ($content) { $content = preg_replace('/^@charset\s+[\'"](\S*)\b[\'"];/i', '', $content); $content = preg_replace_callback('/@import\s*(?:url\(\s*)?[\'"]?(?![a-z]+:)([^\'"\()]+)[\'"]?\s*\)?\s*;/', array($this, '_load'), $content); } $path = $oldpath; return $content; } /* Function: _load Load file recursively and fix url paths Parameters: $matches - Array Returns: String */ protected function _load($matches) { $filename = $matches[1]; // resolve @import rules recursively $file = $this->load($matches[1]); // get file's directory remove '.' if its the current directory $directory = dirname($matches[1]); $directory = $directory == '.' ? '' : $directory . '/'; // add directory file's to urls paths return preg_replace('/url\s*\(([\'"]?)(?![a-z]+:|\/+)/i', 'url(\1' . $directory, $file); } } /* Class: WidgetkitAssetFilterCSSRewriteURL Rewrite stylesheet urls, rewrites relative urls to absolute urls */ class WidgetkitAssetFilterCSSRewriteURL implements WidgetkitAssetFilterInterface { protected static $path; /* Function: filterLoad On load filter callback Parameters: $asset - Object Returns: Void */ public function filterLoad($asset) { // has url? if (!$asset->getUrl()) { return; } // set base path self::$path = dirname($asset->getUrl()).'/'; $asset->setContent(preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', array($this, 'rewrite'), $asset->getContent())); } /* Function: filterContent On content filter callback Parameters: $asset - Object Returns: Void */ public function filterContent($asset) {} /* Function: rewrite Rewrite url callback Parameters: $matches - Array Returns: String */ protected function rewrite($matches) { // prefix with base and remove '../' segments if possible $path = self::$path.$matches[1]; $last = ''; while ($path != $last) { $last = $path; $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path); } return 'url("'.$path.'")'; } } /* Class: WidgetkitAssetFilterCSSImageBase64 Replace stylesheets image urls with base64 image strings */ class WidgetkitAssetFilterCSSImageBase64 implements WidgetkitAssetFilterInterface { /* Function: filterLoad On load filter callback Parameters: $asset - Object Returns: Void */ public function filterLoad($asset) {} /* Function: filterContent On content filter callback Parameters: $asset - Object Returns: Void */ public function filterContent($asset) { $images = array(); $content = $asset->getContent(); // get images and the related path if (preg_match_all('/url\(\s*[\'"]?([^\'"]+)[\'"]?\s*\)/Ui', $asset->getContent(), $matches)) { foreach ($matches[0] as $i => $url) { if ($path = realpath($asset['base_path'].'/'.ltrim(preg_replace('/'.preg_quote($asset['base_url'], '/').'/', '', $matches[1][$i], 1), '/'))) { $images[$url] = $path; } } } // check if image exists and filesize < 10kb foreach ($images as $url => $path) { if (filesize($path) <= 10240 && preg_match('/\.(gif|png|jpg)$/i', $path, $extension)) { $content = str_replace($url, sprintf('url(data:image/%s;base64,%s)', str_replace('jpg', 'jpeg', strtolower($extension[1])), base64_encode(file_get_contents($path))), $content); } } $asset->setContent($content); } } /* Class: WidgetkitAssetFilterCSSCompressor Stylesheet compressor, minifies css Based on Minify_CSS_Compressor (https://github.com/mrclay/minify, Ryan Grove <ryan@wonko.com>, Stephen Clay <steve@mrclay.org>, BSD License) */ class WidgetkitAssetFilterCSSCompressor implements WidgetkitAssetFilterInterface { /** * @var bool Are we "in" a hack? * * I.e. are some browsers targetted until the next comment? */ protected $_inHack = false; /** * Filter callbacks */ public function filterLoad($asset) {} public function filterContent($asset) { $asset->setContent($this->process($asset->getContent())); } /** * Minify a CSS string * * @param string $css * * @return string */ public function process($css) { $css = str_replace("\r\n", "\n", $css); // preserve empty comment after '>' // http://www.webdevout.net/css-hacks#in_css-selectors $css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css); // preserve empty comment between property and value // http://css-discuss.incutio.com/?page=BoxModelHack $css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css); $css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css); // apply callback to all valid comments (and strip out surrounding ws $css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@' ,array($this, '_commentCB'), $css); // remove ws around { } and last semicolon in declaration block $css = preg_replace('/\\s*{\\s*/', '{', $css); $css = preg_replace('/;?\\s*}\\s*/', '}', $css); // remove ws surrounding semicolons $css = preg_replace('/\\s*;\\s*/', ';', $css); // remove ws around urls $css = preg_replace('/ url\\( # url( \\s* ([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis) \\s* \\) # ) /x', 'url($1)', $css); // remove ws between rules and colons $css = preg_replace('/ \\s* ([{;]) # 1 = beginning of block or rule separator \\s* ([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter) \\s* : \\s* (\\b|[#\'"-]) # 3 = first character of a value /x', '$1$2:$3', $css); // remove ws in selectors $css = preg_replace_callback('/ (?: # non-capture \\s* [^~>+,\\s]+ # selector part \\s* [,>+~] # combinators )+ \\s* [^~>+,\\s]+ # selector part { # open declaration block /x' ,array($this, '_selectorsCB'), $css); // minimize hex colors $css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i' , '$1#$2$3$4$5', $css); // remove spaces between font families $css = preg_replace_callback('/font-family:([^;}]+)([;}])/' ,array($this, '_fontFamilyCB'), $css); $css = preg_replace('/@import\\s+url/', '@import url', $css); // replace any ws involving newlines with a single newline $css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css); // separate common descendent selectors w/ newlines (to limit line lengths) $css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css); // Use newline after 1st numeric value (to limit line lengths). $css = preg_replace('/ ((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value \\s+ /x' ,"$1\n", $css); // prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/ $css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css); return trim($css); } /** * Replace what looks like a set of selectors * * @param array $m regex matches * * @return string */ protected function _selectorsCB($m) { // remove ws around the combinators return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]); } /** * Process a comment and return a replacement * * @param array $m regex matches * * @return string */ protected function _commentCB($m) { $hasSurroundingWs = (trim($m[0]) !== $m[1]); $m = $m[1]; // $m is the comment content w/o the surrounding tokens, // but the return value will replace the entire comment. if ($m === 'keep') { return '/**/'; } if ($m === '" "') { // component of http://tantek.com/CSS/Examples/midpass.html return '/*" "*/'; } if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) { // component of http://tantek.com/CSS/Examples/midpass.html return '/*";}}/* */'; } if ($this->_inHack) { // inversion: feeding only to one browser if (preg_match('@ ^/ # comment started like /*/ \\s* (\\S[\\s\\S]+?) # has at least some non-ws content \\s* /\\* # ends like /*/ or /**/ @x', $m, $n)) { // end hack mode after this comment, but preserve the hack and comment content $this->_inHack = false; return "/*/{$n[1]}/**/"; } } if (substr($m, -1) === '\\') { // comment ends like \*/ // begin hack mode and preserve hack $this->_inHack = true; return '/*\\*/'; } if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */ // begin hack mode and preserve hack $this->_inHack = true; return '/*/*/'; } if ($this->_inHack) { // a regular comment ends hack mode but should be preserved $this->_inHack = false; return '/**/'; } // Issue 107: if there's any surrounding whitespace, it may be important, so // replace the comment with a single space return $hasSurroundingWs // remove all other comments ? ' ' : ''; } /** * Process a font-family listing and return a replacement * * @param array $m regex matches * * @return string */ protected function _fontFamilyCB($m) { $m[1] = preg_replace('/ \\s* ( "[^"]+" # 1 = family in double qutoes |\'[^\']+\' # or 1 = family in single quotes |[\\w\\-]+ # or 1 = unquoted family ) \\s* /x', '$1', $m[1]); return 'font-family:' . $m[1] . $m[2]; } } /* Class: WidgetkitAssetFilterJSCompressor Javascript compressor, minifies javascript Based on JSMin (https://github.com/mrclay/minify, Ryan Grove <ryan@wonko.com>, Stephen Clay <steve@mrclay.org>, BSD License) */ class WidgetkitAssetFilterJSCompressor implements WidgetkitAssetFilterInterface { const ORD_LF = 10; const ORD_SPACE = 32; const ACTION_KEEP_A = 1; const ACTION_DELETE_A = 2; const ACTION_DELETE_A_B = 3; protected $a = "\n"; protected $b = ''; protected $input = ''; protected $inputIndex = 0; protected $inputLength = 0; protected $lookAhead = null; protected $output = ''; protected $lastByteOut = ''; /** * Filter callbacks */ public function filterLoad($asset) {} public function filterContent($asset) { $asset->setContent($this->process($asset->getContent())); } /** * Minify Javascript. * * @param string $script Javascript to be minified * * @return string */ public function process($script) { // init vars $this->a = "\n"; $this->b = ''; $this->input = $script; $this->inputIndex = 0; $this->inputLength = 0; $this->lookAhead = null; $this->output = ''; $this->lastByteOut = ''; try { $script = trim($this->min()); } catch (Exception $e) {} return $script; } /** * Perform minification, return result * * @return string */ public function min() { if ($this->output !== '') { // min already run return $this->output; } $mbIntEnc = null; if (function_exists('mb_strlen') && ((int)ini_get('mbstring.func_overload') & 2)) { $mbIntEnc = mb_internal_encoding(); mb_internal_encoding('8bit'); } $this->input = str_replace("\r\n", "\n", $this->input); $this->inputLength = strlen($this->input); $this->action(self::ACTION_DELETE_A_B); while ($this->a !== null) { // determine next command $command = self::ACTION_KEEP_A; // default if ($this->a === ' ') { if (($this->lastByteOut === '+' || $this->lastByteOut === '-') && ($this->b === $this->lastByteOut)) { // Don't delete this space. If we do, the addition/subtraction // could be parsed as a post-increment } elseif (! $this->isAlphaNum($this->b)) { $command = self::ACTION_DELETE_A; } } elseif ($this->a === "\n") { if ($this->b === ' ') { $command = self::ACTION_DELETE_A_B; // in case of mbstring.func_overload & 2, must check for null b, // otherwise mb_strpos will give WARNING } elseif ($this->b === null || (false === strpos('{[(+-', $this->b) && ! $this->isAlphaNum($this->b))) { $command = self::ACTION_DELETE_A; } } elseif (! $this->isAlphaNum($this->a)) { if ($this->b === ' ' || ($this->b === "\n" && (false === strpos('}])+-"\'', $this->a)))) { $command = self::ACTION_DELETE_A_B; } } $this->action($command); } $this->output = trim($this->output); if ($mbIntEnc !== null) { mb_internal_encoding($mbIntEnc); } return $this->output; } /** * ACTION_KEEP_A = Output A. Copy B to A. Get the next B. * ACTION_DELETE_A = Copy B to A. Get the next B. * ACTION_DELETE_A_B = Get the next B. * * @param int $command * @throws Exception */ protected function action($command) { if ($command === self::ACTION_DELETE_A_B && $this->b === ' ' && ($this->a === '+' || $this->a === '-')) { // Note: we're at an addition/substraction operator; the inputIndex // will certainly be a valid index if ($this->input[$this->inputIndex] === $this->a) { // This is "+ +" or "- -". Don't delete the space. $command = self::ACTION_KEEP_A; } } switch ($command) { case self::ACTION_KEEP_A: $this->output .= $this->a; $this->lastByteOut = $this->a; // fallthrough case self::ACTION_DELETE_A: $this->a = $this->b; if ($this->a === "'" || $this->a === '"') { // string literal $str = $this->a; // in case needed for exception while (true) { $this->output .= $this->a; $this->lastByteOut = $this->a; $this->a = $this->get(); if ($this->a === $this->b) { // end quote break; } if (ord($this->a) <= self::ORD_LF) { throw new Exception( "JSMin: Unterminated String at byte " . $this->inputIndex . ": {$str}"); } $str .= $this->a; if ($this->a === '\\') { $this->output .= $this->a; $this->lastByteOut = $this->a; $this->a = $this->get(); $str .= $this->a; } } } // fallthrough case self::ACTION_DELETE_A_B: $this->b = $this->next(); if ($this->b === '/' && $this->isRegexpLiteral()) { // RegExp literal $this->output .= $this->a . $this->b; $pattern = '/'; // in case needed for exception while (true) { $this->a = $this->get(); $pattern .= $this->a; if ($this->a === '/') { // end pattern break; // while (true) } elseif ($this->a === '\\') { $this->output .= $this->a; $this->a = $this->get(); $pattern .= $this->a; } elseif (ord($this->a) <= self::ORD_LF) { throw new Exception( "JSMin: Unterminated RegExp at byte " . $this->inputIndex .": {$pattern}"); } $this->output .= $this->a; $this->lastByteOut = $this->a; } $this->b = $this->next(); } // end case ACTION_DELETE_A_B } } /** * @return bool */ protected function isRegexpLiteral() { if (false !== strpos("\n{;(,=:[!&|?", $this->a)) { // we aren't dividing return true; } if (' ' === $this->a) { $length = strlen($this->output); if ($length < 2) { // weird edge case return true; } // you can't divide a keyword if (preg_match('/(?:case|else|in|return|typeof)$/', $this->output, $m)) { if ($this->output === $m[0]) { // odd but could happen return true; } // make sure it's a keyword, not end of an identifier $charBeforeKeyword = substr($this->output, $length - strlen($m[0]) - 1, 1); if (! $this->isAlphaNum($charBeforeKeyword)) { return true; } } } return false; } /** * Get next char. Convert ctrl char to space. * * @return string */ protected function get() { $c = $this->lookAhead; $this->lookAhead = null; if ($c === null) { if ($this->inputIndex < $this->inputLength) { $c = $this->input[$this->inputIndex]; $this->inputIndex += 1; } else { return null; } } if ($c === "\r" || $c === "\n") { return "\n"; } if (ord($c) < self::ORD_SPACE) { // control char return ' '; } return $c; } /** * Get next char. If is ctrl character, translate to a space or newline. * * @return string */ protected function peek() { $this->lookAhead = $this->get(); return $this->lookAhead; } /** * Is $c a letter, digit, underscore, dollar sign, escape, or non-ASCII? * * @param string $c * * @return bool */ protected function isAlphaNum($c) { return (preg_match('/^[0-9a-zA-Z_\\$\\\\]$/', $c) || ord($c) > 126); } /** * @return string */ protected function singleLineComment() { $comment = ''; while (true) { $get = $this->get(); $comment .= $get; if (ord($get) <= self::ORD_LF) { // EOL reached // if IE conditional comment if (preg_match('/^\\/@(?:cc_on|if|elif|else|end)\\b/', $comment)) { return "/{$comment}"; } return $get; } } } /** * @return string * @throws Exception */ protected function multipleLineComment() { $this->get(); $comment = ''; while (true) { $get = $this->get(); if ($get === '*') { if ($this->peek() === '/') { // end of comment reached $this->get(); // if comment preserved by YUI Compressor if (0 === strpos($comment, '!')) { return "\n/*!" . substr($comment, 1) . "*/\n"; } // if IE conditional comment if (preg_match('/^@(?:cc_on|if|elif|else|end)\\b/', $comment)) { return "/*{$comment}*/"; } return ' '; } } elseif ($get === null) { throw new Exception( "JSMin: Unterminated comment at byte " . $this->inputIndex . ": /*{$comment}"); } $comment .= $get; } } /** * Get the next character, skipping over comments. * Some comments may be preserved. * * @return string */ protected function next() { $get = $this->get(); if ($get !== '/') { return $get; } switch ($this->peek()) { case '/': return $this->singleLineComment(); case '*': return $this->multipleLineComment(); default: return $get; } } }
/var/www/iplanru/data/www/i-plan.ru/administrator/components/com_widgetkit/helpers/assetfilter.php