diff --git a/composer.json b/composer.json index 41543c3..dc4ad6c 100644 --- a/composer.json +++ b/composer.json @@ -50,11 +50,9 @@ "lint": "phpstan --no-progress -cphpstan.neon" }, "suggest": { - "latte/latte": "Latte template engine" - }, - "suggest-dev": { + "latte/latte": "Latte template engine", "tracy/tracy": "Tracy debugger" - }, + }, "replace": { "mikecao/flight": "2.0.2" } diff --git a/flight/Engine.php b/flight/Engine.php index 4f0f60a..4a1ed3f 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -758,9 +758,8 @@ class Engine /** * Gets a url from an alias that's supplied. * - * @param string $alias the route alias - * @param array the params for the route if applicable - * @return string + * @param string $alias the route alias. + * @param array $params The params for the route if applicable. */ public function _getUrl(string $alias, array $params = []): string { diff --git a/flight/template/View.php b/flight/template/View.php index 818a100..21963ee 100644 --- a/flight/template/View.php +++ b/flight/template/View.php @@ -17,32 +17,16 @@ namespace flight\template; */ class View { - /** - * Location of view templates. - * - * @var string - */ + /** @var string Location of view templates. */ public $path; - /** - * File extension. - * - * @var string - */ + /** @var string File extension. */ public $extension = '.php'; - /** - * View variables. - * - * @var array - */ + /** @var array View variables. */ protected $vars = []; - /** - * Template file. - * - * @var string - */ + /** @var string Template file. */ private $template; /** @@ -58,9 +42,9 @@ class View /** * Gets a template variable. * - * @param string $key Key + * @param string $key * - * @return mixed Value + * @return mixed Variable value or `null` if doesn't exists */ public function get($key) { @@ -70,13 +54,13 @@ class View /** * Sets a template variable. * - * @param string|iterable $key Key + * @param string|iterable $key * @param mixed $value Value - * @return static + * @return $this */ public function set($key, $value = null) { - if (\is_array($key) || \is_object($key)) { + if (\is_iterable($key)) { foreach ($key as $k => $v) { $this->vars[$k] = $v; } @@ -90,7 +74,7 @@ class View /** * Checks if a template variable is set. * - * @param string $key Key + * @param string $key * * @return bool If key exists */ @@ -102,8 +86,9 @@ class View /** * Unsets a template variable. If no key is passed in, clear all variables. * - * @param string $key Key - * @return static + * @param ?string $key + * + * @return $this */ public function clear($key = null) { @@ -120,24 +105,25 @@ class View * Renders a template. * * @param string $file Template file - * @param array $data Template data + * @param ?array $data Template data * - * @throws \Exception If template not found * @return void + * @throws \Exception If template not found */ public function render($file, $data = null) { $this->template = $this->getTemplate($file); - if (!file_exists($this->template)) { - throw new \Exception("Template file not found: {$this->template}."); + if (!\file_exists($this->template)) { + $normalized_path = self::normalizePath($this->template); + throw new \Exception("Template file not found: {$normalized_path}."); } if (\is_array($data)) { - $this->vars = array_merge($this->vars, $data); + $this->vars = \array_merge($this->vars, $data); } - extract($this->vars); + \extract($this->vars); include $this->template; } @@ -146,17 +132,17 @@ class View * Gets the output of a template. * * @param string $file Template file - * @param array $data Template data + * @param ?array $data Template data * * @return string Output of template */ public function fetch($file, $data = null) { - ob_start(); + \ob_start(); $this->render($file, $data); - return ob_get_clean(); + return \ob_get_clean(); } /** @@ -168,7 +154,7 @@ class View */ public function exists($file) { - return file_exists($this->getTemplate($file)); + return \file_exists($this->getTemplate($file)); } /** @@ -182,13 +168,13 @@ class View { $ext = $this->extension; - if (!empty($ext) && (substr($file, -1 * \strlen($ext)) != $ext)) { + if (!empty($ext) && (\substr($file, -1 * \strlen($ext)) != $ext)) { $file .= $ext; } - $is_windows = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; + $is_windows = \strtoupper(\substr(PHP_OS, 0, 3)) === 'WIN'; - if (('/' == substr($file, 0, 1)) || ($is_windows === true && ':' == substr($file, 1, 1))) { + if (('/' == \substr($file, 0, 1)) || ($is_windows === true && ':' == \substr($file, 1, 1))) { return $file; } @@ -204,8 +190,19 @@ class View */ public function e($str) { - $value = htmlentities($str); + $value = \htmlentities($str); echo $value; return $value; } + + /** + * @param string $path An unnormalized path. + * @param string $separator Path separator. + * + * @return string Normalized path. + */ + protected static function normalizePath($path, $separator = DIRECTORY_SEPARATOR) + { + return \str_replace(['\\', '/'], $separator, $path); + } } diff --git a/tests/ViewTest.php b/tests/ViewTest.php index 2013861..f83e0c5 100644 --- a/tests/ViewTest.php +++ b/tests/ViewTest.php @@ -1,4 +1,7 @@ expectException(Exception::class); - $this->expectExceptionMessage('Template file not found: '.__DIR__ . '/views/badfile.php'); + $this->expectExceptionMessage('Template file not found: ' . __DIR__ . DIRECTORY_SEPARATOR . 'views'. DIRECTORY_SEPARATOR . 'badfile.php'); $this->view->render('badfile'); } @@ -117,4 +120,27 @@ class ViewTest extends PHPUnit\Framework\TestCase $result = $this->view->e('script'); $this->assertEquals('script', $result); } + + public function testNormalizePath(): void + { + $viewMock = new class extends View { + public static function normalizePath($path, $separator = DIRECTORY_SEPARATOR) + { + return parent::normalizePath($path, $separator); + } + }; + + $this->assertSame( + 'C:/xampp/htdocs/libs/Flight/core/index.php', + $viewMock::normalizePath('C:\xampp\htdocs\libs\Flight/core/index.php', '/') + ); + $this->assertSame( + 'C:\xampp\htdocs\libs\Flight\core\index.php', + $viewMock::normalizePath('C:/xampp/htdocs/libs/Flight\core\index.php', '\\') + ); + $this->assertSame( + 'C:°xampp°htdocs°libs°Flight°core°index.php', + $viewMock::normalizePath('C:/xampp/htdocs/libs/Flight\core\index.php', '°') + ); + } }