From fbc1fdd0b7244d2f03164b62eb893223ff930319 Mon Sep 17 00:00:00 2001
From: ewinslow $categories ' . elgg_view('input/file', array('internalname' => 'upload')) . ' ' . elgg_echo('file:title') . ": " . elgg_view("input/text", array('internalname' => 'title')) . ' ' . elgg_echo('file:desc') . ": " . elgg_view("input/text",array('internalname' => 'description')) . ' ' . elgg_echo('file:tags') . ": " . elgg_view("input/tags", array('internalname' => 'tags')) . ' ' . elgg_echo('access') . ": " . elgg_view('input/access', array('internalname' => 'access_id', 'value' => $access_id)) . ' ' . elgg_view('input/submit', array('value' => elgg_echo('upload'))) . '
+ +
++ +
+HTML; + + echo elgg_view('input/submit', array('value' => elgg_echo('send'))); +} else { + echo elgg_echo('invitefriends:registration_disabled'); +} diff --git a/mod/invitefriends/views/default/invitefriends/form.php b/mod/invitefriends/views/default/invitefriends/form.php index 7ab9314f7..badcf8759 100644 --- a/mod/invitefriends/views/default/invitefriends/form.php +++ b/mod/invitefriends/views/default/invitefriends/form.php @@ -5,9 +5,4 @@ * @package ElggInviteFriends */ -echo elgg_view('input/form', array( - 'action' => 'action/invitefriends/invite', - 'body' => elgg_view('invitefriends/formitems'), - 'method' => 'post' - ) -); +echo elgg_view_form('invitefriends/invite'); diff --git a/mod/invitefriends/views/default/invitefriends/formitems.php b/mod/invitefriends/views/default/invitefriends/formitems.php index 555311dd0..afdff4164 100644 --- a/mod/invitefriends/views/default/invitefriends/formitems.php +++ b/mod/invitefriends/views/default/invitefriends/formitems.php @@ -1,33 +1,4 @@ -name)); - - echo <<< HTML -- -
-- -
-HTML; - - echo elgg_view('input/submit', array('value' => elgg_echo('send'))); -} else { - echo elgg_echo('invitefriends:registration_disabled'); -} +elgg_deprecated_notice("invitefriends/formitems was moved to forms/invitefriends/invite", 1.8); +echo elgg_view('forms/invitefriends/invite'); \ No newline at end of file diff --git a/mod/logbrowser/views/default/logbrowser/form.php b/mod/logbrowser/views/default/logbrowser/form.php index 7b430b8f7..0b76ba313 100644 --- a/mod/logbrowser/views/default/logbrowser/form.php +++ b/mod/logbrowser/views/default/logbrowser/form.php @@ -50,6 +50,7 @@ 'value' => elgg_echo('search'), )); + //@todo Forms 1.8: Convert to use elgg_view_form() $wrappedform = elgg_view('input/form', array( 'body' => $form, 'method' => 'get', diff --git a/mod/minify/lib/min/.htaccess b/mod/minify/lib/min/.htaccess new file mode 100644 index 000000000..42f13eb23 --- /dev/null +++ b/mod/minify/lib/min/.htaccess @@ -0,0 +1,4 @@ +Found by bookmarklet: /' + + location.hash.substr(1).split(',').join(' | /') + + '
' + ); + $('#bmUris a').click(function () { + MUB.addButtonClick(); + $('#sources li:last input').val(this.innerHTML) + MUB.liUpdateTestLink.call($('#sources li:last')[0]); + $('#results').hide(); + return false; + }).attr({title:'Add file +'}); + } else { + // copy bookmarklet code into href + var bmUri = location.pathname.replace(/\/[^\/]*$/, '/bm.js').substr(1); + $.ajax({ + url : '../?f=' + bmUri + ,success : function (code) { + $('#bm')[0].href = code + .replace('%BUILDER_URL%', location.href) + .replace(/\n/g, ' '); + } + ,dataType : 'text' + }); + $.browser.msie && $('#getBm p:last').append(' Sorry, not supported in MSIE!'); + MUB.addButtonClick(); + } + MUB.checkRewrite(); + } +}; +window.onload = MUB.init; \ No newline at end of file diff --git a/mod/minify/lib/min/builder/bm.js b/mod/minify/lib/min/builder/bm.js new file mode 100644 index 000000000..10d194381 --- /dev/null +++ b/mod/minify/lib/min/builder/bm.js @@ -0,0 +1,36 @@ +javascript:(function() { + var d = document + ,uris = [] + ,i = 0 + ,o + ,home = (location + '').split('/').splice(0, 3).join('/') + '/'; + function add(uri) { + return (0 === uri.indexOf(home)) + && (!/[\?&]/.test(uri)) + && uris.push(escape(uri.substr(home.length))); + }; + function sheet(ss) { + // we must check the domain with add() before accessing ss.cssRules + // otherwise a security exception will be thrown + if (ss.href && add(ss.href) && ss.cssRules) { + var i = 0, r; + while (r = ss.cssRules[i++]) + r.styleSheet && sheet(r.styleSheet); + } + }; + while (o = d.getElementsByTagName('script')[i++]) + o.src && !(o.type && /vbs/i.test(o.type)) && add(o.src); + i = 0; + while (o = d.styleSheets[i++]) + /* http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-DocumentStyle-styleSheets + document.styleSheet is a list property where [0] accesses the 1st element and + [outOfRange] returns null. In IE, styleSheets is a function, and also throws an + exception when you check the out of bounds index. (sigh) */ + sheet(o); + if (uris.length) + window.open('%BUILDER_URL%#' + uris.join(',')); + else + alert('No js/css files found with URLs within "' + + home.split('/')[2] + + '".\n(This tool is limited to URLs with the same domain.)'); +})(); \ No newline at end of file diff --git a/mod/minify/lib/min/builder/index.php b/mod/minify/lib/min/builder/index.php new file mode 100644 index 000000000..b24286f09 --- /dev/null +++ b/mod/minify/lib/min/builder/index.php @@ -0,0 +1,182 @@ + + + + +Note: Please set $min_cachePath
+in /min/config.php to improve performance.
Note: Your webserver does not seem to +support mod_rewrite (used in /min/.htaccess). Your Minify URIs will contain "?", which +may reduce the benefit of proxy cache servers.
+ +Create a list of Javascript or CSS files (or 1 is fine) you'd like to combine +and click [Update].
+ +Place this URI in your HTML to serve the files above combined, minified, compressed and +with cache headers.
+URI | /min (opens in new window) |
---|---|
HTML |
For the best performance you can serve these files as a pre-defined group with a URI
+like: /min/?g=keyName
To do this, add a line like this to /min/groupsConfig.php:
+ +return array(
+ ... your existing groups here ...
+
+);
+
+Make sure to replace keyName
with a unique key for this group.
You can use the bookmarklet below to fetch all CSS & Javascript URIs from a page +on your site. When you active it, this page will open in a new window with a list of +available URIs to add.
+ +Create Minify URIs (right-click, add to bookmarks)
+@import
If your CSS files contain @import
declarations, Minify will not
+remove them. Therefore, you will want to remove those that point to files already
+in your list, and move any others to the top of the first file in your list
+(imports below any styles will be ignored by browsers as invalid).
If you desire, you can use Minify URIs in imports and they will not be touched
+by Minify. E.g. @import "/min/?g=css2";
Need help? Search or post to the Minify discussion list.
+This app is minified :) view +source
+ + + + + + + ob_get_contents() + ,'id' => __FILE__ + ,'lastModifiedTime' => max( + // regenerate cache if either of these change + filemtime(__FILE__) + ,filemtime(dirname(__FILE__) . '/../config.php') + ) + ,'minifyAll' => true + ,'encodeOutput' => $encodeOutput +); +ob_end_clean(); + +set_include_path(dirname(__FILE__) . '/../lib' . PATH_SEPARATOR . get_include_path()); + +require 'Minify.php'; + +if (0 === stripos(PHP_OS, 'win')) { + Minify::setDocRoot(); // we may be on IIS +} +Minify::setCache(isset($min_cachePath) ? $min_cachePath : null); +Minify::$uploaderHoursBehind = $min_uploaderHoursBehind; + +Minify::serve('Page', $serveOpts); diff --git a/mod/minify/lib/min/builder/ocCheck.php b/mod/minify/lib/min/builder/ocCheck.php new file mode 100644 index 000000000..8cc19af8b --- /dev/null +++ b/mod/minify/lib/min/builder/ocCheck.php @@ -0,0 +1,36 @@ + 'World!' + ,'method' => 'deflate' + )); + $he->encode(); + $he->sendAll(); + +} else { + // echo status "0" or "1" + header('Content-Type: text/plain'); + echo (int)$_oc; +} diff --git a/mod/minify/lib/min/builder/rewriteTest.js b/mod/minify/lib/min/builder/rewriteTest.js new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/mod/minify/lib/min/builder/rewriteTest.js @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/mod/minify/lib/min/config.php b/mod/minify/lib/min/config.php new file mode 100644 index 000000000..00605f856 --- /dev/null +++ b/mod/minify/lib/min/config.php @@ -0,0 +1,155 @@ + + * array('//symlink' => '/real/target/path') // unix + * array('//static' => 'D:\\staticStorage') // Windows + * + */ +$min_symlinks = array(); + + +/** + * If you upload files from Windows to a non-Windows server, Windows may report + * incorrect mtimes for the files. This may cause Minify to keep serving stale + * cache files when source file changes are made too frequently (e.g. more than + * once an hour). + * + * Immediately after modifying and uploading a file, use the touch command to + * update the mtime on the server. If the mtime jumps ahead by a number of hours, + * set this variable to that number. If the mtime moves back, this should not be + * needed. + * + * In the Windows SFTP client WinSCP, there's an option that may fix this + * issue without changing the variable below. Under login > environment, + * select the option "Adjust remote timestamp with DST". + * @link http://winscp.net/eng/docs/ui_login_environment#daylight_saving_time + */ +$min_uploaderHoursBehind = 0; + + +/** + * Path to Minify's lib folder. If you happen to move it, change + * this accordingly. + */ +$min_libPath = dirname(__FILE__) . '/lib'; + + +// try to disable output_compression (may not have an effect) +ini_set('zlib.output_compression', '0'); diff --git a/mod/minify/lib/min/groupsConfig.php b/mod/minify/lib/min/groupsConfig.php new file mode 100644 index 000000000..9e2514d7a --- /dev/null +++ b/mod/minify/lib/min/groupsConfig.php @@ -0,0 +1,34 @@ + array('//js/file1.js', '//js/file2.js'), + // 'css' => array('//css/file1.css', '//css/file2.css'), + + // custom source example + /*'js2' => array( + dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + // do NOT process this file + new Minify_Source(array( + 'filepath' => dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + 'minifier' => create_function('$a', 'return $a;') + )) + ),//*/ + + /*'js3' => array( + dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + // do NOT process this file + new Minify_Source(array( + 'filepath' => dirname(__FILE__) . '/../min_unit_tests/_test_files/js/before.js', + 'minifier' => array('Minify_Packer', 'minify') + )) + ),//*/ +); \ No newline at end of file diff --git a/mod/minify/lib/min/index.php b/mod/minify/lib/min/index.php new file mode 100644 index 000000000..51c352569 --- /dev/null +++ b/mod/minify/lib/min/index.php @@ -0,0 +1,66 @@ + + * @author http://code.google.com/u/1stvamp/ (Issue 64 patch) + */ +class Minify_CSS { + + /** + * Minify a CSS string + * + * @param string $css + * + * @param array $options available options: + * + * 'preserveComments': (default true) multi-line comments that begin + * with "/*!" will be preserved with newlines before and after to + * enhance readability. + * + * 'prependRelativePath': (default null) if given, this string will be + * prepended to all relative URIs in import/url declarations + * + * 'currentDir': (default null) if given, this is assumed to be the + * directory of the current CSS file. Using this, minify will rewrite + * all relative URIs in import/url declarations to correctly point to + * the desired files. For this to work, the files *must* exist and be + * visible by the PHP process. + * + * 'symlinks': (default = array()) If the CSS file is stored in + * a symlink-ed directory, provide an array of link paths to + * target paths, where the link paths are within the document root. Because + * paths need to be normalized for this to work, use "//" to substitute + * the doc root in the link paths (the array keys). E.g.: + *
+ * array('//symlink' => '/real/target/path') // unix
+ * array('//static' => 'D:\\staticStorage') // Windows
+ *
+ *
+ * @return string
+ */
+ public static function minify($css, $options = array())
+ {
+ require_once dirname(__FILE__).'/Minify/CSS/Compressor.php';
+ if (isset($options['preserveComments'])
+ && !$options['preserveComments']) {
+ $css = Minify_CSS_Compressor::process($css, $options);
+ } else {
+ require_once 'Minify/CommentPreserver.php';
+ $css = Minify_CommentPreserver::process(
+ $css
+ ,array('Minify_CSS_Compressor', 'process')
+ ,array($options)
+ );
+ }
+ if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
+ return $css;
+ }
+ require_once 'Minify/CSS/UriRewriter.php';
+ if (isset($options['currentDir'])) {
+ return Minify_CSS_UriRewriter::rewrite(
+ $css
+ ,$options['currentDir']
+ ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
+ ,isset($options['symlinks']) ? $options['symlinks'] : array()
+ );
+ } else {
+ return Minify_CSS_UriRewriter::prepend(
+ $css
+ ,$options['prependRelativePath']
+ );
+ }
+ }
+}
diff --git a/mod/minify/lib/min/lib/FirePHP.php b/mod/minify/lib/min/lib/FirePHP.php
new file mode 100644
index 000000000..d301a641a
--- /dev/null
+++ b/mod/minify/lib/min/lib/FirePHP.php
@@ -0,0 +1,1370 @@
+
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @package FirePHP
+ */
+
+
+/**
+ * Sends the given data to the FirePHP Firefox Extension.
+ * The data can be displayed in the Firebug Console or in the
+ * "Server" request tab.
+ *
+ * For more information see: http://www.firephp.org/
+ *
+ * @copyright Copyright (C) 2007-2008 Christoph Dorn
+ * @author Christoph Dorn
+ * HTTP_ConditionalGet::check($updateTime, true); // exits if client has cache
+ * echo $content;
+ *
+ *
+ * E.g. Content from DB with no update time:
+ *
+ * $content = getContentFromDB();
+ * $cg = new HTTP_ConditionalGet(array(
+ * 'contentHash' => md5($content)
+ * ));
+ * $cg->sendHeaders();
+ * if ($cg->cacheIsValid) {
+ * exit();
+ * }
+ * echo $content;
+ *
+ *
+ * E.g. Static content with some static includes:
+ *
+ * // before content
+ * $cg = new HTTP_ConditionalGet(array(
+ * 'lastUpdateTime' => max(
+ * filemtime(__FILE__)
+ * ,filemtime('/path/to/header.inc')
+ * ,filemtime('/path/to/footer.inc')
+ * )
+ * ));
+ * $cg->sendHeaders();
+ * if ($cg->cacheIsValid) {
+ * exit();
+ * }
+ *
+ * @package Minify
+ * @subpackage HTTP
+ * @author Stephen Clay
+ * array(
+ * 'Cache-Control' => 'max-age=0, public'
+ * ,'ETag' => '"foobar"'
+ * )
+ *
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->_headers;
+ }
+
+ /**
+ * Set the Content-Length header in bytes
+ *
+ * With most PHP configs, as long as you don't flush() output, this method
+ * is not needed and PHP will buffer all output and set Content-Length for
+ * you. Otherwise you'll want to call this to let the client know up front.
+ *
+ * @param int $bytes
+ *
+ * @return int copy of input $bytes
+ */
+ public function setContentLength($bytes)
+ {
+ return $this->_headers['Content-Length'] = $bytes;
+ }
+
+ /**
+ * Send headers
+ *
+ * @see getHeaders()
+ *
+ * Note this doesn't "clear" the headers. Calling sendHeaders() will
+ * call header() again (but probably have not effect) and getHeaders() will
+ * still return the headers.
+ *
+ * @return null
+ */
+ public function sendHeaders()
+ {
+ $headers = $this->_headers;
+ if (array_key_exists('_responseCode', $headers)) {
+ header($headers['_responseCode']);
+ unset($headers['_responseCode']);
+ }
+ foreach ($headers as $name => $val) {
+ header($name . ': ' . $val);
+ }
+ }
+
+ /**
+ * Exit if the client's cache is valid for this resource
+ *
+ * This is a convenience method for common use of the class
+ *
+ * @param int $lastModifiedTime if given, both ETag AND Last-Modified headers
+ * will be sent with content. This is recommended.
+ *
+ * @param bool $isPublic (default false) if true, the Cache-Control header
+ * will contain "public", allowing proxies to cache the content. Otherwise
+ * "private" will be sent, allowing only browser caching.
+ *
+ * @param array $options (default empty) additional options for constructor
+ *
+ * @return null
+ */
+ public static function check($lastModifiedTime = null, $isPublic = false, $options = array())
+ {
+ if (null !== $lastModifiedTime) {
+ $options['lastModifiedTime'] = (int)$lastModifiedTime;
+ }
+ $options['isPublic'] = (bool)$isPublic;
+ $cg = new HTTP_ConditionalGet($options);
+ $cg->sendHeaders();
+ if ($cg->cacheIsValid) {
+ exit();
+ }
+ }
+
+
+ /**
+ * Get a GMT formatted date for use in HTTP headers
+ *
+ *
+ * header('Expires: ' . HTTP_ConditionalGet::gmtdate($time));
+ *
+ *
+ * @param int $time unix timestamp
+ *
+ * @return string
+ */
+ public static function gmtDate($time)
+ {
+ return gmdate('D, d M Y H:i:s \G\M\T', $time);
+ }
+
+ protected $_headers = array();
+ protected $_lmTime = null;
+ protected $_etag = null;
+ protected $_stripEtag = false;
+
+ protected function _setEtag($hash, $scope)
+ {
+ $this->_etag = '"' . substr($scope, 0, 3) . $hash . '"';
+ $this->_headers['ETag'] = $this->_etag;
+ }
+
+ protected function _setLastModified($time)
+ {
+ $this->_lmTime = (int)$time;
+ $this->_headers['Last-Modified'] = self::gmtDate($time);
+ }
+
+ /**
+ * Determine validity of client cache and queue 304 header if valid
+ */
+ protected function _isCacheValid()
+ {
+ if (null === $this->_etag) {
+ // lmTime is copied to ETag, so this condition implies that the
+ // server sent neither ETag nor Last-Modified, so the client can't
+ // possibly has a valid cache.
+ return false;
+ }
+ $isValid = ($this->resourceMatchedEtag() || $this->resourceNotModified());
+ if ($isValid) {
+ $this->_headers['_responseCode'] = 'HTTP/1.0 304 Not Modified';
+ }
+ return $isValid;
+ }
+
+ protected function resourceMatchedEtag()
+ {
+ if (!isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
+ return false;
+ }
+ $clientEtagList = get_magic_quotes_gpc()
+ ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])
+ : $_SERVER['HTTP_IF_NONE_MATCH'];
+ $clientEtags = explode(',', $clientEtagList);
+
+ $compareTo = $this->normalizeEtag($this->_etag);
+ foreach ($clientEtags as $clientEtag) {
+ if ($this->normalizeEtag($clientEtag) === $compareTo) {
+ // respond with the client's matched ETag, even if it's not what
+ // we would've sent by default
+ $this->_headers['ETag'] = trim($clientEtag);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected function normalizeEtag($etag) {
+ $etag = trim($etag);
+ return $this->_stripEtag
+ ? preg_replace('/;\\w\\w"$/', '"', $etag)
+ : $etag;
+ }
+
+ protected function resourceNotModified()
+ {
+ if (!isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
+ return false;
+ }
+ $ifModifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
+ if (false !== ($semicolon = strrpos($ifModifiedSince, ';'))) {
+ // IE has tacked on extra data to this header, strip it
+ $ifModifiedSince = substr($ifModifiedSince, 0, $semicolon);
+ }
+ if ($ifModifiedSince == self::gmtDate($this->_lmTime)) {
+ // Apache 2.2's behavior. If there was no ETag match, send the
+ // non-encoded version of the ETag value.
+ $this->_headers['ETag'] = $this->normalizeEtag($this->_etag);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/mod/minify/lib/min/lib/HTTP/Encoder.php b/mod/minify/lib/min/lib/HTTP/Encoder.php
new file mode 100644
index 000000000..05ca552ec
--- /dev/null
+++ b/mod/minify/lib/min/lib/HTTP/Encoder.php
@@ -0,0 +1,326 @@
+
+ * // Send a CSS file, compressed if possible
+ * $he = new HTTP_Encoder(array(
+ * 'content' => file_get_contents($cssFile)
+ * ,'type' => 'text/css'
+ * ));
+ * $he->encode();
+ * $he->sendAll();
+ *
+ *
+ *
+ * // Shortcut to encoding output
+ * header('Content-Type: text/css'); // needed if not HTML
+ * HTTP_Encoder::output($css);
+ *
+ *
+ *
+ * // Just sniff for the accepted encoding
+ * $encoding = HTTP_Encoder::getAcceptedEncoding();
+ *
+ *
+ * For more control over headers, use getHeaders() and getData() and send your
+ * own output.
+ *
+ * Note: If you don't need header mgmt, use PHP's native gzencode, gzdeflate,
+ * and gzcompress functions for gzip, deflate, and compress-encoding
+ * respectively.
+ *
+ * @package Minify
+ * @subpackage HTTP
+ * @author Stephen Clay
+ * array(
+ * 'Content-Length' => '615'
+ * ,'Content-Encoding' => 'x-gzip'
+ * ,'Vary' => 'Accept-Encoding'
+ * )
+ *
+ *
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->_headers;
+ }
+
+ /**
+ * Send output headers
+ *
+ * You must call this before headers are sent and it probably cannot be
+ * used in conjunction with zlib output buffering / mod_gzip. Errors are
+ * not handled purposefully.
+ *
+ * @see getHeaders()
+ *
+ * @return null
+ */
+ public function sendHeaders()
+ {
+ foreach ($this->_headers as $name => $val) {
+ header($name . ': ' . $val);
+ }
+ }
+
+ /**
+ * Send output headers and content
+ *
+ * A shortcut for sendHeaders() and echo getContent()
+ *
+ * You must call this before headers are sent and it probably cannot be
+ * used in conjunction with zlib output buffering / mod_gzip. Errors are
+ * not handled purposefully.
+ *
+ * @return null
+ */
+ public function sendAll()
+ {
+ $this->sendHeaders();
+ echo $this->_content;
+ }
+
+ /**
+ * Determine the client's best encoding method from the HTTP Accept-Encoding
+ * header.
+ *
+ * If no Accept-Encoding header is set, or the browser is IE before v6 SP2,
+ * this will return ('', ''), the "identity" encoding.
+ *
+ * A syntax-aware scan is done of the Accept-Encoding, so the method must
+ * be non 0. The methods are favored in order of gzip, deflate, then
+ * compress. Deflate is always smallest and generally faster, but is
+ * rarely sent by servers, so client support could be buggier.
+ *
+ * @param bool $allowCompress allow the older compress encoding
+ *
+ * @param bool $allowDeflate allow the more recent deflate encoding
+ *
+ * @return array two values, 1st is the actual encoding method, 2nd is the
+ * alias of that method to use in the Content-Encoding header (some browsers
+ * call gzip "x-gzip" etc.)
+ */
+ public static function getAcceptedEncoding($allowCompress = true, $allowDeflate = true)
+ {
+ // @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+
+ if (! isset($_SERVER['HTTP_ACCEPT_ENCODING'])
+ || self::_isBuggyIe())
+ {
+ return array('', '');
+ }
+ $ae = $_SERVER['HTTP_ACCEPT_ENCODING'];
+ // gzip checks (quick)
+ if (0 === strpos($ae, 'gzip,') // most browsers
+ || 0 === strpos($ae, 'deflate, gzip,') // opera
+ ) {
+ return array('gzip', 'gzip');
+ }
+ // gzip checks (slow)
+ if (preg_match(
+ '@(?:^|,)\\s*((?:x-)?gzip)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@'
+ ,$ae
+ ,$m)) {
+ return array('gzip', $m[1]);
+ }
+ if ($allowDeflate) {
+ // deflate checks
+ $aeRev = strrev($ae);
+ if (0 === strpos($aeRev, 'etalfed ,') // ie, webkit
+ || 0 === strpos($aeRev, 'etalfed,') // gecko
+ || 0 === strpos($ae, 'deflate,') // opera
+ // slow parsing
+ || preg_match(
+ '@(?:^|,)\\s*deflate\\s*(?:$|,|;\\s*q=(?:0\\.|1))@', $ae)) {
+ return array('deflate', 'deflate');
+ }
+ }
+ if ($allowCompress && preg_match(
+ '@(?:^|,)\\s*((?:x-)?compress)\\s*(?:$|,|;\\s*q=(?:0\\.|1))@'
+ ,$ae
+ ,$m)) {
+ return array('compress', $m[1]);
+ }
+ return array('', '');
+ }
+
+ /**
+ * Encode (compress) the content
+ *
+ * If the encode method is '' (none) or compression level is 0, or the 'zlib'
+ * extension isn't loaded, we return false.
+ *
+ * Then the appropriate gz_* function is called to compress the content. If
+ * this fails, false is returned.
+ *
+ * The header "Vary: Accept-Encoding" is added. If encoding is successful,
+ * the Content-Length header is updated, and Content-Encoding is also added.
+ *
+ * @param int $compressionLevel given to zlib functions. If not given, the
+ * class default will be used.
+ *
+ * @return bool success true if the content was actually compressed
+ */
+ public function encode($compressionLevel = null)
+ {
+ $this->_headers['Vary'] = 'Accept-Encoding';
+ if (null === $compressionLevel) {
+ $compressionLevel = self::$compressionLevel;
+ }
+ if ('' === $this->_encodeMethod[0]
+ || ($compressionLevel == 0)
+ || !extension_loaded('zlib'))
+ {
+ return false;
+ }
+ if ($this->_encodeMethod[0] === 'deflate') {
+ $encoded = gzdeflate($this->_content, $compressionLevel);
+ } elseif ($this->_encodeMethod[0] === 'gzip') {
+ $encoded = gzencode($this->_content, $compressionLevel);
+ } else {
+ $encoded = gzcompress($this->_content, $compressionLevel);
+ }
+ if (false === $encoded) {
+ return false;
+ }
+ $this->_headers['Content-Length'] = strlen($encoded);
+ $this->_headers['Content-Encoding'] = $this->_encodeMethod[1];
+ $this->_content = $encoded;
+ return true;
+ }
+
+ /**
+ * Encode and send appropriate headers and content
+ *
+ * This is a convenience method for common use of the class
+ *
+ * @param string $content
+ *
+ * @param int $compressionLevel given to zlib functions. If not given, the
+ * class default will be used.
+ *
+ * @return bool success true if the content was actually compressed
+ */
+ public static function output($content, $compressionLevel = null)
+ {
+ if (null === $compressionLevel) {
+ $compressionLevel = self::$compressionLevel;
+ }
+ $he = new HTTP_Encoder(array('content' => $content));
+ $ret = $he->encode($compressionLevel);
+ $he->sendAll();
+ return $ret;
+ }
+
+ protected $_content = '';
+ protected $_headers = array();
+ protected $_encodeMethod = array('', '');
+
+ /**
+ * Is the browser an IE version earlier than 6 SP2?
+ */
+ protected static function _isBuggyIe()
+ {
+ $ua = $_SERVER['HTTP_USER_AGENT'];
+ // quick escape for non-IEs
+ if (0 !== strpos($ua, 'Mozilla/4.0 (compatible; MSIE ')
+ || false !== strpos($ua, 'Opera')) {
+ return false;
+ }
+ // no regex = faaast
+ $version = (float)substr($ua, 30);
+ return self::$encodeToIe6
+ ? ($version < 6 || ($version == 6 && false === strpos($ua, 'SV1')))
+ : ($version < 7);
+ }
+}
diff --git a/mod/minify/lib/min/lib/JSMin.php b/mod/minify/lib/min/lib/JSMin.php
new file mode 100644
index 000000000..770e1c610
--- /dev/null
+++ b/mod/minify/lib/min/lib/JSMin.php
@@ -0,0 +1,314 @@
+ (PHP port)
+ * @author Steve Clay
+ * echo $b->uri('/site.js');
+ * // outputs "/site.js?1678242"
+ *
+ * echo $b->uri('/scriptaculous.js?load=effects');
+ * // outputs "/scriptaculous.js?load=effects&1678242"
+ *
+ *
+ * @param string $uri
+ * @param boolean $forceAmpersand (default = false) Force the use of ampersand to
+ * append the timestamp to the URI.
+ * @return string
+ */
+ public function uri($uri, $forceAmpersand = false) {
+ $sep = ($forceAmpersand || strpos($uri, '?') !== false)
+ ? self::$ampersand
+ : '?';
+ return "{$uri}{$sep}{$this->lastModified}";
+ }
+
+ /**
+ * Create a build object
+ *
+ * @param array $sources array of Minify_Source objects and/or file paths
+ *
+ * @return null
+ */
+ public function __construct($sources)
+ {
+ $max = 0;
+ foreach ((array)$sources as $source) {
+ if ($source instanceof Minify_Source) {
+ $max = max($max, $source->lastModified);
+ } elseif (is_string($source)) {
+ if (0 === strpos($source, '//')) {
+ $source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1);
+ }
+ if (is_file($source)) {
+ $max = max($max, filemtime($source));
+ }
+ }
+ }
+ $this->lastModified = $max;
+ }
+}
diff --git a/mod/minify/lib/min/lib/Minify/CSS/Compressor.php b/mod/minify/lib/min/lib/Minify/CSS/Compressor.php
new file mode 100644
index 000000000..d483b2fed
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/CSS/Compressor.php
@@ -0,0 +1,250 @@
+
+ * @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
+ */
+class Minify_CSS_Compressor {
+
+ /**
+ * Minify a CSS string
+ *
+ * @param string $css
+ *
+ * @param array $options (currently ignored)
+ *
+ * @return string
+ */
+ public static function process($css, $options = array())
+ {
+ $obj = new Minify_CSS_Compressor($options);
+ return $obj->_process($css);
+ }
+
+ /**
+ * @var array options
+ */
+ protected $_options = null;
+
+ /**
+ * @var bool Are we "in" a hack?
+ *
+ * I.e. are some browsers targetted until the next comment?
+ */
+ protected $_inHack = false;
+
+
+ /**
+ * Constructor
+ *
+ * @param array $options (currently ignored)
+ *
+ * @return null
+ */
+ private function __construct($options) {
+ $this->_options = $options;
+ }
+
+ /**
+ * Minify a CSS string
+ *
+ * @param string $css
+ *
+ * @return string
+ */
+ protected 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];
+ }
+}
diff --git a/mod/minify/lib/min/lib/Minify/CSS/UriRewriter.php b/mod/minify/lib/min/lib/Minify/CSS/UriRewriter.php
new file mode 100644
index 000000000..2b47cfc1d
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/CSS/UriRewriter.php
@@ -0,0 +1,270 @@
+
+ */
+class Minify_CSS_UriRewriter {
+
+ /**
+ * Defines which class to call as part of callbacks, change this
+ * if you extend Minify_CSS_UriRewriter
+ * @var string
+ */
+ protected static $className = 'Minify_CSS_UriRewriter';
+
+ /**
+ * rewrite() and rewriteRelative() append debugging information here
+ * @var string
+ */
+ public static $debugText = '';
+
+ /**
+ * Rewrite file relative URIs as root relative in CSS files
+ *
+ * @param string $css
+ *
+ * @param string $currentDir The directory of the current CSS file.
+ *
+ * @param string $docRoot The document root of the web site in which
+ * the CSS file resides (default = $_SERVER['DOCUMENT_ROOT']).
+ *
+ * @param array $symlinks (default = array()) If the CSS file is stored in
+ * a symlink-ed directory, provide an array of link paths to
+ * target paths, where the link paths are within the document root. Because
+ * paths need to be normalized for this to work, use "//" to substitute
+ * the doc root in the link paths (the array keys). E.g.:
+ *
+ * array('//symlink' => '/real/target/path') // unix
+ * array('//static' => 'D:\\staticStorage') // Windows
+ *
+ *
+ * @return string
+ */
+ public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array())
+ {
+ self::$_docRoot = self::_realpath(
+ $docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT']
+ );
+ self::$_currentDir = self::_realpath($currentDir);
+ self::$_symlinks = array();
+
+ // normalize symlinks
+ foreach ($symlinks as $link => $target) {
+ $link = ($link === '//')
+ ? self::$_docRoot
+ : str_replace('//', self::$_docRoot . '/', $link);
+ $link = strtr($link, '/', DIRECTORY_SEPARATOR);
+ self::$_symlinks[$link] = self::_realpath($target);
+ }
+
+ self::$debugText .= "docRoot : " . self::$_docRoot . "\n"
+ . "currentDir : " . self::$_currentDir . "\n";
+ if (self::$_symlinks) {
+ self::$debugText .= "symlinks : " . var_export(self::$_symlinks, 1) . "\n";
+ }
+ self::$debugText .= "\n";
+
+ $css = self::_trimUrls($css);
+
+ // rewrite
+ $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
+ ,array(self::$className, '_processUriCB'), $css);
+ $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
+ ,array(self::$className, '_processUriCB'), $css);
+
+ return $css;
+ }
+
+ /**
+ * Prepend a path to relative URIs in CSS files
+ *
+ * @param string $css
+ *
+ * @param string $path The path to prepend.
+ *
+ * @return string
+ */
+ public static function prepend($css, $path)
+ {
+ self::$_prependPath = $path;
+
+ $css = self::_trimUrls($css);
+
+ // append
+ $css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
+ ,array(self::$className, '_processUriCB'), $css);
+ $css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
+ ,array(self::$className, '_processUriCB'), $css);
+
+ self::$_prependPath = null;
+ return $css;
+ }
+
+
+ /**
+ * @var string directory of this stylesheet
+ */
+ private static $_currentDir = '';
+
+ /**
+ * @var string DOC_ROOT
+ */
+ private static $_docRoot = '';
+
+ /**
+ * @var array directory replacements to map symlink targets back to their
+ * source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
+ */
+ private static $_symlinks = array();
+
+ /**
+ * @var string path to prepend
+ */
+ private static $_prependPath = null;
+
+ private static function _trimUrls($css)
+ {
+ return preg_replace('/
+ url\\( # url(
+ \\s*
+ ([^\\)]+?) # 1 = URI (assuming does not contain ")")
+ \\s*
+ \\) # )
+ /x', 'url($1)', $css);
+ }
+
+ private static function _processUriCB($m)
+ {
+ // $m matched either '/@import\\s+([\'"])(.*?)[\'"]/' or '/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
+ $isImport = ($m[0][0] === '@');
+ // determine URI and the quote character (if any)
+ if ($isImport) {
+ $quoteChar = $m[1];
+ $uri = $m[2];
+ } else {
+ // $m[1] is either quoted or not
+ $quoteChar = ($m[1][0] === "'" || $m[1][0] === '"')
+ ? $m[1][0]
+ : '';
+ $uri = ($quoteChar === '')
+ ? $m[1]
+ : substr($m[1], 1, strlen($m[1]) - 2);
+ }
+ // analyze URI
+ if ('/' !== $uri[0] // root-relative
+ && false === strpos($uri, '//') // protocol (non-data)
+ && 0 !== strpos($uri, 'data:') // data protocol
+ ) {
+ // URI is file-relative: rewrite depending on options
+ $uri = (self::$_prependPath !== null)
+ ? (self::$_prependPath . $uri)
+ : self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks);
+ }
+ return $isImport
+ ? "@import {$quoteChar}{$uri}{$quoteChar}"
+ : "url({$quoteChar}{$uri}{$quoteChar})";
+ }
+
+ /**
+ * Rewrite a file relative URI as root relative
+ *
+ *
+ * Minify_CSS_UriRewriter::rewriteRelative(
+ * '../img/hello.gif'
+ * , '/home/user/www/css' // path of CSS file
+ * , '/home/user/www' // doc root
+ * );
+ * // returns '/img/hello.gif'
+ *
+ * // example where static files are stored in a symlinked directory
+ * Minify_CSS_UriRewriter::rewriteRelative(
+ * 'hello.gif'
+ * , '/var/staticFiles/theme'
+ * , '/home/user/www'
+ * , array('/home/user/www/static' => '/var/staticFiles')
+ * );
+ * // returns '/static/theme/hello.gif'
+ *
+ *
+ * @param string $uri file relative URI
+ *
+ * @param string $realCurrentDir realpath of the current file's directory.
+ *
+ * @param string $realDocRoot realpath of the site document root.
+ *
+ * @param array $symlinks (default = array()) If the file is stored in
+ * a symlink-ed directory, provide an array of link paths to
+ * real target paths, where the link paths "appear" to be within the document
+ * root. E.g.:
+ *
+ * array('/home/foo/www/not/real/path' => '/real/target/path') // unix
+ * array('C:\\htdocs\\not\\real' => 'D:\\real\\target\\path') // Windows
+ *
+ *
+ * @return string
+ */
+ public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array())
+ {
+ // prepend path with current dir separator (OS-independent)
+ $path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR)
+ . DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);
+
+ self::$debugText .= "file-relative URI : {$uri}\n"
+ . "path prepended : {$path}\n";
+
+ // "unresolve" a symlink back to doc root
+ foreach ($symlinks as $link => $target) {
+ if (0 === strpos($path, $target)) {
+ // replace $target with $link
+ $path = $link . substr($path, strlen($target));
+
+ self::$debugText .= "symlink unresolved : {$path}\n";
+
+ break;
+ }
+ }
+ // strip doc root
+ $path = substr($path, strlen($realDocRoot));
+
+ self::$debugText .= "docroot stripped : {$path}\n";
+
+ // fix to root-relative URI
+
+ $uri = strtr($path, '/\\', '//');
+
+ // remove /./ and /../ where possible
+ $uri = str_replace('/./', '/', $uri);
+ // inspired by patch from Oleg Cherniy
+ do {
+ $uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, 1, $changed);
+ } while ($changed);
+
+ self::$debugText .= "traversals removed : {$uri}\n\n";
+
+ return $uri;
+ }
+
+ /**
+ * Get realpath with any trailing slash removed. If realpath() fails,
+ * just remove the trailing slash.
+ *
+ * @param string $path
+ *
+ * @return mixed path with no trailing slash
+ */
+ protected static function _realpath($path)
+ {
+ $realPath = realpath($path);
+ if ($realPath !== false) {
+ $path = $realPath;
+ }
+ return rtrim($path, '/\\');
+ }
+}
diff --git a/mod/minify/lib/min/lib/Minify/Cache/APC.php b/mod/minify/lib/min/lib/Minify/Cache/APC.php
new file mode 100644
index 000000000..ca84d2998
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/Cache/APC.php
@@ -0,0 +1,130 @@
+
+ * Minify::setCache(new Minify_Cache_APC());
+ *
+ *
+ * @package Minify
+ * @author Chris Edwards
+ **/
+class Minify_Cache_APC {
+
+ /**
+ * Create a Minify_Cache_APC object, to be passed to
+ * Minify::setCache().
+ *
+ *
+ * @param int $expire seconds until expiration (default = 0
+ * meaning the item will not get an expiration date)
+ *
+ * @return null
+ */
+ public function __construct($expire = 0)
+ {
+ $this->_exp = $expire;
+ }
+
+ /**
+ * Write data to cache.
+ *
+ * @param string $id cache id
+ *
+ * @param string $data
+ *
+ * @return bool success
+ */
+ public function store($id, $data)
+ {
+ return apc_store($id, "{$_SERVER['REQUEST_TIME']}|{$data}", $this->_exp);
+ }
+
+ /**
+ * Get the size of a cache entry
+ *
+ * @param string $id cache id
+ *
+ * @return int size in bytes
+ */
+ public function getSize($id)
+ {
+ return $this->_fetch($id)
+ ? strlen($this->_data)
+ : false;
+ }
+
+ /**
+ * Does a valid cache entry exist?
+ *
+ * @param string $id cache id
+ *
+ * @param int $srcMtime mtime of the original source file(s)
+ *
+ * @return bool exists
+ */
+ public function isValid($id, $srcMtime)
+ {
+ return ($this->_fetch($id) && ($this->_lm >= $srcMtime));
+ }
+
+ /**
+ * Send the cached content to output
+ *
+ * @param string $id cache id
+ */
+ public function display($id)
+ {
+ echo $this->_fetch($id)
+ ? $this->_data
+ : '';
+ }
+
+ /**
+ * Fetch the cached content
+ *
+ * @param string $id cache id
+ *
+ * @return string
+ */
+ public function fetch($id)
+ {
+ return $this->_fetch($id)
+ ? $this->_data
+ : '';
+ }
+
+ private $_exp = null;
+
+ // cache of most recently fetched id
+ private $_lm = null;
+ private $_data = null;
+ private $_id = null;
+
+ /**
+ * Fetch data and timestamp from apc, store in instance
+ *
+ * @param string $id
+ *
+ * @return bool success
+ */
+ private function _fetch($id)
+ {
+ if ($this->_id === $id) {
+ return true;
+ }
+ $ret = apc_fetch($id);
+ if (false === $ret) {
+ $this->_id = null;
+ return false;
+ }
+ list($this->_lm, $this->_data) = explode('|', $ret, 2);
+ $this->_id = $id;
+ return true;
+ }
+}
diff --git a/mod/minify/lib/min/lib/Minify/Cache/File.php b/mod/minify/lib/min/lib/Minify/Cache/File.php
new file mode 100644
index 000000000..2753e6b8e
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/Cache/File.php
@@ -0,0 +1,125 @@
+_locking = $fileLocking;
+ $this->_path = $path;
+ }
+
+ /**
+ * Write data to cache.
+ *
+ * @param string $id cache id (e.g. a filename)
+ *
+ * @param string $data
+ *
+ * @return bool success
+ */
+ public function store($id, $data)
+ {
+ $flag = $this->_locking
+ ? LOCK_EX
+ : null;
+ if (is_file($this->_path . '/' . $id)) {
+ @unlink($this->_path . '/' . $id);
+ }
+ if (! @file_put_contents($this->_path . '/' . $id, $data, $flag)) {
+ return false;
+ }
+ // write control
+ if ($data !== $this->fetch($id)) {
+ @unlink($file);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Get the size of a cache entry
+ *
+ * @param string $id cache id (e.g. a filename)
+ *
+ * @return int size in bytes
+ */
+ public function getSize($id)
+ {
+ return filesize($this->_path . '/' . $id);
+ }
+
+ /**
+ * Does a valid cache entry exist?
+ *
+ * @param string $id cache id (e.g. a filename)
+ *
+ * @param int $srcMtime mtime of the original source file(s)
+ *
+ * @return bool exists
+ */
+ public function isValid($id, $srcMtime)
+ {
+ $file = $this->_path . '/' . $id;
+ return (is_file($file) && (filemtime($file) >= $srcMtime));
+ }
+
+ /**
+ * Send the cached content to output
+ *
+ * @param string $id cache id (e.g. a filename)
+ */
+ public function display($id)
+ {
+ if ($this->_locking) {
+ $fp = fopen($this->_path . '/' . $id, 'rb');
+ flock($fp, LOCK_SH);
+ fpassthru($fp);
+ flock($fp, LOCK_UN);
+ fclose($fp);
+ } else {
+ readfile($this->_path . '/' . $id);
+ }
+ }
+
+ /**
+ * Fetch the cached content
+ *
+ * @param string $id cache id (e.g. a filename)
+ *
+ * @return string
+ */
+ public function fetch($id)
+ {
+ if ($this->_locking) {
+ $fp = fopen($this->_path . '/' . $id, 'rb');
+ flock($fp, LOCK_SH);
+ $ret = stream_get_contents($fp);
+ flock($fp, LOCK_UN);
+ fclose($fp);
+ return $ret;
+ } else {
+ return file_get_contents($this->_path . '/' . $id);
+ }
+ }
+
+ /**
+ * Fetch the cache path used
+ *
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->_path;
+ }
+
+ private $_path = null;
+ private $_locking = null;
+}
diff --git a/mod/minify/lib/min/lib/Minify/Cache/Memcache.php b/mod/minify/lib/min/lib/Minify/Cache/Memcache.php
new file mode 100644
index 000000000..2b81e7a32
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/Cache/Memcache.php
@@ -0,0 +1,137 @@
+
+ * // fall back to disk caching if memcache can't connect
+ * $memcache = new Memcache;
+ * if ($memcache->connect('localhost', 11211)) {
+ * Minify::setCache(new Minify_Cache_Memcache($memcache));
+ * } else {
+ * Minify::setCache();
+ * }
+ *
+ **/
+class Minify_Cache_Memcache {
+
+ /**
+ * Create a Minify_Cache_Memcache object, to be passed to
+ * Minify::setCache().
+ *
+ * @param Memcache $memcache already-connected instance
+ *
+ * @param int $expire seconds until expiration (default = 0
+ * meaning the item will not get an expiration date)
+ *
+ * @return null
+ */
+ public function __construct($memcache, $expire = 0)
+ {
+ $this->_mc = $memcache;
+ $this->_exp = $expire;
+ }
+
+ /**
+ * Write data to cache.
+ *
+ * @param string $id cache id
+ *
+ * @param string $data
+ *
+ * @return bool success
+ */
+ public function store($id, $data)
+ {
+ return $this->_mc->set($id, "{$_SERVER['REQUEST_TIME']}|{$data}", 0, $this->_exp);
+ }
+
+
+ /**
+ * Get the size of a cache entry
+ *
+ * @param string $id cache id
+ *
+ * @return int size in bytes
+ */
+ public function getSize($id)
+ {
+ return $this->_fetch($id)
+ ? strlen($this->_data)
+ : false;
+ }
+
+ /**
+ * Does a valid cache entry exist?
+ *
+ * @param string $id cache id
+ *
+ * @param int $srcMtime mtime of the original source file(s)
+ *
+ * @return bool exists
+ */
+ public function isValid($id, $srcMtime)
+ {
+ return ($this->_fetch($id) && ($this->_lm >= $srcMtime));
+ }
+
+ /**
+ * Send the cached content to output
+ *
+ * @param string $id cache id
+ */
+ public function display($id)
+ {
+ echo $this->_fetch($id)
+ ? $this->_data
+ : '';
+ }
+
+ /**
+ * Fetch the cached content
+ *
+ * @param string $id cache id
+ *
+ * @return string
+ */
+ public function fetch($id)
+ {
+ return $this->_fetch($id)
+ ? $this->_data
+ : '';
+ }
+
+ private $_mc = null;
+ private $_exp = null;
+
+ // cache of most recently fetched id
+ private $_lm = null;
+ private $_data = null;
+ private $_id = null;
+
+ /**
+ * Fetch data and timestamp from memcache, store in instance
+ *
+ * @param string $id
+ *
+ * @return bool success
+ */
+ private function _fetch($id)
+ {
+ if ($this->_id === $id) {
+ return true;
+ }
+ $ret = $this->_mc->get($id);
+ if (false === $ret) {
+ $this->_id = null;
+ return false;
+ }
+ list($this->_lm, $this->_data) = explode('|', $ret, 2);
+ $this->_id = $id;
+ return true;
+ }
+}
diff --git a/mod/minify/lib/min/lib/Minify/CommentPreserver.php b/mod/minify/lib/min/lib/Minify/CommentPreserver.php
new file mode 100644
index 000000000..f56eb3461
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/CommentPreserver.php
@@ -0,0 +1,90 @@
+
+ */
+class Minify_CommentPreserver {
+
+ /**
+ * String to be prepended to each preserved comment
+ *
+ * @var string
+ */
+ public static $prepend = "\n";
+
+ /**
+ * String to be appended to each preserved comment
+ *
+ * @var string
+ */
+ public static $append = "\n";
+
+ /**
+ * Process a string outside of C-style comments that begin with "/*!"
+ *
+ * On each non-empty string outside these comments, the given processor
+ * function will be called. The first "!" will be removed from the
+ * preserved comments, and the comments will be surrounded by
+ * Minify_CommentPreserver::$preprend and Minify_CommentPreserver::$append.
+ *
+ * @param string $content
+ * @param callback $processor function
+ * @param array $args array of extra arguments to pass to the processor
+ * function (default = array())
+ * @return string
+ */
+ public static function process($content, $processor, $args = array())
+ {
+ $ret = '';
+ while (true) {
+ list($beforeComment, $comment, $afterComment) = self::_nextComment($content);
+ if ('' !== $beforeComment) {
+ $callArgs = $args;
+ array_unshift($callArgs, $beforeComment);
+ $ret .= call_user_func_array($processor, $callArgs);
+ }
+ if (false === $comment) {
+ break;
+ }
+ $ret .= $comment;
+ $content = $afterComment;
+ }
+ return $ret;
+ }
+
+ /**
+ * Extract comments that YUI Compressor preserves.
+ *
+ * @param string $in input
+ *
+ * @return array 3 elements are returned. If a YUI comment is found, the
+ * 2nd element is the comment and the 1st and 2nd are the surrounding
+ * strings. If no comment is found, the entire string is returned as the
+ * 1st element and the other two are false.
+ */
+ private static function _nextComment($in)
+ {
+ if (
+ false === ($start = strpos($in, '/*!'))
+ || false === ($end = strpos($in, '*/', $start + 3))
+ ) {
+ return array($in, false, false);
+ }
+ $ret = array(
+ substr($in, 0, $start)
+ ,self::$prepend . '/*' . substr($in, $start + 3, $end - $start - 1) . self::$append
+ );
+ $endChars = (strlen($in) - $end - 2);
+ $ret[] = (0 === $endChars)
+ ? ''
+ : substr($in, -$endChars);
+ return $ret;
+ }
+}
diff --git a/mod/minify/lib/min/lib/Minify/Controller/Base.php b/mod/minify/lib/min/lib/Minify/Controller/Base.php
new file mode 100644
index 000000000..84889b3f0
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/Controller/Base.php
@@ -0,0 +1,202 @@
+
+ */
+abstract class Minify_Controller_Base {
+
+ /**
+ * Setup controller sources and set an needed options for Minify::source
+ *
+ * You must override this method in your subclass controller to set
+ * $this->sources. If the request is NOT valid, make sure $this->sources
+ * is left an empty array. Then strip any controller-specific options from
+ * $options and return it. To serve files, $this->sources must be an array of
+ * Minify_Source objects.
+ *
+ * @param array $options controller and Minify options
+ *
+ * return array $options Minify::serve options
+ */
+ abstract public function setupSources($options);
+
+ /**
+ * Get default Minify options for this controller.
+ *
+ * Override in subclass to change defaults
+ *
+ * @return array options for Minify
+ */
+ public function getDefaultMinifyOptions() {
+ return array(
+ 'isPublic' => true
+ ,'encodeOutput' => function_exists('gzdeflate')
+ ,'encodeMethod' => null // determine later
+ ,'encodeLevel' => 9
+ ,'minifierOptions' => array() // no minifier options
+ ,'contentTypeCharset' => 'utf-8'
+ ,'maxAge' => 1800 // 30 minutes
+ ,'rewriteCssUris' => true
+ ,'bubbleCssImports' => false
+ ,'quiet' => false // serve() will send headers and output
+ ,'debug' => false
+
+ // if you override this, the response code MUST be directly after
+ // the first space.
+ ,'badRequestHeader' => 'HTTP/1.0 400 Bad Request'
+
+ // callback function to see/modify content of all sources
+ ,'postprocessor' => null
+ // file to require to load preprocessor
+ ,'postprocessorRequire' => null
+ );
+ }
+
+ /**
+ * Get default minifiers for this controller.
+ *
+ * Override in subclass to change defaults
+ *
+ * @return array minifier callbacks for common types
+ */
+ public function getDefaultMinifers() {
+ $ret[Minify::TYPE_JS] = array('JSMin', 'minify');
+ $ret[Minify::TYPE_CSS] = array('Minify_CSS', 'minify');
+ $ret[Minify::TYPE_HTML] = array('Minify_HTML', 'minify');
+ return $ret;
+ }
+
+ /**
+ * Load any code necessary to execute the given minifier callback.
+ *
+ * The controller is responsible for loading minification code on demand
+ * via this method. This built-in function will only load classes for
+ * static method callbacks where the class isn't already defined. It uses
+ * the PEAR convention, so, given array('Jimmy_Minifier', 'minCss'), this
+ * function will include 'Jimmy/Minifier.php'.
+ *
+ * If you need code loaded on demand and this doesn't suit you, you'll need
+ * to override this function in your subclass.
+ * @see Minify_Controller_Page::loadMinifier()
+ *
+ * @param callback $minifierCallback callback of minifier function
+ *
+ * @return null
+ */
+ public function loadMinifier($minifierCallback)
+ {
+ if (is_array($minifierCallback)
+ && is_string($minifierCallback[0])
+ && !class_exists($minifierCallback[0], false)) {
+
+ require str_replace('_', '/', $minifierCallback[0]) . '.php';
+ }
+ }
+
+ /**
+ * Is a user-given file within an allowable directory, existing,
+ * and having an extension js/css/html/txt ?
+ *
+ * This is a convenience function for controllers that have to accept
+ * user-given paths
+ *
+ * @param string $file full file path (already processed by realpath())
+ *
+ * @param array $safeDirs directories where files are safe to serve. Files can also
+ * be in subdirectories of these directories.
+ *
+ * @return bool file is safe
+ */
+ public static function _fileIsSafe($file, $safeDirs)
+ {
+ $pathOk = false;
+ foreach ((array)$safeDirs as $safeDir) {
+ if (strpos($file, $safeDir) === 0) {
+ $pathOk = true;
+ break;
+ }
+ }
+ $base = basename($file);
+ if (! $pathOk || ! is_file($file) || $base[0] === '.') {
+ return false;
+ }
+ list($revExt) = explode('.', strrev($base));
+ return in_array(strrev($revExt), array('js', 'css', 'html', 'txt'));
+ }
+
+ /**
+ * @var array instances of Minify_Source, which provide content and
+ * any individual minification needs.
+ *
+ * @see Minify_Source
+ */
+ public $sources = array();
+
+ /**
+ * Mix in default controller options with user-given options
+ *
+ * @param array $options user options
+ *
+ * @return array mixed options
+ */
+ public final function mixInDefaultOptions($options)
+ {
+ $ret = array_merge(
+ $this->getDefaultMinifyOptions(), $options
+ );
+ if (! isset($options['minifiers'])) {
+ $options['minifiers'] = array();
+ }
+ $ret['minifiers'] = array_merge(
+ $this->getDefaultMinifers(), $options['minifiers']
+ );
+ return $ret;
+ }
+
+ /**
+ * Analyze sources (if there are any) and set $options 'contentType'
+ * and 'lastModifiedTime' if they already aren't.
+ *
+ * @param array $options options for Minify
+ *
+ * @return array options for Minify
+ */
+ public final function analyzeSources($options = array())
+ {
+ if ($this->sources) {
+ if (! isset($options['contentType'])) {
+ $options['contentType'] = Minify_Source::getContentType($this->sources);
+ }
+ // last modified is needed for caching, even if setExpires is set
+ if (! isset($options['lastModifiedTime'])) {
+ $max = 0;
+ foreach ($this->sources as $source) {
+ $max = max($source->lastModified, $max);
+ }
+ $options['lastModifiedTime'] = $max;
+ }
+ }
+ return $options;
+ }
+
+ /**
+ * Send message to the Minify logger
+ * @param string $msg
+ * @return null
+ */
+ protected function log($msg) {
+ require_once 'Minify/Logger.php';
+ Minify_Logger::log($msg);
+ }
+}
diff --git a/mod/minify/lib/min/lib/Minify/Controller/Files.php b/mod/minify/lib/min/lib/Minify/Controller/Files.php
new file mode 100644
index 000000000..83f028adf
--- /dev/null
+++ b/mod/minify/lib/min/lib/Minify/Controller/Files.php
@@ -0,0 +1,78 @@
+
+ * Minify::serve('Files', array(
+ * 'files' => array(
+ * '//js/jquery.js'
+ * ,'//js/plugins.js'
+ * ,'/home/username/file.js'
+ * )
+ * ));
+ *
+ *
+ * As a shortcut, the controller will replace "//" at the beginning
+ * of a filename with $_SERVER['DOCUMENT_ROOT'] . '/'.
+ *
+ * @package Minify
+ * @author Stephen Clay
+ * // simplistic HTML cache system
+ * $file = '/path/to/cache/file';
+ * if (! file_exists($file) || filemtime($file) < Minify_groupsMtime(array('js', 'css'))) {
+ * // (re)build cache
+ * $page = buildPage(); // this calls Minify_groupUri() for js and css
+ * file_put_contents($file, $page);
+ * echo $page;
+ * exit();
+ * }
+ * readfile($file);
+ *
+ *
+ * @param array $groups an array of keys from groupsConfig.php
+ * @return int Unix timestamp of the latest modification
+ */
+function Minify_groupsMtime($groups)
+{
+ $max = 0;
+ foreach ((array)$groups as $group) {
+ $max = max($max, _Minify_getBuild($group)->lastModified);
+ }
+ return $max;
+}
+
+/**
+ * @param string $group a key from groupsConfig.php
+ * @return Minify_Build
+ * @private
+ */
+function _Minify_getBuild($group)
+{
+ static $builds = array();
+ static $gc = false;
+ if (false === $gc) {
+ $gc = (require dirname(__FILE__) . '/groupsConfig.php');
+ }
+ if (! isset($builds[$group])) {
+ $builds[$group] = new Minify_Build($gc[$group]);
+ }
+ return $builds[$group];
+}
diff --git a/mod/minify/manifest.xml b/mod/minify/manifest.xml
new file mode 100644
index 000000000..0ae6dde24
--- /dev/null
+++ b/mod/minify/manifest.xml
@@ -0,0 +1,13 @@
+
++ +
+ ++ $foo) { + if ($i > 0) { + echo " | "; + } +?> + | + + | + | "; + } + $fields .= <<< END + | + + | +END; + $i++; + } + +?> +
+ + name; ?> + + |
+
+ + |
- -
- -- $foo) { - if ($i > 0) { - echo " | "; - } -?> - | - - | - | "; - } - $fields .= <<< END - | - - | -END; - $i++; - } - -?> -
- - name; ?> - - |
-
- - |
";
- $form_body .= elgg_echo('installation:' . $field) . "
";
- $warning = elgg_echo('installation:warning:' . $field);
- if ($warning != 'installation:warning:' . $field) {
- echo "" . $warning . "
";
- }
- $value = elgg_get_config($field);
- $form_body .= elgg_view("input/text",array('internalname' => $field, 'value' => $value));
- $form_body .= "
" . elgg_echo('admin:site:access:warning') . "
";
-$form_body .= elgg_echo('installation:sitepermissions');
-$form_body .= elgg_view('input/access', array(
- 'internalname' => 'default_access',
- 'value' => elgg_get_config('default_access'),
-)) . "
" . elgg_echo('installation:allow_user_default_access:description') . "
";
-$form_body .= elgg_view("input/checkboxes", array(
- 'options' => array(elgg_echo('installation:allow_user_default_access:label')),
- 'internalname' => 'allow_user_default_access',
- 'value' => (elgg_get_config('allow_user_default_access') ? elgg_echo('installation:allow_user_default_access:label') : ""),
-)) . "
" . elgg_echo('installation:simplecache:description') . "
";
-$form_body .= elgg_view("input/checkboxes", array(
- 'options' => array(elgg_echo('installation:simplecache:label')),
- 'internalname' => 'simplecache_enabled',
- 'value' => (elgg_get_config('simplecache_enabled') ? elgg_echo('installation:simplecache:label') : ""),
-)) . "
" . elgg_echo('installation:viewpathcache:description') . "
";
-$form_body .= elgg_view("input/checkboxes", array(
- 'options' => array(elgg_echo('installation:viewpathcache:label')),
- 'internalname' => 'viewpath_cache_enabled',
- 'value' => (elgg_get_config('viewpath_cache_enabled') ? elgg_echo('installation:viewpathcache:label') : ""),
-)) . "
" . elgg_echo('installation:debug'); -$form_body .= elgg_view('input/dropdown', array( - 'options_values' => $debug_options, - 'internalname' => 'debug', - 'value' => elgg_get_config('debug'), -)); -$form_body .= '
'; - -// control new user registration -$options = array( - 'options' => array(elgg_echo('installation:registration:label')), - 'internalname' => 'allow_registration', - 'value' => elgg_get_config('allow_registration') ? elgg_echo('installation:registration:label') : '', -); -$form_body .= '' . elgg_echo('installation:registration:description');
-$form_body .= '
' .elgg_view('input/checkboxes', $options) . '
' . elgg_echo('installation:walled_garden:description');
-$form_body .= '
' . elgg_view('input/checkboxes', $options) . '
" . elgg_echo('installation:httpslogin') . "
";
-$form_body .= elgg_view("input/checkboxes", array(
- 'options' => array(elgg_echo('installation:httpslogin:label')),
- 'internalname' => 'https_login',
- 'value' => (elgg_get_config('https_login') ? elgg_echo('installation:httpslogin:label') : "")
-)) . "
" . elgg_echo('installation:disableapi') . "
";
-$on = elgg_echo('installation:disableapi:label');
-$disable_api = elgg_get_config('disable_api');
-if ($disable_api) {
- $on = (disable_api ? "" : elgg_echo('installation:disableapi:label'));
-}
-$form_body .= elgg_view("input/checkboxes", array(
- 'options' => array(elgg_echo('installation:disableapi:label')),
- 'internalname' => 'api',
- 'value' => $on,
-));
-$form_body .= "
'; -$form_body .= elgg_view('input/submit', array('value' => elgg_echo("save"))); -$form_body .= '
'; -$form_body = "";
- $form_body .= elgg_echo('installation:' . $field) . "
";
- $warning = elgg_echo('installation:warning:' . $field);
- if ($warning != 'installation:warning:' . $field) {
- echo "" . $warning . "
";
- }
- $value = elgg_get_config($field);
- $form_body .= elgg_view("input/text",array('internalname' => $field, 'value' => $value));
- $form_body .= "
" . elgg_echo('installation:language'); -$form_body .= elgg_view("input/dropdown", array( - 'internalname' => 'language', - 'value' => elgg_get_config('language'), - 'options_values' => $languages, -)) . "
"; - -$form_body .= ''; -$form_body .= elgg_view('input/submit', array('value' => elgg_echo("save"))); -$form_body .= '
'; -$form_body = "