Laravel Email Verification in custom registeration controller not working - laravel

I have made a registration form in my frontend ( Not a laravel default registration form ) . I have used Laravel Email Verification
I have implements MustVerifyEmail in User Model
But In that custom registraion form in my frontend when i hit submit it redirects the page to /admin/home but email is not been sending when i register but If I click on resend email again it sends the email . I want to fix that
Does anyone know how ?
Do I have to implements MustVerifyEmail to that controller too or what ?
IGNORE THAT CITY AND ROOM IN THE FUNCTION !!!!!
class QuickRegisterController extends Controller
{
public function quickList(Request $request)
{
$this->validate($request ,[
'features' => 'required',
'rommies' => 'required',
'price' => 'required',
'avaiability' => 'required',
'utility' => 'required',
'owner_working_email' => 'required',
'address' => 'required',
'exact_address' => 'required',
'owner_of_the_room' => 'required',
]);
$user = User::firstOrCreate([
'name' => $request->owner_of_the_room,
'email' => $request->owner_working_email,
'password' => bcrypt($request->password),
'role_id' => config('quickadmin.default_role_id'),
]);
\Auth::loginUsingId($user->id);
if (\Auth::check()) {
$city = TotalCity::firstOrCreate([
'name' => $request->city,
'created_by_id' => \Auth::user()->id,
]);
if ($city) {
$room = new MyRoom;
$room->location_id = $city->id;
$room->features = $request->features;
$room->rommies = $request->rommies;
$room->price = $request->price;
$room->utility = $request->utility;
$room->avaiability = $request->avaiability;
$room->owner_woring_email = $request->owner_working_email;
$room->address = $request->address;
$room->exact_address = $request->exact_address;
$room->owner_of_the_room = $request->owner_of_the_room;
$room->save();
}
return redirect('/admin/home');
}
else {
return redirect()->back()->with('Form Submission Failed . Try Again Later');
}
}
}

If you look into the RegisterController that Laravel provides with its auth scaffolding, not sure if you are using that or not, it implements the RegistersUsers trait. That trait implements an event that is triggered upon registration. You can use the RegistersUsers trait in your class or create your own custom event.
I'll show you how to use the trait.
At the top of your file:
use Illuminate\Foundation\Auth\RegistersUsers;
Right inside your class:
use RegistersUsers;
For Example:
use Illuminate\Foundation\Auth\RegistersUsers;
class QuickRegisterController extends Controller
{
use RegistersUsers;
// ....
}
You'll need to set up the route as well.
// The register method is coming from the trait
Route::post('/register', 'QuickRegisterController#register');
Also,
You'll want to update your method name to create, the trait calls a create method from the implementor, which is where the user gets created and then the event is triggered, and in that create a method just return the new user, instead of redirecting back.
This might not be all you need to do to get this working, but it will get you started. If you are interested in creating your own event:
https://laravel.com/docs/5.8/events
Or, as #Bipin Regmi pointed out you can just use the event that is being used in the trait
event(new \Illuminate\Auth\Events\Registered($user = $this->create($request->all())));

Related

How set uploaded avatar in this.$page.props.user with inertiajs?

In Laravel 8 app with inertiajs/inertia-vue 0.7/vuejs2 with fortify (but without jetstream)
I use "spatie/laravel-medialibrary": "^9.9" for avatar uploading like
$loggedUser = auth()->user();
$avatar_file_path = $avatarImageUploadedFile->getPathName();
$loggedUser->addMedia( $avatar_file_path )->toMediaCollection('avatar');
and it works, but in which way can I use avatar in on client part when I use
this.$page.props.user
in vue components properties to check which user is logged and show his info?
Thanks!
You can do this with the 'Shared data' feature via the HandleInertiaRequests middleware.
For example, to share user info you can do the following:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class HandleInertiaRequests extends Middleware
{
public function share(Request $request)
{
return array_merge(parent::share($request), [
'user' => function () {
return Auth::user() ? [
'id' => Auth::user()->id,
'name' => Auth::user()->name,
'email' => Auth::user()->email,
// get path to avatar
'avatar' => Storage::url('avatar-of-the-user.jpg'),
] : null;
},
]);
}
}
Client side you can then access the avatar's URL with this.$page.props.user.avatar.

dynamic mail configuration using Laravel

