Dropdown of available statuses - laravel

I'm trying to figue out what I"m doing wrong to get the error message. I have my User model that has a status_id field and it is a foreign key to my statuses table with an id and name field.
public function scopeAvailable($query, $current = null)
{
$options = $this->getAvailableOptions($current)->toArray();
return $query->whereIn('name', $options);
}
public function getAvailableOptions(string $current = null)
{
$options = collect(['Active', 'Inactive']);
switch ($current) {
case 'Active':
return $options->merge(['Fired', 'Suspended', 'Retired']);
case 'Injured':
return $options->merge(['Fired', 'Retired']);
case 'Suspended':
return $options->merge(['Suspended', 'Retired']);
}
return $options;
}
public function availableStatuses()
{
$status = $this->status ? $this->status->name : null;
return UserStatus::available($status)->get();
}
Type error: Argument 1 passed to App\Models\UserStatus::getAvailableOptions() must be of the type string or null, object given, called in /home/vagrant/projects/app/app/Models/UserStatus.php on line 45

Related

Foreach Storing last data form array in Laravel. Help Plz

I have Tag table, Post Table and PostHasTag Table. But when I go to store my tags in, PostHasTag with post_id and tag_id.
I am using foreach loop for storing tags, but it just stored last tag. Now where is my problem?
public static function postHasTags($post_id, $tag_ids)
{
$store = new PostHasTag();
foreach ($tag_ids as $tag_id) {
$checkTag = PostHasTag::where('post_id', $post_id)->where('tag_id', $tag_id)->get();
if (count($checkTag) > 0) {
return back()->with('error', 'Tag already exists');
} else{
$store->post_id = $post_id;
$store->tag_id = $tag_id;
$store->save();
}
}
return $store;
}
Line $store = new PostHasTag(); should be inside foreach() loop, so it should look like this :
public static function postHasTags($post_id, $tag_ids)
{
foreach ($tag_ids as $tag_id) {
$checkTag = PostHasTag::where('post_id', $post_id)->where('tag_id', $tag_id)->get();
if (count($checkTag)) {
return back()->with('error', 'Tag already exists');
} else{
$store = new PostHasTag(); // Better to put it here
$store->post_id = $post_id;
$store->tag_id = $tag_id;
$store->save();
}
}
return $store;
}
But in this case you are returning only last created PostHasTag. If you need all of them, then push each PostHasTag in a collection and return it.

Laravel application freezes doesn't respond anymore

