how to optimize laravel jobs inside loop - mysql
There is a function that is inside the job (queue) . and I dispatch that queue. Inside for each loop.
public function autoConsignmentChargeCalculate($consignments, $user_id, $notify)
{
$i = 1;
$total_consignments = $consignments->count();
$jobs = [];
foreach ($consignments as $consignment) {
$jobs[] = new CalculateSingleConsignment($consignment, $total_consignments, $i, $user_id, $notify);
$i++;
}
if (count($jobs) > 0) {
Bus::chain($jobs)->onQueue('invoice')->dispatch();
}
}
The function inside the job is
public function calculateConsignmentOneByOne($consignment, $total_consignments, $current_iteration, $user_id, $notify)
{
if ($consignment->finalize == 0) {
$type = 'Income';
$customer = Customer::find($consignment->customer_id);
$delivery_run_id = $consignment->delivery_run_id;
if ($consignment->consignment_type == 'pickup' || $consignment->consignment_type == 'return') {
$delivery_address_id = $consignment->pickup_address;
} else {
$delivery_address_id = $consignment->delivery_address;
}
$customer_id = $consignment->customer_id;
$rate_zone = $consignment->rate_zone_id;
if ($rate_zone == null) {
$address_to_rate_zone_mapping = getRateZoneByAddressMapping($consignment, $type);
if ($address_to_rate_zone_mapping != false) {
$rate_zone = 0;
$rate_zone = $address_to_rate_zone_mapping;
} else {
$rate_zone = $this->getRateZone($delivery_run_id, $delivery_address_id, $type);
}
}
if (!empty($consignment->invoice)) {
if ($consignment->invoice->status === 3) {
$error = 'Related Invoice is Approved,Now you Can not modify charges';
chargeError('Consignment', $consignment->id, 'invoice_approved', $error, $type);
}
}
$productType = $consignment->product_type_id;
if ($rate_zone === 'wrong_delivery_run') {
$error = 'No Delivery Run is Assigned to this consignment';
chargeError('Consignment', $consignment->id, 'wrong_delivery_run', $error, $type);
} else if ($rate_zone === 'wrong_delivery_zone') {
if ($consignment->consignment_type == 'pickup' || $consignment->consignment_type == 'return') {
$address_msg = 'Pickup address';
} else {
$address_msg = 'Delivery address';
}
$error = 'Delivery Zone not found with current suburb and postcode given in ' . $address_msg;
chargeError('Consignment', $consignment->id, 'wrong_delivery_zone', $error, $type);
} else if (empty($productType)) {
$error = 'Please Attach Product Type to Consignment';
chargeError('Consignment', $consignment->id, 'product_type_error', $error, $type);
} else if ($rate_zone === 'wrong_delivery_address') {
$error = 'Delivery Address not Found , May be Deleted';
chargeError('Consignment', $consignment->id, 'wrong_delivery_address', $error, $type);
} else {
$rate_charge = $this->getRateChargeByRateZoneAndCustomer($rate_zone, $type, $consignment, $customer);
if ($rate_charge === 'rate_not_found') {
$error = 'Rate Card in Customer Charge with "' . RateZone::find($rate_zone)->name . '" Rate zone or Charge Type not found';
chargeError('Consignment', $consignment->id, 'rate_not_found', $error, $type);
}
if ($rate_charge === 'customer_not_found') {
$error = 'Customer Not Found, May be Deleted';
chargeError('Consignment', $consignment->id, 'customer_not_found', $error, $type);
}
if ($rate_charge === "invalid_carton_pallet") {
$error = 'No pallets or cartons given, check the consignment data has been loaded correctly.';
chargeError('Consignment', $consignment->id, 'invalid_carton_pallet', $error, $type);
}
if ($rate_charge === "invalid_invoice_value") {
$error = 'No invoice value given, check the consignment data has been loaded correctly.';
chargeError('Consignment', $consignment->id, 'invalid_invoice_value', $error, $type);
}
if ($rate_charge === "invalid_weight") {
$error = 'No Weight value given, check the consignment data has been loaded correctly.';
chargeError('Consignment', $consignment->id, 'invalid_weight', $error, $type);
} else {
if ($type == 'Income') {
$rate_charge_array = array('class' => null, 'type' => $type, 'description' => $this->chargeDescription, 'income' => $rate_charge, 'expense' => 0.00, 'rate_zone_id' => $rate_zone, 'customer_id' => $customer->id, 'apply_fuel_levy' => $this->fuelLevy, 'object_id' => $consignment->id, 'model' => 'Consignment', 'automatic' => 1);
} else {
$rate_charge_array = array('class' => null, 'type' => $type, 'description' => $this->chargeDescription, 'income' => 0.00, 'expense' => $rate_charge, 'rate_zone_id' => $rate_zone, 'customer_id' => $customer->id, 'apply_fuel_levy' => $this->fuelLevy, 'object_id' => $consignment->id, 'model' => 'Consignment', 'automatic' => 1);
}
if ($type == 'Income') {
$final_charges = $this->getAdhocChargeRate($consignment, 'Consignment');
}
$final_charges[] = $rate_charge_array;
$final_charges = collect($final_charges);
Charge::where('object_id', $consignment->id)->where('automatic', 1)->where('model', 'Consignment')->delete();
ChargeError::where('object_id', $consignment->id)->where('model', 'Consignment')->delete();
$this->storeAutoCalculatedConsignmentCharges($final_charges);
$this->calculateFuelLevyForConsignment($consignment->id);
//this will keep updating fuel levy with each consignment calculation
// if (InvoiceTotal::where('invoice_id', $consignment->invoice_id)->where('name', 'Fuel Levy')->exists()) {
// $income = 0;
// $expense = 0;
// $total = InvoiceTotal::where('invoice_id', $consignment->invoice_id)->where('name', 'Fuel Levy')->first();
// $income = (float)$total->income + (float)$consignment->charges()->sum('fuel_levy_value');
// $expense += 0;
// InvoiceTotal::where('invoice_id', $consignment->invoice_id)->where('name', 'Fuel Levy')->update(['income' => $income, 'expense' => $expense]);
// $invoice = Invoice::find($consignment->invoice_id);
// Invoice::where('id', $consignment->invoice_id)->update(['income' => $invoice->invoice_totals()->sum('income'), 'expense' => $invoice->invoice_totals()->sum('expense')]);
// }
Invoice::find($consignment->invoice_id)->update(['sum_up' => 0]);
}
}
$last_consignment = Consignment::select('id', 'invoice_id')->where('invoice_id', $consignment->invoice_id)->where('finalize', 0)->orderBy('id', 'desc')->first();
$invoice_id = $consignment->invoice_id;
//if its last consignment to calculate and notify is true
if ($notify && $total_consignments == $current_iteration) {
Notification_Helper::sendNotification($user_id, 'Invoice Calculation is Completed ', route('invoices.show', $consignment->invoice_id));
}
$upload_to_xero = 0;
if (XeroCustomer::where('customer_id', $consignment->customer_id)->exists()) {
if (XeroCustomer::where('customer_id', $consignment->customer_id)->first()->automatic_invoice_upload_xero == 1) {
$upload_to_xero = 1;
}
}
if ($consignment->id == $last_consignment->id) {
Invoice::find($invoice_id)->update(['calculation_complete' => 1]);
$this->consignmentSumup($invoice_id);
}
//if its last consignment to calculate and has no charge error then
//invoice will be uploaded to xero
if ($consignment->id == $last_consignment->id) {
//checking if error exists Related to current invoice
$consignment_charge_exists = ChargeError::where('model', 'Consignment')->whereIn('object_id', function ($query) use ($invoice_id) {
$query->select('id')
->from(with(new Consignment)->getTable())
->where('invoice_id', $invoice_id);
})->exists();
$po_charge_exist = ChargeError::where('model', 'Purchase Order')->whereIn('object_id', function ($query) use ($invoice_id) {
$query->select('id')
->from(with(new PurchaseOrder)->getTable())
->where('invoice_id', $invoice_id);
})->exists();
$so_charge_exist = ChargeError::where('model', 'Sale Order')->whereIn('object_id', function ($query) use ($invoice_id) {
$query->select('id')
->from(with(new SaleOrder)->getTable())
->where('invoice_id', $invoice_id);
})->exists();
$sp_charge_exist = ChargeError::where('model', 'Storage Period')->whereIn('object_id', function ($query) use ($invoice_id) {
$query->select('id')
->from(with(new StoragePeriod)->getTable())
->where('invoice_id', $invoice_id);
})->exists();
if (!$consignment_charge_exists && !$po_charge_exist && !$so_charge_exist && !$sp_charge_exist && $upload_to_xero == 1 && $this->consignmentSumup($invoice_id)) {
UploadInvoiceToXero::dispatch($consignment->invoice_id)->onQueue('invoice')->delay(Carbon::now()->addMinutes(2));
// CustomerController::uploadAutoInvoiceToXero($consignment->invoice_id, $xeroCredential, new CustomerSettingService);
Invoice::find($consignment->invoice_id)->update(['sum_up' => 1]);
} else {
Invoice::find($consignment->invoice_id)->update(['sum_up' => 1, 'charge_error' => 1]);
}
} else {
Invoice::find($consignment->invoice_id)->update(['sum_up' => 1, 'charge_error' => 1]);
}
}
}
Now the problem is there are about 20,30 queries inside this function. and I have to dispatch this job about 25000 times. when it reaches 200 jobs. My aws DB CPU utilization reaches 100%.
Now I am looking for an optimal solution I can increase DB instance size but I think that is not a solution.
What is good practice I can use here?
SQL is quite fast at doing the "same" thing to lots of rows at the "same" time.
What you seem to have is code that does 20-30 small queries 25K times.
Consider doing 20-30 (maybe a few more than that) queries, each of which acts on 25K rows. Then chuck all the queuing and don't worry about "simultaneously".
Related
How to give rest to mysql cpu while process 100000 queriesne by one in laravel?
I am using laravel jobs to do calculation on week end during calculation i need to run almost 100000 queries in a row one by one due to this my mysql server usage reaches 100% i am thinking of to give rest between this process .How i can do this? Here is the function which i am calling about 25000 times inside loop which has almost 30 queries. public function calculateConsignmentOneByOne($consignment, $total_consignments, $current_iteration, $user_id, $notify) { if ($consignment->finalize == 0) { $type = 'Income'; $customer = $consignment->customers; $delivery_run_id = $consignment->delivery_run_id; if ($consignment->consignment_type == 'pickup' || $consignment->consignment_type == 'return') { $delivery_address_id = $consignment->pickup_address; } else { $delivery_address_id = $consignment->delivery_address; } $customer_id = $consignment->customer_id; $rate_zone = $consignment->rate_zone_id; if ($rate_zone == null) { $address_to_rate_zone_mapping = getRateZoneByAddressMapping($consignment, $type); if ($address_to_rate_zone_mapping != false) { $rate_zone = 0; $rate_zone = $address_to_rate_zone_mapping; } else { $rate_zone = $this->getRateZone($delivery_run_id, $delivery_address_id, $type); } } if (!empty($consignment->invoice)) { if ($consignment->invoice->status === 3) { $error = 'Related Invoice is Approved,Now you Can not modify charges'; chargeError('Consignment', $consignment->id, 'invoice_approved', $error, $type); } } $productType = $consignment->product_type_id; if ($rate_zone === 'wrong_delivery_run') { $error = 'No Delivery Run is Assigned to this consignment'; chargeError('Consignment', $consignment->id, 'wrong_delivery_run', $error, $type); } else if ($rate_zone === 'wrong_delivery_zone') { if ($consignment->consignment_type == 'pickup' || $consignment->consignment_type == 'return') { $address_msg = 'Pickup address'; } else { $address_msg = 'Delivery address'; } $error = 'Delivery Zone not found with current suburb and postcode given in ' . $address_msg; chargeError('Consignment', $consignment->id, 'wrong_delivery_zone', $error, $type); } else if (empty($productType)) { $error = 'Please Attach Product Type to Consignment'; chargeError('Consignment', $consignment->id, 'product_type_error', $error, $type); } else if ($rate_zone === 'wrong_delivery_address') { $error = 'Delivery Address not Found , May be Deleted'; chargeError('Consignment', $consignment->id, 'wrong_delivery_address', $error, $type); } else { $rate_charge = $this->getRateChargeByRateZoneAndCustomer($rate_zone, $type, $consignment, $customer); if ($rate_charge === 'rate_not_found') { $error = 'Rate Card in Customer Charge with "' . RateZone::find($rate_zone)->name . '" Rate zone or Charge Type not found'; chargeError('Consignment', $consignment->id, 'rate_not_found', $error, $type); } if ($rate_charge === 'customer_not_found') { $error = 'Customer Not Found, May be Deleted'; chargeError('Consignment', $consignment->id, 'customer_not_found', $error, $type); } if ($rate_charge === "invalid_carton_pallet") { $error = 'No pallets or cartons given, check the consignment data has been loaded correctly.'; chargeError('Consignment', $consignment->id, 'invalid_carton_pallet', $error, $type); } if ($rate_charge === "invalid_invoice_value") { $error = 'No invoice value given, check the consignment data has been loaded correctly.'; chargeError('Consignment', $consignment->id, 'invalid_invoice_value', $error, $type); } if ($rate_charge === "invalid_weight") { $error = 'No Weight value given, check the consignment data has been loaded correctly.'; chargeError('Consignment', $consignment->id, 'invalid_weight', $error, $type); } else { if ($type == 'Income') { $rate_charge_array = array('class' => null, 'type' => $type, 'description' => $this->chargeDescription, 'income' => $rate_charge, 'expense' => 0.00, 'rate_zone_id' => $rate_zone, 'customer_id' => $customer->id, 'apply_fuel_levy' => $this->fuelLevy, 'object_id' => $consignment->id, 'model' => 'Consignment', 'automatic' => 1); } else { $rate_charge_array = array('class' => null, 'type' => $type, 'description' => $this->chargeDescription, 'income' => 0.00, 'expense' => $rate_charge, 'rate_zone_id' => $rate_zone, 'customer_id' => $customer->id, 'apply_fuel_levy' => $this->fuelLevy, 'object_id' => $consignment->id, 'model' => 'Consignment', 'automatic' => 1); } if ($type == 'Income') { $final_charges = $this->getAdhocChargeRate($consignment, 'Consignment'); } $final_charges[] = $rate_charge_array; $final_charges = collect($final_charges); Charge::where('object_id', $consignment->id)->where('automatic', 1)->where('model', 'Consignment')->delete(); ChargeError::where('object_id', $consignment->id)->where('model', 'Consignment')->delete(); $this->storeAutoCalculatedConsignmentCharges($final_charges); $this->calculateFuelLevyForConsignment($consignment->id); //this will keep updating fuel levy with each consignment calculation // if (InvoiceTotal::where('invoice_id', $consignment->invoice_id)->where('name', 'Fuel Levy')->exists()) { // $income = 0; // $expense = 0; // $total = InvoiceTotal::where('invoice_id', $consignment->invoice_id)->where('name', 'Fuel Levy')->first(); // $income = (float)$total->income + (float)$consignment->charges()->sum('fuel_levy_value'); // $expense += 0; // InvoiceTotal::where('invoice_id', $consignment->invoice_id)->where('name', 'Fuel Levy')->update(['income' => $income, 'expense' => $expense]); // $invoice = Invoice::find($consignment->invoice_id); // Invoice::where('id', $consignment->invoice_id)->update(['income' => $invoice->invoice_totals()->sum('income'), 'expense' => $invoice->invoice_totals()->sum('expense')]); // } Invoice::find($consignment->invoice_id)->update(['sum_up' => 0]); } } $last_consignment = Consignment::select('id', 'invoice_id')->where('invoice_id', $consignment->invoice_id)->where('finalize', 0)->orderBy('id', 'desc')->first(); $invoice_id = $consignment->invoice_id; //if its last consignment to calculate and notify is true if ($notify && $total_consignments == $current_iteration) { Notification_Helper::sendNotification($user_id, 'Invoice Calculation is Completed ', route('invoices.show', $consignment->invoice_id)); } $upload_to_xero = 0; if (XeroCustomer::where('customer_id', $consignment->customer_id)->exists()) { if (XeroCustomer::where('customer_id', $consignment->customer_id)->first()->automatic_invoice_upload_xero == 1) { $upload_to_xero = 1; } } if ($consignment->id == $last_consignment->id) { Invoice::find($invoice_id)->update(['calculation_complete' => 1]); $this->consignmentSumup($invoice_id); } //if its last consignment to calculate and has no charge error then //invoice will be uploaded to xero if ($consignment->id == $last_consignment->id) { //checking if error exists Related to current invoice $consignment_charge_exists = ChargeError::where('model', 'Consignment')->whereIn('object_id', function ($query) use ($invoice_id) { $query->select('id') ->from(with(new Consignment)->getTable()) ->where('invoice_id', $invoice_id); })->exists(); $po_charge_exist = ChargeError::where('model', 'Purchase Order')->whereIn('object_id', function ($query) use ($invoice_id) { $query->select('id') ->from(with(new PurchaseOrder)->getTable()) ->where('invoice_id', $invoice_id); })->exists(); $so_charge_exist = ChargeError::where('model', 'Sale Order')->whereIn('object_id', function ($query) use ($invoice_id) { $query->select('id') ->from(with(new SaleOrder)->getTable()) ->where('invoice_id', $invoice_id); })->exists(); $sp_charge_exist = ChargeError::where('model', 'Storage Period')->whereIn('object_id', function ($query) use ($invoice_id) { $query->select('id') ->from(with(new StoragePeriod)->getTable()) ->where('invoice_id', $invoice_id); })->exists(); if (!$consignment_charge_exists && !$po_charge_exist && !$so_charge_exist && !$sp_charge_exist && $upload_to_xero == 1 && $this->consignmentSumup($invoice_id)) { UploadInvoiceToXero::dispatch($consignment->invoice_id)->onQueue('invoice')->delay(Carbon::now()->addMinutes(2)); // CustomerController::uploadAutoInvoiceToXero($consignment->invoice_id, $xeroCredential, new CustomerSettingService); Invoice::find($consignment->invoice_id)->update(['sum_up' => 1]); } else { Invoice::find($consignment->invoice_id)->update(['sum_up' => 1, 'charge_error' => 1]); } } else { Invoice::find($consignment->invoice_id)->update(['sum_up' => 1, 'charge_error' => 1]); } } }
How can i execute a method of a controller by doing click on a button?
I am trying to use a button to execute directly a method of a controller but it does not working I have tried with href doing action, also with complete routes TOUCH Route::get('task-calendar_show', ['uses'=>'AdminCalendarController#updateIndex']); Route::post('task-calendar_create', ['uses' => 'AdminCalendarController#updateIndex2']); Route::post('task-calendar/updateIndex', ['as' => 'task-calendar.updateIndex', 'uses' => 'AdminCalendarController#updateIndex']); Route::get('task-calendar/updateIndex', ['as' => 'task-calendar.updateIndex', 'uses' => 'AdminCalendarController#updateIndex']); also have a method index but it does not load public function index() { if (auth()->user()->id == '13' || auth()->user()->id == '15' || auth()->user()->id == '27' || auth()->user()->id == '17' || auth()->user()->id == '16' || auth()->user()->id == '10') { $this->tasks = Task::where('status', 'incomplete')->get(); } else { $this->tasks = Task::where('status', 'incomplete')->where('user_id', '=', auth()->user()->id)->get(); } return view('admin.task-calendar.index', $this->data); } This is the method just to return an echo public function updateIndex() { echo 'entro'; } Action App\Http\Controllers\AdminCalendarController#index not defined.
yii queue doesn't detect jobs in database
I'm trying to run a queue using yii so I can do some tests, but whenever I type the command yii queue/run, no job seems to be put in waiting, This is to send the information of an ID and status of a job that when the conditions are met, will be ran in the main page This is the code that sends the data into the queue: class HorarioController extends Controller { public function actionBuscar() { $hora = date("H").":00".":00"; $dia = date("N"); $horarios = Horarios_Equipos::find()->all(); foreach($horarios as $horario) { echo $horario->id_equipo."\n"; echo $horario->estado."\n"; //enviar a cola Yii::$app->queue->push( new HorarioJob([ 'id_equipo' => $horario->id_equipo, 'estado' => $horario->estado, ]) ); } return ExitCode::OK; } } And this is the code that does the action in the queue public function execute($queue) { if($estado == '1'){ if($pin == 1) { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '1'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDa=ON'); return $this->redirect(['view', 'id' => $id]); } elseif ($pin == 2) { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '1'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDb=ON'); return $this->redirect(['view', 'id' => $id]); } elseif ($pin == 3) { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '1'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDc=ON'); return $this->redirect(['view', 'id' => $id]); } elseif ($pin == 4) { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '1'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDd=ON'); return $this->redirect(['view', 'id' => $id]); } } if ($estado == 0){ if ($pin == '1') { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '0'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDa=OFF'); return $this->redirect(['view', 'id' => $id]); } if ($pin == '2') { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '0'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDb=OFF'); return $this->redirect(['view', 'id' => $id]); } if ($pin == '3') { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '0'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDc=OFF'); return $this->redirect(['view', 'id' => $id]); } if ($pin == '4') { $equipo = Equipos::find()->where(['id'=>$id])->one(); $equipo->estado = '0'; $equipo->save (); $curl = new curl\Curl(); $response = $curl->get($equipo->ip.'/gpio/LEDd=OFF'); return $this->redirect(['view', 'id' => $id]); } } } } This is what shows when I run yii queue/run: C:\xampp\htdocs\accontrol>yii queue/run C:\xampp\htdocs\accontrol> And if I run yii queue/info it only shows this: C:\xampp\htdocs\accontrol>yii queue/info Jobs - waiting: 0 - delayed: 0 - reserved: 0 - done: 0 As fas as I know the files where the queue functions are written are correct and I should be able to run the queue/run command, at least get an error to see where I'm wrong, but it just doesn't
Found the problem, PHP had the timezone configured incorrectly so when it tried to search for the time on the database it wouldn't match with the time it had configured, had to modify the php.ini document to set the correct timezone, If you're having this problem to enter the php.ini document you can do it via the control panel: in the Apache section click the config button and select the PHP(php.ini) Then use the find option and search for timezone, and then you may type the timezone of your area, in my case its America/Mexico_City Heres the link where you can find the timezones: https://www.php.net/manual/es/timezones.php
Filter a gridview column that is processed by a function in yii2
I have a column named wp_status. If person A, person B, person C, person D approves a work, the value of column wp_status will be changed to Approved, else the value will be as it is in the database - Assigned. The code to change the value dynamically in the gridview is - [ 'label' => 'Status', 'attribute'=>'wp_status', 'value' => function ($model) { return $model->Status(); } ], And the function Status in model Workpermit is - public function Status() { //$data = Workpermit::findOne($this->id); $total = $this->wp_status; if($this->wp_type == 'Safe Work Permit' && $this->wp_apoapproval == 'Approved' && $this->wp_spsapproval == 'Approved' && $this->wp_officerapproval == 'Approved'){ $total = 'Approved'; } return $total; } This works fine so far. But I'm not sure how to filter it with Kartik Select2 widget. I tried like following - [ 'label' => 'Status', 'attribute'=>'wp_status', 'filterType'=>GridView::FILTER_SELECT2, 'filter'=>ArrayHelper::map(Workpermit::Status()->asArray()->all(), 'total', 'total'), 'filterWidgetOptions'=>[ 'pluginOptions'=>['allowClear'=>true], ], 'filterInputOptions'=>['placeholder'=>'Permit Status'], 'value' => function ($model) { return $model->Status(); } ], And here I'm getting error - Using $this when not in object context
could be uisng a getter public function getStatus() { //$data = Workpermit::findOne($this->id); $total = $this->wp_status; if($this->wp_type == 'Safe Work Permit' && $this->wp_apoapproval == 'Approved' && $this->wp_spsapproval == 'Approved' && $this->wp_officerapproval == 'Approved'){ $total = 'Approved'; } return $total; } the call $model->status (status lowercase) [ 'label' => 'Status', 'attribute'=>'wp_status', 'value' => function ($model) { return $model->status; } ],
refactoring of simple code in Yii2 (if-else)
i was doing some refactoring of code on project in Yii2 framework. I'm just asking if this can be written nicer, with less repetition (i try to follow DRY whenever i can). Any literature recommendation about this kind of topic is more than welcome, sorry for bad English. $exception = Yii::$app->errorHandler->exception; if ($exception !== null) { if (isset($exception->statusCode)) { if ($exception->statusCode == 500) { return $this->render('error-500', ['exception' => $exception]); } elseif ($exception->statusCode == 404) { return $this->render('error-404', ['exception' => $exception]); } else { return $this->render('error', ['exception' => $exception]); } } elseif (isset($exception->code)) { if ($exception->code == 500) { return $this->render('error-500', ['exception' => $exception]); } elseif ($exception->code == 404) { return $this->render('error-404', ['exception' => $exception]); } else { return $this->render('error', ['exception' => $exception]); } } } else { $exception = new \yii\web\HttpException(500); return $this->render('error-500', ['exception' => $exception]); }
You can do so if you like $exception = Yii::$app->errorHandler->exception; if ($exception !== null) { if (isset($exception->statusCode){ return $this-render('error-' . $exception->statusCode , ['exception' => $exception] ); } else if (isset($exception->code)) { return $this-render('error-' . $exception->code , ['exception' => $exception] ) } else { $exception = new \yii\web\HttpException(500); return $this->render('error-500', ['exception' => $exception]); } } or so if like more compact if ($exception !== null) { if (isset($exception->statusCode, $exception->code){ return $this-render('error-' . ($exception->statusCode) ? $exception->statusCode : $exception->code , ['exception' => $exception] ); } else { $exception = new \yii\web\HttpException(500); return $this->render('error-500', ['exception' => $exception]); } }
Another possible way if ($exception !== null) { $exceptionCode = isset($exception->statusCode)?$exception->statusCode: ( isset($exception->code)?$exception->code:null ); if($exceptionCode){ $viewFile = ($exceptionCode == 500)?'error-500': ( ($exceptionCode == 404)?'error-404':'error'); return $this->render($viewFile, ['exception' => $exception]); } else { // you need to something here } }