In my Laravel application, I am trying to send mail notification based on the company_id of the logged in user:
I have this:
$mail=DB::table('mail_settings')->first();
$config = array(
'driver' => $mail->driver,
'host' => $mail->host,
'port' => $mail->port,
'from' => array('address' => $mail->from_address, 'name' => $mail->from_name),
'encryption' => $mail->encryption,
'username' => $mail->username,
'password' => $mail->password,
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false
);
Config::set('mail',$config);
Models
class Company extends Model
{
protected $table = 'companies';
protected $fillable = [
'id',
'organization_name'
];
}
class User extends Authenticatable
{
protected $fillable = [
'name',
'company_id',
'email',
];
}
Is there any way to override default mail configuration (in app/config/mail.php) on-the-fly (e.g. configuration is stored in database) before mailer transport is created?
Thanks
Is there any way to recreate laravel swiftmailer transport so it can pick up updated config values?
The Mailer class is created in the Illuminate\Mail\MailManager class's resolve() method. If you want to dynamically create a mailer, you need to adapt this function in your Controller to use your $config array and return a Mailer from which you could chain the usual methods.
protected function resolve($name)
{
$config = $this->getConfig($name);
if (is_null($config)) {
throw new InvalidArgumentException("Mailer [{$name}] is not defined.");
}
// Once we have created the mailer instance we will set a container instance
// on the mailer. This allows us to resolve mailer classes via containers
// for maximum testability on said classes instead of passing Closures.
$mailer = new Mailer(
$name,
$this->app['view'],
$this->createSwiftMailer($config),
$this->app['events']
);
if ($this->app->bound('queue')) {
$mailer->setQueue($this->app['queue']);
}
// Next we will set all of the global addresses on this mailer, which allows
// for easy unification of all "from" addresses as well as easy debugging
// of sent messages since these will be sent to a single email address.
foreach (['from', 'reply_to', 'to', 'return_path'] as $type) {
$this->setGlobalAddress($mailer, $config, $type);
}
return $mailer;
}

Laravel: Automatically Create Slug from Title Using Create & Validate Methods

I want to automatically create a slug and save it to the database based on the title entered into a form. Currently, this is how my controller is set up:
public function store(News $id) {
News::create($this->validateArticle());
return redirect('/news');
}
public function validateArticle() {
return request()->validate([
'title' => 'required',
'excerpt' => 'nullable',
'body' => 'nullable'
]);
}
How can I modify this code so that I automatically generate a slug based off of the title?
Thanks.
This is another option of how to do it. Or you could use Observer to observe the crating method like so news->slug= Str::slug($request->title);
public function store(Request $request)
{
$news= new News();
$news->title= $request->title;
$news->slug= Str::slug($request->title);
$news->excerpt= $request->excerpt;
$news->body= $request->body;
$news->save();
return redirect('/news');
}
Make use you import Str use Illuminate\Support\Str;

Find data before validate form request laravel

I want to update the data using the request form validation with a unique email role, everything works normally.
Assume I have 3 data from id 1-3 with url:
127.0.0.1:8000/api/user/update/3
Controller:
use App\Http\Requests\Simak\User\Update;
...
public function update(Update $request, $id)
{
try {
// UPDATE DATA
return resp(200, trans('general.message.200'), true);
} catch (\Exception $e) {
// Ambil error
return $e;
}
}
FormRequest "Update":
public function rules()
{
return [
'user_akses_id' => 'required|numeric',
'nama' => 'required|max:50',
'email' => 'required|email|unique:users,email,' . $this->id,
'password' => 'required',
'foto' => 'nullable|image|max:1024|mimes:jpg,png,jpeg',
'ip' => 'nullable|ip',
'status' => 'required|boolean'
];
}
but if the updated id is not found eg:
127.0.0.1:8000/api/user/update/4
The response gets The email has already been taken.
What is the solution so that the return of the data is not found instead of validation first?
The code looks like it should work fine, sharing a few things below that may help.
Solution 1: Check if $this->id contains the id you are updating for.
Solution 2: Try using the following changes, try to get the id from the URL segment.
public function rules()
{
return [
'user_akses_id' => 'required|numeric',
'nama' => 'required|max:50',
'email' => 'required|email|unique:users,email,' . $this->segment(4),
'password' => 'required',
'foto' => 'nullable|image|max:1024|mimes:jpg,png,jpeg',
'ip' => 'nullable|ip',
'status' => 'required|boolean'
];
}
Sharing one more thing that may help you.
Some person uses Request keyword at the end of the request name. The Update sounds generic and the same as the method name you are using the request for. You can use UpdateRequest for more code readability.
What I understand from your question is, you need a way to check if the record really exists or not in the form request. If that's the case create a custom rule that will check if the record exists or not and use that rule inside your request.
CheckRecordRule
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class CheckRecordRule implements Rule
{
protected $recordId;
public function __construct($id)
{
$this->recordId = $id;
}
public function passes($attribute, $value)
{
// this will check and return true/false
return User::where('id', $this->recordId)->exists();
}
public function message()
{
return 'Record not found.';
}
}
Update form request
public function rules()
{
return [
'email' => 'required|email|unique:users,email,' . $this->id.'|'. new CheckRecordRule($this->id),
];
}
So when checking for duplicate it will also check if the record really exists or not and then redirect back with the proper message.

