Generating absolute URLs in symfony tasks - symfony1

I have a quick question regarding the creation of absolute URLs within a symfony task.
Basically I have the following:
/**
* This function returns the link to a route
*
* #param $context context from which to create the config from
* #param $routingText this contains the text to be routed
* #param $object if we are generating an object route we need to pass the object
* #param boolean $absolute - whether to generate an absolute path
* #return string
*/
public static function getUrlFromContext($routingText, $object = null, $application = null, $debug = false,
$absolute = false, $htmlSuffix=true)
{
$currentApplication = sfConfig::get('sf_app');
$currentEnvironment = sfConfig::get('sf_environment');
$context = sfContext::getInstance();
$switchedContext = false;
if (!is_null($application) && $context->getConfiguration()->getApplication() != $application)
{
$configuration = ProjectConfiguration::getApplicationConfiguration($application, $currentEnvironment,
$debug);
$routing = sfContext::createInstance($configuration)->getRouting();
$switchedContext = true;
}
else
{
$routing = $context->getRouting();
}
if (is_object($object))
{
$route = $routing->generate($routingText, $object, $absolute);
}
else
{
$route = $routing->generate($routingText, null, $absolute);
}
if ($switchedContext)
{
sfContext::switchTo($currentApplication);
}
if (strcasecmp($application, 'frontend') == 0 && strcasecmp($currentEnvironment, 'prod') == 0)
{
$route = preg_replace("!/{$currentApplication}(_{$currentEnvironment})?\.php!", $application, $route);
}
else
{
$route = preg_replace("/$currentApplication/", $application, $route);
}
return $route;
}
This allows me to create a URL for any application simply by toggling the context. The big problem I'm having is when creating absolute URLs in a symfony task.
When creating a route in a task I am getting the following:
http://./symfony/symfony/omg-news/omg-news-channel/test002.html
My assumption is that symfony is trying to guess the domain name from the referrer, which when using symfony tasks is non-existent.
The URL is supposed to look like this:
http://trunk.dev/frontend_dev.php/omg-news/omg-news-channel/test002.html
Has anyone been able to create a route which represents an absolute URL from a symfony task? If so have you also encountered this problem, how did you manage to overcome it?

The documentation answers this question. It's enough to edit the factories.yml configuration file:
all:
routing:
class: sfPatternRouting
param:
generate_shortest_url: true
extra_parameters_as_query_string: true
context:
host: example.org

See this similar question where I posted the following answer:
/**
* Gets routing with the host url set to the url of the production server
* #return sfPatternRouting
*/
protected function getProductionRouting()
{
$routing = $this->getRouting();
$routingOptions = $routing->getOptions();
$routingOptions['context']['host'] = 'www.example.com';
$routing->initialize($this->dispatcher, $routing->getCache(), $routingOptions);
return $routing;
}
This method is added to our base task class where we add other common project specific task methods.

Look like you can also trick the Routing only in your task:
sfConfig::set('sf_factory_request_parameters', array('relative_url_root' => "", 'no_script_name' => true));
sfContext::createInstance($this->configuration);
This way you do not have to alter your main config.

Related

Vapor Signed Storage URL 401 with Nova

