From ecfc323557d21a064729897ed254d2bf8a99e8c7 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 13:30:08 +0900 Subject: [PATCH 01/27] test: define param types --- tests/system/Router/RouteCollectionTest.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/system/Router/RouteCollectionTest.php b/tests/system/Router/RouteCollectionTest.php index 89959cd5f33e..ef67c02a29fc 100644 --- a/tests/system/Router/RouteCollectionTest.php +++ b/tests/system/Router/RouteCollectionTest.php @@ -1768,11 +1768,8 @@ public static function provideRouteDefaultNamespace(): iterable ]; } - /** - * @param mixed $namespace - */ #[DataProvider('provideRouteDefaultNamespace')] - public function testAutoRoutesControllerNameReturnsFQCN($namespace): void + public function testAutoRoutesControllerNameReturnsFQCN(string $namespace): void { $routes = $this->getCollector(); $routes->setAutoRoute(true); @@ -1788,11 +1785,8 @@ public function testAutoRoutesControllerNameReturnsFQCN($namespace): void $this->assertSame('\\' . Product::class, $router->controllerName()); } - /** - * @param mixed $namespace - */ #[DataProvider('provideRouteDefaultNamespace')] - public function testRoutesControllerNameReturnsFQCN($namespace): void + public function testRoutesControllerNameReturnsFQCN(string $namespace): void { Services::request()->setMethod(Method::GET); $routes = $this->getCollector(); From ab49378eb7feed6ca2c6657acffb5703302c8864 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 13:34:48 +0900 Subject: [PATCH 02/27] config: change default config for Auto Routing Improved Feature::$autoRoutesImproved -> true Routing::$translateUriToCamelCase -> true --- app/Config/Feature.php | 4 ++-- app/Config/Routing.php | 2 +- tests/system/Commands/RoutesTest.php | 3 +++ .../ControllerMethodReaderTest.php | 5 +++-- tests/system/Router/AutoRouterImprovedTest.php | 18 ++++++++++++++++++ tests/system/Router/RouteCollectionTest.php | 4 ++++ tests/system/Router/RouterTest.php | 8 ++++++++ 7 files changed, 39 insertions(+), 5 deletions(-) diff --git a/app/Config/Feature.php b/app/Config/Feature.php index efd4a0b20ae8..35024d357919 100644 --- a/app/Config/Feature.php +++ b/app/Config/Feature.php @@ -10,9 +10,9 @@ class Feature extends BaseConfig { /** - * Use improved new auto routing instead of the default legacy version. + * Use improved new auto routing instead of the legacy version. */ - public bool $autoRoutesImproved = false; + public bool $autoRoutesImproved = true; /** * Use filter execution order in 4.4 or before. diff --git a/app/Config/Routing.php b/app/Config/Routing.php index 7abadc7b76f0..3005543a9e79 100644 --- a/app/Config/Routing.php +++ b/app/Config/Routing.php @@ -136,5 +136,5 @@ class Routing extends BaseRouting * * Default: false */ - public bool $translateUriToCamelCase = false; + public bool $translateUriToCamelCase = true; } diff --git a/tests/system/Commands/RoutesTest.php b/tests/system/Commands/RoutesTest.php index 2ee9f44f1bac..60b326dee35e 100644 --- a/tests/system/Commands/RoutesTest.php +++ b/tests/system/Commands/RoutesTest.php @@ -16,6 +16,7 @@ use CodeIgniter\Router\RouteCollection; use CodeIgniter\Test\CIUnitTestCase; use CodeIgniter\Test\StreamFilterTrait; +use Config\Feature; use Config\Services; use PHPUnit\Framework\Attributes\Group; @@ -213,6 +214,8 @@ public function testRoutesCommandRouteLegacy(): void $routes = $this->getCleanRoutes(); $routes->loadRoutes(); + $featureConfig = config(Feature::class); + $featureConfig->autoRoutesImproved = false; $routes->setAutoRoute(true); command('routes'); diff --git a/tests/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReaderTest.php b/tests/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReaderTest.php index 936b2b8fe184..2eaabe3cd833 100644 --- a/tests/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReaderTest.php +++ b/tests/system/Commands/Utilities/Routes/AutoRouterImproved/ControllerMethodReaderTest.php @@ -74,8 +74,9 @@ public function testRead(): void public function testReadTranslateURIDashes(): void { - $config = config(Routing::class); - $config->translateURIDashes = true; + $config = config(Routing::class); + $config->translateURIDashes = true; + $config->translateUriToCamelCase = false; Factories::injectMock('config', Routing::class, $config); $reader = $this->createControllerMethodReader( diff --git a/tests/system/Router/AutoRouterImprovedTest.php b/tests/system/Router/AutoRouterImprovedTest.php index 5975280bcdfd..7e6f639f7ddc 100644 --- a/tests/system/Router/AutoRouterImprovedTest.php +++ b/tests/system/Router/AutoRouterImprovedTest.php @@ -204,8 +204,16 @@ public function testAutoRouteFindsControllerWithSubSubfolder(): void $this->assertSame([], $params); } + private function disableTranslateUriToCamelCase(): void + { + $routingConfig = config(Routing::class); + $routingConfig->translateUriToCamelCase = false; + } + public function testAutoRouteFindsDashedSubfolder(): void { + $this->disableTranslateUriToCamelCase(); + $router = $this->createNewAutoRouter(); [$directory, $controller, $method, $params] @@ -222,6 +230,8 @@ public function testAutoRouteFindsDashedSubfolder(): void public function testAutoRouteFindsDashedController(): void { + $this->disableTranslateUriToCamelCase(); + $router = $this->createNewAutoRouter(); [$directory, $controller, $method, $params] @@ -235,6 +245,8 @@ public function testAutoRouteFindsDashedController(): void public function testAutoRouteFindsDashedMethod(): void { + $this->disableTranslateUriToCamelCase(); + $router = $this->createNewAutoRouter(); [$directory, $controller, $method, $params] @@ -248,6 +260,8 @@ public function testAutoRouteFindsDashedMethod(): void public function testAutoRouteFindsDefaultDashFolder(): void { + $this->disableTranslateUriToCamelCase(); + $router = $this->createNewAutoRouter(); [$directory, $controller, $method, $params] @@ -438,6 +452,8 @@ public function testRejectsURIWithUnderscoreController(): void 'AutoRouterImproved prohibits access to the URI containing underscores ("dash_controller")' ); + $this->disableTranslateUriToCamelCase(); + $router = $this->createNewAutoRouter(); $router->getRoute('dash-folder/dash_controller/dash-method', Method::GET); @@ -450,6 +466,8 @@ public function testRejectsURIWithUnderscoreMethod(): void 'AutoRouterImproved prohibits access to the URI containing underscores ("dash_method")' ); + $this->disableTranslateUriToCamelCase(); + $router = $this->createNewAutoRouter(); $router->getRoute('dash-folder/dash-controller/dash_method', Method::GET); diff --git a/tests/system/Router/RouteCollectionTest.php b/tests/system/Router/RouteCollectionTest.php index ef67c02a29fc..6f623196db69 100644 --- a/tests/system/Router/RouteCollectionTest.php +++ b/tests/system/Router/RouteCollectionTest.php @@ -19,6 +19,7 @@ use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\HTTP\Method; use CodeIgniter\Test\CIUnitTestCase; +use Config\Feature; use Config\Modules; use Config\Routing; use PHPUnit\Framework\Attributes\DataProvider; @@ -1771,6 +1772,9 @@ public static function provideRouteDefaultNamespace(): iterable #[DataProvider('provideRouteDefaultNamespace')] public function testAutoRoutesControllerNameReturnsFQCN(string $namespace): void { + $featureConfig = config(Feature::class); + $featureConfig->autoRoutesImproved = false; + $routes = $this->getCollector(); $routes->setAutoRoute(true); $routes->setDefaultNamespace($namespace); diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index bb5302e721dc..e21763b9dc8a 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -23,6 +23,7 @@ use CodeIgniter\Router\Exceptions\RouterException; use CodeIgniter\Test\CIUnitTestCase; use Config\App; +use Config\Feature; use Config\Modules; use Config\Routing; use PHPUnit\Framework\Attributes\DataProvider; @@ -42,12 +43,19 @@ protected function setUp(): void { parent::setUp(); + $this->disableAutoRoutesImproved(); $this->createRouteCollection(); $this->request = Services::request(); $this->request->setMethod(Method::GET); } + private function disableAutoRoutesImproved(): void + { + $featureConfig = config(Feature::class); + $featureConfig->autoRoutesImproved = false; + } + private function createRouteCollection(?Routing $routingConfig = null): void { $moduleConfig = new Modules(); From 5d139c32eb465fa9d8d94bed563b2d26fb92c521 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 13:52:20 +0900 Subject: [PATCH 03/27] docs: create new page auto_routing_improved.rst --- .../source/incoming/auto_routing_improved.rst | 140 ++++++++++++++++++ user_guide_src/source/incoming/index.rst | 1 + user_guide_src/source/incoming/routing.rst | 130 +--------------- 3 files changed, 142 insertions(+), 129 deletions(-) create mode 100644 user_guide_src/source/incoming/auto_routing_improved.rst diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst new file mode 100644 index 000000000000..db168a0d17b7 --- /dev/null +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -0,0 +1,140 @@ +####################### +Auto Routing (Improved) +####################### + +.. versionadded:: 4.2.0 + +.. contents:: + :local: + :depth: 3 + +.. _auto-routing-improved: + +Since v4.2.0, the new more secure Auto Routing has been introduced. + +.. note:: If you are familiar with Auto Routing, which was enabled by default + from CodeIgniter 3.x through 4.1.x, you can see the differences in + :ref:`ChangeLog v4.2.0 `. + +When no defined route is found that matches the URI, the system will attempt to match that URI against the controllers and methods when Auto Routing is enabled. + +.. important:: For security reasons, if a controller is used in the defined routes, Auto Routing (Improved) does not route to the controller. + +Auto Routing can automatically route HTTP requests based on conventions +and execute the corresponding controller methods. + +.. note:: Auto Routing (Improved) is disabled by default. To use it, see below. + +.. _enabled-auto-routing-improved: + +Enable Auto Routing +=================== + +To use it, you need to change the setting ``$autoRoute`` option to ``true`` in **app/Config/Routing.php**:: + + public bool $autoRoute = true; + +And you need to change the property ``$autoRoutesImproved`` to ``true`` in **app/Config/Feature.php**:: + + public bool $autoRoutesImproved = true; + +URI Segments +============ + +The segments in the URL, in following with the Model-View-Controller approach, usually represent:: + + example.com/class/method/ID + +1. The first segment represents the controller **class** that should be invoked. +2. The second segment represents the class **method** that should be called. +3. The third, and any additional segments, represent the ID and any variables that will be passed to the controller. + +Consider this URI:: + + example.com/index.php/helloworld/hello/1 + +In the above example, when you send an HTTP request with **GET** method, +Auto Routing would attempt to find a controller named ``App\Controllers\Helloworld`` +and executes ``getHello()`` method with passing ``'1'`` as the first argument. + +.. note:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. + +See :ref:`Auto Routing in Controllers ` for more info. + +.. _routing-auto-routing-improved-configuration-options: + +Configuration Options +===================== + +These options are available in the **app/Config/Routing.php** file. + +Default Controller +------------------ + +For Site Root URI +^^^^^^^^^^^^^^^^^ + +When a user visits the root of your site (i.e., **example.com**) the controller +to use is determined by the value set to the ``$defaultController`` property, +unless a route exists for it explicitly. + +The default value for this is ``Home`` which matches the controller at +**app/Controllers/Home.php**:: + + public string $defaultController = 'Home'; + +For Directory URI +^^^^^^^^^^^^^^^^^ + +The default controller is also used when no matching route has been found, and the URI would point to a directory +in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at +**app/Controllers/Admin/Home.php**, it would be used. + +.. important:: You cannot access the default controller with the URI of the controller name. + When the default controller is ``Home``, you can access **example.com/**, but if you access **example.com/home**, it will be not found. + +See :ref:`Auto Routing in Controllers ` for more info. + +.. _routing-auto-routing-improved-default-method: + +Default Method +-------------- + +This works similar to the default controller setting, but is used to determine the default method that is used +when a controller is found that matches the URI, but no segment exists for the method. The default value is +``index``. + +In this example, if the user were to visit **example.com/products**, and a ``Products`` +controller existed, the ``Products::getListAll()`` method would be executed:: + + public string $defaultMethod = 'listAll'; + +.. important:: You cannot access the controller with the URI of the default method name. + In the example above, you can access **example.com/products**, but if you access **example.com/products/listall**, it will be not found. + +.. _auto-routing-improved-module-routing: + + +Module Routing +============== + +.. versionadded:: 4.4.0 + +You can use auto routing even if you use :doc:`../general/modules` and place +the controllers in a different namespace. + +To route to a module, the ``$moduleRoutes`` property in **app/Config/Routing.php** +must be set:: + + public array $moduleRoutes = [ + 'blog' => 'Acme\Blog\Controllers', + ]; + +The key is the first URI segment for the module, and the value is the controller +namespace. In the above configuration, **http://localhost:8080/blog/foo/bar** +will be routed to ``Acme\Blog\Controllers\Foo::getBar()``. + +.. note:: If you define ``$moduleRoutes``, the routing for the module takes + precedence. In the above example, even if you have the ``App\Controllers\Blog`` + controller, **http://localhost:8080/blog** will be routed to the default + controller ``Acme\Blog\Controllers\Home``. diff --git a/user_guide_src/source/incoming/index.rst b/user_guide_src/source/incoming/index.rst index b4399e18d1ba..d8faf0a869b5 100644 --- a/user_guide_src/source/incoming/index.rst +++ b/user_guide_src/source/incoming/index.rst @@ -10,6 +10,7 @@ Controllers handle incoming requests. routing controllers filters + auto_routing_improved message request incomingrequest diff --git a/user_guide_src/source/incoming/routing.rst b/user_guide_src/source/incoming/routing.rst index 3ab7a5848bc9..da55dfa7fd20 100644 --- a/user_guide_src/source/incoming/routing.rst +++ b/user_guide_src/source/incoming/routing.rst @@ -767,140 +767,12 @@ will match **product/123**, **product/123/456**, **product/123/456/789** and so And if the URI is **product/123/456**, ``123/456`` will be passed to the first parameter of the ``Catalog::productLookup()`` method. -.. _auto-routing-improved: - Auto Routing (Improved) *********************** .. versionadded:: 4.2.0 -Since v4.2.0, the new more secure Auto Routing has been introduced. - -.. note:: If you are familiar with Auto Routing, which was enabled by default - from CodeIgniter 3.x through 4.1.x, you can see the differences in - :ref:`ChangeLog v4.2.0 `. - -When no defined route is found that matches the URI, the system will attempt to match that URI against the controllers and methods when Auto Routing is enabled. - -.. important:: For security reasons, if a controller is used in the defined routes, Auto Routing (Improved) does not route to the controller. - -Auto Routing can automatically route HTTP requests based on conventions -and execute the corresponding controller methods. - -.. note:: Auto Routing (Improved) is disabled by default. To use it, see below. - -.. _enabled-auto-routing-improved: - -Enable Auto Routing -=================== - -To use it, you need to change the setting ``$autoRoute`` option to ``true`` in **app/Config/Routing.php**:: - - public bool $autoRoute = true; - -And you need to change the property ``$autoRoutesImproved`` to ``true`` in **app/Config/Feature.php**:: - - public bool $autoRoutesImproved = true; - -URI Segments -============ - -The segments in the URL, in following with the Model-View-Controller approach, usually represent:: - - example.com/class/method/ID - -1. The first segment represents the controller **class** that should be invoked. -2. The second segment represents the class **method** that should be called. -3. The third, and any additional segments, represent the ID and any variables that will be passed to the controller. - -Consider this URI:: - - example.com/index.php/helloworld/hello/1 - -In the above example, when you send an HTTP request with **GET** method, -Auto Routing would attempt to find a controller named ``App\Controllers\Helloworld`` -and executes ``getHello()`` method with passing ``'1'`` as the first argument. - -.. note:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. - -See :ref:`Auto Routing in Controllers ` for more info. - -.. _routing-auto-routing-improved-configuration-options: - -Configuration Options -===================== - -These options are available in the **app/Config/Routing.php** file. - -Default Controller ------------------- - -For Site Root URI -^^^^^^^^^^^^^^^^^ - -When a user visits the root of your site (i.e., **example.com**) the controller -to use is determined by the value set to the ``$defaultController`` property, -unless a route exists for it explicitly. - -The default value for this is ``Home`` which matches the controller at -**app/Controllers/Home.php**:: - - public string $defaultController = 'Home'; - -For Directory URI -^^^^^^^^^^^^^^^^^ - -The default controller is also used when no matching route has been found, and the URI would point to a directory -in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at -**app/Controllers/Admin/Home.php**, it would be used. - -.. important:: You cannot access the default controller with the URI of the controller name. - When the default controller is ``Home``, you can access **example.com/**, but if you access **example.com/home**, it will be not found. - -See :ref:`Auto Routing in Controllers ` for more info. - -.. _routing-auto-routing-improved-default-method: - -Default Method --------------- - -This works similar to the default controller setting, but is used to determine the default method that is used -when a controller is found that matches the URI, but no segment exists for the method. The default value is -``index``. - -In this example, if the user were to visit **example.com/products**, and a ``Products`` -controller existed, the ``Products::getListAll()`` method would be executed:: - - public string $defaultMethod = 'listAll'; - -.. important:: You cannot access the controller with the URI of the default method name. - In the example above, you can access **example.com/products**, but if you access **example.com/products/listall**, it will be not found. - -.. _auto-routing-improved-module-routing: - -Module Routing -============== - -.. versionadded:: 4.4.0 - -You can use auto routing even if you use :doc:`../general/modules` and place -the controllers in a different namespace. - -To route to a module, the ``$moduleRoutes`` property in **app/Config/Routing.php** -must be set:: - - public array $moduleRoutes = [ - 'blog' => 'Acme\Blog\Controllers', - ]; - -The key is the first URI segment for the module, and the value is the controller -namespace. In the above configuration, **http://localhost:8080/blog/foo/bar** -will be routed to ``Acme\Blog\Controllers\Foo::getBar()``. - -.. note:: If you define ``$moduleRoutes``, the routing for the module takes - precedence. In the above example, even if you have the ``App\Controllers\Blog`` - controller, **http://localhost:8080/blog** will be routed to the default - controller ``Acme\Blog\Controllers\Home``. +See :doc:`auto_routing_improved`. .. _auto-routing-legacy: From e51627a4f5f491d808296b32eaf94def77f3ad26 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 14:11:15 +0900 Subject: [PATCH 04/27] docs: move contents in controllers.rst to auto_routing_improved.rst --- .../source/incoming/auto_routing_improved.rst | 269 ++++++++++++++++- .../source/incoming/controllers.rst | 278 +----------------- 2 files changed, 269 insertions(+), 278 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index db168a0d17b7..c95aff1b308d 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -59,7 +59,274 @@ and executes ``getHello()`` method with passing ``'1'`` as the first argument. .. note:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. -See :ref:`Auto Routing in Controllers ` for more info. +This section describes the functionality of the new auto-routing. +It automatically routes an HTTP request, and executes the corresponding controller method +without route definitions. + +Consider this URI:: + + example.com/index.php/helloworld/ + +In the above example, CodeIgniter would attempt to find a controller named ``App\Controllers\Helloworld`` and load it, when auto-routing is enabled. + +.. note:: When a controller's short name matches the first segment of a URI, it will be loaded. + +Let's try it: Hello World! +========================== + +Let's create a simple controller so you can see it in action. Using your text editor, create a file called **Helloworld.php**, +and put the following code in it. You will notice that the ``Helloworld`` Controller is extending the ``BaseController``. you can +also extend the ``CodeIgniter\Controller`` if you do not need the functionality of the BaseController. + +The BaseController provides a convenient place for loading components and performing functions that are needed by all your +controllers. You can extend this class in any new controller. + +.. literalinclude:: controllers/020.php + +Then save the file to your **app/Controllers** directory. + +.. important:: The file must be called **Helloworld.php**, with a capital ``H``. When you use Auto Routing, Controller class names MUST start with an uppercase letter and ONLY the first character can be uppercase. + + Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, you can + use CamelCase classnames. See :ref:`controller-translate-uri-to-camelcase` + for details. + +.. important:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. + +Now visit your site using a URL similar to this:: + + example.com/index.php/helloworld + +If you did it right you should see:: + + Hello World! + +This is valid: + +.. literalinclude:: controllers/009.php + +This is **not** valid: + +.. literalinclude:: controllers/010.php + +This is **not** valid: + +.. literalinclude:: controllers/011.php + +.. note:: Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, + you can use CamelCase classnames like above. See + :ref:`controller-translate-uri-to-camelcase` for details. + +Also, always make sure your controller extends the parent controller +class so that it can inherit all its methods. + +.. note:: + The system will attempt to match the URI against Controllers by matching each segment against + directories/files in **app/Controllers**, when a match wasn't found against defined routes. + That's why your directories/files MUST start with a capital letter and the rest MUST be lowercase. + + If you want another naming convention you need to manually define it using the + :ref:`Defined Route Routing `. + Here is an example based on PSR-4 Autoloader: + + .. literalinclude:: controllers/012.php + +Methods +======= + +Method Visibility +----------------- + +When you define a method that is executable via HTTP request, the method must be +declared as ``public``. + +.. warning:: For security reasons be sure to declare any new utility methods as ``protected`` or ``private``. + +Default Method +-------------- + +In the above example, the method name is ``getIndex()``. +The method (HTTP verb + ``Index()``) is called the **default method**, and is loaded if the **second segment** of the URI is empty. + +Normal Methods +-------------- + +The second segment of the URI determines which method in the +controller gets called. + +Let's try it. Add a new method to your controller: + +.. literalinclude:: controllers/021.php + +Now load the following URL to see the ``getComment()`` method:: + + example.com/index.php/helloworld/comment/ + +You should see your new message. + +Passing URI Segments to Your Methods +==================================== + +If your URI contains more than two segments they will be passed to your +method as parameters. + +For example, let's say you have a URI like this:: + + example.com/index.php/products/shoes/sandals/123 + +Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): + +.. literalinclude:: controllers/022.php + +Default Controller +================== + +The Default Controller is a special controller that is used when a URI ends with +a directory name or when a URI is not present, as will be the case when only your +site root URL is requested. + +Defining a Default Controller +----------------------------- + +Let's try it with the ``Helloworld`` controller. + +To specify a default controller open your **app/Config/Routing.php** +file and set this property:: + + public string $defaultController = 'Helloworld'; + +Where ``Helloworld`` is the name of the controller class you want to be used. + +And comment out the line in **app/Config/Routes.php**: + +.. literalinclude:: controllers/016.php + :lines: 2- + +If you now browse to your site without specifying any URI segments you'll +see the "Hello World" message. + +.. important:: When you use Auto Routing (Improved), you must remove the line + ``$routes->get('/', 'Home::index');``. Because defined routes take + precedence over Auto Routing, and controllers defined in the defined routes + are denied access by Auto Routing (Improved) for security reasons. + +For more information, please refer to the +:ref:`routing-auto-routing-improved-configuration-options` documentation. + +.. _controller-default-method-fallback: + +Default Method Fallback +======================= + +.. versionadded:: 4.4.0 + +If the controller method corresponding to the URI segment of the method name +does not exist, and if the default method is defined, the remaining URI segments +are passed to the default method for execution. + +.. literalinclude:: controllers/024.php + +Load the following URL:: + + example.com/index.php/product/15/edit + +The method will be passed URI segments 2 and 3 (``'15'`` and ``'edit'``): + +.. important:: If there are more parameters in the URI than the method parameters, + Auto Routing (Improved) does not execute the method, and it results in 404 + Not Found. + +Fallback to Default Controller +------------------------------ + +If the controller corresponding to the URI segment of the controller name +does not exist, and if the default controller (``Home`` by default) exists in +the directory, the remaining URI segments are passed to the default controller's +default method. + +For example, when you have the following default controller ``Home`` in the +**app/Controllers/News** directory: + +.. literalinclude:: controllers/025.php + +Load the following URL:: + + example.com/index.php/news/101 + +The ``News\Home`` controller and the default ``getIndex()`` method will be found. +So the default method will be passed URI segments 2 (``'101'``): + +.. note:: If there is ``App\Controllers\News`` controller, it takes precedence. + The URI segments are searched sequentially and the first controller found + is used. + +.. note:: If there are more parameters in the URI than the method parameters, + Auto Routing (Improved) does not execute the method, and it results in 404 + Not Found. + +Organizing Your Controllers into Sub-directories +================================================ + +If you are building a large application you might want to hierarchically +organize or structure your controllers into sub-directories. CodeIgniter +permits you to do this. + +Simply create sub-directories under the main **app/Controllers**, +and place your controller classes within them. + +.. important:: Directory names MUST start with an uppercase letter and ONLY the first character can be uppercase. + + Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, you can + use CamelCase directory names. See :ref:`controller-translate-uri-to-camelcase` + for details. + +When using this feature the first segment of your URI must +specify the directory. For example, let's say you have a controller located here:: + + app/Controllers/Products/Shoes.php + +To call the above controller your URI will look something like this:: + + example.com/index.php/products/shoes/show/123 + +.. note:: You cannot have directories with the same name in **app/Controllers** + and **public**. + This is because if there is a directory, the web server will search for it and + it will not be routed to CodeIgniter. + +Each of your sub-directories may contain a default controller which will be +called if the URL contains *only* the sub-directory. Simply put a controller +in there that matches the name of your default controller as specified in +your **app/Config/Routing.php** file. + +CodeIgniter also permits you to map your URIs using its :ref:`Defined Route Routing `.. + +.. _controller-translate-uri-to-camelcase: + +Translate URI To CamelCase +========================== + +.. versionadded:: 4.5.0 + +Since v4.5.0, the ``$translateUriToCamelCase`` option has been implemented, +which works well with the current CodeIgniter's coding standards. + +This option enables you to automatically translate URI with dashes (``-``) to +CamelCase in the controller and method URI segments. + +For example, the URI ``sub-dir/hello-controller/some-method`` will execute the +``SubDir\HelloController::getSomeMethod()`` method. + +.. note:: When this option is enabled, the ``$translateURIDashes`` option is + ignored. + +Enable Translate URI To CamelCase +--------------------------------- + +To enable it, you need to change the setting ``$translateUriToCamelCase`` option +to ``true`` in **app/Config/Routing.php**:: + + public bool $translateUriToCamelCase = true; .. _routing-auto-routing-improved-configuration-options: diff --git a/user_guide_src/source/incoming/controllers.rst b/user_guide_src/source/incoming/controllers.rst index bd1f011df78b..de5798e8477e 100644 --- a/user_guide_src/source/incoming/controllers.rst +++ b/user_guide_src/source/incoming/controllers.rst @@ -182,283 +182,7 @@ Auto Routing (Improved) .. versionadded:: 4.2.0 -Since v4.2.0, the new more secure Auto Routing has been introduced. - -.. note:: If you are familiar with Auto Routing, which was enabled by default - from CodeIgniter 3.x through 4.1.x, you can see the differences in - :ref:`ChangeLog v4.2.0 `. - -This section describes the functionality of the new auto-routing. -It automatically routes an HTTP request, and executes the corresponding controller method -without route definitions. - -Since v4.2.0, the auto-routing is disabled by default. To use it, see :ref:`enabled-auto-routing-improved`. - -Consider this URI:: - - example.com/index.php/helloworld/ - -In the above example, CodeIgniter would attempt to find a controller named ``App\Controllers\Helloworld`` and load it, when auto-routing is enabled. - -.. note:: When a controller's short name matches the first segment of a URI, it will be loaded. - -Let's try it: Hello World! -========================== - -Let's create a simple controller so you can see it in action. Using your text editor, create a file called **Helloworld.php**, -and put the following code in it. You will notice that the ``Helloworld`` Controller is extending the ``BaseController``. you can -also extend the ``CodeIgniter\Controller`` if you do not need the functionality of the BaseController. - -The BaseController provides a convenient place for loading components and performing functions that are needed by all your -controllers. You can extend this class in any new controller. - -.. literalinclude:: controllers/020.php - -Then save the file to your **app/Controllers** directory. - -.. important:: The file must be called **Helloworld.php**, with a capital ``H``. When you use Auto Routing, Controller class names MUST start with an uppercase letter and ONLY the first character can be uppercase. - - Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, you can - use CamelCase classnames. See :ref:`controller-translate-uri-to-camelcase` - for details. - -.. important:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. - -Now visit your site using a URL similar to this:: - - example.com/index.php/helloworld - -If you did it right you should see:: - - Hello World! - -This is valid: - -.. literalinclude:: controllers/009.php - -This is **not** valid: - -.. literalinclude:: controllers/010.php - -This is **not** valid: - -.. literalinclude:: controllers/011.php - -.. note:: Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, - you can use CamelCase classnames like above. See - :ref:`controller-translate-uri-to-camelcase` for details. - -Also, always make sure your controller extends the parent controller -class so that it can inherit all its methods. - -.. note:: - The system will attempt to match the URI against Controllers by matching each segment against - directories/files in **app/Controllers**, when a match wasn't found against defined routes. - That's why your directories/files MUST start with a capital letter and the rest MUST be lowercase. - - If you want another naming convention you need to manually define it using the - :ref:`Defined Route Routing `. - Here is an example based on PSR-4 Autoloader: - - .. literalinclude:: controllers/012.php - -Methods -======= - -Method Visibility ------------------ - -When you define a method that is executable via HTTP request, the method must be -declared as ``public``. - -.. warning:: For security reasons be sure to declare any new utility methods as ``protected`` or ``private``. - -Default Method --------------- - -In the above example, the method name is ``getIndex()``. -The method (HTTP verb + ``Index()``) is called the **default method**, and is loaded if the **second segment** of the URI is empty. - -Normal Methods --------------- - -The second segment of the URI determines which method in the -controller gets called. - -Let's try it. Add a new method to your controller: - -.. literalinclude:: controllers/021.php - -Now load the following URL to see the ``getComment()`` method:: - - example.com/index.php/helloworld/comment/ - -You should see your new message. - -Passing URI Segments to Your Methods -==================================== - -If your URI contains more than two segments they will be passed to your -method as parameters. - -For example, let's say you have a URI like this:: - - example.com/index.php/products/shoes/sandals/123 - -Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): - -.. literalinclude:: controllers/022.php - -Default Controller -================== - -The Default Controller is a special controller that is used when a URI ends with -a directory name or when a URI is not present, as will be the case when only your -site root URL is requested. - -Defining a Default Controller ------------------------------ - -Let's try it with the ``Helloworld`` controller. - -To specify a default controller open your **app/Config/Routing.php** -file and set this property:: - - public string $defaultController = 'Helloworld'; - -Where ``Helloworld`` is the name of the controller class you want to be used. - -And comment out the line in **app/Config/Routes.php**: - -.. literalinclude:: controllers/016.php - :lines: 2- - -If you now browse to your site without specifying any URI segments you'll -see the "Hello World" message. - -.. important:: When you use Auto Routing (Improved), you must remove the line - ``$routes->get('/', 'Home::index');``. Because defined routes take - precedence over Auto Routing, and controllers defined in the defined routes - are denied access by Auto Routing (Improved) for security reasons. - -For more information, please refer to the -:ref:`routing-auto-routing-improved-configuration-options` documentation. - -.. _controller-default-method-fallback: - -Default Method Fallback -======================= - -.. versionadded:: 4.4.0 - -If the controller method corresponding to the URI segment of the method name -does not exist, and if the default method is defined, the remaining URI segments -are passed to the default method for execution. - -.. literalinclude:: controllers/024.php - -Load the following URL:: - - example.com/index.php/product/15/edit - -The method will be passed URI segments 2 and 3 (``'15'`` and ``'edit'``): - -.. important:: If there are more parameters in the URI than the method parameters, - Auto Routing (Improved) does not execute the method, and it results in 404 - Not Found. - -Fallback to Default Controller ------------------------------- - -If the controller corresponding to the URI segment of the controller name -does not exist, and if the default controller (``Home`` by default) exists in -the directory, the remaining URI segments are passed to the default controller's -default method. - -For example, when you have the following default controller ``Home`` in the -**app/Controllers/News** directory: - -.. literalinclude:: controllers/025.php - -Load the following URL:: - - example.com/index.php/news/101 - -The ``News\Home`` controller and the default ``getIndex()`` method will be found. -So the default method will be passed URI segments 2 (``'101'``): - -.. note:: If there is ``App\Controllers\News`` controller, it takes precedence. - The URI segments are searched sequentially and the first controller found - is used. - -.. note:: If there are more parameters in the URI than the method parameters, - Auto Routing (Improved) does not execute the method, and it results in 404 - Not Found. - -Organizing Your Controllers into Sub-directories -================================================ - -If you are building a large application you might want to hierarchically -organize or structure your controllers into sub-directories. CodeIgniter -permits you to do this. - -Simply create sub-directories under the main **app/Controllers**, -and place your controller classes within them. - -.. important:: Directory names MUST start with an uppercase letter and ONLY the first character can be uppercase. - - Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, you can - use CamelCase directory names. See :ref:`controller-translate-uri-to-camelcase` - for details. - -When using this feature the first segment of your URI must -specify the directory. For example, let's say you have a controller located here:: - - app/Controllers/Products/Shoes.php - -To call the above controller your URI will look something like this:: - - example.com/index.php/products/shoes/show/123 - -.. note:: You cannot have directories with the same name in **app/Controllers** - and **public**. - This is because if there is a directory, the web server will search for it and - it will not be routed to CodeIgniter. - -Each of your sub-directories may contain a default controller which will be -called if the URL contains *only* the sub-directory. Simply put a controller -in there that matches the name of your default controller as specified in -your **app/Config/Routing.php** file. - -CodeIgniter also permits you to map your URIs using its :ref:`Defined Route Routing `.. - -.. _controller-translate-uri-to-camelcase: - -Translate URI To CamelCase -========================== - -.. versionadded:: 4.5.0 - -Since v4.5.0, the ``$translateUriToCamelCase`` option has been implemented, -which works well with the current CodeIgniter's coding standards. - -This option enables you to automatically translate URI with dashes (``-``) to -CamelCase in the controller and method URI segments. - -For example, the URI ``sub-dir/hello-controller/some-method`` will execute the -``SubDir\HelloController::getSomeMethod()`` method. - -.. note:: When this option is enabled, the ``$translateURIDashes`` option is - ignored. - -Enable Translate URI To CamelCase ---------------------------------- - -To enable it, you need to change the setting ``$translateUriToCamelCase`` option -to ``true`` in **app/Config/Routing.php**:: - - public bool $translateUriToCamelCase = true; - +See :doc:`auto_routing_improved`. .. _controller-auto-routing-legacy: From 7ce54844646beef6d6bf7c7a0e95e4e3f8c08aa8 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 14:15:49 +0900 Subject: [PATCH 05/27] docs: fix section title marks --- .../source/incoming/auto_routing_improved.rst | 54 +++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index c95aff1b308d..cf82ab5f87bc 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -27,8 +27,9 @@ and execute the corresponding controller methods. .. _enabled-auto-routing-improved: +******************* Enable Auto Routing -=================== +******************* To use it, you need to change the setting ``$autoRoute`` option to ``true`` in **app/Config/Routing.php**:: @@ -38,8 +39,9 @@ And you need to change the property ``$autoRoutesImproved`` to ``true`` in **app public bool $autoRoutesImproved = true; +************ URI Segments -============ +************ The segments in the URL, in following with the Model-View-Controller approach, usually represent:: @@ -71,8 +73,9 @@ In the above example, CodeIgniter would attempt to find a controller named ``App .. note:: When a controller's short name matches the first segment of a URI, it will be loaded. +************************** Let's try it: Hello World! -========================== +************************** Let's create a simple controller so you can see it in action. Using your text editor, create a file called **Helloworld.php**, and put the following code in it. You will notice that the ``Helloworld`` Controller is extending the ``BaseController``. you can @@ -131,11 +134,12 @@ class so that it can inherit all its methods. .. literalinclude:: controllers/012.php +******* Methods -======= +******* Method Visibility ------------------ +================= When you define a method that is executable via HTTP request, the method must be declared as ``public``. @@ -143,13 +147,13 @@ declared as ``public``. .. warning:: For security reasons be sure to declare any new utility methods as ``protected`` or ``private``. Default Method --------------- +============== In the above example, the method name is ``getIndex()``. The method (HTTP verb + ``Index()``) is called the **default method**, and is loaded if the **second segment** of the URI is empty. Normal Methods --------------- +============== The second segment of the URI determines which method in the controller gets called. @@ -164,8 +168,9 @@ Now load the following URL to see the ``getComment()`` method:: You should see your new message. +************************************ Passing URI Segments to Your Methods -==================================== +************************************ If your URI contains more than two segments they will be passed to your method as parameters. @@ -178,15 +183,16 @@ Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): .. literalinclude:: controllers/022.php +****************** Default Controller -================== +****************** The Default Controller is a special controller that is used when a URI ends with a directory name or when a URI is not present, as will be the case when only your site root URL is requested. Defining a Default Controller ------------------------------ +============================= Let's try it with the ``Helloworld`` controller. @@ -215,8 +221,9 @@ For more information, please refer to the .. _controller-default-method-fallback: +*********************** Default Method Fallback -======================= +*********************** .. versionadded:: 4.4.0 @@ -237,7 +244,7 @@ The method will be passed URI segments 2 and 3 (``'15'`` and ``'edit'``): Not Found. Fallback to Default Controller ------------------------------- +============================== If the controller corresponding to the URI segment of the controller name does not exist, and if the default controller (``Home`` by default) exists in @@ -264,8 +271,9 @@ So the default method will be passed URI segments 2 (``'101'``): Auto Routing (Improved) does not execute the method, and it results in 404 Not Found. +************************************************ Organizing Your Controllers into Sub-directories -================================================ +************************************************ If you are building a large application you might want to hierarchically organize or structure your controllers into sub-directories. CodeIgniter @@ -303,8 +311,9 @@ CodeIgniter also permits you to map your URIs using its :ref:`Defined Route Rout .. _controller-translate-uri-to-camelcase: +************************** Translate URI To CamelCase -========================== +************************** .. versionadded:: 4.5.0 @@ -321,7 +330,7 @@ For example, the URI ``sub-dir/hello-controller/some-method`` will execute the ignored. Enable Translate URI To CamelCase ---------------------------------- +================================= To enable it, you need to change the setting ``$translateUriToCamelCase`` option to ``true`` in **app/Config/Routing.php**:: @@ -330,16 +339,17 @@ to ``true`` in **app/Config/Routing.php**:: .. _routing-auto-routing-improved-configuration-options: +********************* Configuration Options -===================== +********************* These options are available in the **app/Config/Routing.php** file. Default Controller ------------------- +================== For Site Root URI -^^^^^^^^^^^^^^^^^ +----------------- When a user visits the root of your site (i.e., **example.com**) the controller to use is determined by the value set to the ``$defaultController`` property, @@ -351,7 +361,7 @@ The default value for this is ``Home`` which matches the controller at public string $defaultController = 'Home'; For Directory URI -^^^^^^^^^^^^^^^^^ +----------------- The default controller is also used when no matching route has been found, and the URI would point to a directory in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at @@ -365,7 +375,7 @@ See :ref:`Auto Routing in Controllers ` for mo .. _routing-auto-routing-improved-default-method: Default Method --------------- +============== This works similar to the default controller setting, but is used to determine the default method that is used when a controller is found that matches the URI, but no segment exists for the method. The default value is @@ -381,9 +391,9 @@ controller existed, the ``Products::getListAll()`` method would be executed:: .. _auto-routing-improved-module-routing: - +************** Module Routing -============== +************** .. versionadded:: 4.4.0 From 51607f89a8ca3ba19c3eb2a932cb219dd6ce61a0 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 14:42:24 +0900 Subject: [PATCH 06/27] docs: add section title "What is Auto Routing (Improved) ?" and rewrite --- .../source/incoming/auto_routing_improved.rst | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index cf82ab5f87bc..607752805df0 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -10,18 +10,23 @@ Auto Routing (Improved) .. _auto-routing-improved: -Since v4.2.0, the new more secure Auto Routing has been introduced. +********************************* +What is Auto Routing (Improved) ? +********************************* -.. note:: If you are familiar with Auto Routing, which was enabled by default - from CodeIgniter 3.x through 4.1.x, you can see the differences in - :ref:`ChangeLog v4.2.0 `. +By default, all routes must be :ref:`defined ` in the +configuration file. -When no defined route is found that matches the URI, the system will attempt to match that URI against the controllers and methods when Auto Routing is enabled. +However, with **Auto Routing (Improved)**, you can define the controller name and +its method name according to the convention and it will be automatically routed. +In other words, there is no need to define routes manually. -.. important:: For security reasons, if a controller is used in the defined routes, Auto Routing (Improved) does not route to the controller. +If you enable Auto Routing (Improved), when no defined route is found that matches +the URI, the system will attempt to match that URI against the controllers and +methods. -Auto Routing can automatically route HTTP requests based on conventions -and execute the corresponding controller methods. +.. important:: For security reasons, if a controller is used in the defined routes, + Auto Routing (Improved) does not route to the controller. .. note:: Auto Routing (Improved) is disabled by default. To use it, see below. From 38d8f7261843784ad7b0b52736648267bebdc66e Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 14:43:03 +0900 Subject: [PATCH 07/27] docs: add sectioin "Differences from Auto Routing (Legacy)" --- .../source/incoming/auto_routing_improved.rst | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 607752805df0..8cf855c46f92 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -30,6 +30,31 @@ methods. .. note:: Auto Routing (Improved) is disabled by default. To use it, see below. +************************************** +Differences from Auto Routing (Legacy) +************************************** + +:ref:`auto-routing-legacy` is a routing system from CodeIgniter 3. If you are not +familiar with it, go to the next section. + +If you know it well, these are some changes in **Auto Routing (Improved)**: + +- A controller method needs HTTP verb prefix like ``getIndex()``, ``postCreate()``. + - Developers always know the HTTP method, so requests by an unexpected HTTP + method does not pass. +- The Default Controller (``Home`` by default) and the Default Method (``index`` by default) must be omitted in the URI. + - It restricts one-to-one correspondence between controller methods and URIs. + - E.g. by default, you can access ``/``, but ``/home`` and ``/home/index`` + will be 404. +- It checks method parameter count. + - If there are more parameters in the URI than the method parameters, it results + in 404. +- It does not support ``_remap()`` method. + - It restricts one-to-one correspondence between controller methods and URIs. +- Can't access controllers in Defined Routes. + - It completely separates controllers accessible via **Auto Routing** from + those accessible via **Defined Routes**. + .. _enabled-auto-routing-improved: ******************* From 27b420c77a36bf44b7f3388f41baa75409dea16c Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 14:43:17 +0900 Subject: [PATCH 08/27] docs: change section title --- user_guide_src/source/incoming/auto_routing_improved.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 8cf855c46f92..bcc533c62301 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -57,9 +57,9 @@ If you know it well, these are some changes in **Auto Routing (Improved)**: .. _enabled-auto-routing-improved: -******************* -Enable Auto Routing -******************* +****************************** +Enable Auto Routing (Improved) +****************************** To use it, you need to change the setting ``$autoRoute`` option to ``true`` in **app/Config/Routing.php**:: From 2e3bf1d2d5e62215a9c84913ea5cbcceb605f547 Mon Sep 17 00:00:00 2001 From: kenjis Date: Fri, 21 Jun 2024 15:53:34 +0900 Subject: [PATCH 09/27] docs: rewrite "Auto Routing (Improved)" contents --- .../source/incoming/auto_routing_improved.rst | 254 ++++++++---------- .../incoming/auto_routing_improved/009.php | 8 + .../incoming/auto_routing_improved/010.php | 8 + .../incoming/auto_routing_improved/011.php | 8 + .../020.php | 2 +- .../021.php | 2 +- .../022.php | 4 +- .../source/incoming/controllers.rst | 4 +- user_guide_src/source/incoming/routing.rst | 4 +- 9 files changed, 148 insertions(+), 146 deletions(-) create mode 100644 user_guide_src/source/incoming/auto_routing_improved/009.php create mode 100644 user_guide_src/source/incoming/auto_routing_improved/010.php create mode 100644 user_guide_src/source/incoming/auto_routing_improved/011.php rename user_guide_src/source/incoming/{controllers => auto_routing_improved}/020.php (73%) rename user_guide_src/source/incoming/{controllers => auto_routing_improved}/021.php (82%) rename user_guide_src/source/incoming/{controllers => auto_routing_improved}/022.php (54%) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index bcc533c62301..1fc15a8c5a73 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -1,3 +1,5 @@ +.. _auto-routing-improved: + ####################### Auto Routing (Improved) ####################### @@ -8,8 +10,6 @@ Auto Routing (Improved) :local: :depth: 3 -.. _auto-routing-improved: - ********************************* What is Auto Routing (Improved) ? ********************************* @@ -28,7 +28,8 @@ methods. .. important:: For security reasons, if a controller is used in the defined routes, Auto Routing (Improved) does not route to the controller. -.. note:: Auto Routing (Improved) is disabled by default. To use it, see below. +.. note:: Auto Routing (Improved) is disabled by default. To use it, see + :ref:`enabled-auto-routing-improved`. ************************************** Differences from Auto Routing (Legacy) @@ -51,6 +52,7 @@ If you know it well, these are some changes in **Auto Routing (Improved)**: in 404. - It does not support ``_remap()`` method. - It restricts one-to-one correspondence between controller methods and URIs. + But it has :ref:`controller-default-method-fallback`. - Can't access controllers in Defined Routes. - It completely separates controllers accessible via **Auto Routing** from those accessible via **Defined Routes**. @@ -61,11 +63,13 @@ If you know it well, these are some changes in **Auto Routing (Improved)**: Enable Auto Routing (Improved) ****************************** -To use it, you need to change the setting ``$autoRoute`` option to ``true`` in **app/Config/Routing.php**:: +To use it, you need to change the setting ``$autoRoute`` option to ``true`` in +**app/Config/Routing.php**:: public bool $autoRoute = true; -And you need to change the property ``$autoRoutesImproved`` to ``true`` in **app/Config/Feature.php**:: +And you need to change the property ``$autoRoutesImproved`` to ``true`` in +**app/Config/Feature.php**:: public bool $autoRoutesImproved = true; @@ -73,9 +77,10 @@ And you need to change the property ``$autoRoutesImproved`` to ``true`` in **app URI Segments ************ -The segments in the URL, in following with the Model-View-Controller approach, usually represent:: +The segments in the URL, in following with the Model-View-Controller approach, +usually represent:: - example.com/class/method/ID + http://example.com/class/method/ID 1. The first segment represents the controller **class** that should be invoked. 2. The second segment represents the class **method** that should be called. @@ -83,52 +88,55 @@ The segments in the URL, in following with the Model-View-Controller approach, u Consider this URI:: - example.com/index.php/helloworld/hello/1 + http://example.com/index.php/hello-world/hello/1 In the above example, when you send an HTTP request with **GET** method, -Auto Routing would attempt to find a controller named ``App\Controllers\Helloworld`` -and executes ``getHello()`` method with passing ``'1'`` as the first argument. - -.. note:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. +Auto Routing (Improved) would attempt to find a controller named +``App\Controllers\HelloWorld`` and executes ``getHello()`` method with passing +``'1'`` as the first argument. -This section describes the functionality of the new auto-routing. -It automatically routes an HTTP request, and executes the corresponding controller method -without route definitions. +.. note:: A controller method that will be executed by Auto Routing (Improved) + needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, + ``postCreate()``. -Consider this URI:: - - example.com/index.php/helloworld/ - -In the above example, CodeIgniter would attempt to find a controller named ``App\Controllers\Helloworld`` and load it, when auto-routing is enabled. - -.. note:: When a controller's short name matches the first segment of a URI, it will be loaded. +.. note:: When a controller's short name matches the first segment of a URI, it + will be loaded. ************************** Let's try it: Hello World! ************************** -Let's create a simple controller so you can see it in action. Using your text editor, create a file called **Helloworld.php**, -and put the following code in it. You will notice that the ``Helloworld`` Controller is extending the ``BaseController``. you can -also extend the ``CodeIgniter\Controller`` if you do not need the functionality of the BaseController. +Let's create a simple controller so you can see it in action. -The BaseController provides a convenient place for loading components and performing functions that are needed by all your -controllers. You can extend this class in any new controller. +Using your text editor, create a file called **HelloWorld.php** in your +**app/Controllers** directory, and put the following code in it. -.. literalinclude:: controllers/020.php +.. literalinclude:: auto_routing_improved/020.php -Then save the file to your **app/Controllers** directory. +You will notice that the ``HelloWorld`` Controller is extending the ``BaseController``. +you can also extend the ``CodeIgniter\Controller`` if you do not need the functionality +of the BaseController. -.. important:: The file must be called **Helloworld.php**, with a capital ``H``. When you use Auto Routing, Controller class names MUST start with an uppercase letter and ONLY the first character can be uppercase. +The BaseController provides a convenient place for loading components and performing +functions that are needed by all your controllers. You can extend this class in +any new controller. - Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, you can - use CamelCase classnames. See :ref:`controller-translate-uri-to-camelcase` - for details. +.. important:: The file must be called **HelloWorld.php**. When you use Auto + Routing (Improved), controller class names MUST be CamelCase. -.. important:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. +.. important:: A controller method that will be executed by Auto Routing (Improved) + needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, + ``postCreate()``. Now visit your site using a URL similar to this:: - example.com/index.php/helloworld + http://example.com/index.php/hello-world + +The system automatically translates URI with dashes (``-``) to CamelCase in the +controller and method URI segments. + +For example, the URI ``sub-dir/hello-controller/some-method`` will execute the +``SubDir\HelloController::getSomeMethod()`` method. If you did it right you should see:: @@ -136,34 +144,19 @@ If you did it right you should see:: This is valid: -.. literalinclude:: controllers/009.php +.. literalinclude:: auto_routing_improved/009.php This is **not** valid: -.. literalinclude:: controllers/010.php +.. literalinclude:: auto_routing_improved/010.php This is **not** valid: -.. literalinclude:: controllers/011.php - -.. note:: Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, - you can use CamelCase classnames like above. See - :ref:`controller-translate-uri-to-camelcase` for details. +.. literalinclude:: auto_routing_improved/011.php Also, always make sure your controller extends the parent controller class so that it can inherit all its methods. -.. note:: - The system will attempt to match the URI against Controllers by matching each segment against - directories/files in **app/Controllers**, when a match wasn't found against defined routes. - That's why your directories/files MUST start with a capital letter and the rest MUST be lowercase. - - If you want another naming convention you need to manually define it using the - :ref:`Defined Route Routing `. - Here is an example based on PSR-4 Autoloader: - - .. literalinclude:: controllers/012.php - ******* Methods ******* @@ -174,27 +167,28 @@ Method Visibility When you define a method that is executable via HTTP request, the method must be declared as ``public``. -.. warning:: For security reasons be sure to declare any new utility methods as ``protected`` or ``private``. +.. warning:: For security reasons be sure to declare any new utility methods as + ``protected`` or ``private``. Default Method ============== -In the above example, the method name is ``getIndex()``. -The method (HTTP verb + ``Index()``) is called the **default method**, and is loaded if the **second segment** of the URI is empty. +In the above example, the method name is ``getIndex()``. The method +(HTTP verb + ``Index()``) is called the **Default Method**, and is loaded if the +**second segment** of the URI is empty. Normal Methods ============== -The second segment of the URI determines which method in the -controller gets called. +The second segment of the URI determines which method in the controller gets called. Let's try it. Add a new method to your controller: -.. literalinclude:: controllers/021.php +.. literalinclude:: auto_routing_improved/021.php Now load the following URL to see the ``getComment()`` method:: - example.com/index.php/helloworld/comment/ + http://example.com/index.php/hello-world/comment/ You should see your new message. @@ -207,47 +201,24 @@ method as parameters. For example, let's say you have a URI like this:: - example.com/index.php/products/shoes/sandals/123 + http://example.com/index.php/products/shoes/sandals/123 Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): -.. literalinclude:: controllers/022.php +.. literalinclude:: auto_routing_improved/022.php ****************** Default Controller ****************** -The Default Controller is a special controller that is used when a URI ends with -a directory name or when a URI is not present, as will be the case when only your -site root URL is requested. - -Defining a Default Controller -============================= - -Let's try it with the ``Helloworld`` controller. +The **Default Controller** is a special controller that is used when a URI ends +with a directory name or when a URI is not present, as will be the case when only +your site root URL is requested. -To specify a default controller open your **app/Config/Routing.php** -file and set this property:: - - public string $defaultController = 'Helloworld'; - -Where ``Helloworld`` is the name of the controller class you want to be used. - -And comment out the line in **app/Config/Routes.php**: - -.. literalinclude:: controllers/016.php - :lines: 2- - -If you now browse to your site without specifying any URI segments you'll -see the "Hello World" message. - -.. important:: When you use Auto Routing (Improved), you must remove the line - ``$routes->get('/', 'Home::index');``. Because defined routes take - precedence over Auto Routing, and controllers defined in the defined routes - are denied access by Auto Routing (Improved) for security reasons. +By default, the Default Controller is ``Home``. For more information, please refer to the -:ref:`routing-auto-routing-improved-configuration-options` documentation. +:ref:`routing-auto-routing-improved-configuration-options`. .. _controller-default-method-fallback: @@ -265,7 +236,7 @@ are passed to the default method for execution. Load the following URL:: - example.com/index.php/product/15/edit + http://example.com/index.php/product/15/edit The method will be passed URI segments 2 and 3 (``'15'`` and ``'edit'``): @@ -288,10 +259,10 @@ For example, when you have the following default controller ``Home`` in the Load the following URL:: - example.com/index.php/news/101 + http://example.com/index.php/news/101 The ``News\Home`` controller and the default ``getIndex()`` method will be found. -So the default method will be passed URI segments 2 (``'101'``): +So the default method will get the second URI segment (``'101'``): .. note:: If there is ``App\Controllers\News`` controller, it takes precedence. The URI segments are searched sequentially and the first controller found @@ -312,11 +283,7 @@ permits you to do this. Simply create sub-directories under the main **app/Controllers**, and place your controller classes within them. -.. important:: Directory names MUST start with an uppercase letter and ONLY the first character can be uppercase. - - Since v4.5.0, if you enable the ``$translateUriToCamelCase`` option, you can - use CamelCase directory names. See :ref:`controller-translate-uri-to-camelcase` - for details. +.. important:: Directory names MUST start with an uppercase letter and be CamelCase. When using this feature the first segment of your URI must specify the directory. For example, let's say you have a controller located here:: @@ -325,7 +292,7 @@ specify the directory. For example, let's say you have a controller located here To call the above controller your URI will look something like this:: - example.com/index.php/products/shoes/show/123 + http://example.com/index.php/products/shoes/show/123 .. note:: You cannot have directories with the same name in **app/Controllers** and **public**. @@ -337,36 +304,6 @@ called if the URL contains *only* the sub-directory. Simply put a controller in there that matches the name of your default controller as specified in your **app/Config/Routing.php** file. -CodeIgniter also permits you to map your URIs using its :ref:`Defined Route Routing `.. - -.. _controller-translate-uri-to-camelcase: - -************************** -Translate URI To CamelCase -************************** - -.. versionadded:: 4.5.0 - -Since v4.5.0, the ``$translateUriToCamelCase`` option has been implemented, -which works well with the current CodeIgniter's coding standards. - -This option enables you to automatically translate URI with dashes (``-``) to -CamelCase in the controller and method URI segments. - -For example, the URI ``sub-dir/hello-controller/some-method`` will execute the -``SubDir\HelloController::getSomeMethod()`` method. - -.. note:: When this option is enabled, the ``$translateURIDashes`` option is - ignored. - -Enable Translate URI To CamelCase -================================= - -To enable it, you need to change the setting ``$translateUriToCamelCase`` option -to ``true`` in **app/Config/Routing.php**:: - - public bool $translateUriToCamelCase = true; - .. _routing-auto-routing-improved-configuration-options: ********************* @@ -390,34 +327,71 @@ The default value for this is ``Home`` which matches the controller at public string $defaultController = 'Home'; +.. important:: If you change the default controller name, you must remove the + line ``$routes->get('/', 'Home::index');`` in **app/Config/Routes.php**. + Because defined routes take precedence over Auto Routing, and controllers + defined in the defined routes are denied access by Auto Routing (Improved) + for security reasons. + For Directory URI ----------------- -The default controller is also used when no matching route has been found, and the URI would point to a directory -in the controllers directory. For example, if the user visits **example.com/admin**, if a controller was found at +The default controller is also used when no matching route has been found, and +the URI would point to a directory in the controllers directory. For example, if +the user visits **example.com/admin**, if a controller was found at **app/Controllers/Admin/Home.php**, it would be used. -.. important:: You cannot access the default controller with the URI of the controller name. - When the default controller is ``Home``, you can access **example.com/**, but if you access **example.com/home**, it will be not found. - -See :ref:`Auto Routing in Controllers ` for more info. +.. important:: You cannot access the default controller with the URI of the + controller name. When the default controller is ``Home``, you can access + **example.com/**, but if you access **example.com/home**, it will be not found. .. _routing-auto-routing-improved-default-method: Default Method ============== -This works similar to the default controller setting, but is used to determine the default method that is used -when a controller is found that matches the URI, but no segment exists for the method. The default value is -``index``. +This works similar to the default controller setting, but is used to determine +the default method that is used when a controller is found that matches the URI, +but no segment exists for the method. The default value is ``index``. In this example, if the user were to visit **example.com/products**, and a ``Products`` controller existed, the ``Products::getListAll()`` method would be executed:: public string $defaultMethod = 'listAll'; -.. important:: You cannot access the controller with the URI of the default method name. - In the example above, you can access **example.com/products**, but if you access **example.com/products/listall**, it will be not found. +.. important:: You cannot access the controller with the URI of the default method + name. In the example above, you can access **example.com/products**, but if + you access **example.com/products/listall**, it will be not found. + +.. _controller-translate-uri-to-camelcase: + +Translate URI To CamelCase +========================== + +.. versionadded:: 4.5.0 + +.. note:: Since v4.6.0, the ``$translateUriToCamelCase`` option is enabled by + default. + +Since v4.5.0, the ``$translateUriToCamelCase`` option has been implemented, +which works well with the current CodeIgniter's coding standards. + +This option enables you to automatically translate URI with dashes (``-``) to +CamelCase in the controller and method URI segments. + +For example, the URI ``sub-dir/hello-controller/some-method`` will execute the +``SubDir\HelloController::getSomeMethod()`` method. + +.. note:: When this option is enabled, the ``$translateURIDashes`` option is + ignored. + +Disable Translate URI To CamelCase +---------------------------------- + +To disable it, you need to change the setting ``$translateUriToCamelCase`` option +to ``false`` in **app/Config/Routing.php**:: + + public bool $translateUriToCamelCase = false; .. _auto-routing-improved-module-routing: diff --git a/user_guide_src/source/incoming/auto_routing_improved/009.php b/user_guide_src/source/incoming/auto_routing_improved/009.php new file mode 100644 index 000000000000..7615eecaeba0 --- /dev/null +++ b/user_guide_src/source/incoming/auto_routing_improved/009.php @@ -0,0 +1,8 @@ + Date: Fri, 21 Jun 2024 16:32:01 +0900 Subject: [PATCH 10/27] test: update test code for config changes --- tests/system/Test/FeatureTestTraitTest.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/system/Test/FeatureTestTraitTest.php b/tests/system/Test/FeatureTestTraitTest.php index 4fd921d6e9a6..b3ee3eadb4cc 100644 --- a/tests/system/Test/FeatureTestTraitTest.php +++ b/tests/system/Test/FeatureTestTraitTest.php @@ -20,6 +20,7 @@ use CodeIgniter\HTTP\Response; use CodeIgniter\Test\Mock\MockCodeIgniter; use Config\App; +use Config\Feature; use Config\Routing; use Config\Services; use PHPUnit\Framework\Attributes\DataProvider; @@ -359,17 +360,19 @@ public static function provideOpenCliRoutesFromHttpGot404(): iterable ]; } - /** - * @param mixed $from - * @param mixed $to - * @param mixed $httpGet - */ + private function disableAutoRoutesImproved(): void + { + $featureConfig = config(Feature::class); + $featureConfig->autoRoutesImproved = false; + } + #[DataProvider('provideOpenCliRoutesFromHttpGot404')] - public function testOpenCliRoutesFromHttpGot404($from, $to, $httpGet): void + public function testOpenCliRoutesFromHttpGot404(string $from, string $to, string $httpGet): void { $this->expectException(PageNotFoundException::class); $this->expectExceptionMessage('Cannot access CLI Route: '); + $this->disableAutoRoutesImproved(); $collection = Services::routes(); $collection->setAutoRoute(true); $collection->setDefaultNamespace('Tests\Support\Controllers'); @@ -641,6 +644,7 @@ public function testSetupRequestBodyWithBody(): void public function testAutoRoutingLegacy(): void { + $this->disableAutoRoutesImproved(); $config = config(Routing::class); $config->autoRoute = true; Factories::injectMock('config', Routing::class, $config); From dd33f98a32dfc9b31aa0d88c60016e5a21c687ef Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 23 Jun 2024 20:30:53 +0900 Subject: [PATCH 11/27] docs: add note --- user_guide_src/source/incoming/auto_routing_improved.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 1fc15a8c5a73..95e65e387def 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -388,6 +388,9 @@ For example, the URI ``sub-dir/hello-controller/some-method`` will execute the Disable Translate URI To CamelCase ---------------------------------- +.. note:: The option to disable "Translate URI To CamelCase" exists only for + backward compatibility. We don't recommend to disable it. + To disable it, you need to change the setting ``$translateUriToCamelCase`` option to ``false`` in **app/Config/Routing.php**:: From 580a59b7e0bd3165d200b445d24d2e6121ec376a Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 23 Jun 2024 20:31:05 +0900 Subject: [PATCH 12/27] docs: add "Examples of Controller/Methods and URIs" --- .../source/incoming/auto_routing_improved.rst | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 95e65e387def..8043995e0f67 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -304,6 +304,32 @@ called if the URL contains *only* the sub-directory. Simply put a controller in there that matches the name of your default controller as specified in your **app/Config/Routing.php** file. +*************************************** +Examples of Controller/Methods and URIs +*************************************** + +In the case of a **GET** request with the default configuration, the mapping +between controller/methods and URIs is as follows: + +============================ ============================ ============================================= +Controller/Method URI Description +============================ ============================ ============================================= +``Home::getIndex()`` / The default controller and the default method. +``Blog::getIndex()`` /blog The default method. +``UserProfile::getIndex()`` /user-profile The default method. +``Blog::getTags()`` /blog/tags +``Blog::getNews($id)`` /blog/news/123 +``Blog\Home::getIndex()`` /blog Sub-directory ``Blog`` and the default + controller and the default method. If there + is ``Blog`` controller, it takes precedence. +``Blog\Tags::getIndex()`` /blog/tags Sub-directory ``Blog`` and the default + method. If there is ``Blog`` controller, it + takes precedence. +``Blog\News::getIndex($id)`` /blog/news/123 Sub-directory ``Blog`` and the default method + fallback. If there is ``Blog`` controller, it + takes precedence. +============================ ============================ ============================================= + .. _routing-auto-routing-improved-configuration-options: ********************* From fd00dfab7825091d0630aeb2bb7513757ebe07dd Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 23 Jun 2024 21:40:47 +0900 Subject: [PATCH 13/27] docs: update :ref: ids --- user_guide_src/source/changelogs/v4.4.0.rst | 2 +- user_guide_src/source/changelogs/v4.5.0.rst | 2 +- user_guide_src/source/incoming/auto_routing_improved.rst | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/user_guide_src/source/changelogs/v4.4.0.rst b/user_guide_src/source/changelogs/v4.4.0.rst index 59092ccd9860..df0b712f3f35 100644 --- a/user_guide_src/source/changelogs/v4.4.0.rst +++ b/user_guide_src/source/changelogs/v4.4.0.rst @@ -261,7 +261,7 @@ Others - If a controller is found that corresponds to a URI segment and that controller does not have a method defined for the URI segment, the default method will now be executed. This addition allows for more flexible handling of URIs in - auto routing. See :ref:`controller-default-method-fallback` for details. + auto routing. See :ref:`auto-routing-improved-default-method-fallback` for details. - **Filters:** Now you can use Filter Arguments with :ref:`$filters property `. - **Request:** Added ``IncomingRequest::setValidLocales()`` method to set valid locales. - **Table:** Added ``Table::setSyncRowsWithHeading()`` method to synchronize row columns with headings. See :ref:`table-sync-rows-with-headings` for details. diff --git a/user_guide_src/source/changelogs/v4.5.0.rst b/user_guide_src/source/changelogs/v4.5.0.rst index 1f978a4dcfc6..97cfe9ec10b0 100644 --- a/user_guide_src/source/changelogs/v4.5.0.rst +++ b/user_guide_src/source/changelogs/v4.5.0.rst @@ -62,7 +62,7 @@ Routing - **AutoRouting Improved:** The ``$translateUriToCamelCase`` option has been added that allows using CamelCase controller and method names. See - :ref:`controller-translate-uri-to-camelcase`. + :ref:`translate-uri-to-camelcase`. - **Others:** - Added option ``$multipleSegmentsOneParam``. When this option is enabled, a placeholder that matches multiple segments, such as ``(:any)``, will diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 8043995e0f67..c9ee8562cc82 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -52,7 +52,7 @@ If you know it well, these are some changes in **Auto Routing (Improved)**: in 404. - It does not support ``_remap()`` method. - It restricts one-to-one correspondence between controller methods and URIs. - But it has :ref:`controller-default-method-fallback`. + But it has :ref:`auto-routing-improved-default-method-fallback`. - Can't access controllers in Defined Routes. - It completely separates controllers accessible via **Auto Routing** from those accessible via **Defined Routes**. @@ -220,7 +220,7 @@ By default, the Default Controller is ``Home``. For more information, please refer to the :ref:`routing-auto-routing-improved-configuration-options`. -.. _controller-default-method-fallback: +.. _auto-routing-improved-default-method-fallback: *********************** Default Method Fallback @@ -389,7 +389,7 @@ controller existed, the ``Products::getListAll()`` method would be executed:: name. In the example above, you can access **example.com/products**, but if you access **example.com/products/listall**, it will be not found. -.. _controller-translate-uri-to-camelcase: +.. _translate-uri-to-camelcase: Translate URI To CamelCase ========================== From ecfbc2f7786f3a0f9e449c6757c9c854666c32ee Mon Sep 17 00:00:00 2001 From: kenjis Date: Sun, 23 Jun 2024 21:54:56 +0900 Subject: [PATCH 14/27] docs: add notes --- user_guide_src/source/incoming/auto_routing_improved.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index c9ee8562cc82..35d821c5b200 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -207,6 +207,10 @@ Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): .. literalinclude:: auto_routing_improved/022.php +.. note:: If there are more parameters in the URI than the method parameters, + Auto Routing (Improved) does not execute the method, and it results in 404 + Not Found. + ****************** Default Controller ****************** @@ -217,6 +221,10 @@ your site root URL is requested. By default, the Default Controller is ``Home``. +.. note:: Define only the default method (``getIndex()`` for GET requests) + in the default controller. If you define any other public method, that method + will not be executed. + For more information, please refer to the :ref:`routing-auto-routing-improved-configuration-options`. From 23ae69c26d7b9e809b3525241d82701724c567c9 Mon Sep 17 00:00:00 2001 From: kenjis Date: Mon, 24 Jun 2024 18:38:40 +0900 Subject: [PATCH 15/27] docs: add upgrade_460 --- user_guide_src/source/installation/upgrade_460.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/installation/upgrade_460.rst b/user_guide_src/source/installation/upgrade_460.rst index 04388acf7d08..8546df1903f2 100644 --- a/user_guide_src/source/installation/upgrade_460.rst +++ b/user_guide_src/source/installation/upgrade_460.rst @@ -91,7 +91,10 @@ and it is recommended that you merge the updated versions with your application: Config ------ -- @TODO +- app/Config/Feature.php + - ``Config\Feature::$autoRoutesImproved`` has been changed to ``true``. +- app/Config/Routing.php + - ``Config\Routing::$translateUriToCamelCase`` has been changed to ``true``. All Changes =========== From 50baeddcc8d6582d7d2dc00acd73145c0f9d2110 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 07:56:41 +0900 Subject: [PATCH 16/27] docs: change note Even if you don't change the default controller name, you must remove the defined route `$routes->get('/', 'Home::index');`. --- .../source/incoming/auto_routing_improved.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 35d821c5b200..fe5b9013420a 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -73,6 +73,12 @@ And you need to change the property ``$autoRoutesImproved`` to ``true`` in public bool $autoRoutesImproved = true; +.. important:: When you use Auto Routing (Improved), you must remove the line + ``$routes->get('/', 'Home::index');`` in **app/Config/Routes.php**. Because + defined routes take precedence over Auto Routing, and controllers defined in + the defined routes are denied access by Auto Routing (Improved) for security + reasons. + ************ URI Segments ************ @@ -361,12 +367,6 @@ The default value for this is ``Home`` which matches the controller at public string $defaultController = 'Home'; -.. important:: If you change the default controller name, you must remove the - line ``$routes->get('/', 'Home::index');`` in **app/Config/Routes.php**. - Because defined routes take precedence over Auto Routing, and controllers - defined in the defined routes are denied access by Auto Routing (Improved) - for security reasons. - For Directory URI ----------------- From c481d2e9a3036b58a2f0e404d6a65074bde4a968 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:04:34 +0900 Subject: [PATCH 17/27] docs: improved descriptions --- .../source/incoming/auto_routing_improved.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index fe5b9013420a..7056ba92402d 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -41,18 +41,19 @@ familiar with it, go to the next section. If you know it well, these are some changes in **Auto Routing (Improved)**: - A controller method needs HTTP verb prefix like ``getIndex()``, ``postCreate()``. - - Developers always know the HTTP method, so requests by an unexpected HTTP - method does not pass. + - Since developers always know the HTTP method, a request with an unexpected + HTTP method will never execute the controller. - The Default Controller (``Home`` by default) and the Default Method (``index`` by default) must be omitted in the URI. - It restricts one-to-one correspondence between controller methods and URIs. - E.g. by default, you can access ``/``, but ``/home`` and ``/home/index`` - will be 404. + will be 404 Not Found. - It checks method parameter count. - If there are more parameters in the URI than the method parameters, it results - in 404. + in 404 Not Found. - It does not support ``_remap()`` method. - It restricts one-to-one correspondence between controller methods and URIs. - But it has :ref:`auto-routing-improved-default-method-fallback`. + - But it has the :ref:`auto-routing-improved-default-method-fallback` feature + instead. - Can't access controllers in Defined Routes. - It completely separates controllers accessible via **Auto Routing** from those accessible via **Defined Routes**. From c953a68c120c0a6e309bd3f42930c7d0f4995f12 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:09:19 +0900 Subject: [PATCH 18/27] docs: remove `index.php` in sample URLs --- .../source/incoming/auto_routing_improved.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 7056ba92402d..f0232f146ce2 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -95,7 +95,7 @@ usually represent:: Consider this URI:: - http://example.com/index.php/hello-world/hello/1 + http://example.com/hello-world/hello/1 In the above example, when you send an HTTP request with **GET** method, Auto Routing (Improved) would attempt to find a controller named @@ -137,7 +137,7 @@ any new controller. Now visit your site using a URL similar to this:: - http://example.com/index.php/hello-world + http://example.com/hello-world The system automatically translates URI with dashes (``-``) to CamelCase in the controller and method URI segments. @@ -195,7 +195,7 @@ Let's try it. Add a new method to your controller: Now load the following URL to see the ``getComment()`` method:: - http://example.com/index.php/hello-world/comment/ + http://example.com/hello-world/comment/ You should see your new message. @@ -208,7 +208,7 @@ method as parameters. For example, let's say you have a URI like this:: - http://example.com/index.php/products/shoes/sandals/123 + http://example.com/products/shoes/sandals/123 Your method will be passed URI segments 3 and 4 (``'sandals'`` and ``'123'``): @@ -251,7 +251,7 @@ are passed to the default method for execution. Load the following URL:: - http://example.com/index.php/product/15/edit + http://example.com/product/15/edit The method will be passed URI segments 2 and 3 (``'15'`` and ``'edit'``): @@ -274,7 +274,7 @@ For example, when you have the following default controller ``Home`` in the Load the following URL:: - http://example.com/index.php/news/101 + http://example.com/news/101 The ``News\Home`` controller and the default ``getIndex()`` method will be found. So the default method will get the second URI segment (``'101'``): @@ -307,7 +307,7 @@ specify the directory. For example, let's say you have a controller located here To call the above controller your URI will look something like this:: - http://example.com/index.php/products/shoes/show/123 + http://example.com/products/shoes/show/123 .. note:: You cannot have directories with the same name in **app/Controllers** and **public**. From c267bc0f18156bf2c5a3bd3a8ced51ada5387944 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:12:00 +0900 Subject: [PATCH 19/27] docs: improve explanation --- user_guide_src/source/incoming/auto_routing_improved.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index f0232f146ce2..2ad1fed2ed7d 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -87,11 +87,11 @@ URI Segments The segments in the URL, in following with the Model-View-Controller approach, usually represent:: - http://example.com/class/method/ID + http://example.com/{class}/{method}/{param1} 1. The first segment represents the controller **class** that should be invoked. 2. The second segment represents the class **method** that should be called. -3. The third, and any additional segments, represent the ID and any variables that will be passed to the controller. +3. The third, and any additional segments, represent any **parameters** that will be passed to the controller. Consider this URI:: @@ -100,7 +100,7 @@ Consider this URI:: In the above example, when you send an HTTP request with **GET** method, Auto Routing (Improved) would attempt to find a controller named ``App\Controllers\HelloWorld`` and executes ``getHello()`` method with passing -``'1'`` as the first argument. +``'1'`` as the first parameter. .. note:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, From 02e645c3c8e5f315b750a0ed019a7737c2c3471a Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:26:24 +0900 Subject: [PATCH 20/27] docs: add sub section titles and explanations --- .../source/incoming/auto_routing_improved.rst | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 2ad1fed2ed7d..0726b1876783 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -115,26 +115,32 @@ Let's try it: Hello World! Let's create a simple controller so you can see it in action. +Create a Controller +=================== + Using your text editor, create a file called **HelloWorld.php** in your **app/Controllers** directory, and put the following code in it. .. literalinclude:: auto_routing_improved/020.php +.. important:: The file must be called **HelloWorld.php**. When you use Auto + Routing (Improved), controller class names MUST be CamelCase. + You will notice that the ``HelloWorld`` Controller is extending the ``BaseController``. -you can also extend the ``CodeIgniter\Controller`` if you do not need the functionality +You can also extend the ``CodeIgniter\Controller`` if you do not need the functionality of the BaseController. The BaseController provides a convenient place for loading components and performing functions that are needed by all your controllers. You can extend this class in any new controller. -.. important:: The file must be called **HelloWorld.php**. When you use Auto - Routing (Improved), controller class names MUST be CamelCase. - .. important:: A controller method that will be executed by Auto Routing (Improved) needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. +Visit Your Site +=============== + Now visit your site using a URL similar to this:: http://example.com/hello-world @@ -149,21 +155,21 @@ If you did it right you should see:: Hello World! -This is valid: +Controller Name Examples +======================== + +This is an valid controller name. Because ``App/Controllers/HelloWorld`` is CamelCase. .. literalinclude:: auto_routing_improved/009.php -This is **not** valid: +This is **not** valid. Because the first letter (``h``) is not capital. .. literalinclude:: auto_routing_improved/010.php -This is **not** valid: +This is also **not** valid. Because the first letter (``h``) is not capital. .. literalinclude:: auto_routing_improved/011.php -Also, always make sure your controller extends the parent controller -class so that it can inherit all its methods. - ******* Methods ******* From 75861b0f844c7fe97c42450dd9bc0f5d6f09638f Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:38:36 +0900 Subject: [PATCH 21/27] docs: add section "Check the Routes" --- .../source/incoming/auto_routing_improved.rst | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 0726b1876783..122178e1c15e 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -138,6 +138,27 @@ any new controller. needs HTTP verb (``get``, ``post``, ``put``, etc.) prefix like ``getIndex()``, ``postCreate()``. +Check the Routes +================ + +You can check your routes with the ``spark routes`` command. + +.. code-block:: console + + php spark routes + +If you did it right, you should see: + +.. code-block:: none + + +-----------+-------------+------+---------------------------------------+----------------+---------------+ + | Method | Route | Name | Handler | Before Filters | After Filters | + +-----------+-------------+------+---------------------------------------+----------------+---------------+ + | GET(auto) | hello-world | | \App\Controllers\HelloWorld::getIndex | | | + +-----------+-------------+------+---------------------------------------+----------------+---------------+ + +See :ref:`routing-spark-routes` for the output details. + Visit Your Site =============== @@ -151,7 +172,7 @@ controller and method URI segments. For example, the URI ``sub-dir/hello-controller/some-method`` will execute the ``SubDir\HelloController::getSomeMethod()`` method. -If you did it right you should see:: +If you did it right, you should see:: Hello World! From 939766ebd80da11c7a99ec06877f94f3962a6065 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:40:46 +0900 Subject: [PATCH 22/27] docs: add `http://` to example URLs --- user_guide_src/source/incoming/auto_routing_improved.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 122178e1c15e..617ce9519c0e 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -386,7 +386,7 @@ Default Controller For Site Root URI ----------------- -When a user visits the root of your site (i.e., **example.com**) the controller +When a user visits the root of your site (i.e., **http://example.com**) the controller to use is determined by the value set to the ``$defaultController`` property, unless a route exists for it explicitly. @@ -400,12 +400,13 @@ For Directory URI The default controller is also used when no matching route has been found, and the URI would point to a directory in the controllers directory. For example, if -the user visits **example.com/admin**, if a controller was found at +the user visits **http://example.com/admin**, if a controller was found at **app/Controllers/Admin/Home.php**, it would be used. .. important:: You cannot access the default controller with the URI of the controller name. When the default controller is ``Home``, you can access - **example.com/**, but if you access **example.com/home**, it will be not found. + **http://example.com/**, but if you access **http://example.com/home**, it + will be not found. .. _routing-auto-routing-improved-default-method: From 990e89e3c4a4b2da47517f6b8a41f7615b3ea718 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:49:00 +0900 Subject: [PATCH 23/27] docs: fix FQCN --- user_guide_src/source/incoming/auto_routing_improved.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 617ce9519c0e..e0beeffdaefe 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -179,7 +179,7 @@ If you did it right, you should see:: Controller Name Examples ======================== -This is an valid controller name. Because ``App/Controllers/HelloWorld`` is CamelCase. +This is an valid controller name. Because ``App\Controllers\HelloWorld`` is CamelCase. .. literalinclude:: auto_routing_improved/009.php From 70ebb3383396a0133e82ebac5ed6c31669d2714a Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 08:49:17 +0900 Subject: [PATCH 24/27] docs: improve section titles --- .../source/incoming/auto_routing_improved.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index e0beeffdaefe..200440624b1f 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -176,8 +176,9 @@ If you did it right, you should see:: Hello World! -Controller Name Examples -======================== +**************************** +Examples of Controller Names +**************************** This is an valid controller name. Because ``App\Controllers\HelloWorld`` is CamelCase. @@ -191,9 +192,9 @@ This is also **not** valid. Because the first letter (``h``) is not capital. .. literalinclude:: auto_routing_improved/011.php -******* -Methods -******* +****************** +Controller Methods +****************** Method Visibility ================= From 9494c40cb6626977041103cb0b409f5e71c732e2 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 10:59:27 +0900 Subject: [PATCH 25/27] docs: replace "This is" --- user_guide_src/source/incoming/auto_routing_improved.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 200440624b1f..74249b64f7a8 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -180,15 +180,16 @@ If you did it right, you should see:: Examples of Controller Names **************************** -This is an valid controller name. Because ``App\Controllers\HelloWorld`` is CamelCase. +The following is an valid controller name. Because ``App\Controllers\HelloWorld`` +is CamelCase. .. literalinclude:: auto_routing_improved/009.php -This is **not** valid. Because the first letter (``h``) is not capital. +The following is **not** valid. Because the first letter (``h``) is not capital. .. literalinclude:: auto_routing_improved/010.php -This is also **not** valid. Because the first letter (``h``) is not capital. +The following is also **not** valid. Because the first letter (``h``) is not capital. .. literalinclude:: auto_routing_improved/011.php From 0ad823c91989f5d9bf6dc333a2252e32ba5ae6e8 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 10:59:46 +0900 Subject: [PATCH 26/27] docs: fix description --- user_guide_src/source/incoming/auto_routing_improved.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 74249b64f7a8..62c1d5ea764a 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -91,7 +91,7 @@ usually represent:: 1. The first segment represents the controller **class** that should be invoked. 2. The second segment represents the class **method** that should be called. -3. The third, and any additional segments, represent any **parameters** that will be passed to the controller. +3. The third, and any additional segments, represent any **parameters** that will be passed to the controller method. Consider this URI:: From f0db26ff3d0fff42779b44389361e1c5077988a4 Mon Sep 17 00:00:00 2001 From: kenjis Date: Tue, 25 Jun 2024 14:41:11 +0900 Subject: [PATCH 27/27] docs: add section "Applying Filters" --- .../source/incoming/auto_routing_improved.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/user_guide_src/source/incoming/auto_routing_improved.rst b/user_guide_src/source/incoming/auto_routing_improved.rst index 62c1d5ea764a..1ed1cb304c6b 100644 --- a/user_guide_src/source/incoming/auto_routing_improved.rst +++ b/user_guide_src/source/incoming/auto_routing_improved.rst @@ -374,6 +374,17 @@ Controller/Method URI Description takes precedence. ============================ ============================ ============================================= +**************** +Applying Filters +**************** + +Applying controller filters allows you to add processing before and after the +controller method execution. This is especially handy during authentication or +api logging. + +If you use Auto Routing, set the filters to be applied in **app/Config/Filters.php**. +See :doc:`Controller Filters ` for more information on setting up filters. + .. _routing-auto-routing-improved-configuration-options: *********************