LaravelSession::insertUpdate() issues while using laravel moltin shopping cart - php

I'm trying to use Moltin Cart in my Laravel 4 app:
I installed Moltin Cart through composer,
then added the Service Provider ('Moltin\Cart\CartServiceProvider')
and added the aliases ('Cart' => 'Moltin\Cart\Facade').
Now I want only logged in users to access the cart so I added
$this->beforeFilter('auth', array('only' => 'postAddToCart', 'getCart', 'getRemoveItem'));
in my storeController.
But I get this error when I try to access
Declaration of Moltin\Cart\Storage\LaravelSession::insertUpdate() must be compatible with Moltin\Cart\StorageInterface::insertUpdate(Moltin\Cart\Item\Line $item)
My Store Controller is :
<?php
class StoresController extends \BaseController {
public function __construct()
{
parent::__construct();
$this->beforeFilter('csrf', array('on' => 'post'));
$this->beforeFilter('auth', array('only' => 'postAddToCart', 'getCart', 'getRemoveItem'));
}
public function getIndex()
{
return View::make('stores.index')
->with('products', Product::take(4)->orderBy('created_at', 'DESC')->get());
}
public function getView($id)
{
return View::make('stores.view')
->with('product', Product::find($id));
}
public function getCategory($category_id)
{
return View::make('stores.category')
->with('products', Product::where('category_id', '=', $category_id)->paginate(6))
->with('category', Category::find($category_id));
}
public function getSearch()
{
$keyword = Input::get('keyword');
return View::make('stores.search')
->with('products', Product::where('title', 'LIKE', '%'. $keyword . '%')->get())
->with('keyword', $keyword);
}
public function postAddToCart()
{
$product = Product::find(Input::get('id'));
$qunatity = Input::get('qunatity');
Cart::insert(array(
'id' => $product->id,
'name' => $product->name,
'price' => $product->price,
'qunatity' => $qunatity,
'image' => $product->image
));
return Redirect::to('store/cart');
}
public function getCart()
{
return View::make('stores.cart')->with('products', Cart::contents());
}
public function getRemoveItem($identifier)
{
$product = Cart::item($identifier);
$product->remove();
return Redirect::to('store/cart');
}
}

The short answer:
Resume your installation assuming that moltin/cart and moltin/laravel-cart repositories are in sync.
The long answer:
As the error message states:
Moltin\Cart\StorageInterface::insertUpdate(Moltin\Cart\Item\Line $item)
Moltin\Cart\Storage\LaravelSession::insertUpdate()
don't have the same signature.
They should be in sync! The issue has nothing to do at all with your StoresController.
I checked:
https://github.com/moltin/cart/blob/master/src/Moltin/Cart/StorageInterface.php and
https://github.com/moltin/laravel-cart/blob/master/src/Moltin/Cart/Storage/LaravelSession.php
I find out that the signatures are OK as the time of my answer post.
namespace Moltin\Cart;
interface StorageInterface
{
/**
* Add or update an item in the cart
*
* #param Item $item The item to insert or update
* #return void
*/
public function insertUpdate(Item $item); // <<<< This is it!
...
}
namespace Moltin\Cart\Storage;
use Moltin\Cart\Item;
...
class LaravelSession implements \Moltin\Cart\StorageInterface
{
...
/**
* Add or update an item in the cart
*
* #param Item $item The item to insert or update
* #return void
*/
public function insertUpdate(Item $item) // <<<< This is it!
{
...
}
...
}
My guess is that you did your install when the repositories (knowing that moltin/cart is a dependency of moltin/laravel-cart) were not in sync for some reason.

Related

How to link attribute in Yii 2 to another model's field?

