/** * @ignore */ public static function renderview($uObject) { if (self::$engine === null) { $tPath = Io::translatePath(Config::get('raintpl/path', '{core}include/3rdparty/raintpl/inc')); require $tPath . '/rain.tpl.class.php'; raintpl::configure('base_url', null); raintpl::configure('tpl_dir', $uObject['templatePath']); raintpl::configure('tpl_ext', '.rain'); raintpl::configure('cache_dir', Io::translatePath('{writable}cache/raintpl/')); if (Framework::$disableCaches) { raintpl::configure('check_template_update', true); } self::$engine = new \RainTPL(); } else { self::$engine = new \RainTPL(); } self::$engine->assign('model', $uObject['model']); if (is_array($uObject['model'])) { foreach ($uObject['model'] as $tKey => $tValue) { self::$engine->assign($tKey, $tValue); } } foreach (Framework::$variables as $tKey => $tValue) { self::$engine->assign($tKey, $tValue); } self::$engine->draw($uObject['templateFile']); }
/** * @ignore */ public static function renderview($uObject) { if (self::$engine === null) { $tPath = Io::translatePath(Config::get('smarty/path', '{core}include/3rdparty/smarty/libs')); require $tPath . '/Smarty.class.php'; self::$engine = new \Smarty(); self::$engine->setTemplateDir($uObject['templatePath']); self::$engine->setCompileDir(Io::translatePath('{writable}cache/smarty/')); if (Framework::$disableCaches) { self::$engine->force_compile = true; } } else { self::$engine->clearAllAssign(); } self::$engine->assignByRef('model', $uObject['model']); if (is_array($uObject['model'])) { foreach ($uObject['model'] as $tKey => $tValue) { self::$engine->assignByRef($tKey, $tValue); } } foreach (Framework::$variables as $tKey => $tValue) { self::$engine->assignByRef($tKey, $tValue); } self::$engine->display($uObject['templateFile']); }
/** * @ignore */ public static function renderview($uObject) { if (self::$engine === null) { $tPath = Io::translatePath(Config::get('phptal/path', '{core}include/3rdparty/PHPTAL')); require $tPath . '/PHPTAL.php'; self::$engine = new \PHPTAL(); } else { unset(self::$engine); // I just don't want to do it in this way, // but phptal.org documentation says it so. self::$engine = new \PHPTAL(); } self::$engine->set('model', $uObject['model']); if (is_array($uObject['model'])) { foreach ($uObject['model'] as $tKey => $tValue) { self::$engine->set($tKey, $tValue); } } foreach (Framework::$variables as $tKey => $tValue) { self::$engine->set($tKey, $tValue); } self::$engine->setForceReparse(false); self::$engine->setTemplateRepository($uObject['templatePath']); self::$engine->setPhpCodeDestination(Io::translatePath('{writable}cache/phptal/')); self::$engine->setOutputMode(PHPTAL::HTML5); self::$engine->setEncoding('UTF-8'); self::$engine->setTemplate($uObject['templateFile']); if (Framework::$disableCaches) { self::$engine->prepare(); } self::$engine->echoExecute(); }
/** * @ignore */ public function mapDirectory($uDirectory, $uExtension, $uAction, array $uArgs) { $tMap = FileSystem::mapFlatten(Io::translatePath($uDirectory), '*' . $uExtension, true, true); array_unshift($uArgs, $uAction); $tPath = implode('/', $uArgs); if (in_array($tPath, $tMap, true)) { $this->view($uDirectory . $tPath . $uExtension); return true; } return false; }
/** * @ignore */ public static function viewFile($uView, $uModel = null) { $tViewFilePath = Io::translatePath($uView); $tViewFileInfo = pathinfo($tViewFilePath); if (self::$viewEngines === null) { self::$viewEngines = Config::get('views/viewEngineList', array()); } if (!isset(self::$viewEngines[$tViewFileInfo['extension']])) { $tViewFileInfo['extension'] = Config::get('views/defaultViewExtension', 'php'); } $tTemplatePath = $tViewFileInfo['dirname'] . '/'; $tViewFile = $tViewFileInfo['basename']; $tViewArray = array('templatePath' => &$tTemplatePath, 'templateFile' => &$tViewFile, 'compiledFile' => hash('adler32', $uView) . '-' . $tViewFileInfo['basename'], 'model' => &$uModel); call_user_func(self::$viewEngines[$tViewFileInfo['extension']] . '::renderview', $tViewArray); }
/** * @ignore */ public static function renderview($uObject) { $tInputFile = $uObject['templatePath'] . $uObject['templateFile']; $tOutputFile = Io::translatePath('{writable}cache/md/' . $uObject['compiledFile']); if (Framework::$disableCaches || !Io::isReadableAndNewer($tOutputFile, filemtime($tInputFile))) { if (self::$engine === null) { self::$engine = new MarkdownExtra(); } $tInput = Io::read($tInputFile); $tOutput = self::$engine->transform($tInput); Io::writeSerialize($tOutputFile, $tOutput); echo $tOutput; } else { echo Io::readSerialize($tOutputFile); } }
/** * @ignore */ public static function renderview($uObject) { if (self::$engine === null) { $tPath = Io::translatePath(Config::get('twig/path', '{core}include/3rdparty/twig/lib/Twig')); require $tPath . '/Autoloader.php'; Twig_Autoloader::register(); self::$loader = new \Twig_Loader_Filesystem($uObject['templatePath']); $tOptions = array('cache' => Io::translatePath('{writable}cache/twig/')); if (Framework::$disableCaches) { $tOptions['auto_reload'] = true; } self::$engine = new \Twig_Environment(self::$loader, $tOptions); } $model = array('model' => &$uObject['model']); if (is_array($uObject['model'])) { $model = array_merge($model, $uObject['model']); } $model = array_merge($model, Framework::$variables); echo self::$engine->render($uObject['templateFile'], $model); }
/** * @ignore * * @throws \Exception */ public static function renderview($uObject) { $tInputFile = $uObject['templatePath'] . $uObject['templateFile']; $tOutputFile = Io::translatePath('{writable}cache/cshtml/' . $uObject['compiledFile']); if (Framework::$disableCaches || !Io::isReadableAndNewer($tOutputFile, filemtime($tInputFile))) { if (self::$engine === null) { self::$engine = new RazorViewRenderer(); } if (Framework::$readonly) { throw new \Exception('Framework runs in read only mode.'); } self::$engine->generateViewFile($tInputFile, $tOutputFile); } // variable extraction $model = $uObject['model']; if (is_array($model)) { extract($model, EXTR_SKIP | EXTR_REFS); } extract(Framework::$variables, EXTR_SKIP | EXTR_REFS); require $tOutputFile; }
/** * Loads the default configuration for the current application. * * @uses Config::loadFile() * @throws \Exception if any extension is not found * @return array loaded configuration */ public static function load() { $tConfigFiles = array(Framework::$corepath . 'config.json'); if (Framework::$application !== null) { Io::glob(Framework::$application->path . 'config/', '*.json', Io::GLOB_RECURSIVE | Io::GLOB_FILES, "", $tConfigFiles); } $tLastModified = Io::getLastModified($tConfigFiles); $tOutputFile = Io::translatePath('{writable}cache/config'); if (!Framework::$disableCaches && Io::isReadableAndNewer($tOutputFile, $tLastModified)) { self::$loadedFromCache = true; return Io::readSerialize($tOutputFile); } $tConfig = array(); foreach ($tConfigFiles as $tFile) { self::loadFile($tConfig, $tFile, true); } if (isset($tConfig['extensionList'])) { foreach ($tConfig['extensionList'] as $tExtension) { $tFile = Framework::$corepath . 'src/Scabbia/Extensions/' . $tExtension . '/config.json'; if (file_exists($tFile)) { self::loadFile($tConfig, $tFile, false); continue; } if (Framework::$application !== null) { $tFile = Framework::$application->path . 'Extensions/' . $tExtension . '/config.json'; if (file_exists($tFile)) { self::loadFile($tConfig, $tFile, false); continue; } } throw new \Exception('extension not found - ' . $tExtension); } } self::$loadedFromCache = false; if (!Framework::$readonly) { Io::writeSerialize($tOutputFile, $tConfig); } return $tConfig; }
/** * Executes a single event. * * @param string $uState state object * @param mixed $uEventArgs arguments for the event * * @return bool whether the event is invoked or not */ public static function invokeSingle($uState, $uEventArgs = null) { // if (self::$disabled) { // return null; // } if ($uState[0] === 'loadClass') { class_exists($uState[1], true); } elseif ($uState[0] === 'include') { include Io::translatePath($uState[1]); } elseif ($uState[0] === 'callback') { if (is_array($uState[1])) { self::$eventDepth[] = get_class($uState[1][0]) . '::' . $uState[1][1] . '()'; } else { self::$eventDepth[] = '\\' . $uState[1] . '()'; } $tReturn = call_user_func($uState[1], $uEventArgs); array_pop(self::$eventDepth); if ($tReturn === false) { return false; } } return true; }
/** * Generates and outputs a captcha image * * @param string $uCookieName name of the cookie which will be stored on the client side * * @return string generated captcha code */ public static function generate($uCookieName = 'captcha') { $tFontFile = Io::translatePath(Config::get('captcha/fontFile', '{core}resources/fonts/KabobExtrabold.ttf')); $tFontSize = (int) Config::get('captcha/fontSize', 45); $tLength = (int) Config::get('captcha/length', 8); // pick a random word $tCode = String::generatePassword($tLength); // create a random gray shade $tColorScale = rand(40, 120); // allocate the image and colors $tImageCanvas = imagecreatetruecolor(300, 80); $tColorBackground = imagecolorallocate($tImageCanvas, 255, 255, 255); $tColorBackgroundChars = imagecolorallocatealpha($tImageCanvas, $tColorScale, $tColorScale, $tColorScale, 80); $tColorTextShadow = imagecolorallocatealpha($tImageCanvas, 255, 255, 255, 20); $tColorText = imagecolorallocatealpha($tImageCanvas, $tColorScale + 25, $tColorScale + 10, $tColorScale + 10, 30); // clear the background imagefilledrectangle($tImageCanvas, 0, 0, 300, 80, $tColorBackground); // create the background letters $tBackgroundChars = 'abcdefghijklmnopqrstuvwxyz'; for ($i = 0; $i < rand(60, 120); $i++) { // randomize the place and angle $x = rand(-50, 300); $y = rand(-50, 80); $tAngle = rand(-90, 90); imagettftext($tImageCanvas, $tFontSize, $tAngle, $x, $y, $tColorBackgroundChars, $tFontFile, $tBackgroundChars[rand(0, strlen($tBackgroundChars) - 1)]); } // randomize the start of the code $x = 50 + rand(-40, 30 - (strlen($tCode) - 6) * 24); $y = 56 + rand(-8, 8); // write the code letter-by-letter for ($i = 0; $i < strlen($tCode); $i++) { // angle is random $tAngle = rand(-10, 10); // create the shadow for the letter for ($ax = -1; $ax < 0; $ax++) { for ($ay = -1; $ay < 0; $ay++) { imagettftext($tImageCanvas, $tFontSize, $tAngle, $x + $ax, $y + $ay, $tColorTextShadow, $tFontFile, $tCode[$i]); } } // create the letter imagettftext($tImageCanvas, $tFontSize, $tAngle, $x, $y, $tColorText, $tFontFile, $tCode[$i]); // calculate the place of the next letter $y += rand(-2, 2); $tTemp = imagettfbbox($tFontSize, 0, $tFontFile, $tCode[$i]); $x += $tTemp[2] + rand(-4, 0); } // fancy border imagerectangle($tImageCanvas, 0, 0, 299, 79, $tColorText); imagerectangle($tImageCanvas, 1, 1, 298, 78, $tColorBackground); // store the code in session Session::set($uCookieName, $tCode); // try to avoid caching header('Expires: Thu, 01 Jan 1970 00:00:00 GMT', true); header('Pragma: public', true); header('Cache-Control: no-store, no-cache, must-revalidate', true); header('Cache-Control: pre-check=0, post-check=0, max-age=0'); header('Content-Type: image/png', true); header('Content-Disposition: inline;filename=' . $uCookieName . '.png', true); // clean up imagepng($tImageCanvas); imagedestroy($tImageCanvas); // return the code return $tCode; }
/** * Invokes the startup methods just for framework extensions so other parties can take over execution. */ public static function run() { Request::init(); // determine active application $tSelectedApplication = null; foreach (self::$applications as $tApplication) { if (count($tApplication['endpoints']) > 0) { foreach ($tApplication['endpoints'] as $tEndpoint) { foreach ((array) $tEndpoint['address'] as $tEndpointAddress) { if (Request::matchesHostname($tEndpointAddress)) { $tSelectedApplication = $tApplication; break 3; } } } } else { $tSelectedApplication = $tApplication; break; } } // construct application object if ($tSelectedApplication !== null) { self::$application = new Application($tSelectedApplication['namespace'], $tSelectedApplication['directory']); } // load configuration w/ extensions Config::$default = Config::load(); // include files foreach (Config::get('includeList', array()) as $tInclude) { $tIncludePath = pathinfo(Io::translatePath($tInclude)); $tFiles = Io::glob($tIncludePath['dirname'] . '/', $tIncludePath['basename'], Io::GLOB_FILES); if ($tFiles !== false) { foreach ($tFiles as $tFilename) { //! todo require_once? include $tFilename; } } } // loadClass classes foreach (Config::get('loadClassList', array()) as $tClass) { class_exists($tClass, true); } // events foreach (Config::get('eventList', array()) as $tLoad) { if ($tLoad['name'] === 'load') { Events::invokeSingle(array($tLoad['type'], $tLoad['value'])); continue; } Events::register($tLoad['name'], $tLoad['type'], $tLoad['value']); } Request::setRoutes(); // output handling ob_start('Scabbia\\Framework::output'); ob_implicit_flush(false); try { // run extensions $tParms = array(); Events::invoke('pre-run', $tParms); // ignite application if ($tSelectedApplication !== null) { self::$application->before->invoke(); $tReturn = self::$application->callbacks->invoke(); self::$application->after->invoke(); if (self::$application->otherwise !== null && $tReturn !== false) { call_user_func(self::$application->otherwise); return false; } } } catch (CustomException $ex) { if ($tSelectedApplication !== null) { call_user_func(self::$application->onError, $ex->type, $ex->title, $ex->getMessage()); } return false; } return true; }
/** * Logs with an arbitrary level. * * @param string $uClass * @param mixed $uLevel * @param array $uContext * @return null */ public static function write($uClass, $uLevel, array $uContext = array()) { if (!isset($uContext['type'])) { $uContext['type'] = $uLevel === LogLevel::DEBUG || $uLevel === LogLevel::INFO ? 'log' : 'error'; } self::$typeCounts[$uContext['type']]++; $uContext['class'] = $uClass; $uContext['category'] = $uLevel; $uContext['ip'] = $_SERVER['REMOTE_ADDR']; if (isset($uContext['message'])) { $uContext['message'] = String::prefixLines($uContext['message'], '- ', PHP_EOL); } if (isset($uContext['file'])) { if (Framework::$development) { $uContext['location'] = Io::extractPath($uContext['file']); if (isset($uContext['line'])) { $uContext['location'] .= ' @' . $uContext['line']; } } else { $uContext['location'] = pathinfo($uContext['file'], PATHINFO_FILENAME); } } else { $uContext['location'] = '-'; } $uContext['stackTrace'] = array(); foreach (array_slice(debug_backtrace(), 2) as $tFrame) { $tArgs = array(); /* if (isset($tFrame['args'])) { foreach ($tFrame['args'] as $tArg) { $tArgs[] = var_export($tArg, true); } } */ if (isset($tFrame['class'])) { $tFunction = $tFrame['class'] . $tFrame['type'] . $tFrame['function']; } else { $tFunction = $tFrame['function']; } if (isset($tFrame['file'])) { if (Framework::$development) { $tLocation = Io::extractPath($tFrame['file']); if (isset($tFrame['line'])) { $tLocation .= ' @' . $tFrame['line']; } } else { $tLocation = pathinfo($tFrame['file'], PATHINFO_FILENAME); } } else { $tLocation = '-'; } $uContext['stackTrace'][] = $tFunction . '(' . implode(', ', $tArgs) . ') in ' . $tLocation; } $uContext['eventDepth'] = Events::$eventDepth; Events::$disabled = true; if (!Framework::$readonly) { $tContent = '+ ' . String::format(Logger::$line, $uContext); $tFilename = Io::translatePath('{writable}logs/' . String::format(Logger::$filename, $uContext), true); Io::write($tFilename, $tContent, LOCK_EX | FILE_APPEND); } self::$console[] = $uContext; Events::$disabled = false; if (isset($uContext['halt']) && $uContext['halt']) { Events::invoke('reportError', $uContext); Framework::end(-1); } }
/** * @ignore * * @throws \Exception */ public static function getDirectory($uSelectedDirectory, $uSubPath) { $tPath = rtrim(Io::translatePath($uSelectedDirectory['path']), '/'); foreach (explode('/', ltrim($uSubPath, '/')) as $tSubDirectory) { if (strlen($tSubDirectory) === 0 || $tSubDirectory[0] === '.') { break; } $tPath .= '/' . $tSubDirectory; } if (!file_exists($tPath)) { throw new \Exception('asset not found.'); } if (isset($uSelectedDirectory['autoViewer/defaultPage'])) { if (is_dir($tPath)) { $tPath = rtrim($tPath, '/') . '/' . $uSelectedDirectory['autoViewer/defaultPage']; } if (isset($uSelectedDirectory['autoViewer/header'])) { Views::viewFile($uSelectedDirectory['autoViewer/header']); } Views::viewFile($tPath); if (isset($uSelectedDirectory['autoViewer/footer'])) { Views::viewFile($uSelectedDirectory['autoViewer/footer']); } return true; } if (is_dir($tPath)) { return false; } header('Content-Type: ' . Mime::getType(pathinfo($tPath, PATHINFO_EXTENSION)), true); header('Content-Transfer-Encoding: binary', true); // header('ETag: "' . md5_file($tPath) . '"', true); readfile($tPath); return true; }
/** * Outputs all parts in single output. * * @returns string Output */ public function output() { $tOutputFile = Io::translatePath('{writable}cache/assets/' . $this->outputName); foreach ($this->classes as $tClassName) { $tOutputFile .= '_' . $tClassName; } $tOutputFile .= '.' . $this->outputType; if (!Framework::$disableCaches && Io::isReadable($tOutputFile, $this->cacheTtl)) { return Io::read($tOutputFile); } $tContent = ""; foreach ($this->parts as $tPart) { if ($tPart['class'] !== null && !in_array($tPart['class'], $this->classes, true)) { continue; } if ($tPart['bindtype'] === 'function') { $tValue = call_user_func($tPart['value'], $tPart); $tDescription = 'function ' . $tPart['value']; } elseif ($tPart['bindtype'] === 'string') { $tValue = $tPart['value']; $tDescription = 'string'; } else { $tValue = Io::read(Io::translatePath($tPart['value'])); $tDescription = 'file ' . $tPart['value']; } if (array_key_exists($tPart['parttype'], self::$fileProcessors)) { $tContent .= call_user_func(self::$fileProcessors[$tPart['parttype']], $tValue, $tDescription); } else { $tContent .= $tValue; } } if (array_key_exists($this->outputType, self::$packProcessors)) { $tContent = call_user_func(self::$packProcessors[$this->outputType], $tContent); } if (!Framework::$readonly) { Io::write($tOutputFile, $tContent); } return $tContent; }
/** * @ignore */ public function storageGarbageCollect() { if ($this->storageTtl > 0) { // path $tPath = Io::translatePath($this->path, true); Io::garbageCollect($tPath, $this->storageTtl); } }
/** * @ignore */ public static function extensionLoad() { self::$cachePath = Io::translatePath('{writable}cache/media/', true); self::$cacheTtl = (int) Config::get('media/cacheTtl', 120); }