I'm working on a Symfony 1.4 project and when I do this:
url_for('');
I'm expecting to get the URL for the index.php controller or at least http://domain/ but I'm getting this:
/sfTCPDF
sfTCPDF is a plugin that I have in this project that in my config/ProjectConfiguration.class.php is used like:
class ProjectConfiguration extends sfProjectConfiguration {
public function setup() {
$this->enablePlugins('sfTCPDFPlugin');
}
}
When I disable the plugin I get the expected result:
$url = url_for('');
> /
Or when I use it like this (Doesn't matter if the plugin is enabled or not):
$url = url_for('/');
> /
I don't understand why the plugin is causing (or even if it's the plugin fault).
Any suggestions? I can search & replace the entire project for url_for('') and put the '/'
But I really want to understand why this is happening.
After some research:
I found out that when the url_for function is called, the procedure is the next:
lib/vendor/symfony/lib/helper/UrlHelper.php url_for()
lib/vendor/symfony/lib/helper/UrlHelper.php url_for2()
lib/vendor/symfony/lib/helper/UrlHelper.php url_for1()
lib/vendor/symfony/lib/controller/sfWebController.class.php gen_url()
lib/vendor/symfony/lib/routing/sfRoute.class.php generate()
And in the last one it gets the $this->pattern here is where the pattern is sfTCPDF/:action
which means that some routing is playing. Continuing my research i found out that the plugin has a routing.yml with:
sfTCPDF:
url: /sfTCPDF/:action
param: { module: sfTCPDF, action: test }
If I delete this routing everything works as expected.
Now the question is: when do the plugin creates a routing object with the pattern of sfTCPDF and why?
I never use the url_for with an empty string.
In my routes file I use to have:
homepage:
url: /
param: { module: home, action: index }
So if I want the route for this, I use:
url_for('#homepage');
url_for uses the route name you provide to find the proper route in the cached routes table. If you provide an empty string it will take the 0 index from the table (which you can find in the file: cache/app/env/config/config_routing.yml.php.
When the TCPDF plugin is on its' route is being added as the first one that's why you get it as the url.
The solution - don't use an empty string for url_for. If you want to get the url of the homepage always use url_for('/') or url_for('#homepage').
Related
I am working on a new website being built in SilverStripe. Currently I am having a ton of trouble trying to get the system to let me change the URL alias (or create a second one) for the Security controller's login (and eventually logout) function.
I have tried playing around with the routes.yml file and I tried creating the paths in my own UserController and loading directly from the Security controller with "return Security::login()". But that gives me errors about the use of the static functions.
Unfortunately I don't come from a ton of object oriented experience and this is the first CMS I have used that actually uses a bunch of true object orientation. The current version of SilverStripe we are using is 3.0 (but we will be upgrading to 3.1.1 in a few days).
Does anyone know much about the routing in SilverStripe?
as you stated correctly, SilverStripe has routes, and they can be defined in a yaml config file.
if you take a look at the existing routes.yml in the framework you can see how the default security route is defined:
https://github.com/silverstripe/silverstripe-framework/blob/fd6a1619cb7696d0f7e3ab344bc5ac7d9f6cfe77/_config/routes.yml#L17
if you just want to replace the Secuirty in Secuirty/login, its as easy as just creating your own routes.ymlin mysite/_config/ with the following content:
---
Name: myroutesorsomeotherrandomname
Before: '*'
After:
- '#rootroutes'
- '#coreroutes'
- '#modelascontrollerroutes'
- '#adminroutes'
---
Director:
rules:
'foobar//$Action/$ID/$OtherID': 'Security'
NOTE: make sure you ran a ?flush=1 to ensure the yml file is loaded (they get cached)
also make sure you use spaces in the yml file, if you use tabs you are going to have a bad time
if you however wish to also replace /login and /logout this is no longer a thing for routing.
login and logout are actions (php functions that are listed in Security::$allowed_actions and thus available as URL) on the on Security.
but its still rather easy, just subclass Security and create the actions you want:
<?php
class MySuperSecurity extends Security {
private static $allowed_actions = array(
'showMeTheLoginForm',
'alternative_login_action_with_dashes',
'doTheLogout',
);
function showMeTheLoginForm() {
// can be visited via http://website.com/foobar/showMeTheLoginForm
return $this->login();
}
function alternative_login_action_with_dashes() {
// can be visited via http://website.com/foobar/alternative-login-action-with-dashes
return $this->login();
}
function doTheLogout($redirect = true) {
// can be visited via http://website.com/foobar/doTheLogout
return $this->logout($redirect);
}
}
and make the route point to your new class instead of Security inside the routes.yml:
'foobar//$Action/$ID/$OtherID': 'MySuperSecurity'
NOTE: again, make sure you did a ?flush=1, both the private static $allowed_actions as well as the yml config file are cached by silverstripe.
NOTE: both solutions suggested in this post will create an additional route to login and does not replace the existing one, so the old Security/login will still be available
I don't know nothing about SilverStripe excepting that is a CMS, but i think SilverStripe must provide a way to aliases Url. Also an alternative is create Alias in virtual host definition if you're using apache or in .htaccess file. Refer to apache doc to further details. If you post a skeleton of your .htaccess file or VirtualHost definition i could help you.
I'm trying to make a redirect from route /admin to /admin/post/list.
I set a route from /admin to IndexController::indexAction()
Then I made controller like this
class IndexController extends AbstractActionController
{
public function indexAction()
{
$this->redirect()->toRoute('postList');
}
}
It works well, but ZF2 required to make a template index/index.phtml.
How I can do this redirect better, without empty templates?
If you add return it should work:
return this->redirect()->toRoute('postList');
I found initially that I couldn't make the return response option work at all, in spite of the docs and plenty of abortive attempts.
In the end I stripped out the default application module that I had included to bootstrap things "out of the box" but wasn't using for anything else, and after shifting the translator config and the factory for it, (as required by the error template - I suppose i could have removed even that, as not required) it started working.
Hey presto!
Being new to Cake on PHP, I am trying to work out if I have a URL, what would be the easiest way to find the controller code for it?
The URL on my local machine is something like:
http://foofoofoo.local/protected/admin/org/edit/1
I have worked out that the location of the view for this file is at this location on my machine:
/var/www/MyApp/protected/app/views/org/admin_edit.ctp
I thought what I'd do is do a search throughout the entire codebase for anything referencing admin_edit.ctp. I found two entries, and changed them to see if I had found the point where the view is called, but despite changing the file name on these entries - the app still works when I visit the URL: http://foofoofoo.local/protected/admin/org/edit/1
I just want to see where the admin_edit.ctp file is being called within the site.
URL: http://foofoofoo.local/protected/admin/org/edit/1
This means I can assume you have a added a route in your /app/Config/routes.php. Where this is pointing can not be said since we don't have access to this file.
Why can I assume you have added this to your routes? Because the posted URL is not matching the CakePHP Conventions which clearly states that controllers should be defined in plural. Since the URL will be accessing the Controller directly through the Controller, unless a route has been specified, I know that the OrgController does not exist. Why?
Try Inflector::pluralize('Org'). It will return 'Orgs' to you. And thus meaning the controller should be called OrgsController and you should be accessing this Controller via the following URL.
http://foofoofoo.local/protected/admin/orgs/edit/1
In this OrgsController there should be an action (function) called admin_edit(), because you have prepended the org with Admin, which is a prefix.
It can be possible that the /protected part, is part of the URL as well, but do not know where your main /App is located and what part of the URL is pointing to the /app/webroot/index.php file.
The Views can be found at /app/View/Orgs/*.ctp.
If you are still having trouble finding your files. Please start with the Blog tutorial written by the Cake Community. This tutorial describes all the neat built-in tricks and will get your first app running in no-time. Please read that first!
If you are still having trouble, feel free to update your question and add the /app/Config/routes.php file.
Under Cake 1.3, if your application has an AppController (check if the file app/app_controller.php exists), you can put this code in the beforeFilter method:
debug($this->params);
It will print an array on your app pages when you are in debug mode, with the name of the controller and the action used.
Array
(
...
[controller] => controller_name
[action] => action_name
...
)
If the AppController does not contain any beforeFilter method, you can just create it:
function beforeFilter()
{
debug($this->params);
}
I heve an embedded controller in my base template. It's a search bar.
For the search bar controller, I have a route "myProject/search".
What I would like is that this route will be taken only when the template where I am embedding the controller (base.html.twig) will call it, and not when i manually put in the browser: "myproject/search".
Any idea on how to do that.
I think, since some time you can't do it:
http://symfony.com/doc/current/book/templating.html#embedding-controllers
quote from the docs:
Even though this controller will only be used internally, you'll need
to create a route that points to the controller
(...)
Since Symfony 2.0.20/2.1.5, the Twig render tag now takes an absolute
url instead of a controller logical path. This fixes an important
security issue (CVE-2012-6431) reported on the official blog. If your
application uses an older version of Symfony or still uses the
previous render tag syntax, you should upgrade as soon as possible.
Anyway, I guess, you can try do it yourself by passing some "secret" argument to search action when you call it from your template. Next in the action you check if the argument was passed to it, and if not you throw 404.
Another way to achieve your goal is use .htaccess file.
You can restrict your route to a certain method by _method option in your routing configuration:
your_rote:
pattern: /myProject/search
defaults: { _controller: YourBundle:YourController:YourAction }
requirements:
_method: POST
I have set up friendly URLs for a few search result pages, using a custom route for each:
friendly_search_resultpage:
url: /products/my-friendly-alias
param:
module: products
action: search
querystring: searchattribute
querystring2: searchattribute2
This works fine, but when doing the search directly (i.e. browsing to /products/search?querystring=search...) I want to set a <link rel="canonical"> containing the matching friendly URL. This will help Google understand the relation and that there isn't duplicate content.
I put my friendly URL route at the top of routes.yml and hoped for a magic match, but URL parameters aren't recognised in the checking done by symfony. I have dug into sfRoute, with no luck. Is it possible?
I ended up writing a custom routing class to use for these routes, which is executed when url_for() is called. Here is the code:
<?php
class mySearchFriendlyRoute extends sfRoute
{
public function matchesParameters($params, $context = array())
{
// I can't find symfony sorting parameters into order, so I do
// (so that foo=x&bar=y is treated the same as bar=y&foo=x)
ksort($params);
$mine = $this->defaults;
ksort($mine);
if ($params == $mine) {
return true;
}
return false;
}
}
To use, add class: mySearchFriendlyRoute to the routes.yml entry.
Try to use Your own Route:
friendly_search_resultpage:
class: YourRouteClassName
...
And overload sfRoute::generate() there by concrete cannonicalization (return the canonical URL).
This redirects with 301 in my project upon of last sf1.4 revision.