session = \Yii::$app->session; if (!$this->session->has('basket')) { $this->session->set('basket', []); } elseif (!empty($this->session->get('basket'))) { $cookies = \Yii::$app->response->cookies; $cookies->add( new Cookie( [ 'name' => 'basket', 'value' => Json::encode($this->session->get('basket')), ] ) ); } parent::__construct($config); } /** * Increment variant with $variant_id count by 1 * * @param int $variant_id * @param int $count */ public function add(int $variant_id, int $count) { $data = $this->getData(); if (array_key_exists($variant_id, $data)) { if ($data[ $variant_id ][ 'count' ] <= 0) { $data[ $variant_id ][ 'count' ] = $count; } else { $data[ $variant_id ][ 'count' ] += $count; } } else { if ($this->findModel($variant_id)) { $data[ $variant_id ] = [ 'count' => $count, ]; } } if ($data[ $variant_id ][ 'count' ] <= 0) { unset($data[ $variant_id ]); } $this->setData($data); } /** * Set variant with $variant_id to $count * * @param int $variant_id * @param int $count */ public function set(int $variant_id, int $count) { $data = $this->getData(); if (array_key_exists($variant_id, $data)) { $data[ $variant_id ][ 'count' ] = $count; if ($data[ $variant_id ][ 'count' ] <= 0) { unset($data[ $variant_id ]); } } elseif ($count > 0) { if ($this->findModel($variant_id)) { $data[ $variant_id ] = [ 'count' => $count, ]; } } $this->setData($data); } /** * Delete product variant with $variant_id from basket * * @param int $variant_id */ public function delete(int $variant_id) { $this->set($variant_id, 0); } /** * Get basket data * * @return array */ public function getData(): array { return $this->session->get('basket'); } /** * Get basket item with $variant_id. Returns false if item not in basket. * * @param int $variant_id * * @return bool|array */ public function getItem(int $variant_id) { $data = $this->getData(); if (!empty($data[ $variant_id ])) { return $data[ $variant_id ]; } else { return false; } } /** * Set basket data * * @param array $data */ public function setData(array $data) { $this->session->set('basket', $data); $cookies = \Yii::$app->response->cookies; if (empty($data)) { $cookies->remove('basket'); } else { $cookies->add( new Cookie( [ 'name' => 'basket', 'value' => Json::encode($data), ] ) ); } } /** * Get count of variants in basket * * @return int */ public function getCount(): int { $data = $this->getData(); return count($data); } /** * Get sum of variants in basket * * @return float */ public function getSum(): float { $data = $this->getData(); $models = $this->findModels(array_keys($data)); $sum = 0; foreach ($models as $model) { $sum += $model->price * $data[ $model->id ][ 'count' ]; } return $sum; } /** * Find Variant by $variant_id * * @param int $variant_id * * @return Variant * @throws \yii\web\NotFoundHttpException */ public function findModel(int $variant_id): Variant { /** * @var Variant $model */ $model = Variant::find() ->where([ 'variant.id' => $variant_id ]) ->andWhere( [ '>', 'variant.stock', 0, ] ) ->joinWith('lang') ->one(); if (empty($model)) { throw new NotFoundHttpException(\Yii::t('app', 'Product not found')); } else { return $model; } } /** * Find all Variants filtered by $variant_ids * * @param array $variant_ids * * @return Variant[] */ public function findModels(array $variant_ids) { if (empty($variant_ids)) { return []; } return Variant::find() ->where([ 'variant.id' => $variant_ids ]) ->joinWith('lang') ->joinWith( [ 'product' => function ($query) { /** * @var \yii\db\ActiveQuery $query */ $query->with( [ 'lang', 'image', ] ); }, ] ) ->with( 'image' ) ->indexBy('id') ->all(); } /** * Clear basket */ public function clear() { $this->setData([]); } }