I have Products model and ProductProperties via hasOne relation:
class Product extends ActiveRecord
{
...
public function getProductProperties()
{
return $this->hasOne(ProductProperties::class, ['product_id' => 'id']);
}
...
}
I had price attribute in Products and I want to remove it (including column in database) and to link it to price attribute of ProductProperties model.
Is it possible and how can I do that? First I tried to override attributes method like this:
public function fields()
{
return [
'price' => function () {
return ProductProperties::find(['product_id' => $this->id])->price;
}
]
...
but I'm not sure if I can assign values using arrow method. Besides, fields() method uses $this->price before it returns anything:
public function fields()
{
if ($this->price){*some manipulations with price*}
...
return [
'price',
..*other fields*
];
}
The question is How can I remove the price from model and use another model's price attribute without too much pain?
If you only want to show the price, you can do
class Product extends ActiveRecord
{
...
public function getProductProperties()
{
return $this->hasOne(ProductProperties::class, ['product_id' => 'id']);
}
public function getPrice() {
return $this->productProperties->price;
}
...
}
And use it
$product = Product::findOne(1);
echo $product->price; // this is a shortcut
echo $product->productProperties->price; // same as this which is the complete route
To save the data, you should first determine how to handle the user data collection, since you have different models and each one has its own validations.
However, if you want to save the price as a Product attribute (I don't recommend it), you could do the following
class Product extends ActiveRecord
{
public $price;
public function rules () {
return [
[['price'], 'integer'] // for massive assignment
];
}
public function afterFind()
{
parent::afterFind();
$this->price = $this->productProperties->price;
}
public function getProductProperties()
{
return $this->hasOne(ProductProperties::class, ['product_id' => 'id']);
}
public function afterSave($insert, $changedAttributes)
{
parent::afterSave($insert, $changedAttributes);
if (array_key_exists('price', $changedAttributes)) {
// You should make sure that $this->productProperties exists.
$this->productProperties->price = $this->price;
$this->productProperties->save();
}
}
...
}

Laravel created event returning the wrong record

I'm currently using Laravel observers to implement events in my project, however, I ran into some problem where the created event returns a wrong record, for example, I create a record called Like that has post_id set to 2 and user_id set to 1, so the laravel created event should return this record right? except it returns a record where post_id is set to 0 and user_id set to 1.
my LikeObserver class:
class LikeObserver
{
/**
* Handle the like "created" event.
*
* #param \App\Like $like
* #return void
*/
public function created(Like $like)
{
dd($like);
$postId = $like->post_id;
Post::find($postId)->increment('likes_count');
}
}
as you can see whenever i dump the newly created record it returns this:
my LikeController class:
class LikeController extends Controller
{
public function insert(Request $request)
{
if(Like::where('user_id','1')->find($request->post_id))
{
return;
}
$like = Like::create(['post_id'=>$request->post_id,'user_id' => '1']);
}
public function remove(Request $request)
{
Like::where('user_id',auth()->user()->id)->findOrFail($request->post_id)->delete();
}
}
I pass post_id set to 2, however, Laravel returns the newly created record with post_id set to 0.
class LikeController extends Controller
{
public function insert(Request $request)
{
$like = Like::firstOrCreate([
'user_id' => '1',
'post_id' => $request->post_id,
]);
if(! $like->wasRecentlyCreated) {
return;
}
}
public function remove(Request $request)
{
Like::where([
'user_id' => auth()->user()->id,
'post_id' => $request->post_id,
])->first()->delete();
}
}
okay so apparently the fix was to use the creating event instead of the created event... this does return the correct record
public static function boot()
{
parent::boot();
static::creating(function ($like){
//returns the correct record.
dd($like);
});
}

Laravel get data from db array not working

When I run the code I get no error but the data I am trying to display is not displaying it's just blank.. can someone tell me what I'm doing wrong?
My controller:
public function openingPage($id) {
$this->getGames();
$games = $this->getGames();
return view('caseopener')->with('games',$games);
}
private function getGames() {
$games = array();
foreach ($this->data->items as $item) {
$game = new Game($item);
$games[] = array(
'id' => $game['id'],
'name' => $game['name'],
'price' => $game['price'],
'image' => $game['image'],
);
}
return $games;
}
The 'Game' Model that is used in 'getGames function':
class Game extends Model
{
private $id;
public $data;
public function __construct($id) {
parent::__construct();
$this->id = $id;
$this->data = $this->getData();
}
private function getData() {
$game = DB::table('products')->where('id', 1)->first();
if(empty($game)) return array();
return $game;
}
}
The view:
#foreach ($games as $game)
<div class="gold">$ {{ $game['price'] }}</div>
#endforeach
I think you are over-complicating things. You could simplify your flow like this:
Given your provided code, it seems like you are using a custom table name ('products') in your Game model. So we'll address this first:
Game.php
class Game extends Model
{
protected $table = 'products'; //
}
Now, it seems like you're searching an array of Game ids ($this->data->items). If so, you could make use of Eloquent for your query, specially the whereIn() method:
YourController.php
public function openingPage($id)
{
$games = Game::whereIn('id', $this->data->items)->get();
return view('caseopener')->with('games', $games);
}
Optionally, if you want to make sure of just returning the id, name, price and image of each Game/product, you could format the response with API Resources:
php artisan make:resource GameResource
Then in your newly created class:
app/Http/Resources/GameResource.php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class GameResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'price' => $this->price,
'image' => $this->image,
];
}
}
So now just update your controller:
YourController.php
use App\Http\Resources\GameResource;
public function openingPage($id)
{
$games = Game::whereIn('id', $this->data->items)->get();
return view('caseopener')->with('games', GameResource::collection($games));
} // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Too many rows with Many To Many Relationship omines/datatables-bundle

