How do I call model function on create event? Laravel-5 - php

I'm trying to create a referral url when a user is first created.
My function inside my User model looks like this:
private function make_url()
{
$url = str_random(40);
$this->referral_url->url = $url;
if ($this->save()){
return true;
}
else{
return false;
}
}
Within the model, I've tried doing this but didn't work
USER::creating(function ($this){
$this->make_url();
})
I also tried calling it in my User Controller within the create user action
public function create(UserRequest $request)
{
$data = $request->all()
$data['password']= bcrypt($request->input('password'));
if($user=User::create($data))
{
$user->make_url();
}
}
I get this error in return
Indirect modification of overloaded property App\User::$referral_url has no effect
Thanks in advance for your help guys =]
p.s: If there's a better way to go about creating referral urls please tell me.
update
My entire user model
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword;
protected $table = 'users';
protected $fillable = [
'first_name',
'last_name',
'url',
'email',
'password',
'answer_1',
'answer_2',
'answer_3'
];
protected $hidden = ['password', 'remember_token'];
public function make_url()
{
$url = str_random(40);
$this->referral_url->url = $url;
if ($this->save()){
return true;
}
else{
return false;
}
}
public function user_info()
{
return $this->hasOne('App\UserInfo');
}
public function sec_questions()
{
return $this->hasOne('App\SecurityQuestions');
}
public function referral_url()
{
return $this->hasOne('App\ReferralUrl');
}
}
update
I modified the function in the model to look like this now.
public function make_url()
{
$url = str_random(40);
$referral_url = $this->referral_url;
$referral_url = new ReferralUrl();
$referral_url->user_id = $this->id;
$referral_url->url = $url;
if ($referral_url->save()){
return true;
}
else{
return false;
}
}
When I call
$user->make_url()
I'm able to create it and it shows up in my db, but I also get the error-
Trying to get property of non-object

Normally the creating method should be called within boot():
public static function boot() {
parent::boot();
static::creating(function ($model) {
$model->foo = 'bar';
});
}
This would then be called automatically before the model is saved for the first time.
The problem that I see with your code is that you're attempting to modify a relation which doesn't exist yet.
So to explain, the hasOne method will attempt to join the current model to the remote model (in your case a ReferralUrl model) in SQL, but it can't do that before you save your model because your model doesn't exist in the database.
With your second attempt, the ReferralUrl object is the one that is changing, so that is the one that you need to save:
public function make_url() {
$url = str_random(40);
$referral_url = $this->referral_url
$referral_url->url = $url;
if ($referral_url->save()){
return true;
} else {
return false;
}
}

Related

How to obtain three level model data laravel

Updated
User model
class User extends Authenticatable
{
use HasFactory, Notifiable, HasApiTokens, HasRoles;
const MALE = 'male';
const FEMALE = 'female';
protected $guard_name = 'sanctum';
public function educationalBackgrounds()
{
return $this->hasMany("App\Models\Users\EducationalBackground", "user_id");
}
public function seminars()
{
return $this->hasMany("App\Models\Users\Seminar", "user_id");
}
}
I have child table EducationalBackground which is related to User table
class EducationalBackground extends Model
{
use HasFactory;
protected $table = 'users.educational_backgrounds';
protected $fillable = [
'user_id',
'studies_type',
'year',
'course',
];
public function user()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
public function educationalAwards()
{
return $this->hasMany("App\Models\Users\EducationalAward", "educational_background_id");
}
}
And a third table that i want to access the award field
class EducationalAward extends Model
{
use HasFactory;
protected $table = 'users.educational_awards';
protected $fillable = [
'educational_background_id',
'award',
'photo',
];
public function educationalBackground()
{
return $this->belongsTo('App\Models\Users\EducationalBackground', 'educational_background_id');
}
}
I have api get route here
Route::get('/educational-background/{id}', [UserProfileController::class, 'getEducationalBackground']);
Here is my api method it works fine. But i want to go deeper and access the data of third table.
public function getEducationalBackground($id)
{
$educationalBackground = EducationalBackground::with('user')->where('user_id', $id)->get();
return response()->json($educationalBackground, 200);
}
It looks like you're not really grasping the concept of relations yet. Also, I'd advise you to look into route model binding :) What you basically want to be doing is:
public function getEducationalBackground($id)
{
$user = User::find($id);
return $user->educationalBackgrounds()->with('educationalAwards')->get();
}
Also, when you're pretty sure that whenever you want to use backgrounds, you also want to use the awards, you can add the with(...) to the model definition like so:
class EducationalBackground extends Model
{
...
protected $with = ['educationalAwards'];
}
That way, you can simplify your controller method to:
public function getEducationalBackground($id)
{
$user = User::find($id);
return $user->educationalBackgrounds;
}