I have a laravel application that uses a while loop to process a txt file(6000 lines) line by line together with various helpers to manipulate each string. At the end of the manipulation it stores a record in db for each line. Everything works fine, the application process the entire file in a minute and returns the view indicated. The problem is that the application than freeze(not sure if this is the appropriate term), it keeps running and the browser ask repeatedly to wait or close the application.
I noticed also this message in the laravel server if it may help
[Wed Apr 21 10:28:26 2021] 127.0.0.1:50897 Closed without sending a request; it was probably just an unused speculative preconnection
Thanks to anyone who could help me.
This is the process:
$log = new UserActivityHelper;
$log->create(Config::get('constants.user_activities.FTP_FILE_PROCESSED_START'), 'test');
$file = fopen(Storage::path("1-2021.txt"), 'r');
while(!feof($file))
{
$line = fgets($file);
//call the method that validate the string
$string = new ValidateStringHelper($line); //FIRST HELPER
$string->validate();
//check the result of the validation
if($string->validated == false){
dd("out");
} elseif ($string->empty == true){
continue;
}else{
//save the validated array of substrings as variable
$my_arr = $string->validatedChars;
//check if the province exists or create it
$province = new ProvinceExistsHelper($my_arr['district']); //SECOND HELPER
$province->check_if_exists_or_create();
if($province->new_province == true) {
$log = new UserActivityHelper;
$log->create(Config::get('constants.ftp_process.FTP_PROVINCE_CREATED'), "Creata nuova provincia con id {$province->district_id}");
self::message('yellow', "Attenzione. Nell'elaborazione sono state create nuove provincie, controllare le impostazioni.");
}
//manipolation of name and lastname
$name = ucwords(strtolower($my_arr['name_lastname']));
//check if the person already exists or create it (passing fiscal code, name and district_id)
$person = new PersonExistsHelper($my_arr['fiscal_code'], $name, $province->district_id); //THIRD HELPER
$person->check_if_exists_or_create();
$newMovement = new Movement;
$newMovement->person_id = $person->person_id;
if(array_key_exists('level', $my_arr)){
$newMovement->level = $my_arr['level'];
}
...
try {
$newMovement->save();
} catch (\Throwable $exception) {
report($exception);
return;
}
}
}
fclose($file);
$log = new UserActivityHelper;
$log->create(Config::get('constants.user_activities.FTP_FILE_PROCESSED_END'), 'test');
return view('ftp.test');
Helpers called:
class ValidateStringHelper
{
public $line;
public $empty = false;
public $validated = false;
public $validationErrors = array();
public $validatedChars = array();
public function __construct($line){
$this->line = $line;
}
public function validate(){
if ($this->line!="")
{
if(strlen($this->line) >= 186)
{
//substrings
$district = trim(substr($this->line, 0, 2));
$trade_union_tax_code = trim(substr($this->line, 2, 3));
...
//validation
//check if validated
$this->validatedChars['district'] = $district;
$this->validatedChars['trade_union_tax_code'] = $trade_union_tax_code;
...
//filter all non empty string values and not all zero strings
$filter_arr = array_filter($this->validatedChars, fn($value) => $value !== '' && preg_filter('/^(?!0*$).*$/', '$0', $value));
$this->validatedChars = $filter_arr;
$this->validated = true;
return $this->validated;
//return $this->validatedChars;
//eturn $this->validated;
} else {
$this->validationErrors[] = "string_length";
return $this->validated;
}
} else {
$this->empty = true;
return $this->empty;
}
}
class PersonExistsHelper
{
public $name_lastname;
public $fiscal_code;
public $district_id;
public $new_person = false;
public $person_id;
public function __construct(string $fiscal_code, string $name_lastname, string $district_id){
$this->fiscal_code = $fiscal_code;
$this->name_lastname = $name_lastname;
$this->district_id = $district_id;
}
public function check_if_exists_or_create()
{
$person = Person::where('fiscal_code', '=', $this->fiscal_code)->first();
if($person == NULL)
{
$this->new_person = true;
$newPerson = new Person;
$newPerson->name_lastname = $this->name_lastname;
$newPerson->district_id = $this->district_id;
$newPerson->fiscal_code = $this->fiscal_code;
$newPerson->created_by = Config::get('constants.people_creation.FTP_PROCESS');
$newPerson->save();
$this->person_id = $newPerson->id;
return $this->person_id;
} else{
$this->person_id = $person->id;
return $this->person_id;
}
}
}
class ProvinceExistsHelper
{
public $district_id;
public $district_code;
public $new_province = false;
public function __construct($district_code){
$this->district_code = $district_code;
}
public function check_if_exists_or_create()
{
//check if the province is in the Provinces table
$province = Province::where('code', '=', $this->district_code)->first();
if(!isset($province))
{
$this->new_province = true;
$newProvince = new Province;
$newProvince->name = $this->district_code;
$newProvince->code = $this->district_code;
$newProvince->save();
$this->district_id = $newProvince->id;
return $this->district_id;
} else {
//if yes, just return the id of the province
$this->district_id = $province->id;
return $this->district_id;
}
}
}

Laravel Eloquent, "inheritance" override fields from parent

Is there any way in Eloquent to have a model which has some sort of parent model, where both have an identical field, nullable on the child. And if I get the value $child->field I get the childs value if it's not null, otherwise I get the parent value? Something like this:
$parent = new Parent();
$parent->info = 'parent';
$parent->save();
$child = new Child();
$child->info = 'child';
$child->parent()->associate($parent);
$child->save();
echo $child->info
Prints 'child'
And opposite:
$parent = new Parent();
$parent->info = 'parent';
$parent->save();
$child = new Child();
$child->parent()->associate($parent);
$child->info = null;
$child->save();
echo $child->info
Prints 'parent'
It must be a pattern somewhere to have one table rows values 'overrule' another, I just can't seem to find what to search for.
You simply need a custom accessor on the model of your choice:
class Child
{
public function getInfoAttribute($value)
{
if ($value === null) {
return $this->parent->info;
}
return $value;
}
}
This will allow you to still access the property via $child->info.
Please be aware that this will not cast the attribute value according to the $casts array. If you need this casting logic as well, you should use a custom getter method instead of the magic accessor:
class Child
{
public function getInfo()
{
$info = $this->info;
if ($info === null) {
$info = $this->parent->info;
}
return $info;
}
}
If you need to multiple properties, you can either duplicate the code and put it into a trait to remove the clutter from your model. Or instead, you can try overriding the magic __get($key) method:
class Child
{
$parentInheritedAttributes = ['info', 'description'];
// solution 1: using normal model properties like $child->info
public function __get($key)
{
if (in_array($key, $this->parentInheritedAttributes)) {
$value = parent::__get($key);
if ($value === null) {
// this will implicitely use __get($key) of parent
$value = $this->parent->$key;
}
return $value;
}
return parent::__get($key);
}
// solution 2: using getters like $child->getInfo()
public function __call($method, $parameters)
{
if (\Illuminate\Support\Str::startsWith($method, 'get')) {
$attribute = \Illuminate\Support\Str::snake(lcfirst(substr($method, 3)));
in_array($attribute, $this->parentInheritedAttributes)) {
$value = $this->$attribute;
if ($value === null) {
$value = $this->parent->$attribute;
}
return $value;
}
}
}
}

