Symfony route to file misunderstanding - php

I had an intention to dynamically generate a robots.txt file for different domain names.
I removed the file from /web/ directory.
I added
bits_cb.common:
resource: "#BitsClientoboxBundle/Controller/CommonController.php"
type: annotation
to routing.yml.
I added
/**
* #Route("/robots.txt", name="robots")
* #param Request $request
*/
public function indexAction(Request $request)
{
//
}
to CommonController.php.
The debug:router console command there is route:
robots ANY ANY ANY /robots.txt
But if I try to get from http://{{sitename}}/robots.txt it returns 404.
To be sure, if I change
* #Route("/robots.txt", name="robots")
to
* #Route("/robots", name="robots")
and get from http://{{sitename}}/robots it works okay.

Related

PHP Routing System - own MVC

I am trying to develop my own MVC and i got to the point where a routing system is due.
I have used some examples from the internet and partially it works fine. Evan so, i think something is wrong and i will detail it right bellow.
My MVC has a frontend and a backend. The first question is : Do i need to load the same routing system for the frontend and the backend? Or do i need to have different routing systems? How would you choose?
In the frontend, whenever i am using the main menu to navigate i can go to home or contact page and the pages are displaying corectlly - and the browser url - looks fine : localhost/home or localhost/contact (without the php extension - which is the desired behaviour.)
In the backend section of my website - reaching it by using localhost/admin - of course the routing system from my front-end section has some rules for the admin, so when i am reaching the admin section the browser url is fine - showing http://localhost/admin/ and displays some login form. The Login Form uses post to send info to another page- login.php which runs the login system, and if successfull requires a page named home.php. The problem is after the successfull login - the browser url is http://localhost/admin/login.php !!! which IS NOT the desired behaviour because i am expecting in fact localhost/admin/home (without the php extension) . i have tried with a different routing system for the backend - but for some reason it's not taken in consideration and i have also tried to include the routing system after the succesfull login. I cannot find a good solution. I am surely missing something and i do not know why so please help me. This is how my routing system is looking.
<?php
// Include router class
include('Route.php');
// Add base route (startpage)
Route::add('/',function(){
require 'pages/home.php';
});
// Simple test route that simulates static html file
Route::add('/contact',function(){
require 'pages/contact.php';
});
// Post route example
Route::add('/contact-form',function(){
echo '<form method="post"><input type="text" name="test" /><input type="submit" value="send" /></form>';
},'get');
// Post route example
Route::add('/contact-form',function(){
echo 'Hey! The form has been sent:<br/>';
print_r($_POST);
},'post');
// Accept only numbers as parameter. Other characters will result in a 404 error
Route::add('/foo/([0-9]*)/bar',function($var1){
echo $var1.' is a great number!';
});
Route::run('/');
My router Class:
class Router
{
/**
* The request we're working with.
*
* #var string
*/
public $request;
/**
* The $routes array will contain our URI's and callbacks.
* #var array
*/
public $routes = [];
/**
* For this example, the constructor will be responsible
* for parsing the request.
*
* #param array $request
*/
public function __construct(array $request)
{
/**
* This is a very (VERY) simple example of parsing
* the request. We use the $_SERVER superglobal to
* grab the URI.
*/
$this->request = basename($request['REQUEST_URI']);
}
/**
* Add a route and callback to our $routes array.
*
* #param string $uri
* #param Callable $fn
*/
public function addRoute(string $uri, \Closure $fn) : void
{
$this->routes[$uri] = $fn;
}
/**
* Determine is the requested route exists in our
* routes array.
*
* #param string $uri
* #return boolean
*/
public function hasRoute(string $uri) : bool
{
return array_key_exists($uri, $this->routes);
}
/**
* Run the router.
*
* #return mixed
*/
public function run()
{
if($this->hasRoute($this->request)) {
$this->routes[$this->request]->call($this);
}
}
}
and my successfull login statement which redirect to home :
if ($login) {
require './pages/home.php';
} else {
echo 'ERROR';
}
my htaccess from the admin section folder :
DirectoryIndex index.php
FallbackResource /index.php
# enable apache rewrite engine
RewriteEngine on
# set your rewrite base
# Edit this in your init method too if you script lives in a subfolder
RewriteBase /admin
# Deliver the folder or file directly if it exists on the server
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Push every request to index.php
RewriteRule ^(.*)$ index.php [QSA]

Route Error: Symfony 4 No route found for "GET /blog"