I'm trying to get file uploads to work in my Laravel Nova on a Vapor server.
When I try to upload, it keeps showing me a 401 response on /vapor/signed-storage-url.
What am I missing?
This is my Nova Resource:
public function fields(Request $request)
{
return [
VaporFile::make('Attachment')->rules('bail', 'required', function ($attribute, $value, $fail) use ($request) {
if (Storage::size($request->input('vaporFile')[$attribute]['key']) > 1000000) {
return $fail('The document size may not be greater than 1 MB');
}
}),
This is added to my app.js:
window.Vapor = require("laravel-vapor");
This is my registered policy:
class UserPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can upload files.
*
* #param \App\User $user
* #return mixed
*/
public function uploadFiles(User $user)
{
return true;
}
Looks to me I've done everything correctly.. but it still fails.

How to modify an URL in a view in CakePHP 2.x

It seems quite simple but there is something I am not able to figure out. I hope someone can help me fast.
I have an url, something like http://host/controller/action/argument/named:1/?query1=1. I want to add another query param to look it like http://host/controller/action/argument1/argument2/named:1/?query1=1&query2=2. I fact I want to add query2=2 to all URLs on a particular page, through some callback or something.
An URL may or may not have query params in the existing page URL.
How do I do it?
Example url : http://www.example.com/myController/myAction/param1:val1/param2:val2
You can use :
$this->redirect(array("controller" => "myController",
"action" => "myAction",
"param1" => "val1",
"param2" => "val2",
$data_can_be_passed_here),
$status,
$exit);
Hope it helps you.
May be I am thinking too much of it but here is how it came out. I put it in a UtilityHelper.
function urlmodify($params = array(), $baseurl = true) {
$top_level_1 = array('plugin', 'controller', 'action'); //top level vars
$top_level_2 = array('pass', 'named'); //top level vars
//for integrated use
$top_level = array_merge($top_level_1, $top_level_2);
$urlparams = array();
//get top level vars
foreach($top_level as $k) {
if(in_array($k, $top_level_1)) {
$urlparams[$k] = $this->request->params[$k];
}
if(in_array($k, $top_level_2)) {
$$k = $this->request->params[$k]; //create $pass & $named
}
}
//get query vars
if($this->request->query) {
$urlparams['?'] = $this->request->query;
}
//check for custom pass vars
if(isset($params['pass'])) {
$pass = array_merge($pass, $params['pass']);
}
//pass var has to be in numarical index
foreach($pass as $v) {
array_push($urlparams, $v);
}
//check for custom named vars
if(isset($params['named'])) {
$named = array_merge($named, $params['named']);
}
//pass var has to be in key=>value pair
foreach($named as $k=>$v) {
$urlparams[$k] = $v;
}
//check for custom query vars
if(isset($params['?'])) {
$urlparams['?'] = array_merge($urlparams['?'], $params['?']);
}
return Router::url($urlparams, $baseurl);
}
}
I have an URL: http://localhost/project/exlplugin/logs/manage_columns/1/a:1/n:1/?b=1. On some links I want to add some certain parameters. Here is the result when i call
echo $this->Utility->urlmodify(array('pass'=>array(2), 'named'=>array('m'=>2), '?'=>array('c'=>2)));*
It gives: http://localhost/thecontrolist/spreadsheet/logs/manage_columns/1/2/a:1/n:1/m:2?b=1&c=2
I just wanted to add just a query parameter to all my listing urls deleted=0 or deleted=1 for the SoftDelete thing :)
Thank you #u2460470 for the answer but it's just about modifying (not removing or creating anything but just adding some params to) current URL on a view page.

Yii. Checking url before redirecting to prevent attack