Object of class Illuminate\Support\Collection could not be converted to int

I have condition in Controller with checks the value in database and based on this value is redirecting user to different login pages
public function getLogin()
{
$login = DB::table('login')->pluck('login');
//var_dump($login);
if ($login == 1) {
return View::make('users.login');
} else {
return View::make('users.login1');
}
}
When I go to login page I've got this error
Object of class Illuminate\Support\Collection could not be converted to int
When I var_dump($login); I get
object(Illuminate\Support\Collection)#304 (1) { ["items":protected]=> array(1) { [0]=> int(1) } }
How can I fix this error?
You can use it like this :
public function getLogin()
{
$login = DB::table('login')->pluck('login');
//var_dump($login);
if ($login->count() == 1) {
return View::make('users.login');
} else {
return View::make('users.login1');
}
}
$login is a collection, you get all the values of table login with your query. if you want this create a for loop and have your if statement inside.
for example :
foreach ($login as $val) {
if ($val== 1) {
return View::make('users.login');
} else {
return View::make('users.login1');
}
}
You should use isEmpty() or count() here, for example:
if (!$login->isEmpty())
if (count($login) > 0)
if ($login->count() > 0)
Ok Its just simple in this case, You can use [0] with login to access it as int.
public function getLogin()
{
$login = DB::table('login')->pluck('login');
//var_dump($login);
if ($login[0] == 1) {
return View::make('users.login');
} else {
return View::make('users.login1');
}
}

Laravel if statement with other variable value

I try to get data from a model, but the value of the column name from the data model is in another variable. Here's a little preview what I try to achieve:
switch($device->target_objectclass_id) {
case 10:
$handler = Servers::findOrFail($device->target_object_id);
default:
break;
}
if($handler->($condition->column) ($condition->condition) ($condition->value)) {
//process the other data it it's true
}
Example of what should be displayed:
if($handler->status == 1) {
//handle data
}
The reason behide this is a little bit complicated. The user's need to create triggers which will be executed.
Btw, all possible conditons are possible.
For example:
check table where column condition value
check servers where status == 1
Hope someone has an answer if you can understand my problem...
I'm not sure how feasible it is to dynamically insert the operator into an expression like that. However, with a limited set of operators, you could do something like this:
class YourClass
{
public function yourMethod()
{
// Your model instance to test, I've just used a stdClass as an example
$instance = new stdClass;
$instance->status = 1;
// Your condition instance
$condition = new stdClass;
$condition->column = 'status';
$condition->condition = '==';
$condition->value = '1';
if ($this->compare($instance, $condition)) {
// This code will execute then $instance->status == '1'
}
}
public function compare($instance, $condition)
{
$operator = $condition->condition;
$condition = $condition->column;
$value = $condition->value;
switch ($operator) {
case '==':
return $instance->$column == $value;
case '!=':
return $instance->$column != $value;
case '>':
return $instance->$column > $value;
case '<':
return $instance->$column < $value;
case '>=':
return $instance->$column >= $value;
case '<=':
return $instance->$column <= $value;
default:
throw new \Exception('Unsupported operator');
}
}
}
Or a nicer, class based way of doing it...
class Conditional
{
protected $operator;
protected $column;
protected $value;
protected $supportedOperators = [
'==' => 'equals',
'!=' => 'notEquals'
];
public function __construct($column, $operator, $value)
{
$this->column = $column;
$this->operator = $operator;
$this->value = $value;
}
public function check($instance)
{
$method = $this->getMethod();
$instanceValue = $instance->{$this->column};
return $this->$method($instanceValue, $this->value);
}
private function getMethod()
{
if (isset($this->supportedOperators[$this->operator]) && method_exists($this, $this->supportedOperators[$this->operator])) {
return $this->supportedOperators[$this->operator];
}
throw new \Exception('Unsupported operator');
}
protected function equals($one, $two)
{
return $one == $two;
}
protected function notEquals($one, $two)
{
return $one != $two;
}
}
Then you can use it like this...
$instance = new stdClass;
$instance->status = 1;
$conditional = new Conditional('status', '==', 1);
if ($conditional->check($instance)) {
// Execute if $instance->status == 1.
}

Resources