Routing using a Controller - concrete5 Route Example - c5-8.5.2
Permalink
I have attempted to get the Developer Documentation example for Routing using a Controller to work but I am stuck. I just get the error message: "The requested URL was not found on this server. Additionally, a 404 Not Found error was encountered..."
Per the example the URL I use is: https://www.mysite.com/api/current_user... (mysite.com is changed to my real domain)
The examples I followed are found on the following two Developers Document pages:
https://documentation.concrete5.org/developers/routing/controllers...
https://documentation.concrete5.org/developers/extending-concrete5-w...
Here is my code:
/application/bootstrap/app.php (code is appended to the end of app.php)
/application/bootstrap/autoload.php (code is appended to the end of autoload.php)
application/src/Api/Controller/User.php
Per the example the URL I use is: https://www.mysite.com/api/current_user... (mysite.com is changed to my real domain)
The examples I followed are found on the following two Developers Document pages:
https://documentation.concrete5.org/developers/routing/controllers...
https://documentation.concrete5.org/developers/extending-concrete5-w...
Here is my code:
/application/bootstrap/app.php (code is appended to the end of app.php)
$app = app(); // in c5-8.5.2+ app() is a Global function $router = $app->make('router'); $router->get('/api/current_user', 'Application\Api\Controller\UserController::getCurrentUser');
/application/bootstrap/autoload.php (code is appended to the end of autoload.php)
$classLoader = new \Symfony\Component\ClassLoader\Psr4ClassLoader(); $classLoader->addPrefix('Application\\Api\\Controller', DIR_APPLICATION . '/' . DIRNAME_CLASSES . '/Api/Controller'); $classLoader->register();
application/src/Api/Controller/User.php
<?php namespace Application\Api\Controller; use Concrete\Core\User\User; use Symfony\HttpFoundation\JsonResponse; class UserController { public function getCurrentUser() { $u = new User(); if ($u->isRegistered()) { $data = []; $data['user_id'] = $u->getUserID(); $data['username'] = $u->getUserName(); return new JsonResponse($data); } else {
Viewing 15 lines of 20 lines. View entire code block.
shahroq,
Thank you for helping me with this issue. I would really like to master this Routing coding…
In all cases I am logged in as SuperUser (admin).
First, I appended your example code:
to the end of \application\bootstrap\autoload.php [ Is appending the code to the end of this file the correct place to put this code? ]
Then I placed your example code:
in \application\src\Api\ApiUsers.php [ I can't figure out how a URL even finds this code ]
Finally I appended your example code:
to the end of /application/bootstrap/app.php [ Is this where this code should go? ]
I clicked on this link: http://mysite.com/testapi1 which took me to a blank page which returned:
“Not Found
The requested URL was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.”
I tried various combinations like removing the \application\src\Api\ApiUsers.php file in case it was interfering with the other, more basic solution, code.
I even tried the most basic example:
using the URL of http://mysite.com/test and http://mysite.com/api/test for Route::register('/api/test', function()…
Every combination returns a 404 Not Found.
There must be something very simple which I am missing since I assume this type of functionality gets used regularly by concrete5 developers.
How can I troubleshoot this code? Are there any fully coded real world examples of this functionality being used in an Add-On or in the c5 code?
Thank you for helping me with this issue. I would really like to master this Routing coding…
In all cases I am logged in as SuperUser (admin).
First, I appended your example code:
$classLoader = new \Symfony\Component\ClassLoader\Psr4ClassLoader(); $classLoader->addPrefix('Application\\Api', DIR_APPLICATION . '/' . DIRNAME_CLASSES . '/Api'); $classLoader->register();
to the end of \application\bootstrap\autoload.php [ Is appending the code to the end of this file the correct place to put this code? ]
Then I placed your example code:
namespace Application\Api; use Symfony\Component\HttpFoundation\JsonResponse; class ApiUsers { public function getCurrentUser() { $u = new \User(); if ($u->isRegistered()) { return new JsonResponse([ 'user_id' => $u->getUserID(), 'username' => $u->getUserName(), ]); } return new JsonResponse([], 500); }
Viewing 15 lines of 16 lines. View entire code block.
in \application\src\Api\ApiUsers.php [ I can't figure out how a URL even finds this code ]
Finally I appended your example code:
use Symfony\Component\HttpFoundation\JsonResponse; Route::register('/testapi1', function() { $u = new \User(); if ($u->isRegistered()) { return new JsonResponse([ 'user_id' => $u->getUserID(), 'username' => $u->getUserName(), ]); } return new JsonResponse([], 500); });
to the end of /application/bootstrap/app.php [ Is this where this code should go? ]
I clicked on this link: http://mysite.com/testapi1 which took me to a blank page which returned:
“Not Found
The requested URL was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.”
I tried various combinations like removing the \application\src\Api\ApiUsers.php file in case it was interfering with the other, more basic solution, code.
I even tried the most basic example:
Route::register('/test', function() { print 'This is a contrived example.'; });
using the URL of http://mysite.com/test and http://mysite.com/api/test for Route::register('/api/test', function()…
Every combination returns a 404 Not Found.
There must be something very simple which I am missing since I assume this type of functionality gets used regularly by concrete5 developers.
How can I troubleshoot this code? Are there any fully coded real world examples of this functionality being used in an Add-On or in the c5 code?
Did you get Apache 'Not Found' page or c5 404 page?
Placing code like this should definitely return your text:
Did you also try the url with 'index.php' included?
mysite.com/index.php/test
Placing code like this should definitely return your text:
Route::register('/test', function() { print 'This is a contrived example.'; return ''; });
Did you also try the url with 'index.php' included?
mysite.com/index.php/test
I can't tell whether the error comes from Apache or c5
I get the following error when using mysite.com/test
Not Found
The requested URL was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Here is the error page script
when I saw the Kasperskey script I turned off the Kaspersky protection and tried it again - with the same results.
and I get the following error when using mysite.com/index.php/test
Error
Call to a member function has() on null
I have attached an image of the error screen.
Will using Postman help solve this problem?
I get the following error when using mysite.com/test
Not Found
The requested URL was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Here is the error page script
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> <script type="text/javascript" src="http://ff.kis.v2.scr.kaspersky-labs.com/FD126C42-EBFA-4E12-B309-BB3FDD723AC1/main.js?attr=S59j59t_UP2HSYhTia2G8RKVh2qHf5oU_J3F6MT-lBiHi2DTHsywZW8HV55STXnIA0eUbNAhjQRElpnJPXtnNg" charset="UTF-8"></script></head><body> <h1>Not Found</h1> <p>The requested URL was not found on this server.</p> <p>Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.</p> </body></html>
when I saw the Kasperskey script I turned off the Kaspersky protection and tried it again - with the same results.
and I get the following error when using mysite.com/index.php/test
Error
Call to a member function has() on null
I have attached an image of the error screen.
Will using Postman help solve this problem?
Hi,
The 'error page script' you have pasted seems like an apache error and, in turn, suggests the 'Pretty URL' is not enabled in your site (/index.php/dashboard/system/seo/urls) and 'index.php' should exist in your route.
& the error in the attached screenshot can be an indication of entering into the route callback method. Just paste this code into your app.php file and you should see contrived message:
Make sure you have that `return` line at the end of your callback method and the result should appear.
The 'error page script' you have pasted seems like an apache error and, in turn, suggests the 'Pretty URL' is not enabled in your site (/index.php/dashboard/system/seo/urls) and 'index.php' should exist in your route.
& the error in the attached screenshot can be an indication of entering into the route callback method. Just paste this code into your app.php file and you should see contrived message:
Route::register('/testroute', function() { print 'This is a contrived example.'; return ''; }); // the route would be: ursite.com/index.php/testroute
Make sure you have that `return` line at the end of your callback method and the result should appear.
Thank you for hanging in here with me.
Your first 2 examples are now working. Thank you. My attempt at using a controller is still not working.
Example 1 works when called at: https://mywebsite.com/index.php/testroute...
Example 2 works when called at: https://mywebsite.com/index.php/testapi...
Example 3 does not work when called at: https://mywebsite.com/index.php/api/current_user...
I copied the example, with some mods based on your examples, from: https://documentation.concrete5.org/developers/routing/controllers...
and
I have attached an image of the error window. The basic error is:
"ReflectionException (-1) - Class \Application\Api\Controller\UserController does not exist"
Your help in solving this last problem would be much appreciated.
Your first 2 examples are now working. Thank you. My attempt at using a controller is still not working.
Example 1 works when called at: https://mywebsite.com/index.php/testroute...
/* Code in: /application/bootstrap/app.php */ Route::register('/testroute', function() { print 'This is a contrived example.'; return ''; });
Example 2 works when called at: https://mywebsite.com/index.php/testapi...
/* Code in: /application/bootstrap/app.php */ use Symfony\Component\HttpFoundation\JsonResponse; Route::register('/testapi', function() { $u = new \User(); if ($u->isRegistered()) { return new JsonResponse([ 'user_id' => $u->getUserID(), 'username' => $u->getUserName(), ]); } return new JsonResponse([], 500); });
Example 3 does not work when called at: https://mywebsite.com/index.php/api/current_user...
I copied the example, with some mods based on your examples, from: https://documentation.concrete5.org/developers/routing/controllers...
/* Code in: /application/src/Api/Controller/User.php */ namespace Application\Api\Controller; use Concrete\Core\User\User; use Symfony\Component\HttpFoundation\JsonResponse; // per shahroq class UserController { public function getCurrentUser() { $u = new User(); if ($u->isRegistered()) { $data = []; $data['user_id'] = $u->getUserID(); $data['username'] = $u->getUserName(); return new JsonResponse($data); } else {
Viewing 15 lines of 19 lines. View entire code block.
and
/* Code in: /application/bootstrap/app.php */ Route::register('/api/current_user', '\Application\Api\Controller\UserController::getCurrentUser');
I have attached an image of the error window. The basic error is:
"ReflectionException (-1) - Class \Application\Api\Controller\UserController does not exist"
Your help in solving this last problem would be much appreciated.
In your code, the class name does not match the file name. Renaming `/application/src/Api/Controller/User.php` to `/application/src/Api/Controller/UserController.php` should fix that.
I renamed User.php to UserController.php and it still does not work.
The Error is: " ReflectionException (-1) - Class \Application\Api\Controller\UserController does not exist"
The Class of UserController.php is UserController. And its namespace is Application\Api\Controller
The Documentation at:https://documentation.concrete5.org/developers/routing/controllers... says:
Let’s take our current_user route example. How about we move it out of a route, and into a dedicated PHP controller. This is how that’s done:
We now no longer include the logic of retrieving the current user inline with the route definition. Instead, it is housed in a separate class, found at Application\Api\Controller\User. Furthermore, we have a specific method within this controller class that we run when the route is visited, getCurrentUser.
What does this controller look like? There isn’t much to it. At application/src/Api/Controller/User.php, we have:
In the documentation...
The Route registration says:
Application\Api\Controller\UserController::getCurrentUser
The location of the controller says:
application/src/Api/Controller/User.php (not UserController.php)
One has the src directory and the other does not, but I understand the src is no longer necessary in the namespace.
The Error is: " ReflectionException (-1) - Class \Application\Api\Controller\UserController does not exist"
The Class of UserController.php is UserController. And its namespace is Application\Api\Controller
The Documentation at:https://documentation.concrete5.org/developers/routing/controllers... says:
Let’s take our current_user route example. How about we move it out of a route, and into a dedicated PHP controller. This is how that’s done:
$router->get(‘/api/current_user’, ‘Application\Api\Controller\UserController::getCurrentUser’);
We now no longer include the logic of retrieving the current user inline with the route definition. Instead, it is housed in a separate class, found at Application\Api\Controller\User. Furthermore, we have a specific method within this controller class that we run when the route is visited, getCurrentUser.
What does this controller look like? There isn’t much to it. At application/src/Api/Controller/User.php, we have:
<?php namespace Application\Api\Controller; use Concrete\Core\User\User; use Symfony\HttpFoundation\JsonResponse; /* use Symfony\Component\HttpFoundation\JsonResponse; // should be this per shahroq */ class UserController { public function getCurrentUser() { $u = new User(); if ($u->isRegistered()) { $data = []; $data[‘user_id’] = $u->getUserID(); $data[‘username’] = $u->getUserName(); return new JsonResponse($data);
Viewing 15 lines of 20 lines. View entire code block.
In the documentation...
The Route registration says:
Application\Api\Controller\UserController::getCurrentUser
The location of the controller says:
application/src/Api/Controller/User.php (not UserController.php)
One has the src directory and the other does not, but I understand the src is no longer necessary in the namespace.
Solved the problem when using a routing controller by place the following code in /application/bootstrap/autoload.php
$classLoader = new \Symfony\Component\ClassLoader\Psr4ClassLoader(); $classLoader->addPrefix('Application\\Api\\Controller', DIR_APPLICATION . '/' . DIRNAME_CLASSES . '/Api/Controller'); $classLoader->register();
In your case, using this code should simply do the trick:
Or, should you insist on placing your code into a separate file, a file can be created preferably in:
\application\src\Api\Controller\UserApi.php
And don't forget to register the path in:
\application\bootstrap\autoload.php
In either case, you should be able to hit the route with: