public function clear() { $files = Directory::search($this->m_cache, Directory::R_ANY); foreach ($files as $file) { unlink($file); Log::debug(sprintf('[delete] %s', str_replace('\\', '/', $file))); } return $files; }
/** * Application entry point. */ public static function start() { // hide errors error_reporting(E_ALL); ini_set('display_errors', 0); // use UTC on server date_default_timezone_set('UTC'); // error/exception Handlers set_error_handler([__CLASS__, 'error']); set_exception_handler([__CLASS__, 'exception']); register_shutdown_function([__CLASS__, 'shutdown']); // configuration define('BRAMBLE_URL', self::get_app_url()); Stopwatch::start()->register(); Log::time('~init'); // handle request Request::execute(); }
/** * Connection factory * @param \stdClass $options * @return IDatabase */ public static function connect(\stdClass $options) { if (!self::$c_databases) { self::$c_databases = []; } $key = json_encode($options); if (!isset(self::$c_databases[$key])) { $adapter = $options->adapter; $class = isset(self::$c_adapters[$adapter]) ? self::$c_adapters[$adapter] : $adapter; //try { self::$c_databases[$key] = new $class($options); //} catch(\Exception $e) { //throw ServiceException::code(ServiceException::E_DB_CONNECT, NULL, $e); //} } Log::debug(sprintf('[database] %s(%s)', $options->adapter, $options->database)); return self::$c_databases[$key]; }
private function create_page($rows) { $data = array_merge_recursive(TemplateBase::load(), ['Page' => reset($rows)]); Log::time('load'); return $this->m_manager->evaluate('Page', $data); }
/** * Performs the specified action. * @return Response * @throws KnownException */ public function execute() { $this->before(); // map action to method // $this->action_[method]_name() $route = $this->m_request->route(); $method = $route->method() ? $this->method() : ''; $action = sprintf('action_%s_%s', $method, $this->m_request->route()->action()); Log::debug(sprintf('[action] %s->%s()', get_class($this), $action)); if (!method_exists($this, $action)) { throw new KnownException('E_ROUTING_ACTION_NOT_FOUND', ['uri' => $this->m_request->uri(), 'method' => $this->m_request->method()]); } // fill in parameters automatically $dynamic = array_change_key_case($this->params()); $args = []; $reflect = new \ReflectionMethod($this, $action); foreach ($reflect->getParameters() as $param) { $name = $param->getName(); $name_lower = strtolower($name); $value = NULL; if (array_key_exists($name_lower, $dynamic)) { $value = $dynamic[$name_lower]; if ($value instanceof \Closure) { $value = $value(); } Log::debug(sprintf('[param] $%s from dynamic param', $name)); // warn about missing type hint if applicable if (is_object($value) && get_class($value) !== 'stdClass' && !($param_class = $param->getClass())) { Log::debug(sprintf('[param] $%s should have type hint %s', $name, get_class($value))); } } else { if (($arg = $this->m_request->route()->param($name)) !== NULL) { $value = $arg; Log::debug(sprintf('[param] $%s from Route param', $name)); } else { if (isset($_REQUEST[$name])) { $value = $_REQUEST[$name]; Log::debug(sprintf('[param] $%s from $_REQUEST', $name)); } else { if ($param->isDefaultValueAvailable()) { $value = $param->getDefaultValue(); Log::debug(sprintf('[param] $%s from default', $name)); } else { Log::debug(sprintf('[param] $%s unmatched', $name)); } } } } // pass unmatched params as NULL for now $args[] = $value; } Log::time('~before'); $body = $reflect->invokeArgs($this, $args); $this->m_response->body($body, true); $this->after(); return $this->m_response; }
private function create_posts($title, $rows) { $data = array_merge_recursive(TemplateBase::load(), ['Posts' => ['title' => $title, 'list' => self::create_posts_list($rows)]]); Log::time('load'); return $this->m_manager->evaluate('Posts', $data); }
public function action__content() { // load posts/pages // parse and create thumbnails // in the future, I could alert about unused images/refs, dead links, etc. $images = []; $subvert_options = ['image_callback' => function (&$attributes) use(&$images) { $src = $attributes['src']; if (!isset($images[$src])) { $images[$src] = []; } $width = isset($attributes['width']) && ctype_digit($attributes['width']) ? (int) $attributes['width'] : 0; $height = isset($attributes['height']) && ctype_digit($attributes['height']) ? (int) $attributes['height'] : 0; $key = sprintf('%sx%s', $width, $height); if (!isset($images[$src][$key])) { $images[$src][$key] = ['width' => $width, 'height' => $height]; } }, 'link_callback' => function (&$attributes) { }]; $res = Database::query(' SELECT Content FROM Objects WHERE Type IN (:types) ', ['types' => ['post', 'page']]); foreach ($res->column() as $content) { Subvert::Parse($content, $subvert_options); } Log::time('load+subvert'); ksort($images, SORT_NATURAL); foreach ($images as $image_path => $versions) { foreach ($versions as $version => $dimensions) { if ($version !== '0x0') { $parts = pathinfo($image_path); $thumbnail_path = sprintf('%s/%s-%s.%s', $parts['dirname'], $parts['filename'], $version, $parts['extension']); Log::debug("[resize] {$thumbnail_path}]"); $src = BRAMBLE_DIR . $image_path; $dst = BRAMBLE_DIR . $thumbnail_path; if (file_exists($src)) { $image = GdImage::load($src); $image->resize($dimensions['width'], $dimensions['height'])->save($dst)->dispose(); $image->dispose(); } } } } Log::time('thumbnails'); return NULL; }
/** * Execute the controller action. */ public static function execute() { $instance = self::get(); // take over buffering if (ob_get_level() === 0) { ob_start(); } Log::debug("[uri] {$instance->method()} /{$instance->m_uri}"); try { $routes = RouteMap::instance(); $instance->m_route = $routes->find($instance->m_uri, $instance->m_method); if (!$instance->m_route) { throw new KnownException('E_ROUTING_ROUTE_NOT_FOUND', ['uri' => $instance->uri(), 'method' => $instance->method()]); } $controller_class_name = $instance->m_route->controller(); try { $controller = new $controller_class_name($instance); } catch (\Exception $e) { throw new KnownException('E_INTERNAL_CONTROLLER_FAILED'); } if (!$controller instanceof Controller) { throw new KnownException('E_INTERNAL_CONTROLLER_INVALID'); } $response = $controller->execute(); } catch (KnownException $e) { $response = $e->response(); } catch (\Exception $e) { $response = (new KnownException('E_INTERNAL', NULL, $e))->response(); } /*$leaked = ob_get_contents(); if ($leaked) { // ignore for now }*/ ob_end_clean(); // write instrumentation to log Log::time('~response'); Stopwatch::instance()->stop(); $response->body($response->body()); $response->send(); }
private static function create($init) { // todo: remove this! $path = 'c:/tmp/db/bramble.sqlite3'; if (file_exists($path)) { unlink($path); } $tables = self::tables(); Log::time('load'); foreach ($tables as $table) { Database::execute((string) $table); Log::debug("[database] CREATE TABLE {$table->name()}"); } Log::time('create'); $saved = []; foreach ($init as $action) { $sql = $action['sql']; $fill = isset($action['fill']) ? $action['fill'] : []; $load = isset($action['load']) ? $action['load'] : []; $expand = isset($action['expand']) ? explode('/', $action['expand'], 2) : NULL; $variables = self::sql_vars($sql); if (isset($action['data'])) { $rows = $action['data']; if (is_string($rows)) { // load saved by name $rows = $saved[$rows]; } else { $map = isset($action['map']) ? $action['map'] : $variables; // create associative arrays for data $rows = array_map(function ($a) use($map) { return array_combine($map, $a); }, $rows); } foreach ($rows as $row) { foreach ($fill as $variable => $method) { /** @var callable $method */ $method = [self::class, "_{$method}"]; $row[$variable] = $method($row); } foreach ($load as $variable => $query) { $params2 = self::convert_keys(array_intersect_key($row, array_fill_keys(self::sql_vars($query), true))); $res = Database::query($query, $params2); $row[$variable] = $res->single_value(); } if ($expand) { foreach ($row[$expand[0]] as $expanded) { $row[$expand[1]] = $expanded; self::execute_row($sql, $row, $variables); } } else { self::execute_row($sql, $row, $variables); } } if (isset($action['save'])) { $saved[$action['save']] = $rows; } } else { Database::execute($sql); } } Log::time('fill'); }