I'm working Cake 2.1.3, and the routes.php file, everything worked fine except the login management, for example I want my url be as follows:
http://mysite.com/companyx/users/login
where companyx is the slug, however when you run that url in the browser is as follows:
http://mysite.com/users/login
In this file routes.php I have defined as follows:
Router::connect(
'/:slug/users/login', // E.g. /companyx/users/login
array('controller' => 'users', 'action' => 'login'), array(
// order matters
'pass' => array('slug')
)
);
With other controllers I have no problems such as:
Router::connect(
'/:slug/users', // E.g. /companyx/users
array('controller' => 'users', 'action' => 'index'), array(
// order matters
'pass' => array('slug')
)
);
Best Regards ;)
CakePHP has a default login action defined in the AuthComponent. (line 171)
/**
* A URL (defined as a string or array) to the controller action that handles
* logins. Defaults to `/users/login`
*
* #var mixed
*/
public $loginAction = array(
'controller' => 'users',
'action' => 'login',
'plugin' => null
);
You can override this action with the beforeFilter in your own UsersController.
thanks for you answer. I solved this case this way:
public function beforeFilter() {
parent::beforeFilter();
if (!$this->request->is('post')) {
$this->Auth->loginAction = 'this is:slug/users/login/';
}
}
Where "this is slug", should be the slug.
Best Regards.
Related
I want to write new route for RSS-View. The call /news/index.rss must open the RSS-Feed, but it open wrong methode.
routes.php
Router::parseExtensions('rss');
...
// don't work
Router::connect('/news/index.rss', array('controller' => 'news', 'action' => 'index'));
...
// open News:indexForPage()
Router::connect('/news/indexForPage/*', array('controller' => 'news', 'action' => 'indexForPage'));
...
// List width pagignation (News:index())
Router::connect('/news/*/:slug/:page',
array(
'controller' => 'news',
'action' => 'index'
),
array(
'competence_id'=>'[a-z,0-9,A-Z,\-]+',
'page'=>'[a-z,0-9,A-Z,\-]+'
)
);
...
// After call '/news/{Title-of-the-Article}-{ID}', it open News:view(ID)
Router::connect('/news/**', array('controller' => 'news', 'action' => 'view'));
That are all rules width "/news".
And wenn I call in browser "localhost/news/index.rss", it open News:view(), but not News:index(). If I deactivate the last line, it works, but I need this line.
How can I correct it?
You need to add 'ext' => 'rss' to your route as you are using Router::parseExtensions('rss');:-
Router::connect(
'/news/index.rss',
array('controller' => 'news', 'action' => 'index', 'ext' => 'rss')
);
I accepted the answer from drmonkeyninja quickly and not tested all functions.
I'm pleased width actually functions, but it is not perfect.
What I want, what I have, and what works:
localhost/news/index.rss – It opens RSS-Feed. It works.
localhost/news/, localhost/news/index – It opens all news sorted by publish date width pagignation (AJAX). It works.
localhost/news/{CATEGORY-ID} – It must open news filtered by CATEGORY-ID (integer) sorted by publish date width pagignation (AJAX). It don't work. (It opens localhost/news/view/{NEWS-ID}, see next point.) But it is not important, see "my alternative solution".
localhost/news/{NEWS-TITLE}-{NEWS-ID}, localhost/news/view/{NEWS-ID} – It opens the content of the one news width id={NEWS-ID}. It works. Where {NEWS-TITLE} is string (characters, numbers and '-'), and {NEWS-ID} is integer.
My code:
routes.php
// RSS-Feed. See point 1.
Router::connect('/news/index.rss', array('controller' => 'news', 'action' => 'index', 'ext' => 'rss'));
// See point 2. localhost/news/index
Router::connect('/news/index', array('controller' => 'news', 'action' => 'index'));
// It is for other methode. It works, and it isn't interesting.
Router::connect('/news/indexForPage/*', array('controller' => 'news', 'action' => 'indexForPage'));
// It is easy. localhost/news/view/{NEWS-ID} See point 4.
Router::connect('/news/view/*', array('controller' => 'news', 'action' => 'view'));
// localhost/news/{NEWS-TITLE}-{NEWS-ID} See point 4.
Router::connect('/news/*', array('controller' => 'news', 'action' => 'view'));
// My alternative solution for point 3. (e.g. localhost/breaking-news/3 It works fine with filter and AJAX-pagignation.)
Router::connect('/breaking-news/*/:slug/:page',
array(
'controller' => 'news',
'action' => 'index'
),
array(
'competence_id'=>'[0-9]+',
'page'=>'[a-z,0-9,A-Z,\-]+'
)
);
NewsController.php
class NewsController extends AppController {
public $helpers = array('Paginator');
public $components = array('RequestHandler', 'Paginator');
/**
* See points 1-3.
* #param string $competence_id
*/
public function index($competence_id = NULL) {...}
/**
* It isn't interesting.
* #param int $count
* #param int $sector
*/
public function indexForPage($count = NULL, $sector = NULL) {...}
/**
* See point 4.
* #param string $id
*/
public function view($id = NULL) {...}
}
Points for betterment are welcome:
New rooles in routes.php for cases localhost/news/{integer} (point 3) and localhost/news/{string}-{integer} (point 4)
Alternative solutions
I just started learning about the Auth component and I'm having a problem with redirection. The path of my local aplication is: localhost/school but when a logged user tries to acces to a url he isnt't allowed the site redirects to localhost/school/school and it says "The requested address '/school/school/' was not found on this server". I want no redirection when this happens, just show "you are not allowed" in the same page or maybe redirect to specific error page, how can I do that?. I have no problems with login or logout redirection, only what I said before. This is my App Controller:
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
'Session'
);
public $helpers = array('Html', 'Form', 'Session');
public function beforeFilter() {
//Configure AuthComponent
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->logoutRedirect = array(
'controller' => 'users',
'action' => 'login'
);
$this->set('current_user',$this->Auth->User());
$this->Auth->authError = "You're not allowed.";
}
I had the same problem and I solved it.
Try this code in AppController
public function beforeFilter() {
//Configure AuthComponent
// note just these two lines
$this->Auth->unauthorizedRedirect=FALSE ;
$this->Auth->authError="Access Denied";
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->logoutRedirect = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->loginRedirect = array(
'controller' => 'posts',
'action' => 'add'
);
$this->Auth->allow('display');
//$this->Auth->allow();
}
class AppController extends Controller {
// added the debug toolkit
// sessions support
// authorization for login and logut redirect
public $components = array(
'Session','Flash',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login'),
'authError' => 'You must be logged in to view this page.',
'loginError' => 'Invalid Username or Password entered, please try again.'
));
// only allow the login controllers only
public function beforeFilter() {
$this->Auth->allow('login');
}
public function isAuthorized($user) {
// Here is where we should verify the role and give access based on role
return true;
}
}
and in your controller it should be like this :
class UsersController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('login','add');
}
public function login() {
//if already logged-in, redirect
if($this->Session->check('Auth.User')){
$this->redirect(array('action' => 'index'));
}
// if we get the post information, try to authenticate
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->Flash->set(__('Welcome, '. $this->Auth->user('username')));
$this->redirect($this->Auth->redirectUrl());
} else {
$this->Flash->set(__('Invalid username or password'));
}
}
}
If you're not allowing someone access to a page, then what do you want the controller to do when they request it?
For example, you can set a redirect with :
$this->redirect(array(
'controller'=>'users',
'action' => 'login'));`
You can display a message using Session::setFlash();
localhost/projectName/projectName is a redirection when you don't have permission to this action. I had same problem. I comment for a moment 'Actions' => array('actionPath' => 'controllers') ) in $components. After that I set aros_acos by executing this code:
$group = $this->User->Group->read(null,'1');
$this->Acl->allow($group, 'controllers/Users/controlPanel');
After that I uncomment code, and in action 'controlPanel' and error disappear :) I don't know how I can change this redirection, but if I have record in aros_acos everything works.
What im trying to do here is maintain the variable 42 all throughout all pagination urls. I want my url to change from this
/exams/take/42/page:2
to this
/exams/take/42/items/2
Again,the number 42 is the variable..and the number 2 is the page number..Thanks.
UPDATE :
routes.php
Router::connect('/examinations/take/:id/page/:page',
array('controller' => 'examinations', 'action' => 'take'),
array(
'pass' => array('id', 'page'),
'id' => '[0-9]+',
'page' => '[0-9]+'
)
);
in the view/take
$this->Paginator->options(array('url' => $this->passedArgs));
AppController.php
public function beforeFilter(){
if (isset($this->request->params['page'])) {
$this->request->params['named']['page'] = $this->request->params['page'];
}
}
ive tried this ..but the generated url is the same,/examinations/take/42/page:2 ,when i click the next and prev links..
You've to define custom routes:
http://book.cakephp.org/2.0/en/development/routing.html
Example as below:
Router::connect(
'/exams/take/:id/items/:number',
array('controller' => 'exams', 'action' => 'take'),
array('pass' => array('id', 'number'))
);
Also you can get more information from below url try this:
http://www.sakic.net/blog/changing-cakephp-pagination-urls
yes you can do it with the use of custom routing. for more undrestanding you can see cakephp manual to manage custom routing in pagination
http://book.cakephp.org/2.0/en/development/routing.html
below will be your
e.g.
And by adding this route:
Router::connect('/:id/page/:page',
array('controller' => 'examinations', 'action' => 'take'),
array(
'pass' => array('id', 'page'),
'id' => '[0-9]+',
'page' => '[0-9]+'
)
);
and i does not work you can refer link
I'm using different routing tables for every language, and I have wrote action which change language and redirects to the same page but in target language (and target url).
The main problem is that my action is way too complicated - how can I make it simple?
It should change language and redirect to new url (in target language).
In short: We had random valid cake url in one language and we had to translate it to adequate url in another language.
My routing table:
if( 'en' == Configure::read('Config.language') ) {
Router::connect('/help', array('controller' => 'pages', 'action' => 'display', 'help') );
} else {
Router::connect('/pomoc', array('controller' => 'pages', 'action' => 'display', 'help') );
}
Action changing language:
function lang($lang) {
// getting previous url table
$url = $this->referer();
$url = Router::parse($url);
// changing language
if( in_array($lang, Configure::read('Languages.valid') ) ) {
$this->Session->write('Language', $lang);
Configure::write('Config.language', $lang);
}
// saving base params
$requestInfo = array(Router::getParams(), Router::getPaths());
// reload routing table
Router::reload();
include(CONFIGS.'routes.php');
// restore base params
Router::setRequestInfo($requestInfo);
// fix for 'pass' params
if(!empty($url['pass']) && is_array($url['pass'])) {
$url = array_merge($url, $url['pass']);
unset($url['pass']);
}
$this->redirect($url);
}
About 'pass' key in url table:
/pages/display/help
after Router::parse(), parameter is extracted:
pass => array(
0 => 'help'
)
and later return value from Router::url() look like that:
/pages/display/pass:Array
so I have to fix it by merging 'pass' value with whole array and removing key
I have my routes.php like this
Configure::write('Config.language', $_SESSION['lang']);
Router::connect(__('/help',true), array('controller' => 'pages', 'action' => 'display', 'help') );
so I use the __() to translate the url. It seaches the translation in the po files. And in your lang() function, after changing the Session to the current lang, all you need to do is:
$this->redirect(__('/help'));
Hope this helps
I know it is too late to answer that, but for those who experience the similar needs:
In routes.php p1 identifies the static page (same for all languages), could be any string that uniquely identifies the page.
Router::connect('/:language/p1/:translation', array(
'controller' => 'pages',
'action' => 'display',
'help',
'options' => array('language' => '[a-zA-Z]{2}')
) );
In your view
$this->Html->link('Click me', array(
'language' => Configure::read('Config.language'),
'controller' => 'pages',
'action' => 'display',
'help',
'translation' => __('help') // could be any string in fact
));
will generate link to /en/p1/help in English, else to /xx/p1/pomoc.
Injection of language parameter into every link could be done in AppHelper::url() instead of providing it in every link occurence.
If you want to redirect in controller:
$this->redirect(array(
'language' => Configure::read('Config.language'),
'controller' => 'pages',
'action' => 'display',
'help',
'translation' => __('help')
));
My localization files (.po) work if I change the default language, but I can't make the routes working, here's what I've got atm:
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/login/*', array('controller' => 'users', 'action' => 'login'));
Router::connect('/logout/*', array('controller' => 'users', 'action' => 'logout'));
Router::connect('/register/*', array('controller' => 'users', 'action' => 'register'));
Router::connect('/:lang/:controller/:action/*', array('lang' => 'en'), array('lang' => 'en|fr'));
But when I try : domain.com/fr/login, the cake is looking for the "fr" controller.
I am using this function in the AppController beforeFilter to switch between languages:
function setLanguage() {
if(!isset($this->params['lang']))
{
$this->params['lang'] = 'en';
}
$lang = $this->params['lang'];
App::import('Core', 'i18n');
$I18n =& I18n::getInstance();
$I18n->l10n->get($lang);
foreach (Configure::read('Config.languages') as $lang => $locale)
{
if($lang == $this->params['lang'])
{
$this->params['locale'] = $locale['locale'];
}
}
}
Cheers,
Nicolas.
You do not have a login controller. So your bottom route does not match and Cake then tries the default by looking for an fr controller.
Routes don't interact as you expect them to:
/login - would match your second route
/fr/users/login - would match your last route.
/fr/login - does NOT intelligently "merge" the two routes. You need to explicitly make such a route.