Refactor array of function values - php

I have the following code that contains too much duplication, and I want to simplify it. I am not a back-end dev and have rudimentary php skills, so I will appreciate any help:
'gateways' => [
'cod' => [
'initializePayment' => function(OrderPage $virtualOrderPage): OrderPage {
return $virtualOrderPage;
},
'completePayment' => function(OrderPage $virtualOrderPage, array $data): OrderPage {
$virtualOrderPage->content()->update([
'paymentComplete' => true,
'payedDate' => date('c'),
]);
return $virtualOrderPage;
}
],
'deposit' => [
'initializePayment' => function(OrderPage $virtualOrderPage): OrderPage {
return $virtualOrderPage;
},
'completePayment' => function(OrderPage $virtualOrderPage, array $data): OrderPage {
$virtualOrderPage->content()->update([
'paymentComplete' => true,
'payedDate' => date('c'),
]);
return $virtualOrderPage;
}
],
],

Just pulling the arrayFunc out would clear code a bit
$arrayFunc = [
'initializePayment' => function(OrderPage $virtualOrderPage): OrderPage {
return $virtualOrderPage;
},
'completePayment' => function(OrderPage $virtualOrderPage, array $data): OrderPage {
$virtualOrderPage->content()->update([
'paymentComplete' => true,
'payedDate' => date('c'),
]);
return $virtualOrderPage;
}
];
'gateways' => [
'cod' => $arrayFunc,
'deposit' => $arrayFunc,

Related

How to properly fix - Cannot use empty array elements in arrays

I have the code below but it showing an error "Cannot use empty array elements in arrays".
It seems that the issue is in this line }), collect(json_decode($post['comments'], true))->map(function ($comment) {
Code:
'data' => [
'comments' =>
collect(json_decode($configs['comments'], true))->map(function ($comment) {
return [
'title' => $comment['attributes']['title'],
'message' => $comment['attributes']['message'],
];
}), collect(json_decode($posts['comments'], true))->map(function ($comment) {
return [
'title' => $comment['attributes']['title'],
'message' => $comment['attributes']['message'],
];
}),
]
If we simplify your code it seems like this;
'data' => [
'comments' =>
collect(),
collect()
]
It is not a valid syntax. You can try like this;
$comments = collect(json_decode($configs['comments'], true))->map(function ($comment) {
return [
'title' => $comment['attributes']['title'],
'message' => $comment['attributes']['message'],
];
});
$postComments = collect(json_decode($posts['comments'], true))->map(function ($comment) {
return [
'title' => $comment['attributes']['title'],
'message' => $comment['attributes']['message'],
];
});
'data' => [
'comments' => $comments->merge($postComments)->toArray()
];

Laravel POST API -> cURL error 28 in a working api

hope you are all doing well,
on my project, I faced an issue with posting data to an internal API, and keep getting cURL error 28 which means "Operation timed out after 30006 milliseconds with 0 bytes received"
BUT when I test the same API with the same values in POSTMAN it works fine, [Screenshot] -> https://tppr.me/hensp
And here is more details from laravel reports
https://flareapp.io/share/47q1Olz7#share
And my code is attached below.
Thanks in advance
public function addToCart($productId, array $options = [], $quantity = 1)
{
$this->product = Product::findOrFail($productId);
if (!Session::has('cart-token'))
Session::put('cart-token', Str::random(100));
$response = Http::post(env('APP_API_URL') . '/cart/store', [
'productId' => $this->product->id,
'quantity' => $quantity,
'options' => $options,
'cartToken' => Session::get('cart-token')
]);
$this->dispatchBrowserEvent('alert', [
'type' => $response['status'] ? 'success' : 'error',
'message' => $response['message']
]);
}
and the env variable is
APP_URL=127.0.0.1:8000
API_VERSION=1
APP_API_URL="${APP_URL}/api/v${API_VERSION}"
API controllers
public function addToCart(Request $request)
{
App::setLocale('en');
$request->validate([
'productId' => 'required|integer|exists:products,id',
'options' => 'array',
'options.*' => 'distinct|integer',
'quantity' => 'required|integer',
'cartToken' => 'nullable|string|max:191'
]);
$this->product = Product::findOrFail($request['productId']);
if ($request['quantity'] < 0)
$this->condition = true;
else
$condition = $this->conditions($request['options'] ?? [], $request['quantity']);
if ($this->conditionStatus) {
try {
$query = CartModel::where('cart_token', $request['cartToken'])
->where('product_id', $this->product->id)
->whereJsonContains('option_ids', $request['options'] ?? [])
->firstOrFail();
$query->update([
'quantity' => $query->quantity + $request['quantity']
]);
} catch (\Exception $e) {
$query = CartModel::create([
'cart_token' => $request['cartToken'],
'product_id' => $this->product->id,
'option_ids' => $request['options'] ?? [],
'quantity' => $request['quantity']
]);
}
return response()->json([
'status' => true,
'code' => 101,
'cart_token' => $query->cart_token,
'message' => trans('frontend/alert.cart.added_to_cart', ['product' => $this->product->detail->handleMultipleLanuage('title')])
]);
}
return response()->json($condition, 422);
}
public function conditions(array $options = [], $quantity)
{
$productOptions = ProductOption::where('product_id', $this->product->id)->get();
if ($productOptions) {
if (count($productOptions) != count($options))
return [
'status' => false,
'code' => 107,
'message' => trans('frontend/alert.cart.select_option')
];
$userCart = CartModel::where('option_ids', $options)->sum('quantity');
$productOptionLists = ProductOptionList::whereIn('id', $options)->get();
foreach ($productOptionLists as $listItem) {
if ($listItem->quantity == 0)
return response()->json([
'status' => false,
'code' => 102,
'message' => trans('frontend/alert.cart.out_of_stock', ['product' => $this->product->detail->handleMultipleLanuage('title')])
]);
if ($listItem->quantity < $userCart + $quantity)
return [
'status' => false,
'code' => 103,
'message' => trans('frontend/alert.cart.maximum_units')
];
}
}
if ($this->product->stock->quantity == 0 && $this->product->stock->quantity < $quantity)
return response()->json([
'status' => false,
'code' => 102,
'message' => trans('frontend/alert.cart.out_of_stock', ['product' => $this->product->detail->handleMultipleLanuage('title')])
]);
if ($this->product->stock->quantity < CartModel::where('product_id', $this->product->id)->sum('quantity') + $quantity)
return [
'success' => false,
'code' => 103,
'message' => trans('frontend/alert.cart.maximum_units')
];
$this->conditionStatus = true;
}

how to render columns in laravel datatable?

i'm got stuck for 2 days, i got confused how to render column usind yajra/laravel-datatable
i'm using postgre as database, and yajra/laravel-datatables as package.
i have query builder like this
$data = DB::select("SELECT * FROM get_list_count_amount_transaction('chat', 'done', '2019-03-01', '2021-12-31' )")[0];
which generates a value of object : (i use var_dump() to see the value)
{ ["list_data"]=> string(2171)
"[{"id":"44649ccd-9195-4964-b48c-ed2098077dc5","kd_join":1,"status":"done","booking_date":"2021-04-18","transaction_type":"chat","price":4000.00,"date_create":"2021-04-18T19:56:57"},
{"id":"e500d2c1-99ae-4436-8ecc-8073f4f05bba","kd_join":1,"status":"done","booking_date":"2021-03-20","transaction_type":"chat","price":10000.00,"date_create":"2021-03-19T21:41:41"}
]"
["count_transaction"]=> int(12)
["total_amount_transaction"]=> string(9) "160500.00"
}
i'm confused, how to render list_data into a table using datatble
this is my html builder function :
public function html()
{
return $this->builder()
->columns($this->getColumns())
->minifiedAjax()
->addAction(['width' => '200px'])
->addColumnBefore([
'defaultContent' => '',
'data' => 'DT_Row_Index',
'name' => 'DT_Row_Index',
'title' => 'No',
'render' => function () {
return 'function(data,type,fullData,meta){return meta.settings._iDisplayStart+meta.row+1;}';
},
'orderable' => false,
'searchable' => false,
'exportable' => false,
'printable' => true,
'footer' => '',
]);
}
protected function getColumns()
{
return [
['data' => 'transaction_type', 'name' => 'transaction_type', 'title' => 'Tipe Transaksi', 'orderable' => false],
['data' => 'status', 'name' => 'status', 'title' => 'Status', 'orderable' => false],
['data' => 'booking_date', 'name' => 'booking_date', 'title' => 'Tanggal Booking', 'orderable' => false],
['data' => 'price', 'name' => 'price', 'title' => 'Jumlah', 'orderable' => false],
];
}
}
Just grab the list_data, use json_decode and laravel collection to make your needed structure. Try to use map, filter, mapWithKeys or whatever suitable.
For Instance:
collect(json_decode($listData))->mapWithKeys(function($item)){
//
}

