I have a form in laravel.
If submits a bunch of information about the user and then submits it to a store() function.
public function store()
{
$input = Input::except('_token');
if ( ! $this->validator->with($input)->passes())
{
return Redirect::back()->withErrors($this->validator->errors())->withInput($input);
}
$this->title->save($input);
return Redirect::back()->withSuccess( trans('main.created successfully') );
}
public function save()
{
if ($this->query && $this->values)
{
return DB::statement($this->query, array_values($this->values));
}
}
The query is executed in the save() function
The User can then access the info at www.mysite/{$id}
The {$id} variable is generated when the query is executed and saved into my db. It is the value of the id column in my db.
I want to email the user when they submit the form to say that the info has been entered successfully and that they can view it at www.mysite/{$id} but I don't know what variable I should put into my mailer() function to denote the {$id} because that variable is generated when it is saved. How do I implement a way to pass the {$id} variable to my mailer() function?
Related
I am new to laravel.I have a controller called userController to mangae user in my application.Here i have a user authentication and profile system.It will send the user to its own profile after login.Sometimes user may wish to search for a random username or id field in the url to search for a user.If desired user is found ,their profile info will be shown in the profile section.But if no user is found i want my application to get the current logged in user and show his/her info instead.How i can do that?
if my user name is 'zim' i can write the url mydomain/user/zim ,it will get my profile,But if i search an invalid name say 'zi' mydomain/user/zi , i want my application to return mydomain/user/zim again
All i can manage here is to show a flash message if no user is found.Can't figure out how to retrieve the current logged user.Tried to use the Request class but seems not working
loginUser function():
public function loginUser(Request $request){
$data = $request->all();
$rules = array(
'name' => 'required',
'password'=>'required'
);
// Create a new validator instance.
$validator = Validator::make($data, $rules);
if($validator->fails()){
$errors=$validator->messages();
return redirect()->back()->withErrors($validator);
}else{
if(Auth::attempt(['name'=>$request['name'],'password'=>$request['password']])){
return redirect()->route('user.show',[$request['name']]);
}else{
return redirect()->back()->with('data', 'wrong username or password');
}
}
}
show() method in userController:
public function show($user,Request $request) // tried with Request but failed
{
//
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if($info){
return View::make('user.show')->with('user',$info);
}else{
session()->flash('message','no user');
return View::make('user.show');
}
}
You just need to change your show method slightly.
public function show($user,Request $request)
{
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if(empty($info)){
return View::make('user.show')->with('user',$info);
}else{
session()->flash('message','no user but here is your info :)');
return View::make('user.show')->with('user', Auth::user());
}
}
Edited for better logic.
public function show($username)
{
$info = userModel::where(username, $username)->get()->first();
if($info != null){
return View::make('user.show')->with('user', $info);
}
else{
session()->flash('message','No user found! But here is your info!');
return View::make('user.show')->with('user',Auth::user());
}
}
Here is a much simplified option. (Always allow the URL to collect only one type instead of checking if its id or username)
I have a Yii form accept first name, last name and email from user. Using an add more link, users can add multiple rows of those three elements.
For email validation, unique and required are set in model rules and everything works fine. I am using JavaScript to create addition row on clicking add more link.
Problem
On the first row my values are John, Newman, johnnewman#gmail.com and the second row, i'm entering Mathew, Heyden, johnnewman#gmail.com. In this case email address is duplicated. None of the validation rules (require and unique) is capable of validating this. Can some one suggest a better method to validate this ?
Update:
I created a custom validation function and i guess this is enough to solve my problem. Can someone tell me how to access the whole form data / post data in a custom validation function ?
public function uniqueOnForm($attribute){
// This post data is not working
error_log($_REQUEST, true);
$this->addError($attribute, 'Sorry, email address shouldn\'t be repeated');
}
You can try this:
<?php
public function rules()
{
return array(
array('first_name', 'checkUser')
);
}
public function checkUser($attribute)
{
if($this->first_name == $this->other_first_name){
$this->addError($attribute, 'Please select another first name');
}
}
?>
You can also look into this extension
You can write custom validator:
//protected/extensions/validators
class UniqueMailValidator extends CValidator
{
/**
* #inheritdoc
*/
protected function validateAttribute($object, $attribute)
{
$record = YourModel::model()->findAllByAttributes(array('email' => $object->$attribute));
if ($record) {
$object->addError($attribute, 'Email are exists in db.');
}
}
}
// in your model
public function rules()
{
return array(
array('email', 'ext.validators.UniqueMailValidator'),
...
Or better try to use THIS
public function rules(){
return array(
//other rules
array('email', 'validEmail'),
)
}
public function validEmail($attribute, $params){
if(!empty($this->email) && is_array($this->email)){
$isduplicate = $this->isDuplicate($this->email);
if($isduplicate){
$this->addError('email', 'Email address must be unique!');
}
}
}
private function isDuplicate($arr){
if(count(array_unique($arr)) < count($arr)){
return true;
}
else {
return false;
}
}
because you are using tabular input (multiple row) , so make sure input field as an array. might be like this :
<?php echo $form->textField($model, 'email[]'); ?>
I'm not a pro, but know my way around PHP, I'm new to Codeigniter.
Been going through these tutorials: http://net.tutsplus.com/articles/news/codeigniter-from-scratch-day-5-crud/
OK, so I have a page that lists users, clicking on users name will go to an edit page, the url of that page being: index.php/users/edit/1 (where 1 is the users id)
On edit page is a form, this form contains a few parts, each part is populated from different tables in the DB. So my Controller for edit is as follows:
function edit() {
//load model
$this->load->model('users_model');
//assign user data from DB
$data['data_user'] = $this->users_model->getUser($this->uri->segment(3));
//get users Password, using username from above
$data['data_user_password']= $this->users_model->getUserPassword($data['data_user'][0]->UserName);
$data['page_content'] = 'pages/users_edit';
$this->load->view('template/template', $data);
}
Notice:
$data['data_user'] contains users data like name, username, email
$data['data_user_password'] contains users password from a different table
I can then populate the form, on users_edit.php, this all works fine.
I'm accessing this data by doing the following:
if (is_array($data_user)) {
foreach($data_user as $user)
{
$userID = $user->id;
$userName = $user->Name;
$userUserName = $user->UserName;
$userMail = $user->Mail;
$userDepartment = $user->Department;
$userWorkPhone = $user->WorkPhone;
$userHomePhone = $user->HomePhone;
$userMobile = $user->Mobile;
}
}
//user password
if (is_array($data_user_password)) {
foreach($data_user_password as $user)
{
$userPassword = $user->value;
}
}
Name:
<?php echo form_input('name', set_value('name', $userName), 'id="name" class="inputLong"'); ?>
When I post, I'm sending data to: index.php/users/update
My controller for this page so far is:
function update() {
echo '<pre>';
print_r($_POST);
echo '</pre>';
//exit();
$this->load->library('form_validation');
$this->form_validation->set_rules('name', 'Name', 'trim|required');
if ($this->form_validation->run() == FALSE)
{
$this->load->view('pages/users_edit');
}
else
{
$this->index();
}
}
For now, I'm just testing validation on users "name" where form input=name id=name
I think I'm not handling the if ($this->form_validation->run() == FALSE) part of it correctly, if the form contains data, it passes and redirects to index, if I leave name blank it either not handling the edit page correctly, or I dont know, something isnt right.. I think its because the page is being reloaded using the post array, and not passing the $data like I did in function edit().
Back to the form page, where it should be showing the validation_errors, its showing:
The Name field is required.
This is correct, however, for the rest of the fields that should be pre-populated, its showing PHP error:
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: userUserName
Filename: pages/users_edit.php
Line Number: 50
You could do your validation inside your edit function instead of having an update function, that way, your data is still available for your view and if the validation has errors, codeigniter will take in charge to repopulate your fields. If the validation is ok, you do your next step
function edit() {
//load model
$this->load->model('users_model');
//assign user data from DB
$data['data_user'] = $this->users_model->getUser($this->uri->segment(3));
//get users Password, using username from above
$data['data_user_password']= $this->users_model->getUserPassword($data['data_user'][0]->UserName);
$data['page_content'] = 'pages/users_edit';
$this->load->view('template/template', $data);
//is the form submitted
if(form submit){
if ($this->form_validation->run() == TRUE)
{
$this->index();
}
else
{
$this->load->view('pages/users_edit', $data);
}
}
}
$this->load->view('pages/users_edit');
Inside your function update(), after your validation you load view but you don't PASS any data variables to it. So you don't have any variables which you can access at your view file..
You have to set your variables the same way as in your function edit():
$this->load->view('template/template', $data);
Currently there is not set variable $data_user so you can't loop it and use it..
I have the following two actions in my controller:
function add()
{
if (!empty($this->data))
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been saved.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
function edit($id = null)
{
$this->Favour->id = $id;
if (empty($this->data))
{
$this->data = $this->Favour->read();
}
else
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been updated.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
1) I want to be able to add the logged in user id to the add action so that the new post is created with that user as its author id (their is a foreign key in the db table). I'm not sure how to talk to fields within the controller itself.
2) And for the edit action I want to make it so that only the author can edit the post so for example user 200 creates post 20 but user 100 cannot edit this post because his id is not 200! I'm not using ACL for my app but just simple authentication.
I've thought about doing a simple if statement in the action like:
function edit($id = null)
{
$this->Favour->id = $id;
$this->Favour->user_id = $user_id;
if($this->Auth->user('id') != $user_id)
{
$this->Session->setFlash('You do not have permission to edit that favour!');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
else
{
if (empty($this->data))
{
$this->data = $this->Favour->read();
}
else
{
if ($this->Favour->save($this->data))
{
$this->Session->setFlash('Your favour has been updated.');
$this->redirect(array('controller'=>'favours','action'=>'index'));
}
}
}
Would this be correct? BUT how do I get the user id from the favour?
function add() {
if (!empty($this->data)) {
$this->data['Favour']['user_id'] = $this->Auth->user('id');
if ($this->Favour->save($this->data)) {
//etc
This code assumes:
Your user is logged in
the user can access the add function
You are storing the id value of the logged in user in the field id
You have a foreign key in Favours table called user_id that matches the data type of the user id
As for edit; couple ways of achieving it.
I'd do:
function edit($id) {
$this->Favour->id = $id;
$favour_author = $this->Favour->field('user_id');
// get the user of this post
if($this->Auth->user('id') != $favour_author) {
$this->Session->setFlash('You do not own this post.');
$this->redirect('/someplace');
}
if (empty($this->data)) {
$this->data = $this->Favour->read();
}
// carry on.
If you use Auth Component, you can access the logged-in user record in $this->Auth->user() in controller. So to access the id: $this->Auth->user('id'). If you write your own authentication, it's up to you.
how to talk to fields within the controller itself.
What do you mean?
i created a update profile page.
i have this in the controller to populate the form and also handle update:
$user = User::model()->findByPk(Yii::app()->user->id);
// Collect user input
if (isset($_POST['User'])) {
$user->attributes = $_POST['User'];
if ($user->save()) {
echo "update successfully";
}
else {
echo "update failed";
}
}
// View
$this->render('user_view', array('user'=>$user,));
however, this doesn't work. although $user->save is true, the record is not updated in the database. i've also check that $_POST['User'] is returning the updated data but $user->attributes is not saving them.
why is that so?
You need to set which model attributes are "safe" for "massive assignments". Read more about this here.
The mass attribute assignment $user->attributes will only assign to variables with validation rules. Just give the name attribute a rule, even if it's just the "safe" validator.
public function rules()
{
return array(
array('name', 'safe')
);
}
I'm pretty sure this is the problem you are having, it's happened to me!