/** * Makes sure that template and compiler paths are set * @param string $method * @throws KnitException */ public function checkPaths(string $method) { // Path to template files if (!isset($this->diskTemplate)) { throw KnitException::pathNotSet($method, "template", "setTemplatePath"); } // Path to compiler's working directory if (!isset($this->diskCompiler)) { throw KnitException::pathNotSet($method, "compiler", "setCompilerPath"); } }
/** * Handle a knit include * @return string * @throws KnitException */ public function parseIncludeKnit() : string { // exp: include knit="file.knit" $pieces = preg_split('/\\s/', $this->token); $knit = substr($pieces[1], 6, -1); // Return parsed template file try { return (new Template($this->compiler, $knit))->getParsed(); } catch (KnitException $e) { throw KnitException::parseError(sprintf('%1$s included in "%2$s" on line # %4$d', $e->getMessage(), basename($this->file), $this->file, $this->lineNum)); } }
/** * Sandbox constructor. * @param string $knitCompiledPhp * @param array $data * @throws KnitException */ public function __construct(string $knitCompiledPhp, array $data = []) { $this->data = $data; $startTimer = microtime(true); ob_start(); include $knitCompiledPhp; $this->output = ob_get_contents(); ob_end_clean(); if (!defined("COMELY_KNIT") || !defined("COMELY_KNIT_PARSE_TIMER") || !defined("COMELY_KNIT_COMPILED_ON")) { throw KnitException::sandBoxError("Bad or incomplete Knit compiled script"); } if (!is_float(COMELY_KNIT_PARSE_TIMER) || !is_float(COMELY_KNIT_COMPILED_ON)) { throw KnitException::sandBoxError("Compiled PHP script is missing timestamps"); } $this->timers = [COMELY_KNIT_PARSE_TIMER, COMELY_KNIT_COMPILED_ON, microtime(true) - $startTimer]; }
/** * @param array $args * @return array * @throws KnitException */ protected function assertArgs(array $args) : array { // Count passed argument $numArgs = count($args); // Minimum number of arguments if (static::MIN_ARGS > $numArgs) { throw KnitException::parseError(sprintf('expects minimum of %d args, %d passed', static::MIN_ARGS, $numArgs)); } // Maximum number of arguments if (static::MAX_ARGS < $numArgs) { throw KnitException::parseError(sprintf('expects maximum of %d args, %d passed', static::MAX_ARGS, $numArgs)); } // Typecast $asserted = []; foreach (static::ARGS as $index => $arg) { // Check if arg. was passed if (!array_key_exists($index, $args)) { // Not passed, check if default value is available if (!array_key_exists(1, $arg)) { // No default value, throw exception throw KnitException::parseError(sprintf('missing argument %d', $index + 1)); } else { // Set default value $value = $arg[1]; } } else { // Passed value $value = $args[$index]; } // Check if casts match $valueType = $this->getType($value); if ($arg[0] !== "~") { if ($valueType === "str" && preg_match('/^\\$[a-z\\_][a-z0-9\\_\\[\\]\\"\'\\-\\>]+$/i', $value)) { // Variable, ...do nothing? } else { $value = call_user_func($arg[0] . "val", $value); // Cast } } $asserted[] = $value; } // Return args return $asserted; }
/** * @param string $key * @param $value * @throws KnitException */ public function set(string $key, $value) { // Lowercase key $key = strtolower($key); // Check if key is reserved if (in_array($key, $this->reservedKeys)) { throw KnitException::reservedDataKey($key); } // Check value type if (is_object($value)) { // Convert Object to Array $value = json_decode(json_encode($value), true); } if (!is_scalar($value) && !is_null($value) && !is_array($value)) { // Unsupported value type throw KnitException::badAssignedValue($key, gettype($value)); } // Assign $this->data[$key] = $value; }
/** * @return Knit * @throws KnitException */ public function flushCache() : Knit { if (!isset($this->diskCache)) { throw KnitException::pathNotSet(__METHOD__, "cache", "setCachePath"); } $cacheFiles = $this->diskCache->find("knit_*"); foreach ($cacheFiles as $file) { $this->diskCache->delete($file); } return $this; }
/** * @param string $script * @param array $data * @return Sandbox * @throws KnitException */ protected function runSandbox(string $script, array $data) : Sandbox { try { return new Sandbox($script, $data); } catch (\Throwable $e) { throw KnitException::sandBoxError($e->getMessage()); } }
/** * @param string $message * @throws KnitException */ private function throwException(string $message) { throw KnitException::parseError(sprintf('Parsing error "%1$s" in template file "%2$s" on line # %4$d near "%5$s"', $message, basename($this->file), $this->file, $this->lineNum, substr($this->token, 0, 16) . "...")); }
/** * @return string * @throws KnitException */ public function getCachePath() : string { if (!isset($this->diskCache)) { throw KnitException::pathNotSet(__METHOD__, "cache", "setCachePath"); } return $this->diskCache->getPath(); }