How to solve this error: explode() expects parameter 2 to be string, object given?

I'm trying to setup different user types and their respective permissions in my AppServiceProvider.php in my project, and I get the error
explode() expects parameter 2 to be string, object given
Nowhere in my code do I have an explode() at least that I can see. Before adding the Inertia::share(function(){}) there was no such error.
This is my code:
public function register()
{
Inertia::version(function () {
return md5_file(public_path('mix-manifest.json'));
});
Inertia::share(function () {
$auth = null;
if (Auth::user()) {
$perms = [];
$user = Auth::user();
if ($user->isSuperAdmin() || $user->isAdmin()) {
$perms = [
[
'url' => '/',
'icon' => 'fa fa-home',
'name' => 'Dashboard'
],
[
//rest of permissions
],
];
}
if ($user->isUser()) {
$perms = [
[
'url' => '/',
'icon' => 'fa fa-home',
'name' => 'Dashboard'
],
[
//rest of permissions
],
];
}
$auth = [
'id' => Auth::user()->id,
'name' => Auth::user()->name,
'card' => Auth::user()->card,
'scard' => Auth::user()->scard,
'user_type_id' => Auth::user()->user_type_id,
'email' => Auth::user()->email,
'perms' => $perms
];
}
return [
'app' => [
'name' => Config::get('app.name'),
],
'auth' => [
'user' => $auth,
],
'flash' => [
'success' => Session::get('success'),
],
'errors' => Session::get('errors') ? Session::get('errors')->getBag('default')->getMessages() : (object)[],
]
});
What am I doing wrong? Where i'm getting the error it doesn't specify where the error is, just what it is, it signals the last line of the code I presented as where the error is, but all that's there is the closing parenthesis and brackets.
Knowing nothing of Inertia, it seems you are misusing the Inertia::share function. In their docs, I see 3 examples. The first two have parameter 1 being a string (eg. 'auth.user' or 'app.name'), and the last has parameter 1 being an associative array, so each element still has a unique string key.
In your code, you are passing a closure as the first parameter. I believe that you can fix it by simply adding a name as the first parameter:
Inertia::share('auth.user', function () {
$auth = null;
if (Auth::user()) {
$perms = [];
$user = Auth::user();
if ($user->isSuperAdmin() || $user->isAdmin()) {
$perms = [
[
'url' => '/',
'icon' => 'fa fa-home',
'name' => 'Dashboard'
],
[
//rest of permissions
],
];
}
if ($user->isUser()) {
$perms = [
[
'url' => '/',
'icon' => 'fa fa-home',
'name' => 'Dashboard'
],
[
//rest of permissions
],
];
}
$auth = [
'id' => Auth::user()->id,
'name' => Auth::user()->name,
'card' => Auth::user()->card,
'scard' => Auth::user()->scard,
'user_type_id' => Auth::user()->user_type_id,
'email' => Auth::user()->email,
'perms' => $perms
];
}
return [
'app' => [
'name' => Config::get('app.name'),
],
'auth' => [
'user' => $auth,
],
'flash' => [
'success' => Session::get('success'),
],
'errors' => Session::get('errors') ? Session::get('errors')->getBag('default')->getMessages() : (object)[],
];
});

yii2 select2 by kartik-v set default value

I've a question about yii2 kartik-v widget select 2.
the widget is attached to a field in my view
<?=
$form->field($model, 'address')->widget(Select2::className(), [
'options' => ['placeholder' => 'Inserta an address '],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'ajax' => [
'url' => Url::to(['register/addresses']),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(address) { return address.name; }'),
'templateSelection' => new JsExpression('function (address) { return address.name; }'),
],
'pluginEvents' => [
"select2:select" => "function(e) {
// some function
}",
],
]);
?>
if in my controller i want to set to this field a value
like: $model->address = "Some Value"; on the view the field remain blank
what can i do?
UPDATE!
As the documentation say i can use the option: 'initValueText' if i use the ajax version of this plugin. So i've tried to set 'initValueText' => $model->address, but the result is the same
hey i had the same issue with #ajax neither placeholder nor initValueText were showing
what i did was this
<?php
$product = $model->product_id ? Product::findOne($model->product_id)->name : 'select ....';
echo $form->field($model, 'product_id')->widget(Select2::classname(), [
'initValueText' => $product, // set the initial display text
// 'options' => ['placeholder' => 'select ....'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'ajax' => [
'url' => Url::to(['list']),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(product_id) { return product_id.name; }'),
'templateSelection' => new JsExpression('function (product_id) { return product_id.name; }'),
],
]);?>
if the model is new 'select ....' is shown else the product's name
since "options" is not doing much either
hope this will be hopeful to someone
The problem was this:
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(address) { return address.name; }'),
'templateSelection' => new JsExpression('function (address) { return address.name; }'),
It seems that this plugin want a specific return for the keys 'templateResult' and 'templateSelection'.
I've modified the JsExpression return value with address.text (instead of adress.name) as the guide examples : Link.
And then i've modified also the PHP method that return the results:
public function actionAddresses($q = NULL, $id = NULL)
{
Yii::$app->response->format = Response::FORMAT_JSON;
$results = array();
if (!is_null($q)) {
$geocoder = new GeocodingClient();
$request = $geocoder->lookup(['address' => $q]);
$counter = 1;
foreach ($request['results'] as $key => $value) {
$results['results'][] = [
'id' => $counter,
'text' => $value['formatted_address'], // Instead of 'name'
'coordinate' => $value['geometry']['location']
];
$counter++;
}
}
return $results;
}
I hope this may help someone with a similar problem.
Its bit late.. but i too had same problem.. i resolved it by assigning value
<?=
$form->field($model, 'address')->widget(Select2::className(), [
'initValueText' => $model->address,
'value' => $model->address,
'options' => ['placeholder' => 'Inserta an address '],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 3,
'ajax' => [
'url' => Url::to(['register/addresses']),
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('function(address) { return address.name; }'),
'templateSelection' => new JsExpression('function (address) { return address.name; }'),
],
'pluginEvents' => [
"select2:select" => "function(e) {
// some function
}",
],
]);
?>
you use kartik select2, in controller you have set a value (id/ids) and name values for 'initValueText'
$model->id = 1; // or if arrays [1,3,4,5]
$username = User::find()->select('name')->where('id' => $model->id)->scalar();
and in view kartik select2
$form->field($model, 'username')->widget(Select2::className(), [
'initValueText' => $username;
...
I was facing same problem. Then I tried value key into the options and it worked.
<?php
echo $form->field($model, 'test')->widget(Select2::classname(), [
//'data' => ['test', 'test2'],
'initValueText'=>['test','test2'],
'options' => ['multiple' => true, 'value'=>['1','2']],
'pluginOptions' => [
'multiple' => true,
'allowClear' => true,
'minimumInputLength' => 1,
'language' => [
'errorLoading' => new JsExpression("function () { return 'Waiting for results...'; }"),
],
'ajax' => [
'url' => '...',
'dataType' => 'json',
'data' => new JsExpression('function(params) { return {q:params.term}; }')
],
'escapeMarkup' => new JsExpression('function (m) { return m; }')
?>
Hope It'll be helpful for someone.
I fix this solution by using trigger function. In below method we can set default value in kartik select2 widget.
$('#id').val(11).trigger('change'); //in val() mention the hash value of your select2 list

Categories