I am trying to pass the id of the person whosoever logs-in to my site. I am using Auth for login in cakephp. So can anyone tell me how to pass the value during the login and retrieve it at the home page? I am new to cakephp.
This is what I have tried.
app controller.php
class AppController extends Controller {
//...
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'members', 'action' => 'home',$member['Member']['id']),
'logoutRedirect' => array('controller' => 'members', 'action' => 'index')
)
);
MembersController.php
public function home($id = null) {
$this->Member->id = $id;
}
home.ctp
<div align='center'><h2>Hi user welcome to home page </h2></div>
<?php
//I am just trying to print the id of the logged in person
echo $this->Form->value('User.id');
?>
<?php
echo $this->Html->link('LogOut',array('controller'=>'users','action'=>'logout'));
?>
echo $this->Form->value('User.id');
Is part of the FormHelper.
If you would like to have your form prefilled, make use of the conventions. Simply create an input field like this:
echo $this->Form->input('User.id');
If the $this->request->data contains this value ($this->request->data['User']['id']) it will automatically fill your form.
In order to retrieve values from the AuthComponent You can simply do something like $userName= $this->Auth->user('name'); (Just make sure the column 'name' exists in your 'users` database).
In order to pass variables to your view, you can simply use the method set which is defined in the Controller, which is extended by the AppController which is extend by FooBarsController.
If you want to set this variable to your view (as mentioned earlier) use set.
$this->set('userName', $userName);
In your view you can now do:
printf('Welcome %s', $userName);
Blog tutorial to get your started
AuthComponent
FormHelper
How Views work
How Controllers work
How Models work
Related
Assume I'm in my items controller.
Ok say I am in my view action (the url would be something like /items/view/10012?date=2013-09-30) which lists a list of items that belongs to a client on a given date.
I want to link to add a new item. I would use the htmlhelper like so:
echo $this->Html('action'=>'add');
In my add action I have a form which has fields like client_id and item_date.
When I'm in my view action I know these values as I am viewing the items for a specific client on a specific date. I want to pass these variables to my add action so it will prefill those fields on the form.
If I add a query string in my link ('?' => array('client_id'=>$client_id)) it breaks the add action as it will give an error if the request is not POST. If I use a form->postLink I get another error as the add action's POST data must only be used for adding the record, not passing data to prefill the form.
I basically want to make my link on the view page pass those 2 variables to the add action in the controller so I can define some variables to prefill the form. Is there a way to do this?
Here is my add controller code. It may differ in content a bit from my question above as I have tried to simplify the question a bit but the concept should still apply.
public function add(){
if ($this->request->is('post')) {
$this->Holding->create();
if ($this->Holding->save($this->request->data)) {
$this->Session->setFlash(__('Holding has been saved.'), 'default', array('class' => 'alert alert-success'));
return $this->redirect(array('action' => 'index'));
}
$this->Session->setFlash(__('Unable to add your holding.'), 'default', array('class' => 'alert alert-danger'));
}
$this->set('accounts', $this->Holding->Account->find('list'));
$sedol_list = $this->Holding->Sedol->find('all', array(
'fields' => array(
'id', 'sedol_description'
),
'recursive' => 0,
'order' => 'description'
)
);
$this->set('sedols', Hash::combine($sedol_list, '{n}.Sedol.id', '{n}.Sedol.sedol_description') );
}
Why not use proper Cake URL parameters?
echo $this->Html->link('Add Item', array(
'action' => 'add',
$client_id,
$item_date
));
This will give you a much nicer URL like:
http://www.example.com/items/add/10012/2013-09-30
And then in your controller, you modify the function to receive those parameters:
public function add($client_id, $item_date) {
// Prefill the form on this page by manually setting the values
// in the request data array. This is what Cake uses to populate
// the form inputs on your page.
if (empty($this->request->data)) {
$this->request->data['Item']['client_id'] = $client_id;
$this->request->data['Item']['item_date'] = $item_date;
} else {
// In here process the form data normally from when the
// user has submitted it themselves...
}
}
I'd like to make an application in CakePHP which manages exercises and users results. Users and results are not important in this question.
I want to have a possibility to add an exercise with adding only a specific table and line to .ini config file. Application should route to a GenericExercisesController if specific one doesn't exists. Controller should load a GenericExerciseModel if specific doesn't exists. I'd managed with model loading and partially with routing with controller like this:
In route.php
foreach(Configure::read('exercisesTables') as $exerciseName){
if( App::import('Controller', Inflector::pluralize($exerciseName))){
Router::connect('/exercises/'.Inflector::pluralize($exerciseName).'/:action', array('controller' => Inflector::pluralize($exerciseName)));
}else{
Router::connect('/exercises/'.Inflector::pluralize($exerciseName).'/:action', array('controller' => 'GenericExercises', 'fakeModel' => $exerciseName));
}
}
So if I want to load an exercise Foo I should use address:
http://example.com/exercises/Foos/view
And this works fine, doesn't matter if specific controller exists.
Problem begins when I use reverse routing to generate links in views. If exercise Foo have specific controller this works correctly:
print $this->Html->url(array('controller' => Inflector::pluralize($exerciseName), 'action' => 'view'));
produces:
/exercises/Foos/view
But when exercise Bar doesn't have specific controller then the same code produces:
/Bars
This causes a problem, there is no Bars Controller.
Temporarily I'm generating those links manually, but I don't think that this is the best solution:
print $this->Html->url("/".Configure::read('exerciseRoutingPrefix')."/".Inflector::pluralize($exerciseName)."/view");
Maybe someone of you know a better solution. Thank you for reading my question.
UPDATE 1:
Those are routes in route.php defined before foreach in order as they're in file:
Router::connect('/', array('controller' => 'questions', 'action' => 'regulations'));
Router::connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
Router::connect('/help', array('controller' => 'pages', 'action' => 'faq'));
If I understood your question correctly, you could try making a "MyHtmlHelper" which does some magic before parsing your options to the HtmlHelper::link();
You can do it like so:
/app/View/Helpes/MyHtmlHelper.php
Create a helper which extends the "HtmlHelper" like so:
<?php
App::uses('HtmlHelper', 'View/Helper');
class MyHtmlHelper extends HtmlHelper {
public function link($title, $url = null, $options = array(), $confirmMessage = false) {
//do your magic here and change the $title, $url or $options accordingly.
return parent::link($title, $url, $options, $confirmMessage);
}
}
Now in your controller, you should include the Helper like so (aliasing) $helpers = array('Html' => array('className' => 'MyHtml')); instead of $helpers = array('Html');.
I guess you can fill in the blanks on the public function link yourself. If not, feel free to ask more help :)
More about helpers
Off course it is possible to do this with every other Helper or method you can think off. HtmlHelper::link() is just used as example.
I was wondering if there was an easy and best practices way to make routes in CakePHP (routes.php file) to map userIDs to a vanity url?
I have (terrible way to do this) the following test code in my routes page:
$users = array
(
1 => 'firstname-lastname',
2 => 'firstname2-lastname2'
);
//profiles
foreach($users as $k => $v)
{
// LESSONS (Profiles)
Router::connect('/:user', array('controller' => 'teachers', 'action' => 'contentProfile', $k),
array('user' => '(?i:'.$v.')'));
}
The above code routes my teachers controller with conProfile as the action from:
mydomain.com/teachers/contentProfile/1
to
mydomain.com/firstname-lastname
Can I connect to the db from the routing page? Is that not a good idea in terms of performance? Let me know what's the best way to do this.
You can create a custom route class that will look up passed urls in the database and translate them to the correct user id. Setting a long cache time should mitigate any performance impact of hitting the DB.
The book documentation is a little thin, however, but the basic structure is this:
class TeachersRoute extends CakeRoute {
/**
* Modify incoming parameters so that controller receives the correct data
*/
function parse($url) {
$params = parent::parse($url);
// Add / modify parameter information
// The teacher id should be sent as the first value in the $params['pass'] array
return $params;
// Or return false if lookup failed
}
/**
* Modify parameters so calls like HtmlHelper::url() output the correct value
*/
function match($url) {
// modify parameters
// add $url['slug'] if only id provided
return parent::match($url);
}
And then in your routes:
Router::connect(
'/:slug',
array(
'controller' => 'teachers',
'action' => 'contentProfile'
),
array(
'slug' => '[a-zA-Z0-9_-]+'
'routeClass' => 'TeachersRoute',
)
);
I am working on Kohana PHP framework.
I want to show a 'username' instead of controller name in my URL.
For example,
username = james then how to show
http://localhost:3000/james
instead of
http://localhost:3000/scrapbook/index => ... localhost:3000/scrapbook
(controller: scrapbook, action: index)
in the url.
My bootstrap file have the entry for such types of url. If I manually write ..//localhost:3000/james, it takes me to the requested page.
//Viewing a user's profile or account details - user/action
Route::set('profile', '(<username>(/<action>(/<id>)))',
array(
'username' => '([A-Za-z0-9\-]+)'))
->defaults(array(
'controller' => 'scrapbook',
'action' => 'index'));
What I want is if I manually signin and go to scrapbook, my url should show 'username' and not the name of the controller. I will appreciate if anyone can guide me in this.
Thanks
When you complete your sign in action, you'll want to redirect the user to the desired URL using reverse routing:
// ...in your controller
function action_signin()
{
// ...sign in logic
$this->request->redirect(
Route::get('profile')->uri(array(
'username' => $username
))
);
}
$username will be whatever the username of the user of the logged in user is that just signed in.
First of all I have a Model user.php which connects to users table.
I have a controller UsersController.
I created a view for search: (filename: index.ctp)
<p><?php
echo $this->Form->create("Users", array('action' => 'search'));
echo $this->Form->input("Search Label", array('action' => 'search', 'name' => 'txt_search'));
echo $this->Form->end("Search");
?></p>
And this will go to UsersController/search() function
function search() {
if (!empty($this->data))
{
$name = $this->data['Users']['txt_search'];
$conditions = array("User.name Like " => "%$name%");
$result = $this->User->find('all', array('conditions'=> $conditions));
$this->set('users', $result);
}
}
And this will load search.ctp
My problem is, when I use the variable $users in search.ctp, it gives me an error Undefined variable: Users [APP\views\users\search.ctp, line 10].
I don't understand.
Please help. Thanks!
You're specifying a custom name for your input and then you're checking $this->data which will be empty because you're input is not named properly (and does not get auto populated in $this->data). Use the following.
echo $this->Form->input("txt_search", array('label' => 'Search Label'));
A couple of things you should be looking at.
Set a default value to your users variable so your page doesn't break if they request it directly. Have $result = array(); at the top and do an empty() check on it in search.ctp
Why have you specified an action attribute in your input? You don't need that.