![Smarty Forum Index Smarty Forum Index](templates/smarty/images/phpbb2_logo.gif) |
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
mitchenall Smarty Pro
![](images/avatars/55888307848c09187dbdd9.jpg)
Joined: 27 Feb 2004 Posts: 107 Location: London, UK
|
Posted: Fri Jan 14, 2005 9:46 pm Post subject: Modifier add_url_param |
|
|
I wrote this simple modifier today to get me out of a problem I had with setting parameters in URLs when I was getting the URL from {$smarty.server.REQUEST_URI}. It was very useful for me so I figured I'd post it for others.
[php:1:16484b570e]<?php
/**
* Smarty add_url_param modifier plugin
* ----------------------------------------
*
* This plugin adds parameters to existing URLs and is useful
* when you want to append or update a parameter without
* knowing anything about the contents of the existing
* URL.
*
* If any of the parameters passed to the modifier
* are already contained in the URL, their values
* are updated in the URL, rather than appending another
* parameter to the end.
*
* Examples:
*
* {$smarty.server.REQUEST_URI|add_url_param:'param=test¶m2=test2'}
* {$smarty.server.REQUEST_URI|add_url_param:$paramArray}
* {$smarty.server.REQUEST_URI|add_url_param:'variable':$value}
*
*
* @author Mark Mitchenall <mark@standingwave.co.uk>
* @copyright Standingwave Ltd, 2005
*
* @param $url string URL to add the parameters to
* @param $parameter mixed Assoc. Array with param names and
* values or string contain the
* additional parameter(s)
* @param $paramValue string (optional) Parameter value when
* $parameter contains just a
* parameter name.
* @return string
*/
function smarty_modifier_add_url_param($url, $parameter, $paramValue = NULL)
{
if ($paramValue !== NULL) {
// we were passed the parameter and value as
// separate plug-in parameters, so just apply
// them to the URL.
$url = _addURLParameter ($url, $parameter, $paramValue) ;
} elseif (is_array($parameter)) {
// we were passed an assoc. array containing
// parameter names and parameter values, so
// apply them all to the URL.
foreach ($parameter as $paramName => $paramValue) {
$url = _addURLParameter ($url, $paramName, $paramValue) ;
}
} else {
// was passed a string containing at least one parameter
// so parse out those passed and apply them separately
// to the URL.
$numParams = preg_match_all('/([^=?&]+?)=([^&]*)/', $parameter, $matches, PREG_SET_ORDER) ;
foreach ($matches as $match) {
$url = _addURLParameter ($url, $match[1], $match[2]) ;
}
}
return $url ;
}
function _addURLParameter ($url, $paramName, $paramValue) {
// first check whether the parameter is already
// defined in the URL so that we can just update
// the value if that's the case.
if (preg_match('/[?&]('.$paramName.')=[^&]*/', $url)) {
// parameter is already defined in the URL, so
// replace the parameter value, rather than
// append it to the end.
$url = preg_replace('/([?&]'.$paramName.')=[^&]*/', '$1='.$paramValue, $url) ;
} else {
// can simply append to the end of the URL, once
// we know whether this is the only parameter in
// there or not.
$url .= strpos($url, '?') ? '&' : '?';
$url .= $paramName . '=' . $paramValue;
}
return $url ;
}
?>[/php:1:16484b570e] _________________ Mark Mitchenall
Last edited by mitchenall on Sat Jan 29, 2005 11:39 am; edited 1 time in total |
|
Back to top |
|
soukupl Smarty n00b
Joined: 28 Jan 2005 Posts: 1
|
Posted: Fri Jan 28, 2005 10:26 pm Post subject: |
|
|
Hi,
very nice and useful modificator )
But, there is one problem. What if I need to unset variable in GET?
Example:
Code: | url is: index.php?action=read&id=17&page=18 |
and I need only one modification of url - REMOVE the action...
I have found only one way how to do it with your modifier:
Code: | {$smarty.server.REQUEST_URI|add_url_param:'action':''} |
But this will result in error (the empty url param will be duplicated in url each time it is set via your modifier
So i have ask some clever people on one forum, and here is the answer...
Just add this one line at the end of the script (before return $url;)
Code: | $url = preg_replace('/(\w+=&?)(?=(\w+=))|(&?\w+=)(?=(&\w+=)*$)|(\??\w+=&?)(?=(\w+=&?)*$)/', '', $url); |
This will filter all variables without value But, this is not the best way
So if you will have time, can you please consider adding feature to REMOVE some variable from the existing url (if it exists there)?
Thanks for the NICE modifier (it realy helps me).
Ladislav Soukup |
|
Back to top |
|
mohrt Administrator
Joined: 16 Apr 2003 Posts: 7368 Location: Lincoln Nebraska, USA
|
Posted: Fri Jan 28, 2005 10:35 pm Post subject: Re: Modifier add_url_param |
|
|
mitchenall wrote: |
[php:1:1ed449816d]if (preg_match('/\?/', $url))[/php:1:1ed449816d]
|
Just a programmers note, simple tests like these are more efficiently handled without regular expressions:
[php:1:1ed449816d]if(strpos($url, '?') !== false)[/php:1:1ed449816d]
This whole segment could be shortened up with:
[php:1:1ed449816d]
$url .= strpos($url, '?') ? '&' : '?';
$url .= $paramName . '=' . $paramValue;
[/php:1:1ed449816d] |
|
Back to top |
|
mitchenall Smarty Pro
![](images/avatars/55888307848c09187dbdd9.jpg)
Joined: 27 Feb 2004 Posts: 107 Location: London, UK
|
Posted: Sat Jan 29, 2005 11:36 am Post subject: Re: Modifier add_url_param |
|
|
mohrt wrote: |
This whole segment could be shortened up with:
[php:1:7b530d0727]
$url .= strpos($url, '?') ? '&' : '?';
$url .= $paramName . '=' . $paramValue;
[/php:1:7b530d0727] |
Yeah.... I'd thought that too... plus the cost of using a regex function instead of the simpler string functions for this type of test. Thanks for that. |
|
Back to top |
|
mitchenall Smarty Pro
![](images/avatars/55888307848c09187dbdd9.jpg)
Joined: 27 Feb 2004 Posts: 107 Location: London, UK
|
Posted: Sat Jan 29, 2005 11:44 am Post subject: |
|
|
soukupl wrote: | Hi,
very nice and useful modificator )
But, there is one problem. What if I need to unset variable in GET?
Example:
Code: | url is: index.php?action=read&id=17&page=18 |
and I need only one modification of url - REMOVE the action...
|
Thanks for the comments. I actually hadn't needed that, but I can see that it's useful. I haven't done something to remove the parameter, as that breaks the name of the plug-in. But instead I have made it so that you can make the value of the parameter an empty string.
soukupl wrote: |
I have found only one way how to do it with your modifier:
Code: | {$smarty.server.REQUEST_URI|add_url_param:'action':''} |
But this will result in error (the empty url param will be duplicated in url each time it is set via your modifier
So i have ask some clever people on one forum, and here is the answer...
Just add this one line at the end of the script (before return $url;)
Code: | $url = preg_replace('/(\w+=&?)(?=(\w+=))|(&?\w+=)(?=(&\w+=)*$)|(\??\w+=&?)(?=(\w+=&?)*$)/', '', $url); |
This will filter all variables without value But, this is not the best way
|
I'm not sure about that. I'll have to look at your regex after a lot of coffee. I have modified the regex's in the above code to handle empty values in parameters. Hopefully this will help a bit. Plus it will set an empty value to an existing parameter. It just doesn't remove them as I think there should be a differently named modifier for that, i.e. modifier_remove_url_param ![Wink](images/smiles/icon_wink.gif) |
|
Back to top |
|
barma3 Smarty Rookie
Joined: 12 May 2005 Posts: 5
|
Posted: Thu May 12, 2005 6:33 pm Post subject: |
|
|
Is it possible to remove PHPSESSID param from URL?
What you think about this solution:
Code: |
// if exist PHPSESSID cookie, remove PHPSESSID param
// from URL.
if (isset($_COOKIE['PHPSESSID'])) {
$url = preg_replace('/([?&]PHPSESSID=[^&]*)/', '', $url) ;
}
|
|
|
Back to top |
|
mitchenall Smarty Pro
![](images/avatars/55888307848c09187dbdd9.jpg)
Joined: 27 Feb 2004 Posts: 107 Location: London, UK
|
Posted: Thu May 19, 2005 3:36 am Post subject: |
|
|
barma3 wrote: | Is it possible to remove PHPSESSID param from URL?
What you think about this solution:
Code: |
// if exist PHPSESSID cookie, remove PHPSESSID param
// from URL.
if (isset($_COOKIE['PHPSESSID'])) {
$url = preg_replace('/([?&]PHPSESSID=[^&]*)/', '', $url) ;
}
|
|
Hey.. that could be a nice idea! .... strip the PHPSESSID from a URL if the template being output is cached, but it needs to be more generic than that so that it identifies the variable being used as the session ID, just in case it's been customised.
Still.... it sounds a little like it's beyond the scope of this modifier. If you want to remove parameters, I think there should be a modifier which explicitly states that.
Also, when it comes to stripping out PHPSESSID params, I think this would be better handed in a post-filter. Nice idea though.
Best,
Mark _________________ Mark Mitchenall |
|
Back to top |
|
stagnate Smarty n00b
Joined: 08 Feb 2005 Posts: 2
|
Posted: Mon May 30, 2005 3:45 am Post subject: strpos doesn't work for empty param string |
|
|
Note that if ? is the first character, your strpos function doesn't work as expected (0 evaluates as false but should be true). Works fine for a URL, but worth watching out for.
However, the code doesn't work for a URL with just ? at the end. Couple of ways to handle it but you can do whatever's elegant. strpos compared to length of string, perhaps. |
|
Back to top |
|
Lykurg Smarty Rookie
Joined: 18 Mar 2005 Posts: 8
|
Posted: Wed Jun 01, 2005 1:51 pm Post subject: |
|
|
Hi,
I have the same problem with adding parameters to my links in the templates, and your modifier is nice, but:
The real php-script decides wich parameters should be added, and so the parameter must be assignd first to the template, and then you must take care, that all links are modified.
Is it possible to write a outputfilter, which is using your modifier? I thougt the postfilter extracts all relative links and add a assigned parameter. (For forms maybe hidden-fields) Because then you don't have to care about all the links you are using in your templates.
The only problem is, how to assing a variable to an outputfilter?
Thought such kind of an outputfilter would be nice,
Lykurg |
|
Back to top |
|
mitchenall Smarty Pro
![](images/avatars/55888307848c09187dbdd9.jpg)
Joined: 27 Feb 2004 Posts: 107 Location: London, UK
|
Posted: Mon Jun 06, 2005 8:02 pm Post subject: |
|
|
Lykurg wrote: |
The only problem is, how to assing a variable to an outputfilter? |
The outputfilter gets the smarty instance in it's 2nd parameter, so you can just get the assigned variable from there, can't you? |
|
Back to top |
|
douglassdavis Smarty Junkie
Joined: 21 Jan 2008 Posts: 541
|
Posted: Wed Dec 04, 2013 4:11 pm Post subject: another version |
|
|
I made a different version of this (still smarty 2). Just in case it is useful, I decided to post it. Note that it can set and unset (by setting to null) parameters. It also handles parameters that are arrays. Example usage is:
Code: |
<a href="<{$url|add_url_param:'page=1&ajax=' }>"
...
|
Code: |
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
/**
* Smarty add_url_param modifier plugin.
*
* Will add the parameters in the query string given to the URL.
* If the URL already has these parameters, then they will be replaced.
*
* Type: modifier<br>
* Name: add_url_param<br>
* Purpose: Add a parameter to the end of a URL.
* @author Douglass Davis
* @param url A url
* @param add_query_string The parameter to add in the form of param=value
* @return The new url
*/
function smarty_modifier_add_url_param($url, $add_query_string)
{
// parse original URL
$parsed_url = parse_url($url);
$old_qs_parsed = array();
// parse query strings
parse_str($parsed_url['query'], $old_qs_parsed);
parse_str($add_query_string, $add_qs_parsed);
// replace old query string params with new
$new_qs_parsed = smarty_array_merge_recursive_simple($old_qs_parsed, $add_qs_parsed);
// remove empty params
foreach ($new_qs_parsed as $key => $value)
{
if ($value === null || $value === '')
unset($new_qs_parsed[$key]);
}
$parsed_url['query'] = http_build_query($new_qs_parsed);
// rebuild URL from parts
$new_url = '';
if ($parsed_url['scheme'])
{
$new_url .= $parsed_url['scheme'].'://';
}
if ($parsed_url['user'])
{
$new_url .= $parsed_url['user'];
if ($parsed_url['pass'])
{
$new_url .= ':'.$parsed_url['pass'];
}
$new_url .= '@';
}
if ($parsed_url['host'])
{
$new_url .= $parsed_url['host'];
}
if ($parsed_url['path'])
{
$new_url .= $parsed_url['path'];
}
if ($parsed_url['query'] || $parsed_url['fragment'])
{
$new_url .= '?';
}
if ($parsed_url['query'])
{
$new_url .= $parsed_url['query'];
}
if ($parsed_url['fragment'])
{
$new_url .= '#'.$parsed_url['fragment'];
}
return $new_url;
}
// array_merge handles numeric keys differently than string keys.
// For numeric keys it combines the values in the arrays.
// For string keys it replaces them.
//
// However, array_merge_recursive doesn't have that expected behavior.
//
// So, the following is a replacement for array_merge_recursive that
// acts more like array_merge.
//
// From comments in http://www.php.net/manual/en/function.array-merge-recursive.php
//
function smarty_array_merge_recursive_simple() {
if (func_num_args() < 2) {
trigger_error(__FUNCTION__ .' needs two or more array arguments', E_USER_WARNING);
return;
}
$arrays = func_get_args();
$merged = array();
while ($arrays) {
$array = array_shift($arrays);
if (!is_array($array)) {
trigger_error(__FUNCTION__ .' encountered a non array argument', E_USER_WARNING);
return;
}
if (!$array)
continue;
foreach ($array as $key => $value)
if (is_string($key))
if (is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key]))
$merged[$key] = call_user_func(__FUNCTION__, $merged[$key], $value);
else
$merged[$key] = $value;
else
$merged[] = $value;
}
return $merged;
}
|
|
|
Back to top |
|
osben Smarty n00b
Joined: 17 Aug 2014 Posts: 1
|
Posted: Sun Aug 17, 2014 9:23 pm Post subject: |
|
|
Code: | /**
* URL
*/
public function url($params = array())
{
$url = @parse_url($_SERVER["REQUEST_URI"]);
parse_str($url['query'], $query);
if(get_magic_quotes_gpc())
foreach($query as &$v)
{
if(!is_array($v))
$v = stripslashes(urldecode($v));
}
foreach($params as $name=>$value)
$query[$name] = $value;
$query_is_empty = true;
foreach($query as $name=>$value)
if($value!='' && $value!=null)
$query_is_empty = false;
if(!$query_is_empty)
$url['query'] = http_build_query($query);
else
$url['query'] = null;
$result = http_build_url(null, $url);
return $result;
} |
|
|
Back to top |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|