How can I do this more readable? - php

I have to make permissions on seeder. Right now I have something like this:
$adminPermissions = collect([
$adminPermissions = collect([
'permission_read',
'permission_list',
'permission_create',
'permission_edit',
'permission_delete',
'role_read',
'role_list',
'role_create',
'role_edit',
'role_delete',
])->map(function ($name) {
return Permission::create([
'name' => $name
]);
});
])->map(function ($name) {
return Permission::create([
'name' => $name
]);
});
But I want to make something like this:
$rolePermissions = [
'role_read',
'role_list',
'role_create',
'role_edit',
'role_delete',
];
$permissionsForPermissions = [
'permission_read',
'permission_list',
'permission_create',
'permission_edit',
'permission_delete',
];
$adminPermissions = collect([
$PermissionsForPermissions,
$rolePermissions
])->map(function ($name) {
return Permission::create([
'name' => $name
]);
});
I know that this will not work because collect is waiting only for one array but I am asking if it's possible to do something like this because the first example is ugly.

You can use array_merge(), to merge your permission's arrays into one. So it will be something like:
$adminPermissions = collect(
array_merge(
$permissionsForPermissions,
$rolePermissions
)
)->map(function ($name) {
return Permission::create([
'name' => $name
]);
});
P.S. I am still not sure this is "more readable", but tastes differs.

I am not sure but you can try this. I used it like this way
$permission = array(
array('name' => 'user_view'),
array('name' => 'user_create'),
array('name' => 'user_edit'),
array('name' => 'user_delete'),
array('name' => 'project_view'),
array('name' => 'project_create'),
array('name' => 'project_edit'),
array('name' => 'project_delete'),
array('name' => 'team_view'),
array('name' => 'team_create'),
array('name' => 'team_edit'),
array('name' => 'team_delete')
);
Permission::insert($permission);

Related

Indirect modification of overloaded element of App\Models\ has no effect

