Anonymous
Результат добавления атрибута Laravel из-за нехватки памяти
Сообщение
Anonymous » 25 июл 2024, 17:57
В модели OrderItem я пытаюсь добавить значение купона, обращаясь к взаимосвязи «Заказ», как показано ниже:
Код: Выделить всё
public function getCouponValueAttribute() {
if($this->order->coupon_data) {
if(!$this->sale && !$this->gift) {
return ($this->original_price * $this->quantity) - (($this->original_price * $this->quantity) - (($this->original_price * $this->quantity)*($this->order->coupon_data['percentage']/100)));
}
}
return 0;
}
Это приводит к нехватке памяти на сервере.
Связь заказов через модель заказа
Код: Выделить всё
public function order() {
return $this->belongsTo(Order::class);
}
Модель заказа выглядит следующим образом:
Код: Выделить всё
class Order extends Model
{
use FilterQueryString;
protected $guarded = [];
protected $filters = ['in', 'inPayment', 'sort'];
protected $appends = ['subtotal', 'discountTotal', 'discountTotal2', 'couponDiscount', 'shipping_details', 'shipping_product_name', 'gross_value', 'net_value', 'shipping_iso', 'generated_tracking_url', 'is_retail'];
protected $casts = [
'shipping_address' => 'array',
'billing_address' => 'array',
'shipping_option' => 'array',
'coupon_data' => 'array',
'customer' => 'array',
'invoice' => 'array'
];
public function items() {
return $this->hasMany(OrderItem::class);
}
public function payment() {
return $this->hasOne(PaymentDetail::class);
}
public function user() {
return $this->belongsTo(User::class);
}
public function notes() {
return $this->hasMany(OrderNote::class);
}
public function added_payments() {
return $this->hasMany(AddedPayment::class);
}
public function inPayment($query, $value) {
$value = explode(",", $value);
return $query->whereHas('payment', function($q) use ($value) {
$q->whereIn('status', $value);
});
}
public function country() {
return $this->hasOneThrough(Country::class, User::class, 'country_id', 'id', 'user_id', 'id');
}
public function coupon() {
return $this->belongsTo(Coupon::class);
}
public function points() {
return $this->hasOne(LoyaltyPoint::class);
}
public function shipments() {
return $this->hasMany(OrderShipment::class);
}
public function scopeQuote($query) {
return $query->where('quote', true)->orWhere('was_quote', true);
}
public function scopeActive($query) {
return $query->whereIn('status', [1,2,3]);
}
public function getActiveItemsAttribute() {
return array_filter($this->items->toArray(), function($q) {
return $q['status'] == 1;
});
}
public function getSubtotalAttribute() {
$subtotal = 0;
foreach($this->items as $i) {
if($i->status) {
$subtotal += $i->price * $i->quantity;
}
}
return $subtotal;
}
public function getCouponDiscountAttribute() {
$discount = 0;
if($this->coupon_data) {
foreach($this->items as $i) {
if($i->status && !$i->sale && !$i->gift) {
$price = $i->bulk_price ? $i->bulk_price : $i->original_price;
$discount += ($price - $i->price) * $i->quantity;
}
}
}
return abs($discount);
}
public function getDiscountTotalAttribute() {
$discount = 0;
foreach($this->items as $i) {
if($i->status) {
$discount += ($i->original_price - $i->price) * $i->quantity;
}
}
return abs($discount);
}
public function getNetValueAttribute() {
$net_value = 0;
foreach($this->items as $i) {
$net_value += $i->price*$i->quantity;
}
return $net_value;
}
public function getShippingProfilesAttribute() {
return (array) [
(object)[
'quantity' => 4,
'length' => 25,
'width' => 20,
'height' => 10
],
(object) [
'quantity' => 8,
'length' => 30.5,
'width' => 21.5,
'height' => 20
],
(object) [
'quantity' => 15,
'length' => 32,
'width' => 24,
'height' => 24
],
(object) [
'quantity' => 20,
'length' => 50,
'width' => 30,
'height' => 20
],
(object) [
'quantity' => 30,
'length' => 50,
'width' => 30,
'height' => 25
],
(object) [
'quantity' => 40,
'length' => 60,
'width' => 40,
'height' => 20
],
(object) [
'quantity' => 50,
'length' => 48,
'width' => 40,
'height' => 30
],
(object) [
'quantity' => 60,
'length' => 60,
'width' => 40,
'height' => 25
]
];
}
public function getDhlPackagesAttribute() {
$packages = [];
$quantity = 0;
foreach($this->items as $i) {
$quantity += $i->quantity;
}
do {
foreach($this->shipping_profiles as $key => $p) {
if($quantity > 0) {
if($quantity quantity) {
$data = (object)[
'weight' => number_format(floatVal((($p->length*$p->width*$p->height)/5000)), 2),
'dimensions' => (object)[
'length' => $p->length,
'width' => $p->width,
'height' => $p->height
]
];
$quantity -= $p->quantity;
array_push($packages, $data);
}
else if ($key == array_key_last($this->shipping_profiles)) {
$data = (object)[
'weight' => number_format(floatVal((($p->length*$p->width*$p->height)/5000)), 2),
'dimensions' => (object)[
'length' => $p->length,
'width' => $p->width,
'height' => $p->height
]
];
$quantity -= $p->quantity;
array_push($packages, $data);
}
}
}
}while($quantity > 0);
return $packages;
}
public function getDiscountTotal2Attribute() {
//Discount based on product discount
$discount = 0;
foreach($this->items as $i) {
if($i->sale && $i->status) {
$discount += ($i->original_price * $i->quantity) - ($i->price * $i->quantity);
}
}
return abs($discount);
}
public function getIsRetailAttribute() {
if(isset($this->user->is_retail)) {
if($this->user->is_retail) {
return true;
}
}
return false;
}
public function getGrossValueAttribute() {
$gross_value = 0;
foreach($this->items as $i) {
if($i->status) {
$gross_value += $i->original_price * $i->quantity;
}
}
return $gross_value;
}
public function getItemQuantityAttribute() {
$quantity = 0;
foreach($this->items as $i) {
if($i->status) {
$quantity += $i->quantity;
}
};
return $quantity;
}
public function getShippingDetailsAttribute() {
if(isset($this->shipping_option['shipping_option'])) {
return $this->shipping_option['shipping_option'];
}
if(isset($this->shipping_option)) {
return $this->shipping_option;
}
return null;
}
public function getShippingProductNameAttribute() {
if(isset($this->shipping_option['name'])) {
return $this->shipping_option['name'];
}
if(isset($this->shipping_option['productName'])) {
return $this->shipping_option['productName'];
}
return null;
}
public function getShippingIsoAttribute() {
$country = Country::find($this->shipping_address['country_id']);
return $country->iso2;
}
public function getGeneratedTrackingUrlAttribute() {
if($this->shipping_company == 'dhl') {
return 'https://www.dhl.com/gr-en/home/tracking.html?tracking-id='.$this->tracking_id;
}
if($this->shipping_company == 'speedex') {
return 'http://www.speedex.gr/isapohi.asp';
}
if($this->shipping_company == 'fedex') {
return 'https://www.fedex.com/fedextrack/?trknbr='.$this->tracking_id;
}
return null;
}
protected static function booted()
{
static::deleting(function ($order) {
$order->payment()->delete();
$order->added_payments()->delete();
$order->shipments()->delete();
$order->items()->delete();
$order->notes()->delete();
$order->points()->delete();
});
static::updated(function($order) {
Loyalty::calculateOrderPoints($order);
});
static::created(function($order) {
Loyalty::calculateOrderPoints($order);
});
}
}
Возможно, атрибут, который я пытаюсь добавить, создает где-то цикл, и на сервере не хватает памяти, я не могу это понять.
Подробнее здесь:
https://stackoverflow.com/questions/787 ... -of-memory
1721919457
Anonymous
В модели OrderItem я пытаюсь добавить значение купона, обращаясь к взаимосвязи «Заказ», как показано ниже: [code]public function getCouponValueAttribute() { if($this->order->coupon_data) { if(!$this->sale && !$this->gift) { return ($this->original_price * $this->quantity) - (($this->original_price * $this->quantity) - (($this->original_price * $this->quantity)*($this->order->coupon_data['percentage']/100))); } } return 0; } [/code] Это приводит к нехватке памяти на сервере. Связь заказов через модель заказа [code] public function order() { return $this->belongsTo(Order::class); } [/code] Модель заказа выглядит следующим образом: [code]class Order extends Model { use FilterQueryString; protected $guarded = []; protected $filters = ['in', 'inPayment', 'sort']; protected $appends = ['subtotal', 'discountTotal', 'discountTotal2', 'couponDiscount', 'shipping_details', 'shipping_product_name', 'gross_value', 'net_value', 'shipping_iso', 'generated_tracking_url', 'is_retail']; protected $casts = [ 'shipping_address' => 'array', 'billing_address' => 'array', 'shipping_option' => 'array', 'coupon_data' => 'array', 'customer' => 'array', 'invoice' => 'array' ]; public function items() { return $this->hasMany(OrderItem::class); } public function payment() { return $this->hasOne(PaymentDetail::class); } public function user() { return $this->belongsTo(User::class); } public function notes() { return $this->hasMany(OrderNote::class); } public function added_payments() { return $this->hasMany(AddedPayment::class); } public function inPayment($query, $value) { $value = explode(",", $value); return $query->whereHas('payment', function($q) use ($value) { $q->whereIn('status', $value); }); } public function country() { return $this->hasOneThrough(Country::class, User::class, 'country_id', 'id', 'user_id', 'id'); } public function coupon() { return $this->belongsTo(Coupon::class); } public function points() { return $this->hasOne(LoyaltyPoint::class); } public function shipments() { return $this->hasMany(OrderShipment::class); } public function scopeQuote($query) { return $query->where('quote', true)->orWhere('was_quote', true); } public function scopeActive($query) { return $query->whereIn('status', [1,2,3]); } public function getActiveItemsAttribute() { return array_filter($this->items->toArray(), function($q) { return $q['status'] == 1; }); } public function getSubtotalAttribute() { $subtotal = 0; foreach($this->items as $i) { if($i->status) { $subtotal += $i->price * $i->quantity; } } return $subtotal; } public function getCouponDiscountAttribute() { $discount = 0; if($this->coupon_data) { foreach($this->items as $i) { if($i->status && !$i->sale && !$i->gift) { $price = $i->bulk_price ? $i->bulk_price : $i->original_price; $discount += ($price - $i->price) * $i->quantity; } } } return abs($discount); } public function getDiscountTotalAttribute() { $discount = 0; foreach($this->items as $i) { if($i->status) { $discount += ($i->original_price - $i->price) * $i->quantity; } } return abs($discount); } public function getNetValueAttribute() { $net_value = 0; foreach($this->items as $i) { $net_value += $i->price*$i->quantity; } return $net_value; } public function getShippingProfilesAttribute() { return (array) [ (object)[ 'quantity' => 4, 'length' => 25, 'width' => 20, 'height' => 10 ], (object) [ 'quantity' => 8, 'length' => 30.5, 'width' => 21.5, 'height' => 20 ], (object) [ 'quantity' => 15, 'length' => 32, 'width' => 24, 'height' => 24 ], (object) [ 'quantity' => 20, 'length' => 50, 'width' => 30, 'height' => 20 ], (object) [ 'quantity' => 30, 'length' => 50, 'width' => 30, 'height' => 25 ], (object) [ 'quantity' => 40, 'length' => 60, 'width' => 40, 'height' => 20 ], (object) [ 'quantity' => 50, 'length' => 48, 'width' => 40, 'height' => 30 ], (object) [ 'quantity' => 60, 'length' => 60, 'width' => 40, 'height' => 25 ] ]; } public function getDhlPackagesAttribute() { $packages = []; $quantity = 0; foreach($this->items as $i) { $quantity += $i->quantity; } do { foreach($this->shipping_profiles as $key => $p) { if($quantity > 0) { if($quantity quantity) { $data = (object)[ 'weight' => number_format(floatVal((($p->length*$p->width*$p->height)/5000)), 2), 'dimensions' => (object)[ 'length' => $p->length, 'width' => $p->width, 'height' => $p->height ] ]; $quantity -= $p->quantity; array_push($packages, $data); } else if ($key == array_key_last($this->shipping_profiles)) { $data = (object)[ 'weight' => number_format(floatVal((($p->length*$p->width*$p->height)/5000)), 2), 'dimensions' => (object)[ 'length' => $p->length, 'width' => $p->width, 'height' => $p->height ] ]; $quantity -= $p->quantity; array_push($packages, $data); } } } }while($quantity > 0); return $packages; } public function getDiscountTotal2Attribute() { //Discount based on product discount $discount = 0; foreach($this->items as $i) { if($i->sale && $i->status) { $discount += ($i->original_price * $i->quantity) - ($i->price * $i->quantity); } } return abs($discount); } public function getIsRetailAttribute() { if(isset($this->user->is_retail)) { if($this->user->is_retail) { return true; } } return false; } public function getGrossValueAttribute() { $gross_value = 0; foreach($this->items as $i) { if($i->status) { $gross_value += $i->original_price * $i->quantity; } } return $gross_value; } public function getItemQuantityAttribute() { $quantity = 0; foreach($this->items as $i) { if($i->status) { $quantity += $i->quantity; } }; return $quantity; } public function getShippingDetailsAttribute() { if(isset($this->shipping_option['shipping_option'])) { return $this->shipping_option['shipping_option']; } if(isset($this->shipping_option)) { return $this->shipping_option; } return null; } public function getShippingProductNameAttribute() { if(isset($this->shipping_option['name'])) { return $this->shipping_option['name']; } if(isset($this->shipping_option['productName'])) { return $this->shipping_option['productName']; } return null; } public function getShippingIsoAttribute() { $country = Country::find($this->shipping_address['country_id']); return $country->iso2; } public function getGeneratedTrackingUrlAttribute() { if($this->shipping_company == 'dhl') { return 'https://www.dhl.com/gr-en/home/tracking.html?tracking-id='.$this->tracking_id; } if($this->shipping_company == 'speedex') { return 'http://www.speedex.gr/isapohi.asp'; } if($this->shipping_company == 'fedex') { return 'https://www.fedex.com/fedextrack/?trknbr='.$this->tracking_id; } return null; } protected static function booted() { static::deleting(function ($order) { $order->payment()->delete(); $order->added_payments()->delete(); $order->shipments()->delete(); $order->items()->delete(); $order->notes()->delete(); $order->points()->delete(); }); static::updated(function($order) { Loyalty::calculateOrderPoints($order); }); static::created(function($order) { Loyalty::calculateOrderPoints($order); }); } } [/code] Возможно, атрибут, который я пытаюсь добавить, создает где-то цикл, и на сервере не хватает памяти, я не могу это понять. Подробнее здесь: [url]https://stackoverflow.com/questions/78792227/laravel-appending-attribute-results-to-out-of-memory[/url]