Does $this->Html->url() generate RESTful URL? - web-services

I use CakePHP 2.4.6.
In routes.php, I put
Router::mapResources('themes');
Then, I can access 'localhost/themes/211' which display screen generated by the action "view" of the controller "themes" just as I expect.
BUt in a view file, I use
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>
Then this generate '/themes/view/211' in html, where I expected '/themes/211'.
Does $this->Html->url() generate RESTful URL?
If not, How can Cake view file generate RESTful URL in other way?
Do I do any mistake?
Thanks in advance.

leave the action blank
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => '',
$theme['Theme']['id']));
?>
Or,
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' =>$theme['Theme']['id']
));
?>

If you want this to happen, go to your \app\Config\routes.php and add Router::connect('/themes', array('controller' => 'themes', 'action' => 'view'));
You don't have to change
<?php
echo $this->Html->url(array(
'controller' => 'themes',
'action' => 'view',
$theme['Theme']['id']));
?>

You probably have some more Restfull api calls to define, so maybe something more generic:
Router::connect('/api/:controller', array('api' => true, 'action' => 'index', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller', array('api' => true, 'action' => 'add', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'view', "[method]" => "GET"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
Router::connect('/api/:controller/:id', array('api' => true, 'action' => 'edit', "[method]" => "POST"), array('pass' => array('id'), 'id' => '([0-9]+|me)'));
These route calls like "api/Themes/123" to the action index in the Themes controller, however, if you try and do a POST request it will route to the add action.

Related

ZF2 Segment Route doesn't match parent's constraint when using children

I created the following routes:
'relatorios' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/relatorios/:tipo',
'defaults' => array(
'controller' => 'Relatorios',
'action' => 'index',
'tipo' => 'normais',
),
'constraints' => array('tipo' => '(normais|administrativos)$',
),
'may_terminate' => true,
'child_routes' => array(
'view' => array(
'type' => 'Zend\Mvc\Router\Http\Segment',
'options' => array(
'route' => '/view/:id_relatorio',
'defaults' => array('action' => 'view'),
'constraints' => array('id_relatorio' => '[0-9]+'),
),
),
),
);
This is supposed to match the following routes:
/relatorios/normais //matches
/relatorios/administrativos //matches
/relatorios/normais/view/1 //doesn't match
/relatorios/administrativos/view/1 //doesn't match
So basically the :tipo parameter must be either normais or administrativos and there is a child /view/any_digits.
When the parent route is called it matches, when the child view is called it doesn't match because of my tipo constraint. Why is that?
As per my comment, the $ on the constraint means 'end of the string' (which in this case is the URL path), so it shouldn't be there.

Zend Framework 2 child regex and literal routing

Based on this stackoverflow question 15077075 i have accomplished that my application has a regex based route so i can pass this to my view and edit action.
app/123 - app controller view action (get by article id)
app/name-of-article - app controller view action (get by article name)
app/123/edit - app controller edit action (article id)
app/name-of-article/edit - app controller edit action (article name)
app/search/{search-string} - app controler search action (currently only accepts a searchstring without spaces and special characters)
This i have accomplished with the code below and is similar to the code in the link above:
'app' => array(
'type' => 'literal',
'options' => array(
'route' => '/app',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
'priority' => -1000,
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
'priority' => -1000,
),
I have twoone issue
the first is that the url viewhelper doesn't recognize my routes
$controller = app
$action = recent
$this->url( $controller, array( 'action' => $action ) )
it just prints /app instead of /app/recent,
The same occurs when $action = 'search' or $action = 'new' it only prints /app
the second is that the search is recognized to its controller action only it fails when i put spaces or special characters in it
when i try to add \s in the constraints of the searchkey ( '[\sa-zA-Z0-9_-]+' ) it routes to the edit function
the route of search looks like this
Edited the route to this and it worked
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[a-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
),
),
),
i hope it's clear what i want if any code snippits are needed please ask
Sorted it out!
If one needs to get routes in his application this way you can use the code below
/App App/Index
/App/name-of-article App/View
/App/123 App/View
/App/name-of-article/edit App/Edit
/App/123/edit App/Edit
/App/recent App/Recent
/App/search App/Search
/App/new App/New
In my module.config.php i changed the route to:
'app' => array(
'type' => 'segment',
'options' => array(
'route' => '/app[/:action]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'index',
),
),
'may_terminate' => true,
),
'search' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/search',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'search',
),
),
'priority' => 1,
'may_terminate' => true,
'child_routes' => array(
'search' => array(
'type' => 'segment',
'options' => array(
'route' => '/[:searchkey]',
'constraints' => array(
'searchkey' => '[\sa-zA-Z0-9_\+-]+'
),
'defaults' => array(
'action' => 'search'
),
),
'priority' => 2,
'may_terminate' => true,
),
),
),
'new' => array(
'type' => 'literal',
'options' => array(
'route' => '/app/new',
'defaults' => array(
'controller' => 'App',
'action' => 'recent',
),
),
'priority' => 2,
),
'view' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'view',
),
'spec' => '/app/%view%',
),
),
'edit' => array(
'type' => 'regex',
'options' => array(
'regex' => '/app/(?<view>[a-zA-Z0-9_-]+)/(?<edit>[a-zA-Z0-9_-]+)',
'defaults' => array(
'controller' => 'App\Controller\App',
'action' => 'edit',
),
'spec' => '/app/%view%/%edit%',
),
),
If you need other routes you can just add a new literal route below te app route, make sure you don't forget to set the priority

