Repository: codeigniter4/CodeIgniter4 (PHP)

Issue:
Bug: Cant use route_to function in cli request
### PHP Version

7.4

### CodeIgniter4 Version

4.2.4

### CodeIgniter4 Installation Method

Manual (zip or tar.gz)

### Which operating systems have you tested for this bug?

Linux

### Which server did you use?

fpm-fcgi

### Database

_No response_

### What happened?

Cant use route_to function in cli request because localization is not supported in CLI.

`Locale detection only works for web-based requests that use the IncomingRequest class. Command-line requests will not have these features.`

Here's the error trace:

```
CRITICAL - 2022-08-14 09:36:22 --> Call to undefined method CodeIgniter\HTTP\CLIRequest::getLocale()
in SYSTEMPATH/Router/RouteCollection.php on line 1061.
 1 SYSTEMPATH/Router/RouteCollection.php(1004): CodeIgniter\Router\RouteCollection->localizeRoute()
 2 SYSTEMPATH/Common.php(915): CodeIgniter\Router\RouteCollection->reverseRoute()
 3 APPPATH/Helpers/common_helper.php(154): route_to()
 4 APPPATH/Controllers/Process.php(531): get_image()
 5 APPPATH/Controllers/Process.php(1099): App\Controllers\Process->save()
 6 SYSTEMPATH/CodeIgniter.php(898): App\Controllers\Process->cronTask()
 7 SYSTEMPATH/CodeIgniter.php(457): CodeIgniter\CodeIgniter->runController()
 8 SYSTEMPATH/CodeIgniter.php(340): CodeIgniter\CodeIgniter->handleRequest()
 9 FCPATH/index.php(67): CodeIgniter\CodeIgniter->run()
```

I am not using localization in my script. I am using `route_to()` to get path for the image asset so that the required image can be generated in the background. This helps to follow the DRY principle.

### Steps to Reproduce

Call a `route_to()` function in CLI request.

### Expected Output

`route_to()` should return the path that was requested.

### Anything else?

### Update with more details:

I have this function in helper it helps to return either an absolute path to an image or its url:

```php
function get_image($post, $type = 'url')
{
	$year = date('Y', strtotime($post['date_added']));
	$month = date('m', strtotime($post['date_added']));

	$path = ltrim(route_to('image', $year, $month, $post['slug']), '/');

	if ($type === 'path') {
		return FCPATH . $path;
	}

	return base_url($path);
}
```

The image route:

```php
$routes->get('images/(:num)/(:num)/(:segment).png', 'Post::image/$1/$2/$3', ['as' => 'image']);
```

The image is displayed to the front like this:

```php
<img src="<?php echo get_image($site); ?>" width="16" height="16">
```

The `Post::image()` controller function logs if any request is received so that I know that some image was not generated automatically.

In the background a cron creates the image to the path returned by `get_image()` for specific post.

So when the cron is run in cli, the `route_to()` function gives the above error. 



Discussion:
> I am using route_to() to get path for the image asset so that the required image can be generated in the background. This helps to follow the DRY principle.

I don't get what you mean. What's the relation between route_to() and image path?
Could you explain more?

I have updated the issue with more details. Do you need any thing else?
The route may contain a locale. The locale can be obtained from the HTTP request. But the CLI call cannot have an HTTP request in principle.
Therefore, such an error occurs when trying to generate an address in the CLI.
From the point of view of the HTTP request, this is not a bug.

I do not know how your application works, but I will try to advise the following:

1. The Post::image() can generate a non-existent image instead of logging the absence of an image.
Even if the operation has a high price, it is one-time.

2. If the Post::image() generates a cron task, then in it (method) you can generate a URL and pass it to the task.
Thank for the response @kenjis and @iRedds 

I understand that there are alternative ways. But I think that `route_to()` is a function that should be available on any requests.

For example, I have another use of that function in cli. I generate/update my sitemaps xml files with a cron and if the cron cant call `route_to()` function how do we create a sitemap.
The issue is how to handle the locale in CLI?

> The issue is how to handle the locale in CLI?

May be yes. The issue is that an essential function like reverse routing cant be used in CLI because `\CodeIgniter\HTTP\CLIRequest` doesn't have a `getLocale()` function.

May be `\CodeIgniter\Router\RouteCollection::localizeRoute()` should check if `Services::request()` has a method called `getLocale`

