Skip to content

Commit 97c5398

Browse files
committed
ProductImages & ProductAttributes added in product update options :worked with Stub,Artisan Command on Penguin\Bread package
1 parent 4cb47c3 commit 97c5398

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+5319
-3066
lines changed

README.md

+68
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,71 @@
88
npm run watch-poll
99
```
1010

11+
# Polymorphic Relationship
12+
13+
### One to Many (Images with Product, User , Brand, Category etc :smile:
14+
15+
> ### ` php artisan make:model Image -mc `
16+
17+
```php
18+
//[...] database/migrations/2020_11_13_154946_create_images_table.php
19+
20+
Schema::create('images', function (Blueprint $table) {
21+
$table->id();
22+
$table->morphs('imageable');
23+
// $table->unsignedBigInteger('imageable_id')->index();
24+
// $table->string('imageable_type');
25+
$table->timestamps();
26+
});
27+
28+
```
29+
30+
```php
31+
<?php
32+
33+
namespace App\Models;
34+
35+
use Illuminate\Database\Eloquent\Model;
36+
37+
class Image extends Model
38+
{
39+
public function imageable()
40+
{
41+
return $this->morphTo();
42+
}
43+
}
44+
```
45+
```php
46+
class Product extends Model
47+
{
48+
public function images()
49+
{
50+
return $this->morphMany('App\Models\Image', 'imageable');
51+
// imageable is method came from Image Model
52+
}
53+
}
54+
```
55+
```php
56+
class Post extends Model
57+
{
58+
public function images()
59+
{
60+
return $this->morphMany('App\Models\Image', 'imageable');
61+
// imageable is method came from Image Model
62+
}
63+
}
64+
```
65+
66+
```php
67+
class Brand extends Model
68+
{
69+
public function images()
70+
{
71+
return $this->morphMany('App\Models\Image', 'imageable');
72+
// imageable is method came from Image Model
73+
}
74+
}
75+
```
76+
77+
78+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace App\Http\Controllers\Admin;
4+
5+
use App\Http\Controllers\Controller;
6+
use App\Http\Resources\ProductResource;
7+
use App\Models\Image;
8+
use App\Models\Product;
9+
use App\Traits\UploadAble;
10+
use Illuminate\Http\Request;
11+
use Illuminate\Support\Facades\Storage;
12+
13+
class ImageController extends Controller
14+
{
15+
16+
use UploadAble;
17+
18+
public function index()
19+
{
20+
return Image::latest()->get();
21+
}
22+
23+
/**
24+
* Store a newly created resource in storage.
25+
*
26+
* @param \Illuminate\Http\Request $request
27+
* @return \Illuminate\Http\Response
28+
*/
29+
public function store(Request $request)
30+
{
31+
// return $request->images[0];
32+
$this->validate($request,[
33+
'images' => 'required',
34+
'productId' => 'required'
35+
]);
36+
37+
$product = Product::find($request->productId);
38+
// $images = collect($request->images);
39+
foreach ($request->images as $encoded_data) {
40+
$newImage = $this->base64ToImage($encoded_data)['image'];
41+
$extension = $this->base64ToImage($encoded_data)['extension'];
42+
43+
$uploadedFile = $this->uploadBase64File($encoded_data , 'images/','public');
44+
45+
$product->images()->create([
46+
'image' => $uploadedFile['name']
47+
]);
48+
}
49+
return response()->json(
50+
new ProductResource($product), 201
51+
);
52+
}
53+
54+
/**
55+
* Display the specified resource.
56+
*
57+
* @param \App\Models\Image $image
58+
* @return \Illuminate\Http\Response
59+
*/
60+
public function show(Image $image)
61+
{
62+
return $image;
63+
}
64+
65+
/**
66+
* Update the specified resource in storage.
67+
*
68+
* @param \Illuminate\Http\Request $request
69+
* @param \App\Models\Image $image
70+
* @return \Illuminate\Http\Response
71+
*/
72+
public function update(Request $request, Image $image)
73+
{
74+
return $image->update($request->all());
75+
}
76+
77+
/**
78+
* Remove the specified resource from storage.
79+
*
80+
* @param \App\Models\Image $image
81+
* @return \Illuminate\Http\Response
82+
*/
83+
public function destroy(Image $image)
84+
{
85+
if($this->deleteOne($image->image, "images/")){
86+
return $image->delete();
87+
};
88+
89+
// return $image->delete();
90+
}
91+
}

app/Http/Controllers/Admin/ProductController.php

+32
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
use App\Contracts\ProductContract;
66
use App\Http\Controllers\Controller;
77
use App\Http\Requests\ProductRequest;
8+
use App\Http\Resources\ProductAttributeResource;
9+
use App\Http\Resources\ProductResource;
810
use App\Models\Product;
11+
use App\Models\ProductAttribute;
912
use App\Traits\UploadAble;
1013
use Illuminate\Http\Request;
1114
use Illuminate\Support\Facades\Storage;
@@ -112,6 +115,35 @@ public function update(ProductRequest $request, Product $product)
112115
$merged = array_merge($request->all(),$attributes);
113116
return $this->productRepository->update($merged,$request->id);
114117
}
118+
public function getProductAttribute()
119+
{
120+
$productAttributes = ProductAttribute::all();
121+
return ProductAttributeResource::collection($productAttributes);
122+
}
123+
public function createProductAttribute(Request $request)
124+
{
125+
$this->validate($request , [
126+
'attribute_id' => 'required',
127+
'product_id' => 'required',
128+
'quantity' => 'required|numeric',
129+
'price' => 'required'
130+
]);
131+
$attribute = ProductAttribute::create($request->all());
132+
$product = Product::findOrFail($request->product_id);
133+
return response()->json(
134+
new ProductAttributeResource($attribute)
135+
, 201);
136+
}
137+
public function deleteProductAttribute($productAttributeId)
138+
{
139+
$productAttribute = ProductAttribute::find($productAttributeId);
140+
if ($productAttribute) {
141+
return $productAttribute->delete();
142+
}
143+
return response()->json([
144+
"error" => 'Atrribute Not Found'
145+
], 404);
146+
}
115147

116148
/**
117149
* Remove the specified resource from storage.

app/Http/Requests/ProductRequest.php

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public function rules()
3131
'price' => 'required',
3232
'description' => 'required',
3333
'slug' => !$this->slug ? 'nullable|unique:products,slug' : 'nullable|unique:products,slug,'.$this->id,
34+
'categories' => 'required',
3435
'brand_id' => 'required|exists:brands,id',
3536
'quantity' => 'required'
3637
];

app/Http/Resources/AttributeResource.php

+1-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ public function toArray($request)
2121
"name" =>$this->name,
2222
"slug" => $this->slug ? $this->slug: "none",
2323
"type" => $this->value?['id'=>$this->value->id,'name'=>$this->value->name,'slug'=>$this->value->slug]: "",
24-
"values" => $this->values,
25-
"created_at" => $this->created_at->diffForHumans(),
26-
"updated_at" => $this->updated_at->diffForHumans()
24+
"values" => $this->values
2725
];
2826
}
2927
}
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
use Illuminate\Support\Facades\Storage;
7+
8+
class CategoryResource extends JsonResource
9+
{
10+
/**
11+
* Transform the resource into an array.
12+
*
13+
* @param \Illuminate\Http\Request $request
14+
* @return array
15+
*/
16+
public function toArray($request)
17+
{
18+
return [
19+
'id' => $this->id,
20+
'name' => $this->name,
21+
'slug' => $this->slug,
22+
'icon' => $this->icon ? Storage::url('categories/'.$this->icon) : Storage::url('categories/default.png')
23+
];
24+
}
25+
}

app/Http/Resources/ImageResource.php

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
use Illuminate\Support\Facades\Storage;
7+
8+
class ImageResource extends JsonResource
9+
{
10+
/**
11+
* Transform the resource into an array.
12+
*
13+
* @param \Illuminate\Http\Request $request
14+
* @return array
15+
*/
16+
public function toArray($request)
17+
{
18+
// return parent::toArray($request);
19+
return [
20+
'id' => $this->id,
21+
'url' => Storage::url('images/'.$this->image),
22+
'imageable_id' => $this->imageable_id,
23+
'imageable_type' => $this->imageable_type,
24+
];
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Resources\Json\JsonResource;
6+
7+
class ProductAttributeResource extends JsonResource
8+
{
9+
/**
10+
* Transform the resource into an array.
11+
*
12+
* @param \Illuminate\Http\Request $request
13+
* @return array
14+
*/
15+
public function toArray($request)
16+
{
17+
// return parent::toArray($request);
18+
return [
19+
"id" => $this->id,
20+
"attribute_id" => $this->attribute_id,
21+
"price" => $this->price,
22+
"quantity" => $this->quantity,
23+
'type' => $this->attribute->value,
24+
'name' => $this->attribute->name,
25+
'slug' => $this->attribute->slug
26+
];
27+
}
28+
}

app/Http/Resources/ProductResource.php

+3-9
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,9 @@ public function toArray($request)
2727
"quantity" => $this->quantity,
2828
"featured" => $this->featured == 1 ? true : false,
2929
"status" => $this->status == 1 ,
30-
'categories' => $this->categories->map(function($cat)
31-
{
32-
return [
33-
'id' => $cat->id,
34-
'name' => $cat->name,
35-
'slug' => $cat->slug,
36-
'icon' => $cat->icon ? Storage::url('categories/'.$cat->icon) : Storage::url('categories/default.png')
37-
];
38-
}),
30+
'categories' => CategoryResource::collection($this->categories),
31+
'images' => ImageResource::collection($this->images),
32+
'attributes' => ProductAttributeResource::collection($this->attributes),
3933
"image" => $this->image ? Storage::url('products/'.$this->image) : Storage::url('products/default.png'),
4034
"description" => $this->description,
4135
"created_at" => $this->created_at->diffForHumans(),

app/Models/Image.php

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class Image extends Model
8+
{
9+
protected $guarded = [];
10+
11+
public function imageable()
12+
{
13+
return $this->morphTo();
14+
}
15+
}

app/Models/Product.php

+11-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Factories\HasFactory;
66
use Illuminate\Database\Eloquent\Model;
7-
7+
use Str;
88
class Product extends Model
99
{
1010
use HasFactory;
@@ -22,9 +22,18 @@ public function categories()
2222
return $this->morphToMany('App\Models\Category', 'categoryable');
2323
}
2424

25+
public function images()
26+
{
27+
return $this->morphMany('App\Models\Image', 'imageable');
28+
}
29+
public function attributes()
30+
{
31+
return $this->hasMany('App\Models\ProductAttribute');
32+
}
33+
2534
public function setNameAttribute($value){
2635
$this->attributes['name'] = $value;
27-
$this->attributes['slug'] = \Str::slug($value);
36+
$this->attributes['slug'] = Str::slug($value);
2837
}
2938
public function scopeSearch($query , $q)
3039
{

app/Models/ProductAttribute.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class ProductAttribute extends Model
8+
{
9+
10+
protected $guarded = [];
11+
protected $table = 'product_attributes';
12+
public $timestamps = false;
13+
14+
public function product()
15+
{
16+
return $this->belongsTo(Product::class);
17+
}
18+
19+
public function attribute()
20+
{
21+
return $this->belongsTo(Attribute::class);
22+
}
23+
}

0 commit comments

Comments
 (0)