I am trying to add an image parameter in Gloudemans Shoppingcart but am getting an error
Please supply a valid weight
I am pretty sure this is because am inserting the image parameter in a position configured for "weight", now my question is where do I add the image parameter? it doesn't seem to exist in any of the Gloudemans config files, please assist, below am listing all files under config in Gloudemans shoppingcart
Cart Controller
public function addItem($id)
{
$product=Product::find($id);
Cart::add($id,$product->product_name,1,$product->price,$product->product_image);
return back();
}
Cart.php file under folders vender\bumbummen99\src
<?php
namespace Gloudemans\Shoppingcart;
use Carbon\Carbon;
use Closure;
use Gloudemans\Shoppingcart\Contracts\Buyable;
use Gloudemans\Shoppingcart\Contracts\InstanceIdentifier;
use Gloudemans\Shoppingcart\Exceptions\CartAlreadyStoredException;
use Gloudemans\Shoppingcart\Exceptions\InvalidRowIDException;
use Gloudemans\Shoppingcart\Exceptions\UnknownModelException;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Database\DatabaseManager;
use Illuminate\Session\SessionManager;
use Illuminate\Support\Collection;
class Cart
{
const DEFAULT_INSTANCE = 'default';
/**
* Instance of the session manager.
*
* #var \Illuminate\Session\SessionManager
*/
private $session;
/**
* Instance of the event dispatcher.
*
* #var \Illuminate\Contracts\Events\Dispatcher
*/
private $events;
/**
* Holds the current cart instance.
*
* #var string
*/
private $instance;
/**
* Holds the creation date of the cart.
*
* #var mixed
*/
private $createdAt;
/**
* Holds the update date of the cart.
*
* #var mixed
*/
private $updatedAt;
/**
* Defines the discount percentage.
*
* #var float
*/
private $discount = 0;
/**
* Defines the tax rate.
*
* #var float
*/
private $taxRate = 0;
/**
* Cart constructor.
*
* #param \Illuminate\Session\SessionManager $session
* #param \Illuminate\Contracts\Events\Dispatcher $events
*/
public function __construct(SessionManager $session, Dispatcher $events)
{
$this->session = $session;
$this->events = $events;
$this->taxRate = config('cart.tax');
$this->instance(self::DEFAULT_INSTANCE);
}
/**
* Set the current cart instance.
*
* #param string|null $instance
*
* #return \Gloudemans\Shoppingcart\Cart
*/
public function instance($instance = null)
{
$instance = $instance ?: self::DEFAULT_INSTANCE;
if ($instance instanceof InstanceIdentifier) {
$this->discount = $instance->getInstanceGlobalDiscount();
$instance = $instance->getInstanceIdentifier();
}
$this->instance = sprintf('%s.%s', 'cart', $instance);
return $this;
}
/**
* Get the current cart instance.
*
* #return string
*/
public function currentInstance()
{
return str_replace('cart.', '', $this->instance);
}
/**
* Add an item to the cart.
*
* #param mixed $id
* #param mixed $name
* #param int|float $qty
* #param float $price
* #param float $weight
* #param array $options
*
* #return \Gloudemans\Shoppingcart\CartItem
*/
public function add($id, $name = null, $qty = null, $price = null, $weight = 0, array $options = [])
{
if ($this->isMulti($id)) {
return array_map(function ($item) {
return $this->add($item);
}, $id);
}
$cartItem = $this->createCartItem($id, $name, $qty, $price, $weight, $options);
return $this->addCartItem($cartItem);
}
/**
* Add an item to the cart.
*
* #param \Gloudemans\Shoppingcart\CartItem $item Item to add to the Cart
* #param bool $keepDiscount Keep the discount rate of the Item
* #param bool $keepTax Keep the Tax rate of the Item
* #param bool $dispatchEvent
*
* #return \Gloudemans\Shoppingcart\CartItem The CartItem
*/
public function addCartItem($item, $keepDiscount = false, $keepTax = false, $dispatchEvent = true)
{
if (!$keepDiscount) {
$item->setDiscountRate($this->discount);
}
if (!$keepTax) {
$item->setTaxRate($this->taxRate);
}
$content = $this->getContent();
if ($content->has($item->rowId)) {
$item->qty += $content->get($item->rowId)->qty;
}
$content->put($item->rowId, $item);
if ($dispatchEvent) {
$this->events->dispatch('cart.added', $item);
}
$this->session->put($this->instance, $content);
return $item;
}
/**
* Update the cart item with the given rowId.
*
* #param string $rowId
* #param mixed $qty
*
* #return \Gloudemans\Shoppingcart\CartItem
*/
public function update($rowId, $qty)
{
$cartItem = $this->get($rowId);
if ($qty instanceof Buyable) {
$cartItem->updateFromBuyable($qty);
} elseif (is_array($qty)) {
$cartItem->updateFromArray($qty);
} else {
$cartItem->qty = $qty;
}
$content = $this->getContent();
if ($rowId !== $cartItem->rowId) {
$itemOldIndex = $content->keys()->search($rowId);
$content->pull($rowId);
if ($content->has($cartItem->rowId)) {
$existingCartItem = $this->get($cartItem->rowId);
$cartItem->setQuantity($existingCartItem->qty + $cartItem->qty);
}
}
if ($cartItem->qty <= 0) {
$this->remove($cartItem->rowId);
return;
} else {
if (isset($itemOldIndex)) {
$content = $content->slice(0, $itemOldIndex)
->merge([$cartItem->rowId => $cartItem])
->merge($content->slice($itemOldIndex));
} else {
$content->put($cartItem->rowId, $cartItem);
}
}
$this->events->dispatch('cart.updated', $cartItem);
$this->session->put($this->instance, $content);
return $cartItem;
}
/**
* Remove the cart item with the given rowId from the cart.
*
* #param string $rowId
*
* #return void
*/
public function remove($rowId)
{
$cartItem = $this->get($rowId);
$content = $this->getContent();
$content->pull($cartItem->rowId);
$this->events->dispatch('cart.removed', $cartItem);
$this->session->put($this->instance, $content);
}
/**
* Get a cart item from the cart by its rowId.
*
* #param string $rowId
*
* #return \Gloudemans\Shoppingcart\CartItem
*/
public function get($rowId)
{
$content = $this->getContent();
if (!$content->has($rowId)) {
throw new InvalidRowIDException("The cart does not contain rowId {$rowId}.");
}
return $content->get($rowId);
}
/**
* Destroy the current cart instance.
*
* #return void
*/
public function destroy()
{
$this->session->remove($this->instance);
}
/**
* Get the content of the cart.
*
* #return \Illuminate\Support\Collection
*/
public function content()
{
if (is_null($this->session->get($this->instance))) {
return new Collection([]);
}
return $this->session->get($this->instance);
}
/**
* Get the number of items in the cart.
*
* #return int|float
*/
public function count()
{
return $this->getContent()->sum('qty');
}
/**
* Get the number of items instances in the cart.
*
* #return int|float
*/
public function countInstances()
{
return $this->getContent()->count();
}
/**
* Get the total price of the items in the cart.
*
* #return float
*/
public function totalFloat()
{
return $this->getContent()->reduce(function ($total, CartItem $cartItem) {
return $total + $cartItem->total;
}, 0);
}
/**
* Get the total price of the items in the cart as formatted string.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
*
* #return string
*/
public function total($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->totalFloat(), $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the total tax of the items in the cart.
*
* #return float
*/
public function taxFloat()
{
return $this->getContent()->reduce(function ($tax, CartItem $cartItem) {
return $tax + $cartItem->taxTotal;
}, 0);
}
/**
* Get the total tax of the items in the cart as formatted string.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
*
* #return string
*/
public function tax($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->taxFloat(), $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the subtotal (total - tax) of the items in the cart.
*
* #return float
*/
public function subtotalFloat()
{
return $this->getContent()->reduce(function ($subTotal, CartItem $cartItem) {
return $subTotal + $cartItem->subtotal;
}, 0);
}
/**
* Get the subtotal (total - tax) of the items in the cart as formatted string.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
*
* #return string
*/
public function subtotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->subtotalFloat(), $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the discount of the items in the cart.
*
* #return float
*/
public function discountFloat()
{
return $this->getContent()->reduce(function ($discount, CartItem $cartItem) {
return $discount + $cartItem->discountTotal;
}, 0);
}
/**
* Get the discount of the items in the cart as formatted string.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
*
* #return string
*/
public function discount($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->discountFloat(), $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the price of the items in the cart (not rounded).
*
* #return float
*/
public function initialFloat()
{
return $this->getContent()->reduce(function ($initial, CartItem $cartItem) {
return $initial + ($cartItem->qty * $cartItem->price);
}, 0);
}
/**
* Get the price of the items in the cart as formatted string.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
*
* #return string
*/
public function initial($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->initialFloat(), $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the price of the items in the cart (previously rounded).
*
* #return float
*/
public function priceTotalFloat()
{
return $this->getContent()->reduce(function ($initial, CartItem $cartItem) {
return $initial + $cartItem->priceTotal;
}, 0);
}
/**
* Get the price of the items in the cart as formatted string.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
*
* #return string
*/
public function priceTotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->priceTotalFloat(), $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the total weight of the items in the cart.
*
* #return float
*/
public function weightFloat()
{
return $this->getContent()->reduce(function ($total, CartItem $cartItem) {
return $total + ($cartItem->qty * $cartItem->weight);
}, 0);
}
/**
* Get the total weight of the items in the cart.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
*
* #return string
*/
public function weight($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
return $this->numberFormat($this->weightFloat(), $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Search the cart content for a cart item matching the given search closure.
*
* #param \Closure $search
*
* #return \Illuminate\Support\Collection
*/
public function search(Closure $search)
{
return $this->getContent()->filter($search);
}
/**
* Associate the cart item with the given rowId with the given model.
*
* #param string $rowId
* #param mixed $model
*
* #return void
*/
public function associate($rowId, $model)
{
if (is_string($model) && !class_exists($model)) {
throw new UnknownModelException("The supplied model {$model} does not exist.");
}
$cartItem = $this->get($rowId);
$cartItem->associate($model);
$content = $this->getContent();
$content->put($cartItem->rowId, $cartItem);
$this->session->put($this->instance, $content);
}
/**
* Set the tax rate for the cart item with the given rowId.
*
* #param string $rowId
* #param int|float $taxRate
*
* #return void
*/
public function setTax($rowId, $taxRate)
{
$cartItem = $this->get($rowId);
$cartItem->setTaxRate($taxRate);
$content = $this->getContent();
$content->put($cartItem->rowId, $cartItem);
$this->session->put($this->instance, $content);
}
/**
* Set the global tax rate for the cart.
* This will set the tax rate for all items.
*
* #param float $discount
*/
public function setGlobalTax($taxRate)
{
$this->taxRate = $taxRate;
$content = $this->getContent();
if ($content && $content->count()) {
$content->each(function ($item, $key) {
$item->setTaxRate($this->taxRate);
});
}
}
/**
* Set the discount rate for the cart item with the given rowId.
*
* #param string $rowId
* #param int|float $taxRate
*
* #return void
*/
public function setDiscount($rowId, $discount)
{
$cartItem = $this->get($rowId);
$cartItem->setDiscountRate($discount);
$content = $this->getContent();
$content->put($cartItem->rowId, $cartItem);
$this->session->put($this->instance, $content);
}
/**
* Set the global discount percentage for the cart.
* This will set the discount for all cart items.
*
* #param float $discount
*
* #return void
*/
public function setGlobalDiscount($discount)
{
$this->discount = $discount;
$content = $this->getContent();
if ($content && $content->count()) {
$content->each(function ($item, $key) {
$item->setDiscountRate($this->discount);
});
}
}
/**
* Store an the current instance of the cart.
*
* #param mixed $identifier
*
* #return void
*/
public function store($identifier)
{
$content = $this->getContent();
if ($identifier instanceof InstanceIdentifier) {
$identifier = $identifier->getInstanceIdentifier();
}
if ($this->storedCartWithIdentifierExists($identifier)) {
throw new CartAlreadyStoredException("A cart with identifier {$identifier} was already stored.");
}
$this->getConnection()->table($this->getTableName())->insert([
'identifier' => $identifier,
'instance' => $this->currentInstance(),
'content' => serialize($content),
'created_at' => $this->createdAt ?: Carbon::now(),
'updated_at' => Carbon::now(),
]);
$this->events->dispatch('cart.stored');
}
/**
* Restore the cart with the given identifier.
*
* #param mixed $identifier
*
* #return void
*/
public function restore($identifier)
{
if ($identifier instanceof InstanceIdentifier) {
$identifier = $identifier->getInstanceIdentifier();
}
if (!$this->storedCartWithIdentifierExists($identifier)) {
return;
}
$stored = $this->getConnection()->table($this->getTableName())
->where('identifier', $identifier)->first();
$storedContent = unserialize(data_get($stored, 'content'));
$currentInstance = $this->currentInstance();
$this->instance(data_get($stored, 'instance'));
$content = $this->getContent();
foreach ($storedContent as $cartItem) {
$content->put($cartItem->rowId, $cartItem);
}
$this->events->dispatch('cart.restored');
$this->session->put($this->instance, $content);
$this->instance($currentInstance);
$this->createdAt = Carbon::parse(data_get($stored, 'created_at'));
$this->updatedAt = Carbon::parse(data_get($stored, 'updated_at'));
$this->getConnection()->table($this->getTableName())->where('identifier', $identifier)->delete();
}
/**
* Erase the cart with the given identifier.
*
* #param mixed $identifier
*
* #return void
*/
public function erase($identifier)
{
if ($identifier instanceof InstanceIdentifier) {
$identifier = $identifier->getInstanceIdentifier();
}
if (!$this->storedCartWithIdentifierExists($identifier)) {
return;
}
$this->getConnection()->table($this->getTableName())->where('identifier', $identifier)->delete();
$this->events->dispatch('cart.erased');
}
/**
* Merges the contents of another cart into this cart.
*
* #param mixed $identifier Identifier of the Cart to merge with.
* #param bool $keepDiscount Keep the discount of the CartItems.
* #param bool $keepTax Keep the tax of the CartItems.
* #param bool $dispatchAdd Flag to dispatch the add events.
*
* #return bool
*/
public function merge($identifier, $keepDiscount = false, $keepTax = false, $dispatchAdd = true)
{
if (!$this->storedCartWithIdentifierExists($identifier)) {
return false;
}
$stored = $this->getConnection()->table($this->getTableName())
->where('identifier', $identifier)->first();
$storedContent = unserialize($stored->content);
foreach ($storedContent as $cartItem) {
$this->addCartItem($cartItem, $keepDiscount, $keepTax, $dispatchAdd);
}
$this->events->dispatch('cart.merged');
return true;
}
/**
* Magic method to make accessing the total, tax and subtotal properties possible.
*
* #param string $attribute
*
* #return float|null
*/
public function __get($attribute)
{
switch ($attribute) {
case 'total':
return $this->total();
case 'tax':
return $this->tax();
case 'subtotal':
return $this->subtotal();
default:
return;
}
}
/**
* Get the carts content, if there is no cart content set yet, return a new empty Collection.
*
* #return \Illuminate\Support\Collection
*/
protected function getContent()
{
if ($this->session->has($this->instance)) {
return $this->session->get($this->instance);
}
return new Collection();
}
/**
* Create a new CartItem from the supplied attributes.
*
* #param mixed $id
* #param mixed $name
* #param int|float $qty
* #param float $price
* #param float $weight
* #param array $options
*
* #return \Gloudemans\Shoppingcart\CartItem
*/
private function createCartItem($id, $name, $qty, $price, $weight, array $options)
{
if ($id instanceof Buyable) {
$cartItem = CartItem::fromBuyable($id, $qty ?: []);
$cartItem->setQuantity($name ?: 1);
$cartItem->associate($id);
} elseif (is_array($id)) {
$cartItem = CartItem::fromArray($id);
$cartItem->setQuantity($id['qty']);
} else {
$cartItem = CartItem::fromAttributes($id, $name, $price, $weight, $options);
$cartItem->setQuantity($qty);
}
return $cartItem;
}
/**
* Check if the item is a multidimensional array or an array of Buyables.
*
* #param mixed $item
*
* #return bool
*/
private function isMulti($item)
{
if (!is_array($item)) {
return false;
}
return is_array(head($item)) || head($item) instanceof Buyable;
}
/**
* #param $identifier
*
* #return bool
*/
private function storedCartWithIdentifierExists($identifier)
{
return $this->getConnection()->table($this->getTableName())->where('identifier', $identifier)->exists();
}
/**
* Get the database connection.
*
* #return \Illuminate\Database\Connection
*/
private function getConnection()
{
return app(DatabaseManager::class)->connection($this->getConnectionName());
}
/**
* Get the database table name.
*
* #return string
*/
private function getTableName()
{
return config('cart.database.table', 'shoppingcart');
}
/**
* Get the database connection name.
*
* #return string
*/
private function getConnectionName()
{
$connection = config('cart.database.connection');
return is_null($connection) ? config('database.default') : $connection;
}
/**
* Get the Formatted number.
*
* #param $value
* #param $decimals
* #param $decimalPoint
* #param $thousandSeperator
*
* #return string
*/
private function numberFormat($value, $decimals, $decimalPoint, $thousandSeperator)
{
if (is_null($decimals)) {
$decimals = config('cart.format.decimals', 2);
}
if (is_null($decimalPoint)) {
$decimalPoint = config('cart.format.decimal_point', '.');
}
if (is_null($thousandSeperator)) {
$thousandSeperator = config('cart.format.thousand_separator', ',');
}
return number_format($value, $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the creation date of the cart (db context).
*
* #return \Carbon\Carbon|null
*/
public function createdAt()
{
return $this->createdAt;
}
/**
* Get the lats update date of the cart (db context).
*
* #return \Carbon\Carbon|null
*/
public function updatedAt()
{
return $this->updatedAt;
}
}
I have tried checcking out Crinsane's repo but there is no documentation about this
Related
Entry is getting updated through the function pasted below. I am trying to update the entry::position, and after the request is applied to the $entry, debug reveals that it has the new position.
Position is in a one-to-many relationship with entry.
Positions can be related to one another (parent or child relation), but entry can only belong to a single position.
I make an array of all positions related to the position that the entry belongs to, then iterate over all other entries that belong to those other positions (to find if there is a conflict with THE entry).
When I do that iteration (or probably when I call the $r->getEntries() on a related position) something magical happens =) entry::position is then reverted to the value it had prior to the form submission was applied to the entity $entry, and my update is undone (though everything saves without error, so kind of a silent fail).
Why is this? Does it have something to do with me getting all the entries from all related positions, and this current entry kind of still belongs to the old position there until entityManager::flush() is called?
How could I do it differently so that my entity isn't changed upon that foreach stage?
public function editAction(Request $request, Entry $entry)
{
$user = $this->getUser();
$unit = $entry->getPosition()->getACRGroup();
$editForm = $this->createForm('App\Form\EntryType', $entry, ['unit' => $unit]);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
//find related positions
$relatives = $entry->getPosition()->getRelatedPositions();
//debug here reveals that $entry->getPosition() is what it is set to in the form
//scoop up the entries from each of the related positions into the same entries array
$allEntries = array();
foreach($relatives as $r) {
foreach($r->getEntries() as $e) {
$allEntries[] = $e;
}
}
//debug here reveals that $entry->getPosition() is reverted to what it was before the form submit was applied to it
}
Entry
namespace App\Entity\Poslog;
use Doctrine\ORM\Mapping as ORM;
/**
* Entry
*
* #ORM\Table(name="entry")
* #ORM\Entity
*/
class Entry
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="start", type="integer")
*/
private $start;
/**
* #var int|null
*
* #ORM\Column(name="stop", type="integer", nullable=true)
*/
private $stop;
/**
* #var object \App\Entity\Poslog\Position
*
* #ORM\ManyToOne(targetEntity="\App\Entity\Poslog\Position", inversedBy="entries")
* #ORM\JoinColumn(name="position", referencedColumnName="id", nullable=false)
*/
protected $position;
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set start.
*
* #param int $start
*
* #return Entry
*/
public function setStart($start)
{
$this->start = $start->getTimestamp();
return $this;
}
/**
* Get start.
*
* #return \DateTime
*/
public function getStart($timezone = null)
{
$val = $this->start;
$date = new \DateTime("#".$val, new \DateTimeZone("UTC"));
if ($timezone) {
$date->setTimezone( new \DateTimeZone( $timezone ) );
}
return $date;
}
/**
* Set stop.
*
* #param int|null $stop
*
* #return Entry
*/
public function setStop($stop = null)
{
if ($stop == null) {
$this->stop = null;
} else {
$this->stop = $stop->getTimestamp();
}
return $this;
}
/**
* Get stop.
*
* #return \DateTime|null
*/
public function getStop($timezone = null)
{
$val = $this->stop;
if ($val == null) {
return null;
} else {
$date = new \DateTime("#".$val, new \DateTimeZone("UTC"));
if ($timezone) {
$date->setTimezone( new \DateTimeZone( $timezone ) );
}
return $date;
}
}
/**
* Set Position
*
* #param \App\Entity\Poslog\Position $position
*
* #return Entry
*/
public function setPosition(\App\Entity\Poslog\Position $position)
{
$this->position = $position;
return $this;
}
/**
* Get Position
*
* #return \App\Entity\Poslog\Position
*/
public function getPosition()
{
return $this->position;
}
public function getStartDate() {
$full = $this->getStart();
return $full->format('Y-m-d');
}
}
Position
namespace App\Entity\Poslog;
use Doctrine\ORM\Mapping as ORM;
/**
* Position
*
* #ORM\Table(name="position")
* #ORM\Entity
*/
class Position
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="\App\Entity\Poslog\Entry", mappedBy="position")
*/
private $entries;
/**
* #var object \App\Entity\Poslog\Position
*
* #ORM\ManyToOne(targetEntity="\App\Entity\Poslog\Position", inversedBy="children")
* #ORM\JoinColumn(name="parent", referencedColumnName="id", nullable=true)
*/
protected $parent;
/**
* #ORM\OneToMany(targetEntity="\App\Entity\Poslog\Position", mappedBy="parent")
*/
private $children;
/**
* Get id.
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set name.
*
* #param string $name
*
* #return Position
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name.
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set parent
*
* #param \App\Entity\Poslog\Position
*/
public function setParent(\App\Entity\Poslog\Position $parent = NULL)
{
$this->parent = $parent;
}
/**
* Get parent
*
* #return \App\Entity\Poslog\Position
*/
public function getParent()
{
return $this->parent;
}
/**
* Add children
*
* #param \App\Entity\Poslog\Position $children
*/
public function addPosition(\App\Entity\Poslog\Position $children)
{
$this->children[] = $children;
}
/**
* Get children
*
* #return Doctrine\Common\Collections\Collection
*/
public function getChildren()
{
return $this->children;
}
/**
* Add entry
*
* #param \App\Entity\Poslog\Entry $entry
*
* #return Position
*/
public function addEntry(\App\Entity\Poslog\Entry $entry)
{
$this->entries[] = $entry;
return $this;
}
/**
* Remove entry
*
* #param \App\Entity\Poslog\Entry $entry
*/
public function removeEntry(\App\Entity\Poslog\Entry $entry)
{
$this->entries->removeElement($entry);
}
/**
* Get entries
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getEntries()
{
return $this->entries;
}
/**
* Get todays entries
*
*/
public function getTodaysEntries($date = null) //pass in a date to get entries for a specified day
{
//TODO: Possibly refactor this to a doctrine query for performance?
$all = $this->entries;
$todays_entries = array();
if ($date == null) {
$todays_date = gmdate("Y-m-d");
} else {
$todays_date = $date->format("Y-m-d");
}
foreach($all as $e) {
if ($e->getStart()->format("Y-m-d") == $todays_date) {
$todays_entries[] = $e;
}
}
return $todays_entries;
}
public function getEntriesArray($sort = 'asc')
{
// SAME FUNCTION EXISTS ON OPERATOR ENTITY (slight variation)
$entries = $this->getEntries();
$arrayOfEntries = array();
foreach ($entries as $e) {
$a = array();
$a['id'] = $e->getId();
$a['start_unix'] = $e->getStart()->format('U');
$a['start_date'] = $e->getStart()->format('Y-m-d');
$a['start_time'] = $e->getStart()->format('H:i');
if ( $a['stop_unix'] = $e->getStop() == null ) {
$a['is_open'] = 1;
$a['stop_unix'] = "";
$a['stop_date'] = "";
$a['stop_time'] = "";
} else {
$a['is_open'] = 0;
$a['stop_unix'] = $e->getStop()->format('U');
$a['stop_date'] = $e->getStop()->format('Y-m-d');
$a['stop_time'] = $e->getStop()->format('H:i');
}
$arrayOfEntries[] = $a;
}
if ($sort == 'asc') { //sort with earliest date first
usort($arrayOfEntries, function ($a, $b) {
return strnatcmp($a['start_unix'], $b['start_unix']);
});
} elseif ($sort == 'desc') { //sort with most recent date first
usort($arrayOfEntries, function ($a, $b) {
return strnatcmp($b['start_unix'], $a['start_unix']);
});
}
return $arrayOfEntries;
}
public function getRelatedPositions() {
$relatedPosition = array();
$parent = $this->getParent();
$children = $this->getChildren();
if ($parent) {
$relatedPositions[] = $parent;
}
if ($children) {
foreach($children as $c) {
$relatedPositions[] = $c;
}
}
return $relatedPositions;
}
public function getRelatedEntries($includeOwnEntries = false) {
$entries = array();
if ($includeOwnEntries == true) { //start with this position's entries
foreach($this->getEntries() as $e) {
$entries[] = $e;
}
}
//find related positions
$relatives = $this->getRelatedPositions();
//scoop up the entries from each of the related positions into the same entries array
foreach($relatives as $r) {
foreach($r->getEntries() as $e) {
$entries[] = $e;
}
}
return $entries;
}
}
I have the following problem with shopping cart. I don’t know where to place the calculation, so it can update total price dynamically (Such when the cart item is removed, or the quantity updated). Because I need to call updateTotalPrice() method almost everywhere, but I don’t want to repeat the code that many times
So far it look like this
CartService
class CartService extends AbstractController
{
private CartRepository $cartRepository;
private ManagerRegistry $managerRegistry;
private CartItemRepository $cartItemRepository;
public function __construct(CartItemRepository $cartItemRepository, CartRepository $cartRepository, ManagerRegistry $managerRegistry)
{
$this->cartItemRepository = $cartItemRepository;
$this->cartRepository = $cartRepository;
$this->managerRegistry = $managerRegistry;
}
/**
* Get Cart by ID
*
* #return Cart|null
*/
public function getCartByUserId(): ?Cart
{
/**
* #var User $user
*/
$user = $this->getUser();
return $this->cartRepository->findOneBy(['customer' => $user->getId()]);
}
/**
* Create Cart for Customer
*
* #return Cart|null
*/
public function createNewCart(): ?Cart
{
$entityManager = $this->managerRegistry->getManager();
$cart = new Cart();
/**
* #var User $user
*/
$cart->setCustomer($this->getUser());
$entityManager->persist($cart);
$entityManager->flush();
return $cart;
}
/**
* #param Cart $cart
* #param Product $product
* #return CartItem|null
*/
public function isProductInCart(Cart $cart, Product $product): ?CartItem
{
return $this->cartItemRepository->findOneBy(['product' => $product->getId(), 'cart' => $cart->getId()]);
}
/**
* Add new product to cart
*
* #param Cart $cart
* #param Product $product
* #param int $quantity
* #return void
*/
public function insertProduct(Cart $cart, Product $product, int $quantity): void
{
$entityManager = $this->managerRegistry->getManager();
$insertProduct = new CartItem();
$insertProduct->setCart($cart)
->setCart($cart)
->setQuantity($quantity)
->setProduct($product);
$cart->addCartItem($insertProduct);
$cart->setTotalprice($cart->getTotalprice() + $insertProduct->getQuantity() * $insertProduct->getProduct()->getPrice());
$entityManager->persist($insertProduct);
$entityManager->flush();
}
/**
* Update item's quantity
*
* #param CartItem $cartItem
* #param int $quantity
* #return void
*/
public function updateCartItemQuantity(CartItem $cartItem, int $quantity): void
{
$entityManager = $this->managerRegistry->getManager();
$cartItem->setQuantity($quantity);
$entityManager->persist($cartItem);
$entityManager->flush();
}
/**
* Remove specific product from cart
*
* #param int $id
* #return void
*/
public function removeProductFromCart(int $id): void
{
$product = $this->cartItemRepository->findOneBy(['product' => $id]);
$entityManager = $this->managerRegistry->getManager();
$entityManager->remove($product);
$entityManager->flush();
}
/**
* Set or update total price
*
* #param Cart $cart
* #param float $totalprice
* #return void
*/
public function updateTotalPrice(Cart $cart, float $totalprice): void
{
$entityManager = $this->managerRegistry->getManager();
$cart->setTotalprice($cart->getTotalprice() + $totalprice);
$entityManager->persist($cart);
$entityManager->flush($cart);
}
/**
* Add Product to Cart
*
* #param Product $product
* #param $cartItem
* #return void
*/
public function addOrUpdateProduct(Product $product, $cartItem): void
{
$cart = $this->getCartByUserId();
if (!$cart instanceof Cart) {
$cart = $this->createNewCart();
}
$isProductInCart = $this->isProductInCart($cart, $product);
//If product doens't exist, insert it inside cart. If exist, update quantity and add message
if (!$isProductInCart) {
$this->insertProduct($cart, $product, $cartItem->getQuantity());
$this->addFlash('productAdded', 'Product added to Cart');
} else {
$this->updateCartItemQuantity($isProductInCart, $cartItem->getQuantity() + $isProductInCart->getQuantity());
$this->updateTotalPrice($cart, $cartItem->getQuantity() * $cartItem->getProduct()->getPrice());
$this->addFlash('productAdded', 'Product already in cart. Quantity Updated');
}
}
OrderController (That's the cart)
<?php
namespace App\Controller;
/**
* #IsGranted("IS_AUTHENTICATED_FULLY")
*/
#[Route('/cart', name: 'cart.')]
class OrderController extends AbstractController
{
/**
* Show current Cart
*
* #param CartService $cartService
* #return Response
*/
#[Route('/', name: 'show_cart')]
public function showCart(CartService $cartService): Response
{
$cart = $cartService->getCartByUserId();
return $this->render('cart/index.html.twig', [
'cart' => $cart,
]);
}
/**
* Update existing cart item quantity
*
* #param CartItem $cartItem
* #param int $quantity
* #param CartService $cartService
* #return Response
*/
#[Route('/updatecartquantity/{id}/{quantity}', name: 'updatequantity')]
public function updateCartQuantity(CartItem $cartItem, int $quantity, CartService $cartService): Response
{
$cartService->updateCartItemQuantity($cartItem, $quantity);
return $this->redirect($this->generateUrl('cart.show_cart'));
}
/**
* Remove product from cart
*
* #param CartService $cartService
* #param int $id
* #return Response
*/
#[Route('/removeitem/{id}', name: 'removefromcart')]
public function removeFromCart(CartService $cartService, int $id): Response
{
$cartService->removeProductFromCart($id);
return $this->redirect($this->generateUrl('cart.show_cart'));
}
}
Product Controller (Shows the product -> After choosing quantity can be inserted inside cart
#[Route('/product', name: 'product.')]
class ProductController extends AbstractController
{
/**
* Show Product, and add to cart
*
* #param Product $product
* #param CartService $cartService
* #param Request $request
* #return Response
*/
#[Route('/showproduct/{id}', name: 'showproduct')]
public function showProduct(Product $product, CartService $cartService, Request $request): Response
{
$form = $this->createForm(CartItemType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$item = $form->getData();
$item->setProduct($product);
$cartService->addOrUpdateProduct($product, $item);
}
return $this->render('product/showproduct.html.twig', [
'product' => $product,
'form' => $form->createView()
]);
}
}
I solved by adding showCart() method, which instead inserts and updates values in database, it runs only, when I want to display Cart.
public function showCart(): ?Cart
{
$cart = $this->getCartByUserId();
$cartItem = $this->cartItemRepository->findBy(['cart' => $cart]);
$totalprice = 0;
foreach ($cartItem as $carti) {
$totalprice += $carti->getQuantity() * $carti->getProduct()->getPrice();
}
$cart->setTotalprice($totalprice);
return $cart;
}
i have added a new field/column to my "listing" entity, which is a boolean named "promoted" which is like one already present in the db "certified", it is created to behave exactly the same, however, it is'nt working..
The mariadb db updated correctly with the new row containing a boolean, but when i try to use it in a partial query or to update the field from 0 to 1 with a form it dont update, like it's unmapped, here's my code (not all just the important parts are it is 3 functions with 1000~+ lines: BaseListing.php
/**
* Listing
*
* #CocoricoAssert\ListingConstraint()
*
* #ORM\MappedSuperclass
*/
abstract class BaseListing
{
protected $price = 0;
/**
*
* #ORM\Column(name="certified", type="boolean", nullable=true)
*
* #var boolean
*/
protected $certified;
/**
*
* #ORM\Column(name="min_duration", type="smallint", nullable=true)
*
* #var integer
*/
/**
*
* #ORM\Column(name="promoted", type="boolean", nullable=true)
*
* #var boolean
*/
protected $promoted;
/**
* #return boolean
*/
public function isCertified()
{
return $this->certified;
}
/**
* #param boolean $certified
*/
public function setCertified($certified)
{
$this->certified = $certified;
}
/**
* #return boolean
*/
public function isPromoted()
{
return $this->promoted;
}
/**
* #param boolean $promoted
*/
public function setPromoted($promoted)
{
$this->promoted = $promoted;
}
}
here's AdminListing.php to generate the form for the admin panel to pass certified on / off and as i wish promoted on / off (cuted because it's a too large file):
class ListingAdmin extends AbstractAdmin
{
/** #inheritdoc */
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('admin.listing.title')
->add(
'status',
ChoiceType::class,
array(
'choices' => array_flip(Listing::$statusValues),
'placeholder' => 'admin.listing.status.label',
'translation_domain' => 'cocorico_listing',
'label' => 'admin.listing.status.label',
)
)
->add(
'adminNotation',
ChoiceType::class,
array(
'choices' => array_combine(
range(0, 10, 0.5),
array_map(
function ($num) {
return number_format($num, 1);
},
range(0, 10, 0.5)
)
),
'placeholder' => 'admin.listing.admin_notation.label',
'label' => 'admin.listing.admin_notation.label',
'required' => false,
)
)
->add(
'certified',
null,
array(
'label' => 'admin.listing.certified.label',
)
)
->add(
'promoted',
CheckboxType::class,
array(
'label' => 'admin.listing.promoted.label',
'required' => false,
)
)
This is not working because i have a query in ListingRepository that use "certified":
public function getFindSelectPart(QueryBuilder $queryBuilder)
{
$queryBuilder
->select("partial l.{id, price, averageRating, certified, createdAt, commentCount}")
->addSelect("partial t.{id, locale, slug, title, description}")
->addSelect("partial llcat.{id, listing, category}")
->addSelect("partial ca.{id, lft, lvl, rgt, root}")
->addSelect("partial cat.{id, locale, name}")
->addSelect("partial i.{id, name}")
->addSelect("partial u.{id, firstName}")
->addSelect("partial ln.{id, city, route, country}")
->addSelect("partial co.{id, lat, lng}")
->addSelect("partial ui.{id, name}")
->addSelect("'' AS DUMMY");//To maintain fields on same array level when extra fields are added
return $queryBuilder;
}
And when i put promoted just behind the certified in the partial query it says:
[Semantical Error] line 0, col 88 near partial.l Error: There is no mapped field named 'promoted' on class Cocorico\ListingBundle\Entity\Listing
besides i have done exactly the same setup as the certified value, i have cleared cache and updated DB scheme.
Here's my Entity\Listing.php :
?php
namespace Cocorico\ListingBundle\Entity;
use Cocorico\BookingBundle\Entity\Booking;
use Cocorico\ListingBundle\Model\BaseListing;
use Cocorico\ListingBundle\Model\ListingOptionInterface;
use Cocorico\ListingCategoryBundle\Entity\ListingListingCategory;
use Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic;
use Cocorico\ListingDiscountBundle\Entity\ListingDiscount;
use Cocorico\ListingImageBundle\Entity\ListingImage;
use Cocorico\ListingLocationBundle\Entity\ListingLocation;
use Cocorico\MessageBundle\Entity\Thread;
use Cocorico\UserBundle\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Listing
*
* #ORM\Entity(repositoryClass="Cocorico\ListingBundle\Repository\ListingRepository")
*
* #ORM\Table(name="listing",indexes={
* #ORM\Index(name="created_at_l_idx", columns={"created_at"}),
* #ORM\Index(name="status_l_idx", columns={"status"}),
* #ORM\Index(name="price_idx", columns={"price"}),
* #ORM\Index(name="type_idx", columns={"type"}),
* #ORM\Index(name="min_duration_idx", columns={"min_duration"}),
* #ORM\Index(name="max_duration_idx", columns={"max_duration"}),
* #ORM\Index(name="average_rating_idx", columns={"average_rating"}),
* #ORM\Index(name="admin_notation_idx", columns={"admin_notation"}),
* #ORM\Index(name="platform_notation_idx", columns={"platform_notation"})
* })
*/
class Listing extends BaseListing
{
use ORMBehaviors\Timestampable\Timestampable;
use ORMBehaviors\Translatable\Translatable;
use \Cocorico\ListingSearchAdvancedBundle\Model\ListingSearchableTrait;
// use \Cocorico\ListingCategoryFieldBundle\Model\ListingCategoryFieldableTrait;
// use \Cocorico\DeliveryBundle\Model\ListingDeliverableTrait;
// use \Cocorico\ListingDepositBundle\Model\ListingDepositableTrait;
// use \Cocorico\ListingSessionBundle\Model\ListingSessionableTrait;
// use \Cocorico\ServiceBundle\Model\ListingTrait;
// use \Cocorico\ListingVideoBundle\Model\ListingVideoTrait;
// use \Cocorico\CarrierBundle\Model\ListingCarrierableTrait;
/**
* #ORM\Id
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class="Cocorico\CoreBundle\Model\CustomIdGenerator")
*
* #var integer
*/
protected $id;
/**
* #Assert\NotBlank(message="assert.not_blank")
*
* #ORM\ManyToOne(targetEntity="Cocorico\UserBundle\Entity\User", inversedBy="listings", cascade={"persist"})
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
*
* #var User
*/
protected $user;
/**
* #ORM\OneToOne(targetEntity="Cocorico\ListingLocationBundle\Entity\ListingLocation", inversedBy="listing", cas\
cade={"persist", "remove"}, orphanRemoval=true)
* #ORM\JoinColumn(name="location_id", referencedColumnName="id", onDelete="CASCADE")
*
* #var ListingLocation
**/
protected $location;
/**
* #ORM\OneToMany(targetEntity="Cocorico\ListingCategoryBundle\Entity\ListingListingCategory", mappedBy="listing\
", cascade={"persist", "remove"}, orphanRemoval=true)//, fetch="EAGER"
*
*/
protected $listingListingCategories;
/**
* For Asserts #see \Cocorico\ListingBundle\Validator\Constraints\ListingValidator
*
* #ORM\OneToMany(targetEntity="Cocorico\ListingImageBundle\Entity\ListingImage", mappedBy="listing", cascade={"\
persist", "remove"}, orphanRemoval=true)
* #ORM\OrderBy({"position" = "asc"})
*/
protected $images;
/**
* #ORM\OneToMany(targetEntity="Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic", mappe\
dBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) //, fetch="EAGER"
*
*/
protected $listingListingCharacteristics;
/**
*
* #ORM\OneToMany(targetEntity="Cocorico\ListingDiscountBundle\Entity\ListingDiscount", mappedBy="listing", casc\
ade={"persist", "remove"}, orphanRemoval=true)
* #ORM\OrderBy({"fromQuantity" = "asc"})
*/
protected $discounts;
/**
* #ORM\OneToMany(targetEntity="Cocorico\BookingBundle\Entity\Booking", mappedBy="listing", cascade={"persist", \
"remove"}, orphanRemoval=true)
* #ORM\OrderBy({"createdAt" = "desc"})
*/
protected $bookings;
/**
* #ORM\OneToMany(targetEntity="Cocorico\MessageBundle\Entity\Thread", mappedBy="listing", cascade={"remove"}, o\
rphanRemoval=true)
* #ORM\OrderBy({"createdAt" = "desc"})
*/
protected $threads;
/**
*
* #ORM\OneToMany(targetEntity="Cocorico\ListingBundle\Model\ListingOptionInterface", mappedBy="listing", cascad\
e={"persist", "remove"}, orphanRemoval=true)
*/
protected $options;
public function __construct()
{
$this->images = new ArrayCollection();
$this->listingListingCharacteristics = new ArrayCollection();
$this->listingListingCategories = new ArrayCollection();
$this->discounts = new ArrayCollection();
$this->bookings = new ArrayCollection();
$this->threads = new ArrayCollection();
$this->options = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Add characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
* #return Listing
*/
public function addListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic)
{
$this->listingListingCharacteristics[] = $listingListingCharacteristic;
return $this;
}
/**
* Remove characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
*/
public function removeListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic)
{
$this->listingListingCharacteristics->removeElement($listingListingCharacteristic);
$listingListingCharacteristic->setListing(null);
}
/**
* Get characteristics
*
* #return \Doctrine\Common\Collections\Collection|ListingListingCharacteristic[]
*/
public function getListingListingCharacteristics()
{
return $this->listingListingCharacteristics;
}
/**
* Get characteristics ordered by Group and Characteristic
*
* #return ArrayCollection
*/
public function getListingListingCharacteristicsOrderedByGroup()
{
$iterator = $this->listingListingCharacteristics->getIterator();
$iterator->uasort(
function ($a, $b) {
/**
* #var ListingListingCharacteristic $a
* #var ListingListingCharacteristic $b
*/
$groupPosA = $a->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition();
$groupPosB = $b->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition();
$characteristicPosA = $a->getListingCharacteristic()->getPosition();
$characteristicPosB = $b->getListingCharacteristic()->getPosition();
if ($groupPosA == $groupPosB) {
if ($characteristicPosA == $characteristicPosB) {
return 0;
}
return ($characteristicPosA < $characteristicPosB) ? -1 : 1;
}
return ($groupPosA < $groupPosB) ? -1 : 1;
}
);
return new ArrayCollection(iterator_to_array($iterator));
}
/**
* Add characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
* #return Listing
*/
public function addListingListingCharacteristicsOrderedByGroup(
ListingListingCharacteristic $listingListingCharacteristic
) {
return $this->addListingListingCharacteristic($listingListingCharacteristic);
}
/**
* Remove characteristics
*
* #param ListingListingCharacteristic $listingListingCharacteristic
*/
public function removeListingListingCharacteristicsOrderedByGroup(
ListingListingCharacteristic $listingListingCharacteristic
) {
$this->removeListingListingCharacteristic($listingListingCharacteristic);
}
/**
* Add category
*
* #param ListingListingCategory $listingListingCategory
* #return Listing
*/
public function addListingListingCategory(ListingListingCategory $listingListingCategory)
{
$listingListingCategory->setListing($this);
$this->listingListingCategories[] = $listingListingCategory;
return $this;
}
/**
* Remove category
*
* #param ListingListingCategory $listingListingCategory
*/
public function removeListingListingCategory(ListingListingCategory $listingListingCategory)
{
// foreach ($listingListingCategory->getValues() as $value) {
// $listingListingCategory->removeValue($value);
// }
$this->listingListingCategories->removeElement($listingListingCategory);
}
/**
* Get categories
*
* #return \Doctrine\Common\Collections\Collection|ListingListingCategory[]
*/
public function getListingListingCategories()
{
return $this->listingListingCategories;
}
/**
* Set user
*
* #param \Cocorico\UserBundle\Entity\User $user
* #return Listing
*/
public function setUser(User $user = null)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \Cocorico\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Add images
*
* #param ListingImage $image
* #return Listing
*/
public function addImage(ListingImage $image)
{
$image->setListing($this); //Because the owning side of this relation is listing image
$this->images[] = $image;
return $this;
}
/**
* Remove images
*
* #param ListingImage $image
*/
public function removeImage(ListingImage $image)
{
$this->images->removeElement($image);
$image->setListing(null);
}
/**
* Get images
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getImages()
{
return $this->images;
}
/**
* Set location
*
* #param ListingLocation $location
* #return Listing
*/
public function setLocation(ListingLocation $location = null)
{
$this->location = $location;
//Needed to persist listing_id on listing_location table when inserting a new listing embedding a listing location form
$this->location->setListing($this);
}
/**
* Get location
*
* #return ListingLocation
*/
public function getLocation()
{
return $this->location;
}
/**
* Add discount
*
* #param ListingDiscount $discount
* #return Listing
*/
public function addDiscount(ListingDiscount $discount)
{
$discount->setListing($this);
$this->discounts[] = $discount;
return $this;
}
/**
* Remove discount
*
* #param ListingDiscount $discount
*/
public function removeDiscount(ListingDiscount $discount)
{
$this->discounts->removeElement($discount);
$discount->setListing(null);
}
/**
* Get discounts
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDiscounts()
{
return $this->discounts;
}
/**
* #param ArrayCollection|ListingDiscount[] $discounts
*/
public function setDiscounts(ArrayCollection $discounts)
{
foreach ($discounts as $discount) {
$discount->setListing($this);
}
$this->discounts = $discounts;
}
/**
* #return \Doctrine\Common\Collections\Collection|Booking[]
*/
public function getBookings()
{
return $this->bookings;
}
/**
* #param ArrayCollection|Booking[] $bookings
*/
public function setBookings(ArrayCollection $bookings)
{
foreach ($bookings as $booking) {
$booking->setListing($this);
}
$this->bookings = $bookings;
}
/**
* Add booking
*
* #param Booking $booking
*
* #return Listing
*/
public function addBooking(Booking $booking)
{
$this->bookings[] = $booking;
return $this;
}
/**
* Remove booking
*
* #param Booking $booking
*/
public function removeBooking(Booking $booking)
{
$this->bookings->removeElement($booking);
}
/**
* #return mixed
*/
public function getThreads()
{
return $this->threads;
}
/**
* #param ArrayCollection|Thread[] $threads
*/
public function setThreads(ArrayCollection $threads)
{
foreach ($threads as $thread) {
$thread->setListing($this);
}
$this->threads = $threads;
}
/**
* Add thread
*
* #param Thread $thread
*
* #return Listing
*/
public function addThread(Thread $thread)
{
$this->threads[] = $thread;
return $this;
}
/**
* Remove thread
*
* #param Thread $thread
*/
public function removeThread(Thread $thread)
{
$this->threads->removeElement($thread);
}
/**
* Add ListingOption
*
* #param ListingOptionInterface $option
* #return Listing
*/
public function addOption($option)
{
$option->setListing($this);
$this->options[] = $option;
return $this;
}
/**
* Remove ListingOption
*
* #param ListingOptionInterface $option
*/
public function removeOption($option)
{
$this->options->removeElement($option);
}foreach ($threads as $thread) {
$thread->setListing($this);
}
$this->threads = $threads;
}
/**
* Add thread
*
* #param Thread $thread
*
* #return Listing
*/
public function addThread(Thread $thread)
{
$this->threads[] = $thread;
return $this;
}
/**
* Remove thread
*
* #param Thread $thread
*/
public function removeThread(Thread $thread)
{
$this->threads->removeElement($thread);
}
/**
* Add ListingOption
*
* #param ListingOptionInterface $option
* #return Listing
*/
public function addOption($option)
{
$option->setListing($this);
$this->options[] = $option;
return $this;
}
/**
* Remove ListingOption
*
* #param ListingOptionInterface $option
*/
public function removeOption($option)
{
$this->options->removeElement($option);
}
/**
* Get ListingOptions
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getOptions()
{
return $this->options;
}
/**
* #param ArrayCollection $options
* #return $this
*/
public function setOptions(ArrayCollection $options)
{
foreach ($options as $option) {
$option->setListing($this);
}
$this->options = $options;
return $this;
}
/**
* #param int $minImages
* #param bool $strict
*
* #return array
*/
public function getCompletionInformations($minImages, $strict = true)
{
$characteristic = 0;
foreach ($this->getListingListingCharacteristics() as $characteristics) {
if ($characteristics->getListingCharacteristicValue()) {
$characteristic = 1;
}
}
return array(
"title" => $this->getTitle() ? 1 : 0,
"description" => (
($strict && $this->getDescription()) ||
(!$strict && strlen($this->getDescription()) > 250)
) ? 1 : 0,
"price" => $this->getPrice() ? 1 : 0,
"image" => (
($strict && count($this->getImages()) >= $minImages) ||
(!$strict && count($this->getImages()) > $minImages)
) ? 1 : 0,
"characteristic" => $characteristic,
);
}
public function getTitle()
{
return (string)$this->translate()->getTitle();
}
public function getSlug()
{
return (string)$this->translate()->getSlug();
}
public function __toString()
{
return (string)$this->getTitle();
}
/**
* To add impersonating link into admin :
*
* #return User
*/
public function getImpersonating()
{
return $this->getUser();
}
}
I am working with Symfony2 and I faced with an error:
Error: Method Proxies__CG__\Sprint\SiteBundle\Entity\Task::__toString() must not throw an exception
Here is this this code in my Entity\Task.php:
/**
* #return string
*/
public function __toString()
{
return $this->title;
}
The main problem, that on my local version of this site everything okay and I have this error only on my live site. But they are similar!
Here my Entity\Task.php code:
class Task
{
use TraitDateTimeFields;
use TraitCreatorTimeFields;
use TraitTaskTeamFields;
use TraitTimeTrackFields;
use TraitTagFields;
/**
* #ORM\ManyToMany(targetEntity="Sprint\SiteBundle\Entity\Tag")
* #ORM\JoinTable(
* name="s_task_tags",
* joinColumns={
* #ORM\JoinColumn(name="task_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="tag_id", referencedColumnName="id")
* }
* )
*/
private $tags;
/**
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue
* #Gedmo\TreePathSource
* #var integer
*/
private $id;
/**
* #ORM\Column(type="integer", name="depth", nullable=true)
* #Gedmo\TreeLevel
* #var integer
*/
private $depth;
/**
* #ORM\Column(type="string", name="path", length=255, nullable=true)
* #Gedmo\TreePath
* #var string
*/
private $path;
/** Это группа
* #ORM\Column(type="boolean", name="flag_group")
* #var string
*/
private $flagGroup = false;
/** Архив
*
* #ORM\Column(type="boolean", name="flag_archive")
* #var string
*/
private $flagArchive = false;
/**
* #ORM\Column(type="string", name="number", nullable=false)
* #var string
*/
protected $number = '';
/**
* #ORM\Column(type="string", name="title", nullable=true)
* #var string
*/
protected $title;
/**
* #ORM\Column(type="integer", name="resource")
* #var string
* #deprecated
*/
protected $resource = 0;
/**
* #ORM\Column(type="integer", name="bonus")
* #var string
*/
protected $bonus = 0;
/**
* #ORM\Column(type="integer", name="state")
* #var string
*/
protected $state = TaskState::C_WORKING;
/**
* #ORM\Column(type="integer", name="ttype")
* #var string
*/
protected $type = TaskType::C_INNER;
/** Начало
*
* #ORM\Column(type="datetime", name="start_to", nullable=true)
* #var \DateTime
*/
private $startTo;
/** Дедлайн
*
* #ORM\Column(type="datetime", name="deadline_to", nullable=true)
* #var \DateTime
*/
private $deadlineTo;
/** Срочно
*
* #ORM\Column(type="boolean", name="flag_quicly")
* #var string
*/
private $flagQuickly = false;
/** Формирование бюджета
*
* #ORM\Column(type="boolean", name="flag_budget")
* #var string
*/
private $flagBudget = true;
/**
* #ORM\OneToMany(targetEntity="Sprint\SiteBundle\Entity\EstimateOperatingRow", mappedBy="task", cascade={"detach","persist"}, orphanRemoval=false)
* #var \Doctrine\Common\Collections\ArrayCollection
*/
protected $estimateRows;
/**
* #ORM\ManyToOne(targetEntity="Sprint\SiteBundle\Entity\Project", inversedBy="tasks")
* #ORM\JoinColumn(name="project_id", referencedColumnName="id", onDelete="CASCADE")
* #var \Sprint\SiteBundle\Entity\Project
*/
protected $project;
/**
* #ORM\ManyToOne(targetEntity="Sprint\SiteBundle\Entity\Task", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
* #Gedmo\TreeParent
* #var \Sprint\SiteBundle\Entity\Task
*/
protected $parent;
/** Подзадачи
*
* #ORM\OneToMany(targetEntity="Sprint\SiteBundle\Entity\Task", mappedBy="parent", cascade={"all"}, orphanRemoval=true)
* #var \Doctrine\Common\Collections\ArrayCollection
*/
public $children;
/** Задания
*
* #ORM\OneToMany(targetEntity="Sprint\SiteBundle\Entity\TaskAssignment", mappedBy="task", cascade={"all"}, orphanRemoval=true)
* #var \Doctrine\Common\Collections\ArrayCollection
*/
public $assignment;
/** Активность
*
* #ORM\OneToMany(targetEntity="Sprint\SiteBundle\Entity\TaskActivityItem", mappedBy="task", cascade={"all"}, orphanRemoval=true)
* #var \Doctrine\Common\Collections\ArrayCollection
*/
public $activity;
private $activitySummary = [];
protected $operationItems = [];
/**
* Task constructor.
*/
public function __construct()
{
$this->children = new \Doctrine\Common\Collections\ArrayCollection();
$this->activity = new \Doctrine\Common\Collections\ArrayCollection();
$this->auditors = new \Doctrine\Common\Collections\ArrayCollection();
$this->staff = new \Doctrine\Common\Collections\ArrayCollection();
$this->tags = new \Doctrine\Common\Collections\ArrayCollection();
$this->estimateRows = new \Doctrine\Common\Collections\ArrayCollection();
$this->assignment = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #return string
*/
public function __toString()
{
return $this->title;
}
public function getTreeTitle()
{
return str_pad('', ($this->depth-1)*6*4, ' ', STR_PAD_LEFT) . ($this->flagGroup ? ' ' : ' ') . $this->title;
}
/**
* #return array
*/
public function getPaySummary()
{
$result = [
'total' => 0,
'paid' => 0,
'remains' => 0,
'credit' => 0
];
$now = new \DateTime();
foreach ($this->getOperationItems() as $opt) {
$optSummary = $opt->getSummary();
$result['total'] += $optSummary['total'];
$result['paid'] += $optSummary['paid'];
$result['remains'] += $optSummary['remains'];
if ($opt->getExpectedAt()) {
$df = $now->diff($opt->getExpectedAt());
if ($df->invert) {
$result['credit'] += $optSummary['remains'];
}
}
}
return $result;
}
/**
* #return array
*/
public function getActivitySummary($hourPrice, $forced = false)
{
if ($forced) {
$this->activitySummary = [];
}
if ($this->activitySummary) {
return $this->activitySummary;
}
$result = [
'plannedHours' => 0,
'plannedSmens' => 0,
'plannedPrice' => 0,
'plannedHoursRemains' => 0,
'plannedSmensRemains' => 0,
'plannedPriceRemains' => 0,
'developHours' => 0,
'developSmens' => 0,
'developPrice' => 0,
'developHoursRemains' => 0,
'developSmensRemains' => 0,
'developPriceRemains' => 0,
'innerHours' => 0,
'innerSmens' => 0,
'innerPrice' => 0,
'innerHoursRemains' => 0,
'innerSmensRemains' => 0,
'innerPriceRemains' => 0,
'outherHours' => 0,
'outherSmens' => 0,
'outherPrice' => 0,
'outherHoursRemains' => 0,
'outherSmensRemains' => 0,
'outherPriceRemains' => 0,
'resource' => 0
];
if ($this->flagGroup) {
$childs = $this->getChildren();
if (!$childs->isEmpty()) {
$cnt = $childs->count();
$planSummary = 0.0;
foreach ($childs as $c) {
$planSummary += $c->getPlannedHours();
$cRes = $c->getActivitySummary($hourPrice, $forced);
foreach ($cRes as $k => $v) {
$result[$k] += $v;
}
}
$this->setPlannedHours($planSummary);
}
} else {
foreach ($this->activity as $a) {
switch ($a->getActivity()) {
case TaskActivity::C_DEVELOP :
$result['plannedHours'] += $a->getSpend();
$result['developHours'] += $a->getSpend();
break;
case TaskActivity::C_INNER :
$result['plannedHours'] += $a->getSpend();
$result['innerHours'] += $a->getSpend();
break;
case TaskActivity::C_OUTHER :
$result['plannedHours'] += $a->getSpend();
$result['outherHours'] += $a->getSpend();
break;
}
}
$result['plannedHoursRemains'] = $this->getPlannedHours() - $result['plannedHours'];
$result['developHoursRemains'] = $this->getDevelopHours() - $result['developHours'];
$result['innerHoursRemains'] = $this->getInnerHours() - $result['innerHours'];
$result['outherHoursRemains'] = $this->getOutherHours() - $result['outherHours'];
}
$result['plannedSmens'] = $result['plannedHours'] / 8;
$result['developSmens'] = $result['developHours'] / 8;
$result['innerSmens'] = $result['innerHours'] / 8;
$result['outherSmens'] = $result['outherHours'] / 8;
$result['plannedPrice'] = $result['plannedHours'] * $hourPrice;
$result['developPrice'] = $result['developHours'] * $hourPrice;
$result['innerPrice'] = $result['innerHours'] * $hourPrice;
$result['outherPrice'] = $result['outherHours'] * $hourPrice;
$result['plannedSmensRemains'] = $result['plannedHoursRemains'] / 8;
$result['developSmensRemains'] = $result['developHoursRemains'] / 8;
$result['innerSmensRemains'] = $result['innerHoursRemains'] / 8;
$result['outherSmensRemains'] = $result['outherHoursRemains'] / 8;
$result['plannedPriceRemains'] = $result['plannedHoursRemains'] * $hourPrice;
$result['developPriceRemains'] = $result['developHoursRemains'] * $hourPrice;
$result['innerPriceRemains'] = $result['innerHoursRemains'] * $hourPrice;
$result['outherPriceRemains'] = $result['outherHoursRemains'] * $hourPrice;
if ($this->plannedHours) {
$result['resource'] = round(
($result['developHours'] + $result['innerHours'] + $result['outherHours']) / $this->plannedHours * 100
);
}
$this->activitySummary = $result;
return $this->activitySummary;
}
/**
* #return string
*/
public function getResource()
{
return $this->resource;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* #param string $title
*/
public function setTitle($title)
{
$this->title = $title;
}
/**
* #return bool|\DateInterval
*/
public function getTimeToDeadline()
{
return $this->deadlineTo ? $this->deadlineTo->diff(new \DateTime()) : null;
}
/**
* #return string
*/
public function getFlagQuickly()
{
$interval = $this->getTimeToDeadline();
return ($interval && $interval->invert && $interval->days*24 < 8);
}
/**
* #param string $flagQuickly
*/
public function setFlagQuickly($flagQuickly)
{
$this->flagQuickly = $flagQuickly;
}
/**
* #return string
*/
public function getFlagBudget()
{
return $this->flagBudget;
}
/**
* #param string $flagBudget
*/
public function setFlagBudget($flagBudget)
{
$this->flagBudget = $flagBudget;
}
/**
* #param Project $project
* #return Task
*/
public function setProject($project)
{
$this->project = $project;
return $this;
}
/**
* #return Project
*/
public function getProject()
{
return $this->project;
}
/**
* #return ArrayCollection
*/
public function getChildren()
{
return $this->children;
}
/**
* #return \Doctrine\Common\Collections\Collection|static
*/
public function getDisplayedChildren()
{
$criteria = Criteria::create();
$criteria->orderBy(['createdAt' => 'DESC']);
$criteria->where(Criteria::expr()->eq('parent', $this));
return $this->children->matching($criteria);
}
/**
* #param Task $parent
* #return Task
*/
public function setParent($parent)
{
$this->parent = $parent;
return $this;
}
/**
* #return Task
*/
public function getParent()
{
return $this->parent;
}
/**
* #param \DateTime $startTo
* #return Task
*/
public function setStartTo($startTo)
{
$this->startTo = $startTo;
return $this;
}
/**
* #return \DateTime
*/
public function getStartTo()
{
return $this->startTo;
}
/**
* #param \DateTime $deadlineTo
* #return Task
*/
public function setDeadlineTo($deadlineTo)
{
$this->deadlineTo = $deadlineTo;
return $this;
}
/**
* #return \DateTime
*/
public function getDeadlineTo()
{
return $this->deadlineTo;
}
/**
* #param string $number
* #return Task
*/
public function setNumber($number)
{
$this->number = $number;
return $this;
}
/**
* #return string
*/
public function getNumber()
{
return $this->number;
}
/**
* #param string $resource
* #return Task
*/
public function setResource($resource)
{
$this->resource = $resource;
return $this;
}
/**
* #return mixed
*/
public function getEstimateRows()
{
return $this->estimateRows;
}
/**
* #param $estimateRow
*/
public function addEstimateRow($estimateRow)
{
$estimateRow->setTask($this);
$this->estimateRows->add($estimateRow);
}
/**
* #param $estimateRow
*/
public function removeEstimateRow($estimateRow)
{
$estimateRow->setTask(null);
$this->estimateRows->removeElement($estimateRow);
}
/**
* #param mixed $estimateRows
*/
/*
public function setEstimateRows($estimateRows)
{
$this->estimateRows = $estimateRows;
}
*/
/**
* #return mixed
*/
public function getState()
{
return $this->state;
}
/**
* #param mixed $state
*/
public function setState($state)
{
$this->state = $state;
}
/**
* #return mixed
*/
public function getType()
{
return $this->type;
}
/**
* #param mixed $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* #return string
*/
public function getTags()
{
return $this->tags;
}
/**
* #param string $tags
*/
public function setTags($tags)
{
$this->tags = $tags;
}
/**
* #return mixed
*/
public function getBonus()
{
return $this->bonus;
}
/**
* #param mixed $bonus
*/
public function setBonus($bonus)
{
$this->bonus = $bonus;
}
/**
* #return ArrayCollection
*/
public function getActivity()
{
return $this->activity;
}
/**
* #return ArrayCollection
*/
public function getAssignment()
{
return $this->assignment;
}
/**
* #return \Doctrine\Common\Collections\Collection|static
*/
public function getDisplayedActivity()
{
$criteria = Criteria::create();
$criteria->orderBy(['createdAt' => 'DESC']);
$criteria->where(Criteria::expr()->isNull('parent'));
return $this->activity->matching($criteria);
}
/**
* #param $activity
*/
public function addActivity($activity)
{
$this->activity->add($activity);
}
/**
* #param $activity
*/
public function removeActivity($activity)
{
$this->activity->removeElement($activity);
}
/**
* #return mixed
*/
public function getDepth()
{
return $this->depth;
}
/**
* #param mixed $depth
*/
public function setDepth($depth)
{
$this->depth = $depth;
}
/**
* #return mixed
*/
public function getPath()
{
return $this->path;
}
/**
* #param mixed $path
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* #return string
*/
public function getFlagGroup()
{
return $this->flagGroup;
}
/**
* #param string $flagGroup
*/
public function setFlagGroup($flagGroup)
{
$this->flagGroup = $flagGroup;
}
public function getDirector()
{
return $this->project ? $this->project->getDirector() : $this->director;
}
/**
* #return mixed
*/
public function getFlagArchive()
{
return $this->flagArchive;
}
/**
* #param mixed $flagArchive
*/
public function setFlagArchive($flagArchive)
{
$this->flagArchive = $flagArchive;
}
/**
* #return mixed
*/
public function getOperationItems()
{
return $this->operationItems;
}
/**
* #param mixed $operations
*/
public function setOperationItems($operations)
{
$this->operationItems = $operations;
}
}
You declared $title prop as "nullable". That means, what it can be NULL.
But __toString() must always return the string value.
Try to cast to string return value.
public function __toString()
{
return (string)$this->title;
}
Make sure the function 1. is not called explicitly statically because then $this does not exist and 2. $this->title actually has a value or is casted to string because otherwise it would return null.
/**
* #return string
*/
public function __toString()
{
return (isset($this) && $this->title !== '')
? (string)$this->title
: '';
}
I'm getting the following error: Fatal error: Call to a member function getBillingAddress() on a non-object in /data/web/public/app/code/core/Mage/Payment/Model/Method/Abstract.php on line 689
I'm on Magento 1.9.1.1. Also have this problem with a completely different magento installation on a different server. Both same versions 1.9.1.1.
This error happens, when from the Manage Customers page, you'll want to create an order for a specific customer. Happens with any registerd customer.
Could this be a core magento bug? And how to fix it?
All help very much appreciated!
Abstract.php
/**
* Payment method abstract model
*
* #author Magento Core Team <core#magentocommerce.com>
*/
abstract class Mage_Payment_Model_Method_Abstract extends Varien_Object
{
const ACTION_ORDER = 'order';
const ACTION_AUTHORIZE = 'authorize';
const ACTION_AUTHORIZE_CAPTURE = 'authorize_capture';
const STATUS_UNKNOWN = 'UNKNOWN';
const STATUS_APPROVED = 'APPROVED';
const STATUS_ERROR = 'ERROR';
const STATUS_DECLINED = 'DECLINED';
const STATUS_VOID = 'VOID';
const STATUS_SUCCESS = 'SUCCESS';
/**
* Bit masks to specify different payment method checks.
* #see Mage_Payment_Model_Method_Abstract::isApplicableToQuote
*/
const CHECK_USE_FOR_COUNTRY = 1;
const CHECK_USE_FOR_CURRENCY = 2;
const CHECK_USE_CHECKOUT = 4;
const CHECK_USE_FOR_MULTISHIPPING = 8;
const CHECK_USE_INTERNAL = 16;
const CHECK_ORDER_TOTAL_MIN_MAX = 32;
const CHECK_RECURRING_PROFILES = 64;
const CHECK_ZERO_TOTAL = 128;
protected $_code;
protected $_formBlockType = 'payment/form';
protected $_infoBlockType = 'payment/info';
/**
* Payment Method features
* #var bool
*/
protected $_isGateway = false;
protected $_canOrder = false;
protected $_canAuthorize = false;
protected $_canCapture = false;
protected $_canCapturePartial = false;
protected $_canCaptureOnce = false;
protected $_canRefund = false;
protected $_canRefundInvoicePartial = false;
protected $_canVoid = false;
protected $_canUseInternal = true;
protected $_canUseCheckout = true;
protected $_canUseForMultishipping = true;
protected $_isInitializeNeeded = false;
protected $_canFetchTransactionInfo = false;
protected $_canReviewPayment = false;
protected $_canCreateBillingAgreement = false;
protected $_canManageRecurringProfiles = true;
/**
* TODO: whether a captured transaction may be voided by this gateway
* This may happen when amount is captured, but not settled
* #var bool
*/
protected $_canCancelInvoice = false;
/**
* Fields that should be replaced in debug with '***'
*
* #var array
*/
protected $_debugReplacePrivateDataKeys = array();
public function __construct()
{
}
/**
* Check order availability
*
* #return bool
*/
public function canOrder()
{
return $this->_canOrder;
}
/**
* Check authorise availability
*
* #return bool
*/
public function canAuthorize()
{
return $this->_canAuthorize;
}
/**
* Check capture availability
*
* #return bool
*/
public function canCapture()
{
return $this->_canCapture;
}
/**
* Check partial capture availability
*
* #return bool
*/
public function canCapturePartial()
{
return $this->_canCapturePartial;
}
/**
* Check whether capture can be performed once and no further capture possible
*
* #return bool
*/
public function canCaptureOnce()
{
return $this->_canCaptureOnce;
}
/**
* Check refund availability
*
* #return bool
*/
public function canRefund()
{
return $this->_canRefund;
}
/**
* Check partial refund availability for invoice
*
* #return bool
*/
public function canRefundPartialPerInvoice()
{
return $this->_canRefundInvoicePartial;
}
/**
* Check void availability
*
* #param Varien_Object $payment
* #return bool
*/
public function canVoid(Varien_Object $payment)
{
return $this->_canVoid;
}
/**
* Using internal pages for input payment data
* Can be used in admin
*
* #return bool
*/
public function canUseInternal()
{
return $this->_canUseInternal;
}
/**
* Can be used in regular checkout
*
* #return bool
*/
public function canUseCheckout()
{
return $this->_canUseCheckout;
}
/**
* Using for multiple shipping address
*
* #return bool
*/
public function canUseForMultishipping()
{
return $this->_canUseForMultishipping;
}
/**
* Can be edit order (renew order)
*
* #return bool
*/
public function canEdit()
{
return true;
}
/**
* Check fetch transaction info availability
*
* #return bool
*/
public function canFetchTransactionInfo()
{
return $this->_canFetchTransactionInfo;
}
/**
* Check whether payment method instance can create billing agreements
*
* #return bool
*/
public function canCreateBillingAgreement()
{
return $this->_canCreateBillingAgreement;
}
/**
* Fetch transaction info
*
* #param Mage_Payment_Model_Info $payment
* #param string $transactionId
* #return array
*/
public function fetchTransactionInfo(Mage_Payment_Model_Info $payment, $transactionId)
{
return array();
}
/**
* Retrieve payment system relation flag
*
* #return bool
*/
public function isGateway()
{
return $this->_isGateway;
}
/**
* flag if we need to run payment initialize while order place
*
* #return bool
*/
public function isInitializeNeeded()
{
return $this->_isInitializeNeeded;
}
/**
* To check billing country is allowed for the payment method
*
* #return bool
*/
public function canUseForCountry($country)
{
/*
for specific country, the flag will set up as 1
*/
if($this->getConfigData('allowspecific')==1){
$availableCountries = explode(',', $this->getConfigData('specificcountry'));
if(!in_array($country, $availableCountries)){
return false;
}
}
return true;
}
/**
* Check method for processing with base currency
*
* #param string $currencyCode
* #return boolean
*/
public function canUseForCurrency($currencyCode)
{
return true;
}
/**
* Check manage billing agreements availability
*
* #return bool
*/
public function canManageBillingAgreements()
{
return ($this instanceof Mage_Payment_Model_Billing_Agreement_MethodInterface);
}
/**
* Whether can manage recurring profiles
*
* #return bool
*/
public function canManageRecurringProfiles()
{
return $this->_canManageRecurringProfiles
&& ($this instanceof Mage_Payment_Model_Recurring_Profile_MethodInterface);
}
/**
* Retrieve model helper
*
* #return Mage_Payment_Helper_Data
*/
protected function _getHelper()
{
return Mage::helper('payment');
}
/**
* Retrieve payment method code
*
* #return string
*/
public function getCode()
{
if (empty($this->_code)) {
Mage::throwException(Mage::helper('payment')->__('Cannot retrieve the payment method code.'));
}
return $this->_code;
}
/**
* Retrieve block type for method form generation
*
* #return string
*/
public function getFormBlockType()
{
return $this->_formBlockType;
}
/**
* Retrieve block type for display method information
*
* #return string
*/
public function getInfoBlockType()
{
return $this->_infoBlockType;
}
/**
* Retrieve payment iformation model object
*
* #return Mage_Payment_Model_Info
*/
public function getInfoInstance()
{
$instance = $this->getData('info_instance');
if (!($instance instanceof Mage_Payment_Model_Info)) {
Mage::throwException(Mage::helper('payment')->__('Cannot retrieve the payment information object instance.'));
}
return $instance;
}
/**
* Validate payment method information object
*
* #return Mage_Payment_Model_Abstract
*/
public function validate()
{
/**
* to validate payment method is allowed for billing country or not
*/
$paymentInfo = $this->getInfoInstance();
if ($paymentInfo instanceof Mage_Sales_Model_Order_Payment) {
$billingCountry = $paymentInfo->getOrder()->getBillingAddress()->getCountryId();
} else {
$billingCountry = $paymentInfo->getQuote()->getBillingAddress()->getCountryId();
}
if (!$this->canUseForCountry($billingCountry)) {
Mage::throwException(Mage::helper('payment')->__('Selected payment type is not allowed for billing country.'));
}
return $this;
}
/**
* Order payment abstract method
*
* #param Varien_Object $payment
* #param float $amount
*
* #return Mage_Payment_Model_Abstract
*/
public function order(Varien_Object $payment, $amount)
{
if (!$this->canOrder()) {
Mage::throwException(Mage::helper('payment')->__('Order action is not available.'));
}
return $this;
}
/**
* Authorize payment abstract method
*
* #param Varien_Object $payment
* #param float $amount
*
* #return Mage_Payment_Model_Abstract
*/
public function authorize(Varien_Object $payment, $amount)
{
if (!$this->canAuthorize()) {
Mage::throwException(Mage::helper('payment')->__('Authorize action is not available.'));
}
return $this;
}
/**
* Capture payment abstract method
*
* #param Varien_Object $payment
* #param float $amount
*
* #return Mage_Payment_Model_Abstract
*/
public function capture(Varien_Object $payment, $amount)
{
if (!$this->canCapture()) {
Mage::throwException(Mage::helper('payment')->__('Capture action is not available.'));
}
return $this;
}
/**
* Set capture transaction ID to invoice for informational purposes
* #param Mage_Sales_Model_Order_Invoice $invoice
* #param Mage_Sales_Model_Order_Payment $payment
* #return Mage_Payment_Model_Method_Abstract
*/
public function processInvoice($invoice, $payment)
{
$invoice->setTransactionId($payment->getLastTransId());
return $this;
}
/**
* Set refund transaction id to payment object for informational purposes
* Candidate to be deprecated:
* there can be multiple refunds per payment, thus payment.refund_transaction_id doesn't make big sense
*
* #param Mage_Sales_Model_Order_Invoice $invoice
* #param Mage_Sales_Model_Order_Payment $payment
* #return Mage_Payment_Model_Method_Abstract
*/
public function processBeforeRefund($invoice, $payment)
{
$payment->setRefundTransactionId($invoice->getTransactionId());
return $this;
}
/**
* Refund specified amount for payment
*
* #param Varien_Object $payment
* #param float $amount
*
* #return Mage_Payment_Model_Abstract
*/
public function refund(Varien_Object $payment, $amount)
{
if (!$this->canRefund()) {
Mage::throwException(Mage::helper('payment')->__('Refund action is not available.'));
}
return $this;
}
/**
* Set transaction ID into creditmemo for informational purposes
* #param Mage_Sales_Model_Order_Creditmemo $creditmemo
* #param Mage_Sales_Model_Order_Payment $payment
* #return Mage_Payment_Model_Method_Abstract
*/
public function processCreditmemo($creditmemo, $payment)
{
$creditmemo->setTransactionId($payment->getLastTransId());
return $this;
}
/**
* Cancel payment abstract method
*
* #param Varien_Object $payment
*
* #return Mage_Payment_Model_Abstract
*/
public function cancel(Varien_Object $payment)
{
return $this;
}
/**
* #deprecated after 1.4.0.0-alpha3
* this method doesn't make sense, because invoice must not void entire authorization
* there should be method for invoice cancellation
* #param Mage_Sales_Model_Order_Invoice $invoice
* #param Mage_Sales_Model_Order_Payment $payment
* #return Mage_Payment_Model_Method_Abstract
*/
public function processBeforeVoid($invoice, $payment)
{
$payment->setVoidTransactionId($invoice->getTransactionId());
return $this;
}
/**
* Void payment abstract method
*
* #param Varien_Object $payment
*
* #return Mage_Payment_Model_Abstract
*/
public function void(Varien_Object $payment)
{
if (!$this->canVoid($payment)) {
Mage::throwException(Mage::helper('payment')->__('Void action is not available.'));
}
return $this;
}
/**
* Whether this method can accept or deny payment
*
* #param Mage_Payment_Model_Info $payment
*
* #return bool
*/
public function canReviewPayment(Mage_Payment_Model_Info $payment)
{
return $this->_canReviewPayment;
}
/**
* Attempt to accept a payment that us under review
*
* #param Mage_Payment_Model_Info $payment
* #return bool
* #throws Mage_Core_Exception
*/
public function acceptPayment(Mage_Payment_Model_Info $payment)
{
if (!$this->canReviewPayment($payment)) {
Mage::throwException(Mage::helper('payment')->__('The payment review action is unavailable.'));
}
return false;
}
/**
* Attempt to deny a payment that us under review
*
* #param Mage_Payment_Model_Info $payment
* #return bool
* #throws Mage_Core_Exception
*/
public function denyPayment(Mage_Payment_Model_Info $payment)
{
if (!$this->canReviewPayment($payment)) {
Mage::throwException(Mage::helper('payment')->__('The payment review action is unavailable.'));
}
return false;
}
/**
* Retrieve payment method title
*
* #return string
*/
public function getTitle()
{
return $this->getConfigData('title');
}
/**
* Retrieve information from payment configuration
*
* #param string $field
* #param int|string|null|Mage_Core_Model_Store $storeId
*
* #return mixed
*/
public function getConfigData($field, $storeId = null)
{
if (null === $storeId) {
$storeId = $this->getStore();
}
$path = 'payment/'.$this->getCode().'/'.$field;
return Mage::getStoreConfig($path, $storeId);
}
/**
* Assign data to info model instance
*
* #param mixed $data
* #return Mage_Payment_Model_Info
*/
public function assignData($data)
{
if (is_array($data)) {
$this->getInfoInstance()->addData($data);
}
elseif ($data instanceof Varien_Object) {
$this->getInfoInstance()->addData($data->getData());
}
return $this;
}
/**
* Parepare info instance for save
*
* #return Mage_Payment_Model_Abstract
*/
public function prepareSave()
{
return $this;
}
/**
* Check whether payment method can be used
*
* TODO: payment method instance is not supposed to know about quote
*
* #param Mage_Sales_Model_Quote|null $quote
*
* #return bool
*/
public function isAvailable($quote = null)
{
$checkResult = new StdClass;
$isActive = (bool)(int)$this->getConfigData('active', $quote ? $quote->getStoreId() : null);
$checkResult->isAvailable = $isActive;
$checkResult->isDeniedInConfig = !$isActive; // for future use in observers
Mage::dispatchEvent('payment_method_is_active', array(
'result' => $checkResult,
'method_instance' => $this,
'quote' => $quote,
));
if ($checkResult->isAvailable && $quote) {
$checkResult->isAvailable = $this->isApplicableToQuote($quote, self::CHECK_RECURRING_PROFILES);
}
return $checkResult->isAvailable;
}
/**
* Check whether payment method is applicable to quote
* Purposed to allow use in controllers some logic that was implemented in blocks only before
*
* #param Mage_Sales_Model_Quote $quote
* #param int|null $checksBitMask
* #return bool
*/
public function isApplicableToQuote($quote, $checksBitMask)
{
if ($checksBitMask & self::CHECK_USE_FOR_COUNTRY) {
if (!$this->canUseForCountry($quote->getBillingAddress()->getCountry())) {
return false;
}
}
if ($checksBitMask & self::CHECK_USE_FOR_CURRENCY) {
if (!$this->canUseForCurrency($quote->getStore()->getBaseCurrencyCode())) {
return false;
}
}
if ($checksBitMask & self::CHECK_USE_CHECKOUT) {
if (!$this->canUseCheckout()) {
return false;
}
}
if ($checksBitMask & self::CHECK_USE_FOR_MULTISHIPPING) {
if (!$this->canUseForMultishipping()) {
return false;
}
}
if ($checksBitMask & self::CHECK_USE_INTERNAL) {
if (!$this->canUseInternal()) {
return false;
}
}
if ($checksBitMask & self::CHECK_ORDER_TOTAL_MIN_MAX) {
$total = $quote->getBaseGrandTotal();
$minTotal = $this->getConfigData('min_order_total');
$maxTotal = $this->getConfigData('max_order_total');
if (!empty($minTotal) && $total < $minTotal || !empty($maxTotal) && $total > $maxTotal) {
return false;
}
}
if ($checksBitMask & self::CHECK_RECURRING_PROFILES) {
if (!$this->canManageRecurringProfiles() && $quote->hasRecurringItems()) {
return false;
}
}
if ($checksBitMask & self::CHECK_ZERO_TOTAL) {
$total = $quote->getBaseSubtotal() + $quote->getShippingAddress()->getBaseShippingAmount();
if ($total < 0.0001 && $this->getCode() != 'free'
&& !($this->canManageRecurringProfiles() && $quote->hasRecurringItems())
) {
return false;
}
}
return true;
}
/**
* Method that will be executed instead of authorize or capture
* if flag isInitializeNeeded set to true
*
* #param string $paymentAction
* #param object $stateObject
*
* #return Mage_Payment_Model_Abstract
*/
public function initialize($paymentAction, $stateObject)
{
return $this;
}
/**
* Get config payment action url
* Used to universalize payment actions when processing payment place
*
* #return string
*/
public function getConfigPaymentAction()
{
return $this->getConfigData('payment_action');
}
/**
* Log debug data to file
*
* #param mixed $debugData
*/
protected function _debug($debugData)
{
if ($this->getDebugFlag()) {
Mage::getModel('core/log_adapter', 'payment_' . $this->getCode() . '.log')
->setFilterDataKeys($this->_debugReplacePrivateDataKeys)
->log($debugData);
}
}
/**
* Define if debugging is enabled
*
* #return bool
*/
public function getDebugFlag()
{
return $this->getConfigData('debug');
}
/**
* Used to call debug method from not Payment Method context
*
* #param mixed $debugData
*/
public function debugData($debugData)
{
$this->_debug($debugData);
}
}
I had similar issue in success page, so i load object by loadByIncrementId function, it worked for me
$orderId = '600008796';
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
then you can access to billing/shipping address by object
$order->getBillingAddress()->getFirstname();
$order->getBillingAddress()->getEmail();
$order->getShippingAddress()->getFirstname();
$order->getShippingAddress()->getEmail();