Zend route regex, optional parameters - php

I need some help about my routes in Zend (Zend1) ...
I need that I can use my route like that :
http://mywebsite.com/myfolder/region/job/
http://mywebsite.com/myfolder/region/job/add
http://mywebsite.com/myfolder/region/job/add/page
http://mywebsite.com/myfolder/region/job/page
Parameters add and page are optional ...
This is what I did
$route = new Zend_Controller_Router_Route_Regex(
'myfolder/([^/]+)/([^/]+)/?([^/]+)?/?([0-9]+)?',
array('controller' => 'myfolder','action' => 'search'),
array(1 => 'region',2 => 'job', 3 => 'add', 4 => 'page'),
'myfolder/%s/%s/%s/%s'
);
Obviously, it doesn't work ...
What I want? I want that last the two parameters (add and page) are optional ...
Can you help me? what's wrong with my regex?
EDIT 1:
Ok, so I tried it, but isn't ok ...
I need that parameters add and page are optional ...
$route = new Zend_Controller_Router_Route(
'myfolder/:region/:job/:add/:page',
array(
'controller' => 'myfolder',
'action' => 'search',
'region' => 'XX',
'job' => '',
'add' => '',
'page' => 1
),
array(
'region' => '[a-zA-Z-_0-9-]+',
'job' => '[a-zA-Z-_0-9-]+',
'add' => '[a-zA-Z-_]+',
'page' => '\d+'
)
);
With that, this one http://mywebsite.com/myfolder/region/job/page doesn't work ...
EDIT 2:
I also tried with 'myfolder/:region/:job/*', but the result is same, doesn't work as I want ...
I really wonder if it is possible ...
EDIT 3:##
$route = new Zend_Controller_Router_Route_Regex('myfolder/([^/]+)/([^/]+)(?:/|$)(?:(?!\d+(?:/|$))([^/]+)(?:/|$))?(?:(\d+)(?:/|$))?$',
array('controller' => 'myfolder', 'action' => 'recherche', 'presta' => ''),
array(1 => 'region',2 => 'job', 3 => 'presta', 4 => 'page'),
'myfolder/%s/%s/%s/%s');

Prepare yourself.
The RegEx
myfolder/([^/]+)/([^/]+)(?:/|$)(?:(?!\d+(?:/|$))([^/]+)(?:/|$))?(?:(\d+)(?:/|$))?$
See it working on RegExr (on RegExr, I had to add \n\r to one of the negated classes so it didn't match all my line breaks, in practice you probably won't be dealing with line breaks though.)
The important thing to note on RegExr is that in the 4th case, the page number is in the 4th capture group, with nothing in the 3rd group.
Explanation
myfolder/([^/]+)/([^/]+) All looking good up to here, no changes yet.
(?:/|$) Match a / or end of input.
Next, overall we have a non-capturing group that is optional. This would be the add section.
(?:(?!\d+(?:\|$))([^/]+)(?:/|$))?
Now lets break it down further:
(?!\d+(?:/|$)) Make sure its not a page number - digits only followed by / or end of input. (Negative lookahead)
([^/]+) Our capture group - add in the example.
(?:/|$) Match a / or end of input.
Now for our page number group, again it's optional and non-capturing:
(?:(\d+)(?:/|$))? Captures the numbers, then matches / or end of input again.
$ And just in case it tries to match substrings of actual matches, I threw in another end of input anchor (since you can match as many in a row as you like), although the regex functions without it.
Generating The Path
What you basically want is a way of doing this:
At the moment the 2nd and 3rd parameters are:
array(1 => 'region',2 => 'job', 3 => 'add', 4 => 'page'),
'myfolder/%s/%s/%s/%s'
You want them to be something like:
array(1 => 'region',2 => 'job', 3 => '/'+'add', 4 => '/'+'page'),
'myfolder/%s/%s%s%s'
Where you only add the / if the optional group is present. The code above won't work but perhaps there is some way you could implement that.

Related

RegEx - extend a given string while leaving the rest untouched

I have an associate array inside a PHP class method going like this:
// ...
$filters = [
self::FILTER_CREATION_DATE => "Base/*/Creation/Date.php",
self::FILTER_CREATION_DATE_BETWEEN => "Base/*/Creation/Date.php",
self::FILTER_CREATION_DATE_GREATER => "Base/*/Creation/Date.php",
self::FILTER_CREATION_DATE_GREATER_OR_EQUAL => "Base/*/Creation/Date.php",
self::FILTER_CREATION_DATE_LESS => "Base/*/Creation/Date.php",
self::FILTER_CREATION_DATE_LESS_OR_EQUAL => "Base/*/Creation/Date.php",
];
// ...
What I would like to do is to convert this string from:
self::FILTER_CREATION_DATE_BETWEEN => "Base/*/Creation/Date.php",
to this one:
self::FILTER_CREATION_DATE_BETWEEN => "Base/*/Creation/Date/Between.php",
I would like to use a RegEx to extend the string but leave the rest untouched. I need to do this because there's more than 120 constants defined ending with *_BETWEEN.
How can I do this?
In the Intellij editor or the free Notepad++, you can find and replace by regex.
I'm sure other IDE's have similar functionality
Find self::([_A-Z]+)_BETWEEN => "(.*)/Date.php"(,)*
Replace self::$1_BETWEEN => "$2/Date/Between.php"$3
The regex groups the variable components of your search together by wrapping it in ()
In the replace you can reference them in order by $1, $2, etc..

