I have this scenario in my app where I have to send user's password and username to their email right away after their account created by admin. Here is what I've done so far :
Controller :
public function store(Request $request) {
$data = $request->all();
$validasi = Validator::make($data, [
'name' => 'required|max:255',
'username' => 'required|max:255|unique:users',
'email' => 'required|email|max:150|unique:users',
'password' => 'required|confirmed|min:6',
'level' => 'required|in:admin,author',
]);
if ($validasi->fails()) {
return redirect('user/create')->withInput()->withErrors($validasi);
}
$data['password'] = bcrypt($data['password']);
$email = $data['email'];
Mail::to($email)->send(new UserAdded());
User::create($data);
return redirect('user');
}
The email will send successfully but I want to pass $data['username'] and $data['password'] to email view as well.
email view :
<div class="row">
<div class="col-sm-12 col-xs-12">
<h2><span>Welcome new User!</span></h2>
<p>Your username </p>
<p>Your password</p>
</div>
Mailable function :
class UserAdded extends Mailable
{
use Queueable, SerializesModels;
public function __construct()
{
}
public function build()
{
return $this->view('email/newuser');
}
}
How to do it ? where will I define the $user data ? thanks for the help!
First of all, you need a class that builds the view. There you can define properties which you'll pass to the class. They'll be accessable in the view then.
<?php
namespace App\Mail;
use App\Order;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class UserAdded extends Mailable
{
use Queueable, SerializesModels;
public $username;
public $password;
/**
* Create a new message instance.
*
* #return void
*/
public function __construct($username, $password)
{
$this->username = $username;
$this->password = $password;
}
public function build()
{
return $this->view('reference.your.view.path.here'); //CHANGE
}
}
You can now access the variables in your view.
<div class="row">
<div class="col-sm-12 col-xs-12">
<h2><span>Welcome new User!</span></h2>
<p>Your username: {{$username}} </p>
<p>Your password: {{$password}} </p>
</div>
Calling your view can be realized like this:
Mail::to($email)->send(new UserAdded($data['username'],$password));
Related
I'm working on Laravel task and struggling to add a login feature. Register and validation features seem work well, but can't login even if i put correct user_name and pass_word. also old helper function is not working as well.
i am a very beginner of Laravel and I know my code is messy and not coherent. But need to get this task done. appreciate if you help me solve this!
So here are files of my task. when i tried to login it always goes to this page.
<?php
use App\Http\Controllers\RegisterController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('users/list', 'App\Http\Controllers\UserController#getUser');
Route::get('register', [RegisterController::class, 'create'])->middleware('guest');
Route::post('register', [UserController::class, 'register'])->middleware('guest');
Route::get('login', [UserController::class, 'loginView']);
Route::post('login', [UserController::class, 'login']);
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserLoginRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Models\User;
use App\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
private $userService;
public function __construct(
UserService $userService
) {
$this->userService = $userService;
}
public function getUser() {
$users = User::all();
return view('users/list')
->with('users', $users);
}
public function register(UserRegisterRequest $request)
{
$this->userService->registerUser($request->user_name, $request->pass_word);
return redirect('users/list');
}
public function loginView()
{
return view('users/loginView');
}
public function login(Request $request)
{
$validatedData = $request->validate([
'user_name' => ['required'],
'pass_word' => ['required'],
]);
if (Auth::attempt($validatedData)) {
$request->session()->regenerate();
return redirect('users/list');
}
return back()->withErrors([
'user_name' => 'wrong username'
]);
}
}
<main>
<h1>Login!</h1>
<form action="login" method="POST">
#csrf
<div>
<label for="user_name">
User_name
<input type="text" name="user_name" id="user_name" value="{{ old('user_name') }}" >
</label>
#error('user_name')
<div class="error">{{ $message }}</div>
#enderror
</div>
<div>
<label for="pass_word">
Password
<input type="password" name="pass_word" id="pass_word" value="{{ old('pass_word') }}">
</label>
#error('pass_word')
<div class="error">{{ $message }}</div>
#enderror
</div>
<div>
<button type="submit">
Submit
</button>
</div>
</form>
</main>
<?php
namespace App\Services;
use Illuminate\Database\Eloquent\Collection;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
class UserService
{
/**
*
*
* #param string $name
* #param string $email
* #param string $pass_word
* #return void
*/
public function registerUser($user_name, $pass_word) : void
{
$user = new User();
$user->user_name = $user_name;
$user->pass_word = Hash::make($pass_word);
$user->save();
}
}
enter image description here
First, if you want to redirect using back() helper to another controller method, you should put ->withInput or ->onlyInput('user_name').
back()->withErrors([
'user_name' => 'wrong username'
])->onlyInput('user_name');
or
back()
->withErrors([
'user_name' => 'wrong username'
])->withInput();
You may dump the errors on the view because probably it comes from the password error may be?
I have several methods that require email submissions. An example is, after making a purchase.
My class Mailable
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use App\Models\Order;
class AfterOrder extends Mailable
{
use Queueable, SerializesModels;
public $order;
public function __construct(Order $order)
{
$this->Order = $order;
}
/**
* Build the message.
*
* #return $this
*/
public function build()
{
return $this->subject('Thanks for your purchase')->view('mail.after-order');
}
}
My mail view
<div class="container">
<h1>Nombre: {{\Auth::user()->email}}</h1>
<h1>Order: {{$order->reference}}</h1>
</div>
My Controller
public function sendMail(Order $order) {
$order = $order->newQuery();
$order->whereHas('user', function($query){
$query->where('email', '=', \Auth::user()->email);
});
$order = $order->orderBy('id', 'desc')->first();
$user = User::where('email', '=', \Auth::user()->email)->first();
Mail::to($user->email)->send(new AfterOrder($order));
//return redirect()->route('home')->with(['message' => 'Thank you for shopping at Sneakers!']);
}
What am I doing wrong? If I, for example, in my controller make a $ order-> reference I get the order reference but when passing the variable to the view it treats me as null or empty
You should use the with method
public function build()
{
return $this->view('mail.after-order')
->with([
'orderName' => $this->order->name,
'orderPrice' => $this->order->price,
]);
}
in your mailable class AfterOrder. With that you have access to the name and the price of the order in your mail view.
You can then access these with {{ $orderPrice }} and {{ $orderName }} in your view.
Was a typo. just change $this->Order = $order; to $this->order = $order;
I'm not familiar with Vue.js at all, so found a good replacement using Livewire.
The challenge that I've got to solve is to have a user friendly registration on my website using Fortify + Livewire. The registration process is a multistep one and depends on the choices that the user makes it will load the relative fields.
So far I set up the Fortify views by adding in the FortifyServiceProvider.php file the following code:
Fortify::loginView(function () {
return view('auth.login');
});
Fortify::registerView(function () {
return view('auth.register');
});
The auth/login.blade.php view loading the livewire component which is basically a form:
<form action="{{ route('register') }}" method="POST" wire:submit.prevent="submit">
/**
* Here would go the inputs that must be shown depends on what users choice
* (is it an ordinar user or a company)
*/
<button type="submit">Save<button/>
</form>
The multiform challenge would be resolved by adding $step property into the Register.php class:
class RegisterForm extends Component
{
public $step;
public function mount()
{
$this->step = 0;
}
public function submit()
{
if ($this->step < 3) {
$this->step++;
} else {
// pass all the data to the fortify register method
// <-- Here is my trouble!
}
}
}
which will be incremented by passing each of the registration steps ($this->step++).
The most important thing that is quite complicated for me is how to prevent form submission to have the validation + form changes and by the end all the set of the data to pass trough Fortify registration process?
Look at the fortify Controller for register
public function store(Request $request, CreatesNewUsers $creator): RegisterResponse
{
event(new Registered($user = $creator->create($request->all())));
$this->guard->login($user);
return app(RegisterResponse::class);
}
T
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use Laravel\Fortify\Contracts\CreatesNewUsers;
use Livewire\Component;
class Register extends Component
{
public $name;
public $email;
public $password;
public $password_confirmation;
public function submit(CreatesNewUsers $creator)
{
event(new Registered($user = $creator->create([
'name' => $this->name,
'email' => $this->email,
'password' => $this->password,
'password_confirmation' => $this->password_confirmation,
])));
Auth::guard()->login($user);
$this->redirect('home');
}
public function render()
{
return view('livewire.register');
}
}
Something like this will work for your use case.
You are still using the fortify Action and Still Firing the Event
The response is to use app container
<?php
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use App\Actions\Fortify\CreateNewUser;
use Livewire\Component;
class Register extends Component
{
public $name;
public $email;
public $password;
public $password_confirmation;
public function submit()
{
event(new Registered($user = app(CreateNewUser::class)->create([
'name' => $this->name,
'email' => $this->email,
'password' => $this->password,
'password_confirmation' => $this->password_confirmation,
])));
Auth::guard()->login($user);
$this->redirect('home');
}
public function render()
{
return view('livewire.register');
}
}
The response is to use dependency injection by injecting the Fortify CreateNewUser action in the mounting method of the Livewire component.
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use App\Actions\Fortify\CreateNewUser;
use Livewire\Component;
class Register extends Component
{
public $name;
public $email;
public $password;
public $password_confirmation;
protected $creator;
public function mount(CreateNewUser $creator)
{
$this->creator = $creator;
}
public function submit()
{
event(new Registered($user = $this->creator->create([
'name' => $this->name,
'email' => $this->email,
'password' => $this->password,
'password_confirmation' => $this->password_confirmation,
])));
Auth::guard()->login($user);
$this->redirect('home');
}
public function render()
{
return view('livewire.register');
}
}
you can use blade example
#if($step > 3)
<input name="name" type="text">
#endif
I'm creating a news feed kind of thing where users can post anything and the post will have comments also. I'm able to create the newsfeed and the comment section, but my real problem is I'm not able to show the comments which belongs to the post. Right now all the comments are displayed under every news feed. Though I've declared the eloquent relationship between feed and comment but still I'm not able to save the feed_id in comment table.
This is my FeedsController:-
<?php namespace App\Http\Controllers;
use Request;
use Auth;
use Sentinel;
use App\Feed;
use App\Http\Requests;
use App\Blog;
use App\Http\Controllers\Controller;
use App\Comment;
class FeedsController extends Controller
{
public function index() {
$comments = Comment::latest()->get();
$feeds = Feed::where('user_id', Sentinel::getUser()->id)->latest()->get();
$blogs = Blog::latest()->simplePaginate(5);
$blogs->setPath('blog');
return view('action.index')->with('feeds', $feeds)->with('comments', $comments)->with('blogs', $blogs);
}
public function store(Requests\CreateFeedRequest $request){
$requet = $request->all();
$request['user_id'] = Sentinel::getuser()->id;
Feed::create($request->all());
return redirect('home');
}
public function storecomment(Requests\CommentRequest $request, Feed $feed)
{
$comment = new Comment;
$comment->user_id =Sentinel::getuser()->id;
$comment->feed_id = $request->feed_id;
$comment->comment = $request->comment;
$comment->save();
return redirect('home');
}
}
This is the models:
Comment model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $fillable = [
'comment',
'user_id',
'feed_id'
];
public function feed()
{
return $this->belongsTo('App\Feed');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
Feed model:
use Illuminate\Database\Eloquent\Model;
class Feed extends Model
{
protected $fillable = [
'feed_id',
'user_id',
'feed_content'
];
public function user()
{
return $this->belongsTo('App\User');
}
public function comment()
{
return $this->hasMany('App\Comment');
}
}
User model:-
<?php namespace App;
use Cartalyst\Sentinel\Users\EloquentUser;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends EloquentUser {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes to be fillable from the model.
*
* A dirty hack to allow fields to be fillable by calling empty fillable array
*
* #var array
*/
protected $fillable = [];
protected $guarded = ['id'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
/**
* To allow soft deletes
*/
use SoftDeletes;
protected $dates = ['deleted_at'];
public function feeds()
{
return $this->hasMany('App\Feed');
}
public function comment()
{
return $this->hasMany('App\Comment');
}
}
This is my feed.blade.php where I'm displaying the feeds output and commnets
#foreach($feeds as $feed)
<article class="media">
<div class="well">
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'.$feed->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
<strong>{{ $feed->user->first_name }}
{{ $feed->user->last_name }}
<small> posted </small>
</strong>
{{ $feed->created_at->diffForHumans() }}<br><hr>
{{ $feed->feed_content }}
<hr>
{!! Form::open(['url' => 'home/{storecomment}']) !!}
<div class="form-group">
{!! Form::text('comment', null, ['class'=>'form-control', 'rows'=>3, 'placeholder'=>"Comment"]) !!}
</div>
<div class="form-group feed_post_submit">
{!! Form::submit('Comment', ['class' => 'btn btn-default btn-xs']) !!}
</div>
{!! Form::close() !!}
#foreach($comments as $comment)
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'. $comment->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
{{ $comment->user->first_name }}
{{ $comment->created_at->diffForHumans() }}
{{ $comment->comment }}<hr>
#endforeach
</div>
</article>
#endforeach
Can anyone tell me how to store the feed_id into comment table and displaying the comments according to the feed. Thank You. I'm using Laravel 5.1
Based on our lengthy convo -
To save the feed_id (which is our foreign key for future relationships), you need to set/send the feed_id in your POST request. Laravel is not magic and won't know this automatically. You can do this by adding a hidden input, like so:
<input type="hidden" name="feed_id" value="{{ $feed->feed_id }}" />
In your FeedController, change your index to this:
public function index() {
// $comments = Comment::latest()->get(); remove this
// notice the "with" below. I'm eager loading in relations here
$feeds = Feed::with('comments', 'user')->where('user_id', Sentinel::getUser()->id)->latest()->get();
$blogs = Blog::latest()->simplePaginate(5);
$blogs->setPath('blog');
return view('action.index', compact('feeds', 'blogs'));
}
Feed Model should have the correct relationships, as below:
class Feed extends Model
{
protected $fillable = [
'feed_id',
'user_id',
'feed_content'
];
public function user()
{
return $this->belongsTo('App\User', 'id', 'user_id');
}
public function comments()
{
return $this->hasMany('App\Comment', 'feed_id', 'feed_id');
}
}
Comment Model should have the correct relationships, as below:
class Comment extends Model
{
protected $fillable = [
'comment',
'user_id',
'feed_id'
];
public function feed()
{
return $this->belongsTo('App\Feed');
}
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id');
}
}
Now you should be able to run your foreach as you currently have it.
I'm having trouble logging in. Even when there are no validation errors to be found, it goes to the else statement block in my postIndex method and brings me back to the login page. Any idea on what the problem is and what do i need to change to fix it?
routes.php
<?php
Route::get('/', 'HomeController#getGuestIndex');
Route::controller('login', 'LoginController');
?>
HomeController.php
<?php
class HomeController extends BaseController {
public function getGuestIndex()
{
return View::make('guests.index');
}
public function getAdminIndex()
{
return View::make('admin.index');
}
}
?>
LoginController.php
<?php
class LoginController extends BaseController {
public function getIndex()
{
// Check if we are already logged in.
if (Auth::check()) {
return Redirect::action('HomeController#getAdminIndex')
->with('message', 'You are already logged in');
}
return View::make('guests.login')
->with('title', 'Login');
}
public function postIndex()
{
// Get all the inputs
$user = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
$validation = User::validate($user);
if ($validation->passes()) {
// Try to log the user in.
if (Auth::attempt($user)) {
return Redirect::action('HomeController#getAdminIndex')
->with('message', 'You have logged in successfully');
}
return Redirect::to('login')
->withErrors($validation)
->withInput(Input::except('password'));
} else {
// Something went wrong.
return Redirect::back()
->withErrors($validation)
->withInput(Input::except('password'));
}
}
}
?>
BaseModel.php
<?php
class BaseModel extends Eloquent {
public static function validate($inputs)
{
return Validator::make($inputs, static::$rules);
}
}
?>
User.php
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends BaseModel implements UserInterface, RemindableInterface {
protected $table = 'users';
protected $hidden = array('password');
protected static $rules = array(
'username' => 'required|alpha_dash|min:4',
'email' => 'required|email',
'password' => 'required|alpha_num|min:8|confirmed',
'password_confirmation' => 'required|alpha_num|min:8'
);
public function getAuthIdentifier()
{
return $this->getKey();
}
public function getAuthPassword()
{
return $this->password;
}
public function getReminderEmail()
{
return $this->email;
}
}
?>
login.blade.php
#extends('layouts.master')
#section('content')
<h2>Login into your account</h2>
{{ Form::open(array('url' => 'login')) }}
<p>
{{ Form::label('username', 'Username') }}
{{ Form::text('username', Input::old('username')) }}
</p>
<p>
{{ Form::label('password', 'Password') }}
{{ Form::password('password') }}
</p>
<p>
{{ Form::submit('Login') }}
</p>
{{ Form::close() }}
<p>{{ $errors->first('username') }}</p>
<p>{{ $errors->first('password') }}</p>
#stop
Based on your question and example script the validation is failing.
The problem is likely with the model based validation implementation. You are validating login with registration rules.
One set of validation rules does not fit all situations.
If you add the following lines to your login.blade.php I think you will see additional errors:
<p>{{ $errors->first('email') }}</p>
<p>{{ $errors->first('password_confirmation') }}</p>
To fix it, you will need to either change the validation rules on your model, or change the validation implementation. These two excellent tutorials show a couple approaches:
https://tutsplus.com/lesson/validation-services/
https://tutsplus.com/lesson/validating-with-models-and-event-listeners/