I’m getting this error: Indirect modification of overloaded element of App\Models\ has no effect, change ->get(); to ->first->toArray(); another error Call to a member function toArray() on null
here the code
$penjualan = Penjualan::find(session('id_penjualan'));
$detail = PenjualanDetail::with('produk')->where('id_penjualan', session('id_penjualan'))->get();
$transaction = new Penjualan();
foreach ($detail as $item) {
$transaction_details = [
'order_id' => $penjualan->id_penjualan,
'gross_amount' => $penjualan->bayar,
];
$item_details = [
'id' => $penjualan->id_penjualan,
'price' => $item->harga_jual,
'quantity' => $item->jumlah,
'name' => $item->produk->nama_produk,
];
$customer_details = [
'first_name' => $request->get('uname'),
'last_name' => '',
'email' => $request->get('email'),
'phone' => $request->get('number'),
];
$transaction = [
'transaction_details' => $transaction_details,
'item_details' => $item_details,
'customer_details' => $customer_details,
];
}
$snapToken = Midtrans\Snap::getSnapToken($transaction);
$transaction->snap_token = $snapToken;
$transaction->save();
anyone could help me to fix this?
I have done Midtrans payment before.
The problem you've got with your current code are
you want to store snap_token inside your Penjualan model, but you use new Penjualan()
when multiple items are ordered, your code do not support it cause $item_details is a single array inside foreach loop
So here is an updated code with some notes and recommendations.
$id = session('id_penjualan');
$validated = $request->validate([
'uname' => 'required|string',
// 'lname' => 'nullable|string',
'email' => 'required|string',
'number' => 'required|string',
]);
// use single query to retrieve Penjualan and PenjualanDetail
// for product name, recommend to store it within PenjualanDetail, along with price and base_price
$penjualan = Penjualan::query()
->with('details')
->find($id);
if (!$penjualan) {
// you can redirect your customer to cart or any other page
return redirect('cart')->with('error', 'Can not find Penjualan.');
}
$item_details = [];
foreach ($penjualan->details as $item) {
$item_details[] = [
'id' => $item->id,
'price' => $item->harga_jual,
'quantity' => $item->jumlah,
// recommended product's name to be stored within PenjualanDetail
'name' => $item->nama_produk,
];
}
$transaction_details = [
'order_id' => $penjualan->id_penjualan,
// "bayar" must not contain any decimal, use cast Money
'gross_amount' => $penjualan->bayar,
];
// Optional
$customer_details = [
'first_name' => $validated['uname'],
'last_name' => '', // $validated['lname'],
'email' => $validated['email'],
'phone' => $validated['number'],
// 'billing_address' => '',
// 'shipping_address' => '',
];
// this is a simple array that will be sent to method getSnapToken()
$transaction = [
'transaction_details' => $transaction_details,
'customer_details' => $customer_details,
'item_details' => $item_details,
];
// this method only accept good old array
$snapToken = Midtrans\Snap::getSnapToken($transaction);
$penjualan->snap_token = $snapToken;
// recommend to store your customer detail here, either multiple fields or single array field storing $customer_details
// $penjualan->first_name = $customer_details['first_name'];
// $penjualan->last_name = $customer_details['last_name'];
// $penjualan->email = $customer_details['email'];
// $penjualan->phone = $customer_details['phone'];
// $penjualan->billing_address = $customer_details['billing_address'];
// $penjualan->shipping_address = $customer_details['shipping_address'];
$penjualan->save();
I commented out some parts that you might not use, where I did used them in the past.
Feel free to adjust them to suite your needs.
public function getSnapToken ()
{
$id = session('id_penjualan');
$member = Member::orderBy('nama')->get();
$penjualan = Penjualan::with(['penjualan_detail' => $detail = function ($query) {
$query->where('item', 'kode_produk, subtotal, jumlah, nama_produk');
}])->where('id_penjualan', ('id_penjualan'))
->orderBy('id_penjualan')
->get();
$transaction = array($penjualan);
foreach ( $detail as $item ) {
$transaction_details = [
'order_id' => $this->penjualan->id_penjualan,
'gross_amount' => $this->penjualan->bayar,
];
$item_details = [
'id' => $item->produk->kode_produk,
'price' => $item->jumlah * $item->subtotal,
'quantity' => $item->jumlah,
'name' => $item->produk->nama_produk,
];
$customer_details = [
'id' => $penjualan->member->kode_member,
'first_name' => $validated['uname'],
'last_name' => $validated['lname'],
'email' => $validated['email'],
'phone' => $validated['number'],
// 'billing_address' => '',
// 'shipping_address' => '',
];
$transaction = [
'transaction_details' => $transaction_details,
'item_details' => $item_details,
'customer_details' => $customer_details,
];
}
$snap_token = '';
try {
$snap_token = \Midtrans\Snap::getSnapToken($transaction);
}
catch (\Exception $e) {
echo $e->getMessage();
}
echo "snap_token = ".$snap_token;
}
public function payment(Penjualan $penjualan)
{
$snap_token = $penjualan->snap_token;
if (is_null($snap_token)) {
$midtrans = new CreateSnapTokenService($penjualan);
$snap_token = $midtrans->getSnapToken();
$snap_token = Penjualan::where('id_penjualan')->update(['snap_token' => $snap_token]);
}
return view('penjualan.payment', ['snap_token'=>$snap_token]);
}

Laravel update table

I'm trying to do simple function edit student table field, But its updating only first field: first_name
My controller.
public function editStudent(Request $request)
{
$studId = $request->get('studId');
$studFirstName = $request->get('firstName');
$studLastName = $request->get('lastName');
$studGender = $request->get('gender');
$studBirthday = $request->get('birthday');
$studSchoolId = $request->get('schoolId');
$update = Student::where('id', $studId)->update(['first_name' => $studFirstName],
['last_name' => $studLastName], ['gender' => $studGender], ['birthday', $studBirthday], ['school_id' => $studSchoolId]);
return response()->json([
"update" => $update,
]);
}
Update takes a single array, you're passing in multiple arrays
$update = Student::where('id', $studId)
->update([
'first_name' => $studFirstName,
'last_name' => $studLastName,
'gender' => $studGender,
'birthday'=> $studBirthday,
'school_id' => $studSchoolId
]);
Its better to get the item from DB then update that on a second query:
$student = Student::find($studId);
$student->update([
'first_name' => $request->firstName,
'last_name' => $request->lastName,
'gender' => $request->gender,
'birthday'=> $request->birthday,
'school_id' => $request->schoolId
]);

How to create a factory for post where it also enters data in meta table for that post in laravel

