I want to use a different (plural) model name for my route names, because my url is in a different language.
I can Achieve it with Restful Naming Resource Routes
Route::resource('/foo', BarController::class)->parameters([
'foo' => 'bar',
])->names([
'index' => 'bar.index',
'create' => 'bar.create',
'store' => 'bar.store',
'show' => 'bar.show',
'edit' => 'bar.edit',
'update' => 'bar.update',
'destroy' => 'bar.destroy',
]);
But.. I would have to do it for every resource route:
Route::resource('/usuarios', UserController::class)->parameters([
'usuarios' => 'user',
])->names([
'index' => 'user.index',
'create' => 'user.create',
'store' => 'user.store',
'show' => 'user.show',
'edit' => 'user.edit',
'update' => 'user.update',
'destroy' => 'user.destroy',
]);
How could I make this DRY?
You can extract that part into a function.
function routeNames($model)
{
return array_map(
fn ($n) => "{$model}.{$n}",
['index', 'create', 'store', 'show', 'edit', 'update', 'destroy']
);
}
Route::resource('/usuarios', UserController::class)->parameters([
'usuarios' => 'user',
])->names(routeNames('user'));
Related
i got this method on my routes.php:
Route::resource('maintenance/templates', 'TemplateController', ['names' => createRouteNames('fleet.maintenance.templates')]);
But, i understand, this method break in laravel 5 so, How can i upgrade this method? I understand i need use Route::group( but, i don't know how.
This is one of the tries i did, but, it didn't work:
Route::group(['maintenance/templates' => 'TemplateController'], function(){
Route::resource('template/config', 'ConfigController',[
'only' => ['store', 'update', 'destroy'],
'names' => createRouteNames('fleet.template.config'),
]);
Route::controller('template', 'TemplateController', [
'getTemplates' => 'api.template',
'postService' => 'api.template.service',
]);
});
You don't need the group for the resource function. You can achieve it like this:
Route::resource('maintenance/templates', 'TemplateController', [
'only' => [
'store', 'update', 'destroy'
],
'names' => [
'store' => 'maintenance/templates.store',
'update' => 'maintenance/templates.update',
'destroy' => 'maintenance/templates.destroy',
]
]);
Or you can pass a callable that will return an associative array like the example above:
Route::resource('maintenance/templates', 'TemplateController', [
'only' => [
'store', 'update', 'destroy'
],
'names' => createRouteNames('fleet.maintenance.templates')
]);
I have a group of route that I apply auth Middleware.
How should I except the tournaments.show ????
I only found examples with $this->middleware syntax, but none with Route::group
Route::group(['middleware' => ['auth']],
function () {
Route::resource('tournaments', 'TournamentController', [
'names' => [
'index' => 'tournaments.index',
'show' => 'tournaments.show',
'create' => 'tournaments.create',
'edit' => 'tournaments.edit', 'store' => 'tournaments.store', 'update' => 'tournaments.update' ],
]);
});
You can except the show route from the resource() as:
Route::group(['middleware' => ['auth']],
function () {
Route::resource('tournaments', 'TournamentController',
[
'names' =>
['index' => 'tournaments.index',
'create' => 'tournaments.create',
'edit' => 'tournaments.edit',
'store' => 'tournaments.store',
'update' => 'tournaments.update'
],
'except' => ['show'],
]
);
});
And then define it outside the group as:
Route::get('tournaments/{id}', 'TournamentController#show')->name('tournaments.show');
I was trying to find a solution on-line (as always) but came up with nothing obviously.
I'm using CakePHP and I need to add some sorting into some controllers. I would also like to create custom routes for that. So here's my code that is not working (pagination works, sorting nope):
RatesController.php:
public $paginate = array(
'Rate' => array(
'limit' => 10,
'order' => array(
'Rate.created' => 'desc'
),
'conditions' => array( 'Rate.accepted' => 1 ),
//'fields' => array('Rate.*', 'User.username')
),
'Airline' => array(
'limit' => 50,
/*'order' => array(
'Airline.rate' => 'desc',
'Airline.name' => 'asc'
),*/
'conditions' => array(
'Airline.rate >' => 0
),
'fields' => array('Airline.id', 'Airline.name', 'Airline.image_id', 'Airline.rate', 'Image.*')
)
);
function index($category = 'airlines'){
pr($this->request);
$data = $this->paginate('Airline');
pr($data);
}
And in view:
$this->Paginator->options(array(
'url' => array(
'controller' => 'rates',
'action' => 'index',
'category' => $category
)
));
echo $this->Paginator->first('«', array('escape' => false), null, array('class' => 'disabled', 'escape' => false));
echo $this->Paginator->prev('<', array('escape' => false), null, array('class' => 'disabled', 'escape' => false));
echo $this->Paginator->numbers(array(
'modulus' => 6,
'separator' => false
));
echo $this->Paginator->next('>', array('escape' => false), null, array('class' => 'disabled', 'escape' => false));
echo $this->Paginator->last('»', array('escape' => false), null, array('class' => 'disabled', 'escape' => false));
echo' sort by ';
echo $this->Paginator->sort('Airline.rate');
echo' or by ';
echo $this->Paginator->sort('Airline.name');
Routes:
Router::connectNamed(array('page'), array('default' => false, 'greedy' => false));
Router::connectNamed(array('sort', 'direction'), array('default' => false, 'greedy' => false));
Router::connect('/rate-airlines', array('controller' => 'rates', 'action' => 'index', 'category' => 'airlines'));
/*
Router::connect(
'/rate-airlines/:page/',
array('controller' => 'rates', 'action' => 'index', 'category' => 'airlines'),
array(
'named' => array('page' => '[a-z]+')
)
);
Router::connect(
'/rate-airlines/:page/:sort/:direction',
array('controller' => 'rates', 'action' => 'index', 'category' => 'airlines'),
array(
'pass' => array('page', 'sort', 'direction'),
//'id' => '[0-9]+',
'named' => array('page' => '[\d]+', 'sort', 'direction')
)
);*/
Router::connect(
'/rate-airlines/:sort/:direction',
array('controller' => 'rates', 'action' => 'index', 'category' => 'airlines'),
array(
'named' => array('sort', 'direction')
)
);
I seriously have no idea why it's not working, I've already spent hours trying to make it work, seeking answers.
Ps. No matter what I did I couldn't manage to put :sort and :direction into named array in request:
CakeRequest Object
(
[params] => Array
(
[plugin] =>
[controller] => rates
[action] => index
[named] => Array
(
)
[pass] => Array
(
)
[sort] => Airline.rate
[direction] => asc
[category] => airlines
[isAjax] =>
)
...
)
Any ideas please?
Mike
You really shouldn’t use route parameters for sorting. It was such a bad idea that CakePHP have dropped them in the forth-coming 3.x release.
Instead, use query string parameters. That’s exactly what they’re for: manipulating a single view. If you have a list, pass parameters like ‘sort’ and ‘direction’ there.
Say you have a URL like http://example.com/rates/?sort=name&direction=asc, you can then parse it in your controller as follows:
<?php
class RatesController extends AppController {
public function index() {
$sort = isset($this->request->query['sort']) ? $this->request->query['sort'] : 'created';
$direction = isset($this->request->query['direction']) ? $this->request->query['direction'] : 'desc';
$this->Paginator->settings = array(
'order' => array($sort => $direction)
);
$rates = $this->paginate('Rate');
$this->set(compact('rates'));
}
}
I also like to go one step further and use query strings for pagination…
<?php
class AppController extends Controller {
public $paginate = array(
'paramType' => 'querystring'
);
}
…But that’s just personal preference.
The above was written during a long day. After thinking about it, CakePHP handles sorting in pagination out of the box. You don’t need to manually specify routes containing the name parameters.
So long as you use the Pagination component and Paginator helper (as you have done), and defined a single route for your controller action, you don’t need to do anything else. In your case, your controller would look like:
<?php
class RatesController extends AppController {
public function index() {
$rates = $this->paginate('Rate');
$this->set(compact('rates'));
}
}
And your view would look like:
<?php echo $this->Paginator->sort('Airline.name'); ?>
If you wanted to rewrite /rates to /rates-airlines, then your single route would look like this:
<?php
Router::connect('/rates-airlines', array(
'controller' => 'rates',
'action' => 'index',
));
With the above, the paginate call will take into account the column to sort by and the direction.
Sorry for the convoluted answer above!
thanks for your replies. The thing is that I really need custom routing for pagination, so I finally managed to achieve what I wanted using following code:
In AppController.php (note that all $this->request->query[...] variables were added just because I also wanted to use sorting interface via forms with GET method)
function beforeFilter() {
if (isset($this->request->params['page'])) {
$this->request->params['named']['page'] = $this->request->params['page'];
}elseif( isset($this->request->query['page']) ){
$this->request->params['named']['page'] = $this->request->query['page'];
}
if (isset($this->request->params['sort'])) {
$this->request->params['named']['sort'] = $this->request->params['sort'];
}elseif (isset($this->request->query['sort'])) {
$this->request->params['named']['sort'] = $this->request->query['sort'];
}
if (isset($this->request->params['direction'])) {
$this->request->params['named']['direction'] = $this->request->params['direction'];
}elseif (isset($this->request->query['direction'])) {
$this->request->params['named']['direction'] = $this->request->query['direction'];
}
in routes.php
Router::connect('/rates-airlines', array('controller' => 'rates', 'action' => 'index', 'airlines'));
Router::connect(
'/rates-airlines/:page',
array('controller' => 'rates', 'action' => 'index', 'airlines'),
array(
'named' => array('page' => '[\d]+')
)
);
Router::connect(
'/rates-airlines/:page/:sort/:direction',
array('controller' => 'rates', 'action' => 'index', 'airlines'),
array(
'named' => array('page' => '[\d]+', 'sort', 'direction')
)
);
Router::connect(
'/rates-airlines/:sort/:direction',
array('controller' => 'rates', 'action' => 'index', 'airlines'),
array(
'named' => array('sort', 'direction')
)
);
Hope someone will find this useful!
Mike
There is an easier way. Just add one more route with '/*':
Router::connect('/rates-airlines', array('controller' => 'rates', 'action' => 'index', 'airlines'));
Router::connect('/rates-airlines/*', array('controller' => 'rates', 'action' => 'index', 'airlines'));
And all will work correctly.
Could use some help. I have a drupal6 install that im having trouble with in terms of caching for authenticated users. Boost is handling the none authenticated caching very well. With my current setup, sessions cannot be created at all, when attempting to login the result is "You are not authorized to view this page". Memcache and apc are installed on the server and working according to phpinfo. Here is my current setup (without cacherouter):
include_once('./sites/all/modules/memcache/memcache.inc');
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['session_inc'] = './sites/all/modules/memcache/memcache-session.inc';
$conf['memcache_servers'] = array(
'127.0.0.1:11211' => 'default',
'127.0.0.1:11212' => 'block',
'127.0.0.1:11213' => 'content',
'127.0.0.1:11214' => 'filter',
'127.0.0.1:11215' => 'form',
'127.0.0.1:11216' => 'menu',
'127.0.0.1:11217' => 'page',
'127.0.0.1:11218' => 'update',
'127.0.0.1:11219' => 'views',
'127.0.0.1:11221' => 'session',
'127.0.0.1:11222' => 'users'
);
$conf['memcache_bins'] = array(
'cache' => 'default',
'cache_block' => 'block',
'cache_content' => 'content',
'cache_filter' => 'filter',
'cache_form' => 'form',
'cache_menu' => 'menu',
'cache_page' => 'page',
'cache_update' => 'update',
'cache_views' => 'views',
'session' => 'session',
'users' => 'users'
);
Before this setup, I was using cacherouter with authcache and had apc as the engine. Users could log in, but there was no actual caching happening for authenticated users. I have been reading everything I could find on this to get it going, doing various test and changing configurations, but without success. Here was the previous setup:
$conf['cacherouter'] = array(
'default' => array(
'engine' => 'apc',
'server' => array('127.0.0.1:11211'),
'shared' => TRUE,
'prefix' => '',
'path' => 'storage_bin/filecache',
'static' => FALSE
),
);
$conf['cache_inc'] = './sites/all/modules/authcache/authcache.inc';
$conf['memcache_servers'] = array(
'127.0.0.1:11211' => 'default',
'127.0.0.1:11212' => 'block',
'127.0.0.1:11213' => 'content',
'127.0.0.1:11214' => 'filter',
'127.0.0.1:11215' => 'form',
'127.0.0.1:11216' => 'menu',
'127.0.0.1:11217' => 'page',
'127.0.0.1:11218' => 'update',
'127.0.0.1:11219' => 'views'
);
$conf['memcache_bins'] = array(
'cache' => 'default',
'cache_block' => 'block',
'cache_content' => 'content',
'cache_filter' => 'filter',
'cache_form' => 'form',
'cache_menu' => 'menu',
'cache_page' => 'page',
'cache_update' => 'update',
'cache_views' => 'views'
);
The site is visible at www.thewildside.com. Any help on this would be greatly appreciated.
If anyone else runs into this, my solution was to ditch cacherouter (did not perform as expected), authcache(too beta), and boost (simply to avoid hitting apache at all for cached pages)… proceeding with Memcache API (the drupal module), memcache (the caching system), apc and varnish (3.0). Memcache API allows me to cache both to RAM via memcache and to the drupal db as backup in case memcache is not available (via memcache.db.inc). Benchmark to determine how much RAM to use for each cache component. I can also keep session info in memcache, but I have not noticed a great performance gain with this, so you may choose not to include memcache-session.inc. Create memcache instances for each drupal cache db (or use one default instance). Setup a cache bin for each instance you've created, and throw in reverse proxy settings and default ttl. Here is my whats in my setting.php file;
$conf = array(
'cache_inc' => './sites/all/modules/memcache/memcache.db.inc',
'memcache_key_prefix' => 'ws',
'session_inc' => './sites/all/modules/memcache/memcache-session.inc',
'memcache_servers' => array(
'unix:///var/run/memcached/memcached_wildside.sock' => 'default',
'unix:///var/run/memcached/memcached_wildside_apachesolr.sock' => 'apachesolr',
'unix:///var/run/memcached/memcached_wildside_block.sock' => 'block',
'unix:///var/run/memcached/memcached_wildside_content.sock' => 'content',
'unix:///var/run/memcached/memcached_wildside_filter.sock' => 'filter',
'unix:///var/run/memcached/memcached_wildside_form.sock' => 'form',
'unix:///var/run/memcached/memcached_wildside_media_youtube_status.sock' => 'media_youtube_status',
'unix:///var/run/memcached/memcached_wildside_menu.sock' => 'menu',
'unix:///var/run/memcached/memcached_wildside_objects.sock' => 'objects',
'unix:///var/run/memcached/memcached_wildside_page.sock' => 'page',
'unix:///var/run/memcached/memcached_wildside_path.sock' => 'path',
'unix:///var/run/memcached/memcached_wildside_rules.sock' => 'rules',
'unix:///var/run/memcached/memcached_wildside_update.sock' => 'update',
'unix:///var/run/memcached/memcached_wildside_views.sock' => 'views',
'unix:///var/run/memcached/memcached_wildside_views_data.sock' => 'views_data',
'unix:///var/run/memcached/memcached_wildside_session.sock' => 'session',
'unix:///var/run/memcached/memcached_wildside_users.sock' => 'users'),
'memcache_bins' => array(
'cache' => 'default',
'cache_apachesolr' => 'apachesolr',
'cache_block' => 'block',
'cache_content' => 'content',
'cache_filter' => 'filter',
'cache_form' => 'form',
'cache_media_youtube_status' => 'media_youtube_status',
'cache_menu' => 'menu',
'cache_objects' => 'objects',
'cache_page' => 'page',
'cache_path' => 'path',
'cache_rules' => 'rules',
'cache_update' => 'update',
'cache_views' => 'views',
'cache_views_data' => 'views_data',
'session' => 'session',
'users' => 'users'),
);
$conf['https'] = TRUE;
$conf['mimedetect_magic'] = '/usr/share/file/magic';
$conf['reverse_proxy'] = TRUE;
$conf['reverse_proxy_addresses'] = array('127.0.0.1');
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])){
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$_SERVER['HTTPS']='on';
}else{
$_SERVER['HTTPS']='';
}
}
/* 1 day cache lifetime = 86400 */
$conf['cache_lifetime'] = 86400;
$conf['page_cache_maximum_age'] = 86400;
When setting up Varnish's config file (.vcl), just be sure that the syntax you use corresponds to the version of varnish you have installed.
I am creating a multi lingual application using ZF2.. and cannot determine how to add a part URL which will form the base of each URL regardless of modules.
http://localhost/en/us/application/index/index/
I totally understand how to configure /[:namespace[/:controller[/:action]]] using DI
http://localhost/application/index/index/
http://localhost/guestbook/index/index/
http://localhost/forum/index/index/
What I do not understand is how to configure a Part route which will be the base for all routes.. In ZF1 I used Route Chaining to achieve this..
So I need to configure a Part route of /[:lang[/:locale]] which applies site wide and then let the module configure /[:namespace[/:controller[/:action]]] or any other route necessary..
http://localhost/en/us/application/index/index/
http://localhost/zh/cn/application/index/index/
http://localhost/en/uk/forum/index/index/
I think what you are looking for is the child_routes configuration key. Take a look at how ZfcUser configures it's routing (here): it creates a base Literal route (/user) and then chains the sub-routes (/user/login, etc) onto it via the child_routes array.
I think something like this will do the trick for you:
'router' => array(
'routes' => array(
'myapp' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:lang[/:locale]]',
'defaults' => array(
'lang' => 'en',
'locale' => 'us',
),
),
'may_terminate' => false,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '/[:controller[/:action]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
),
'defaults' => array(
'controller' => 'index',
'action' => 'index',
),
),
),
),
),
),
Then in your controller you could do this to get the lang and locale:
$this->params()->fromRoute('lang');
$this->params()->fromRoute('locale');