ZF3: Action and view doesn't found - php

In my application I have created a second action in a controller. When I call the application with the url http://local.domain I've got the correct page so it's called the correct controller. But If I want to make this call http://local.domain/liga-futbol-1 it doesn't work and I've got this error:
A 404 error occurred Page not found. The requested URL could not be
matched by routing.
No Exception available
IndexController.php
namespace Stats\Controller;
use Zend\Mvc\Controller\AbstractActionController;
class IndexController extends AbstractActionController {
public function indexAction()
{
//This action serves the page
return [];
}
public function ligaFubtol1Action(){
return [];
} }
module.config.php
namespace Stats;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'controllers' => [
'factories' => [
Controller\IndexController::class => InvokableFactory::class,
],
],
'router' => [
'routes' => [
'home' => [
'type' => 'Literal',
'options' => [
// This works!!! => http://local.domain
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
// This doesn't work!!! http://local.domain/liga-futbol-1
'liga-futbol-1' => [
'type' => Segment::class,
'options' => [
'route' => '/liga-futbol-1',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'ligaFutbol1'
],
],
'may_terminate' => true,
'child_routes' => [
],
],
],
],
],
],
'view_manager' => [
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'stats/index/index' => __DIR__ . '/../view/stats/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
/*
* Con este array de parámetros permitimos enviar datos y no mostrar vista
*/
'strategies' => [
'ViewJsonStrategy',
],
],
];
Directories:
I have checked my cache in "/dir_project/data/cache" and there is nothing.
What am I doing wrong?

Have a look at the route option of the home route: it’s set to /. The liga-futbol-1 route is a child route of the home route, so its URL is a “sum” of:
home URL: /
liga-futbol-1 URL: /liga-futbol-1
In result: //liga-futbol-1 is the URL of the home/liga-futbol-1 route.
If you want just something like /liga-futbol-1, there are two solutions:
Make the liga-futbol-1 route independent of the home route (i.e. not its child):
'routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index'
]
]
],
'liga-futbol-1' => [
'type' => Segment::class,
'options' => [
'route' => '/liga-futbol-1',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'ligaFutbol1'
]
]
]
]
Remove / from the beginning of liga-futbol-1’s route option:
'liga-futbol-1' => [
'type' => Segment::class,
'options' => [
'route' => 'liga-futbol-1',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'ligaFutbol1'
]
]
]

Related

ZF3 How to use optional parameter in homepage route

I'm having trouble adding an optional parameter to my home route.
This is my current router:
'routes' => [
'home' => [
'type' => Segment::class,
'options' => [
'route' => '/[:salon/]',
'constraints' => [
'salon' => '[a-zA-Z][a-zA-Z0-9_-]*'
],
'defaults' => [
'controller' => 'Application\Controller\Index',
'action' => 'index',
'salon' => 'test'
],
],
],
'application' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/:controller[/:action]]',
'constraints' => [
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
],
'defaults' => [
'__NAMESPACE__' => 'Application\Controller',
'controller' => 'Application\Controller\Index',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'default' => [
'type' => 'wildcard'
]
]
],
],
My Controller:
<?php
namespace Application\Controller;
class IndexController extends AbstractController
{
public function indexAction()
{
var_dump($this->params('salon'));
die;
}
}
domain.ltd/
This works and I'm getting default value for salon paramter which is 'test'
domain.ltd/test123
Expected value would be 'test123' but this displays me 404 error: The requested URL could not be matched by routing.

Add new controller to existed module in zf3

In Zend framework 3, I tried adding new controller "ArticleController" to a existed module City but failed. I post screen shot, my folder structure and module.config.php. Could you explain what the problem is? Incidentally, it worked when accessing http://0.0.0.0:7000/city
When accessing http://0.0.0.0:7000/article
Next, module\city\config\module.config.php codes are following:
<?php
namespace City;
use Zend\Router\Http\Segment;
return [
'router' => [
'routes' => [
'city' => [
'type' => Segment::class,
'options' => [
'route' => '/city[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\CityController::class,
'action' => 'index',
],
],
],
'article' => [
'type' => Segment::class,
'options' => [
'route' => '/article[/:action[/:id]]',
'constraints' => [
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
],
'defaults' => [
'controller' => Controller\ArticleController::class,
'action' => 'index',
],
],
],
],
],
'view_manager' => [
'template_path_stack' => [
'city' => __DIR__ . '/../view',
],
],
];
Error message is clear. Application doesn't know anything about your controller. Your module config has to have information about controllers under "controllers" key. Checkout zend documentation, you'll see "controllers" key in config file.

ZF3: Controllers with child routes doesn't work

I'm ZF2 developer and I'm migrating to ZF3 and I'm having troubles whith some controllers.
For example, I have this url: http://localhost/admin which calls to the correct controller (IndexController) and show the correct view. But If I want to associate this url: http://localhos/admin/articulo with ArticuloController doesn't work. When I call to this url: http://localhost/admin/articulo the controller called is AdminController and doesn't find the view.
OPTION 1 => module.config.php:
namespace Admin;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'router' => [
'routes' => [
'admin' => [
'type' => Segment::class,
'options' => [
'route' => '/admin[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'admin/articulos' => [
'type' => Segment::class,
'options' => [
'route' => '/admin/articulos[/:action]',
'defaults' => [
'controller' => Controller\ArticulosController::class,
'action' => 'index',
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => InvokableFactory::class,
Controller\ArticulosController::class => InvokableFactory::class,
],
],
'view_manager' => [
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../view/layout/layout-admin.phtml',
'admin/index/index' => __DIR__ . '/../view/admin/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
/*
* Con este array de parámetros permitimos enviar datos y no mostrar vista
*/
'strategies' => [
'ViewJsonStrategy',
],
],
];
OPTION 2 => module.config.php (ZF2 style):
namespace Admin;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'router' => [
'routes' => [
'admin' => [
'type' => Segment::class,
'options' => [
'route' => '/admin[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
'admin/articulos' => [
'type' => Literal::class,
'options' => [
'route' => '/admin/articulos[/:action]',
'defaults' => [
'controller' => 'Articulos',
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'default' =>[
'type' => Segment::class,
'options' => [
'route' => '/[:controller[/:action][/:id1]]',
'constraints' => [
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id1' => '[0-9_-]*'
],
'defaults' => [],
],
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => InvokableFactory::class,
Controller\ArticulosController::class => InvokableFactory::class,
],
],
'view_manager' => [
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../view/layout/layout-admin.phtml',
'admin/index/index' => __DIR__ . '/../view/admin/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
/*
* Con este array de parámetros permitimos enviar datos y no mostrar vista
*/
'strategies' => [
'ViewJsonStrategy',
],
],
];
OPTION 3 => module.config.php (following zf3 tutorial):
https://docs.zendframework.com/zend-mvc/routing/#http-routing-examples
namespace Admin;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;
return [
'router' => [
'routes' => [
'admin' => [
'type' => Segment::class,
'options' => [
'route' => '/admin[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'articulos' => [
'type' => Segment::class,
'options' => [
'route' => '/articulos[/:action]',
'defaults' => [
'controller' => Controller\ArticulosController::class,
'action' => 'index'
],
],
],
],
],
],
],
'controllers' => [
'factories' => [
Controller\IndexController::class => InvokableFactory::class,
Controller\ArticulosController::class => InvokableFactory::class,
],
],
'view_manager' => [
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../view/layout/layout-admin.phtml',
'admin/index/index' => __DIR__ . '/../view/admin/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
],
'template_path_stack' => [
__DIR__ . '/../view',
],
/*
* Con este array de parámetros permitimos enviar datos y no mostrar vista
*/
'strategies' => [
'ViewJsonStrategy',
],
],
];
For all of the configurations when I call the url: http://localhost/admin/articulos the view that I get is ...
Where you can see that the controller called is Admin\Controller\IndexController and not Admin\Controller\ArticulosController
What am I doing wrong?
Update 1:
The option 3 configuration works fine!!! I have delete all the content from /cache directory and now the controller is found but ... I have got now an error rendering the template ...
Message:
Zend\View\Renderer\PhpRenderer::render: Unable to render template
"admin/articulos/index"; resolver could not resolve to a file
Stack Trace:
0 /var/www/html/31juegos/vendor/zendframework/zend-view/src/View.php(207):
Zend\View\Renderer\PhpRenderer->render()
1 /var/www/html/31juegos/vendor/zendframework/zend-view/src/View.php(236):
Zend\View\View->render(Object(Zend\View\Model\ViewModel))
2 /var/www/html/31juegos/vendor/zendframework/zend-view/src/View.php(200):
Zend\View\View->renderChildren(Object(Zend\View\Model\ViewModel))
3 /var/www/html/31juegos/vendor/zendframework/zend-mvc/src/View/Http/DefaultRenderingStrategy.php(105):
Zend\View\View->render(Object(Zend\View\Model\ViewModel))
4 /var/www/html/31juegos/vendor/zendframework/zend-eventmanager/src/EventManager.php(322):
Zend\Mvc\View\Http\DefaultRenderingStrategy->render(Object(Zend\Mvc\MvcEvent))
5 /var/www/html/31juegos/vendor/zendframework/zend-eventmanager/src/EventManager.php(171):
Zend\EventManager\EventManager->triggerListeners(Object(Zend\Mvc\MvcEvent))
6 /var/www/html/31juegos/vendor/zendframework/zend-mvc/src/Application.php(367):
Zend\EventManager\EventManager->triggerEvent(Object(Zend\Mvc\MvcEvent))
7 /var/www/html/31juegos/vendor/zendframework/zend-mvc/src/Application.php(348):
Zend\Mvc\Application->completeRequest(Object(Zend\Mvc\MvcEvent))
8 /var/www/html/31juegos/public/index.php(40): Zend\Mvc\Application->run()
9 {main}
It is a typo issue. Try with this http://localhost/admin/articulos (note the ending "s") because your router is /admin/articulos which points to this ArticulosController's indexAction(). That is why this url http://localhost/admin/articulo (without ending "s") was not able to dispatch. And the view structure should be of type module/controller/action.
(Posted on behalf of the OP).
Finally, I have fixed my last problem. The problem was due to my index.phtml was in an wrong directory /view/admin/articulos/**index/**index.phtml. The correct directory is /view/admin/articulos/index.phtml.

ZF3 optional parameter with child routes on Segment class doesn't want to match

I want to create routes with an optional [lang] parameter that would be used to set the application language as follows:
Example with default lang param(EN for example)
domain.tld/
domain.tld/users
domain.tld/contacts
etc.
Example witt new lang param(DE for examle)
domain.tld/de
domain.tld/de/users
domain.tld/de/contacts
etc.
This is my route configuration:
'router' => [
'routes' => [
'site' => [
'type' => Segment::class,
'options' => [
'route' => '[/:lang]',
'constraints' => [
'lang' => '[a-z]{2}',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
'lang' => 'en',
],
],
'may_terminate' => true,
'child_routes' => [
'home' => [
'type' => Literal::class,
'options' => [
'route' => '/',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
],
'application' => [
'type' => Segment::class,
'options' => [
'route' => '/application[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
'may_terminate' => true,
],
],
],
],
]
When I have lang param in the url everything is fine. But when I try to open "default" lang without specifying it into the path (ex. example.tld/application/test) it gives me 404 error.
What I found is that the final regex after transformation from Segment class is (\G(?:/(?P<param1>([a-z]{2})))?) and path is /application/test. When preg_match is executed on Segment.php:385 it return match with following values:
[
'0' => '/ad',
'param1' => 'ad',
'1' => 'ad',
],
which is obviously the wrong behavior. My language is set to "ad" instead of open application/test action. I tested around 10 more regex but without success... (ex. ^[a-z]{2}$).
What I am doing wrong?
You get 404 because URL does not match site route, so child routes of site are skipped.
Try this:
'home' => [
'type' => Segment::class,
'options' => [
'route' => '/[:lang/]',
'constraints' => [
'lang' => '(en|de)?',
],
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
'lang' => 'en',
],
],
'may_terminate' => true,
'child_routes' => [
'application' => [
'type' => Segment::class,
'options' => [
'route' => 'application[/:action]',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'index',
],
],
],
],
]
If you do not provide lang param then it takes default (en in my example) param.
Example:
example.tld/application/test
lang is en
controller is IndexController
action is test (testAction())
example.tld/de/application/test
lang is de
controller is IndexController
action is test (testAction())

Not getting default route parameter in ZF3

In ZF3 I want to get default parameter from route. I'm getting parameters in this way in controller:
$params = $this->params()->fromRoute('crud');
My urls looks like this:
1: somedomain/admin/color/add
2: somedomain/admin/color
In 1) I'm getting add in my $params variable.
In 2) I'm getting null but I'm expecting default (in this case view)
I think this is problem with bad router configuration.
'admin' => [
'type' => Segment::class,
'options' => [
'route' => '/admin/:action',
'defaults' => [
'controller' => Controller\AdminController::class,
'action' => 'index',
],
],
'may_terminate' => true,
'child_routes' => [
'color' => [
'type' => Segment::class,
'options' => [
'route' => '/:crud',
'constraints' => [
'crud' => 'add|edit|delete|view',
],
'defaults' => [
'controller' => Controller\AdminController::class,
'crud' => 'view',
],
],
],
],
],
In your route definition, you didn't says the router that your crud parameter is optionnal. So when you call somedomain/admin/color, it is the route /admin/:action which is selected.
To specify a optional parameter, use the bracket notation (assuming you use the same action):
'admin' => [
'type' => Segment::class,
'options' => [
'route' => '/admin/:action[/:crud]',
'defaults' => [
'controller' => Controller\AdminController::class,
'action' => 'index',
'crud' => 'view',
],
'constraints' => [
'crud' => 'add|edit|delete|view',
],
],
],

Categories