error: TypeError: Observable_1.Observable.throw is not a function
at CatchSubscriber.push../node_modules/adal-angular8/adal8-http.service.js.Adal8HTTPService.handleError
[as selector] (adal8-http.service.js:172)
at CatchSubscriber.push../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchSubscriber.error
(catchError.js:34)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error
(Subscriber.js:79)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error
(Subscriber.js:59)
at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error
(Subscriber.js:79)
at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error
(Subscriber.js:59)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/OuterSubscriber.js.OuterSubscriber.notifyError
(OuterSubscriber.js:13)
at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._error (InnerSubscriber.js:18)
at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error
(Subscriber.js:59)
at XMLHttpRequest.onLoad (http.js:1707)
I'm getting this error every time when my API return a 400 error
you find below my code snippet:
import { Injectable } from '#angular/core';
import { Adal8HTTPService } from 'adal-angular8';
import { HttpErrorResponse, HttpHeaders } from '#angular/common/http';
import { Observable,throwError } from 'rxjs';
import { catchError } from "rxjs/operators";
#Injectable({
providedIn: 'root'
})
export class HttpService {
constructor(
private adal8HttpService: Adal8HTTPService
) { }
public post(url: string, body: any): Observable<any> {
const options = this.prepareOptions();
return this.adal8HttpService.post(url, body, options).pipe(
catchError(this.handleError)
)
}
private prepareOptions(): any {
let headers = new HttpHeaders();
return {headers};
}
handleError(err: HttpErrorResponse) {
console.log('err', err) <== error is displayed here
return throwError(err);
}
}
the adal service in node module code snippet is :
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
var Observable_1 = require("rxjs/internal/Observable");
var core_1 = require("#angular/core");
var http_1 = require("#angular/common/http");
var operators_1 = require("rxjs/operators");
/**
*
*
* #export
* #class Adal8HTTPService
*/
var Adal8HTTPService = /** #class */ (function () {
/**
* Creates an instance of Adal8HTTPService.
* #param {HttpClient} http
* #param {Adal8Service} service
*
* #memberOf Adal8HTTPService
*/
function Adal8HTTPService(http, service) {
this.http = http;
this.service = service;
}
Adal8HTTPService_1 = Adal8HTTPService;
/**
*
*
* #static
* #param {HttpClient} http
* #param {Adal8Service} service
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.factory = function (http, service) {
return new Adal8HTTPService_1(http, service);
};
/**
*
*
* #param {string} url
* #param {*} [options]
* #returns {Observable<any>}
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.get = function (url, options) {
return this.sendRequest('get', url, options);
};
/**
*
*
* #param {string} url
* #param {*} body
* #param {*} [options]
* #returns {Observable<any>}
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.post = function (url, body, options) {
options.body = body;
return this.sendRequest('post', url, options);
};
/**
*
*
* #param {string} url
* #param {*} [options]
* #returns {Observable<any>}
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.delete = function (url, options) {
return this.sendRequest('delete', url, options);
};
/**
*
*
* #param {string} url
* #param {*} body
* #param {*} [options]
* #returns {Observable<any>}
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.patch = function (url, body, options) {
options.body = body;
return this.sendRequest('patch', url, options);
};
/**
*
*
* #param {string} url
* #param {*} body
* #param {*} [options]
* #returns {Observable<any>}
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.put = function (url, body, options) {
options.body = body;
return this.sendRequest('put', url, options);
};
/**
*
*
* #param {string} url
* #param {*} [options]
* #returns {Observable<any>}
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.head = function (url, options) {
return this.sendRequest('head', url, options);
};
/**
*
*
* #private
* #param {string} method
* #param {string} url
* #param {RequestOptionsArgs} options
* #returns {Observable<string>}
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.sendRequest = function (method, url, options) {
var _this = this;
var resource = this.service.getResourceForEndpoint(url);
var authenticatedCall;
if (resource) {
if (this.service.userInfo.authenticated) {
authenticatedCall = this.service.acquireToken(resource)
.pipe(operators_1.mergeMap(function (token) {
if (options.headers == null) {
options.headers = new http_1.HttpHeaders();
}
options.headers = options.headers.append('Authorization', 'Bearer ' + token);
return _this.http.request(method, url, options)
.pipe(operators_1.catchError(_this.handleError));
}));
}
else {
authenticatedCall = Observable_1.Observable.throw(new Error('User Not Authenticated.'));
}
}
else {
authenticatedCall = this.http.request(method, url, options)
.pipe(operators_1.catchError(this.handleError));
}
return authenticatedCall;
};
/**
*
*
* #private
* #param {*} error
* #returns
*
* #memberOf Adal8HTTPService
*/
Adal8HTTPService.prototype.handleError = function (error) {
// In a real world app, we might send the error to remote logging infrastructure
var errMsg = error.message || 'Server error';
console.error(JSON.stringify(error)); // log to console instead
return Observable_1.Observable.throw(error); <== this line cause the probleme
};
var Adal8HTTPService_1;
Adal8HTTPService = Adal8HTTPService_1 = __decorate([
core_1.Injectable()
], Adal8HTTPService);
return Adal8HTTPService;
}());
exports.Adal8HTTPService = Adal8HTTPService;
Related
I use api-platform v3 and symfony v5. I have problem with displayed properties.
For examle we have simple entity class Category:
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ApiResource()
* #ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
*/
class Category
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $title;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="children")
*/
private $parent;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Category", mappedBy="parent")
*/
private $children;
public function __construct()
{
$this->children = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): self
{
$this->title = $title;
return $this;
}
public function getParent(): ?self
{
return $this->parent;
}
public function setParent(?self $parent): self
{
$this->parent = $parent;
return $this;
}
/**
* #return Collection|self[]
*/
public function getChildren(): Collection
{
return $this->children;
}
public function addChild(self $child): self
{
if (!$this->children->contains($child)) {
$this->children[] = $child;
$child->setParent($this);
}
return $this;
}
public function removeChild(self $child): self
{
if ($this->children->contains($child)) {
$this->children->removeElement($child);
// set the owning side to null (unless already changed)
if ($child->getParent() === $this) {
$child->setParent(null);
}
}
return $this;
}
}
So far, we see the correct and logical "Example Value":
Now I want to display the title and parent properties for reading and writing. To do this, I enter group annotations:
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ApiResource(
* normalizationContext={"groups" = {"category:read"}},
* denormalizationContext={"groups" = {"category:write"}}
* )
* #ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
*/
class Category
{
//...
/**
* #ORM\Column(type="string", length=255)
* #Groups({"category:read", "category:write"})
*/
private $title;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="children")
* #Groups({"category:read", "category:write"})
*/
private $parent;
/**
* #ORM\OneToMany(targetEntity="App\Entity\Category", mappedBy="parent")
*/
private $children;
//...
}
After that, we see the "title" property in the swagger documentation. But the "parent" property is not visible:
Why can't I see the "parent" property in the "Example value" section?
As temporary solution I describe the documentation swagger:
<?php
declare(strict_types=1);
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ApiResource(
* collectionOperations={
* "get",
* "post" = {
* "sequrity" = "is_granted('ROLE_ADMIN')",
* "openapi_context" = {
* "requestBody" = {
* "content" = {
* "application/json" = {
* "schema" = {
* "type" = "object",
* "required" = {
* "title"
* },
* "properties" = {
* "title" = {
* "type" = "string"
* },
* "parent" = {
* "type" = "string"
* }
* }
* }
* }
* }
* }
* }
* }
* },
* normalizationContext={"groups" = {"category:read"}},
* denormalizationContext={"groups" = {"category:write"}}
* )
* #ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
*/
class Category
{
//...
}
I want to know how to do it right.
Why groups do not work for "parent" property?
Had the same issue right now. Try to use annotation #ApiProperty(readableLink=false) for $parent property.
/**
* #ORM\ManyToOne(targetEntity=CounterpartCategory::class, inversedBy="children")
* #ORM\JoinColumn(nullable=true, onDelete="CASCADE")
* #Groups({"category:read", "category:write"})
* #ApiProperty(readableLink=false)
*/
private ?self $parent;
My code works perfect on the local machine, i deployed but the delete, add and update function do not work well that is why i get the following errow "The cart does not contain rowId ce5452f389f041ab17e46324cc050c0d."
Here is my controller
public function index()
{
$cartItems=Cart::content();
return view('cart.index',compact('cartItems'));
}
public function addItem($id)
{
$product=Product::find($id);
Cart::add($id,$product->name,1,$product->price,['size'=>'medium']);
return back();
}
public function update(Request $request, $id)
{
// dd(Cart::content());
// dd($request->all());
Cart::update($id,['qty'=>$request->qty,"options"=>['size'=>$request->size]]);
return back();
}
public function destroy($id)
{
Cart::remove($id);
return back();
}
MY "MODEL" please be patient with me, i only seek understanding if i appear to be some sort of slow
namespace Gloudemans\Shoppingcart;
use Closure;
use Illuminate\Support\Collection;
use Illuminate\Session\SessionManager;
use Illuminate\Database\DatabaseManager;
use Illuminate\Contracts\Events\Dispatcher;
use Gloudemans\Shoppingcart\Contracts\Buyable;
use Gloudemans\Shoppingcart\Exceptions\UnknownModelException;
use Gloudemans\Shoppingcart\Exceptions\InvalidRowIDException;
use Gloudemans\Shoppingcart\Exceptions\CartAlreadyStoredException;
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;
/**
* 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->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;
$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 array $options
* #return \Gloudemans\Shoppingcart\CartItem
*/
public function add($id, $name = null, $qty = null, $price = null, array $options = [])
{
if ($this->isMulti($id)) {
return array_map(function ($item) {
return $this->add($item);
}, $id);
}
$cartItem = $this->createCartItem($id, $name, $qty, $price, $options);
$content = $this->getContent();
if ($content->has($cartItem->rowId)) {
$cartItem->qty += $content->get($cartItem->rowId)->qty;
}
$content->put($cartItem->rowId, $cartItem);
$this->events->fire('cart.added', $cartItem);
$this->session->put($this->instance, $content);
return $cartItem;
}
/**
* 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) {
$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 {
$content->put($cartItem->rowId, $cartItem);
}
$this->events->fire('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->fire('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()
{
$content = $this->getContent();
return $content->sum('qty');
}
/**
* Get the total price of the items in the cart.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
* #return string
*/
public function total($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
$content = $this->getContent();
$total = $content->reduce(function ($total, CartItem $cartItem) {
return $total + ($cartItem->qty * $cartItem->priceTax);
}, 0);
return $this->numberFormat($total, $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the total tax of the items in the cart.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
* #return float
*/
public function tax($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
$content = $this->getContent();
$tax = $content->reduce(function ($tax, CartItem $cartItem) {
return $tax + ($cartItem->qty * $cartItem->tax);
}, 0);
return $this->numberFormat($tax, $decimals, $decimalPoint, $thousandSeperator);
}
/**
* Get the subtotal (total - tax) of the items in the cart.
*
* #param int $decimals
* #param string $decimalPoint
* #param string $thousandSeperator
* #return float
*/
public function subtotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
$content = $this->getContent();
$subTotal = $content->reduce(function ($subTotal, CartItem $cartItem) {
return $subTotal + ($cartItem->qty * $cartItem->price);
}, 0);
return $this->numberFormat($subTotal, $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)
{
$content = $this->getContent();
return $content->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);
}
/**
* Store an the current instance of the cart.
*
* #param mixed $identifier
* #return void
*/
public function store($identifier)
{
$content = $this->getContent();
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)
]);
$this->events->fire('cart.stored');
}
/**
* Restore the cart with the given identifier.
*
* #param mixed $identifier
* #return void
*/
public function restore($identifier)
{
if( ! $this->storedCartWithIdentifierExists($identifier)) {
return;
}
$stored = $this->getConnection()->table($this->getTableName())
->where('identifier', $identifier)->first();
$storedContent = unserialize($stored->content);
$currentInstance = $this->currentInstance();
$this->instance($stored->instance);
$content = $this->getContent();
foreach ($storedContent as $cartItem) {
$content->put($cartItem->rowId, $cartItem);
}
$this->events->fire('cart.restored');
$this->session->put($this->instance, $content);
$this->instance($currentInstance);
$this->getConnection()->table($this->getTableName())
->where('identifier', $identifier)->delete();
}
/**
* Magic method to make accessing the total, tax and subtotal properties possible.
*
* #param string $attribute
* #return float|null
*/
public function __get($attribute)
{
if($attribute === 'total') {
return $this->total();
}
if($attribute === 'tax') {
return $this->tax();
}
if($attribute === 'subtotal') {
return $this->subtotal();
}
return null;
}
/**
* Get the carts content, if there is no cart content set yet, return a new empty Collection
*
* #return \Illuminate\Support\Collection
*/
protected function getContent()
{
$content = $this->session->has($this->instance)
? $this->session->get($this->instance)
: new Collection;
return $content;
}
/**
* Create a new CartItem from the supplied attributes.
*
* #param mixed $id
* #param mixed $name
* #param int|float $qty
* #param float $price
* #param array $options
* #return \Gloudemans\Shoppingcart\CartItem
*/
private function createCartItem($id, $name, $qty, $price, 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, $options);
$cartItem->setQuantity($qty);
}
$cartItem->setTaxRate(config('cart.tax'));
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()
{
$connectionName = $this->getConnectionName();
return app(DatabaseManager::class)->connection($connectionName);
}
/**
* 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 Formated number
*
* #param $value
* #param $decimals
* #param $decimalPoint
* #param $thousandSeperator
* #return string
*/
private function numberFormat($value, $decimals, $decimalPoint, $thousandSeperator)
{
if(is_null($decimals)){
$decimals = is_null(config('cart.format.decimals')) ? 2 : config('cart.format.decimals');
}
if(is_null($decimalPoint)){
$decimalPoint = is_null(config('cart.format.decimal_point')) ? '.' : config('cart.format.decimal_point');
}
if(is_null($thousandSeperator)){
$thousandSeperator = is_null(config('cart.format.thousand_seperator')) ? ',' : config('cart.format.thousand_seperator');
}
return number_format($value, $decimals, $decimalPoint, $thousandSeperator);
}
}
MY "VIEW"
#foreach($cartItems as $cartItem)
<tr>
<td style="border-style: solid">{{$cartItem->name}}</td>
<td style="border-style: solid">{{$cartItem->price}}</td>
<td style="border-style: solid">
{!! Form::open(['route' => ['cart.update',$cartItem->rowId], 'method' => 'PUT']) !!}
<input name="qty" type="text" value="{{$cartItem->qty}}">
</td>
<td style="border-style: solid">
<input style="float: left" type="submit" class="btn btn-success" value="Ok">
{!! Form::close() !!}
</td>
<td style="border-style: solid">
<form action="{{route('cart.destroy',$cartItem->rowId)}}" method="POST" >
{{csrf_field()}}
{{method_field('DELETE')}}
<input class="btn btn-danger" type="submit" value="Delete">
</form>
</td>
</tr>
#endforeach
My inspector shows the rowID, i can understand that the rowID is generated by the cart when i add the item but where to located this rowID is something different.
<tr>
<td style="border-style: solid">ASGHJSDFGHJDF</td>
<td style="border-style: solid">56</td>
<td style="border-style: solid">
<form method="POST" action="http://rorisangmaimane.co.za/cart/ce5452f389f041ab17e46324cc050c0d" accept-charset="UTF-8"><input name="_method" type="hidden" value="PUT"><input name="_token" type="hidden" value="iXJ3ncGwro7lVA07Mph4rbZloVF1UTQ0m8mlmpK6">
<input name="qty" type="text" value="2">
</td>
<td style="border-style: solid">
<input style="float: left" type="submit" class="btn btn-success" value="Ok">
</form>
</td>
<td style="border-style: solid">
<form action="http://rorisangmaimane.co.za/cart/ce5452f389f041ab17e46324cc050c0d" method="POST" >
<input type="hidden" name="_token" value="iXJ3ncGwro7lVA07Mph4rbZloVF1UTQ0m8mlmpK6">
<input type="hidden" name="_method" value="DELETE">
<input class="btn btn-danger" type="submit" value="Delete">
</form>
</td>
</tr>
I also face the same problem. But my problem happen when user click the update/remove button twice at a same time.
I solved the issue by following ways -
First check whether the rowId is available or not. Then implement actions -
$cart = Cart::content()->where('rowId',$id);
if($cart->isNotEmpty()){
Cart::remove($id);
}
Same way in the updated functions also.
Im working on Magento 2.1.1 . When I open product page from product list page i cant able to see category name on breadcrumbs . It just shows homepage url followed by product name . Very rarely I can able to see full breadcrumbs with category name .
breadcrumbs - category name is missing .
Could someone please give me some ideas to solve this issue?
This issue is already reported to Magento 2 GitHub repository here:
https://github.com/magento/magento2/issues/7967
There is a gist linked in the comments which has a workaround:
https://gist.github.com/mbahar/82703c4b95d924d9bc8e6990202fdeba
I've found solution, approved by Magento team. Because if you use approaches with block rewrites or plugins and you have some extensions that use Breadcrumbs block or Magento\Catalog\Controller\Product\View.php, you'll have problems.
So, you have to customize just app/code/Magento/Catalog/view/frontend/web/js/product/breadcrumbs.js.
So, here is a full code:
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'jquery',
'Magento_Theme/js/model/breadcrumb-list'
], function ($, breadcrumbList) {
'use strict';
return function (widget) {
$.widget('mage.breadcrumbs', widget, {
options: {
categoryUrlSuffix: '',
useCategoryPathInUrl: false,
product: '',
menuContainer: '[data-action="navigation"] > ul'
},
/** #inheritdoc */
_render: function () {
this._appendCatalogCrumbs();
this._super();
},
/**
* Append category and product crumbs.
*
* #private
*/
_appendCatalogCrumbs: function () {
var categoryCrumbs = this._resolveCategoryCrumbs();
categoryCrumbs.forEach(function (crumbInfo) {
breadcrumbList.push(crumbInfo);
});
if (this.options.product) {
breadcrumbList.push(this._getProductCrumb());
}
},
/**
* Resolve categories crumbs.
*
* #return Array
* #private
*/
_resolveCategoryCrumbs: function () {
var menuItem = this._resolveCategoryMenuItem(),
categoryCrumbs = [];
if (menuItem !== null && menuItem.length) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
while ((menuItem = this._getParentMenuItem(menuItem)) !== null) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
}
}
return categoryCrumbs;
},
/**
* Returns crumb data.
*
* #param {Object} menuItem
* #return {Object}
* #private
*/
_getCategoryCrumb: function (menuItem) {
return {
'name': 'category',
'label': menuItem.text(),
'link': menuItem.attr('href'),
'title': ''
};
},
/**
* Returns product crumb.
*
* #return {Object}
* #private
*/
_getProductCrumb: function () {
return {
'name': 'product',
'label': this.options.product,
'link': '',
'title': ''
};
},
/**
* Find parent menu item for current.
*
* #param {Object} menuItem
* #return {Object|null}
* #private
*/
_getParentMenuItem: function (menuItem) {
var classes,
classNav,
parentClass,
parentMenuItem = null;
if (!menuItem) {
return null;
}
classes = menuItem.parent().attr('class');
classNav = classes.match(/(nav\-)[0-9]+(\-[0-9]+)+/gi);
if (classNav) {
classNav = classNav[0];
parentClass = classNav.substr(0, classNav.lastIndexOf('-'));
if (parentClass.lastIndexOf('-') !== -1) {
parentMenuItem = $(this.options.menuContainer).find('.' + parentClass + ' > a');
parentMenuItem = parentMenuItem.length ? parentMenuItem : null;
}
}
return parentMenuItem;
},
/**
* Returns category menu item.
*
* Tries to resolve category from url or from referrer as fallback and
* find menu item from navigation menu by category url.
*
* #return {Object|null}
* #private
*/
_resolveCategoryMenuItem: function () {
var categoryUrl = this._resolveCategoryUrl(),
menu = $(this.options.menuContainer),
categoryMenuItem = null;
if (categoryUrl && menu.length) {
categoryMenuItem = menu.find('a[href="' + categoryUrl + '"]');
}
return categoryMenuItem;
},
/**
* Returns category url.
*
* #return {String}
* #private
*/
_resolveCategoryUrl: function () {
var categoryUrl;
if (this.options.useCategoryPathInUrl) {
// In case category path is used in product url - resolve category url from current url.
categoryUrl = window.location.href.split('?')[0];
categoryUrl = categoryUrl.substring(0, categoryUrl.lastIndexOf('/')) +
this.options.categoryUrlSuffix;
} else {
// In other case - try to resolve it from referrer (without parameters).
categoryUrl = document.referrer;
if (categoryUrl.indexOf('?') > 0) {
categoryUrl = categoryUrl.substr(0, categoryUrl.indexOf('?'));
}
}
return categoryUrl;
}
});
return $.mage.breadcrumbs;
};
});
And here is a link to merge request: ENGCOM-1707
I've found a solution for the above issue. Kindly check the below js file.
vendor/magento/module-catalog/view/frontend/web/js/product/breadcrumbs.js
The breadcrumbs.js file has taken some classes by using the menu. If you are customizing the menu, the category name is missed in the breadcrumbs-Product detail page.
Menu must have the following class:
1)Menu nav section must have "data-action="navigation".
2)Menu li element must have "category-item" class.
3)The parent li element must have "nav-1","nav-2",.. class and the sub child li("nav-1")element must have "nav-1-1","nav-1-2" and so on..
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'jquery',
'Magento_Theme/js/model/breadcrumb-list'
], function ($, breadcrumbList) {
'use strict';
return function (widget) {
// calling menu class and data-action "categoryItemSelector","menuContainer"**
$.widget('mage.breadcrumbs', widget, {
options: {
categoryUrlSuffix: '',
useCategoryPathInUrl: false,
product: '',
categoryItemSelector: '.category-item',
menuContainer: '[data-action="navigation"] > ul'**
},
/** #inheritdoc */
_render: function () {
this._appendCatalogCrumbs();
this._super();
},
/**
* Append category and product crumbs.
*
* #private
*/
_appendCatalogCrumbs: function () {
var categoryCrumbs = this._resolveCategoryCrumbs();
categoryCrumbs.forEach(function (crumbInfo) {
breadcrumbList.push(crumbInfo);
});
if (this.options.product) {
breadcrumbList.push(this._getProductCrumb());
}
},
/**
* Resolve categories crumbs.
*
* #return Array
* #private
*/
_resolveCategoryCrumbs: function () {
var menuItem = this._resolveCategoryMenuItem(),
categoryCrumbs = [];
if (menuItem !== null && menuItem.length) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
while ((menuItem = this._getParentMenuItem(menuItem)) !== null) {
categoryCrumbs.unshift(this._getCategoryCrumb(menuItem));
}
}
return categoryCrumbs;
},
/**
* Returns crumb data.
*
* #param {Object} menuItem
* #return {Object}
* #private
*/
_getCategoryCrumb: function (menuItem) {
return {
'name': 'category',
'label': menuItem.text(),
'link': menuItem.attr('href'),
'title': ''
};
},
/**
* Returns product crumb.
*
* #return {Object}
* #private
*/
_getProductCrumb: function () {
return {
'name': 'product',
'label': this.options.product,
'link': '',
'title': ''
};
},
/**
* Find parent menu item for current.
*
* #param {Object} menuItem
* #return {Object|null}
* #private
*/
_getParentMenuItem: function (menuItem) {
var classes,
classNav,
parentClass,
parentMenuItem = null;
if (!menuItem) {
return null;
}
classes = menuItem.parent().attr('class');
// calling menu nav class**********
**classNav = classes.match(/(nav\-)[0-9]+(\-[0-9]+)+/gi);**
if (classNav) {
classNav = classNav[0];
parentClass = classNav.substr(0, classNav.lastIndexOf('-'));
if (parentClass.lastIndexOf('-') !== -1) {
parentMenuItem = $(this.options.menuContainer).find('.' + parentClass + ' > a');
parentMenuItem = parentMenuItem.length ? parentMenuItem : null;
}
}
return parentMenuItem;
},
/**
* Returns category menu item.
*
* Tries to resolve category from url or from referrer as fallback and
* find menu item from navigation menu by category url.
*
* #return {Object|null}
* #private
*/
_resolveCategoryMenuItem: function () {
var categoryUrl = this._resolveCategoryUrl(),
menu = $(this.options.menuContainer),
categoryMenuItem = null;
if (categoryUrl && menu.length) {
categoryMenuItem = menu.find(
this.options.categoryItemSelector +
' > a[href="' + categoryUrl + '"]'
);
}
return categoryMenuItem;
},
/**
* Returns category url.
*
* #return {String}
* #private
*/
_resolveCategoryUrl: function () {
var categoryUrl;
if (this.options.useCategoryPathInUrl) {
// In case category path is used in product url - resolve category url from current url.
categoryUrl = window.location.href.split('?')[0];
categoryUrl = categoryUrl.substring(0, categoryUrl.lastIndexOf('/')) +
this.options.categoryUrlSuffix;
} else {
// In other case - try to resolve it from referrer (without parameters).
categoryUrl = document.referrer;
if (categoryUrl.indexOf('?') > 0) {
categoryUrl = categoryUrl.substr(0, categoryUrl.indexOf('?'));
}
}
return categoryUrl;
}
});
return $.mage.breadcrumbs;
};
});
I haven't tried the above workaround, but people say it's not always working.
Meanwhile the following seems to be working nicely (I've just tested it):
https://github.com/magento/magento2/issues/7967#issuecomment-315310890
[Vendor]/[Module]/etc/frontend/events.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_controller_product_init_after">
<observer instance="[Vendor]\[Module]\Observer\Catalog\Product\FullPathBreadcrumbs" name="addProductFullPathBreadcrumbs"/>
</event>
</config>
[Vendor]/[Module]//Observer/Catalog/Product/FullPathBreadcrumbs
<?php
namespace [Vendor]\[Module]\Observer\Catalog\Product;
class FullPathBreadcrumbs implements \Magento\Framework\Event\ObserverInterface
{
protected $_registry;
protected $_categoryRepository;
public function __construct(
\Magento\Framework\Registry $registry,
\Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
) {
$this->_registry=$registry;
$this->_categoryRepository = $categoryRepository;
}
/**
* Execute observer
*
* #param \Magento\Framework\Event\Observer $observer
* #return void
*/
public function execute(
\Magento\Framework\Event\Observer $observer
) {
$product = $observer->getEvent()->getProduct();
if ($product != null && !$this->_registry->registry('current_category')) {
$cats = $product->getAvailableInCategories();
if(sizeof($cats)===1){
$last = $cats[0];
}else{
end($cats);
$last = prev($cats);
}
if($last) {
$category = $this->_categoryRepository->get($last);
$this->_registry->register('current_category', $category, true);
}
}
}
}
I am using Codeigniter 3 for my development and below is the Database configuration details. I have also enabled database session, so I can store session data in the Database.
Here is my Database configuration
$active_group = 'default';
$query_builder = TRUE;
$db['default'] = array(
'dsn' => '',
'hostname' => 'localhost',
'username' => 'root',
'password' => '',
'database' => 'tel',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => FALSE,
'db_debug' => TRUE,
'cache_on' => TRUE,
'cachedir' => '/application/cache',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'encrypt' => TRUE,
'compress' => TRUE,
'stricton' => FALSE,
'failover' => array(),
'save_queries' => TRUE
);
After enabling sessions, I get an exception
An uncaught Exception was encountered
Type: Exception
Message: Configured database connection has cache enabled. Aborting.
Filename: D:\My data\project\wamp\www\fertilize\system\libraries\Session\drivers\Session_database_driver.php
Line Number: 98
Backtrace:
File: D:\My data\project\wamp\www\fertilize\application\core\MY_Controller.php
Line: 11
Function: __construct
File: D:\My data\project\wamp\www\fertilize\application\libraries\Main_Controller.php
I am not sure what is the reason for this, please help.
Above exception is not an error but a Codeigniter 3 security feature built into the framework. If you check system/Session/drivers/Session_database_driver.php, you can see this exception in the code along with few other exceptions.
public function __construct(&$params)
{
parent::__construct($params);
$CI =& get_instance();
isset($CI->db) OR $CI->load->database();
$this->_db = $CI->db;
if ( ! $this->_db instanceof CI_DB_query_builder)
{
throw new Exception('Query Builder not enabled for the configured database. Aborting.');
}
elseif ($this->_db->pconnect)
{
throw new Exception('Configured database connection is persistent. Aborting.');
}
elseif ($this->_db->cache_on)
{
throw new Exception('Configured database connection has cache enabled. Aborting.');
}
$db_driver = $this->_db->dbdriver.(empty($this->_db->subdriver) ? '' : '_'.$this->_db->subdriver);
if (strpos($db_driver, 'mysql') !== FALSE)
{
$this->_platform = 'mysql';
}
elseif (in_array($db_driver, array('postgre', 'pdo_pgsql'), TRUE))
{
$this->_platform = 'postgre';
}
The reason for the exception is since you are enabling sessions(stored in the database) at the same time using database caching globally. By doing this, your session queries will save to cache posing a security risk. You can avoid this by using local database caching.
for more details on how to use local db cache - http://www.codeigniter.com/user_guide/database/caching.html?highlight=database%20cache
As a good practice make sure to create a folder call db under application/cache(application/cache/db) and use it for database cache, to separate file cache from Database cache.
If you still want to keep database caching global, you can use Redis or Memcache as session driver which will avoid session queries in database and fix your problem (http://www.codeigniter.com/user_guide/libraries/sessions.html?highlight=session%20class).
I solved by changing some code in Session_database_driver.php
<?php
/**
* CodeIgniter
*
* An open source application development framework for PHP
*
* This content is released under the MIT License (MIT)
*
* Copyright (c) 2014 - 2018, British Columbia Institute of Technology
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* #package CodeIgniter
* #author EllisLab Dev Team
* #copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
* #copyright Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
* #license http://opensource.org/licenses/MIT MIT License
* #link https://codeigniter.com
* #since Version 3.0.0
* #filesource
*/
defined('BASEPATH') or exit('No direct script access allowed');
/**
* CodeIgniter Session Database Driver
*
* #package CodeIgniter
* #subpackage Libraries
* #category Sessions
* #author Andrey Andreev
* #link https://codeigniter.com/user_guide/libraries/sessions.html
*/
class CI_Session_database_driver extends CI_Session_driver implements SessionHandlerInterface
{
/**
* DB object
*
* #var object
*/
protected $_db;
/**
* Row exists flag
*
* #var bool
*/
protected $_row_exists = FALSE;
/**
* Lock "driver" flag
*
* #var string
*/
protected $_platform;
// ------------------------------------------------------------------------
/**
* Class constructor
*
* #param array $params Configuration parameters
* #return void
*/
public function __construct(&$params)
{
parent::__construct($params);
$CI = &get_instance();
isset($CI->db) or $CI->load->database();
$this->_db = $CI->db;
if (!$this->_db instanceof CI_DB_query_builder) {
throw new Exception('Query Builder not enabled for the configured database. Aborting.');
} elseif ($this->_db->pconnect) {
throw new Exception('Configured database connection is persistent. Aborting.');
} elseif ($this->_db->cache_on) {
//20210908 - MP - Removed check on cache active. Managed to disabled cache just before running session queries, reactivating cache after that
//throw new Exception('Configured database connection has cache enabled. Aborting.');
}
$db_driver = $this->_db->dbdriver . (empty($this->_db->subdriver) ? '' : '_' . $this->_db->subdriver);
if (strpos($db_driver, 'mysql') !== FALSE) {
$this->_platform = 'mysql';
} elseif (in_array($db_driver, array('postgre', 'pdo_pgsql'), TRUE)) {
$this->_platform = 'postgre';
}
// Note: BC work-around for the old 'sess_table_name' setting, should be removed in the future.
if (!isset($this->_config['save_path']) && ($this->_config['save_path'] = config_item('sess_table_name'))) {
log_message('debug', 'Session: "sess_save_path" is empty; using BC fallback to "sess_table_name".');
}
}
// ------------------------------------------------------------------------
/**
* Open
*
* Initializes the database connection
*
* #param string $save_path Table name
* #param string $name Session cookie name, unused
* #return bool
*/
public function open($save_path, $name)
{
if (empty($this->_db->conn_id) && !$this->_db->db_connect()) {
return $this->_fail();
}
return $this->_success;
}
// ------------------------------------------------------------------------
/**
* Read
*
* Reads session data and acquires a lock
*
* #param string $session_id Session ID
* #return string Serialized session data
*/
public function read($session_id)
{
if ($cache_enabled = $this->_db->cache_on) {
$this->_db->cache_off();
}
if ($this->_get_lock($session_id) !== FALSE) {
// Prevent previous QB calls from messing with our queries
$this->_db->reset_query();
// Needed by write() to detect session_regenerate_id() calls
$this->_session_id = $session_id;
$this->_db
->select('data')
->from($this->_config['save_path'])
->where('id', $session_id);
if ($this->_config['match_ip']) {
$this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']);
}
if (!($result = $this->_db->get()) or ($result = $result->row()) === NULL) {
// PHP7 will reuse the same SessionHandler object after
// ID regeneration, so we need to explicitly set this to
// FALSE instead of relying on the default ...
$this->_row_exists = FALSE;
$this->_fingerprint = md5('');
if ($cache_enabled) {
$this->_db->cache_on();
}
return '';
}
// PostgreSQL's variant of a BLOB datatype is Bytea, which is a
// PITA to work with, so we use base64-encoded data in a TEXT
// field instead.
$result = ($this->_platform === 'postgre')
? base64_decode(rtrim($result->data))
: $result->data;
$this->_fingerprint = md5($result);
$this->_row_exists = TRUE;
if ($cache_enabled) {
$this->_db->cache_on();
}
return $result;
}
$this->_fingerprint = md5('');
if ($cache_enabled) {
$this->_db->cache_on();
}
return '';
}
// ------------------------------------------------------------------------
/**
* Write
*
* Writes (create / update) session data
*
* #param string $session_id Session ID
* #param string $session_data Serialized session data
* #return bool
*/
public function write($session_id, $session_data)
{
if ($cache_enabled = $this->_db->cache_on) {
$this->_db->cache_off();
}
// Prevent previous QB calls from messing with our queries
$this->_db->reset_query();
// Was the ID regenerated?
if (isset($this->_session_id) && $session_id !== $this->_session_id) {
if (!$this->_release_lock() or !$this->_get_lock($session_id)) {
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_fail();
}
$this->_row_exists = FALSE;
$this->_session_id = $session_id;
} elseif ($this->_lock === FALSE) {
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_fail();
}
if ($this->_row_exists === FALSE) {
$insert_data = array(
'id' => $session_id,
'ip_address' => $_SERVER['REMOTE_ADDR'],
'timestamp' => time(),
'data' => ($this->_platform === 'postgre' ? base64_encode($session_data) : $session_data)
);
if ($this->_db->insert($this->_config['save_path'], $insert_data)) {
$this->_fingerprint = md5($session_data);
$this->_row_exists = TRUE;
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_success;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_fail();
}
$this->_db->where('id', $session_id);
if ($this->_config['match_ip']) {
$this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']);
}
$update_data = array('timestamp' => time());
if ($this->_fingerprint !== md5($session_data)) {
$update_data['data'] = ($this->_platform === 'postgre')
? base64_encode($session_data)
: $session_data;
}
if ($this->_db->update($this->_config['save_path'], $update_data)) {
$this->_fingerprint = md5($session_data);
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_success;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_fail();
}
// ------------------------------------------------------------------------
/**
* Close
*
* Releases locks
*
* #return bool
*/
public function close()
{
return ($this->_lock && !$this->_release_lock())
? $this->_fail()
: $this->_success;
}
// ------------------------------------------------------------------------
/**
* Destroy
*
* Destroys the current session.
*
* #param string $session_id Session ID
* #return bool
*/
public function destroy($session_id)
{
if ($cache_enabled = $this->_db->cache_on) {
$this->_db->cache_off();
}
if ($this->_lock) {
// Prevent previous QB calls from messing with our queries
$this->_db->reset_query();
$this->_db->where('id', $session_id);
if ($this->_config['match_ip']) {
$this->_db->where('ip_address', $_SERVER['REMOTE_ADDR']);
}
if (!$this->_db->delete($this->_config['save_path'])) {
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_fail();
}
}
if ($this->close() === $this->_success) {
$this->_cookie_destroy();
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_success;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return $this->_fail();
}
// ------------------------------------------------------------------------
/**
* Garbage Collector
*
* Deletes expired sessions
*
* #param int $maxlifetime Maximum lifetime of sessions
* #return bool
*/
public function gc($maxlifetime)
{
if ($cache_enabled = $this->_db->cache_on) {
$this->_db->cache_off();
}
// Prevent previous QB calls from messing with our queries
$this->_db->reset_query();
$ret = $this->_db->delete($this->_config['save_path'], 'timestamp < ' . (time() - $maxlifetime));
if ($cache_enabled) {
$this->_db->cache_on();
}
return ($ret)
? $this->_success
: $this->_fail();
}
// ------------------------------------------------------------------------
/**
* Get lock
*
* Acquires a lock, depending on the underlying platform.
*
* #param string $session_id Session ID
* #return bool
*/
protected function _get_lock($session_id)
{
if ($cache_enabled = $this->_db->cache_on) {
$this->_db->cache_off();
}
if ($this->_platform === 'mysql') {
$arg = md5($session_id . ($this->_config['match_ip'] ? '_' . $_SERVER['REMOTE_ADDR'] : ''));
if ($this->_db->query("SELECT GET_LOCK('" . $arg . "', 300) AS ci_session_lock")->row()->ci_session_lock) {
$this->_lock = $arg;
if ($cache_enabled) {
$this->_db->cache_on();
}
return TRUE;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return FALSE;
} elseif ($this->_platform === 'postgre') {
$arg = "hashtext('" . $session_id . "')" . ($this->_config['match_ip'] ? ", hashtext('" . $_SERVER['REMOTE_ADDR'] . "')" : '');
if ($this->_db->simple_query('SELECT pg_advisory_lock(' . $arg . ')')) {
$this->_lock = $arg;
if ($cache_enabled) {
$this->_db->cache_on();
}
return TRUE;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return FALSE;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return parent::_get_lock($session_id);
}
// ------------------------------------------------------------------------
/**
* Release lock
*
* Releases a previously acquired lock
*
* #return bool
*/
protected function _release_lock()
{
if (!$this->_lock) {
return TRUE;
}
if ($cache_enabled = $this->_db->cache_on) {
$this->_db->cache_off();
}
if ($this->_platform === 'mysql') {
if ($this->_db->query("SELECT RELEASE_LOCK('" . $this->_lock . "') AS ci_session_lock")->row()->ci_session_lock) {
$this->_lock = FALSE;
if ($cache_enabled) {
$this->_db->cache_on();
}
return TRUE;
}
return FALSE;
} elseif ($this->_platform === 'postgre') {
if ($this->_db->simple_query('SELECT pg_advisory_unlock(' . $this->_lock . ')')) {
$this->_lock = FALSE;
if ($cache_enabled) {
$this->_db->cache_on();
}
return TRUE;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return FALSE;
}
if ($cache_enabled) {
$this->_db->cache_on();
}
return parent::_release_lock();
}
}
Simply, just go to config/database.php and set $db['default']['pconnect'] = FALSE;
I am getting error in admin panel after adding plugin.
Error :
Fatal error: Call to a member function toOptionArray() on a non-object in /var/lib/openshift/5374ca8999fc775bdc00009d/app-root/runtime/repo/php/app/code/core/Mage/Adminhtml/Block/System/Config/Form.php on line 463
Here is the code :
public function toOptionArray() {
return array(
array('value'=>'0', 'label'=>'No Credit'),
array('value'=>'1', 'label'=>'Credit Only Invited Customer'),
array('value'=>'2', 'label'=>'Credit Only Customer who invite'),
array('value'=>'3', 'label'=>'Credit Both Customer')
);
Form.php file :
<?php
class Mage_Adminhtml_Block_System_Config_Form extends Mage_Adminhtml_Block_Widget_Form
{
const SCOPE_DEFAULT = 'default';
const SCOPE_WEBSITES = 'websites';
const SCOPE_STORES = 'stores';
/**
* Config data array
*
* #var array
*/
protected $_configData;
/**
* Adminhtml config data instance
*
* #var Mage_Adminhtml_Model_Config_Data
*/
protected $_configDataObject;
/**
* Enter description here...
*
* #var Varien_Simplexml_Element
*/
protected $_configRoot;
/**
* Enter description here...
*
* #var Mage_Adminhtml_Model_Config
*/
protected $_configFields;
/**
* Enter description here...
*
* #var Mage_Adminhtml_Block_System_Config_Form_Fieldset
*/
protected $_defaultFieldsetRenderer;
/**
* Enter description here...
*
* #var Mage_Adminhtml_Block_System_Config_Form_Field
*/
protected $_defaultFieldRenderer;
/**
* Enter description here...
*
* #var array
*/
protected $_fieldsets = array();
/**
* Translated scope labels
*
* #var array
*/
protected $_scopeLabels = array();
/**
* Enter description here...
*
*/
public function __construct()
{
parent::__construct();
$this->_scopeLabels = array(
self::SCOPE_DEFAULT => Mage::helper('adminhtml')->__('[GLOBAL]'),
self::SCOPE_WEBSITES => Mage::helper('adminhtml')->__('[WEBSITE]'),
self::SCOPE_STORES => Mage::helper('adminhtml')->__('[STORE VIEW]'),
);
}
/**
* Enter description here...
*
* #return Mage_Adminhtml_Block_System_Config_Form
*/
protected function _initObjects()
{
/** #var $_configDataObject Mage_Adminhtml_Model_Config_Data */
$this->_configDataObject = Mage::getSingleton('adminhtml/config_data');
$this->_configRoot = $this->_configDataObject->getConfigRoot();
$this->_configData = $this->_configDataObject->load();
$this->_configFields = Mage::getSingleton('adminhtml/config');
$this->_defaultFieldsetRenderer = Mage::getBlockSingleton('adminhtml/system_config_form_fieldset');
$this->_defaultFieldRenderer = Mage::getBlockSingleton('adminhtml/system_config_form_field');
return $this;
}
/**
* Enter description here...
*
* #return Mage_Adminhtml_Block_System_Config_Form
*/
public function initForm()
{
$this->_initObjects();
$form = new Varien_Data_Form();
$sections = $this->_configFields->getSection(
$this->getSectionCode(),
$this->getWebsiteCode(),
$this->getStoreCode()
);
if (empty($sections)) {
$sections = array();
}
foreach ($sections as $section) {
/* #var $section Varien_Simplexml_Element */
if (!$this->_canShowField($section)) {
continue;
}
foreach ($section->groups as $groups){
$groups = (array)$groups;
usort($groups, array($this, '_sortForm'));
foreach ($groups as $group){
/* #var $group Varien_Simplexml_Element */
if (!$this->_canShowField($group)) {
continue;
}
$this->_initGroup($form, $group, $section);
}
}
}
$this->setForm($form);
return $this;
}
/**
* Init config group
*
* #param Varien_Data_Form $form
* #param Varien_Simplexml_Element $group
* #param Varien_Simplexml_Element $section
* #param Varien_Data_Form_Element_Fieldset|null $parentElement
*/
protected function _initGroup($form, $group, $section, $parentElement = null)
{
if ($group->frontend_model) {
$fieldsetRenderer = Mage::getBlockSingleton((string)$group->frontend_model);
} else {
$fieldsetRenderer = $this->_defaultFieldsetRenderer;
}
$fieldsetRenderer->setForm($this)
->setConfigData($this->_configData);
if ($this->_configFields->hasChildren($group, $this->getWebsiteCode(), $this->getStoreCode())) {
$helperName = $this->_configFields->getAttributeModule($section, $group);
$fieldsetConfig = array('legend' => Mage::helper($helperName)->__((string)$group->label));
if (!empty($group->comment)) {
$fieldsetConfig['comment'] = Mage::helper($helperName)->__((string)$group->comment);
}
if (!empty($group->expanded)) {
$fieldsetConfig['expanded'] = (bool)$group->expanded;
}
$fieldset = new Varien_Data_Form_Element_Fieldset($fieldsetConfig);
$fieldset->setId($section->getName() . '_' . $group->getName())
->setRenderer($fieldsetRenderer)
->setGroup($group);
if ($parentElement) {
$fieldset->setIsNested(true);
$parentElement->addElement($fieldset);
} else {
$form->addElement($fieldset);
}
$this->_prepareFieldOriginalData($fieldset, $group);
$this->_addElementTypes($fieldset);
$this->_fieldsets[$group->getName()] = $fieldset;
if ($group->clone_fields) {
if ($group->clone_model) {
$cloneModel = Mage::getModel((string)$group->clone_model);
} else {
Mage::throwException($this->__('Config form fieldset clone model required to be able to clone fields'));
}
foreach ($cloneModel->getPrefixes() as $prefix) {
$this->initFields($fieldset, $group, $section, $prefix['field'], $prefix['label']);
}
} else {
$this->initFields($fieldset, $group, $section);
}
}
}
/**
* Return dependency block object
*
* #return Mage_Adminhtml_Block_Widget_Form_Element_Dependence
*/
protected function _getDependence()
{
if (!$this->getChild('element_dependense')){
$this->setChild('element_dependense',
$this->getLayout()->createBlock('adminhtml/widget_form_element_dependence'));
}
return $this->getChild('element_dependense');
}
/**
* Init fieldset fields
*
* #param Varien_Data_Form_Element_Fieldset $fieldset
* #param Varien_Simplexml_Element $group
* #param Varien_Simplexml_Element $section
* #param string $fieldPrefix
* #param string $labelPrefix
* #return Mage_Adminhtml_Block_System_Config_Form
*/
public function initFields($fieldset, $group, $section, $fieldPrefix='', $labelPrefix='')
{
if (!$this->_configDataObject) {
$this->_initObjects();
}
// Extends for config data
$configDataAdditionalGroups = array();
foreach ($group->fields as $elements) {
$elements = (array)$elements;
// sort either by sort_order or by child node values bypassing the sort_order
if ($group->sort_fields && $group->sort_fields->by) {
$fieldset->setSortElementsByAttribute(
(string)$group->sort_fields->by,
$group->sort_fields->direction_desc ? SORT_DESC : SORT_ASC
);
} else {
usort($elements, array($this, '_sortForm'));
}
foreach ($elements as $element) {
if (!$this->_canShowField($element)) {
continue;
}
if ((string)$element->getAttribute('type') == 'group') {
$this->_initGroup($fieldset->getForm(), $element, $section, $fieldset);
continue;
}
/**
* Look for custom defined field path
*/
$path = (string)$element->config_path;
if (empty($path)) {
$path = $section->getName() . '/' . $group->getName() . '/' . $fieldPrefix . $element->getName();
} elseif (strrpos($path, '/') > 0) {
// Extend config data with new section group
$groupPath = substr($path, 0, strrpos($path, '/'));
if (!isset($configDataAdditionalGroups[$groupPath])) {
$this->_configData = $this->_configDataObject->extendConfig(
$groupPath,
false,
$this->_configData
);
$configDataAdditionalGroups[$groupPath] = true;
}
}
$data = $this->_configDataObject->getConfigDataValue($path, $inherit, $this->_configData);
if ($element->frontend_model) {
$fieldRenderer = Mage::getBlockSingleton((string)$element->frontend_model);
} else {
$fieldRenderer = $this->_defaultFieldRenderer;
}
$fieldRenderer->setForm($this);
$fieldRenderer->setConfigData($this->_configData);
$helperName = $this->_configFields->getAttributeModule($section, $group, $element);
$fieldType = (string)$element->frontend_type ? (string)$element->frontend_type : 'text';
$name = 'groups[' . $group->getName() . '][fields][' . $fieldPrefix.$element->getName() . '][value]';
$label = Mage::helper($helperName)->__($labelPrefix) . ' '
. Mage::helper($helperName)->__((string)$element->label);
$hint = (string)$element->hint ? Mage::helper($helperName)->__((string)$element->hint) : '';
if ($element->backend_model) {
$model = Mage::getModel((string)$element->backend_model);
if (!$model instanceof Mage_Core_Model_Config_Data) {
Mage::throwException('Invalid config field backend model: '.(string)$element->backend_model);
}
$model->setPath($path)
->setValue($data)
->setWebsite($this->getWebsiteCode())
->setStore($this->getStoreCode())
->afterLoad();
$data = $model->getValue();
}
$comment = $this->_prepareFieldComment($element, $helperName, $data);
$tooltip = $this->_prepareFieldTooltip($element, $helperName);
$id = $section->getName() . '_' . $group->getName() . '_' . $fieldPrefix . $element->getName();
if ($element->depends) {
foreach ($element->depends->children() as $dependent) {
/* #var $dependent Mage_Core_Model_Config_Element */
if (isset($dependent->fieldset)) {
$dependentFieldGroupName = (string)$dependent->fieldset;
if (!isset($this->_fieldsets[$dependentFieldGroupName])) {
$dependentFieldGroupName = $group->getName();
}
} else {
$dependentFieldGroupName = $group->getName();
}
$dependentFieldNameValue = $dependent->getName();
$dependentFieldGroup = $dependentFieldGroupName == $group->getName()
? $group
: $this->_fieldsets[$dependentFieldGroupName]->getGroup();
$dependentId = $section->getName()
. '_' . $dependentFieldGroupName
. '_' . $fieldPrefix
. $dependentFieldNameValue;
$shouldBeAddedDependence = true;
$dependentValue = (string)(isset($dependent->value) ? $dependent->value : $dependent);
if (isset($dependent['separator'])) {
$dependentValue = explode((string)$dependent['separator'], $dependentValue);
}
$dependentFieldName = $fieldPrefix . $dependent->getName();
$dependentField = $dependentFieldGroup->fields->$dependentFieldName;
/*
* If dependent field can't be shown in current scope and real dependent config value
* is not equal to preferred one, then hide dependence fields by adding dependence
* based on not shown field (not rendered field)
*/
if (!$this->_canShowField($dependentField)) {
$dependentFullPath = $section->getName()
. '/' . $dependentFieldGroupName
. '/' . $fieldPrefix
. $dependent->getName();
$dependentValueInStore = Mage::getStoreConfig($dependentFullPath, $this->getStoreCode());
if (is_array($dependentValue)) {
$shouldBeAddedDependence = !in_array($dependentValueInStore, $dependentValue);
} else {
$shouldBeAddedDependence = $dependentValue != $dependentValueInStore;
}
}
if ($shouldBeAddedDependence) {
$this->_getDependence()
->addFieldMap($id, $id)
->addFieldMap($dependentId, $dependentId)
->addFieldDependence($id, $dependentId, $dependentValue);
}
}
}
$sharedClass = '';
if ($element->shared && $element->config_path) {
$sharedClass = ' shared shared-' . str_replace('/', '-', $element->config_path);
}
$requiresClass = '';
if ($element->requires) {
$requiresClass = ' requires';
foreach (explode(',', $element->requires) as $groupName) {
$requiresClass .= ' requires-' . $section->getName() . '_' . $groupName;
}
}
$field = $fieldset->addField($id, $fieldType, array(
'name' => $name,
'label' => $label,
'comment' => $comment,
'tooltip' => $tooltip,
'hint' => $hint,
'value' => $data,
'inherit' => $inherit,
'class' => $element->frontend_class . $sharedClass . $requiresClass,
'field_config' => $element,
'scope' => $this->getScope(),
'scope_id' => $this->getScopeId(),
'scope_label' => $this->getScopeLabel($element),
'can_use_default_value' => $this->canUseDefaultValue((int)$element->show_in_default),
'can_use_website_value' => $this->canUseWebsiteValue((int)$element->show_in_website),
));
$this->_prepareFieldOriginalData($field, $element);
if (isset($element->validate)) {
$field->addClass($element->validate);
}
if (isset($element->frontend_type)
&& 'multiselect' === (string)$element->frontend_type
&& isset($element->can_be_empty)
) {
$field->setCanBeEmpty(true);
}
$field->setRenderer($fieldRenderer);
if ($element->source_model) {
// determine callback for the source model
$factoryName = (string)$element->source_model;
$method = false;
if (preg_match('/^([^:]+?)::([^:]+?)$/', $factoryName, $matches)) {
array_shift($matches);
list($factoryName, $method) = array_values($matches);
}
$sourceModel = Mage::getSingleton($factoryName);
if ($sourceModel instanceof Varien_Object) {
$sourceModel->setPath($path);
}
if ($method) {
if ($fieldType == 'multiselect') {
$optionArray = $sourceModel->$method();
} else {
$optionArray = array();
foreach ($sourceModel->$method() as $value => $label) {
$optionArray[] = array('label' => $label, 'value' => $value);
}
}
} else {
$optionArray = $sourceModel->toOptionArray($fieldType == 'multiselect');
}
$field->setValues($optionArray);
}
}
}
return $this;
}
/**
* Return config root node for current scope
*
* #return Varien_Simplexml_Element
*/
public function getConfigRoot()
{
if (empty($this->_configRoot)) {
$this->_configRoot = Mage::getSingleton('adminhtml/config_data')->getConfigRoot();
}
return $this->_configRoot;
}
/**
* Set "original_data" array to the element, composed from nodes with scalar values
*
* #param Varien_Data_Form_Element_Abstract $field
* #param Varien_Simplexml_Element $xmlElement
*/
protected function _prepareFieldOriginalData($field, $xmlElement)
{
$originalData = array();
foreach ($xmlElement as $key => $value) {
if (!$value->hasChildren()) {
$originalData[$key] = (string)$value;
}
}
$field->setOriginalData($originalData);
}
/**
* Support models "getCommentText" method for field note generation
*
* #param Mage_Core_Model_Config_Element $element
* #param string $helper
* #return string
*/
protected function _prepareFieldComment($element, $helper, $currentValue)
{
$comment = '';
if ($element->comment) {
$commentInfo = $element->comment->asArray();
if (is_array($commentInfo)) {
if (isset($commentInfo['model'])) {
$model = Mage::getModel($commentInfo['model']);
if (method_exists($model, 'getCommentText')) {
$comment = $model->getCommentText($element, $currentValue);
}
}
} else {
$comment = Mage::helper($helper)->__($commentInfo);
}
}
return $comment;
}
/**
* Prepare additional comment for field like tooltip
*
* #param Mage_Core_Model_Config_Element $element
* #param string $helper
* #return string
*/
protected function _prepareFieldTooltip($element, $helper)
{
if ($element->tooltip) {
return Mage::helper($helper)->__((string)$element->tooltip);
} elseif ($element->tooltip_block) {
return $this->getLayout()->createBlock((string)$element->tooltip_block)->toHtml();
}
return '';
}
/**
* Append dependence block at then end of form block
*
*
*/
protected function _afterToHtml($html)
{
if ($this->_getDependence()) {
$html .= $this->_getDependence()->toHtml();
}
$html = parent::_afterToHtml($html);
return $html;
}
/**
* Enter description here...
*
* #param Varien_Simplexml_Element $a
* #param Varien_Simplexml_Element $b
* #return boolean
*/
protected function _sortForm($a, $b)
{
return (int)$a->sort_order < (int)$b->sort_order ? -1 : ((int)$a->sort_order > (int)$b->sort_order ? 1 : 0);
}
/**
* Enter description here...
*
* #param Varien_Simplexml_Element $field
* #return boolean
*/
public function canUseDefaultValue($field)
{
if ($this->getScope() == self::SCOPE_STORES && $field) {
return true;
}
if ($this->getScope() == self::SCOPE_WEBSITES && $field) {
return true;
}
return false;
}
/**
* Enter description here...
*
* #param Varien_Simplexml_Element $field
* #return boolean
*/
public function canUseWebsiteValue($field)
{
if ($this->getScope() == self::SCOPE_STORES && $field) {
return true;
}
return false;
}
/**
* Checking field visibility
*
* #param Varien_Simplexml_Element $field
* #return bool
*/
protected function _canShowField($field)
{
$ifModuleEnabled = trim((string)$field->if_module_enabled);
if ($ifModuleEnabled && !Mage::helper('Core')->isModuleEnabled($ifModuleEnabled)) {
return false;
}
switch ($this->getScope()) {
case self::SCOPE_DEFAULT:
return (int)$field->show_in_default;
break;
case self::SCOPE_WEBSITES:
return (int)$field->show_in_website;
break;
case self::SCOPE_STORES:
return (int)$field->show_in_store;
break;
}
return true;
}
/**
* Retrieve current scope
*
* #return string
*/
public function getScope()
{
$scope = $this->getData('scope');
if (is_null($scope)) {
if ($this->getStoreCode()) {
$scope = self::SCOPE_STORES;
} elseif ($this->getWebsiteCode()) {
$scope = self::SCOPE_WEBSITES;
} else {
$scope = self::SCOPE_DEFAULT;
}
$this->setScope($scope);
}
return $scope;
}
/**
* Retrieve label for scope
*
* #param Mage_Core_Model_Config_Element $element
* #return string
*/
public function getScopeLabel($element)
{
if ($element->show_in_store == 1) {
return $this->_scopeLabels[self::SCOPE_STORES];
} elseif ($element->show_in_website == 1) {
return $this->_scopeLabels[self::SCOPE_WEBSITES];
}
return $this->_scopeLabels[self::SCOPE_DEFAULT];
}
/**
* Get current scope code
*
* #return string
*/
public function getScopeCode()
{
$scopeCode = $this->getData('scope_code');
if (is_null($scopeCode)) {
if ($this->getStoreCode()) {
$scopeCode = $this->getStoreCode();
} elseif ($this->getWebsiteCode()) {
$scopeCode = $this->getWebsiteCode();
} else {
$scopeCode = '';
}
$this->setScopeCode($scopeCode);
}
return $scopeCode;
}
/**
* Get current scope code
*
* #return int|string
*/
public function getScopeId()
{
$scopeId = $this->getData('scope_id');
if (is_null($scopeId)) {
if ($this->getStoreCode()) {
$scopeId = Mage::app()->getStore($this->getStoreCode())->getId();
} elseif ($this->getWebsiteCode()) {
$scopeId = Mage::app()->getWebsite($this->getWebsiteCode())->getId();
} else {
$scopeId = '';
}
$this->setScopeId($scopeId);
}
return $scopeId;
}
/**
* Enter description here...
*
* #return array
*/
protected function _getAdditionalElementTypes()
{
return array(
'export' => Mage::getConfig()->getBlockClassName('adminhtml/system_config_form_field_export'),
'import' => Mage::getConfig()->getBlockClassName('adminhtml/system_config_form_field_import'),
'allowspecific' => Mage::getConfig()
->getBlockClassName('adminhtml/system_config_form_field_select_allowspecific'),
'image' => Mage::getConfig()->getBlockClassName('adminhtml/system_config_form_field_image'),
'file' => Mage::getConfig()->getBlockClassName('adminhtml/system_config_form_field_file')
);
}
/**
* Temporary moved those $this->getRequest()->getParam('blabla') from the code accross this block
* to getBlala() methods to be later set from controller with setters
*/
/**
* Enter description here...
*
* #TODO delete this methods when {^see above^} is done
* #return string
*/
public function getSectionCode()
{
return $this->getRequest()->getParam('section', '');
}
/**
* Enter description here...
*
* #TODO delete this methods when {^see above^} is done
* #return string
*/
public function getWebsiteCode()
{
return $this->getRequest()->getParam('website', '');
}
/**
* Enter description here...
*
* #TODO delete this methods when {^see above^} is done
* #return string
*/
public function getStoreCode()
{
return $this->getRequest()->getParam('store', '');
}
}
Guide me how to resolve this.
Thanks in advance
Since you did not provide any code I can break down the basics.
That error means the object is empty.
If your code looked like this for example.
$results->toOptionArray()
Then the error is telling you $results is not an instance of an object.