/** * Please bootstrap first, than run the application! * * Run a application, let application accept a request, route the request, * dispatch to controller/action, render response and return response to client finally. * * @param array $get Array of variables passed to the current script via the URL parameters. * @param array $post Array of variables passed to the current script via the HTTP POST method. * @param array $cookie Array of variables passed to the current script via HTTP Cookies. * * @throws \LogicException If application not bootstrapped. * @return void */ public static function run(array $get, array $post, array $cookie) { $cli = array(); if (Sapi::isCli()) { $cli = Cli::parse((array) Registry::get('env')->argv); if (count($cli) < 1 || isset($cli['list'])) { Cli::absorb(); exit(0); } } $conf = Registry::get('conf'); $prefix = Str::ensureTrailing('\\', $conf['app']['name']); $repository = BASE_PATH . 'app/' . $conf['app']['name'] . '/Controller'; if (isset($cli['controller']) && $cli['controller'] == 'core') { $prefix = 'Pimf\\'; $repository = BASE_PATH . 'pimf-framework/core/Pimf/Controller'; } $resolver = new Resolver(new Request($get, $post, $cookie, $cli), $repository, $prefix); $sessionized = Sapi::isWeb() && $conf['session']['storage'] !== ''; if ($sessionized) { Session::load(); } $pimf = $resolver->process(); if ($sessionized) { Session::save(); Cookie::send(); } $pimf->render(); }
/** * @param Request $request * @param string $repositoryPath * @param string $prefix * * @throws Resolver\Exception */ public function __construct(Request $request, $repositoryPath = '/Controller', $prefix = 'Pimf\\') { $conf = Registry::get('conf'); $controllerName = $request->fromGet()->get('controller'); if ($conf['app']['routeable'] === true) { $target = Registry::get('router')->find(); if ($target instanceof \Pimf\Route\Target) { $controllerName = $target->getController(); } } if (Sapi::isCli() && $conf['environment'] == 'production') { $controllerName = $request->fromCli()->get('controller'); } if (!$controllerName) { $controllerName = $conf['app']['default_controller']; } $this->repositoryPath = $repositoryPath; $this->request = $request; $this->controllerClass = $prefix . 'Controller\\'; $basepath = $this->repositoryPath . '/'; $controller = ucfirst($controllerName); if (Str::isEvilPath($basepath . $controller)) { throw new Bomb('directory traversal attack is not funny!'); } $this->controllerPath = $basepath . $controller . '.php'; if (!file_exists($this->controllerPath)) { throw new Bomb('no controller found at the repository path; ' . $this->controllerPath); } }
/** * Get a new session ID that isn't assigned to any current session. * * @return string */ public function id() { // just return any string since the Cookie storage has no idea. if ($this instanceof \Pimf\Session\Storages\Cookie) { return String::random(40); } // we'll find an random ID here. do { $session = $this->load($key = String::random(40)); } while ($session !== null); return $key; }
/** * Create a new cache storage instance. * * @param string $storage * * @return CS\Apc|CS\Dba|CS\File|CS\Memcached|CS\Memory|CS\Pdo|CS\Redis|CS\WinCache * @throws \RuntimeException */ protected static function factory($storage) { $conf = Registry::get('conf'); switch ($storage) { case 'apc': return new CS\Apc($conf['cache']['key']); case 'file': return new CS\File($conf['cache']['storage_path']); case 'pdo': return new CS\Pdo(Pdo\Factory::get($conf['cache']['database']), $conf['cache']['key']); case 'memcached': return new CS\Memcached(Memcached::connection(), $conf['cache']['key']); case 'memory': return new CS\Memory(); case 'redis': return new CS\Redis(Redis::database()); case 'wincache': return new CS\WinCache($conf['cache']['key']); case 'dba': return new CS\Dba(String::ensureTrailing('/', $conf['cache']['storage_path']) . $conf['cache']['key']); default: throw new \RuntimeException("Cache storage {$storage} is not supported."); } }
/** * @param array $commands * * @return array */ public static function parse(array $commands) { $cli = array(); parse_str(implode('&', array_slice($commands, 1)), $cli); $command = current(array_keys((array) $cli, '')); if (String::contains($command, ':')) { list($controller, $action) = explode(':', $command); $cli['controller'] = $controller; $cli['action'] = $action; } return $cli; }
/** * Determine if the current URI matches a given pattern. * * @param string $pattern * * @return bool */ public static function is($pattern) { return Str::is($pattern, static::current()); }
/** * Load the session for the current request. * * @param null|string $key */ public function load($key) { if ($key !== null) { $this->session = $this->storage->load($key); } // If the session doesn't exist or is invalid. if (is_null($this->session) or static::expired($this->session)) { $this->exists = false; $this->session = $this->storage->fresh(); } // A CSRF token is stored in every session to protect // the application from cross-site request if (!$this->has(Session::CSRF)) { $this->put(Session::CSRF, String::random(40)); } }
/** * Get cleaner URLs or old-fashioned » RFC 3986 URL-query string. * * @param string $route controller/action * @param array $params * @param null $https * @param bool $asset * * @return string */ public static function compute($route = '', array $params = array(), $https = null, $asset = false) { // if your application should work with RFC 3986 URL-query strings $conf = Registry::get('conf'); if ($conf['app']['routeable'] === false) { list($controller, $action) = explode('/', $route); $params = array_merge(compact('controller', 'action'), $params); return Str::ensureTrailing('/', self::format($https, $asset)) . '?' . http_build_query($params, null, '&'); } // otherwise PIMF will serve you cleaner URLs $slug = implode('/', $params); if ($slug != '') { $slug = '/' . $slug; } return self::to($route, $https, $asset) . $slug; }