using factory is a cleaner way to create seed data.
I can generate the result from another method of foreach or for loop. but how to do it with the factory ?
below is the post factory page
<?php
/** #var \Illuminate\Database\Eloquent\Factory $factory */
use App\Post;
use App\MetaData;
use Faker\Factory;
$factory->define(Post::class, function () {
$faker = Faker\Factory::create('en_IN');
$w = $faker->unique()->sentence.' '.mt_rand(0,1000);
$r = [
'title' => $w,
'slug' => strtolower(str_replace(' ', '-', $w)),
'banner' => 'https://source.unsplash.com/random/600x600',
'content' => $faker->text,
'views' => mt_rand(0,1000),
'status' => rand(0,1),
'creator_id' => mt_rand(0,100),
'moderator_id' => mt_rand(0,100),
];
$factory->define(MetaData::class, function () {
return [
'for' => 'article',
'record_id' => $r->id,
'title' => $w,
'slug' => strtolower(str_replace(' ', '-', $w)),
'description' => $faker->sentences,
'banner' => 'https://source.unsplash.com/random/600x600',
'keywords' => $faker->words,
'status' => 1,
'creator_id' => mt_rand(0,100),
'moderator_id' => mt_rand(0,100),
];
});
return $r;
});
I want to do something like this, but end up with an error like below:
ErrorException : Undefined variable: factory
at /Users/dragonar/Dev/pdp/database/factories/PostFactory.php:23
19| 'creator_id' => mt_rand(0,100),
20| 'moderator_id' => mt_rand(0,100),
21| ];
22|
> 23| $factory->define(MetaData::class, function () {
24| return [
25| 'for' => 'article',
26| 'record_id' => $r->id,
27| 'title' => $w,
Exception trace:
1 Illuminate\Foundation\Bootstrap\HandleExceptions::handleError("Undefined variable: factory", "/Users/dragonar/Dev/pdp/database/factories/PostFactory.php", [Object(Faker\Generator), "Aut voluptatum sed aut beatae. 380"])
/Users/dragonar/Dev/pdp/database/factories/PostFactory.php:23
2 Illuminate\Database\Eloquent\Factory::{closure}(Object(Faker\Generator), [])
/Users/dragonar/Dev/pdp/vendor/laravel/framework/src/Illuminate/Database/Eloquent/FactoryBuilder.php:273
Please use the argument -v to see more details.
if this solves, I also want to add categories and tags to the same post.
please try this
$factory->define('App\MetaData', function($faker) use ($factory) {
// Your stuff here
});
The problem here is that you are trying to define the child inside the factory of the parent.
You are getting an ErrorException : Undefined variable: factory error, that tells you that $factory is not defined. This is because you are doing it in the closure for the post factory.
One way you can get around this, is to reference the post when creating the meta data, so you do not create them both at the same time.
<?php
/** #var \Illuminate\Database\Eloquent\Factory $factory */
use App\Post;
use App\MetaData;
use Faker\Factory;
$factory->define(Post::class, function () {
$faker = Faker\Factory::create('en_IN');
$w = $faker->unique()->sentence.' '.mt_rand(0,1000);
return [
'title' => $w,
'slug' => strtolower(str_replace(' ', '-', $w)),
'banner' => 'https://source.unsplash.com/random/600x600',
'content' => $faker->text,
'views' => mt_rand(0,1000),
'status' => rand(0,1),
'creator_id' => mt_rand(0,100),
'moderator_id' => mt_rand(0,100),
];
});
$factory->define(MetaData::class, function () {
return [
'for' => 'article',
'record_id' => factory(Post::class)->id,
'title' => $w,
'slug' => strtolower(str_replace(' ', '-', $w)),
'description' => $faker->sentences,
'banner' => 'https://source.unsplash.com/random/600x600',
'keywords' => $faker->words,
'status' => 1,
'creator_id' => mt_rand(0,100),
'moderator_id' => mt_rand(0,100),
];
});
When doing it like this, you first create the post, then you create the metadata and reference the post when creating it. However, I am not sure that helps you with your issue. So what you could do is create a helper class, where you can pass in some overrides for both classes, in case you want to control what data goes into each model.
Can be done like so:
<?php
use App\Post;
use App\MetaData;
class FactoryHelper {
public static function createPostWithMetaData(array $postAttributes = [], array $metaDataAttributes = [])
{
$post = factory(Post::class)->create(postAttributes);
$metaData = factory(MetaData::class)->create(array_merge([
'record_id' => $post->id
], $metaDataAttributes));
return $post;
}
}

Updating has many relationship in Laravel

I'm building a small application in Laravel 5.5 where I'm having two models: Interaction and Interaction Summary in my Interaction model I'm having following relationship:
public function meetingSummaries()
{
return $this->hasMany('App\InteractionSummary');
}
Now to create the interaction I'm using following in my controller:
$data = $request->only('user_id', 'event_type', 'schedule', 'summaries', 'type', 'venue', 'with_client');
$data['schedule'] = Carbon::parse($request->schedule)->addHours(5)->addMinutes(30)->toDateTimeString();
$meeting = [];
$meeting['user_id']= $data['user_id'];
$meeting['schedule'] = $data['schedule'];
$meeting['type'] = $data['type'];
$meeting['with_client'] = $data['with_client'];
$meeting['venue'] = $data['venue'];
$meeting['event_type'] = $data['event_type'];
$interaction = Interaction::create($meeting);
if($data['summaries'])
{
$container = [];
foreach($data['summaries'] as $summary)
{
$summary = (Object)$summary;
if($summary->client['label'])
{
$container[] = new InteractionSummary([
'company_id' => $summary->client['label'],
'nature' => $summary->type,
'user_id' => $summary->mention['label'],
'action' => $summary->action,
'feedback' => $summary->comment
]);
}
}
}
$interaction->meetingSummaries()->saveMany($container);
}
But while updating I don't know to overcome this, as in my fields there might be new or old relational data. I'm trying something like this:
if($data['summaries'])
{
$container = [];
foreach($data['summaries'] as $summary)
{
$summary = (Object)$summary;
if($summary->id)
{
$container[] = new InteractionSummary([
'id' => $summary->id,
'company_id' => $summary->client['value'],
'nature' => $summary->type,
'user_id' => $summary->mention['value'],
'action' => $summary->action,
'feedback' => $summary->comment
]);
}
else {
$container[] = new InteractionSummary([
'company_id' => $summary->client['value'],
'nature' => $summary->type,
'user_id' => $summary->mention['value'],
'action' => $summary->action,
'feedback' => $summary->comment
]);
}
}
$interaction->meetingSummaries()->save($container);
}
Which is sending me error:
Type error: Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an instance of Illuminate\Database\Eloquent\Model, array given, called in ~\app\Http\Controllers\InteractionsController.php on line 449
If I do:
$interaction->meetingSummaries()->saveMany($container);
I get repeated new fields.
Guide me how to overcome this. Thanks.
Use the findOrNew() method:
$summaryItem = InteractionSummary::findOrNew($summary->id);
$summaryItem->fill([
'company_id' => $summary->client['value'],
'nature' => $summary->type,
'user_id' => $summary->mention['value'],
'action' => $summary->action,
'feedback' => $summary->comment
]);

Codeigniter cart

I am new and I don't know much.
I tried several ways but still nothing.
It's not working this way.
public function addToCart(){
$product_url=md5($this->input->post('produktUrl'));
$cart['id']=$product_url;
$cart['qty']=$this->input->post('kol');
$cart['price']=$this->model->cena($this->input->post('produktUrl'));
$cart['name']=$this->input->post('produktUrl');
$cart['ime']=$this->input->post('ime');
$cart['options']['size']=$this->input->post('golemina');
$cart['options']['color']=$this->input->post('boja');
foreach ($this->cart->contents() as $key) {
if($cart['id']==$key['id']){
$cart['rowid']=$key['rowid'];
$cart['qty']=$this->input->post('kol');
$this->cart->update($cart);
} else {
$this->cart->insert($cart);
}
}
print_r($this->cart->contents());
}
I don't actually know what your problem is, but you can try this one:
public function addToCart() {
$product_url = md5($this->input->post('produktUrl'));
$data = array(
'id' => $product_url,
'qty' => $this->input->post('kol'),
'price' => $this->model->cena($this->input->post('produktUrl')),
'name' => $this->input->post('produktUrl'),
'options' => array(
'ime' => $this->input->post('ime'),
'size' => $this->input->post('golemina'),
'color' => $this->input->post('boja')
)
);
$this->cart->insert($data);
print_r($this->cart->contents());
}
also, make sure that you've loaded this in application/config/autoload.php
$autoload['libraries'] = array('database' , 'session', 'cart');
I hope this helps.

Categories