How to build login system in Codeigniter 4?

I want to build a login system using Codeigniter 4.
But I face some error.
I have some data in Users_model;
Here is my some codes:
Controller/Signin.php
<?php
namespace App\Controllers;
use App\models\Users_model;
class Signin extends BaseController {
public function index() {
return view('signin/index');
}
public function authenticate() {
if ($this->exists($_POST['email'], $_POST['password']) != NULL) {
$session = session();
$session->set('email', $_POST['email']);
return $this->response->redirect(site_url('signin/profile'));
} else {
$data['msg'] = 'wrong';
return view('signin', $data);
}
}
public function profile() {
return view('signin/profile');
}
private function exists($email, $password) {
$model = new Users_model();
$account = $model->where('email', $email)->first();
if ($account != NULL) {
if (password_verify($password, $account['password'])) {
return $account;
}
}
return NULL;
}
}
Models/Users_model.php
<?php
namespace App\models;
use CodeIgniter\Model;
class Users_model extends Model {
protected $table = 'users';
protected $primaryKey = 'id';
protected $allowedFields = ['first_name', 'last_name', 'email', 'password'];
}
But I face this error:
Please help me.
Or please someone suggest me a login system in another way in Codeigniter 4?
If you want to make login system, I suggest you to use validation to make user is valid and redirect to another controller or view. Then you can use filter to check that user is logged in or not and adding some routes filter to protect other controller.
First read this Codeigniter 4.0.4 documentation https://codeigniter4.github.io/userguide/libraries/validation.html
You could search anything you need there.
return view('signin', $data);
for
return view('signin/index', $data);

Laravel query with multiple where not returning expected result

I'm trying to build a query from a Repository in a Model with 2 where clauses.
This is the data I have in a MySql table:
id name environment_hash
1 online_debit abc
2 credit_cart abc
I want to query by name and environment_hash. To do this, I created the method findByHashAndMethod() (see below).
But when I use it in my controller, like this:
$online_debit = $this->ecommercePaymentMethodRepository->findByHashAndMethod($hash, 'online_debit')->first();
or this:
$credit_card = $this->ecommercePaymentMethodRepository->findByHashAndMethod($hash, 'credit_cart')->first();
I keep getting both rows and not only the ones filtered. What's wrong with the code?
This is my PaymentMethodRepository.php
class EcommercePaymentMethodRepository extends BaseRepository
{
public function findByHashAndMethod($hash = null, $payment_method)
{
$model = $this->model;
if($hash)
{
$filters = ['environment_hash' => $hash, 'name' => $payment_method];
$this->model->where($filters);
}
else
{
$this->model->where('environment_hash', Auth::user()->environment_hash)
->where('name', $payment_method);
}
return $model;
}
public function model()
{
return EcommercePaymentMethod::class;
}
}
And this is my model EcommercePaymentMethod.php
<?php
namespace App\Models;
use Eloquent as Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class EcommercePaymentMethod extends Model
{
use SoftDeletes;
public $table = "ecommerce_payment_methods";
protected $dates = ['deleted_at'];
public $fillable = [
"name",
"payment_processor_id",
"active",
"environment_hash"
];
protected $casts = [
"name" => "string"
];
public function payment_processor()
{
return $this->hasOne('App\Models\EcommercePaymentProcessor');
}
}
While I am not entirely sure why ->first() would ever return more than one result, your Repository method had some few glaring issues that's prone to errors.
class EcommercePaymentMethodRepository extends BaseRepository
{
// 1. Do not put optional parameter BEFORE non-optional
public function findByHashAndMethod($payment_method, $hash = null)
{
// 2. Call ->model() method
$model = new $this->model();
// 3. Logic cleanup
if (is_null($hash)) {
$hash = Auth::user()->environment_hash;
}
return $model->where('environment_hash', $hash)
->where('name', $payment_method);
}
public function model()
{
return EcommercePaymentMethod::class;
}
}

