/** * @param string $filePath - path+filename (often just filename) * relative to physical_path AND request_url, no leading slash */ public static function get($filePath) { $c =& self::$config; // shorthand enforce(is_file($c->STATICPATH . $filePath), 'getStatic: requested file ' . $c->STATICPATH . $filePath . ' does not exist'); $ts = filemtime($c->STATICPATH . $filePath); return $c->STATICURL . $filePath . ($c->REWRITE ? '-' . $ts : ''); // go through rewrite }
function staticCacheExpired($key) { if (!version_development) { return false; } static $resultCache = array(); if (!array_key_exists($key, $resultCache)) { $timestampFile = $_SERVER['cachePath'] . '/staticCacheExpired_' . sha1($key) . '.timestamp'; $resultCache[$key] = !is_file($timestampFile) || filemtime($timestampFile) < lastCodeChangeTimestamp(); directory(dirname($timestampFile)); $touchResult = touch($timestampFile); enforce($touchResult, "Could not touch '{$timestampFile}'"); } return $resultCache[$key]; }
function codeChanged() { static $includedFiles = array(); static $result = true; $newIncludedFiles = includedFile(); if (count($includedFiles) != count($newIncludedFiles)) { $fingerprintFile = $_SERVER['cachePath'] . '/codeBase_' . sha1(serialize($newIncludedFiles)) . '.timestamp'; $result = !is_file($fingerprintFile) || codeTimestamp() > filemtime($fingerprintFile); if ($result) { directory(dirname($fingerprintFile)); $touchResult = touch($fingerprintFile); enforce($touchResult, "Could not touch '{$fingerprintFile}'"); } $includedFiles = $newIncludedFiles; } return $result; }
function symbolicLink($link, $dir) { $_setup_bin_path = _setup_bin_path(); switch (strtolower(strtok(php_uname('s'), ' '))) { case 'linux': case 'mac': case 'darwin': `ln -s {$dir} {$link}`; break; case 'windows': enforce(is_file("{$_setup_bin_path}/junction.exe"), 'junction executable not found'); `{$_setup_bin_path}/junction.exe {$link} {$dir}`; break; default: assertTrue(false); } }
function error_handler($errno, $errstr, $errfile, $errline) { throw new ErrorException($errstr, $errno, 1, $errfile, $errline); } set_error_handler('error_handler'); function error($message = 'An error occurred') { throw new Exception($message); } function enforce($condition, $message = 'Enforcement failed') { if (!$condition) { error($message); } return $condition; } enforce(!get_magic_quotes_gpc(), "Magic quotes are on!"); $count = $_REQUEST['count']; $dir = uniqid('', true) . '-' . urlencode($_REQUEST['program']); mkdir($dir, 0700, true); $filelist = ""; foreach ($_FILES as $name => $file) { if ($file["error"] == UPLOAD_ERR_OK) { $tmp_name = $file["tmp_name"]; $filename = $file["name"]; $filename = basename($filename); move_uploaded_file($tmp_name, "{$dir}/{$filename}"); $filelist .= $url = "http://" . $_SERVER['HTTP_HOST'] . dirname($_SERVER['REQUEST_URI']) . "/{$dir}/{$filename}\n"; } } mail(EMAIL, 'Sleepy Crashback', $filelist);
function byte_to_human($b, $precision = 1) { $b = 0 + $b; // convert to int, if needed enforce(is_long($b), '$b is not an int'); if ($b < 1024) { return $b . ' byte'; } if ($b < 0.9 * 1048576) { // 0.9 round higher levels if close enough return round($b / 1024, $precision) . ' kb'; } if ($b < 0.9 * 1073741824) { return round($b / 1048576, $precision) . ' MB'; } if ($b < 0.9 * 1099511627776) { return round($b / 1073741824, $precision) . ' GB'; } }
function execute($callback) { $exitCode = 0; try { $result = $callback(); enforce($result == 0, 'Exit code: ' . $result); } catch (Exception $e) { echo "\nFail\n\n"; echo $e; $exitCode = $e->getCode(); if ($exitCode == 0) { $exitCode = 1; } echo "\nExit code: {$exitCode}\n"; } exit($exitCode); }
function generateStubs($destinationDirectory) { enforce(isset($_SERVER['basePath']), 'basePath is required for stubs generation'); $timestamp = microtime(true); echo 'Listing files ..'; $files = array(); foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($_SERVER['basePath'])) as $file) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if (!in_array($file->getExtension(), array('php'))) { continue; } if (strpos(realpath($file), realpath($destinationDirectory) . DIRECTORY_SEPARATOR) === 0) { continue; } $fileContent = file_get_contents($file); if (preg_match('/(?si)function\\s*stub/', $fileContent) == 0) { continue; } $files[] = $file; } echo ' ' . count($files) . "\n"; echo 'Including files ..'; $i = 0; // php include can overwrite variable values so we need to isolate include in a function $includeFile = function ($file) { ob_start(); include_once (string) $file; ob_end_clean(); }; foreach ($files as $file) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if (in_array(realpath($file), get_included_files())) { continue; } $i++; $includeFile($file); } echo ' ' . $i . "\n"; $callables = array(); echo 'Listing stub generators ..'; $functions = get_defined_functions(); foreach (array_merge($functions['internal'], $functions['user']) as $function) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if (strpos(strtolower($function), 'stub') === 0) { $callables[] = $function; } } foreach (get_declared_classes() as $class) { foreach (get_class_methods($class) as $method) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if (strpos(strtolower($method), 'stub') === 0) { $callables[] = array($class, $method); } } } echo ' ' . count($callables) . "\n"; echo "\nRunning " . count($callables) . " stub generator(s):\n"; $stubsTree = (object) array(); foreach ($callables as $callable) { $id = (is_string($callable) ? $callable : $callable[0] . '::' . $callable[1]) . '()'; echo ' ' . $id; $stubs = call_user_func($callable); foreach (is_array($stubs) ? $stubs : array($stubs) as $stub) { generateStub($stubsTree, $stub); } echo "\n"; } directory($destinationDirectory); echo "\nGenerating stub files:\n"; foreach ($stubsTree as $stub) { if (isset($stub->{'class'})) { $stubFile = $stub->{'class'}; $stubString = generateStubString($stub); } echo " {$stubFile}\n"; file_put_contents($destinationDirectory . '/' . $stubFile . '.stubs.php', "<?php\n\n{$stubString}\n\n"); } echo "Done\n"; }
/** * verifies existence of a thumb in a particular resolution * returns the url, false if there is no source image! * - smart "semi-static" caching including thumbnail timestamp in url * ==> be sure to understand the rewrite rules * ==> be sure to have a proper cache/ to _cache/ rewrite in your root .htaccess * * @param string $file - path to original file * @param string $mode - scale mode. currently only 'b' (boxing in) supported * @param int $sizeX - target width (must be within $c->PERMITTED_SIZES) * @param int $sizeY - target height (must be within $c->PERMITTED_SIZES) * @param bool $force - ignore cache and always reproduce (maybe during development) * @param bool $timestamp - attach timestamp to url (and remove leading underscore?) * @param int $dstW - CBR - passes back resulting size (<=$sizeX) * @param int $dstH - CBR - " , important for alignment, especially vertical * @param float $scale - deliver Thumb bigger by this factor. dstW, dstH remain unaffected. (used to prep for CSS3 scalings) * * @return string the url (which to use in the img tag, gets rewritten to actual path) */ public static function getThumb($file, $mode, $sizeX, $sizeY, $force = false, $timestamp = true, $scale = 1.0, &$dstW = false, &$dstH = false) { $c =& self::$config; // shorthand enforce(self::$config !== false, 'you neet to call config() first'); //convert int and save pre-scae $origSizeX = $sizeX = 0 + $sizeX; $origSizeY = $sizeY = 0 + $sizeY; enforce(is_int($sizeX), "sizeX is not an int"); enforce(is_int($sizeY), "sizeX is not an int"); enforce(in_array($sizeX, $c->PERMITTED_SIZES, true), 'not a permitted sizeX'); enforce(in_array($sizeY, $c->PERMITTED_SIZES, true), 'not a permitted sizeY'); enforce(in_array($scale, $c->PERMITTED_SCALINGS, true), 'scale not allowed'); if ($scale !== 1.0) { $sizeX = intval(round($sizeX * $scale)); $sizeY = intval(round($sizeY * $scale)); } // for the moment only boxed mode is supported... enforce(in_array($mode, array('b'), true), 'invalid dimension (read: not boxed mode)'); $srcUrl = $c->ROOT . '/' . $file; /* * fallback image in case thumb creation fails (likely cases: broken files, and still in upload) * benefit of this approach: if upload continues and eventuell gets final, it does have a newer * timestamp than what got created from '$broken'... ==> subsequent reloads have a chance. */ if (!file_exists($srcUrl)) { out("file {$srcUrl} does not exist"); $dstW = $dstH = 0; return false; // (also important, to not show thumb, if orig gone...) } // computing dstUrl, must also take local path to source into account etc... ----------------------------- // -arguably- obfuscation might be desirable, although this stands against SEO // // REF: // dstUrl: Dörte A一B二CÖDE _cache/c7_u/bearbeitet-7_upload_b300-226.jpg // dstUrl: D__rte_A___B___C__DE__cache/c7_u/bearbeitet-7_upload_b300-226.jpg $parts[0] = str_replace(array('ö', 'ü', 'ä', 'ß', '@'), array('oe', 'ue', 'ae', 'ss', ' at '), strtolower($file)); $parts[0] = trim(str_replace(array('/', '\\'), '-', $parts[0]), ' -'); $parts[0] = preg_replace('/([^\\w\\/\\-\\.])/', '_', $parts[0]); $parts[] = $mode; $parts[] = $sizeX; $parts[] = $sizeY; $dstUrl = implode('-', $parts); // spread out into subDirs: safer/better performance // avoids limitations with certain file systems (too many files in a single dir) $subDir = preg_replace('/([^\\w\\d])/', '', $dstUrl); // hint:bump letter if something basic about thumbnailing changes // (as a hack to invalidate all prior thumbs, also on live) $subDir = 'd' . substr($subDir, 0, 3); $subDirPath = $c->CACHEPATH . $subDir; // for mkdir, below // turn into absolute path, and add thumb extension $dstCore = $subDir . '/' . $dstUrl . '.jpg'; $dstUrl = $c->CACHEURL . $dstCore; $dstPath = $c->CACHEPATH . $dstCore; if ($force || !isNewer($dstPath, $srcUrl)) { set_error_handler('cache_error_handler'); try { // just peeking for errors getimagesize($srcUrl); $srcImg = false; switch (strtolower(pathinfo($srcUrl, PATHINFO_EXTENSION))) { case 'jpg': case 'jpeg': $srcImg = imagecreatefromjpeg($srcUrl); break; case 'png': $srcImg = imagecreatefrompng($srcUrl); break; default: fail('unknown extension for thumbnailing'); } } catch (Exception $e) { enforce(is_file($c->BROKENURL), 'image for failed thumbs does not exist: ' . $c->BROKENURL); $srcUrl = $c->BROKENURL; $srcImg = imagecreatefrompng($srcUrl); $fallbackImage = true; } restore_error_handler(); if (!file_exists($subDirPath)) { enforce(mkdir($subDirPath, 0777, true)); } enforce(file_exists($subDirPath)); $srcW = $srcH = $dstW = $dstH = $image_type = false; list($srcW, $srcH, $image_type) = getimagesize($srcUrl); enforce($srcW > 0 && $srcH > 0, 'sanity'); list($dstW, $dstH) = self::getScaledBox($mode, $srcW, $srcH, $sizeX, $sizeY); $dstImg = imagecreatetruecolor($dstW, $dstH); enforce(imagecopyresampled($dstImg, $srcImg, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH), 'resizing failed'); // Output and free memory imagejpeg($dstImg, $dstPath, $c->JPEG_QUALITY); chmod($dstPath, 0666); // do not enforce imagedestroy($srcImg); imagedestroy($dstImg); // recompute unscaled values, if needed if ($scale !== 1.0) { list($dstW, $dstH) = self::getScaledBox($mode, $srcW, $srcH, $origSizeX, $origSizeY); } } else { list($dstW, $dstH) = getimagesize($dstPath); // COULDDO: take from a to-be meta-sidecar // this is akward. $dstW = intval(round($dstW / $scale)); $dstH = intval(round($dstH / $scale)); } if ($timestamp) { // also remove leading underscores (those would trigger a Rewrite) $dstUrl = ltrim($dstUrl, '_') . '/' . filemtime($dstPath); } return $dstUrl; }
/** * Data validation can be done by creating a validateKey method, where * key is the name of the property to validate. * * For generic rules, use addRule($rule, $key1[, $key2...]); */ private function validate($key, $value) { if (method_exists($this, "validate{$key}")) { return call_user_func_array(array($this, "validate{$key}"), $value); } foreach ($this->__rules as $r) { if (array_key_exists($key, $r)) { return enforce($rule, $value); } } }
function redirect($url) { if (strpos($url, '://') == false) { enforce('unitTestEnvironmentException', isset($_SERVER['baseUrl']), "baseUrl not set"); $url = $_SERVER['baseUrl'] . (substr($url, 0, 1) == '/' ? substr($url, 1) : $url); } $this->context->get($url); assertTrue(!$this->hasError(), 'Error in page: ' . $this->errorMessage()); }
function compile() { enforce(isset($_SERVER['basePath']), 'basePath is required for compile'); $isExcluded = function ($path) { $sPath = rtrim(str_replace(array('\\', '/'), array('/', '/'), $path), '/'); if (array_key_exists('excludePath', $_SERVER)) { foreach ($_SERVER['excludePath'] as $excludePath) { $sExcludePath = rtrim(str_replace(array('\\', '/'), array('/', '/'), $excludePath), '/'); if (substr($sPath, 0, strlen($sExcludePath)) === $sExcludePath) { return true; } } } return false; }; $timestamp = microtime(true); echo 'Listing files ..'; $files = array(); foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($_SERVER['basePath'])) as $file) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if ($isExcluded($file)) { continue; } if (!in_array($file->getExtension(), array('php'))) { continue; } $fileContent = file_get_contents($file); if (preg_match('/(?si)function\\s*compile_/', strtolower($fileContent)) === 0) { continue; } $files[] = $file; } echo ' ' . count($files) . "\n"; echo 'Including files ..'; $i = 0; // php include can overwrite variable values so we need to isolate include in a function $includeFile = function ($file) { ob_start(); include_once (string) $file; ob_end_clean(); }; foreach ($files as $file) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if (in_array(realpath($file), get_included_files())) { continue; } $i++; $includeFile($file); } echo ' ' . $i . "\n"; $callables = array(); echo 'Listing compilers ..'; $functions = get_defined_functions(); foreach (array_merge($functions['internal'], $functions['user']) as $function) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if (strpos(strtolower($function), 'compile_') === 0) { $callables[] = $function; } } foreach (get_declared_classes() as $class) { foreach (get_class_methods($class) as $method) { if (microtime(true) > $timestamp + 1) { $timestamp = microtime(true); echo '.'; } if (strpos(strtolower($method), 'compile_') === 0) { $callables[] = array($class, $method); } } } echo ' ' . count($callables) . "\n"; echo "\nRunning " . count($callables) . " compiler(s):\n"; foreach ($callables as $callable) { $id = (is_string($callable) ? $callable : $callable[0] . '::' . $callable[1]) . '()'; echo ' ' . $id; call_user_func($callable); echo "\n"; } echo "Done\n"; }
/** * actually renders the file set */ public function render($mode = 'auto', $size = 'auto') { $c =& $this->config; // shorthand out(''); if ($mode === 'auto') { // do not count readme for decision (otherwise 2 pics and one readme would be only 66% ...) // ignorereadmeCompensate (otherwise 2 pics and one readme would be only 66% ...) $total = $this->totalFiles() - (empty($this->readme_content) ? 0 : 1); if ($total > 0 && $this->thumbCount / $total > $c->GRID_THRESHOLD) { $mode = 'grid'; } else { $mode = 'list'; } } if ($size === 'auto') { if ($mode === 'gallery') { $size = 1280; } if ($mode === 'grid') { $size = 128; } else { $size = 32; } } enforce(is_int($size)); if ($mode === 'gallery') { foreach ($this->fileList as $file) { $o = (object) $file; // shorthand // only images matter if (!isset(self::$thumb_support[$o->ext])) { continue; } $url = Cache::getThumb($c->origUrl . '/' . $o->filename, 'b', $size, $size, false, true, $c->thumbScale, $imgW, $imgH); out("<a href='{$url}' id='" . $file['thumbID'] . "'></a>"); } return; } //for (potentially larger thumbs) enforce(in_array($size, array(32, 64, 128, 256)), 'non-available icon size'); // OLD enforce( in_array($thumbSize, Cache::$PERMITTED_SIZES),'invalid thumb size' ); $ulClass = array("dirList"); $ulClass[] = "dirList-{$mode}"; $ulClass[] = "dirList-{$size}"; $ulClass[] = "dirList-{$mode}-{$size}"; /* use singleCol rather than styling dirList list width 780px * since singeCol is already adjust-styled for Mobile... */ if ($mode === 'list') { $ulClass[] = 'singleCol'; } outPush("<ul class='" . implode(' ', $ulClass) . "'>", $c->indent); if (count($this->fileList) < 2) { //if empty aka only .. in there out("<li class='item item-empty'>This directory is empty.</li>"); } // odd-even class $even = true; // iterate file-list foreach ($this->fileList as $file) { $o = (object) $file; // shorthand $liClass = array('item'); if ($even) { $liClass[] = 'item-even'; } $even = !$even; // links open in external tab $target = $o->type === 'link' ? " target='_blank'" : ''; // single-column (folders and other no-downloaders) $hasDownload = $o->type === 'file'; $singleCol = !$hasDownload; if ($singleCol) { $liClass[] = 'item-singleCol'; } // computer right icon and path, default fallback. $iconBaseUrl = $c->ICONURL . $size . '/'; $iconUrl = $iconBaseUrl . $o->icon; $iconPath = $this->ROOT . '/' . $c->ICONPATH . $size . '/'; if (!is_file($iconPath . $o->icon)) { error_log("missing ICONPATH: " . $iconPath . $o->icon); $iconUrl = $iconBaseUrl . $c->ICON_DEFAULT; } //get prior .meta(data) file $meta = array(); // assume empty array for now $metaFile = $this->ROOT . $c->origUrl . '/' . $o->filename . '.meta'; if (is_file($metaFile)) { $metaString = file_get_contents($metaFile); $metaString = str_replace('\\\\r\\\\n', '<br>', $metaString); $meta = json_decode($metaString); } $title = $o->filename; if (isset($meta->caption)) { $title = json_clean($meta->caption); } // COULDO: // $download-Only stuff gets singleCol and download-Button... $iconOrThumb = isset(self::$thumb_support[$o->ext]) ? 'thumb' : 'icon'; $liClass[] = $iconOrThumb; outPush("<li class='" . implode(' ', $liClass) . "'>"); $thumbID = isset($o->thumbID) ? " data-thumbid='{$o->thumbID}'" : ''; outPush("<a class='view'{$thumbID}{$target} href='{$o->link}' title='{$o->title}'>"); if ($iconOrThumb === 'thumb') { $imgW = $imgH = 0; $url = Cache::getThumb($c->origUrl . '/' . $o->filename, 'b', $size, $size, false, true, $c->thumbScale, $imgW, $imgH); $marginTop = floor(($size - $imgH) / 2) . 'px'; $marginLeft = floor(($size - $imgW) / 2) . 'px'; out("<img src='{$url}' alt='{$title}' width='{$imgW}' height='{$imgH}' style='margin-top:{$marginTop};margin-left:{$marginLeft}'>"); } else { out("<img src='{$iconUrl}' alt='' width='{$size}' height='{$size}'>"); } if ($o->size !== null && $o->size !== '') { out("<span class='filesize'>" . self::humanSize($o->size) . "</span>"); } out("<span class='filename'>{$title}</span>"); outPop("</a>"); if ($hasDownload) { out("<a class='download neverprint' title='Herunterladen' href='?download={$o->link}'><span>Download</span></a>"); } outPop("</li>"); } // foreach $file outPop("</ul>"); if ($mode !== 'list') { out("<hr class='clear'/>"); } out("<div style='text-align:center;font-size: x-small;color:#888'>powered by " . "<a href='http://github.com/fran-kee/dirList' target='_blank'>" . "dirList</a></div>"); }