Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Добрый день.
У меня есть сервис CartService
/**
* @var \Illuminate\Session\Store
*/
protected $session;
/**
* @var Guard
*/
protected $auth;
/**
* @var ProductVariation
*/
protected $variation;
/**
* @var Cart
*/
protected $cart;
/**
* @var SettingService
*/
protected $setting;
/**
* @var Request
*/
protected $request;
/**
* CartService constructor.
* @param Request $request
* @param Guard $auth
* @param ProductVariation $variation
* @param Cart $cart
*/
public function __construct(Request $request, Guard $auth, ProductVariation $variation, Cart $cart)
{
$this->request = $request;
$this->session = $request->session();
$this->auth = $auth;
$this->variation = $variation;
$this->setting = new SettingService();
$this->cart = $this->setCart($cart);
}
Так вот, если создавать обьект этого сервиса в методе контроллера, то все четко работает как надо, но если создавать обьект этого сервиса в конструкторе контроллера, то вылазиет ошибка
(1/1) RuntimeException Session store not set on request. in Request.php (line 399) at Request->session() in CartService.php (line 53) at CartService->__construct(object(Request), object(SessionGuard), object(ProductVariation), object(Cart)) in FrontendCartController.php (line 38) at FrontendCartController->__construct(object(Request), object(SessionGuard), object(ProductVariation), object(Cart))
Нагугли на ларавел ньюс ком что начиная с лары 5.3 обьект реквеста в контроллере конструктора нельзя создавать. Окей, но почему то у меня в других контроллерах (в конструкторе) я спокойно (инжектю?) через лок контейнер без всяких ошибок. Почему тут он ругается?
Вот собственно сам код контроллера
/**
* @var CartService
*/
protected $cart;
/**
* @var Guard
*/
protected $auth;
/**
* @var ProductVariation
*/
protected $variation;
/**
* FrontendCartController constructor.
* @param Request $request
* @param Guard $auth
* @param ProductVariation $variation
* @param Cart $cart
*/
public function __construct(Request $request, Guard $auth, ProductVariation $variation, Cart $cart)
{
parent::__construct();
$this->auth = $auth;
$this->cart = new CartService($request, $auth, $variation, $cart);;
$this->variation = $variation;
}
Не в сети
А зачем ты это изначально делаешь? Есть ведь глобальный помощник session() для работы с сессией.
Изменено AlexeyMezenin (12.10.2017 16:24:46)
Не в сети
Не в сети
Нормально. Не видел в реальных приложениях, чтобы кто-то так делал. session() читаемый, тестировать функционал легко и пр., зачем его внедрять в конструктор?
Не в сети
Не в сети
И всеже с хелпером не работает. Хелпер возвращает пустой результат.
Перенес посредника StartSession из $middlewareGroups в $middleware, все стало работать. Вопрос в том — на сколько это критично? Сейчас использую лару 5.4, покрошется ли приложение при обновлении?
Я где то на SO в комментариях видел что вы Алексей писали что все отлично работает после этих действий. Так ли это? Я имею ввиду, не пришлось ли менять все обратно?
Не в сети
И всеже с хелпером не работает. Хелпер возвращает пустой результат.
Покажи код пожалуйста. Где именно пробуешь сохранить данные и где пробуешь получить?
Перенес посредника StartSession из $middlewareGroups в $middleware, все стало работать. Вопрос в том — на сколько это критично? Сейчас использую лару 5.4, покрошется ли приложение при обновлении? Я где то на SO в комментариях видел что вы Алексей писали что все отлично работает после этих действий.
Давай на ты. Я помню что-то подобное, но не скажу что будет при очередном обновлении. Хорошая идея - не модифицировать такие вещи.
Сессия нормально работает из коробки почти во всех версиях (в некоторых минорных были проблемы). У тебя свежая установка или менял что-то?
Изменено AlexeyMezenin (15.10.2017 09:23:15)
Не в сети
- Покажи код пожалуйста. Где именно пробуешь сохранить данные и где пробуешь получить?
Полностью весь сервис, для понимания. Нсли вернуть сессию обратно, то код будит работать не правильно в функции code() где берется код из сессии. Когда пробую получить код из сессии, он возвращает null и создается все время новая корзина.
namespace App\Services;
use App\Cart;
use App\ProductVariation;
class CartService extends Service
{
/**
* @var ProductVariation
*/
protected $variation;
/**
* @var Cart
*/
protected $cart;
/**
* @var SettingService
*/
protected $setting;
/**
* @var mixed
*/
protected $code;
/**
* CartService constructor.
* @param ProductVariation $variation
* @param Cart $cart
*/
public function __construct(ProductVariation $variation, Cart $cart)
{
parent::__construct();
$this->variation = $variation;
$this->setting = new SettingService();
$this->cart = $cart;
$this->code = $this->code();
}
/**
* Add products to cart
*
* @param $productId
* @param int $quantity
* @param array $variations
*/
public function add($productId, $quantity = 1, array $variations = [])
{
$cart = $this->gerCart();
if(count($variations)) {
$this->setVariation($productId, $variations);
}
$cart->products()->attach($productId,[
'product_variation_id' => isset($this->variation->id) ? $this->variation->id : 0,
'quantity' => $quantity
]);
}
/**
* Load products in cart and return cart / products
*
* @param bool $withModel
* @param array $fields
* @return mixed
*/
public function products($withModel = true, array $fields = ['*'])
{
$cart = $this->cart->with([
'cartProducts',
'cartProducts.product' => function($q) use($fields){
$q->select($fields);
},
'cartProducts.variation',
'cartProducts.variation.combinations'])->whereCode($this->code)->first();
if($withModel) {
return $cart;
}
return $cart->cartProducts;
}
/**
* Remove product from cart
*
* @param $id
* @return bool
*/
public function remove($id)
{
if(isset($id) && is_numeric($id) && $id !== 0) {
$variation = $this->variation->whereHas('product', function($q) use($id){
$q->where('id', $id);
})->first();
$cart = $this->gerCart();
if($variation) {
return $cart->products()->wherePivot('product_variation_id', $variation->id)->detach($id);
} else {
return $cart->products()->detach($id);
}
}
return false;
}
/**
* Get code or create new one and cart
*
* @return mixed
*/
public function code()
{
$code = $this->session->get('cart.code');
if(is_null($code)) {
return $this->createNewCart();
}
return $code;
}
/**
* Get cart
*
* @return mixed
*/
public function getCart()
{
return $this->cart->whereCode($this->code)->first();
}
/**
* Find product variation by it attributes
*
* @param $id
* @param array $attributes
*/
private function setVariation($id, array $attributes)
{
$this->variation = $this->variation->whereHas('combinations', function($q) use($attributes) {
$q->whereIn('product_variation_combination.attribute_id', $attributes);
})->where('product_id', $id)->first();
}
/**
* Create a new cart instance
*
* @return mixed
*/
public function createNewCart()
{
$cart = $this->cart->create([
'code' => strtoupper(str_random(12)),
'user_id' => $this->auth->id() ? $this->auth->id() : Null,
'shop_id' => $this->setting->get('shop.id'),
'lang_id' => $this->session->get('lang', $this->setting->get('parameters.general.language_id'))
]);
$this->session->put('cart', $cart->toArray());
return $cart->code;
}
}
use App\Cart;
use App\ProductVariation;
use Illuminate\Http\Request;
use App\Services\CartService;
class FrontendCartController extends FrontendBaseController
{
/**
* @var Cart
*/
protected $cart;
/**
* @var ProductVariation
*/
protected $variation;
/**
* FrontendCartController constructor.
* @param ProductVariation $variation
* @param Cart $cart
*/
public function __construct(ProductVariation $variation, Cart $cart)
{
parent::__construct();
$this->cart = new CartService($variation, $cart);
}
/**
* Add product to cart
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function addToCart(Request $request)
{
try
{
// We filter request data, as quantity or variation
// may not be in request
$data = [
'id' => (int)$request->product,
'quantity' => $request->quantity ? (int)$request->quantity : 1,
'variation' => (array)$request->variation
];
$this->cart->add($data['id'], $data['quantity'], $data['variation']);
return response()->json(view('frontend.ajax.cart', [
'products' => $this->cart->products()
])->render(), 200);
}
catch (\Throwable $t)
{
return response()->json(['error ' . $t->getMessage() . $t->getFile() . $t->getLine()], 422);
}
}
/**
* Show cart
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function showCart(Request $request)
{
return response()->json(view('frontend.ajax.cart', [
'cart' => $this->cart->products()
])->render());
}
/**
* Remove product from cart
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function removeFromCart(Request $request)
{
try
{
$this->cart->remove($request->product);
return response()->json('success', 200);
}
catch (\Throwable $t)
{
return response()->json(['error ' . $t->getMessage() . $t->getFile() . $t->getLine()], 422);
}
}
}
- Давай на ты
- Сессия нормально работает из коробки почти во всех версиях (в некоторых минорных были проблемы). У тебя свежая установка или менял что-то?
Я ничего не менял. Устанавливал еще где то в августе.
- php artisan -V
Laravel Framework 5.4.28
Сейчас пока нет возможности обновить до 5.5 тк на сервере php 5.6
Изменено Testuser123 (15.10.2017 11:23:24)
Не в сети
Раз у тебя сервис использует сессию при его создании, внедряй сервис не в конструкторе контроллера, а в методах, где он используется.
Или попробуй избавиться от:
$this->code = $this->code();
И в коде вместо $this->code, используй геттер $this->code() (луше, кстати, переименовть в getCode()).
Изменено AlexeyMezenin (15.10.2017 11:39:41)
Не в сети
AlexeyMezenin, придется так сделать. Спасибо!
Не в сети
Страницы 1