I am having this error:
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: No route
found for "GET /blog" (from "http://localhost:8000/produits")
I added the annotation #Route in the method in my controller (like I saw in other website):
/**
* #Route("/blog", name="article.index")
* #return Response
* */
public function index():Response
{
return $this->render("blog/article.html.twig", [
"current_menu" => 'articles'
]);
}
I tried to add methods={"GET","HEAD"} in #Route but I have the same error
How do I solve this problem?
This one worked for me (adding / to the end of route path):
/**
* #Route("/blog/", name="article.index")
* #return Response
* */
public function index():Response
{
return $this->render("blog/article.html.twig", [
"current_menu" => 'articles'
]);
}
You will also at least need use Symfony\Component\Routing\Annotation\Route; at the start of the file (among the other 'use' lines), Some framework setup for Route annotations could also need to be enabled. Also, how does blog/article.html.twig refer to the route or path?
A freshly installed Symfony 4 instance will need composer require doctrine/annotations package, unless its already been installed by some other package.
https://symfony.com/doc/current/routing.html#creating-routes has more details.

Symfony2 Controller Route clash

Hey all I have a bit of a problem with root annotations in Symfony2.
I have two different controllers that call methods from the same URL positions /test.
Controller 1:
**
* #Route("/test", service="myProject.test.controller.art")
* #Cache(expires="+5 minutes", public=true)
*/
class BlogController
{
/**
* #Route("/{text}", defaults={"text" = null})
* #Route("/topic/{tag}", defaults={"tag" = null})
* #Method({"GET"})
*/
public function listAction(ArtQuery $query)
{
//.................
}
}
Controller 2:
**
* #Route("/test" , service="myProject.test.controller.sitemap"))
* #Cache(expires="+5 minutes", public=true)
*/
class SitemapController
{
/**
* #Route("/sitemap.xml/")
* #Method({"GET"})
*/
public function sitemapAction()
{
//..................
}
}
The problem is that the second Controller is never matched only if is add in my #route("/sitemap.xml/") but I realy want the route to be only #route("/sitemap.xml").
I think the problem is when i input the url /test/sitemap.xml Symfony treats sitemap.xml as /{text} variable route in first controller.
Can I make a exception so that first controller ends as soon as it hits sitemap.xml....?
I read something about requirements but dont quiet understand this concept
The router will use the first route that matches the path.
The only way to prioritize a route over another which could match is to ensure that the stricter requirements are check before the weaker ones.
Normally this would be accomplished by placing the sitemapAction method above listAction.
However since you have a controller for each of these, you will have to put the controllers in the correct order.
To do this you will need to add the controllers to the config individually like this:
app_sitemap:
resource: "#AppBundle/Controller/SitemapController.php"
type: annotation
prefix: /
app_blog:
resource: "#AppBundle/Controller/BlogController.php"
type: annotation
prefix: /
This way the controllers will be iterated in this order.
However it is better if you can give each route a unique path, perhaps:
#Route("/query/{text}", defaults={"text" = null})
according to documentation
Earlier Routes always Win
What this all means is that the order of the routes is very important.
If the blog_show route were placed above the blog route, the URL
/blog/2 would match blog_show instead of blog since the {slug}
parameter of blog_show has no requirements. By using proper ordering
and clever requirements, you can accomplish just about anything.
http://symfony.com/doc/current/book/routing.html
i suggest to use yml or xml file for routing
or you can make a requirement in your first route
/**
* #Route("/{text}", defaults={"text" = null}, requirements={"text" = "^(?!sitemap\.xml)$"})
* #Route("/topic/{tag}", defaults={"tag" = null})
* #Method({"GET"})
*/
public function listAction(ArtQuery $query)
{
//.................
}

Generate well formed routes from MenuBuilder class in Symfony2

I've this route defined in a controller:
/**
* #Secure(roles="IS_AUTHENTICATED_FULLY")
* #Route(
* "/proccess/{slug}",
* requirements={"slug": "^([a-zA-Z0-9]*-[a-zA-Z0-9]*)+$"},
* name="registerRPNI"
* )
*/
public function indexAction(Request $request)
{
......
}
And I need to set the right route in KNPMenuBundle MenuBuilder class. I'm doing as follow:
->addChild('Process RPNI', array(
'uri' => '/process/national-and-imported-products-registration',
))
And it works for dev environment since route shows the right page and execute the right code but if I move away from dev and goes live to prod then I got a 404 Not found, what I'm doing wrong in this case? What should be the right way to generate the routes inside the MenuBuilder class? Any advice around this?

How Generating URLs from a template correctly in Symfony2/Twig

I'm working with Symfony2 and:
I have this in the routing.yml
_welcome:
resource: "#AcmeBundle/Controller/"
type: annotation
I this method within a controller:
/**
* #Route("/{page}")
*/
public function staticAction($page)
{
return $this->render('AcmeBundle:Static:'.$page.'.html.twig');
}
To generate common pages:
/home
/contact
/privacy
But when I make the url on the menu:
Home
Contact
Privacy
And I Symfony generates these urls:
…./?page=home
…./?page=contact
…./?page=privacy
And the right would be:
/home
/contact
/privacy
What must I do?
You've to add a route name in your controller route annotations as follow,
/**
* #Route("/{page}", name="static")
*/
public function staticAction($page)
{
// ...
}
You could then call the twig path helper using that name,
Home

Categories