I need to store an expiration date in my database to check if the user account is still valid when he/she try to log in.
This is my User model:
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
protected $dates = [
'expiration_date'
];
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'first_name',
'last_name',
'email',
'password',
'expiration_date'
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token'
];
/**
* Questa funzione fa in modo di criptare in automatico la password quando si crea un utente
*
* #param $password
*
* #return string
*/
public function setPAsswordAttribute( $password )
{
return $this->attributes['password'] = bcrypt( $password );
}
public function setExpirationDateAttribute( $expiration )
{
return $this->attributes['expiration_date'] = Carbon::createFromDate('Y-m-d', $expiration);
}
}
In my form I have a text input that uses datepicker to set a tabe in dd/mm/yyyy format.
When I press submit in the DB I get only 0000-00-00 00:00:00
What is the problem?
As you can see from the code, Carbon::createFromDate($year = null, $month = null, $day = null, $tz = null) method accepts 4 parameters and you are passing invalid arguments to it.
I believe that the method you are looking for is Carbon::createFromFormat($format, $time, $tz) which accepts format, string with date or time and DateTimeZone instance or a string timezone as parameters.
Related
I'm using Laravel Notification and i want to save data in my database table if i write my insert query then i'm getting following error otherwise Notification are running :
TypeError: Return value of App\User::getLogNameToUse() must be of the
type string, null
This is the query
public function toMail($notifiable)
{
$users = User::find($notifiable->id);
$users->verification_link=$link;
$users->save();
...
...
}
Model:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use App\Notifications\ResetPasswordNotification;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Activitylog\Traits\LogsActivity;
class User extends Authenticatable
{
use Notifiable, LogsActivity;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'role_id', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function role()
{
return $this->belongsTo(Models\Role::class);
}
}
Seems like the error is with the logName and without looking at more code and data it is difficult to pinpoint exactly what is wrong.
Following could work
/**
* Get the log name to use for the model.
*
* #param string $eventName
* #return string
*/
public function getLogNameToUse(string $eventName = ''): string
{
return Str::kebab(Str::plural(class_basename($this)));
}
This is just overriding the piece of code causing issue. Give it a try.
I have a model called Address. It has an 'additional' attribute. Although the attribute is filled, the model returns an empty array. I use an API resource to get the data.
This is the Address model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Address extends Model
{
use HasFactory;
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'addresses';
/**
* The primary key associated with the table.
*
* #var string
*/
protected $primaryKey = 'id';
/**
* Indicates if the model's ID is auto-incrementing.
*
* #var bool
*/
public $incrementing = true;
/**
* Indicates if the model should be timestamped.
*
* #var bool
*/
public $timestamps = false;
/**
* The database connection that should be used by the model.
*
* #var string
*/
protected $connection = 'solarium';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
//
];
/**
* The attributes that aren't mass assignable.
*
* #var array
*/
protected $guarded = [];
/**
* The model's default values for attributes.
*
* #var array
*/
protected $attributes = [
//
];
/**
* The attributes that should be cast.
*
* #var array
*/
protected $casts = [
//
];
public function addressable()
{
return $this->morphTo();
}
}
This is the Address API resource:
<?php
namespace App\Http\Resources;
use App\Models\Address;
use Illuminate\Http\Resources\Json\JsonResource;
class AddressResource extends JsonResource
{
/**
* The resource that this resource collects.
*
* #var string
*/
public $collects = Address::class;
/**
* Indicates if the resource's collection keys should be preserved.
*
* #var bool
*/
public $preserveKeys = true;
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'cep' => $this->cep,
'street' => $this->street,
'number' => $this->number,
'district' => $this->district,
'city' => $this->city,
'state' => $this->state,
'additional' => $this->additional,
];
}
}
As I said, the 'additional' attribute returns an empty array although it is filled with a string value.
The JsonResource has a public property named additional which has a default value of [], an empty array. That is what you are accessing since $this->additional is asking for that property. This is not forwarding that access to the model (resource) since this is an accessible property on this instance, (how PHP's OOP works).
You would probably have to access the underlying resource from the property of the JsonResource to then access that particular property (attribute):
$this->resource->additional
EDIT:
in novas ActionEvent.php class i edited the two rows fields and exceptions for the forResourceUpdate function:
Whats actually strange now my resource is updated but there is nothing in the ACTION EVENT table.
public static function forResourceUpdate($user, $model)
{
return new static([
'batch_id' => (string) Str::orderedUuid(),
'user_id' => $user->getKey(),
'name' => 'Update',
'actionable_type' => $model->getMorphClass(),
'actionable_id' => $model->getKey(),
'target_type' => get_class($model),
'target_id' => $model->getKey(),
'model_type' => get_class($model),
'model_id' => $model->getKey(),
'fields' => 'test',
'status' => 'finished',
'exception' => 'test',
]);
}
so i just installed Nova set up some Resources, it shows everything fine, but when i try to update any of them, i get a Database error that i cant insert NULL into ACTION_EVENT.FIELDS.
https://nova.laravel.com/docs/1.0/actions/defining-actions.html#action-fields
The Doc says i can define some fields in the Actions fields function , but i didnt generate any Action class not i want to. I think its some sort of default action logging?
Can i turn it off, or do i have to add some Fields somewhere?
<?php
namespace App\Nova;
use Laravel\Nova\Fields\ID;
use Illuminate\Http\Request;
use Laravel\Nova\Http\Requests\NovaRequest;
class Chain extends Resource
{
public static $category = "Stammdaten";
/**
* The model the resource corresponds to.
*
* #var string
*/
public static $model = 'App\Model\System\Partner\Chain';
/**
* The single value that should be used to represent the resource when being displayed.
*
* #var string
*/
public static $title = 'id';
/**
* The columns that should be searched.
*
* #var array
*/
public static $search = [
'id',
];
/**
* Get the fields displayed by the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function fields(Request $request)
{
return [
ID::make()->sortable(),
];
}
/**
* Get the cards available for the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function cards(Request $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function filters(Request $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function lenses(Request $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function actions(Request $request)
{
return [];
}
}
And The Model:
class Chain extends Model
{
use SoftDeletes;
use ObservantTrait;
use TranslationTrait;
protected $primaryKey = 'partner_chain_id';
protected $table = 'tbl_prm_partner_chain';
public $sequence = 'seq_partner_chain_id';
const CREATED_BY = 'insert_user';
const CREATED_AT = 'insert_timestamp';
const UPDATED_BY = 'update_user';
const UPDATED_AT = 'update_timestamp';
const DELETED_BY = 'delete_user';
const DELETED_AT = 'delete_timestamp';
protected $fillable = ['name_text', 'partner_type_id'];
protected $dates = ['delete_timestamp', 'insert_timestamp'];
thats all its quit simple, thats why i have no Clue right now where i am going wrong.
I am new to laravel and now trying to learn policies so I created the following models:
class group extends Model
{
protected $fillable = [
'id','book_id',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
public function users(){
return $this->belongsToMany('BOOK_DONATION\User')->withPivot('last_seen_id');
}
}
and :
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email','country','state/provience','city', 'token', 'password','postal_code',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password','verfied', 'remember_token',
];
public function Book(){
return $this->hasMany('App\Book');
}
public function groups(){
return $this->belongsToMAny('BOOK_DONATION\group')->withPivot('last_seen_id');
}
}
and :
class group_user extends Model
{
//
protected $table='group_user';
protected $fillable = [
'user_id','group_id','last_seen_id'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
];
}
now the group_user is model for the intermidate table required for the many to many relation between users and groups
and here is my policy:
class group_userPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the group_user.
*
* #param \BOOK_DONATION\User $user
* #param \BOOK_DONATION\group_user $groupUser
* #return mixed
*/
public function view(User $user, group_user $groupUser)
{
//
return in_array($user->id,$groupUser->user_id);
}
}
and here is the specific programming lines from controller related :
$grouUser=group_user::where('group_id',$group_id)->pluck('user_id');
if(Auth::user()->cant('joinChat',$grouUser)) return redirect('/sorry');
now I always get redirected to sorry page but I have the right yo join chat so what is wrong?
In a nutshell, I want to create a function that my query scopes can use across multiple models:
public function scopeNormaliseCurrency($query,$targetCurrency) {
return $query->normaliseCurrencyFields(
['cost_per_day','cost_per_week'],
$targetCurrency
);
}
I have got my logic working within this scope function no problem, but I want to make this code available to all my models, as there are multiple currency fields in different tables and I don't want to be replicating the code in each query scope - only specify the columns that need attention.
So, where would I make my function normaliseCurrencyFields? I have extended the Model class as well as used the newCollection keyword to extend Collection but both result in Call to undefined method Illuminate\Database\Query\Builder::normaliseCurrencyFields() errors.
I have looked into Global Scoping but this seems to be localised to a Model.
Am I along the right lines? Should I be targeting Eloquent specifically?
Create an abstract base model that extends eloquent then extend it with the classes you want to have access to it. I do this for searching functions, uuid creation, and class code functions. So that all of my saved models are required to have to certain attributes and access to my searching functions. For instance I created a static search function getobjectbyid(). So that when extended I can call it like so:
$user = User::getobjectbyid('habwiifnbrklsnbbd1938');
Thus way I know I am getting a user object back.
My base model:
<?php
/**
* Created by PhpStorm.
* User: amac
* Date: 6/5/17
* Time: 12:45 AM
*/
namespace App;
use Illuminate\Database\Eloquent\Model as Eloquent;
abstract class Model extends Eloquent
{
protected $guarded = [
'class_code',
'id'
];
public $primaryKey = 'id';
public $incrementing = false;
public function __construct($attributes = array()) {
parent::__construct($attributes); // Eloquent
$this->class_code = \App\Enums\EnumClassCode::getValueByKey(get_class($this));
$this->id = $this->class_code . uniqid();
return $this;
}
public static function getObjectById($id){
$class = get_called_class();
$results = $class::find($id);
return $results;
}
public static function getAllObjects(){
$class = get_called_class();
return $class::all();
}
my user model:
<?php
namespace App;
use Mockery\Exception;
use Illuminate\Support\Facades\Hash;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use App\Model as Model;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'contact', 'username', 'email_address'
];
/**
* The column name of the "remember me" token.
*
* #var string
*/
protected $rememberTokenName = 'remember_token';
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'remember_token', 'active'
];
/**
* the attributes that should be guarded from Mass Assignment
*
* #var array
*/
protected $guarded = [
'created_at', 'updated_at', 'password_hash'
];
/**
* Define table to be used with this model. It defaults and assumes table names will have an s added to the end.
*for instance App\User table by default would be users
*/
protected $table = "user";
/**
* We have a non incrementing primary key
*
* #var bool
*/
public $incrementing = false;
/**
* relationships
*/
public function contact(){
// return $this->hasOne(Contact::class, 'id', 'contact_id');
return $this->hasOne(Contact::class);
}
public function customers(){
// return $this->hasOne(Contact::class, 'id', 'contact_id');
return $this->hasMany(Customer::class);
}
/**
* User constructor.
* #param array $attributes
*/
public function __construct($attributes = array()) {
parent::__construct($attributes); // Eloquent
// Your construct code.
$this->active = 1;
return $this;
}
/**
* #param $password string
* set user password_hash
* #return $this
*/
public function setPassword($password){
// TODO Password Validation
try{
$this->isActive();
$this->password_hash = Hash::make($password);
$this->save();
} catch(\Exception $e) {
dump($e->getMessage());
}
return $this;
}
/**
* Returns whether or not this use is active.
*
* #return bool
*/
public function isActive(){
if($this->active) {
return true;
} else {
Throw new Exception('This user is not active. Therefore you cannot change the password', 409);
}
}
public function getEmailUsername(){
$contact = Contact::getObjectById($this->contact_id);
$email = Email::getObjectById($contact->email_id);
return $email->username_prefix;
}
/**
* #return string
*
* getFullName
* returns concatenated first and last name of user.
*/
public function getFullName(){
return $this->first_name . ' ' . $this->last_name;
}
/**
* Get the name of the unique identifier for the user.
*
* #return string
*/
public function getAuthIdentifierName(){
return $this->getKeyName();
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier(){
return $this->{$this->getAuthIdentifierName()};
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword(){
return $this->password_hash;
}
/**
* Get the token value for the "remember me" session.
*
* #return string
*/
public function getRememberToken(){
if (! empty($this->getRememberTokenName())) {
return $this->{$this->getRememberTokenName()};
}
}
/**
* Set the token value for the "remember me" session.
*
* #param string $value
* #return void
*/
public function setRememberToken($value){
if (! empty($this->getRememberTokenName())) {
$this->{$this->getRememberTokenName()} = $value;
}
}
/**
* Get the column name for the "remember me" token.
*
* #return string
*/
public function getRememberTokenName(){
return $this->rememberTokenName;
}
/**
* Get the e-mail address where password reset links are sent.
*
* #return string
*/
public function getEmailForPasswordReset(){
}
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token){
}
public function validateAddress(){
}
}
a TestController:
public function test(){
$user = User::getObjectById('USR594079ca59746');
$customers = array();
foreach ($user->customers as $customer){
$contact = Contact::getObjectById($customer->contact_id);
$name = PersonName::getObjectById($contact->personname_id);
$c = new \stdClass();
$c->id = $customer->id;
$c->name = $name->preferred_name;
$customers[] = $c;
}
$response = response()->json($customers);
return $response;
}
Take note on how getObjectById is extended and available to my other classes that extend my base model. Also I do not have to specify in my user model an 'id' or 'class_code' and when my user model is constructed it calls the parent constructor which is the constructor on my base model that handles 'id' and 'class_code'.