laravel 4 hasOne/ hasMany / belongsTo doesn't work

I have some models belong to Activity Model.
in my Activity.php I had
<?php
class Activity extends \Eloquent {
protected $fillable = [];
public function activity_car_nums()
{
return $this->hasMany('ActivityCarNum');
}
public function newables()
{
return $this->hasMany('Newable');
}
public function serial_codes()
{
return $this->hasMany('SerialCode');
}
public function applys()
{
return $this->hasMany('Apply');
}
}
and in SerialCode.php, I had
<?php
class SerialCode extends \Eloquent {
protected $fillable = ['code'];
public function activity()
{
return $this->belongsTo('Activity');
}
}
and in my controller, when I wrote
$serial_codes = [];
while(count($serial_codes) < $serial_code_total)
{
$code = substr(md5(uniqid(rand(), true)),0,5);
$serial_code = new SerialCode(['code' => $code]);
if(!in_array($serial_code, $serial_codes))
{
$serial_codes[] = $serial_code;
}
}
$activity->serial_codes()->saveMany($serial_codes);
it works.
But when it turns to
//this can get activity object
$activity = Activity::find($id);
//this can get the serial codes of the object above.
$serial_codes = SerialCode::whereActivityId($id)->get();
//this don't work, it returns null
$serial_codes = $activity->serial_codes;
for I really don't know why...
Can anybody help me please, and sorry for my poor English. Thank You.
(If you need any code else please tell me.)
my model code:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use DB;
class Product extends Model
{
public $table="s_products";
protected $primaryKey = 'product_id';
public function reviews()
{
return $this->hasMany('App\ProductReview');
}
public function attributes()
{
return $this->hasMany('App\AttributeMapping');
}
public function images()
{
return $this->hasMany('App\Image');
}
}
I found the reason that why my model query cannot work, because the "_" in function name.
just change
public function serial_codes()
to
public function serialcodes()
then everything will go fine.
Thank to everybody.

Laravel Model Events don't fire

I have a model with this code:
<?php
use Illuminate\Database\Eloquent\SoftDeletingTrait;
class Intervention extends Eloquent {
use SoftDeletingTrait;
protected $fillable = array('start_date','stove_id','description','operation_mode','store_id','user_id','intervention_status_id','code');
public function operations()
{
return $this->hasMany('InterventionOperation');
}
public function store()
{
return $this->belongsTo('Store');
}
public function stove()
{
return $this->belongsTo('Stove');
}
public function user()
{
return $this->belongsTo('User');
}
public function statues()
{
return $this->hasMany('InterventionStatus');
}
then the boot
public static function boot()
{
parent::boot();
static::creating(function($intervention)
{
exit("creating");
});
static::created(function($intervention){
exit("created");
});
static::updating(function($intervention)
{
exit("updating");
});
}
the controller:
$intervention = new \Intervention(\Input::all());
$status = \Status::find(\Input::get('status')['id']);
$interventionStatus = new \InterventionStatus();
$interventionStatus->change_status_date = new \DateTime();
$interventionStatus->status()->associate($status);
$interventionStatus->description = "";
$user = \Auth::user();
$store = $user->store;
$intervention->store()->associate($store);
$intervention->user()->associate($user);
$intervention->request_date = new \DateTime();
$intervention->save();
...
but when save model, creating callback is not call.
I have try put exit("test") after parent::boot(); and exit is triggered.
If I put event's code in app/start/global.php it work.
I have try use the code in another model and work.
I do not know why it does not work.
Resolved:
I recreated the database and now everything works. Probably, in the various attempts to save, some relationship was skipped.
Thank you all for the help!
I think this has something to with the namespaces and registering the correct class in the event. Let's hack the source code a bit :)
In: /vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php
Add:
public function getAllEvents()
{
return array_keys($this->listeners);
}
And call/dump Event::getAllEvents();
Try this for both cases (boot in the model and in the global.php) and compare.

Categories