/** * {@inheritdoc} * * @param int $offset * @param int $limit * @param array $params * @return array|int|mixed */ public function readSet($offset = 0, $limit = 10, $params = array()) { $select = Db::select('*')->from('test', 't'); if ($limit) { $selectPart = $select->getQueryPart('select'); $selectPart = 'SQL_CALC_FOUND_ROWS ' . current($selectPart); $select->select($selectPart); $select->setLimit($limit); $select->setOffset($offset); } $result = $select->execute('\\Application\\Test\\Row'); if ($limit) { $total = Db::fetchOne('SELECT FOUND_ROWS()'); } else { $total = sizeof($result); } if (sizeof($result) < $total && Request::METHOD_GET == Request::getMethod()) { Response::setStatusCode(206); Response::setHeader('Content-Range', 'items ' . $offset . '-' . ($offset + sizeof($result)) . '/' . $total); } return $result; }
case 406: $title = __("Not Acceptable"); $description = __("The server is not acceptable generating content type described at `Accept` header"); break; case 500: $title = __("Internal Server Error"); $description = __("The server encountered an unexpected condition"); break; case 501: $title = __("Not Implemented"); $description = __("The server does not understand or does not support the HTTP method"); break; case 503: $title = __("Service Unavailable"); $description = __("The server is currently unable to handle the request due to a temporary overloading"); Response::setHeader('Retry-After', '600'); break; default: $title = __("Internal Server Error"); $description = __("An unexpected error occurred with your request. Please try again later"); break; } // check CLI or HTTP request if (Request::isHttp()) { // simple AJAX call, accept JSON if (Request::getAccept(['application/json'])) { $this->useJson(); Messages::addError($description); return null; } // dialog AJAX call, accept HTML
/** * Do process * @return void */ protected function doProcess() { Logger::info("app:process:do"); $module = Request::getModule(); $controller = Request::getController(); $params = Request::getAllParams(); // try to dispatch controller try { // get reflection of requested controller $controllerFile = $this->getControllerFile($module, $controller); $reflection = $this->reflection($controllerFile); // check header "accept" for catch JSON(P) or XML requests, and switch presentation // it's some magic for AJAX and REST requests if ($produces = $reflection->getAccept() and $accept = $this->getRequest()->getAccept()) { // switch statement for $accept switch ($accept) { case Request::ACCEPT_HTML: // with layout // without additional presentation break; case Request::ACCEPT_JSON: $this->useJson(); break; case Request::ACCEPT_JSONP: $this->useJsonp(); break; case Request::ACCEPT_XML: $this->useXml(); break; default: // not acceptable MIME type throw new NotAcceptableException(); break; } } // check call method(s) if ($reflection->getMethod() && !in_array(Request::getMethod(), $reflection->getMethod())) { throw new NotAllowedException(join(',', $reflection->getMethod())); } // check HTML cache if ($reflection->getCacheHtml() && Request::getMethod() == Request::METHOD_GET) { $htmlKey = 'html:' . $module . ':' . $controller . ':' . http_build_query($params); if ($cachedHtml = Cache::get($htmlKey)) { Response::setBody($cachedHtml); return; } } // dispatch controller $dispatchResult = $this->dispatch($module, $controller, $params); } catch (RedirectException $e) { Response::setException($e); if (Request::isXmlHttpRequest()) { // 204 - No Content Response::setStatusCode(204); Response::setHeader('Bluz-Redirect', $e->getMessage()); } else { Response::setStatusCode($e->getCode()); Response::setHeader('Location', $e->getMessage()); } return null; } catch (ReloadException $e) { Response::setException($e); if (Request::isXmlHttpRequest()) { // 204 - No Content Response::setStatusCode(204); Response::setHeader('Bluz-Reload', 'true'); } else { Response::setStatusCode($e->getCode()); Response::setHeader('Refresh', '0; url=' . Request::getRequestUri()); } return null; } catch (\Exception $e) { Response::setException($e); // cast to valid HTTP error code // 500 - Internal Server Error $statusCode = 100 <= $e->getCode() && $e->getCode() <= 505 ? $e->getCode() : 500; Response::setStatusCode($statusCode); $dispatchResult = $this->dispatch(Router::getErrorModule(), Router::getErrorController(), array('code' => $e->getCode(), 'message' => $e->getMessage())); } if ($this->hasLayout()) { Layout::setContent($dispatchResult); $dispatchResult = Layout::getInstance(); } if (isset($htmlKey, $reflection)) { // @TODO: Added ETag header Cache::set($htmlKey, $dispatchResult(), $reflection->getCacheHtml()); Cache::addTag($htmlKey, $module); Cache::addTag($htmlKey, 'html'); Cache::addTag($htmlKey, 'html:' . $module); Cache::addTag($htmlKey, 'html:' . $module . ':' . $controller); } Response::setBody($dispatchResult); }
/** * Render with debug headers * @return void */ public function render() { if ($this->debugFlag && !headers_sent()) { $debugString = sprintf("%fsec; %skb", microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'], ceil(memory_get_usage() / 1024)); $debugString .= '; ' . Request::getModule() . '/' . Request::getController(); Response::setHeader('Bluz-Debug', $debugString); if ($info = Logger::get('info')) { Response::setHeader('Bluz-Bar', json_encode($info)); } else { Response::setHeader('Bluz-Bar', '{"!":"Logger is disabled"}'); } } parent::render(); }
/** * Method OPTIONS * * @return false */ public function methodOptions() { $allow = $this->getMethods(sizeof($this->primary)); Response::setHeader('Allow', join(',', $allow)); return null; // no body }
/** * Check `Method` * * @throws NotAllowedException */ public function checkMethod() { if ($this->getReflection()->getMethod() && !in_array(Request::getMethod(), $this->getReflection()->getMethod())) { Response::setHeader('Allow', join(',', $this->getReflection()->getMethod())); throw new NotAllowedException(); } }
* @accept JSON * @method POST * * @param \Bluz\Crud\Table $crud * @param mixed $primary * @param array $data * @return void|array * @throws BadRequestException * @throws NotImplementedException */ return function ($crud, $primary, $data) { if (!empty($primary)) { // POST + ID is incorrect behaviour throw new NotImplementedException(); } try { $result = $crud->createOne($data); if (!$result) { // system can't create record with this data throw new BadRequestException(); } if (is_array($result)) { $result = join('-', array_values($result)); } } catch (ValidatorException $e) { Response::setStatusCode(400); return ['errors' => $e->getErrors()]; } Response::setStatusCode(201); Response::setHeader('Location', Router::getUrl(Request::getModule(), Request::getController()) . '/' . $result); };
* @accept JSON * @method GET * * @param \Bluz\Crud\Table $crud * @param mixed $primary * @return array */ return function ($crud, $primary) { if (!empty($primary)) { // @throws NotFoundException return [$crud->readOne($primary)]; } else { $params = Request::getParams(); // setup default offset and limit - safe way $offset = Request::getParam('offset', 0); $limit = Request::getParam('limit', 10); if ($range = Request::getHeader('Range')) { list(, $offset, $last) = preg_split('/[-=]/', $range); // for better compatibility $limit = $last - $offset; } Response::setStatusCode(206); $total = 0; $result = $crud->readSet($offset, $limit, $params, $total); if (sizeof($result) < $total) { Response::setStatusCode(206); Response::setHeader('Content-Range', 'items ' . $offset . '-' . ($offset + sizeof($result)) . '/' . $total); } return $result; } };
* @link https://github.com/bluzphp/framework */ /** * @namespace */ namespace Bluz\Application\Helper; use Bluz\Application\Application; use Bluz\Proxy\Request; use Bluz\Proxy\Response; /** * Redirect helper can be declared inside Bootstrap * @param string $url * @return null */ return function ($url) { /** * @var Application $this */ $this->useLayout(false); Response::removeHeaders(); Response::clearBody(); if (Request::isXmlHttpRequest()) { Response::setStatusCode(204); Response::setHeader('Bluz-Redirect', $url); } else { Response::setStatusCode(302); Response::setHeader('Location', $url); } return null; };
<?php /** * REST controller for OPTIONS method * * @category Application * * @author Anton Shevchuk * @created 19.02.15 16:27 */ namespace Application; use Bluz\Controller; use Bluz\Proxy\Response; /** * @accept HTML * @accept JSON * @method OPTIONS * * @param \Bluz\Crud\Table $crud * @param mixed $primary * @param array $data * @return void */ return function ($crud, $primary, $data) { Response::setStatusCode(204); Response::setHeader('Allow', join(',', $data)); };