i have a problem in my project. How to create a flash session in class request / validation ? I haven't found a way.
This my Request class code
class UserRequest extends FormRequest {
public function authorize()
{
return TRUE;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
$rules = [
"user_fullname" => "required|alpha_spaces",
"user_email" => "required|email|unique,list_user,user_email",
"user_phone" => "nullable|numeric",
"access_id" => "required|alpha_num_spaces",
"user_password" => "required|min:6|regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9]).*$/|confirmed",
"warehouse_id" => "alpha_num_spaces|nullable",
];
if ($this->method() == "POST") {
$rules["province_id"] = "alpha_num_spaces|nullable";
$rules["district_id"] = "alpha_num_spaces|nullable";
$rules["subdistrict_id"] = "alpha_num_spaces|nullable";
$rules["kode_pos"] = "alpha_num_spaces|nullable";
$rules["user_address"] = "alpha_num_spaces|nullable";
}
return $rules;
}
public function messages()
{
return [
"user_password.regex" => "Password wajib terdiri dari huruf & angka!"
];
}
}
This my controller
public function process_user_add(UserRequest $user_request)
{
$user_request->validated();
$request = \request();
$input = (object) \request()->all();
$check = User::add_user_from_owner($input);
if ($check->success) {
return \redirect()->to("administrator/user/" . \encrypt_url($check->id))->with("message", "<script>sweet('success', 'Success!', '$check->message')</script>");
} else {
return \redirect()->back()->with("message", "<script>sweet(\"error\", \"Failed!\", \"$check->message\")</script>")->withInput($request->all());
}
}
How to i check if validation failed, i create a flash message? To my knowledge, class request is auto redirect goback url if validation error
You can use die Validator Facade. Validator::make() After then you can rescieve the fails with the fails() Method. Take a look in the code below:
$rules = array(
"user_fullname" => "required|alpha_spaces",
"user_email" => "required|email|unique,list_user,user_email",
"user_phone" => "nullable|numeric",
"access_id" => "required|alpha_num_spaces",
"user_password" => "required|min:6|regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9]).*$/|confirmed",
"warehouse_id" => "alpha_num_spaces|nullable",
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails())
{
return Redirect::to('/your_url')->withInput()->withErrors($validator);
}
This section from the documentation will point you to the right direction
Related
Hello I have this method that mass create student sections
Enrollment controller method this code works fine but it doesn't get in my studentSectionObserver. Although it's getting saved one by one with for loop.
public function setStudentsSection(Request $request)
{
$enrollments = Enrollment::whereIn('student_id', $request->students)->where('session_id', $request->session_id)->get();
$program_section = ProgramSection::withCount('students')->find($request->program_section_id);
if(($program_section->students_count + count($enrollments)) <= $program_section->max_students) {
$new_student_sections = array();
foreach($enrollments as $enrollment) {
$data = [
'student_id' => $enrollment->student_id,
'enrollment_id' => $enrollment->id,
'section_id' => $request->program_section_id,
'created_at' => Carbon::now()
];
array_push($new_student_sections, $data);
}
return StudentSection::insert($new_student_sections);
}
return response()->json(['errors' => ['message' => 'Selected Section is full.']], 405);
}
Then i output this activity with studentSectionObserver and added log::info but it doesn't log anything
public function created(StudentSection $student_section)
{
Log::info('test');
$student = $student_section->student()->get()->first();
$section = $student_section->section()->get()->first();
Logger::createLog("Assigned " . $student->first_name . " " . $student->last_name . " '" . $section->section->name . "'");
}
I know this observer gets triggered cause i tested it with this method whenever i add section the studentSectionObserver triggers Logger.
public function enrollStudent(EnrollmentRequest $request)
{
$check_if_exist = Enrollment::where('student_id', $request->student_id)->where('session_id', $request->session_id)->first();
if (!$check_if_exist) {
$program_section = ProgramSection::withCount('students')->find($request->section_id);
if($program_section) {
if($program_section->students_count < $program_section->max_students) {
$enrollment = Enrollment::create($request->all());
$section_data = ['student_id' => $request->student_id, 'section_id' => $request->section_id, 'enrollment_id' => $enrollment->id];
$section = StudentSection::create($section_data);
return response()->json($enrollment, 200);
}
return response()->json(['errors' => ['message' => 'Selected Section is full.']], 405);
}
$enrollment = Enrollment::create($request->all());
return response()->json($enrollment, 200);
}
return response()->json(['errors' => ['message' => 'Student is already enrolled in this session.']], 405);
}
Any help would be greatly appreciated.
As you have figured out the answer on your own.
The reason for using create method is because it triggers the event on the model. Same goes for update method.
Following is the update method under the hood:
/**
* Update the model in the database.
*
* #param array $attributes
* #param array $options
* #return bool
*/
public function update(array $attributes = [], array $options = [])
{
if (! $this->exists) {
return false;
}
return $this->fill($attributes)->save($options);
}
And the save method has these lines of code:
if ($this->fireModelEvent('saving') === false) {
return false;
}
Similarly, create method works. That's why insert doesn't trigger the event on model and you had to use create method.
Turns out i just need to use create method.
public function setStudentsSection(Request $request)
{
$enrollments = Enrollment::whereIn('student_id', $request->students)->where('session_id', $request->session_id)->get();
$program_section = ProgramSection::withCount('students')->find($request->program_section_id);
if(($program_section->students_count + count($enrollments)) <= $program_section->max_students) {
foreach($enrollments as $enrollment) {
$response = StudentSection::create([
'student_id' => $enrollment->student_id,
'enrollment_id' => $enrollment->id,
'section_id' => $request->program_section_id,
'created_at' => Carbon::now()
]);
return $response;
}
}
return response()->json(['errors' => ['message' => 'Selected Section is full.']], 405);
}
Laravel observer doesn't work on bulk objects, it only works with single object.
So when you use create() function it will trigger the observer.
i want to validate data if data is not exsist in database on update case
my controller
public function update(Request $request )
{
$no = DB::table('member')->where('id',$request->id)->select('nokartu');
$plat1 = DB::table('member')->where('id',$request->id)->select('nopol');
$plat2 = DB::table('member')->where('id',$request->id)->select('nopol2');
$data = member::find($request->id);
$data->nokartu = $request->nokartu;
$data->nama = $request->nama;
$data->paket = $request->paket;
$data->jenisk = $request->jenisk;
$data->tipe = $request->tipe;
$data->nopol = $request->nopol;
$data->nopol2 = $request->nopol2;
$data->awal = $request->awal;
$data->akhir = $request->akhir;
this my validate to check if data was not exsist in data base
if (!($no == $request->nokartu)) {
if (member::where('nokartu', '=', $request->nokartu)->count() > 0)
{
$data=member::find($request->id);
$produk['data'] = DB::table('produk')->get();
return view('member.edit', ['produk'=> $produk],['member'=>$data])->withMessage( 'Kartu sudah dipakai');
}
}
$data->save();
return redirect('/member')->with(['success' => 'Data berhasil di simpan']);
You can use a form request to validate the requests. https://laravel.com/docs/8.x/validation#form-request-validation.
It can be done by doing some thing like this
// Controller
public function update(UpdateModelRequest $request) {...}
// UpdateModelRequest
use Illuminate\Validation\Rule;
...
public function rules(): array
{
return [
'nokartu' => ['required', 'string'],
'id' => ['required', 'int', Rule::exists('member', 'id)]
}
NotiMail.php
public $notiInfo;
public function __construct($notiInfo)
{
$this->type = $notiInfo->type;
$this->name = $notiInfo->name;
}
public function build()
{
if($this->type=="Document") {
return $this->markdown('emails.statusDoc')->with('name', $this->name);
}
elseif($this->type=="Announcement") {
return $this->markdown('emails.statusTap')->with('name', $this->name);
}
}
AnnouncementController.php
use Illuminate\Support\Facades\Mail;
use App\Mail\NotiMail;
public function store(Request $request)
{
$hawkers = Hawker::select('hawker_id')->get();
$request->validate([
'announce_title' => ['required', 'unique:announcements,title'],
'announce_desc' => ['required'],
]);
$current = new Carbon('now', 'UTC');
$Mtime = $current->addHours(8);
$announce = new Announcement();
$announce->title = $request->input('announce_title');
$announce->desc = $request->input('announce_desc');
$announce->announce_date = $Mtime;
$announce->save();
foreach ($hawkers as $hawk) {
$noti = new Notification();
$noti->hawker_id = $hawk->hawker_id;
$noti->title = $request->input('announce_title');
$noti->desc = $request->input('announce_desc');
$noti->notiDate = $Mtime;
$noti->save();
$hawker = Hawker::find($hawk->hawker_id);
$notiInfo = [
'name' => $hawker->name,
'type' => "Announcement"
];
Mail::to($hawker->email)->send(new NotiMail($notiInfo));
}
return redirect()->route('announcement.index')->with('success', "Announcement made!");
}
The error appears from NotiMail.php. Most of the solutions where because the public variable was not included. However, as you can see i already have. Yet the array from AnnouncementController does not seem to pass the values to NotiMail.php.
<?php
namespace frontend\controllers;
use Yii;
use common\models\Subscriber;
use common\models\SubscriberSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
/**
* SubscriberController implements the CRUD actions for Subscriber model.
*/
class SubscriberController extends Controller
{
/**
* Creates a new Subscriber model.
* If creation is successful, the browser will be redirected to the 'view' page.
* #return mixed
*/
public function actionSubscribe()
{
$model = new Subscriber();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail()) {
Yii::$app->session->setFlash('success', 'You have successfully subscribed My-Blog. You will get notification whenever New post is published');
return $this->goHome();
} else {
Yii::$app->session->setFlash('error', 'Sorry, we are unable to subscribe for the provided email address.');
}
}
return $this->render('create', [
'model' => $model,
]);
}
/**
* Finds the Subscriber model based on its primary key value.
* If the model is not found, a 404 HTTP exception will be thrown.
* #param integer $id
* #return Subscriber the loaded model
* #throws NotFoundHttpException if the model cannot be found
*/`enter code here`
}
using following model :
<?php
namespace common\models;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveRecord;
use yii\db\Expression;
/**
* This is the model class for table "subscriber".
*
* #property int $id
* #property string $email
* #property string $token
* #property int $status
* #property int $created_at
* #property int $updated_at
*/
class Subscriber extends \yii\db\ActiveRecord
{
const STATUS_DEACTIVE = 0;
const STATUS_ACTIVE = 1;
/**
* #inheritdoc
*/
public static function tableName()
{
return 'subscriber';
}
public function behaviors()
{
return [
'timestamp' => [
'class' => TimestampBehavior::className(),
'attributes' => [
ActiveRecord::EVENT_BEFORE_INSERT => ['created_at', 'updated_at'],
ActiveRecord::EVENT_BEFORE_UPDATE => ['updated_at'],
],
'value' => new Expression('NOW()'),
],
];
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['email'], 'required'],
[['status', 'created_at', 'updated_at'], 'integer'],
[['email'], 'string', 'max' => 60],
[['token'], 'string', 'max' => 255],
[['token'], 'unique'],
[['email'], 'unique', 'targetClass' => '\common\models\Subscriber', 'message' => 'This email has already subscribed our blog.','filter' => ['!=','status' ,0]],
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'email' => 'Email',
'token' => 'Token',
'status' => 'Status',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}
/**
* Generates subscriber token
*/
public function generateSubscriberToken()
{
return $this->token = Yii::$app->security->generateRandomString() . '_' . time();
}
/**
* Send Email when successfully subscribe
*/
public function sendEmail()
{
$subscribers = Subscriber::find()->where(['email' => $this->email, 'status' => 0,])->one();
if(!$subscribers)
{
$this->generateSubscriberToken();
if(!$this->save())
{
return false;
}
return Yii::$app->mailer
->compose()
->setFrom(['noreply#my-blog.com' => Yii::$app->name . ' robot'])
->setTo('piyush#localhost')
->setSubject('Subscription : ' . Yii::$app->name)
->setHtmlBody('Thank you '.$this->email.' for subscribing '.Yii::$app->name.'<br /><br /> You will receive notification whenever new trick or post is published to website')
->send();
}
$subscribers->generateSubscriberToken();
$subscribers->status = 1;
if(!$subscribers->save())
{
return false;
}
return Yii::$app->mailer
->compose()
->setFrom(['noreply#my-blog.com' => Yii::$app->name . ' robot'])
->setTo('piyush#localhost')
->setSubject('Subscription : ' . Yii::$app->name)
->setHtmlBody('Welcome back '.$this->email.'Thank you for subscribing '.Yii::$app->name.'<br /><br /> You will receive notification whenever new trick or post is published to website')
->send();
}
}
This controller and model are being used to make subscribe activity using email. I want that IF a user has unsubscribed and after some time again want to subscribe then update status = 1 and regenerate token. Above sendEmail is working fine if it's a new subscriber but if it is an old subscriber with status 0 then not working.
Above all, you need to replace the lines
$subscribers->generateSubscriberToken();
$subscribers->status = 1;
with
$subscriber->token =$this->generateSubscriberToken();
$subscribers->status = 1;
as in your function you are setting $this->token and returning it and to update the record you need to set the $subcribers->token filed with the value.
And you should not search the table for the email with status 0 just query the email and check in PHP if status ==0 because a new record should only be entered if the email does not exist, without caring what the status field has so in your case if the email exists but with status =1 your query won't fetch the record and it will try to insert a record instead of doing nothing.
To understand you can try using var_dump(!$subscribers) in both cases an see what it returns.
Moreover, you are repeating things like sending email and token generation you should change your function to the below.
public function sendEmail()
{
$subscribers = self::find()->where(['email' => $this->email])->one();
//set flag for sending email
$sendMail = false;
//email subject
$subject = '';
//generate token
$token = $this->generateSubscriberToken();
//if email found in subscribers
if ($subscribers !== null) {
//check if inactive
if ($subscribers->status !== self::STATUS_ACTIVE) {
//assign token
$subscribers->token = $token;
//set status to active
$subscribers->status = self::STATUS_ACTIVE;
//update the recrod
if (!$subscribers->save()) {
return false;
}
//set subject
$subject = 'Welcome back ' . $this->email . 'Thank you for subscribing ' . Yii::$app->name . '<br /><br /> You will receive notification whenever new trick or post is published to website';
$sendMail = true;
}
} else { //if email does not exist only then insert a new record
$this->status = 1;
if (!$this->save()) {
return false;
}
$subject = 'Thank you ' . $this->email . ' for subscribing ' . Yii::$app->name . '<br /><br /> You will receive notification whenever new trick or post is published to website';
$sendMail = true;
}
//check if send mail flag set
if ($sendMail) {
return Yii::$app->mailer
->compose()
->setFrom(['noreply#my-blog.com' => Yii::$app->name . ' robot'])
->setTo('piyush#localhost')
->setSubject('Subscription : ' . Yii::$app->name)
->setHtmlBody($subject)
->send();
}
}
I'm trying to get my controller cleaner by moving 'validation request' into a form request called 'BookRequest'.
The problem is on the update process, I try to create a condition to check, if it PATCH or POST with the following codes
MyRequest.php
public function rules()
{
// Check Create or Update
if ($this->method() == 'PATCH')
{
$a_rules = 'required|string|size:6|unique:books,column2,' .$this->get('id');
$b_rules = 'sometimes|string|size:10|unique:books,column3,' .$this->get('id');
}
else
{
$a_rules = 'required|string|size:6|unique:books,column2';
$b_rules = 'sometimes|string|size:10|unique:books,column3';
}
return [
'column1' => 'required|string|max:100',
'column2' => $a_rules,
'column3' => $b_rules,
'column4' => 'required|date',
'column5' => 'required|in:foo,bar',
'column6' => 'required',
'column7' => 'required',
'column8' => 'required',
];
}
.$this->get('id') it failed, the form still treat the unique on the update.
Controller#update
public function update($id, BookRequest $request)
{
$book = Book::findOrFail($id);
$input = $request->all();
$book->update($request->all());
return view('dashboards.book');
}
Controller#edit
public function edit($id)
{
$book = Book::findOrFail($id);
return view('dashboards.edit', compact('book'));
}
Controller#create
public function create()
{
return view('dashboards.create');
}
Controller#store
public function store(BookRequest $request)
{
$input = $request->all();
$book = Book::create($input);
return redirect('dashboards/book/index');
}
I try the alternative .$book->id, and it throw me an ErrorException Undefined variable: book
Any suggestion? I'm using Laravel 5.2 by the way
You are using book as your route parameter but trying to get with id. try this-
if ($this->method() == 'PATCH')
{
$a_rules = 'required|string|size:6|unique:books,column2,' .$this->route()->parameter('book');
$b_rules = 'sometimes|string|size:10|unique:books,column3,' .$this->route()->parameter('book');
}
Hope it helps :)