Or `\CodeIgniter\Router\RouteCollection::reverseRoute()` should check if localization is even needed before calling `localizeRoute()`

Or something like that.
> The issue is that an essential function like reverse routing cant be used in CLI because \CodeIgniter\HTTP\CLIRequest doesn't have a getLocale() function.

Then what value does the `CLIRequest::getLocale()` return?
@dobaniashish v4.2.5 is not released. Do you mean 4.2.4?

> @dobaniashish v4.2.5 is not released. Do you mean 4.2.4?

Yes 4.2.4

> > The issue is that an essential function like reverse routing cant be used in CLI because \CodeIgniter\HTTP\CLIRequest doesn't have a getLocale() function.
> 
> Then what value does the `CLIRequest::getLocale()` return?

```
Call to undefined method CodeIgniter\HTTP\CLIRequest::getLocale()

at SYSTEMPATH\Router\RouteCollection.php:1061

Backtrace:
  1    SYSTEMPATH\Router\RouteCollection.php:1004
       CodeIgniter\Router\RouteCollection()->localizeRoute()

  2    SYSTEMPATH\Common.php:915
       CodeIgniter\Router\RouteCollection()->reverseRoute()

  3    APPPATH\Views\home.php:56
       route_to()

  4    SYSTEMPATH\View\View.php:213
       include('D:\\Server\\htdocs\\localhost.com\\private\\application\\app\\Views\\home.php')

  5    SYSTEMPATH\View\View.php:216
       CodeIgniter\View\View()->CodeIgniter\View\{closure}()

  6    SYSTEMPATH\Common.php:1137
       CodeIgniter\View\View()->render()

  7    APPPATH\Controllers\Home.php:77
       view()

  8    SYSTEMPATH\CodeIgniter.php:898
       App\Controllers\Home()->index()

  9    SYSTEMPATH\CodeIgniter.php:457
       CodeIgniter\CodeIgniter()->runController()

 10    SYSTEMPATH\CodeIgniter.php:340
       CodeIgniter\CodeIgniter()->handleRequest()

 11    FCPATH\index.php:67
       CodeIgniter\CodeIgniter()->run()
```

Sorry, I mean, what value shuld the CLIRequest::getLocale() return?
Technically nothing. CLIRequest should not have a getLocale function. Instead route_to should have a parameter to provide locale as said here by @iRedds https://github.com/codeigniter4/CodeIgniter4/pull/6379#issuecomment-1214885981

And if the locale parameter is not passed or is null, default can be used from `\Config\App::$defaultLocale`
@dobaniashish Thank you for your opinion.



Patch:
diff --git a/system/HTTP/CLIRequest.php b/system/HTTP/CLIRequest.php
index 0b6c2b83a12d..e81ae9cabbd9 100644
--- a/system/HTTP/CLIRequest.php
+++ b/system/HTTP/CLIRequest.php
@@ -12,6 +12,7 @@
 namespace CodeIgniter\HTTP;
 
 use Config\App;
+use Locale;
 use RuntimeException;
 
 /**
@@ -280,4 +281,13 @@ private function returnNullOrEmptyArray($index)
     {
         return ($index === null || is_array($index)) ? [] : null;
     }
+
+    /**
+     * Gets the current locale, with a fallback to the default
+     * locale if none is set.
+     */
+    public function getLocale(): string
+    {
+        return Locale::getDefault();
+    }
 }


Test patch:
diff --git a/tests/system/HTTP/CLIRequestTest.php b/tests/system/HTTP/CLIRequestTest.php
index e8e57dbc611b..b294d1621b2b 100644
--- a/tests/system/HTTP/CLIRequestTest.php
+++ b/tests/system/HTTP/CLIRequestTest.php
@@ -599,16 +599,21 @@ public function testGetGet()
 
     public function testGetPost()
     {
-        $this->assertSame([], $this->request->getGet());
+        $this->assertSame([], $this->request->getPost());
     }
 
     public function testGetPostGet()
     {
-        $this->assertSame([], $this->request->getGet());
+        $this->assertSame([], $this->request->getPostGet());
     }
 
     public function testGetGetPost()
     {
-        $this->assertSame([], $this->request->getGet());
+        $this->assertSame([], $this->request->getGetPost());
+    }
+
+    public function testGetLocale()
+    {
+        $this->assertSame('en', $this->request->getLocale());
     }
 }