bixbite 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +49 -0
- data/VERSION +1 -0
- data/bin/bixbite +73 -0
- data/lib/bixbite.rb +13 -0
- data/lib/bixbite/command.rb +14 -0
- data/lib/bixbite/create.rb +76 -0
- data/template/Rakefile +25 -0
- data/template/assets/bixbite/Rakefile.rb +297 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
- data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
- data/template/assets/utilities/pngout +0 -0
- data/template/deploy/public_html/.htaccess +0 -0
- data/template/documentation/js/.htaccess +0 -0
- data/template/src/html/.htaccess +76 -0
- data/template/src/html/css/cmn/global.css +96 -0
- data/template/src/html/css/cmn/ie.css +15 -0
- data/template/src/html/css/cmn/ie6.css +15 -0
- data/template/src/html/images/cmn/.htaccess +0 -0
- data/template/src/html/images/tmp/.htaccess +0 -0
- data/template/src/html/includes/debug.inc +5 -0
- data/template/src/html/includes/footer.inc +52 -0
- data/template/src/html/includes/header.inc +61 -0
- data/template/src/html/includes/html.inc +3 -0
- data/template/src/html/includes/namespace.inc +19 -0
- data/template/src/html/includes/page.inc +151 -0
- data/template/src/html/index.html +35 -0
- data/template/src/html/js/cmn/bootstrap.js +74 -0
- data/template/src/html/js/cmn/global.js +142 -0
- data/template/src/html/js/cmn/lib/LAB.js +348 -0
- data/template/src/html/min/.htaccess +4 -0
- data/template/src/html/min/MinifyCLI.php +19 -0
- data/template/src/html/min/README.txt +132 -0
- data/template/src/html/min/builder/_index.js +242 -0
- data/template/src/html/min/builder/bm.js +36 -0
- data/template/src/html/min/builder/index.php +182 -0
- data/template/src/html/min/builder/ocCheck.php +36 -0
- data/template/src/html/min/builder/rewriteTest.js +1 -0
- data/template/src/html/min/config.php +187 -0
- data/template/src/html/min/groupsConfig.php +34 -0
- data/template/src/html/min/index.php +66 -0
- data/template/src/html/min/lib/FirePHP.php +1370 -0
- data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
- data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
- data/template/src/html/min/lib/JSMin.php +314 -0
- data/template/src/html/min/lib/JSMinPlus.php +1872 -0
- data/template/src/html/min/lib/Minify.php +532 -0
- data/template/src/html/min/lib/Minify/Build.php +103 -0
- data/template/src/html/min/lib/Minify/CSS.php +83 -0
- data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
- data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
- data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
- data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
- data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
- data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
- data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
- data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
- data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
- data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
- data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
- data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
- data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
- data/template/src/html/min/lib/Minify/HTML.php +245 -0
- data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
- data/template/src/html/min/lib/Minify/Lines.php +131 -0
- data/template/src/html/min/lib/Minify/Logger.php +45 -0
- data/template/src/html/min/lib/Minify/Packer.php +37 -0
- data/template/src/html/min/lib/Minify/Source.php +187 -0
- data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
- data/template/src/html/min/lib/Solar/Dir.php +199 -0
- data/template/src/html/min/lib/closure-compiler.jar +0 -0
- data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
- data/template/src/html/min/utils.php +90 -0
- data/template/src/templates/css/template.css +7 -0
- data/template/src/templates/js/template.js +72 -0
- data/template/src/templates/template.html +18 -0
- data/template/src/yaml/config.yml +46 -0
- data/template/src/yaml/deploy.yml +35 -0
- data/test/bixbite_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +278 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_Build
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
require_once 'Minify/Source.php';
|
8
|
+
|
9
|
+
/**
|
10
|
+
* Maintain a single last modification time for a group of Minify sources to
|
11
|
+
* allow use of far off Expires headers in Minify.
|
12
|
+
*
|
13
|
+
* <code>
|
14
|
+
* // in config file
|
15
|
+
* $groupSources = array(
|
16
|
+
* 'js' => array('file1.js', 'file2.js')
|
17
|
+
* ,'css' => array('file1.css', 'file2.css', 'file3.css')
|
18
|
+
* )
|
19
|
+
*
|
20
|
+
* // during HTML generation
|
21
|
+
* $jsBuild = new Minify_Build($groupSources['js']);
|
22
|
+
* $cssBuild = new Minify_Build($groupSources['css']);
|
23
|
+
*
|
24
|
+
* $script = "<script type='text/javascript' src='"
|
25
|
+
* . $jsBuild->uri('/min.php/js') . "'></script>";
|
26
|
+
* $link = "<link rel='stylesheet' type='text/css' href='"
|
27
|
+
* . $cssBuild->uri('/min.php/css') . "'>";
|
28
|
+
*
|
29
|
+
* // in min.php
|
30
|
+
* Minify::serve('Groups', array(
|
31
|
+
* 'groups' => $groupSources
|
32
|
+
* ,'setExpires' => (time() + 86400 * 365)
|
33
|
+
* ));
|
34
|
+
* </code>
|
35
|
+
*
|
36
|
+
* @package Minify
|
37
|
+
* @author Stephen Clay <steve@mrclay.org>
|
38
|
+
*/
|
39
|
+
class Minify_Build {
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Last modification time of all files in the build
|
43
|
+
*
|
44
|
+
* @var int
|
45
|
+
*/
|
46
|
+
public $lastModified = 0;
|
47
|
+
|
48
|
+
/**
|
49
|
+
* String to use as ampersand in uri(). Set this to '&' if
|
50
|
+
* you are not HTML-escaping URIs.
|
51
|
+
*
|
52
|
+
* @var string
|
53
|
+
*/
|
54
|
+
public static $ampersand = '&';
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Get a time-stamped URI
|
58
|
+
*
|
59
|
+
* <code>
|
60
|
+
* echo $b->uri('/site.js');
|
61
|
+
* // outputs "/site.js?1678242"
|
62
|
+
*
|
63
|
+
* echo $b->uri('/scriptaculous.js?load=effects');
|
64
|
+
* // outputs "/scriptaculous.js?load=effects&1678242"
|
65
|
+
* </code>
|
66
|
+
*
|
67
|
+
* @param string $uri
|
68
|
+
* @param boolean $forceAmpersand (default = false) Force the use of ampersand to
|
69
|
+
* append the timestamp to the URI.
|
70
|
+
* @return string
|
71
|
+
*/
|
72
|
+
public function uri($uri, $forceAmpersand = false) {
|
73
|
+
$sep = ($forceAmpersand || strpos($uri, '?') !== false)
|
74
|
+
? self::$ampersand
|
75
|
+
: '?';
|
76
|
+
return "{$uri}{$sep}{$this->lastModified}";
|
77
|
+
}
|
78
|
+
|
79
|
+
/**
|
80
|
+
* Create a build object
|
81
|
+
*
|
82
|
+
* @param array $sources array of Minify_Source objects and/or file paths
|
83
|
+
*
|
84
|
+
* @return null
|
85
|
+
*/
|
86
|
+
public function __construct($sources)
|
87
|
+
{
|
88
|
+
$max = 0;
|
89
|
+
foreach ((array)$sources as $source) {
|
90
|
+
if ($source instanceof Minify_Source) {
|
91
|
+
$max = max($max, $source->lastModified);
|
92
|
+
} elseif (is_string($source)) {
|
93
|
+
if (0 === strpos($source, '//')) {
|
94
|
+
$source = $_SERVER['DOCUMENT_ROOT'] . substr($source, 1);
|
95
|
+
}
|
96
|
+
if (is_file($source)) {
|
97
|
+
$max = max($max, filemtime($source));
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
$this->lastModified = $max;
|
102
|
+
}
|
103
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_CSS
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Minify CSS
|
9
|
+
*
|
10
|
+
* This class uses Minify_CSS_Compressor and Minify_CSS_UriRewriter to
|
11
|
+
* minify CSS and rewrite relative URIs.
|
12
|
+
*
|
13
|
+
* @package Minify
|
14
|
+
* @author Stephen Clay <steve@mrclay.org>
|
15
|
+
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
16
|
+
*/
|
17
|
+
class Minify_CSS {
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Minify a CSS string
|
21
|
+
*
|
22
|
+
* @param string $css
|
23
|
+
*
|
24
|
+
* @param array $options available options:
|
25
|
+
*
|
26
|
+
* 'preserveComments': (default true) multi-line comments that begin
|
27
|
+
* with "/*!" will be preserved with newlines before and after to
|
28
|
+
* enhance readability.
|
29
|
+
*
|
30
|
+
* 'prependRelativePath': (default null) if given, this string will be
|
31
|
+
* prepended to all relative URIs in import/url declarations
|
32
|
+
*
|
33
|
+
* 'currentDir': (default null) if given, this is assumed to be the
|
34
|
+
* directory of the current CSS file. Using this, minify will rewrite
|
35
|
+
* all relative URIs in import/url declarations to correctly point to
|
36
|
+
* the desired files. For this to work, the files *must* exist and be
|
37
|
+
* visible by the PHP process.
|
38
|
+
*
|
39
|
+
* 'symlinks': (default = array()) If the CSS file is stored in
|
40
|
+
* a symlink-ed directory, provide an array of link paths to
|
41
|
+
* target paths, where the link paths are within the document root. Because
|
42
|
+
* paths need to be normalized for this to work, use "//" to substitute
|
43
|
+
* the doc root in the link paths (the array keys). E.g.:
|
44
|
+
* <code>
|
45
|
+
* array('//symlink' => '/real/target/path') // unix
|
46
|
+
* array('//static' => 'D:\\staticStorage') // Windows
|
47
|
+
* </code>
|
48
|
+
*
|
49
|
+
* @return string
|
50
|
+
*/
|
51
|
+
public static function minify($css, $options = array())
|
52
|
+
{
|
53
|
+
require_once 'Minify/CSS/Compressor.php';
|
54
|
+
if (isset($options['preserveComments'])
|
55
|
+
&& !$options['preserveComments']) {
|
56
|
+
$css = Minify_CSS_Compressor::process($css, $options);
|
57
|
+
} else {
|
58
|
+
require_once 'Minify/CommentPreserver.php';
|
59
|
+
$css = Minify_CommentPreserver::process(
|
60
|
+
$css
|
61
|
+
,array('Minify_CSS_Compressor', 'process')
|
62
|
+
,array($options)
|
63
|
+
);
|
64
|
+
}
|
65
|
+
if (! isset($options['currentDir']) && ! isset($options['prependRelativePath'])) {
|
66
|
+
return $css;
|
67
|
+
}
|
68
|
+
require_once 'Minify/CSS/UriRewriter.php';
|
69
|
+
if (isset($options['currentDir'])) {
|
70
|
+
return Minify_CSS_UriRewriter::rewrite(
|
71
|
+
$css
|
72
|
+
,$options['currentDir']
|
73
|
+
,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
|
74
|
+
,isset($options['symlinks']) ? $options['symlinks'] : array()
|
75
|
+
);
|
76
|
+
} else {
|
77
|
+
return Minify_CSS_UriRewriter::prepend(
|
78
|
+
$css
|
79
|
+
,$options['prependRelativePath']
|
80
|
+
);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
@@ -0,0 +1,250 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_CSS_Compressor
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Compress CSS
|
9
|
+
*
|
10
|
+
* This is a heavy regex-based removal of whitespace, unnecessary
|
11
|
+
* comments and tokens, and some CSS value minimization, where practical.
|
12
|
+
* Many steps have been taken to avoid breaking comment-based hacks,
|
13
|
+
* including the ie5/mac filter (and its inversion), but expect tricky
|
14
|
+
* hacks involving comment tokens in 'content' value strings to break
|
15
|
+
* minimization badly. A test suite is available.
|
16
|
+
*
|
17
|
+
* @package Minify
|
18
|
+
* @author Stephen Clay <steve@mrclay.org>
|
19
|
+
* @author http://code.google.com/u/1stvamp/ (Issue 64 patch)
|
20
|
+
*/
|
21
|
+
class Minify_CSS_Compressor {
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Minify a CSS string
|
25
|
+
*
|
26
|
+
* @param string $css
|
27
|
+
*
|
28
|
+
* @param array $options (currently ignored)
|
29
|
+
*
|
30
|
+
* @return string
|
31
|
+
*/
|
32
|
+
public static function process($css, $options = array())
|
33
|
+
{
|
34
|
+
$obj = new Minify_CSS_Compressor($options);
|
35
|
+
return $obj->_process($css);
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @var array options
|
40
|
+
*/
|
41
|
+
protected $_options = null;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* @var bool Are we "in" a hack?
|
45
|
+
*
|
46
|
+
* I.e. are some browsers targetted until the next comment?
|
47
|
+
*/
|
48
|
+
protected $_inHack = false;
|
49
|
+
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Constructor
|
53
|
+
*
|
54
|
+
* @param array $options (currently ignored)
|
55
|
+
*
|
56
|
+
* @return null
|
57
|
+
*/
|
58
|
+
private function __construct($options) {
|
59
|
+
$this->_options = $options;
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* Minify a CSS string
|
64
|
+
*
|
65
|
+
* @param string $css
|
66
|
+
*
|
67
|
+
* @return string
|
68
|
+
*/
|
69
|
+
protected function _process($css)
|
70
|
+
{
|
71
|
+
$css = str_replace("\r\n", "\n", $css);
|
72
|
+
|
73
|
+
// preserve empty comment after '>'
|
74
|
+
// http://www.webdevout.net/css-hacks#in_css-selectors
|
75
|
+
$css = preg_replace('@>/\\*\\s*\\*/@', '>/*keep*/', $css);
|
76
|
+
|
77
|
+
// preserve empty comment between property and value
|
78
|
+
// http://css-discuss.incutio.com/?page=BoxModelHack
|
79
|
+
$css = preg_replace('@/\\*\\s*\\*/\\s*:@', '/*keep*/:', $css);
|
80
|
+
$css = preg_replace('@:\\s*/\\*\\s*\\*/@', ':/*keep*/', $css);
|
81
|
+
|
82
|
+
// apply callback to all valid comments (and strip out surrounding ws
|
83
|
+
$css = preg_replace_callback('@\\s*/\\*([\\s\\S]*?)\\*/\\s*@'
|
84
|
+
,array($this, '_commentCB'), $css);
|
85
|
+
|
86
|
+
// remove ws around { } and last semicolon in declaration block
|
87
|
+
$css = preg_replace('/\\s*{\\s*/', '{', $css);
|
88
|
+
$css = preg_replace('/;?\\s*}\\s*/', '}', $css);
|
89
|
+
|
90
|
+
// remove ws surrounding semicolons
|
91
|
+
$css = preg_replace('/\\s*;\\s*/', ';', $css);
|
92
|
+
|
93
|
+
// remove ws around urls
|
94
|
+
$css = preg_replace('/
|
95
|
+
url\\( # url(
|
96
|
+
\\s*
|
97
|
+
([^\\)]+?) # 1 = the URL (really just a bunch of non right parenthesis)
|
98
|
+
\\s*
|
99
|
+
\\) # )
|
100
|
+
/x', 'url($1)', $css);
|
101
|
+
|
102
|
+
// remove ws between rules and colons
|
103
|
+
$css = preg_replace('/
|
104
|
+
\\s*
|
105
|
+
([{;]) # 1 = beginning of block or rule separator
|
106
|
+
\\s*
|
107
|
+
([\\*_]?[\\w\\-]+) # 2 = property (and maybe IE filter)
|
108
|
+
\\s*
|
109
|
+
:
|
110
|
+
\\s*
|
111
|
+
(\\b|[#\'"]) # 3 = first character of a value
|
112
|
+
/x', '$1$2:$3', $css);
|
113
|
+
|
114
|
+
// remove ws in selectors
|
115
|
+
$css = preg_replace_callback('/
|
116
|
+
(?: # non-capture
|
117
|
+
\\s*
|
118
|
+
[^~>+,\\s]+ # selector part
|
119
|
+
\\s*
|
120
|
+
[,>+~] # combinators
|
121
|
+
)+
|
122
|
+
\\s*
|
123
|
+
[^~>+,\\s]+ # selector part
|
124
|
+
{ # open declaration block
|
125
|
+
/x'
|
126
|
+
,array($this, '_selectorsCB'), $css);
|
127
|
+
|
128
|
+
// minimize hex colors
|
129
|
+
$css = preg_replace('/([^=])#([a-f\\d])\\2([a-f\\d])\\3([a-f\\d])\\4([\\s;\\}])/i'
|
130
|
+
, '$1#$2$3$4$5', $css);
|
131
|
+
|
132
|
+
// remove spaces between font families
|
133
|
+
$css = preg_replace_callback('/font-family:([^;}]+)([;}])/'
|
134
|
+
,array($this, '_fontFamilyCB'), $css);
|
135
|
+
|
136
|
+
$css = preg_replace('/@import\\s+url/', '@import url', $css);
|
137
|
+
|
138
|
+
// replace any ws involving newlines with a single newline
|
139
|
+
$css = preg_replace('/[ \\t]*\\n+\\s*/', "\n", $css);
|
140
|
+
|
141
|
+
// separate common descendent selectors w/ newlines (to limit line lengths)
|
142
|
+
$css = preg_replace('/([\\w#\\.\\*]+)\\s+([\\w#\\.\\*]+){/', "$1\n$2{", $css);
|
143
|
+
|
144
|
+
// Use newline after 1st numeric value (to limit line lengths).
|
145
|
+
$css = preg_replace('/
|
146
|
+
((?:padding|margin|border|outline):\\d+(?:px|em)?) # 1 = prop : 1st numeric value
|
147
|
+
\\s+
|
148
|
+
/x'
|
149
|
+
,"$1\n", $css);
|
150
|
+
|
151
|
+
// prevent triggering IE6 bug: http://www.crankygeek.com/ie6pebug/
|
152
|
+
$css = preg_replace('/:first-l(etter|ine)\\{/', ':first-l$1 {', $css);
|
153
|
+
|
154
|
+
return trim($css);
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* Replace what looks like a set of selectors
|
159
|
+
*
|
160
|
+
* @param array $m regex matches
|
161
|
+
*
|
162
|
+
* @return string
|
163
|
+
*/
|
164
|
+
protected function _selectorsCB($m)
|
165
|
+
{
|
166
|
+
// remove ws around the combinators
|
167
|
+
return preg_replace('/\\s*([,>+~])\\s*/', '$1', $m[0]);
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* Process a comment and return a replacement
|
172
|
+
*
|
173
|
+
* @param array $m regex matches
|
174
|
+
*
|
175
|
+
* @return string
|
176
|
+
*/
|
177
|
+
protected function _commentCB($m)
|
178
|
+
{
|
179
|
+
$hasSurroundingWs = (trim($m[0]) !== $m[1]);
|
180
|
+
$m = $m[1];
|
181
|
+
// $m is the comment content w/o the surrounding tokens,
|
182
|
+
// but the return value will replace the entire comment.
|
183
|
+
if ($m === 'keep') {
|
184
|
+
return '/**/';
|
185
|
+
}
|
186
|
+
if ($m === '" "') {
|
187
|
+
// component of http://tantek.com/CSS/Examples/midpass.html
|
188
|
+
return '/*" "*/';
|
189
|
+
}
|
190
|
+
if (preg_match('@";\\}\\s*\\}/\\*\\s+@', $m)) {
|
191
|
+
// component of http://tantek.com/CSS/Examples/midpass.html
|
192
|
+
return '/*";}}/* */';
|
193
|
+
}
|
194
|
+
if ($this->_inHack) {
|
195
|
+
// inversion: feeding only to one browser
|
196
|
+
if (preg_match('@
|
197
|
+
^/ # comment started like /*/
|
198
|
+
\\s*
|
199
|
+
(\\S[\\s\\S]+?) # has at least some non-ws content
|
200
|
+
\\s*
|
201
|
+
/\\* # ends like /*/ or /**/
|
202
|
+
@x', $m, $n)) {
|
203
|
+
// end hack mode after this comment, but preserve the hack and comment content
|
204
|
+
$this->_inHack = false;
|
205
|
+
return "/*/{$n[1]}/**/";
|
206
|
+
}
|
207
|
+
}
|
208
|
+
if (substr($m, -1) === '\\') { // comment ends like \*/
|
209
|
+
// begin hack mode and preserve hack
|
210
|
+
$this->_inHack = true;
|
211
|
+
return '/*\\*/';
|
212
|
+
}
|
213
|
+
if ($m !== '' && $m[0] === '/') { // comment looks like /*/ foo */
|
214
|
+
// begin hack mode and preserve hack
|
215
|
+
$this->_inHack = true;
|
216
|
+
return '/*/*/';
|
217
|
+
}
|
218
|
+
if ($this->_inHack) {
|
219
|
+
// a regular comment ends hack mode but should be preserved
|
220
|
+
$this->_inHack = false;
|
221
|
+
return '/**/';
|
222
|
+
}
|
223
|
+
// Issue 107: if there's any surrounding whitespace, it may be important, so
|
224
|
+
// replace the comment with a single space
|
225
|
+
return $hasSurroundingWs // remove all other comments
|
226
|
+
? ' '
|
227
|
+
: '';
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
* Process a font-family listing and return a replacement
|
232
|
+
*
|
233
|
+
* @param array $m regex matches
|
234
|
+
*
|
235
|
+
* @return string
|
236
|
+
*/
|
237
|
+
protected function _fontFamilyCB($m)
|
238
|
+
{
|
239
|
+
$m[1] = preg_replace('/
|
240
|
+
\\s*
|
241
|
+
(
|
242
|
+
"[^"]+" # 1 = family in double qutoes
|
243
|
+
|\'[^\']+\' # or 1 = family in single quotes
|
244
|
+
|[\\w\\-]+ # or 1 = unquoted family
|
245
|
+
)
|
246
|
+
\\s*
|
247
|
+
/x', '$1', $m[1]);
|
248
|
+
return 'font-family:' . $m[1] . $m[2];
|
249
|
+
}
|
250
|
+
}
|
@@ -0,0 +1,270 @@
|
|
1
|
+
<?php
|
2
|
+
/**
|
3
|
+
* Class Minify_CSS_UriRewriter
|
4
|
+
* @package Minify
|
5
|
+
*/
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Rewrite file-relative URIs as root-relative in CSS files
|
9
|
+
*
|
10
|
+
* @package Minify
|
11
|
+
* @author Stephen Clay <steve@mrclay.org>
|
12
|
+
*/
|
13
|
+
class Minify_CSS_UriRewriter {
|
14
|
+
|
15
|
+
/**
|
16
|
+
* Defines which class to call as part of callbacks, change this
|
17
|
+
* if you extend Minify_CSS_UriRewriter
|
18
|
+
* @var string
|
19
|
+
*/
|
20
|
+
protected static $className = 'Minify_CSS_UriRewriter';
|
21
|
+
|
22
|
+
/**
|
23
|
+
* rewrite() and rewriteRelative() append debugging information here
|
24
|
+
* @var string
|
25
|
+
*/
|
26
|
+
public static $debugText = '';
|
27
|
+
|
28
|
+
/**
|
29
|
+
* Rewrite file relative URIs as root relative in CSS files
|
30
|
+
*
|
31
|
+
* @param string $css
|
32
|
+
*
|
33
|
+
* @param string $currentDir The directory of the current CSS file.
|
34
|
+
*
|
35
|
+
* @param string $docRoot The document root of the web site in which
|
36
|
+
* the CSS file resides (default = $_SERVER['DOCUMENT_ROOT']).
|
37
|
+
*
|
38
|
+
* @param array $symlinks (default = array()) If the CSS file is stored in
|
39
|
+
* a symlink-ed directory, provide an array of link paths to
|
40
|
+
* target paths, where the link paths are within the document root. Because
|
41
|
+
* paths need to be normalized for this to work, use "//" to substitute
|
42
|
+
* the doc root in the link paths (the array keys). E.g.:
|
43
|
+
* <code>
|
44
|
+
* array('//symlink' => '/real/target/path') // unix
|
45
|
+
* array('//static' => 'D:\\staticStorage') // Windows
|
46
|
+
* </code>
|
47
|
+
*
|
48
|
+
* @return string
|
49
|
+
*/
|
50
|
+
public static function rewrite($css, $currentDir, $docRoot = null, $symlinks = array())
|
51
|
+
{
|
52
|
+
self::$_docRoot = self::_realpath(
|
53
|
+
$docRoot ? $docRoot : $_SERVER['DOCUMENT_ROOT']
|
54
|
+
);
|
55
|
+
self::$_currentDir = self::_realpath($currentDir);
|
56
|
+
self::$_symlinks = array();
|
57
|
+
|
58
|
+
// normalize symlinks
|
59
|
+
foreach ($symlinks as $link => $target) {
|
60
|
+
$link = ($link === '//')
|
61
|
+
? self::$_docRoot
|
62
|
+
: str_replace('//', self::$_docRoot . '/', $link);
|
63
|
+
$link = strtr($link, '/', DIRECTORY_SEPARATOR);
|
64
|
+
self::$_symlinks[$link] = self::_realpath($target);
|
65
|
+
}
|
66
|
+
|
67
|
+
self::$debugText .= "docRoot : " . self::$_docRoot . "\n"
|
68
|
+
. "currentDir : " . self::$_currentDir . "\n";
|
69
|
+
if (self::$_symlinks) {
|
70
|
+
self::$debugText .= "symlinks : " . var_export(self::$_symlinks, 1) . "\n";
|
71
|
+
}
|
72
|
+
self::$debugText .= "\n";
|
73
|
+
|
74
|
+
$css = self::_trimUrls($css);
|
75
|
+
|
76
|
+
// rewrite
|
77
|
+
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
|
78
|
+
,array(self::$className, '_processUriCB'), $css);
|
79
|
+
$css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
80
|
+
,array(self::$className, '_processUriCB'), $css);
|
81
|
+
|
82
|
+
return $css;
|
83
|
+
}
|
84
|
+
|
85
|
+
/**
|
86
|
+
* Prepend a path to relative URIs in CSS files
|
87
|
+
*
|
88
|
+
* @param string $css
|
89
|
+
*
|
90
|
+
* @param string $path The path to prepend.
|
91
|
+
*
|
92
|
+
* @return string
|
93
|
+
*/
|
94
|
+
public static function prepend($css, $path)
|
95
|
+
{
|
96
|
+
self::$_prependPath = $path;
|
97
|
+
|
98
|
+
$css = self::_trimUrls($css);
|
99
|
+
|
100
|
+
// append
|
101
|
+
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
|
102
|
+
,array(self::$className, '_processUriCB'), $css);
|
103
|
+
$css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
104
|
+
,array(self::$className, '_processUriCB'), $css);
|
105
|
+
|
106
|
+
self::$_prependPath = null;
|
107
|
+
return $css;
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
/**
|
112
|
+
* @var string directory of this stylesheet
|
113
|
+
*/
|
114
|
+
private static $_currentDir = '';
|
115
|
+
|
116
|
+
/**
|
117
|
+
* @var string DOC_ROOT
|
118
|
+
*/
|
119
|
+
private static $_docRoot = '';
|
120
|
+
|
121
|
+
/**
|
122
|
+
* @var array directory replacements to map symlink targets back to their
|
123
|
+
* source (within the document root) E.g. '/var/www/symlink' => '/var/realpath'
|
124
|
+
*/
|
125
|
+
private static $_symlinks = array();
|
126
|
+
|
127
|
+
/**
|
128
|
+
* @var string path to prepend
|
129
|
+
*/
|
130
|
+
private static $_prependPath = null;
|
131
|
+
|
132
|
+
private static function _trimUrls($css)
|
133
|
+
{
|
134
|
+
return preg_replace('/
|
135
|
+
url\\( # url(
|
136
|
+
\\s*
|
137
|
+
([^\\)]+?) # 1 = URI (assuming does not contain ")")
|
138
|
+
\\s*
|
139
|
+
\\) # )
|
140
|
+
/x', 'url($1)', $css);
|
141
|
+
}
|
142
|
+
|
143
|
+
private static function _processUriCB($m)
|
144
|
+
{
|
145
|
+
// $m matched either '/@import\\s+([\'"])(.*?)[\'"]/' or '/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
|
146
|
+
$isImport = ($m[0][0] === '@');
|
147
|
+
// determine URI and the quote character (if any)
|
148
|
+
if ($isImport) {
|
149
|
+
$quoteChar = $m[1];
|
150
|
+
$uri = $m[2];
|
151
|
+
} else {
|
152
|
+
// $m[1] is either quoted or not
|
153
|
+
$quoteChar = ($m[1][0] === "'" || $m[1][0] === '"')
|
154
|
+
? $m[1][0]
|
155
|
+
: '';
|
156
|
+
$uri = ($quoteChar === '')
|
157
|
+
? $m[1]
|
158
|
+
: substr($m[1], 1, strlen($m[1]) - 2);
|
159
|
+
}
|
160
|
+
// analyze URI
|
161
|
+
if ('/' !== $uri[0] // root-relative
|
162
|
+
&& false === strpos($uri, '//') // protocol (non-data)
|
163
|
+
&& 0 !== strpos($uri, 'data:') // data protocol
|
164
|
+
) {
|
165
|
+
// URI is file-relative: rewrite depending on options
|
166
|
+
$uri = (self::$_prependPath !== null)
|
167
|
+
? (self::$_prependPath . $uri)
|
168
|
+
: self::rewriteRelative($uri, self::$_currentDir, self::$_docRoot, self::$_symlinks);
|
169
|
+
}
|
170
|
+
return $isImport
|
171
|
+
? "@import {$quoteChar}{$uri}{$quoteChar}"
|
172
|
+
: "url({$quoteChar}{$uri}{$quoteChar})";
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* Rewrite a file relative URI as root relative
|
177
|
+
*
|
178
|
+
* <code>
|
179
|
+
* Minify_CSS_UriRewriter::rewriteRelative(
|
180
|
+
* '../img/hello.gif'
|
181
|
+
* , '/home/user/www/css' // path of CSS file
|
182
|
+
* , '/home/user/www' // doc root
|
183
|
+
* );
|
184
|
+
* // returns '/img/hello.gif'
|
185
|
+
*
|
186
|
+
* // example where static files are stored in a symlinked directory
|
187
|
+
* Minify_CSS_UriRewriter::rewriteRelative(
|
188
|
+
* 'hello.gif'
|
189
|
+
* , '/var/staticFiles/theme'
|
190
|
+
* , '/home/user/www'
|
191
|
+
* , array('/home/user/www/static' => '/var/staticFiles')
|
192
|
+
* );
|
193
|
+
* // returns '/static/theme/hello.gif'
|
194
|
+
* </code>
|
195
|
+
*
|
196
|
+
* @param string $uri file relative URI
|
197
|
+
*
|
198
|
+
* @param string $realCurrentDir realpath of the current file's directory.
|
199
|
+
*
|
200
|
+
* @param string $realDocRoot realpath of the site document root.
|
201
|
+
*
|
202
|
+
* @param array $symlinks (default = array()) If the file is stored in
|
203
|
+
* a symlink-ed directory, provide an array of link paths to
|
204
|
+
* real target paths, where the link paths "appear" to be within the document
|
205
|
+
* root. E.g.:
|
206
|
+
* <code>
|
207
|
+
* array('/home/foo/www/not/real/path' => '/real/target/path') // unix
|
208
|
+
* array('C:\\htdocs\\not\\real' => 'D:\\real\\target\\path') // Windows
|
209
|
+
* </code>
|
210
|
+
*
|
211
|
+
* @return string
|
212
|
+
*/
|
213
|
+
public static function rewriteRelative($uri, $realCurrentDir, $realDocRoot, $symlinks = array())
|
214
|
+
{
|
215
|
+
// prepend path with current dir separator (OS-independent)
|
216
|
+
$path = strtr($realCurrentDir, '/', DIRECTORY_SEPARATOR)
|
217
|
+
. DIRECTORY_SEPARATOR . strtr($uri, '/', DIRECTORY_SEPARATOR);
|
218
|
+
|
219
|
+
self::$debugText .= "file-relative URI : {$uri}\n"
|
220
|
+
. "path prepended : {$path}\n";
|
221
|
+
|
222
|
+
// "unresolve" a symlink back to doc root
|
223
|
+
foreach ($symlinks as $link => $target) {
|
224
|
+
if (0 === strpos($path, $target)) {
|
225
|
+
// replace $target with $link
|
226
|
+
$path = $link . substr($path, strlen($target));
|
227
|
+
|
228
|
+
self::$debugText .= "symlink unresolved : {$path}\n";
|
229
|
+
|
230
|
+
break;
|
231
|
+
}
|
232
|
+
}
|
233
|
+
// strip doc root
|
234
|
+
$path = substr($path, strlen($realDocRoot));
|
235
|
+
|
236
|
+
self::$debugText .= "docroot stripped : {$path}\n";
|
237
|
+
|
238
|
+
// fix to root-relative URI
|
239
|
+
|
240
|
+
$uri = strtr($path, '/\\', '//');
|
241
|
+
|
242
|
+
// remove /./ and /../ where possible
|
243
|
+
$uri = str_replace('/./', '/', $uri);
|
244
|
+
// inspired by patch from Oleg Cherniy
|
245
|
+
do {
|
246
|
+
$uri = preg_replace('@/[^/]+/\\.\\./@', '/', $uri, 1, $changed);
|
247
|
+
} while ($changed);
|
248
|
+
|
249
|
+
self::$debugText .= "traversals removed : {$uri}\n\n";
|
250
|
+
|
251
|
+
return $uri;
|
252
|
+
}
|
253
|
+
|
254
|
+
/**
|
255
|
+
* Get realpath with any trailing slash removed. If realpath() fails,
|
256
|
+
* just remove the trailing slash.
|
257
|
+
*
|
258
|
+
* @param string $path
|
259
|
+
*
|
260
|
+
* @return mixed path with no trailing slash
|
261
|
+
*/
|
262
|
+
protected static function _realpath($path)
|
263
|
+
{
|
264
|
+
$realPath = realpath($path);
|
265
|
+
if ($realPath !== false) {
|
266
|
+
$path = $realPath;
|
267
|
+
}
|
268
|
+
return rtrim($path, '/\\');
|
269
|
+
}
|
270
|
+
}
|