Example #1
0
 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;
 }
Example #2
0
 /**
  * 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();
 }
Example #3
0
 /**
  * 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];
 }
Example #4
0
 private function create_page($rows)
 {
     $data = array_merge_recursive(TemplateBase::load(), ['Page' => reset($rows)]);
     Log::time('load');
     return $this->m_manager->evaluate('Page', $data);
 }
Example #5
0
 /**
  * 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;
 }
Example #6
0
 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);
 }
Example #7
0
    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;
    }
Example #8
0
 /**
  * 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();
 }
Example #9
0
 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');
 }