I am using bundle omines/datatables-bundle to create tables in my Symfony application. When I create custom query that left joins with a field that has Many to Many relationship it returns too many rows.
I am using Symfony 4.2 and omines/datatables-bundle bundle. The end result it that I have wrong number of total results found and many blank pages in my table.
This is how my table is being created
class TestTableType implements DataTableTypeInterface
{
public function configure(DataTable $dataTable, array $options)
{
$dataTable
->add('id',
NumberColumn::class,
array(
'label' => 'ID',
'globalSearchable' => false
)
)
->createAdapter(ORMAdapter::class,
array(
'entity' => Test::class,
'query' => function (QueryBuilder $builder)
{
$builder
->distinct()
->select('t')
->from(Test::class, 't')
->leftJoin('t.products', 'prod');
}
)
)
;
}
}
and this is how Many to Many relationship is defined in my entity class.
**
* #ORM\ManyToMany(targetEntity="App\Entity\Product", inversedBy="tests")
* #ORM\JoinTable(name="product_has_test")
*/
private $products;
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
along with getters and setters
public function addProduct(\App\Entity\Product $product)
{
$this->products[] = $product;
return $this;
}
public function removeProduct(\App\Entity\Product $product)
{
$this->products->removeElement($product);
}
public function getProducts()
{
return $this->products;
}
What might be the cause of it? And how can I fix it?

Objects are not persisted by Doctrine

last couple of days I've been busy making a form using Doctrine and MongoDB. Companies should be able to reserve tables, chairs, .. at a certain event by use of this form. The snippet below shows the controller for this form.
The 'ObjectMap' object maps the amount of a certain object to the object itself. The controller creates all the 'ObjectMap' objects, and adds them to the company object. However, the 'ObjectMap' objects are persisted by Doctrine (they show up in the database) but the company object isn't modified at all, there is no database request made by MongoDB. The persist() function seems to have no effect at all.
public function logisticsAction(Company $company)
{
$form = $this->createForm(new LogisticsForm($this->getDoctrine()->getManager()), $company);
if ($this->getRequest()->isMethod('POST')) {
$form->bind($this->getRequest());
if ($form->isValid()) {
$formData = $this->getRequest()->request->get('_company_logistics_edit');
$objects = $this->getDoctrine()->getManager()
->getRepository('Jobfair\AppBundle\Document\Company\Logistics\Object')
->findAll();
foreach($objects as $object) {
$requirement = $formData['objectRequirement_'.$object->getId()];
$map = new ObjectMap($requirement, $object);
$this->getDoctrine()->getManager()->persist($map);
$company->addObjectMap($map);
//print_r($company->getObjectMaps());
}
$this->getDoctrine()->getManager()->persist($company);
$this->getDoctrine()->getManager()->flush();
$this->getRequest()->getSession()->getFlashBag()->add(
'success',
'The information was successfully updated!'
);
return $this->redirect(
$this->generateUrl(
'_company_settings_logistics',
array(
'company' => $company->getId(),
)
)
);
}
}
The Company object is defined here:
class Company{
/**
* #ODM\Id
*/
private $id;
/*
* #ODM\ReferenceMany(targetDocument="Jobfair\AppBundle\Document\Company\Logistics\ObjectMap", cascade={"persist", "remove"})
*/
private $objectMaps;
public function __construct($name = null, $description = null)
{
$this->objectMaps = new ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function getObjectMaps()
{
return $this->objectMaps;
}
public function getObjectsArray()
{
$objects = array();
foreach($this->objectMaps as $map)
$objects[] = array(
'name' => $map->getObject()->getName(),
'amount' => $map->getRequirement()
);
return $objects;
}
public function addObjectMap(ObjectMapDocument $objectMap)
{
$this->objectMaps[] = $objectMap;
}
public function removeObject(ObjectMapDocument $objectMap)
{
$this->objectMaps->removeElement($objectMap);
}
}

Categories