/** * @param Request $request * @param Request\Response $response */ public function init(Request $request, Request\Response $response) { // Save all request related information $this->request = $request; $this->controller = $request->getController(); $this->input = $request->getInput(); $this->method = $request->getMethod(); $this->response = $response; // Get input params $params = $this->input->getData(); try { if ($this->method === "GET") { // Single method for all get requests $callMethod = "getView"; } else { // Check if we have necessary param to build method name if (!array_key_exists(self::REST_METHOD_PARAM, $params)) { throw new \Exception(sprintf('Http requests must have required parameter "%s"', self::REST_METHOD_PARAM)); } // Method name $callMethod = $this->method . "_" . $params[self::REST_METHOD_PARAM]; $callMethod = \Comely::camelCase($callMethod); } // Check if method exists if (!method_exists($this, $callMethod)) { throw new \Exception('Request method not found'); } // Call method call_user_func([$this, $callMethod]); } catch (\Throwable $t) { $this->response->set("error", $t->getMessage()); } // Send response $this->response->send(); }
/** * Save an instance in repository * * @param $instance * @param string|null $key * @throws RepositoryException */ public function push($instance, string $key = null) { // Repository holds only instances if (!is_object($instance)) { throw RepositoryException::badInstance(); } // Use short/base name of class if $key param is not specified $key = $key ?? \Comely::baseClassName(get_class($instance)); // Save instance $this->instances[$key] = $instance; }
/** * @param array $data * @param $object */ private function setProperties(array $data, $object) { foreach ($data as $key => $value) { $key = \Comely::camelCase($key); if (is_array($value)) { $object->{$key} = new PlainObject(); $this->setProperties($value, $object->{$key}); continue; } else { $object->{$key} = $value; } } }
/** * Framework Kernel constructor. * * @param array $components * @param string $env */ public function __construct(array $components, string $env) { // Create a private dependency injection container $this->container = new Container(); // Run through all passed components foreach ($components as $component) { /// Add to container $this->container->add(\Comely::baseClassName(is_object($component) ? get_class($component) : $component), $component); } // Set variables $this->dateTime = new DateTime(); $this->env = $env; $this->setRootPath(dirname(dirname(dirname(dirname(__DIR__))))); $this->errorHandler = new ErrorHandler($this); // Setup disks instances $this->disks = new Repository(); $this->container->add("disks", $this->disks); $this->disks->push(new Disk($this->rootPath . self::DS . self::CACHE_PATH), "cache"); }
/** * @param string $path * @return string * @throws RouterException */ private function resolvePath(string $path) : string { // Filter path $pathKey = $this->filterPath($path); // Check in predefined routes foreach ($this->routes as $route => $controller) { if (preg_match(sprintf("~^%s\$~", $route), $pathKey)) { // Match found return $controller; } } // Make sure default controllers base directory path is set if (!$this->controllersPath) { throw RouterException::controllersPathNull(); } // Dynamically convert path to class name $pathIndex = -1; $controllerClass = array_map(function ($piece) use(&$pathIndex) : string { $pathIndex++; if ($piece && !in_array($pathIndex, $this->ignorePathIndexes)) { return \Comely::pascalCase($piece); } return ""; }, explode("/", trim(Strings::filter(strtolower($path), "an", false, "/_"), "/"))); $controllerClass = trim(implode("\\", $controllerClass), "\\"); $controllerClass = preg_replace("/\\\\{2,}/", "\\", $controllerClass); // Join PascalCased class name with default namespace preset $controllerClass = $this->controllersNamespace . $controllerClass; // Return name of class return $controllerClass; }
/** * Resolves a variable and applies modifiers * @param string $input * @return string */ private function resolveVariable(string $input) : string { // Split $modifiers = explode("|", trim($input)); $var = $modifiers[0]; unset($modifiers[0]); // Resolve var if (!preg_match('/^\\$[a-z\\_][a-z0-9\\_\\.]+$/i', $var)) { $this->throwException('Bad variable syntax'); } // Explode var into pieces (Array) $pieces = explode(".", $var); $var = $pieces[0]; unset($pieces[0]); // Check if its reserved variable (i.e. being used by foreach/count clause) if (!$this->reserved->has($var)) { // Load from assigned data $var = sprintf('$this->data["%s"]', strtolower(substr($var, 1))); } // Assemble pieces array style foreach ($pieces as $piece) { $var .= sprintf('["%s"]', $piece); } // Apply modifiers foreach ($modifiers as $modifier) { preg_match_all("~'[^']++'|\\([^)]++\\)|[^:]++~", $modifier, $modifier); $modifier = $modifier[0]; $opts = $modifier; unset($opts[0]); $modifier = $modifier[0]; // Check modifier args $opts = array_values($opts); $optsCount = count($opts); for ($i = 0; $i < $optsCount; $i++) { if (preg_match('/^\\$[a-z\\_][a-z0-9\\_\\.]+$/i', $opts[$i])) { // Variable $opts[$i] = $this->resolveVariable($opts[$i]); } elseif (preg_match('/^[0-9][\\.0-9]*$/', $opts[$i])) { // Integer or float $cast = strpos($opts[$i], ".") ? "floatval" : "intval"; $opts[$i] = call_user_func($cast, $opts[$i]); } elseif (in_array(strtolower($opts[$i]), ["true", "false"])) { // Boolean $opts[$i] = boolval($opts[$i]); } elseif (strtolower($opts[$i]) === "null") { // NULL $opts[$i] = null; } else { // String $opts[$i] = str_replace(["'", '""'], "", $opts[$i]); // Remove quotes } } try { $modifierInstance = $this->modifiers->pull($modifier, function ($repo, $key) { // Modifier not instantiated yet $modifierClass = sprintf('Comely\\Knit\\Modifiers\\%s', \Comely::pascalCase($key)); if (!class_exists($modifierClass)) { $this->throwException(sprintf("Modifier '%s' not found", $key)); } $modifier = new $modifierClass(); $repo->push($modifier, $key); return $modifier; }); $var = call_user_func_array([$modifierInstance, "apply"], [$var, $opts]); } catch (\Throwable $e) { $this->throwException(sprintf("Modifier '%s' %s", $modifier, $e->getMessage())); } } return $var; }
/** * @param Request $request * @param Response $response * @throws \Comely\IO\Http\Exception\RequestException */ public function init(Request $request, Response $response) { // Save all request related information $this->request = $request; $this->controller = $request->getController(); $this->input = $request->getInput(); $this->method = $request->getMethod(); $this->response = $response; $this->uri = $request->getUri(); $this->page->setProp("root", $request->getUriRoot()); // Get input params $params = $this->input->getData(); try { // Check if we have necessary param to build method name if (!empty($params[self::REST_METHOD_PARAM])) { $callMethod = $this->method . "_" . $params[self::REST_METHOD_PARAM]; $callMethod = \Comely::camelCase($callMethod); } else { // Necessary param not found if ($this->method !== "GET") { // Throw exception if request method is not GET throw new HttpException(get_called_class(), sprintf('Http requests must have required parameter "%s"', self::REST_METHOD_PARAM)); } // If method is GET, default method is getView $callMethod = "getView"; } // Check if method exists if (!method_exists($this, $callMethod)) { throw new HttpException(get_called_class(), sprintf('Request method "%1$s" not found', $callMethod)); } // Call "callBack" method prior to calling request method call_user_func([$this, "callBack"]); // Call method call_user_func([$this, $callMethod]); } catch (KernelException $e) { $this->response->set("message", $e->getMessage()); } // Check number of props in Response object, if ($this->response->count() !== 1) { // populate "errors" property if there are multiple properties already $this->response->set("errors", array_map(function (array $error) { return $error["formatted"]; }, $this->app->errorHandler()->fetchAll())); } }