I have $returnUrl var from Form with controller/action in it:
<?=CHtml::hiddenField('returnUrl',
Yii::app()->urlManager->parseUrl(Yii::app()->request)
);?>
In controller i have something like this:
$returnUrl = Yii::app()->request->getPost('returnUrl');
$returnUrl = array($returnUrl);
$this->redirect($returnUrl);
But it also work then i change $returnUrl from controller/action to external site url. Ex: if i put http://google.com to $_POST['returnUrl'] instead of site/index yii redirect me to /http://google.com without any errors.
What is the best way to check $returnUrl before redirecting? How i can compare $returnUrl with my routes or controllers/actions?
Now i do next:
$returnUrl = Utils::sanitizeReturnUrl($returnUrl);
...
class Utils
{
public static function sanitizeReturnUrl($returnUrl)
{
if (!preg_match('~^([-a-z0-9_]+|[-a-z0-9_]+/[-a-z0-9_]+)+$~i', $returnUrl))
{
$returnUrl = Yii::app()->homeUrl;
}
return $returnUrl;
}
}
But may be exists more appropriate way
The proper way is to parse your returnUrl and remove the scheme (http:// or https://) and other insecure stuff.
<?php
$returnUrl = 'http://username:password#hostname/path?arg=value#anchor';
$returnUrl = sanitizeReturnUrl($returnUrl);
echo $returnUrl;
/**
* now you got:
* hostname/path?arg=value#anchor
*/
function sanitizeReturnUrl ($url)
{
$urlArray = parse_url($url);
$url = $urlArray['host'] . $urlArray['path'] . '?' . $urlArray['query'] . '#' . $urlArray['fragment'];
return $url;
}

Logic block in Grails URLMappings

My site has urls like 'http://someRandomUsername.mysite.com'.
Sometimes users will try urls like
'http://www.someRandomeUsername.mysite.com'. I'd like to have some
logic in my url mappings to deal with this.
With the mappings below when I hit the page , with or without the
unneeded www, I get:
2012-03-01 14:52:16,014 [http-8080-5] ERROR [localhost].[/ambit] -
Unhandled exception occurred whilst decorating page
java.lang.IllegalArgumentException: URL mapping must either provide a
controller or view name to map to!
Any idea how to accomplish this? The mapping is below.
Thanks!
Jason
static mappings = {
name publicMap: "/$action?/$id?" {
def ret = UrlMappings.check(request)
controller = ret.controller
userName = ret.userName
}
}
static check =
{ request ->
def tokens = request?.serverName?.split(/\./) as List ?: []
def ret = [controller:'info']
if(tokens.size() > 3 && token[0] == 'www')
{
ret.userName = tokens[1]
ret.controller = 'redirect'
ret.action = 'removeWWW'
}
else if(tokens.size() == 3)
{
ret.userName = tokens[0]
ret.controller = 'info'
}
return ret
}
Honestly, like DmitryB said, the best way to do this is via the web server, whether it's IIS, Apache, or Tomcat.
Having said that, I feel the best way to accomplish this in Grails would be using filters.
You could create something like this in your ~/conf directory:
public class StripFilters {
def filters = {
stripWWWFilter(controller: '*', action: '*') {
before = {
def tokens = request.serverName.tokenize(/\./) ?: []
if(tokens.size() > 3 && tokens[0] == 'www') {
def url = request.request.requestURL.toString().replace('www.', '')
redirect([url:url, params: [userName: tokens[1]], permanent: true])
return false
}
}
}
}
}
This should do the trick.

Automatic language detection by browser

How can I detect the language of the browser and automatically display the correctly localized version of my grails website depending on that value.
I put this in to Index action
Locale locale = new Locale(params.lang)
cookieLocaleResolver.setLocale(request, response, (Locale)
session.getAttribute('locale'))
{
render controller: "home", action: "index"
return
}
And I got exception--
Error 500: Executing action [index] of controller [socialworking.HomeController] caused exception: null
Servlet: grails
URI: /socialworking/grails/home.dispatch
Exception Message:
Caused by:
Class: Unknown
First off, you should put that in a filter in grails-app/conf directory. Create a filter if you don't already have one.
MyFilters.groovy
class MyFilters {
def filters = {
setLocale(controller:'*', action:'*') {
before = {
// Your logic here
}
}
}
}
Your logic here could look in many ways, but here is a try:
String langToSet = 'en';
if ( params.lang && params.lang in validLanguages )
langToSet = params.lang;
else if ( session.lang ) {
langToSet = session.lang;
}
else if ( ... ) // Cookie lang is set ( User might have accessed the site before and you have stored their preferred lang )
// Get cookie lang
Locale locale = new Locale( langToUse)
org.springframework.web.servlet.support.RequestContextUtils.getLocaleResolver(request).setLocale(request, response, locale);
// Set the cookie lang
...
// We set the session lang
session.lang = langToSet
Note that the above is not a complete implementation but it is almost. The cookie stuff and validLanguages you should be able to figure out what they do.
I hope that helps!

Resources