[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Class Minify_Controller_MinApp 4 * @package Minify 5 */ 6 7 /** 8 * Controller class for requests to /min/index.php 9 * 10 * @package Minify 11 * @author Stephen Clay <steve@mrclay.org> 12 */ 13 class Minify_Controller_MinApp extends Minify_Controller_Base { 14 15 /** 16 * Set up groups of files as sources 17 * 18 * @param array $options controller and Minify options 19 * 20 * @return array Minify options 21 */ 22 public function setupSources($options) { 23 // PHP insecure by default: realpath() and other FS functions can't handle null bytes. 24 foreach (array('g', 'b', 'f') as $key) { 25 if (isset($_GET[$key])) { 26 $_GET[$key] = str_replace("\x00", '', (string)$_GET[$key]); 27 } 28 } 29 30 // filter controller options 31 $cOptions = array_merge( 32 array( 33 'allowDirs' => '//' 34 ,'groupsOnly' => false 35 ,'groups' => array() 36 ,'noMinPattern' => '@[-\\.]min\\.(?:js|css)$@i' // matched against basename 37 ) 38 ,(isset($options['minApp']) ? $options['minApp'] : array()) 39 ); 40 unset($options['minApp']); 41 $sources = array(); 42 $this->selectionId = ''; 43 $firstMissingResource = null; 44 if (isset($_GET['g'])) { 45 // add group(s) 46 $this->selectionId .= 'g=' . $_GET['g']; 47 $keys = explode(',', $_GET['g']); 48 if ($keys != array_unique($keys)) { 49 $this->log("Duplicate group key found."); 50 return $options; 51 } 52 foreach ($keys as $key) { 53 if (! isset($cOptions['groups'][$key])) { 54 $this->log("A group configuration for \"{$key}\" was not found"); 55 return $options; 56 } 57 $files = $cOptions['groups'][$key]; 58 // if $files is a single object, casting will break it 59 if (is_object($files)) { 60 $files = array($files); 61 } elseif (! is_array($files)) { 62 $files = (array)$files; 63 } 64 foreach ($files as $file) { 65 if ($file instanceof Minify_Source) { 66 $sources[] = $file; 67 continue; 68 } 69 if (0 === strpos($file, '//')) { 70 $file = $_SERVER['DOCUMENT_ROOT'] . substr($file, 1); 71 } 72 $realpath = realpath($file); 73 if ($realpath && is_file($realpath)) { 74 $sources[] = $this->_getFileSource($realpath, $cOptions); 75 } else { 76 $this->log("The path \"{$file}\" (realpath \"{$realpath}\") could not be found (or was not a file)"); 77 if (null === $firstMissingResource) { 78 $firstMissingResource = basename($file); 79 continue; 80 } else { 81 $secondMissingResource = basename($file); 82 $this->log("More than one file was missing: '$firstMissingResource', '$secondMissingResource'"); 83 return $options; 84 } 85 } 86 } 87 if ($sources) { 88 try { 89 $this->checkType($sources[0]); 90 } catch (Exception $e) { 91 $this->log($e->getMessage()); 92 return $options; 93 } 94 } 95 } 96 } 97 if (! $cOptions['groupsOnly'] && isset($_GET['f'])) { 98 // try user files 99 // The following restrictions are to limit the URLs that minify will 100 // respond to. 101 if (// verify at least one file, files are single comma separated, 102 // and are all same extension 103 ! preg_match('/^[^,]+\\.(css|js)(?:,[^,]+\\.\\1)*$/', $_GET['f'], $m) 104 // no "//" 105 || strpos($_GET['f'], '//') !== false 106 // no "\" 107 || strpos($_GET['f'], '\\') !== false 108 ) { 109 $this->log("GET param 'f' was invalid"); 110 return $options; 111 } 112 $ext = ".{$m[1]}"; 113 try { 114 $this->checkType($m[1]); 115 } catch (Exception $e) { 116 $this->log($e->getMessage()); 117 return $options; 118 } 119 $files = explode(',', $_GET['f']); 120 if ($files != array_unique($files)) { 121 $this->log("Duplicate files were specified"); 122 return $options; 123 } 124 if (isset($_GET['b'])) { 125 // check for validity 126 if (preg_match('@^[^/]+(?:/[^/]+)*$@', $_GET['b']) 127 && false === strpos($_GET['b'], '..') 128 && $_GET['b'] !== '.') { 129 // valid base 130 $base = "/{$_GET['b']}/"; 131 } else { 132 $this->log("GET param 'b' was invalid"); 133 return $options; 134 } 135 } else { 136 $base = '/'; 137 } 138 $allowDirs = array(); 139 foreach ((array)$cOptions['allowDirs'] as $allowDir) { 140 $allowDirs[] = realpath(str_replace('//', $_SERVER['DOCUMENT_ROOT'] . '/', $allowDir)); 141 } 142 $basenames = array(); // just for cache id 143 foreach ($files as $file) { 144 $uri = $base . $file; 145 $path = $_SERVER['DOCUMENT_ROOT'] . $uri; 146 $realpath = realpath($path); 147 if (false === $realpath || ! is_file($realpath)) { 148 $this->log("The path \"{$path}\" (realpath \"{$realpath}\") could not be found (or was not a file)"); 149 if (null === $firstMissingResource) { 150 $firstMissingResource = $uri; 151 continue; 152 } else { 153 $secondMissingResource = $uri; 154 $this->log("More than one file was missing: '$firstMissingResource', '$secondMissingResource`'"); 155 return $options; 156 } 157 } 158 try { 159 parent::checkNotHidden($realpath); 160 parent::checkAllowDirs($realpath, $allowDirs, $uri); 161 } catch (Exception $e) { 162 $this->log($e->getMessage()); 163 return $options; 164 } 165 $sources[] = $this->_getFileSource($realpath, $cOptions); 166 $basenames[] = basename($realpath, $ext); 167 } 168 if ($this->selectionId) { 169 $this->selectionId .= '_f='; 170 } 171 $this->selectionId .= implode(',', $basenames) . $ext; 172 } 173 if ($sources) { 174 if (null !== $firstMissingResource) { 175 array_unshift($sources, new Minify_Source(array( 176 'id' => 'missingFile' 177 // should not cause cache invalidation 178 ,'lastModified' => 0 179 // due to caching, filename is unreliable. 180 ,'content' => "/* Minify: at least one missing file. See " . Minify::URL_DEBUG . " */\n" 181 ,'minifier' => '' 182 ))); 183 } 184 $this->sources = $sources; 185 } else { 186 $this->log("No sources to serve"); 187 } 188 return $options; 189 } 190 191 /** 192 * @param string $file 193 * 194 * @param array $cOptions 195 * 196 * @return Minify_Source 197 */ 198 protected function _getFileSource($file, $cOptions) 199 { 200 $spec['filepath'] = $file; 201 if ($cOptions['noMinPattern'] && preg_match($cOptions['noMinPattern'], basename($file))) { 202 if (preg_match('~\.css$~i', $file)) { 203 $spec['minifyOptions']['compress'] = false; 204 } else { 205 $spec['minifier'] = ''; 206 } 207 } 208 return new Minify_Source($spec); 209 } 210 211 protected $_type = null; 212 213 /** 214 * Make sure that only source files of a single type are registered 215 * 216 * @param string $sourceOrExt 217 * 218 * @throws Exception 219 */ 220 public function checkType($sourceOrExt) 221 { 222 if ($sourceOrExt === 'js') { 223 $type = Minify::TYPE_JS; 224 } elseif ($sourceOrExt === 'css') { 225 $type = Minify::TYPE_CSS; 226 } elseif ($sourceOrExt->contentType !== null) { 227 $type = $sourceOrExt->contentType; 228 } else { 229 return; 230 } 231 if ($this->_type === null) { 232 $this->_type = $type; 233 } elseif ($this->_type !== $type) { 234 throw new Exception('Content-Type mismatch'); 235 } 236 } 237 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |