I learn a symfony2 and i would try to change route to start page in symfony demo application (blog). Instead FrameworkBundle:Template:template controller with static page default/homepage.html.twig i want to change route to AppBundle:Blog:index but i have following error:
Controller "AppBundle\Controller\BlogController::indexAction()" requires that you provide a value for the "$page" argument (because there is no default value or because there is a non optional argument after this one).
And there is a methods code:
/**
* #Route("/", name="blog_index", defaults={"page" = 1})
* #Route("/page/{page}", name="blog_index_paginated", requirements={"page" : "\d+"})
*/
public function indexAction($page)
{
$query = $this->getDoctrine()->getRepository('AppBundle:Post')->queryLatest();
$paginator = $this->get('knp_paginator');
$posts = $paginator->paginate($query, $page, Post::NUM_ITEMS);
$posts->setUsedRoute('blog_index_paginated');
return $this->render('blog/index.html.twig', array('posts' => $posts));
}
app/config/routing.yml
app:
resource: #AppBundle/Controller/
type: annotation
prefix: /{_locale}
requirements:
_locale: %app_locales%
defaults:
_locale: %locale%
homepage:
path: /{_locale}
requirements:
_locale: %app_locales%
defaults:
_controller: AppBundle:Blog:index
#_controller: FrameworkBundle:Template:template
#template: 'default/homepage.html.twig'
_locale: "%locale%"
I know, i can change in argument "$page = 1" but i think its ugly fix. Anyone can help me?
You can pass default parameter values with the defaults key:
homepage:
path: /{_locale}
requirements:
_locale: %app_locales%
defaults:
_controller: AppBundle:Blog:index
_locale: "%locale%"
page: 1
You can try with this annotation
/**
* #Route(
* path = "/page/{page}",
* name = "blog_index",
* defaults = {"page" = 1},
* requirements={"page" : "\d+"}
* )
*/
Related
I Use Symfony 3, And I Want to understand How symfony chouses the Route.
I have 3 routes, 2 in routing.yml and 1 in annotation.
this is my code:
app/config/routing.yml
app:
resource: "#AppBundle/Controller/"
type: annotation
hello:
path: "hello/{firstName}"
defaults: {_controller: AppBundle:Default:rotta,firstName: "route1"}
hello_name:
path: "hello/{firstName}"
defaults: {_controller: AppBundle:Default:rotta, firstName: "route2"}
src/AppBundle/Controller/DefaultController.php
/**
* #Route("hello/{firstName}", name="hello", defaults={"firstName" = "Annotation"})
*/
public function rottaAction($firstName,Request $request)
{
var_dump($request->get('firstName'));
exit;
}
My result is
string 'route1' (length=6)
with this routing.yml
hello:
path: "hello/{firstName}"
defaults: {_controller: AppBundle:Default:rotta,firstName: "route1"}
hello_name:
path: "hello/{firstName}"
defaults: {_controller: AppBundle:Default:rotta, firstName: "route2"}
app:
resource: "#AppBundle/Controller/"
type: annotation
My result is
string 'route2' (length=6)
and with this combination:
hello:
path: "hello/{firstName}"
defaults: {_controller: AppBundle:Default:rotta,firstName: "route1"}
hello_name:
path: "hello/{firstName}"
defaults: {_controller: AppBundle:Default:rotta, firstName: "route2"}
#app:
# resource: "#AppBundle/Controller/"
# type: annotation
my result is:
string 'route1' (length=6)
I have an application in symfony2, and i create routing like this:
spec_add:
path: /add.html
defaults: { _controller: MyBundle:Spec:add }
methods: [GET, POST]
spec_add_to_order:
path: /{indent}/add.html
defaults: { _controller: MyBundle:Spec:add }
methods: [GET, POST]
requirements:
indent: \d+
spec_edit:
path: /{id}/edit.html
defaults: { _controller: MyBundle:Spec:add }
methods: [GET, POST]
requirements:
id: \d+
And I have controller SpecController and method:
public function addAction(Indent $indent = null,Specification $specification = null, Request $request)
when I go to address mydomain.dev/{myindentId}/add.html
i get indent object but I get Specification object too, Why? i don't want specification in this case what am I doing wrong?
So I've decided to delve into phpunit testing and I've shamefully written out my php code before writing my test. Anyway, I'm just writing a very simple test that tells me if I actually found the correct web page. Unfortunately my one assertion test keeps failing. I know my route "/login" is correct because when I navigate to localhost/index.php/login (where index.php is a link to app_dev.php), the page comes up correctly. Bellow is my routing.php file:
caremonk_mainsite_login:
pattern: /login
defaults: { _controller: CaremonkMainSiteBundle:Security:login }
requirements:
_method: POST|GET
caremonk_mainsite_login_check:
pattern: /login_check
requirements:
_method: POST|GET
caremonk_mainsite_signup:
pattern: /signup
defaults: { _controller: CaremonkMainSiteBundle:CreateUser:signup }
requirements:
_method: POST|GET
caremonk_mainsite_logout:
pattern: /logout
defaults: { _controller: CaremonkMainSiteBundle:Security:logout}
requirements:
_method: POST|GET
caremonk_mainsite_post_blog:
pattern: /post_blog
defaults: { _controller: CaremonkMainSiteBundle:UserEvents:post }
requirements:
_method: POST|GET
caremonk_mainsite_my_profile:
pattern: /my_profile_edit
defaults: { _controller: CaremonkMainSiteBundle:UserEvents:editProfile }
requirements:
_method: POST|GET
caremonk_mainsite_activate:
pattern: /activate/{username}/{token}
defaults: { _controller: CaremonkMainSiteBundle:CreateUser:activateAccount }
requirements:
_methods: GET
caremonk_mainsite_password_reset_request:
pattern: /reset_password/
defaults: { _controller: CaremonkMainSiteBundle:Security:passwordResetRequest }
requirements:
_methods: GET | POST
caremonk_mainsite_reset_password_email:
pattern: /reset_password_email/{username}/{resetPasswordToken}
defaults: { _controller: CaremonkMainSiteBundle:Security:sendNewPassword }
requirements:
_methods: GET
caremonk_mainsite_change_password:
pattern: /change_password
defaults: { _controller: CaremonkMainSiteBundle:Security:changePassword }
requirements:
_methods: GET | POST
caremonk_mainsite_home:
pattern: /
defaults: { _controller: CaremonkMainSiteBundle:Home:index }
requirements:
_methods: GET
Anyway bellow is the test code that keeps failing:
<?php
namespace Caremonk\MainSiteBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class SecurityControllerFunctionalTest extends WebTestCase
{
public function testIndex()
{
$client = static::createClient();
// I've done many tests
// I've tried the following request with all failed results
// $crawler = $client->request('GET', 'index.php/login');
// $crawler = $client->request('GET', 'http://localhost/indpex.php/login');
// $crawler = $client->request('GET', 'localhost/index.php/login');
// You get the idea
$crawler = $client->request('GET', '/login');
$this->assertTrue($client->getResponse()->isSuccessful());
}
}
My routing.yml and routing_dev.yml files are shown bellow
#routing_dev.yml
_wdt:
resource: "#WebProfilerBundle/Resources/config/routing/wdt.xml"
prefix: /_wdt
_profiler:
resource: "#WebProfilerBundle/Resources/config/routing/profiler.xml"
prefix: /_profiler
_configurator:
resource: "#SensioDistributionBundle/Resources/config/routing/webconfigurator.xml"
prefix: /_configurator
_main:
resource: routing.yml
#routing.yml
caremonk_main_site:
resource: "#CaremonkMainSiteBundle/Resources/config/routing.yml"
prefix: /
You prefixed your imported routes with a "/", and your routes path start with a "/".
Normally I would prefix my routes with something more meaningful (and does not end with a "/") or remove the "/" from your imported routes.
Running the following command should give you insight to how your routes are registered.
app/console debug:router
Can someone clearly explain how routes are supposed to be configured for REST requests using FOSRest? Every tutorial seems to do it differently.
My Controller:
<?php
namespace Data\APIBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class DatasetController extends Controller{
protected function postDatasetAction(Request $request){
//Query here
}
The URL should look something like this: Symfony/web/app_dev.php/api/dataset. So I thought the routes should be something like...
app/config/routes.yml
data_api:
resource: "#DataAPIBundle/Resources/config/routing.yml"
prefix: /api
type: rest
And....
Data/APIBundle/Resources/config/routing.yml
data_query:
type: rest
pattern: /dataset
defaults: {_controller: DataAPIBundle:Dataset:datasetAction, _format: json }
requirements:
_method: POST
Please follow the next URL to read the official documentation:
http://symfony.com/doc/master/bundles/FOSRestBundle/index.html
To start with this bundle, I would suggest following the single restful controller documentation:
http://symfony.com/doc/master/bundles/FOSRestBundle/5-automatic-route-generation_single-restful-controller.html
You will also find clear examples (https://github.com/liip/LiipHelloBundle) about what this bundle can offer.
Few things from the snippets you have posted drew my attention:
The visibility of your controller method is protected whereas it should be public (http://symfony.com/doc/current/book/controller.html)
public function postDatasetAction(Request $request) {
// your code
}
The "routing.yml" file created to configure your route shall contain the name of the aforementioned controller method (postDatasetAction instead of DatasetAction):
# routing.yml
data_query:
type: rest
pattern: /dataset
defaults: {_controller: DataAPIBundle:Dataset:postDatasetAction, _format: json }
requirements:
_method: POST
Please find below an example to setup a route like :
get_items GET ANY ANY /items.{json}
# config.yml
fos_rest:
allowed_methods_listener: true
format_listener:
default_priorities: ['json', html, '*/*']
fallback_format: json
prefer_extension: true
param_fetcher_listener: true
routing_loader:
default_format: json
view:
formats:
json: true
mime_types:
json: ['application/json', 'application/x-json']
force_redirects:
html: true
view_response_listener: force
# routing.yml
categories:
type: rest
resource: Acme\DemoBundle\Controller\ItemController
<?php
namespace Acme\DemoBundle\Controller
use FOS\RestBundle\Request\ParamFetcher;
use FOS\RestBundle\Controller\Annotations as Rest;
class ItemController
{
/**
* Get items by constraints
*
* #Rest\QueryParam(name="id", array=true, requirements="\d+", default="-1", description="Identifier")
* #Rest\QueryParam(name="active", requirements="\d?", default="1", description="Active items")
* #Rest\QueryParam(name="from", requirements="\d{4}-\d{2}-\d{2}", default="0000-00-00", description="From date")
* #Rest\QueryParam(name="to", requirements="\d{4}-\d{2}-\d{2}", default="0000-00-00", description="End date")
* #Rest\QueryParam(name="labels", array=true, requirements="\d+", default="-1", description="Labels under which items have been classifed")
*
* #Rest\View()
*
* #param ParamFetcher $paramFetcher
*/
public function getItemsAction(ParamFetcher $paramFetcher) {
$parameters = $paramFetcher->all();
// returns array which will be converted to json contents by FOSRestBundle
return $this->getResource($parameters);
}
}
P.S. : You will need to add a view to display the resource as an HTML page
you are missing the routing part of FOSRestbundle in the controller:
protected function postDatasetAction(Request $request){
//Query here
} // "post_dataset" [POST] /dataset
Well, having the following in my routing_dev.yml
_welcome:
pattern: /
defaults: { _controller: AcmeDemoBundle:Welcome:index }
homepage:
pattern: /
defaults: { _controller: AcmeDemoBundle:Ideup:index }
aboutme:
pattern: /aboutme
defaults: { _controller: AcmeDemoBundle:Ideup:about }
_ideup:
resource: "#AcmeDemoBundle/Controller/IdeupController.php"
type: annotation
prefix: /ideup
_form:
resource: "#AcmeDemoBundle/Controller/FormController.php"
type: annotation
_wdt:
resource: "#WebProfilerBundle/Resources/config/routing/wdt.xml"
prefix: /_wdt
_profiler:
resource: "#WebProfilerBundle/Resources/config/routing/profiler.xml"
prefix: /_profiler
_main:
resource: routing.yml
I'm trying to have a simple form:
<form action="{{ path('_form') }}" method="POST" id="contact_form">
But I keep getting this following exception: "Route "_form" does not exist."
I just don't know where else to look and what to do, any ideas?
_form:
resource: "#AcmeDemoBundle/Controller/FormController.php"
type: annotation
This will just load annotated routes from the FormController.
For example:
/**
* #Route("/my/route", name="my_route")
*/
public function myRouteAction() { ... }
If you want a _form route, you should either load all annotationed routes from the FormController or define it in another way:
_form:
pattern: /path/to/your/form
defaults: { _controller: AcmeDemoBundle:Form:myFormAction }
Of course myFormAction() should exist in the FormController.