Laravel Error: Object of class Torann\GeoIP\Location could not be converted to string

I am getting error on send Location Data To Database Using Laravel GeoIP::getLocation('2405:204:970a:d9b3:10a3:5280:9064:3f31'),
Error:
Object of class Torann\GeoIP\Location could not be converted to string
This Is My Auth LoginController. How to Insert GeoIP Loacation data into database. Please Help me
If i remove this code 'current_location' => GeoIP::getLocation('2405:204:970a:d9b3:10a3:5280:9064:3f31'), i am no longer getting this error, every data inserted into database but i add this code i am getting this error
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Jenssegers\Agent\Agent;
use Carbon\Carbon;
use App\User;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Closure;
use GeoIP;
use Location;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
function authenticated(Request $request, $user)
{
// Chrome, IE, Safari, Firefox, ...
$agent = new Agent();
$browser = $agent->browser();
// Ubuntu, Windows, OS X, ...
$platform = $agent->platform();
$user->update([
'last_signin' => Carbon::now()->toDateTimeString(),
'ip_address' => $request->getClientIp(),
'browser_login' => $agent->browser(),
'browser_version' => $agent->version($browser),
'device_login' => $agent->platform(),
'device_version' => $agent->version($platform),
'current_location' => GeoIP::getLocation('2405:204:970a:d9b3:10a3:5280:9064:3f31'),
'language' => $agent->languages(),
'root' => $agent->robot(),
'https' => $request->server('HTTP_USER_AGENT'),
]);
}
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest',['except'=>['logout', 'userLogout', 'profile']]);
}
public function userLogout()
{
Auth::guard('web')->logout();
return redirect('/');
}
}
Auth Route :
//User Auth Route Function
Auth::routes();
This is happending because GeoIP::getLocation('2405:204:970a:d9b3:10a3:5280:9064:3f31') returns an instance of Torann\GeoIP\Location and you are trying to save it as a String.
Checking the documentation of this object it has this shape:
\Torann\GeoIP\Location {
#attributes:array [
'ip' => '232.223.11.11',
'iso_code' => 'US',
'country' => 'United States',
'city' => 'New Haven',
'state' => 'CT',
'state_name' => 'Connecticut',
'postal_code' => '06510',
'lat' => 41.28,
'lon' => -72.88,
'timezone' => 'America/New_York',
'continent' => 'NA',
'currency' => 'USD',
'default' => false,
]
}
You have to choose a way to represent this location as a String, a possible way can be to save the latitude and the longitude separately.
If you need to use only one column at the DB, you can check some GeoHashing implementations skthon/geogash.
You Might be trying to use getLocation method from wrong instance.
1.) Try as below way :
"use Torann\GeoIP\GeoIPFacade as GeoIP"
$location = GeoIP::getLocation();
2.) Or try as Geoip package documentation suggest here (http://lyften.com/projects/laravel-geoip/doc/methods.html)
from this instance \Torann\GeoIP\GeoIP and then use geoip()->getLocation('27.974.399.65');
This seems to be an issue in the current_location field and how it is typed in your database. From what I read, I guess your field is defined a string, and when trying to save your record to the database, it fails since the data you're trying to save is an Location object.
I would recommend changing your current_location column in your database to make it a json type.
Then you'd be able to insert your data as:
$user->update([
'last_signin' => Carbon::now()->toDateTimeString(),
'ip_address' => $request->getClientIp(),
'browser_login' => $agent->browser(),
'browser_version' => $agent->version($browser),
'device_login' => $agent->platform(),
'device_version' => $agent->version($platform),
'current_location' => json_encode(GeoIP::getLocation('2405:204:970a:d9b3:10a3:5280:9064:3f31')->toArray()),
'language' => $agent->languages(),
'root' => $agent->robot(),
'https' => $request->server('HTTP_USER_AGENT'),
]);

Resources