From 8e9ec47d78058b32b2e5d0841e995a243e255430 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Thu, 29 Nov 2018 11:43:14 -0200 Subject: [PATCH 01/27] Move autoloader to BaseService and ensure locator use shared instance --- system/Config/BaseService.php | 25 +++++++++++++++++++++++++ system/Config/Services.php | 20 -------------------- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index 4da15189cb0f..da27ef47ffea 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -118,6 +118,31 @@ protected static function getSharedInstance(string $key, ...$params) //-------------------------------------------------------------------- + /** + * The Autoloader class is the central class that handles our + * spl_autoload_register method, and helper methods. + * + * @param boolean $getShared + * + * @return \CodeIgniter\Autoloader\Autoloader + */ + public static function autoloader(bool $getShared = true) + { + if ($getShared) + { + if (empty(static::$instances['autoloader'])) + { + static::$instances['autoloader'] = new \CodeIgniter\Autoloader\Autoloader(); + } + + return static::$instances['autoloader']; + } + + return new \CodeIgniter\Autoloader\Autoloader(); + } + + //-------------------------------------------------------------------- + /** * The file locator provides utility methods for looking for non-classes * within namespaced folders, as well as convenience methods for diff --git a/system/Config/Services.php b/system/Config/Services.php index 7f724037b7b9..e9cd8f96735c 100644 --- a/system/Config/Services.php +++ b/system/Config/Services.php @@ -60,26 +60,6 @@ */ class Services extends BaseService { - /** - * The Autoloader class is the central class that handles our - * spl_autoload_register method, and helper methods. - * - * @param boolean $getShared - * - * @return \CodeIgniter\Autoloader\Autoloader - */ - public static function autoloader(bool $getShared = true) - { - if ($getShared) - { - return static::getSharedInstance('autoloader'); - } - - return new \CodeIgniter\Autoloader\Autoloader(); - } - - //-------------------------------------------------------------------- - /** * The cache class provides a simple way to store and retrieve * complex data for later. From 27f7ff52ea1d3345968575af97951458ebdebe58 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Thu, 29 Nov 2018 11:46:00 -0200 Subject: [PATCH 02/27] Move autoloader to BaseService and ensure locator use shared instance --- system/Autoloader/Autoloader.php | 35 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 4735119c85f9..35f30b4c3a6b 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -118,6 +118,8 @@ public function initialize(\Config\Autoload $config) $this->classmap = $config->classmap; } + $this->addNamespace(APP_NAMESPACE, APPPATH); + unset($config); } @@ -160,25 +162,23 @@ public function register() /** * Registers a namespace with the autoloader. * - * @param string $namespace - * @param string $path + * @param array|string $namespace + * @param string $path * * @return Autoloader */ - public function addNamespace(string $namespace, string $path) + public function addNamespace($namespace, string $path = null) { - if (isset($this->prefixes[$namespace])) + if (\is_array($namespace)) { - if (is_string($this->prefixes[$namespace])) + foreach ($namespace as $prefix => $path) { - $this->prefixes[$namespace] = [$this->prefixes[$namespace]]; + $this->prefixes[$prefix] = $path; } - - $this->prefixes[$namespace] = array_merge($this->prefixes[$namespace], [$path]); } else { - $this->prefixes[$namespace] = [$path]; + $this->prefixes[$namespace] = $path; } return $this; @@ -186,6 +186,23 @@ public function addNamespace(string $namespace, string $path) //-------------------------------------------------------------------- + /** + * @var string|null $prefix + * + * @return array|string + */ + public function getNamespace(string $prefix = null) + { + if ($prefix === null) + { + return $this->prefixes; + } + + return $this->prefixes[$prefix]; + } + + //-------------------------------------------------------------------- + /** * Removes a single namespace from the psr4 settings. * From 2ef1c734c90b6618251874623235f79b9544bb62 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Thu, 29 Nov 2018 11:47:12 -0200 Subject: [PATCH 03/27] FileLocator get namespaces by Autoloader DI --- system/Autoloader/FileLocator.php | 40 ++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index fb2893f7c91b..89466adf634f 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -56,21 +56,25 @@ class FileLocator */ protected $namespaces; + /** + * @var \CodeIgniter\Autoloader\Autoloader + */ + protected $autoloader; + //-------------------------------------------------------------------- /** * Constructor * - * @param Autoload $autoload + * @param Autoloader $autoloader */ - public function __construct(Autoload $autoload) + public function __construct(Autoloader $autoloader) { - $this->namespaces = $autoload->psr4; - - unset($autoload); + $this->autoloader = $autoloader; + //$this->autoloader->addNamespace(APP_NAMESPACE, APPPATH); // Always keep the Application directory as a "package". - array_unshift($this->namespaces, APPPATH); + //array_unshift($this->namespaces, APPPATH); } //-------------------------------------------------------------------- @@ -121,12 +125,12 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p { $prefix .= empty($prefix) ? ucfirst(array_shift($segments)) : '\\' . ucfirst(array_shift($segments)); - if (! array_key_exists($prefix, $this->namespaces)) + if (! array_key_exists($prefix, $this->autoloader->getNamespace())) { continue; } - $path = $this->namespaces[$prefix] . '/'; + $path = $this->autoloader->getNamespace($prefix) . '/'; $filename = implode('/', $segments); break; } @@ -224,12 +228,20 @@ public function getClassname(string $file) : string */ public function search(string $path, string $ext = 'php'): array { - $foundPaths = []; + // Ensure the extension is at the end of the filename + if ($ext) + { + $ext = '.' . $ext; - // Ensure the extension is on the filename - $path = strpos($path, '.' . $ext) !== false ? $path : $path . '.' . $ext; + if (strpos($ext, $ext) === false || substr($path, -strlen($ext)) !== $ext) + { + $path .= $ext; + } + } + + $foundPaths = []; - foreach ($this->namespaces as $name => $folder) + foreach ($this->autoloader->getNamespace() as $name => $folder) { $folder = rtrim($folder, '/') . '/'; @@ -265,7 +277,7 @@ public function findQualifiedNameFromPath(string $path) return; } - foreach ($this->namespaces as $namespace => $nsPath) + foreach ($this->autoloader->getNamespace() as $namespace => $nsPath) { $nsPath = realpath($nsPath); if (is_numeric($namespace) || empty($nsPath)) @@ -305,7 +317,7 @@ public function listFiles(string $path): array $files = []; helper('filesystem'); - foreach ($this->namespaces as $namespace => $nsPath) + foreach ($this->autoloader->getNamespace() as $namespace => $nsPath) { $fullPath = realpath(rtrim($nsPath, '/') . '/' . $path); From 6e2857308c107bcb0a98242e05a5834a3e5b7245 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Thu, 29 Nov 2018 11:49:53 -0200 Subject: [PATCH 04/27] Ensure that FileLocator uses the same (first) instance of Autoloader --- system/Config/BaseService.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index da27ef47ffea..3873d7df8a55 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -156,10 +156,17 @@ public static function locator(bool $getShared = true) { if ($getShared) { - return static::getSharedInstance('locator'); + if (empty(static::$instances['locator'])) + { + static::$instances['locator'] = new \CodeIgniter\Autoloader\FileLocator( + static::autoloader() + ); + } + + return static::$instances['locator']; } - return new \CodeIgniter\Autoloader\FileLocator(new \Config\Autoload()); + return new \CodeIgniter\Autoloader\FileLocator(static::autoloader()); } //-------------------------------------------------------------------- From 12192cd41fc4c4b16b46153d0e56511492fb85cd Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 16:18:09 -0200 Subject: [PATCH 05/27] Update Autoloader --- system/Autoloader/Autoloader.php | 62 ++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 35f30b4c3a6b..23e8d47eff7c 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -76,7 +76,6 @@ */ class Autoloader { - /** * Stores namespaces as key, and path as values. * @@ -98,6 +97,8 @@ class Autoloader * the valid parts that we'll need. * * @param \Config\Autoload $config + * + * @return $this */ public function initialize(\Config\Autoload $config) { @@ -110,7 +111,7 @@ public function initialize(\Config\Autoload $config) if (isset($config->psr4)) { - $this->prefixes = $config->psr4; + $this->addNamespace($config->psr4); } if (isset($config->classmap)) @@ -118,17 +119,17 @@ public function initialize(\Config\Autoload $config) $this->classmap = $config->classmap; } - $this->addNamespace(APP_NAMESPACE, APPPATH); + //$this->addNamespace(APP_NAMESPACE, APPPATH); unset($config); + + return $this; } //-------------------------------------------------------------------- /** * Register the loader with the SPL autoloader stack. - * - * @codeCoverageIgnore */ public function register() { @@ -146,21 +147,21 @@ public function register() $config = is_array($this->classmap) ? $this->classmap : []; spl_autoload_register(function ($class) use ($config) { - if (! array_key_exists($class, $config)) + if (empty($config[$class])) { return false; } include_once $config[$class]; }, true, // Throw exception - true // Prepend + true // Prepend ); } //-------------------------------------------------------------------- /** - * Registers a namespace with the autoloader. + * Registers namespaces with the autoloader. * * @param array|string $namespace * @param string $path @@ -169,16 +170,28 @@ public function register() */ public function addNamespace($namespace, string $path = null) { - if (\is_array($namespace)) + if (is_array($namespace)) { foreach ($namespace as $prefix => $path) { - $this->prefixes[$prefix] = $path; + $prefix = trim($prefix, '\\'); + + if (is_array($path)) + { + foreach ($path as $dir) + { + $this->prefixes[$prefix][] = rtrim($dir, '/') . '/'; + } + + continue; + } + + $this->prefixes[$prefix][] = rtrim($path, '/') . '/'; } } else { - $this->prefixes[$namespace] = $path; + $this->prefixes[trim($namespace, '\\')][] = rtrim($path, '/') . '/'; } return $this; @@ -187,9 +200,13 @@ public function addNamespace($namespace, string $path = null) //-------------------------------------------------------------------- /** + * Get namespaces with prefixes as keys and paths as values. + * + * If a prefix param is set, returns only paths to the given prefix. + * * @var string|null $prefix * - * @return array|string + * @return array */ public function getNamespace(string $prefix = null) { @@ -198,7 +215,7 @@ public function getNamespace(string $prefix = null) return $this->prefixes; } - return $this->prefixes[$prefix]; + return $this->prefixes[trim($prefix, '\\')] ?? []; } //-------------------------------------------------------------------- @@ -212,7 +229,7 @@ public function getNamespace(string $prefix = null) */ public function removeNamespace(string $namespace) { - unset($this->prefixes[$namespace]); + unset($this->prefixes[trim($namespace, '\\')]); return $this; } @@ -224,7 +241,7 @@ public function removeNamespace(string $namespace) * * @param string $class The fully qualified class name. * - * @return mixed The mapped file on success, or boolean false + * @return string|false The mapped file on success, or boolean false * on failure. */ public function loadClass(string $class) @@ -251,7 +268,7 @@ public function loadClass(string $class) * * @param string $class The fully-qualified class name * - * @return mixed The mapped file name on success, or boolean false on fail + * @return string|false The mapped file name on success, or boolean false on fail */ protected function loadInNamespace(string $class) { @@ -262,18 +279,14 @@ protected function loadInNamespace(string $class) foreach ($this->prefixes as $namespace => $directories) { - if (is_string($directories)) - { - $directories = [$directories]; - } - foreach ($directories as $directory) { $directory = rtrim($directory, '/'); if (strpos($class, $namespace) === 0) { - $filePath = $directory . str_replace('\\', '/', substr($class, strlen($namespace))) . '.php'; + $filePath = $directory . str_replace('\\', '/', + substr($class, strlen($namespace))) . '.php'; $filename = $this->requireFile($filePath); if ($filename) @@ -333,11 +346,9 @@ protected function loadLegacy(string $class) * A central way to require a file is loaded. Split out primarily * for testing purposes. * - * @codeCoverageIgnore - * * @param string $file * - * @return boolean + * @return string|false The filename on success, false if the file is not loaded */ protected function requireFile(string $file) { @@ -382,6 +393,5 @@ public function sanitizeFilename(string $filename): string return $filename; } - //-------------------------------------------------------------------- } From 1a6fc1204a78ff4bbaed50ebc2bd87a7b20ceff0 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 16:20:48 -0200 Subject: [PATCH 06/27] Test Autoloader --- tests/system/Autoloader/AutoloaderTest.php | 112 +++++++++++---------- 1 file changed, 59 insertions(+), 53 deletions(-) diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php index 5e1b025a60d8..cd7f7f3171d7 100644 --- a/tests/system/Autoloader/AutoloaderTest.php +++ b/tests/system/Autoloader/AutoloaderTest.php @@ -1,15 +1,16 @@ classmap = [ - 'FirstClass' => '/app/dir/First.php', - 'Name\Spaced\Class' => '/app/namespace/Class.php', + 'UnnamespacedClass' => SUPPORTPATH . 'Autoloader/UnnamespacedClass.php', + 'OtherClass' => APPPATH . 'Controllers/Home.php', + 'Name\Spaced\Class' => APPPATH . 'Controllers/Home.php', ]; $config->psr4 = [ - 'App\Controllers' => '/application/Controllers', - 'App\Libraries' => '/application/somewhere', + 'App' => APPPATH, + 'CodeIgniter' => BASEPATH, ]; - $this->loader = new MockAutoloader(); - $this->loader->initialize($config); + //\var_dump($config);exit; + + $this->loader = new Autoloader(); + $this->loader->initialize($config)->register(); + } + + public function testLoadStoredClass() + { + $this->assertInstanceOf('UnnamespacedClass', new \UnnamespacedClass()); + } + + public function testInitializeWithInvalidArguments() + { + $this->expectException(\InvalidArgumentException::class); + + $config = new Autoload(); + $config->classmap = []; + $config->psr4 = []; - $this->loader->setFiles([ - '/application/Controllers/Classname.php', - '/application/somewhere/Classname.php', - '/app/dir/First.php', - '/app/namespace/Class.php', - '/my/app/Class.php', - APPPATH . 'Libraries/someLibrary.php', - APPPATH . 'Models/someModel.php', - APPPATH . 'Models/Some/CoolModel.php', - ]); + (new Autoloader())->initialize($config); } //-------------------------------------------------------------------- @@ -75,12 +84,12 @@ public function testServiceAutoLoader() public function testExistingFile() { - $actual = $this->loader->loadClass('App\Controllers\Classname'); - $expected = '/application/Controllers/Classname.php'; + $actual = $this->loader->loadClass('App\Controllers\Home'); + $expected = APPPATH . 'Controllers/Home.php'; $this->assertSame($expected, $actual); - $actual = $this->loader->loadClass('App\Libraries\Classname'); - $expected = '/application/somewhere/Classname.php'; + $actual = $this->loader->loadClass('CodeIgniter\Helpers\array_helper'); + $expected = BASEPATH . 'Helpers/array_helper.php'; $this->assertSame($expected, $actual); } @@ -88,8 +97,8 @@ public function testExistingFile() public function testMatchesWithPreceedingSlash() { - $actual = $this->loader->loadClass('\App\Controllers\Classname'); - $expected = '/application/Controllers/Classname.php'; + $actual = $this->loader->loadClass('\App\Controllers\Home'); + $expected = APPPATH . 'Controllers/Home.php'; $this->assertSame($expected, $actual); } @@ -97,8 +106,8 @@ public function testMatchesWithPreceedingSlash() public function testMatchesWithFileExtension() { - $actual = $this->loader->loadClass('\App\Controllers\Classname.php'); - $expected = '/application/Controllers/Classname.php'; + $actual = $this->loader->loadClass('\App\Controllers\Home.php'); + $expected = APPPATH . 'Controllers/Home.php'; $this->assertSame($expected, $actual); } @@ -122,7 +131,7 @@ public function testInitializeException() $config->classmap = []; $config->psr4 = []; - $this->loader = new MockAutoloader(); + $this->loader = new Autoloader(); $this->loader->initialize($config); } @@ -130,48 +139,47 @@ public function testAddNamespaceWorks() { $this->assertFalse($this->loader->loadClass('My\App\Class')); - $this->loader->addNamespace('My\App', '/my/app'); + $this->loader->addNamespace('My\App', __DIR__); - $actual = $this->loader->loadClass('My\App\Class'); - $expected = '/my/app/Class.php'; + $actual = $this->loader->loadClass('My\App\AutoloaderTest'); + $expected = __FILE__; $this->assertSame($expected, $actual); } public function testAddNamespaceMultiplePathsWorks() { - $this->loader->addNamespace('My\App', '/my/app'); - $this->loader->addNamespace('My\App', '/test/app'); - $this->loader->setFiles([ - '/my/app/Class.php', - '/test/app/ClassTest.php', - ]); + $this->loader->addNamespace('My\App', APPPATH . 'Config'); + $this->loader->addNamespace('My\App', __DIR__); - $actual = $this->loader->loadClass('My\App\ClassTest'); - $expected = '/test/app/ClassTest.php'; + $actual = $this->loader->loadClass('My\App\App'); + $expected = APPPATH . 'Config/App.php'; $this->assertSame($expected, $actual); - $actual = $this->loader->loadClass('My\App\Class'); - $expected = '/my/app/Class.php'; + $actual = $this->loader->loadClass('My\App\AutoloaderTest'); + $expected = __FILE__; $this->assertSame($expected, $actual); } public function testAddNamespaceStingToArray() { - $this->loader->addNamespace('App\Controllers', '/application/Controllers'); + $this->loader->addNamespace('App\Controllers', __DIR__); - $this->assertSame('/application/Controllers/Classname.php', $this->loader->loadClass('App\Controllers\Classname')); + $this->assertSame( + __FILE__, + $this->loader->loadClass('App\Controllers\AutoloaderTest') + ); } //-------------------------------------------------------------------- public function testRemoveNamespace() { - $this->loader->addNamespace('My\App', '/my/app'); - $this->assertSame('/my/app/Class.php', $this->loader->loadClass('My\App\Class')); + $this->loader->addNamespace('My\App', __DIR__); + $this->assertSame(__FILE__, $this->loader->loadClass('My\App\AutoloaderTest')); $this->loader->removeNamespace('My\App'); - $this->assertFalse((bool) $this->loader->loadClass('My\App\Class')); + $this->assertFalse((bool) $this->loader->loadClass('My\App\AutoloaderTest')); } //-------------------------------------------------------------------- @@ -179,16 +187,14 @@ public function testRemoveNamespace() public function testLoadLegacy() { // should not be able to find a folder - $this->assertFalse((bool) $this->loader->loadClass('someLibraries')); - // should be able to find these because we said so in the MockAutoloader - $this->assertTrue((bool) $this->loader->loadClass('someLibrary')); - $this->assertTrue((bool) $this->loader->loadClass('someModel')); + $this->assertFalse((bool) $this->loader->loadClass(__DIR__)); + // should be able to find these because we said so in the Autoloader + $this->assertTrue((bool) $this->loader->loadClass('Home')); // should not be able to find these - don't exist $this->assertFalse((bool) $this->loader->loadClass('anotherLibrary')); $this->assertFalse((bool) $this->loader->loadClass('\nester\anotherLibrary')); - $this->assertFalse((bool) $this->loader->loadClass('\Shouldnt\Find\This')); // should not be able to find these legacy classes - namespaced - $this->assertFalse($this->loader->loadClass('\Some\CoolModel')); + $this->assertFalse($this->loader->loadClass('Controllers\Home')); } //-------------------------------------------------------------------- From 7ef281f770ca215ab66896776e50485a58f5d5c5 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 16:22:35 -0200 Subject: [PATCH 07/27] Update FileLocator --- system/Autoloader/FileLocator.php | 77 ++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 28 deletions(-) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index 89466adf634f..b6d2c66f508b 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -36,8 +36,6 @@ * @filesource */ -use Config\Autoload; - /** * Class Loader * @@ -48,14 +46,6 @@ */ class FileLocator { - - /** - * Stores our namespaces - * - * @var array - */ - protected $namespaces; - /** * @var \CodeIgniter\Autoloader\Autoloader */ @@ -95,7 +85,8 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p $file = strpos($file, '.' . $ext) !== false ? $file : $file . '.' . $ext; // Clean the folder name from the filename - if (! empty($folder)) + //if (! empty($folder)) + if (! empty($folder) /*&& strpos($file, $folder) === false*/) { $file = str_replace($folder . '/', '', $file); } @@ -123,14 +114,15 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p while (! empty($segments)) { - $prefix .= empty($prefix) ? ucfirst(array_shift($segments)) : '\\' . ucfirst(array_shift($segments)); + $prefix .= empty($prefix) + ? ucfirst(array_shift($segments)) + : '\\' . ucfirst(array_shift($segments)); if (! array_key_exists($prefix, $this->autoloader->getNamespace())) { continue; } - - $path = $this->autoloader->getNamespace($prefix) . '/'; + $path = $this->getNamespaces($prefix); $filename = implode('/', $segments); break; } @@ -241,13 +233,13 @@ public function search(string $path, string $ext = 'php'): array $foundPaths = []; - foreach ($this->autoloader->getNamespace() as $name => $folder) + foreach ($this->getNamespaces() as $namespace) { - $folder = rtrim($folder, '/') . '/'; + $namespace['path'] = rtrim($namespace['path'], '/') . '/'; - if (is_file($folder . $path) === true) + if (is_file($namespace['path'] . $path) === true) { - $foundPaths[] = $folder . $path; + $foundPaths[] = $namespace['path'] . $path; } } @@ -259,6 +251,33 @@ public function search(string $path, string $ext = 'php'): array //-------------------------------------------------------------------- + protected function getNamespaces(string $prefix = null) + { + if ($prefix) + { + $path = $this->autoloader->getNamespace($prefix); + + return isset($path[0]) ? $path[0] : ''; + } + + $namespaces = []; + + foreach ($this->autoloader->getNamespace() as $prefix => $paths) + { + foreach ($paths as $path) + { + $namespaces[] = [ + 'prefix' => $prefix, + 'path' => $path, + ]; + } + } + + return $namespaces; + } + + //-------------------------------------------------------------------- + /** * Attempts to load a file and instantiate a new class by looking * at its full path and comparing that to our existing psr4 namespaces @@ -277,18 +296,21 @@ public function findQualifiedNameFromPath(string $path) return; } - foreach ($this->autoloader->getNamespace() as $namespace => $nsPath) + foreach ($this->getNamespaces() as $namespace) { - $nsPath = realpath($nsPath); - if (is_numeric($namespace) || empty($nsPath)) + $namespace['path'] = realpath($namespace['path']); + + if (empty($namespace['path'])) { continue; } - if (mb_strpos($path, $nsPath) === 0) + if (mb_strpos($path, $namespace['path']) === 0) { - $className = '\\' . $namespace . '\\' . - ltrim(str_replace('/', '\\', mb_substr($path, mb_strlen($nsPath))), '\\'); + $className = '\\' . $namespace['prefix'] . '\\' . + ltrim(str_replace('/', '\\', mb_substr( + $path, mb_strlen($namespace['path'])) + ), '\\'); // Remove the file extension (.php) $className = mb_substr($className, 0, -4); @@ -317,9 +339,9 @@ public function listFiles(string $path): array $files = []; helper('filesystem'); - foreach ($this->autoloader->getNamespace() as $namespace => $nsPath) + foreach ($this->getNamespaces() as $namespace) { - $fullPath = realpath(rtrim($nsPath, '/') . '/' . $path); + $fullPath = realpath(rtrim($namespace['path'], '/') . '/' . $path); if (! is_dir($fullPath)) { @@ -373,8 +395,7 @@ protected function legacyLocate(string $file, string $folder = null): string * Checks to see if a file exists on the file system. This is split * out to it's own method to make testing simpler. * - * @codeCoverageIgnore - * @param string $path + * @param string $path * * @return boolean */ From d25f49c0b6c66c4fd8c10ee71c027444f6a1a569 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 16:25:07 -0200 Subject: [PATCH 08/27] Add UnnamespacedClass to truth test --- tests/_support/Autoloader/UnnamespacedClass.php | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 tests/_support/Autoloader/UnnamespacedClass.php diff --git a/tests/_support/Autoloader/UnnamespacedClass.php b/tests/_support/Autoloader/UnnamespacedClass.php new file mode 100644 index 000000000000..67b1ed352b42 --- /dev/null +++ b/tests/_support/Autoloader/UnnamespacedClass.php @@ -0,0 +1,5 @@ + Date: Fri, 30 Nov 2018 16:25:39 -0200 Subject: [PATCH 09/27] Update FileLocatorTest --- tests/system/Autoloader/FileLocatorTest.php | 152 +++++++++++--------- 1 file changed, 87 insertions(+), 65 deletions(-) diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php index fddc7a085c9a..23d2f8a0b863 100644 --- a/tests/system/Autoloader/FileLocatorTest.php +++ b/tests/system/Autoloader/FileLocatorTest.php @@ -1,15 +1,11 @@ psr4 = [ - 'App\Libraries' => '/application/somewhere', - 'App' => '/application', - 'Sys' => BASEPATH, - 'Blog' => '/modules/blog', + $autoloader = new Autoloader(); + $autoloader->initialize(new \Config\Autoload()); + $autoloader->addNamespace([ + 'Unknown' => '/i/do/not/exist', 'Tests/Support' => TESTPATH . '_support/', - ]; + 'App' => APPPATH, + 'CodeIgniter' => [ + BASEPATH, + TESTPATH, + ], + 'Errors' => APPPATH . 'Views/errors', + 'System' => SUPPORTPATH . 'Autoloader/system', + ]); - $this->loader = new MockFileLocator($config); + $this->locator = new FileLocator($autoloader); + } - $this->loader->setFiles([ - APPPATH . 'index.php', - APPPATH . 'Views/index.php', - APPPATH . 'Views/admin/users/create.php', - '/modules/blog/Views/index.php', - '/modules/blog/Views/admin/posts.php', - ]); + //-------------------------------------------------------------------- + + public function testLocateFileWorksWithLegacyStructure() + { + $file = 'Controllers/Home'; + + $expected = APPPATH . 'Controllers/Home.php'; + + $this->assertEquals($expected, $this->locator->locateFile($file)); + } + + //-------------------------------------------------------------------- + + public function testLocateFileWithLegacyStructureNotFound() + { + $file = 'Unknown'; + + $this->assertEquals('', $this->locator->locateFile($file)); } //-------------------------------------------------------------------- public function testLocateFileWorksInApplicationDirectory() { - $file = 'index'; + $file = 'welcome_message'; - $expected = APPPATH . 'Views/index.php'; + $expected = APPPATH . 'Views/welcome_message.php'; - $this->assertEquals($expected, $this->loader->locateFile($file, 'Views')); + $this->assertEquals($expected, $this->locator->locateFile($file, 'Views')); } //-------------------------------------------------------------------- public function testLocateFileWorksInApplicationDirectoryWithoutFolder() { - $file = 'index'; + $file = 'bootstrap'; - $expected = APPPATH . 'index.php'; + $expected = BASEPATH . 'bootstrap.php'; - $this->assertEquals($expected, $this->loader->locateFile($file)); + $this->assertEquals($expected, $this->locator->locateFile($file)); } //-------------------------------------------------------------------- public function testLocateFileWorksInNestedApplicationDirectory() { - $file = 'admin/users/create'; + $file = 'Controllers/Home'; - $expected = APPPATH . 'Views/admin/users/create.php'; + $expected = APPPATH . 'Controllers/Home.php'; - $this->assertEquals($expected, $this->loader->locateFile($file, 'Views')); + $this->assertEquals($expected, $this->locator->locateFile($file, 'Controllers')); } //-------------------------------------------------------------------- public function testLocateFileReplacesFolderName() { - $file = '\Blog\Views/admin/posts.php'; + $file = '\App\Views/errors/html/error_404.php'; - $expected = '/modules/blog/Views/admin/posts.php'; + $expected = APPPATH . 'Views/errors/html/error_404.php'; - $this->assertEquals($expected, $this->loader->locateFile($file, 'Views')); + $this->assertEquals($expected, $this->locator->locateFile($file, 'Views')); } //-------------------------------------------------------------------- public function testLocateFileReplacesFolderNameLegacy() { - $file = 'Views/index.php'; + $file = 'Views/welcome_message.php'; - $expected = APPPATH . 'Views/index.php'; + $expected = APPPATH . 'Views/welcome_message.php'; - $this->assertEquals($expected, $this->loader->locateFile($file, 'Views')); + $this->assertEquals($expected, $this->locator->locateFile($file, 'Views')); } //-------------------------------------------------------------------- public function testLocateFileCanFindNamespacedView() { - $file = '\Blog\index'; + $file = '\Errors\error_404'; - $expected = '/modules/blog/Views/index.php'; + $expected = APPPATH . 'Views/errors/html/error_404.php'; - $this->assertEquals($expected, $this->loader->locateFile($file, 'Views')); + $this->assertEquals($expected, $this->locator->locateFile($file, 'html')); } //-------------------------------------------------------------------- public function testLocateFileCanFindNestedNamespacedView() { - $file = '\Blog\admin/posts.php'; + $file = '\Errors\html/error_404'; - $expected = '/modules/blog/Views/admin/posts.php'; + $expected = APPPATH . 'Views/errors/html/error_404.php'; - $this->assertEquals($expected, $this->loader->locateFile($file, 'Views')); + $this->assertEquals($expected, $this->locator->locateFile($file, 'html')); } //-------------------------------------------------------------------- @@ -120,16 +133,16 @@ public function testLocateFileReturnsEmptyWithBadNamespace() { $file = '\Blogger\admin/posts.php'; - $this->assertEquals('', $this->loader->locateFile($file, 'Views')); + $this->assertEquals('', $this->locator->locateFile($file, 'Views')); } //-------------------------------------------------------------------- public function testSearchSimple() { - $expected = rtrim(APPPATH, '/') . '/Config/App.php'; + $expected = APPPATH . 'Config/App.php'; - $foundFiles = $this->loader->search('Config/App.php'); + $foundFiles = $this->locator->search('Config/App.php'); $this->assertEquals($expected, $foundFiles[0]); } @@ -138,9 +151,9 @@ public function testSearchSimple() public function testSearchWithFileExtension() { - $expected = rtrim(APPPATH, '/') . '/Config/App.php'; + $expected = APPPATH . 'Config/App.php'; - $foundFiles = $this->loader->search('Config/App', 'php'); + $foundFiles = $this->locator->search('Config/App', 'php'); $this->assertEquals($expected, $foundFiles[0]); } @@ -149,12 +162,12 @@ public function testSearchWithFileExtension() public function testSearchWithMultipleFilesFound() { - $foundFiles = $this->loader->search('index', 'html'); + $foundFiles = $this->locator->search('index', 'html'); - $expected = rtrim(APPPATH, '/') . '/index.html'; + $expected = APPPATH . 'index.html'; $this->assertContains($expected, $foundFiles); - $expected = rtrim(BASEPATH, '/') . '/index.html'; + $expected = BASEPATH . 'index.html'; $this->assertContains($expected, $foundFiles); } @@ -162,7 +175,7 @@ public function testSearchWithMultipleFilesFound() public function testSearchForFileNotExist() { - $foundFiles = $this->loader->search('Views/Fake.html'); + $foundFiles = $this->locator->search('Views/Fake.html'); $this->assertArrayNotHasKey(0, $foundFiles); } @@ -171,7 +184,7 @@ public function testSearchForFileNotExist() public function testListFilesSimple() { - $files = $this->loader->listFiles('Config/'); + $files = $this->locator->listFiles('Config/'); $expectedWin = APPPATH . 'Config\App.php'; $expectedLin = APPPATH . 'Config/App.php'; @@ -182,7 +195,7 @@ public function testListFilesSimple() public function testListFilesWithFileAsInput() { - $files = $this->loader->listFiles('Config/App.php'); + $files = $this->locator->listFiles('Config/App.php'); $this->assertEmpty($files); } @@ -191,7 +204,7 @@ public function testListFilesWithFileAsInput() public function testListFilesFromMultipleDir() { - $files = $this->loader->listFiles('Filters/'); + $files = $this->locator->listFiles('Filters/'); $expectedWin = APPPATH . 'Filters\DebugToolbar.php'; $expectedLin = APPPATH . 'Filters/DebugToolbar.php'; @@ -206,7 +219,7 @@ public function testListFilesFromMultipleDir() public function testListFilesWithPathNotExist() { - $files = $this->loader->listFiles('Fake/'); + $files = $this->locator->listFiles('Fake/'); $this->assertEmpty($files); } @@ -215,38 +228,47 @@ public function testListFilesWithPathNotExist() public function testListFilesWithoutPath() { - $files = $this->loader->listFiles(''); + $files = $this->locator->listFiles(''); $this->assertEmpty($files); } public function testFindQNameFromPathSimple() { - $ClassName = $this->loader->findQualifiedNameFromPath('system/HTTP/Header.php'); - $expected = '\Sys\HTTP\Header'; + $ClassName = $this->locator->findQualifiedNameFromPath(BASEPATH . 'HTTP/Header.php'); + $expected = '\CodeIgniter\HTTP\Header'; $this->assertEquals($expected, $ClassName); } - public function testFindQNameFromPathWithNumericNamespace() + public function testFindQNameFromPathWithFileNotExist() { - $ClassName = $this->loader->findQualifiedNameFromPath('application/Config/App.php'); + $ClassName = $this->locator->findQualifiedNameFromPath('modules/blog/Views/index.php'); $this->assertNull($ClassName); } - public function testFindQNameFromPathWithFileNotExist() + public function testFindQNameFromPathWithoutCorrespondingNamespace() { - $ClassName = $this->loader->findQualifiedNameFromPath('modules/blog/Views/index.php'); + $ClassName = $this->locator->findQualifiedNameFromPath('/etc/hosts'); $this->assertNull($ClassName); } - public function testFindQNameFromPathWithoutCorrespondingNamespace() + public function testGetClassNameFromClassFile() { - $ClassName = $this->loader->findQualifiedNameFromPath('tests/system/CodeIgniterTest.php'); + $this->assertEquals( + __CLASS__, + $this->locator->getClassname(__FILE__) + ); + } - $this->assertNull($ClassName); + public function testGetClassNameFromNonClassFile() + { + $this->assertEquals( + '', + $this->locator->getClassname(BASEPATH . 'bootstrap.php') + ); } } From 7e9b4966c9cf6aaeb88c86932a862501293487c1 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 16:26:33 -0200 Subject: [PATCH 10/27] Remove unused mocks --- tests/_support/Autoloader/MockAutoloader.php | 25 ------------------- tests/_support/Autoloader/MockFileLocator.php | 25 ------------------- 2 files changed, 50 deletions(-) delete mode 100644 tests/_support/Autoloader/MockAutoloader.php delete mode 100644 tests/_support/Autoloader/MockFileLocator.php diff --git a/tests/_support/Autoloader/MockAutoloader.php b/tests/_support/Autoloader/MockAutoloader.php deleted file mode 100644 index 8a722a571235..000000000000 --- a/tests/_support/Autoloader/MockAutoloader.php +++ /dev/null @@ -1,25 +0,0 @@ -files = $files; - } - - //-------------------------------------------------------------------- - - protected function requireFile(string $file) - { - return in_array($file, $this->files) ? $file : false; - } - - //-------------------------------------------------------------------- -} diff --git a/tests/_support/Autoloader/MockFileLocator.php b/tests/_support/Autoloader/MockFileLocator.php deleted file mode 100644 index c683bbb9d8c6..000000000000 --- a/tests/_support/Autoloader/MockFileLocator.php +++ /dev/null @@ -1,25 +0,0 @@ -files = $files; - } - - //-------------------------------------------------------------------- - - protected function requireFile(string $file): bool - { - return in_array($file, $this->files) ? $file : false; - } - - //-------------------------------------------------------------------- -} From 2eb123ce437b56368036260a5bc82a5fc8937e42 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 18:20:13 -0200 Subject: [PATCH 11/27] No more mocks here! --- tests/system/CodeIgniterTest.php | 4 ++-- tests/system/CommonFunctionsTest.php | 10 +++++----- tests/system/HTTP/RedirectResponseTest.php | 4 +--- tests/system/Router/RouteCollectionTest.php | 8 +++----- tests/system/Router/RouterTest.php | 4 ++-- tests/system/View/ParserFilterTest.php | 3 ++- tests/system/View/ParserTest.php | 2 +- tests/system/View/ViewTest.php | 2 +- 8 files changed, 17 insertions(+), 20 deletions(-) diff --git a/tests/system/CodeIgniterTest.php b/tests/system/CodeIgniterTest.php index b2eb0a6a1d64..6a04a0d089a1 100644 --- a/tests/system/CodeIgniterTest.php +++ b/tests/system/CodeIgniterTest.php @@ -3,7 +3,7 @@ use Config\App; use Tests\Support\MockCodeIgniter; use CodeIgniter\Router\RouteCollection; -use Tests\Support\Autoloader\MockFileLocator; +use \CodeIgniter\Config\Services; /** * @backupGlobals enabled @@ -135,7 +135,7 @@ public function testRun404OverrideByClosure() $_SERVER['argc'] = 2; // Inject mock router. - $routes = new RouteCollection(new MockFileLocator(new \Config\Autoload()), new \Config\Modules()); + $routes = new RouteCollection(Services::locator(), new \Config\Modules()); $routes->setAutoRoute(false); $routes->set404Override(function () { echo '404 Override by Closure.'; diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php index e3705d82b406..287457bd96a1 100644 --- a/tests/system/CommonFunctionsTest.php +++ b/tests/system/CommonFunctionsTest.php @@ -3,14 +3,12 @@ use CodeIgniter\Session\Handlers\FileHandler; use CodeIgniter\HTTP\Response; use Config\App; -use Config\Autoload; use CodeIgniter\Config\Services; use CodeIgniter\Router\RouteCollection; use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\HTTP\URI; use CodeIgniter\HTTP\UserAgent; use Config\Logger; -use Tests\Support\Autoloader\MockFileLocator; use Tests\Support\HTTP\MockIncomingRequest; use Tests\Support\Log\TestLogger; use Tests\Support\Session\MockSession; @@ -102,7 +100,9 @@ public function testRedirectReturnsRedirectResponse() $_SERVER['REQUEST_METHOD'] = 'GET'; $response = $this->createMock(\CodeIgniter\HTTP\Response::class); - $routes = new \CodeIgniter\Router\RouteCollection(new \Tests\Support\Autoloader\MockFileLocator(new \Config\Autoload()), new \Config\Modules()); + $routes = new \CodeIgniter\Router\RouteCollection( + Services::locator(), new \Config\Modules() + ); \CodeIgniter\Services::injectMock('response', $response); \CodeIgniter\Services::injectMock('routes', $routes); @@ -267,7 +267,7 @@ public function testOldInput() $this->config = new App(); $this->config->baseURL = 'http://example.com'; - $this->routes = new RouteCollection(new MockFileLocator(new Autoload()), new \Config\Modules()); + $this->routes = new RouteCollection(Services::locator(), new \Config\Modules()); Services::injectMock('routes', $this->routes); $this->request = new MockIncomingRequest($this->config, new URI('http://example.com'), null, new UserAgent()); @@ -303,7 +303,7 @@ public function testOldInputArray() $this->config = new App(); $this->config->baseURL = 'http://example.com'; - $this->routes = new RouteCollection(new MockFileLocator(new Autoload()), new \Config\Modules()); + $this->routes = new RouteCollection(Services::locator(), new \Config\Modules()); Services::injectMock('routes', $this->routes); $this->request = new MockIncomingRequest($this->config, new URI('http://example.com'), null, new UserAgent()); diff --git a/tests/system/HTTP/RedirectResponseTest.php b/tests/system/HTTP/RedirectResponseTest.php index a9d24d621066..e913db325279 100644 --- a/tests/system/HTTP/RedirectResponseTest.php +++ b/tests/system/HTTP/RedirectResponseTest.php @@ -3,11 +3,9 @@ namespace CodeIgniter\HTTP; use Config\App; -use Config\Autoload; use CodeIgniter\Config\Services; use CodeIgniter\Validation\Validation; use CodeIgniter\Router\RouteCollection; -use Tests\Support\Autoloader\MockFileLocator; use Tests\Support\HTTP\MockIncomingRequest; class RedirectResponseTest extends \CIUnitTestCase @@ -29,7 +27,7 @@ public function setUp() $this->config = new App(); $this->config->baseURL = 'http://example.com'; - $this->routes = new RouteCollection(new MockFileLocator(new Autoload()), new \Config\Modules()); + $this->routes = new RouteCollection(Services::locator(), new \Config\Modules()); Services::injectMock('routes', $this->routes); $this->request = new MockIncomingRequest($this->config, new URI('http://example.com'), null, new UserAgent()); diff --git a/tests/system/Router/RouteCollectionTest.php b/tests/system/Router/RouteCollectionTest.php index 009d2f17404a..8cafb3f25e73 100644 --- a/tests/system/Router/RouteCollectionTest.php +++ b/tests/system/Router/RouteCollectionTest.php @@ -1,7 +1,7 @@ psr4 = $config; + Services::autoloader()->addNamespace($config); - $loader = new MockFileLocator($autoload); - $loader->setFiles($files); + $loader = Services::locator(); if ($moduleConfig === null) { diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index 61bf929b0cd3..57706ed5f7c4 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -1,7 +1,7 @@ enabled = false; - $this->collection = new RouteCollection(new MockFileLocator(new \Config\Autoload()), $moduleConfig); + $this->collection = new RouteCollection(Services::locator(), $moduleConfig); $routes = [ 'users' => 'Users::index', diff --git a/tests/system/View/ParserFilterTest.php b/tests/system/View/ParserFilterTest.php index 5a186d2be5a0..a93334ff76ce 100644 --- a/tests/system/View/ParserFilterTest.php +++ b/tests/system/View/ParserFilterTest.php @@ -12,7 +12,8 @@ public function setUp() { parent::setUp(); - $this->loader = new \CodeIgniter\Autoloader\FileLocator(new \Config\Autoload()); + $this->loader = \CodeIgniter\Config\Services::locator(); + ; $this->viewsDir = __DIR__ . '/Views'; $this->config = new Config\View(); } diff --git a/tests/system/View/ParserTest.php b/tests/system/View/ParserTest.php index 671168566bfc..5647ea37a688 100644 --- a/tests/system/View/ParserTest.php +++ b/tests/system/View/ParserTest.php @@ -10,7 +10,7 @@ public function setUp() { parent::setUp(); - $this->loader = new \CodeIgniter\Autoloader\FileLocator(new \Config\Autoload()); + $this->loader = \CodeIgniter\Config\Services::locator(); $this->viewsDir = __DIR__ . '/Views'; $this->config = new Config\View(); } diff --git a/tests/system/View/ViewTest.php b/tests/system/View/ViewTest.php index a322d9f826c0..2e64bf553feb 100644 --- a/tests/system/View/ViewTest.php +++ b/tests/system/View/ViewTest.php @@ -15,7 +15,7 @@ public function setUp() { parent::setUp(); - $this->loader = new \CodeIgniter\Autoloader\FileLocator(new \Config\Autoload()); + $this->loader = \CodeIgniter\Config\Services::locator(); $this->viewsDir = __DIR__ . '/Views'; $this->config = new Config\View(); } From 379d1c638a8144dcc0eb0e048a0def948c6f1c4b Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 19:20:55 -0200 Subject: [PATCH 12/27] Initializes the Autoloader after reset all in ValidationTest --- tests/system/Validation/ValidationTest.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index 986f88c77eae..bef0cce13b9a 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -43,7 +43,10 @@ public function setUp() { parent::setUp(); + // Reset all services instances Services::reset(); + // Initialize the Autoloader... - we need it to search for language files in the locator + Services::autoloader()->initialize(new \Config\Autoload()); $this->validation = new Validation((object) $this->config, \Config\Services::renderer()); $this->validation->reset(); From 958ff8eac04586cf79c5f38f4ffd5cfd3bb018ea Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 19:42:18 -0200 Subject: [PATCH 13/27] Initializes the Autoloader service after a services reset --- tests/system/View/ParserPluginTest.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/system/View/ParserPluginTest.php b/tests/system/View/ParserPluginTest.php index a656e4c15f2f..bd8588ddae3d 100644 --- a/tests/system/View/ParserPluginTest.php +++ b/tests/system/View/ParserPluginTest.php @@ -1,10 +1,14 @@ initialize(new \Config\Autoload()); $this->parser = \Config\Services::parser(); $this->validator = \Config\Services::validation(); } From 2d7f9313ec40e3f98c12427b0398bf51c1776192 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 20:11:53 -0200 Subject: [PATCH 14/27] Test Autoloader package instances --- tests/system/Config/ServicesTest.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/system/Config/ServicesTest.php b/tests/system/Config/ServicesTest.php index f55bffffa254..ed41b839f7c6 100644 --- a/tests/system/Config/ServicesTest.php +++ b/tests/system/Config/ServicesTest.php @@ -22,6 +22,30 @@ public function tearDown() $_SERVER = $this->original; } + public function testNewAutoloader() + { + $actual = Services::autoloader(); + $this->assertInstanceOf(\CodeIgniter\Autoloader\Autoloader::class, $actual); + } + + public function testNewUnsharedAutoloader() + { + $actual = Services::autoloader(false); + $this->assertInstanceOf(\CodeIgniter\Autoloader\Autoloader::class, $actual); + } + + public function testNewFileLocator() + { + $actual = Services::locator(); + $this->assertInstanceOf(\CodeIgniter\Autoloader\FileLocator::class, $actual); + } + + public function testNewUnsharedFileLocator() + { + $actual = Services::locator(false); + $this->assertInstanceOf(\CodeIgniter\Autoloader\FileLocator::class, $actual); + } + public function testNewCurlRequest() { $actual = Services::curlrequest(); From b75b2d5078d1516e876c685f094c009b4c0645c2 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 21:16:50 -0200 Subject: [PATCH 15/27] Test more Services --- tests/system/Config/ServicesTest.php | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/system/Config/ServicesTest.php b/tests/system/Config/ServicesTest.php index ed41b839f7c6..e886a9eb7e24 100644 --- a/tests/system/Config/ServicesTest.php +++ b/tests/system/Config/ServicesTest.php @@ -105,6 +105,46 @@ public function testNewUnsharedClirequest() $this->assertInstanceOf(\CodeIgniter\HTTP\CLIRequest::class, $actual); } + public function testNewEmail() + { + $actual = Services::email(); + $this->assertInstanceOf(\CodeIgniter\Email\Email::class, $actual); + + $actual->fromName = 'Zoboomafoo'; + $this->assertEquals('Zoboomafoo', Services::email()->fromName); + $this->assertEquals('Zoboomafoo', Services::email(new \Config\Email())->fromName); + } + + public function testNewUnsharedEmail() + { + $actual = Services::email(null, false); + $this->assertInstanceOf(\CodeIgniter\Email\Email::class, $actual); + + $actual->fromName = 'Zoboomafoo'; + $this->assertEquals('', Services::email(null, false)->fromName); + $this->assertEquals('', Services::email(new \Config\Email(), false)->fromName); + } + + public function testNewLanguage() + { + $actual = Services::language(); + $this->assertInstanceOf(\CodeIgniter\Language\Language::class, $actual); + $this->assertEquals('en', $actual->getLocale()); + + Services::language('la'); + $this->assertEquals('la', $actual->getLocale()); + } + + public function testNewUnsharedLanguage() + { + $actual = Services::language(null, false); + $this->assertInstanceOf(\CodeIgniter\Language\Language::class, $actual); + $this->assertEquals('en', $actual->getLocale()); + + Services::language('la', false); + $this->assertEquals('en', $actual->getLocale()); + } + public function testNewPager() { $actual = Services::pager(null); From 1e9c5a2d78d9697b9f3582669e95b9b4ebaeebbc Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 21:41:11 -0200 Subject: [PATCH 16/27] Allow get current locale --- system/Language/Language.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/system/Language/Language.php b/system/Language/Language.php index 667182f66fc7..d3f948d86ef2 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -102,6 +102,14 @@ public function setLocale(string $locale = null) return $this; } + /** + * @return string + */ + public function getLocale(): string + { + return $this->locale; + } + /** * Parses the language string for a file, loads the file, if necessary, * getting the line. From 4320de74ff47a79a8153cd7f509dfc49b70df87b Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 22:59:36 -0200 Subject: [PATCH 17/27] Makes the FileLocator even more reliable --- system/Autoloader/FileLocator.php | 55 ++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index b6d2c66f508b..71547575c5be 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -61,10 +61,6 @@ class FileLocator public function __construct(Autoloader $autoloader) { $this->autoloader = $autoloader; - //$this->autoloader->addNamespace(APP_NAMESPACE, APPPATH); - - // Always keep the Application directory as a "package". - //array_unshift($this->namespaces, APPPATH); } //-------------------------------------------------------------------- @@ -81,14 +77,12 @@ public function __construct(Autoloader $autoloader) */ public function locateFile(string $file, string $folder = null, string $ext = 'php'): string { - // Ensure the extension is on the filename - $file = strpos($file, '.' . $ext) !== false ? $file : $file . '.' . $ext; + $file = $this->ensureExt($file, $ext); - // Clean the folder name from the filename - //if (! empty($folder)) - if (! empty($folder) /*&& strpos($file, $folder) === false*/) + // Clears the folder name if it is at the beginning of the filename + if (! empty($folder) && ($pos = strpos($file, $folder)) === 0) { - $file = str_replace($folder . '/', '', $file); + $file = substr_replace($file, '', $pos, strlen($folder . '/')); } // No namespaceing? Try the application folder. @@ -220,16 +214,7 @@ public function getClassname(string $file) : string */ public function search(string $path, string $ext = 'php'): array { - // Ensure the extension is at the end of the filename - if ($ext) - { - $ext = '.' . $ext; - - if (strpos($ext, $ext) === false || substr($path, -strlen($ext)) !== $ext) - { - $path .= $ext; - } - } + $path = $this->ensureExt($path, $ext); $foundPaths = []; @@ -251,6 +236,36 @@ public function search(string $path, string $ext = 'php'): array //-------------------------------------------------------------------- + /** + * Ensures a extension is at the end of a filename + * + * @param string $path + * @param string $ext + * + * @return string + */ + protected function ensureExt(string $path, string $ext): string + { + if ($ext) + { + $ext = '.' . $ext; + + if (substr($path, -strlen($ext)) !== $ext) + { + $path .= $ext; + } + } + + return $path; + } + + //-------------------------------------------------------------------- + + /** + * @param string|null $prefix + * + * @return array|string + */ protected function getNamespaces(string $prefix = null) { if ($prefix) From f31d60556d42274ce83ea92739588a9a6518523d Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 23:12:12 -0200 Subject: [PATCH 18/27] Remove some lines and update test method name --- system/Autoloader/Autoloader.php | 2 -- tests/system/Autoloader/AutoloaderTest.php | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/system/Autoloader/Autoloader.php b/system/Autoloader/Autoloader.php index 23e8d47eff7c..3baf97fd3465 100644 --- a/system/Autoloader/Autoloader.php +++ b/system/Autoloader/Autoloader.php @@ -119,8 +119,6 @@ public function initialize(\Config\Autoload $config) $this->classmap = $config->classmap; } - //$this->addNamespace(APP_NAMESPACE, APPPATH); - unset($config); return $this; diff --git a/tests/system/Autoloader/AutoloaderTest.php b/tests/system/Autoloader/AutoloaderTest.php index cd7f7f3171d7..3d9dca4738a6 100644 --- a/tests/system/Autoloader/AutoloaderTest.php +++ b/tests/system/Autoloader/AutoloaderTest.php @@ -29,8 +29,6 @@ public function setUp() 'CodeIgniter' => BASEPATH, ]; - //\var_dump($config);exit; - $this->loader = new Autoloader(); $this->loader->initialize($config)->register(); } @@ -51,7 +49,6 @@ public function testInitializeWithInvalidArguments() (new Autoloader())->initialize($config); } - //-------------------------------------------------------------------- //-------------------------------------------------------------------- // PSR4 Namespacing //-------------------------------------------------------------------- @@ -118,7 +115,6 @@ public function testMissingFile() $this->assertFalse($this->loader->loadClass('\App\Missing\Classname')); } - //-------------------------------------------------------------------- //-------------------------------------------------------------------- /** @@ -161,7 +157,7 @@ public function testAddNamespaceMultiplePathsWorks() $this->assertSame($expected, $actual); } - public function testAddNamespaceStingToArray() + public function testAddNamespaceStringToArray() { $this->loader->addNamespace('App\Controllers', __DIR__); From d477ac02c46f4b573948cd2ee2c2eb3ebb031340 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 23:20:46 -0200 Subject: [PATCH 19/27] Allow auto-initialize autoloader instance after clear --- system/Config/BaseService.php | 9 ++++++++- tests/system/Validation/ValidationTest.php | 5 +---- tests/system/View/ParserPluginTest.php | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index 3873d7df8a55..7e0cc8288007 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -196,12 +196,19 @@ public static function __callStatic(string $name, array $arguments) /** * Reset shared instances and mocks for testing. + * + * @param boolean $init_autoloader Initializes autoloader instance */ - public static function reset() + public static function reset(bool $init_autoloader = false) { static::$mocks = []; static::$instances = []; + + if ($init_autoloader) + { + static::autoloader()->initialize(new \Config\Autoload()); + } } //-------------------------------------------------------------------- diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index bef0cce13b9a..b355f637dc41 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -43,10 +43,7 @@ public function setUp() { parent::setUp(); - // Reset all services instances - Services::reset(); - // Initialize the Autoloader... - we need it to search for language files in the locator - Services::autoloader()->initialize(new \Config\Autoload()); + Services::reset(true); $this->validation = new Validation((object) $this->config, \Config\Services::renderer()); $this->validation->reset(); diff --git a/tests/system/View/ParserPluginTest.php b/tests/system/View/ParserPluginTest.php index bd8588ddae3d..4b3df74aabe4 100644 --- a/tests/system/View/ParserPluginTest.php +++ b/tests/system/View/ParserPluginTest.php @@ -15,8 +15,8 @@ public function setUp() { parent::setUp(); - \Config\Services::reset(); - \Config\Services::autoloader()->initialize(new \Config\Autoload()); + \Config\Services::reset(true); + $this->parser = \Config\Services::parser(); $this->validator = \Config\Services::validation(); } From ba53ae9f58f740db69963f798d66bf9640c9b2b9 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Fri, 30 Nov 2018 23:43:26 -0200 Subject: [PATCH 20/27] Returns false if the Qualified Name is not found --- system/Autoloader/FileLocator.php | 15 +++++++-------- tests/system/Autoloader/FileLocatorTest.php | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index 71547575c5be..2cffdb882665 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -220,9 +220,7 @@ public function search(string $path, string $ext = 'php'): array foreach ($this->getNamespaces() as $namespace) { - $namespace['path'] = rtrim($namespace['path'], '/') . '/'; - - if (is_file($namespace['path'] . $path) === true) + if (is_file($namespace['path'] . $path)) { $foundPaths[] = $namespace['path'] . $path; } @@ -294,13 +292,12 @@ protected function getNamespaces(string $prefix = null) //-------------------------------------------------------------------- /** - * Attempts to load a file and instantiate a new class by looking - * at its full path and comparing that to our existing psr4 namespaces - * in Autoloader config file. + * Find the qualified name of a file according to + * the namespace of the first matched namespace path. * * @param string $path * - * @return string|void + * @return string|false The qualified name or false if the path is not found */ public function findQualifiedNameFromPath(string $path) { @@ -308,7 +305,7 @@ public function findQualifiedNameFromPath(string $path) if (! $path) { - return; + return false; } foreach ($this->getNamespaces() as $namespace) @@ -332,6 +329,8 @@ public function findQualifiedNameFromPath(string $path) return $className; } } + + return false; } //-------------------------------------------------------------------- diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php index 23d2f8a0b863..f4065ba92bda 100644 --- a/tests/system/Autoloader/FileLocatorTest.php +++ b/tests/system/Autoloader/FileLocatorTest.php @@ -245,14 +245,14 @@ public function testFindQNameFromPathWithFileNotExist() { $ClassName = $this->locator->findQualifiedNameFromPath('modules/blog/Views/index.php'); - $this->assertNull($ClassName); + $this->assertFalse($ClassName); } public function testFindQNameFromPathWithoutCorrespondingNamespace() { $ClassName = $this->locator->findQualifiedNameFromPath('/etc/hosts'); - $this->assertNull($ClassName); + $this->assertFalse($ClassName); } public function testGetClassNameFromClassFile() From 07d7380fcb2c2161dbf2b30b4a3db3b5e6b0d79f Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Sat, 1 Dec 2018 18:15:01 -0200 Subject: [PATCH 21/27] Update FileLocator --- system/Autoloader/FileLocator.php | 58 +++++++-------------- tests/system/Autoloader/FileLocatorTest.php | 6 +-- 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index 2cffdb882665..d2018fa746e1 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -37,7 +37,7 @@ */ /** - * Class Loader + * Class FileLocator * * Allows loading non-class files in a namespaced manner. * Works with Helpers, Views, etc. @@ -73,26 +73,26 @@ public function __construct(Autoloader $autoloader) * @param string $folder The folder within the namespace that we should look for the file. * @param string $ext The file extension the file should have. * - * @return string The path to the file if found, or an empty string. + * @return string|false The path to the file, or false if not found. */ - public function locateFile(string $file, string $folder = null, string $ext = 'php'): string + public function locateFile(string $file, string $folder = null, string $ext = 'php') { $file = $this->ensureExt($file, $ext); // Clears the folder name if it is at the beginning of the filename if (! empty($folder) && ($pos = strpos($file, $folder)) === 0) { - $file = substr_replace($file, '', $pos, strlen($folder . '/')); + $file = substr($file, strlen($folder . '/')); } - // No namespaceing? Try the application folder. + // Is not namespaced? Try the application folder. if (strpos($file, '\\') === false) { return $this->legacyLocate($file, $folder); } // Standardize slashes to handle nested directories. - $file = str_replace('/', '\\', $file); + $file = strtr($file, '/', '\\'); $segments = explode('\\', $file); @@ -106,13 +106,16 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p $prefix = ''; $filename = ''; + // Namespaces always comes with arrays of paths + $namespaces = $this->autoloader->getNamespace(); + while (! empty($segments)) { $prefix .= empty($prefix) ? ucfirst(array_shift($segments)) : '\\' . ucfirst(array_shift($segments)); - if (! array_key_exists($prefix, $this->autoloader->getNamespace())) + if (empty($namespaces[$prefix])) { continue; } @@ -124,19 +127,14 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p // IF we have a folder name, then the calling function // expects this file to be within that folder, like 'Views', // or 'libraries'. - if (! empty($folder) && strpos($filename, $folder) === false) + if (! empty($folder) && strpos($filename, $folder . '/') !== 0) { $filename = $folder . '/' . $filename; } $path .= $filename; - if (! $this->requireFile($path)) - { - $path = ''; - } - - return $path; + return is_file($path) ? $path : false; } //-------------------------------------------------------------------- @@ -337,7 +335,7 @@ public function findQualifiedNameFromPath(string $path) /** * Scans the defined namespaces, returning a list of all files - * that are contained within the subpath specifed by $path. + * that are contained within the subpath specified by $path. * * @param string $path * @@ -355,7 +353,7 @@ public function listFiles(string $path): array foreach ($this->getNamespaces() as $namespace) { - $fullPath = realpath(rtrim($namespace['path'], '/') . '/' . $path); + $fullPath = realpath($namespace['path'] . $path); if (! is_dir($fullPath)) { @@ -373,6 +371,8 @@ public function listFiles(string $path): array return $files; } + //-------------------------------------------------------------------- + /** * Checks the application folder to see if the file can be found. * Only for use with filenames that DO NOT include namespacing. @@ -380,10 +380,9 @@ public function listFiles(string $path): array * @param string $file * @param string|null $folder * - * @return string - * @internal param string $ext + * @return string|false The path to the file, or false if not found. */ - protected function legacyLocate(string $file, string $folder = null): string + protected function legacyLocate(string $file, string $folder = null) { $paths = [ APPPATH, @@ -394,29 +393,12 @@ protected function legacyLocate(string $file, string $folder = null): string { $path .= empty($folder) ? $file : $folder . '/' . $file; - if ($this->requireFile($path) === true) + if (is_file($path)) { return $path; } } - return ''; - } - - //-------------------------------------------------------------------- - - /** - * Checks to see if a file exists on the file system. This is split - * out to it's own method to make testing simpler. - * - * @param string $path - * - * @return boolean - */ - protected function requireFile(string $path): bool - { - return is_file($path); + return false; } - - //-------------------------------------------------------------------- } diff --git a/tests/system/Autoloader/FileLocatorTest.php b/tests/system/Autoloader/FileLocatorTest.php index f4065ba92bda..f9e55ca55657 100644 --- a/tests/system/Autoloader/FileLocatorTest.php +++ b/tests/system/Autoloader/FileLocatorTest.php @@ -47,7 +47,7 @@ public function testLocateFileWithLegacyStructureNotFound() { $file = 'Unknown'; - $this->assertEquals('', $this->locator->locateFile($file)); + $this->assertFalse($this->locator->locateFile($file)); } //-------------------------------------------------------------------- @@ -129,11 +129,11 @@ public function testLocateFileCanFindNestedNamespacedView() //-------------------------------------------------------------------- - public function testLocateFileReturnsEmptyWithBadNamespace() + public function testLocateFileNotFoundWithBadNamespace() { $file = '\Blogger\admin/posts.php'; - $this->assertEquals('', $this->locator->locateFile($file, 'Views')); + $this->assertFalse($this->locator->locateFile($file, 'Views')); } //-------------------------------------------------------------------- From af2eba6fafc6b5ca90253f4e1ca341cdf4ac6889 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Sat, 1 Dec 2018 18:49:29 -0200 Subject: [PATCH 22/27] Return null since it is not a void function --- system/Config/BaseService.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/system/Config/BaseService.php b/system/Config/BaseService.php index 7e0cc8288007..a9e5bba74057 100644 --- a/system/Config/BaseService.php +++ b/system/Config/BaseService.php @@ -235,6 +235,8 @@ public static function injectMock(string $name, $mock) * * @param string $name * @param array $arguments + * + * @return mixed */ protected static function discoverServices(string $name, array $arguments) { @@ -249,7 +251,7 @@ protected static function discoverServices(string $name, array $arguments) if (empty($files)) { - return; + return null; } // Get instances of all service classes and cache them locally. @@ -269,7 +271,7 @@ protected static function discoverServices(string $name, array $arguments) if (! static::$services) { - return; + return null; } // Try to find the desired service method @@ -280,5 +282,7 @@ protected static function discoverServices(string $name, array $arguments) return $class::$name(...$arguments); } } + + return null; } } From f5d9f626934bfa4beee0c6e85f15fde020d4b9d9 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Sat, 1 Dec 2018 19:00:16 -0200 Subject: [PATCH 23/27] Use static method rather than function to use services --- system/CLI/CommandRunner.php | 7 +++---- system/Language/Language.php | 13 ++++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/system/CLI/CommandRunner.php b/system/CLI/CommandRunner.php index 7585aa9fd97f..7f2cdf93e7ce 100644 --- a/system/CLI/CommandRunner.php +++ b/system/CLI/CommandRunner.php @@ -37,6 +37,7 @@ * @filesource */ +use CodeIgniter\Config\Services; use CodeIgniter\Controller; class CommandRunner extends Controller @@ -127,12 +128,10 @@ protected function runCommand(string $command, array $params) /** * Scans all Commands directories and prepares a list * of each command with it's group and file. - * - * @return null|void */ protected function createCommandList() { - $files = service('locator')->listFiles('Commands/'); + $files = Services::locator()->listFiles('Commands/'); // If no matching command files were found, bail if (empty($files)) @@ -144,7 +143,7 @@ protected function createCommandList() // alias exists in the class. If so, return it. Otherwise, try the next. foreach ($files as $file) { - $className = service('locator')->findQualifiedNameFromPath($file); + $className = Services::locator()->findQualifiedNameFromPath($file); if (empty($className) || ! class_exists($className)) { continue; diff --git a/system/Language/Language.php b/system/Language/Language.php index d3f948d86ef2..35f54bfa4dc4 100644 --- a/system/Language/Language.php +++ b/system/Language/Language.php @@ -36,6 +36,13 @@ * @filesource */ +use CodeIgniter\Config\Services; + +/** + * Class Language + * + * @package CodeIgniter\Language + */ class Language { @@ -102,6 +109,8 @@ public function setLocale(string $locale = null) return $this; } + //-------------------------------------------------------------------- + /** * @return string */ @@ -110,6 +119,8 @@ public function getLocale(): string return $this->locale; } + //-------------------------------------------------------------------- + /** * Parses the language string for a file, loads the file, if necessary, * getting the line. @@ -263,7 +274,7 @@ protected function load(string $file, string $locale, bool $return = false) */ protected function requireFile(string $path): array { - $files = service('locator')->search($path); + $files = Services::locator()->search($path); $strings = []; From 817a9cd02a1ddf5cc0cc4c6b052d03ea5248ed00 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Sat, 1 Dec 2018 19:05:47 -0200 Subject: [PATCH 24/27] Add CLI.commandNotFound language string --- system/CLI/CommandRunner.php | 2 +- system/Language/en/CLI.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/system/CLI/CommandRunner.php b/system/CLI/CommandRunner.php index 7f2cdf93e7ce..bca09800090a 100644 --- a/system/CLI/CommandRunner.php +++ b/system/CLI/CommandRunner.php @@ -110,7 +110,7 @@ protected function runCommand(string $command, array $params) { if (! isset($this->commands[$command])) { - CLI::error('Command \'' . $command . '\' not found'); + CLI::error(lang('CLI.commandNotFound', [$command])); CLI::newLine(); return; } diff --git a/system/Language/en/CLI.php b/system/Language/en/CLI.php index 40bc70332028..4f6176e3d9dd 100644 --- a/system/Language/en/CLI.php +++ b/system/Language/en/CLI.php @@ -15,6 +15,7 @@ */ return [ + 'commandNotFound' => 'Command "{0}" not found.', 'helpUsage' => 'Usage:', 'helpDescription' => 'Description:', 'helpOptions' => 'Options:', From 40ec26bf31011e09a0e21fbcecb48ec82656f31e Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Sat, 1 Dec 2018 19:27:29 -0200 Subject: [PATCH 25/27] Update some PHPDocs and return types --- system/Common.php | 8 +++----- system/Log/Logger.php | 36 ++++++++++++++++++------------------ 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/system/Common.php b/system/Common.php index 1814c882d4dd..c9cbadfc81af 100644 --- a/system/Common.php +++ b/system/Common.php @@ -199,7 +199,7 @@ function env(string $key, $default = null) case 'empty': return ''; case 'null': - return; + return null; } return $value; @@ -488,9 +488,7 @@ function is_cli() */ function route_to(string $method, ...$params): string { - $routes = Services::routes(); - - return $routes->reverseRoute($method, ...$params); + return Services::routes()->reverseRoute($method, ...$params); } } @@ -713,7 +711,7 @@ function csrf_field() * * Not testable, as it will exit! * - * @throws \CodeIgniter\HTTP\RedirectException + * @throws \CodeIgniter\HTTP\Exceptions\HTTPException * @codeCoverageIgnore */ function force_https(int $duration = 31536000, RequestInterface $request = null, ResponseInterface $response = null) diff --git a/system/Log/Logger.php b/system/Log/Logger.php index aeb0ab0791c2..983c1d3e2c0a 100644 --- a/system/Log/Logger.php +++ b/system/Log/Logger.php @@ -146,8 +146,8 @@ class Logger implements LoggerInterface /** * Constructor. * - * @param type $config - * @param boolean $debug + * @param \Config\Logger $config + * @param boolean $debug * @throws \RuntimeException */ public function __construct($config, bool $debug = CI_DEBUG) @@ -194,11 +194,11 @@ public function __construct($config, bool $debug = CI_DEBUG) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function emergency($message, array $context = []) { - $this->log('emergency', $message, $context); + return $this->log('emergency', $message, $context); } //-------------------------------------------------------------------- @@ -212,11 +212,11 @@ public function emergency($message, array $context = []) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function alert($message, array $context = []) { - $this->log('alert', $message, $context); + return $this->log('alert', $message, $context); } //-------------------------------------------------------------------- @@ -229,11 +229,11 @@ public function alert($message, array $context = []) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function critical($message, array $context = []) { - $this->log('critical', $message, $context); + return $this->log('critical', $message, $context); } //-------------------------------------------------------------------- @@ -245,11 +245,11 @@ public function critical($message, array $context = []) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function error($message, array $context = []) { - $this->log('error', $message, $context); + return $this->log('error', $message, $context); } //-------------------------------------------------------------------- @@ -263,11 +263,11 @@ public function error($message, array $context = []) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function warning($message, array $context = []) { - $this->log('warning', $message, $context); + return $this->log('warning', $message, $context); } //-------------------------------------------------------------------- @@ -278,11 +278,11 @@ public function warning($message, array $context = []) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function notice($message, array $context = []) { - $this->log('notice', $message, $context); + return $this->log('notice', $message, $context); } //-------------------------------------------------------------------- @@ -295,11 +295,11 @@ public function notice($message, array $context = []) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function info($message, array $context = []) { - $this->log('info', $message, $context); + return $this->log('info', $message, $context); } //-------------------------------------------------------------------- @@ -310,11 +310,11 @@ public function info($message, array $context = []) * @param string $message * @param array $context * - * @return null + * @return boolean */ public function debug($message, array $context = []) { - $this->log('debug', $message, $context); + return $this->log('debug', $message, $context); } //-------------------------------------------------------------------- From 64cfc1af5c913ec79f69d134ce0a59ac9938786d Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Sat, 1 Dec 2018 20:02:45 -0200 Subject: [PATCH 26/27] Update testBadCommand error string --- tests/system/CLI/CommandRunnerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/CLI/CommandRunnerTest.php b/tests/system/CLI/CommandRunnerTest.php index 81102f2fa612..04bb83f7d1fc 100644 --- a/tests/system/CLI/CommandRunnerTest.php +++ b/tests/system/CLI/CommandRunnerTest.php @@ -90,7 +90,7 @@ public function testBadCommand() stream_filter_remove($this->error_filter); // make sure the result looks like a command list - $this->assertContains("Command 'bogus' not found", $result); + $this->assertContains('Command "bogus" not found', $result); } } From 90cab15ae22a328b06abec211c873b0ea9b67dc7 Mon Sep 17 00:00:00 2001 From: Natan Felles Date: Sat, 1 Dec 2018 21:35:54 -0200 Subject: [PATCH 27/27] Surround the check value by slashes to ensure the position is the folder and not any other string part - checking the full filepath --- system/Autoloader/FileLocator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/Autoloader/FileLocator.php b/system/Autoloader/FileLocator.php index d2018fa746e1..05f65f62ce30 100644 --- a/system/Autoloader/FileLocator.php +++ b/system/Autoloader/FileLocator.php @@ -127,7 +127,7 @@ public function locateFile(string $file, string $folder = null, string $ext = 'p // IF we have a folder name, then the calling function // expects this file to be within that folder, like 'Views', // or 'libraries'. - if (! empty($folder) && strpos($filename, $folder . '/') !== 0) + if (! empty($folder) && strpos($path . $filename, '/' . $folder . '/') === false) { $filename = $folder . '/' . $filename; }