Yii routes and creation of URLs with multiple parameters

I would like to get the URL as follow:
http://domain.com/post/1/some-titles-here
But I'm getting:
http://domain.com/post/1?title=some-titles-here
I am using this config:
'urlFormat' => 'path',
...
//'post/<id:\d+>/<title>' => 'post/view/',
'post/<id:\d+>/<title:\w+>' => 'post/view/',
'post/<id:\d+>' => 'post/view/',
...
Then to get the URL I am executing:
Yii::app()->createAbsoluteUrl('post/view', array('id' => $this->id,'title' => $this->title));
im following the third rule here:
http://www.yiiframework.com/doc/guide/1.1/en/topics.url#using-named-parameters
The regular expression you're using to match the title is incorrect: <title:\w+> will only match single words but your title has hyphens as well.
Tuan is correct; it's matching the next rule. That's because the URL manager works its way down the rules until it finds one that matches.
Use this rule instead:
'post/<id:\d+>/<title:([A-Za-z0-9-]+)>' => 'post/view/',
That will match titles with letters, numbers, and hyphens.
This is a code that work for me:
'urlManager'=>array(
'urlFormat'=>'path',
'showScriptName' => false,
'rules'=>array(
'' => 'site/index',
'article/<id:\d+>/<alias:[-\w]+>' => 'article/view',
'article/cat/<id:\d+>-<alias:[-\w]+>' => 'category/view',
Result urls:
http://wowjp.black.dragon/article/2/test-zagolovka
http://wowjp.black.dragon/article/cat/3-345435

Zend pagination and routing

Having a bit of trouble getting my URLs to work properly.
The URL looks like this: /messages/from/1/page/5
My route looks like this
$router->addRoute('messages-from',
new Zend_Controller_Router_Route('messages/from/:user_id/:page', array(
'controller' => 'messages',
'action' => 'from',
'page' => 1
))
);
Which works fine. But the URL is missing the /page/ part. If I add it in:
'messages/from/:user_id/page/:page'
then it breaks and the user_id param is always null.
How can I fix this?
Thanks!
Since you want to be able to leave off the /page/ part from the URL, you would have to define two separate routes, one that matches the user ID and page parameters and one that only matches the user ID without the page so the router can find route matches in both cases.
Alternatively, this regex based route works in both cases.
$route = new Zend_Controller_Router_Route_Regex(
'messages/from/(\d+)(?:/page/(\d+)/?)?',
array(
'controller' => 'messages',
'action' => 'from',
'page' => 1,
),
array(
1 => 'from',
2 => 'page',
)
);
$router->addRoute('messages-from', $route);
Based on the URL you supplied, I assumed in the regex that the from parameter is an integer. If you can have strings passed, you will need to change the (\d+) pattern to something more suitable like ([\w\d_-\.]+).

Custom routes in CakePHP: regex not limiting matches

I'm trying to configure my custom routes in cakephp such that the url
/objects/id/action => ObjectsController.action() with params['id']=id
(This is so that I don't have to have urls like /objects/action/id which logically make less sense to me than objects/id/action).
I still want /objects/action to trigger ObjectsController.action() (e.g. for add, index, search).
My routes config looks like this:
Router::connect('/:controller/:id',
array('action'=>'view'),
array(
':id' => '^[0-9]+$'
)
);
Router::connect('/:controller/:id/:action/*',
array('action'=>'view'),
array(
':id' => '^[0-9]+$',
':action' => '[A-Za-z0-9_\-]*'
)
);
This works with (for example):
/objects/54
/objects/54/edit
/objects/add
But not with
/objects/index/page:2
For which it gives me the error that I need to define the action "page:2" in ObjectsController... Surely it should work, because :id should only match digits, no?
Try to remove ":" from second param:
'id' => '^[0-9]+$'
Also see 'pass' option.
#see google on "cakephp routes":
http://book.cakephp.org/view/945/Routes-Configuration

CakePHP Router::connect and regex

I'm having some trouble with redirection in config/routes.php file
I can't find the right regex
$_skill = '[A-Za-z\-]+'
Router::connect('/-:skill/:city-:zipcode:shit', array('controller' => 'redirects', 'action' => 'district'),
array('city' => '[A-Za-z-0-9\]+.(er|eme)-arrondissement',
'skill' => $_skill,
'zipcode' => $_zipcode,
'shit' => '(.*)',
'pass' => array('zipcode'),
)
);
I would like to match any url where city ends with 'arrondissement' but i'm a total noob in regex
thank you.
With most regex you can use the dollar symbol to match the end of a string.
simply 'arrondissement$'
And drop all the stuff at the beginning.

Categories