Cakephp validating if my user checked at least one option

I have a problem validating if my user checked at least one option from a list of checkboxes.
Here is what i tried:
My view looks like this:
echo $this->Form->input('market_segment_targeted', array(
'multiple' => 'checkbox',
'label'=>array('text' => 'Market segment targeted', 'class'=>'w120'),
'options' => array(
'Home users' => 'Home users',
'SOHO' => 'SOHO',
'SMB' => 'SMB',
'Enterprise' => 'Enterprise'
),
));
In my controller i have added this snippet of code:
$validate_on_fly = array(
'market_segment_targeted' => array(
'notEmpty' => array(
'rule' => array('multiple', array('min' => 1)),
'required' => true,
'message' => 'Please select at least one!'
))
)));
$this->Partner->validate = Set::merge(
$this->Partner->validate,
$validate_on_fly
);
Any ideas what am i doing wrong?
Thank you
In CakePHP you can use Model Validation for checkboxes. Here is a quick example.
Your Form can look like:
$this->Form->create('User');
$this->Form->input('User.agree', array('type'=>'checkbox', 'hiddenField'=>false, 'value'=>'0'));
$this->Form->submit('Save'):
$this->Form->end();
Then in your Model under public $validate, use:
'agree'=>array(
'Not empty'=>array(
'rule'=>array('comparison', '!=', 0),
'required'=>true,
'message'=>'You must agree to the ToS'
)
)

Route_Regex in zend framework

My aim was to create common route for that cases:
http://test.com/pages/cat_name/about
http://test.com/pages/?????/about
http://test.com/pages/about
....
I've wrote in bootstrap:
$router->addRoute("pages",new Zend_Controller_Router_Route_Regex(
'pages/(\w+)/:stitle',
array( 'controller' => 'pages',
'action' => 'index',
'module' => 'pages')));
but it still doesnt work. whats wrong?
your code shoud be like this:
$router = Zend_Controller_Front::getInstance()->getRouter();
$route = new Zend_Controller_Router_Route(':interface/:module/:controller/:action/*',
array('interface' => 'en',
'module' => 'pages',
'controller' => 'pages',
'action' => 'index'));
$router->addRoute('route_name', $route);

cakephp route to not allow file extension

I need a cakephp route which will catch all urls if not matched in previous routes that do not contain file extensions.
Current route for catch all below
Router::connect('/*', array('controller' => 'frontend', 'action' => 'display',null));
I need the above route modified to not all urls with file extensions to be caught
What I have donr in my app based on CakePHP 1.2 to add extension to dynamic generated images is as follows:
Router::connect('/postImage/*', array('controller' => 'posts','action' => 'postImage', 'url' => array('ext' => 'png')));
The above code makes both the folloing url are accesible:
http://myhost.com/posts/postImage/125
and
http://myhost.com/posts/postImage/125.png
I think that the same will going with CakePHP 1.3 and I hope that It helps you.
I don't understand very well your demand, but you can do this:
Router::parseExtensions('html');
Router::connect('/*/:title', array('controller' => 'frontend', 'action' => 'display',null),
array(
'pass' => array('title')
)
);
And the link:
$html->link('Title', array('controller' => 'frontend', 'action' => 'display', 'title' => Inflector::slug('text to slug', '-'), 'ext' => 'html'))
I hope this will help you. good luck