this code is working on simple product but i want to add label on configrable product - label

getSalableQuantityDataBySku = $getSalableQuantityDataBySku;
}
/**
* #param $sku
* #return int|mixed
*/
public function test($sku)
{
$salable = $this->getSalableQuantityDataBySku->execute($sku);
$SalableQty = $salable[0]['qty'];
if ($SalableQty == 0) {
$result = "Not Available";
} else {
$result = "Available";
}
return $result;
}
}
and override the list.phtml file
/* Add Salable Qty */
/** #var AdvanceTask\Ad4\ViewModel\Output */
$viewModel = $block->getViewModel();
?>
<br/>
<span> Available Qty : <?= $block->escapeHtml($viewModel->test($_product->getSku())) ?> </span>

Related

throw new InvalidArgumentException("View [admin.product.edit_product] found.");

Applications/XAMPP/xamppfiles/htdocs/admin_panel/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php
/**
* Find the given view in the list of paths.
*
* #param string $name
* #param array $paths
* #return string
*
* #throws \InvalidArgumentException
*/
protected function findInPaths($name, $paths)
{
foreach ((array) $paths as $path) {
foreach ($this->getPossibleViewFiles($name) as $file) {
if ($this->files->exists($viewPath = $path.'/'.$file)) {
return $viewPath;
}
}
}
throw new InvalidArgumentException("View [admin.product.edit_product] found.");
}
/**
* Get an array of possible view files.
*
* #param string $name
* #return array
*/
protected function getPossibleViewFiles($name)
{
return array_map(function ($extension) use ($name) {
return str_replace('.', '/', $name).'.'.$extension;
Arguments
"View [admin.product.edit_product] found."
https://drive.google.com/file/d/11W45UPAN_6xEZx_OkrzEcHaa3AIqU7Ta/view?usp=sharing
public function editProduct(Request $request, $id=null){
if ($request->isMethod('post')) {
$data = $request->all();
/*echo "<pre>"; print_r($data); die;*/
Product::where(['id'=>$id])->update(['category_id'=>$data['category_id'],'product_name'=>$data['product_name'],'product_code'=>$data['product_code'],'product_color'=>$data['product_color'],'description'=>$data['description'],'price'=>$data['price']]);
return redirect()->back()->with('flash_message_success','Product has been updated successfully!');
}
// Get Product Details
$productDetails = Product::where(['id'=>$id])->first();
// Categories drop down start
$categories = Category::where(['parent_id'=>0])->get();
$categories_dropdown = "<option value='' selected disabled>Select</option>";
foreach($categories as $cat){
if($cat->id==$productDetails->category_id){
$selected = "selected";
}else{
$selected = "";
}
$categories_dropdown .= "<option value='".$cat->id."' ".$selected.">".$cat->name."</option>";
$sub_categories = Category::where(['parent_id'=>$cat->id])->get();
foreach ($sub_categories as $sub_cat) {
if($sub_cat->id==$productDetails->category_id){
$selected = "selected";
}else{
$selected = "";
}
$categories_dropdown .= "<option value = '".$sub_cat->id."' ".$selected."
> -- ".$sub_cat->name."</option>";
}
}
// Categories drop down ends
return view('admin.products.edit_product')->with(compact('productDetails','categories_dropdown'));
}
please help me thank

Laravel: The cart does not contain rowId ce5452f389f041ab17e46324cc050c0d

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.

Magento admin : Fatal error: Call to a member function toOptionArray() on a non-object

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.

Magento - Add custom attribute to navigation

I have the below code that creates a custom menu in Magento:
<?php
/**
* Catalog navigation
*/
class Infortis_Ultimo_Block_Navigation extends Mage_Core_Block_Template
{
//NEW:
protected $_isAccordion = FALSE;
protected $_categoryInstance = null;
/**
* Current category key
*
* #var string
*/
protected $_currentCategoryKey;
/**
* Array of level position counters
*
* #var array
*/
protected $_itemLevelPositions = array();
protected function _construct()
{
$this->addData(array(
'cache_lifetime' => false,
'cache_tags' => array(Mage_Catalog_Model_Category::CACHE_TAG, Mage_Core_Model_Store_Group::CACHE_TAG),
));
}
/**
* Get Key pieces for caching block content
*
* #return array
*/
public function getCacheKeyInfo()
{
$shortCacheId = array(
'CATALOG_NAVIGATION',
Mage::app()->getStore()->getId(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
Mage::getSingleton('customer/session')->getCustomerGroupId(),
'template' => $this->getTemplate(),
'name' => $this->getNameInLayout(),
$this->getCurrenCategoryKey()
);
$cacheId = $shortCacheId;
$shortCacheId = array_values($shortCacheId);
$shortCacheId = implode('|', $shortCacheId);
$shortCacheId = md5($shortCacheId);
$cacheId['category_path'] = $this->getCurrenCategoryKey();
$cacheId['short_cache_id'] = $shortCacheId;
return $cacheId;
}
/**
* Get current category key
*
* #return mixed
*/
public function getCurrenCategoryKey()
{
if (!$this->_currentCategoryKey) {
$category = Mage::registry('current_category');
if ($category) {
$this->_currentCategoryKey = $category->getPath();
} else {
$this->_currentCategoryKey = Mage::app()->getStore()->getRootCategoryId();
}
}
return $this->_currentCategoryKey;
}
/**
* Get catagories of current store
*
* #return Varien_Data_Tree_Node_Collection
*/
public function getStoreCategories()
{
$helper = Mage::helper('catalog/category');
return $helper->getStoreCategories();
}
/**
* Retrieve child categories of current category
*
* #return Varien_Data_Tree_Node_Collection
*/
public function getCurrentChildCategories()
{
$layer = Mage::getSingleton('catalog/layer');
$category = $layer->getCurrentCategory();
/* #var $category Mage_Catalog_Model_Category */
$categories = $category->getChildrenCategories();
$productCollection = Mage::getResourceModel('catalog/product_collection');
$layer->prepareProductCollection($productCollection);
$productCollection->addCountToCategories($categories);
return $categories;
}
/**
* Checkin activity of category
*
* #param Varien_Object $category
* #return bool
*/
public function isCategoryActive($category)
{
if ($this->getCurrentCategory()) {
return in_array($category->getId(), $this->getCurrentCategory()->getPathIds());
}
return false;
}
protected function _getCategoryInstance()
{
if (is_null($this->_categoryInstance)) {
$this->_categoryInstance = Mage::getModel('catalog/category');
}
return $this->_categoryInstance;
}
/**
* Get url for category data
*
* #param Mage_Catalog_Model_Category $category
* #return string
*/
public function getCategoryUrl($category)
{
if ($category instanceof Mage_Catalog_Model_Category) {
$url = $category->getUrl();
} else {
$url = $this->_getCategoryInstance()
->setData($category->getData())
->getUrl();
}
return $url;
}
/**
* Return item position representation in menu tree
*
* #param int $level
* #return string
*/
protected function _getItemPosition($level)
{
if ($level == 0) {
$zeroLevelPosition = isset($this->_itemLevelPositions[$level]) ? $this->_itemLevelPositions[$level] + 1 : 1;
$this->_itemLevelPositions = array();
$this->_itemLevelPositions[$level] = $zeroLevelPosition;
} elseif (isset($this->_itemLevelPositions[$level])) {
$this->_itemLevelPositions[$level]++;
} else {
$this->_itemLevelPositions[$level] = 1;
}
$position = array();
for($i = 0; $i <= $level; $i++) {
if (isset($this->_itemLevelPositions[$i])) {
$position[] = $this->_itemLevelPositions[$i];
}
}
return implode('-', $position);
}
/**
* Render category to html
*
* #param Mage_Catalog_Model_Category $category
* #param int Nesting level number
* #param boolean Whether ot not this item is last, affects list item class
* #param boolean Whether ot not this item is first, affects list item class
* #param boolean Whether ot not this item is outermost, affects list item class
* #param string Extra class of outermost list items
* #param string If specified wraps children list in div with this class
* #param boolean Whether ot not to add on* attributes to list item
* #return string
*/
protected function _renderCategoryMenuItemHtml($category, $level = 0, $isLast = false, $isFirst = false,
$isOutermost = false, $outermostItemClass = '', $childrenWrapClass = '', $noEventAttributes = false)
{
if (!$category->getIsActive()) {
return '';
}
$html = array();
// get all children
if (Mage::helper('catalog/category_flat')->isEnabled()) {
$children = (array)$category->getChildrenNodes();
$childrenCount = count($children);
} else {
$children = $category->getChildren();
$childrenCount = $children->count();
}
$hasChildren = ($children && $childrenCount);
// select active children
$activeChildren = array();
foreach ($children as $child) {
if ($child->getIsActive()) {
$activeChildren[] = $child;
}
}
$activeChildrenCount = count($activeChildren);
$hasActiveChildren = ($activeChildrenCount > 0);
// prepare list item html classes
$classes = array();
$classes[] = 'level' . $level;
$classes[] = 'nav-' . $this->_getItemPosition($level);
if ($this->isCategoryActive($category)) {
$classes[] = 'active';
}
$linkClass = '';
if ($isOutermost && $outermostItemClass) {
$classes[] = $outermostItemClass;
$linkClass = ' class="'.$outermostItemClass.'"';
}
if ($isFirst) {
$classes[] = 'first';
}
if ($isLast) {
$classes[] = 'last';
}
if ($hasActiveChildren) {
$classes[] = 'parent';
}
//NEW: add special class if level == 1 and menu is not an accordion.
if ($this->_isAccordion == FALSE && $level == 1) {
$classes[] = 'item';
}
// prepare list item attributes
$attributes = array();
if (count($classes) > 0) {
$attributes['class'] = implode(' ', $classes);
}
if ($hasActiveChildren && !$noEventAttributes) {
$attributes['onmouseover'] = 'toggleMenu(this,1)';
$attributes['onmouseout'] = 'toggleMenu(this,0)';
}
// assemble list item with attributes
$htmlLi = '<li';
foreach ($attributes as $attrName => $attrValue) {
$htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
}
$htmlLi .= '>';
$html[] = $htmlLi;
if ($level == 0 && $hasChildren) {
$html[] = '<a href="javascript:void(0)"'.$linkClass.'>';
$html[] = '<span>' . $this->escapeHtml($category->getName()) . '</span>';
$html[] = '</a>';
}
else {
$html[] = '<a href="'.$this->getCategoryUrl($category).'"'.$linkClass.'>';
$html[] = '<span>' . $this->escapeHtml($category->getName()) . '</span>';
$html[] = '</a>';
}
// render children
$htmlChildren = '';
$j = 0;
foreach ($activeChildren as $child) {
$htmlChildren .= $this->_renderCategoryMenuItemHtml(
$child,
($level + 1),
($j == $activeChildrenCount - 1),
($j == 0),
false,
$outermostItemClass,
$childrenWrapClass,
$noEventAttributes
);
$j++;
}
if (!empty($htmlChildren)) {
//NEW: add opener if menu is used as accordion.
if ($this->_isAccordion == TRUE)
$html[] = '<span class="opener"> </span>';
if ($childrenWrapClass) {
$html[] = '<div class="' . $childrenWrapClass . '">';
}
$html[] = '<ul class="level' . $level . '">';
$html[] = $htmlChildren;
$html[] = '</ul>';
if ($childrenWrapClass) {
$html[] = '</div>';
}
}
$html[] = '</li>';
$html = implode("\n", $html);
return $html;
}
/**
* Render category to html
*
* #deprecated deprecated after 1.4
* #param Mage_Catalog_Model_Category $category
* #param int Nesting level number
* #param boolean Whether ot not this item is last, affects list item class
* #return string
*/
public function drawItem($category, $level = 0, $last = false)
{
return $this->_renderCategoryMenuItemHtml($category, $level, $last);
}
/**
* Enter description here...
*
* #return Mage_Catalog_Model_Category
*/
public function getCurrentCategory()
{
if (Mage::getSingleton('catalog/layer')) {
return Mage::getSingleton('catalog/layer')->getCurrentCategory();
}
return false;
}
/**
* Enter description here...
*
* #return string
*/
public function getCurrentCategoryPath()
{
if ($this->getCurrentCategory()) {
return explode(',', $this->getCurrentCategory()->getPathInStore());
}
return array();
}
/**
* Enter description here...
*
* #param Mage_Catalog_Model_Category $category
* #return string
*/
public function drawOpenCategoryItem($category) {
$html = '';
if (!$category->getIsActive()) {
return $html;
}
$html.= '<li';
if ($this->isCategoryActive($category)) {
$html.= ' class="active"';
}
$html.= '>'."\n";
$html.= '<span>'.$this->htmlEscape($category->getName()).'</span>'."\n";
if (in_array($category->getId(), $this->getCurrentCategoryPath())){
$children = $category->getChildren();
$hasChildren = $children && $children->count();
if ($hasChildren) {
$htmlChildren = '';
foreach ($children as $child) {
$htmlChildren.= $this->drawOpenCategoryItem($child);
}
if (!empty($htmlChildren)) {
$html.= '<ul>'."\n"
.$htmlChildren
.'</ul>';
}
}
}
$html.= '</li>'."\n";
return $html;
}
/**
* Render categories menu in HTML
*
* #param bool Add opener if menu is used as accordion.
* #param int Level number for list item class to start from
* #param string Extra class of outermost list items
* #param string If specified wraps children list in div with this class
* #return string
*/
public function renderCategoriesMenuHtml($isAccordion = FALSE, $level = 0, $outermostItemClass = '', $childrenWrapClass = '')
{
//NEW: save additional attribute
$this->_isAccordion = $isAccordion;
$activeCategories = array();
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive()) {
$activeCategories[] = $child;
}
}
$activeCategoriesCount = count($activeCategories);
$hasActiveCategoriesCount = ($activeCategoriesCount > 0);
if (!$hasActiveCategoriesCount) {
return '';
}
$html = '';
$j = 0;
foreach ($activeCategories as $category) {
$html .= $this->_renderCategoryMenuItemHtml(
$category,
$level,
($j == $activeCategoriesCount - 1),
($j == 0),
true,
$outermostItemClass,
$childrenWrapClass,
true
);
$j++;
}
return $html;
}
}
I would like to add a custom category attribute (menu_label) to the menu items. I have created the custom category attribute using this tutorial http://www.atwix.com/magento/add-category-attribute/
The attribute shows up fine in admin and I can get it to print out on my normal template files but can't get it to show in this menu.
I thought $this->escapeHtml($category->getMenuLabel()) would have done it but this doesn't output anything.
Any ideas?
You have to consider the fact that Magento is not acting the same with flat categories enable or disable.
I suppose you may be with flat category enabled, in your case, because it should work otherwise.
(Please check in System > Configuration > Catalog > Catalog > Frontend the field Use Flat Catalog Category. If it is set to Yes, then that is where your problem is.)
To solve it add this to your config.xml in the frontend node:
<events>
<catalog_category_flat_loadnodes_before>
<observers>
<somemodule>
<type>singleton</type>
<class>somemodule/observer</class>
<method>addMenuAttributes</method>
</somemodule>
</observers>
</catalog_category_flat_loadnodes_before>
</events>
Then create an Observer.php in the Model folder of your module (the model folder should be declared in your config.xml too, of course).
Here is the observer code:
<?php
class Somecompany_Somemodule_Model_Observer {
public function addMenuAttributes(Varien_Event_Observer $observer) {
$observer->getSelect()->columns(
array('menu_label')
);
}
}
You assumtion is incorrect:
$this->escapeHtml($category->getMenuLabel())
This assumes $category is indeed a Category Model (Mage_Catalog_Model_category) when infact it's not, it's a Node object.
if you look here:
Mage_Catalog_Model_Observer::_addCategoriesToMenu()
You will notice where the actual catalog model is used to create an array which is passed to the Navigation routine as a Varien_Data_Tree_Node.
You can add in your custom attribute here, and then access it inside the block.
$categoryData = array(
'name' => $category->getName(),
'id' => $nodeId,
'url' => Mage::helper('catalog/category')->getCategoryUrl($category),
'is_active' => $this->_isActiveMenuCategory($category),
'my_attribute' => $category->getData('my_attribute')
);
You will then be able to access the attribute inside your custom menu block:
$child->getData('my_attribute');
//$this->escapeHtml($category->getData('my_attribute'))

Magento - Apply Tax On Custom Quote Totals Field

I have created a surcharge module for Magento which adds a custom total field to the quote. The surcharge is input into Magento including tax. I have successfully got the module adding the surcharge to the quote and the grand total is correct on the checkout page.
My issue comes when trying to apply tax to the surcharge so that it gets included and displayed in the tax field on the checkout page. Currently it only includes the tax for the products and the shipping.
I have managed to calculate the tax for the surcharge but cant't get the tax applied to the quote so that it is displayed in the tax field but also don't think my approach is quite correct either. Any help would be much appreciated.
class ********_Deposits_Model_Quote_Address_Total_Surcharge extends Mage_Sales_Model_Quote_Address_Total_Abstract {
protected $_config = null;
public function __construct()
{
$this->setCode('surcharge_price');
$this->_config = Mage::getSingleton('tax/config');
$this->_store = Mage::app()->getStore();
}
protected function _calculateTax(Mage_Sales_Model_Quote_Address $address)
{
$calculator = Mage::getSingleton('tax/calculation');
$inclTax = $this->_config->priceIncludesTax($this->_store);
$taxRateRequest = $calculator->getRateRequest(
$address,
$address->getQuote()->getBillingAddress(),
$address->getQuote()->getCustomerTaxClassId(),
$this->_store
);
$taxRateRequest->setProductClassId(Mage::getStoreConfig('********/surcharges/tax_class', $this->_store));
$rate = $calculator->getRate($taxRateRequest);
$baseTax = $tax = $calculator->calcTaxAmount($address->getBaseSurchargePriceAmount(), $rate, $inclTax, true);
}
/**
* Collect address subtotal
*
* #param ********_Surcharges_Model_Quote_Address $address
* #return ********_Surcharges_Model_Quote_Address_Total_Surcharge
*/
public function collect(Mage_Sales_Model_Quote_Address $address)
{
parent::collect($address);
$this->_setAmount(0)->_setBaseAmount(0);
// If Surcharges Is Enabled Then Calculate Away :-)
if(Mage::getStoreConfig('********/surcharges/surcharge_enabled')) {
$items = $this->_getAddressItems($address);
if (!count($items)) {
return $this;
}
// Calculate Total Surcharge For Items In Quote (Base Prices!)
$surcharge = 0.0;
foreach ($items as $item) {
$price = $item->getData('base_surcharge_price', null);
if(isset($price)) {
$surcharge += $item->getData('base_surcharge_price') * $item->getQty();
}
}
$this->_setAmount($surcharge);
$this->_setBaseAmount($surcharge);
$this->_calculateTax($address);
}
return $this;
}
public function fetch(Mage_Sales_Model_Quote_Address $address)
{
if(Mage::getStoreConfig('********/surcharges/surcharge_enabled')) {
$surcharge = $address->getSurchargePriceAmount();
if(isset($surcharge) && $surcharge > 0) {
$address->addTotal(array(
'code' => $this->getCode(),
'title' => Mage::getStoreConfig('********/surcharges/surcharge_label'),
'value' => $surcharge
));
}
}
return $this;
}
public function getLabel()
{
return Mage::getStoreConfig('********/surcharges/surcharge_label');
}
I managed to solve this this using the following code. Not the best solution but spent hours trying to do it and didn't get anywhere fast. Asterix's need to be replaced.
class *****_Deposits_Model_Quote_Address_Total_Surcharge extends Mage_Sales_Model_Quote_Address_Total_Abstract {
protected $_taxConfig = null;
public function __construct()
{
$this->setCode('surcharge_price');
$this->_taxConfig = Mage::getSingleton('tax/config');
$this->_store = Mage::app()->getStore();
}
protected function _calculateTax(Mage_Sales_Model_Quote_Address $address)
{
$calculator = Mage::getSingleton('tax/calculation');
$calculator->setCustomer($address->getQuote()->getCustomer());
$inclTax = $this->_taxConfig->priceIncludesTax($this->_store);
$taxRateRequest = $calculator->getRateRequest(
$address,
$address->getQuote()->getBillingAddress(),
$address->getQuote()->getCustomerTaxClassId(),
$this->_store
);
$taxRateRequest->setProductClassId(Mage::getStoreConfig('*****/surcharges/tax_class', $this->_store));
$rate = $calculator->getRate($taxRateRequest);
if($rate > 0.0) {
$baseTax = $calculator->calcTaxAmount($address->getBaseSurchargePriceAmount(), $rate, $inclTax, true);
$tax = $address->getQuote()->getStore()->convertPrice($baseTax, false);
$address->addTotalAmount('tax', $tax);
$address->addBaseTotalAmount('tax', $baseTax);
$rates = array();
foreach ($address->getAppliedTaxes() as $rate) {
$rate['amount'] = $rate['amount'] + $tax;
$rate['base_amount'] = $rate['base_amount'] + $baseTax;
$rates[] = $rate;
}
$address->setAppliedTaxes($rates);
if($inclTax) {
$address->setGrandTotal($address->getGrandTotal() - $tax);
$address->setBaseGrandTotal($address->getBaseGrandTotal() - $baseTax);
}
}
}
/**
* Collect address subtotal
*
* #param *****_Surcharges_Model_Quote_Address $address
* #return *****_Surcharges_Model_Quote_Address_Total_Surcharge
*/
public function collect(Mage_Sales_Model_Quote_Address $address)
{
parent::collect($address);
// Clear Cached Values As Multiple Addresses Causes Values To Be Added Twice Otherwise!
$this->_setAmount(0)->_setBaseAmount(0);
// If Surcharges Is Enabled Then Calculate Away :-)
if(Mage::getStoreConfig('*****/surcharges/surcharge_enabled')) {
$items = $this->_getAddressItems($address);
if (!count($items)) {
return $this;
}
// Calculate Total Surcharge For Items In Quote (Base Prices!)
$surcharge = 0.0;
foreach ($items as $item) {
$price = $item->getData('base_surcharge_price', null);
if(isset($price)) {
$surcharge += $item->getData('base_surcharge_price') * $item->getQty();
}
}
$this->_setAmount($address->getQuote()->getStore()->convertPrice($surcharge, false));
$this->_setBaseAmount($surcharge);
$this->_calculateTax($address);
}
return $this;
}
/**
* Assign subtotal amount and label to address object
*
* #param *****_Surcharges_Model_Quote_Address $address
* #return *****_Surcharges_Model_Quote_Address_Total_Surcharge
*/
public function fetch(Mage_Sales_Model_Quote_Address $address)
{
if(Mage::getStoreConfig('*****/surcharges/surcharge_enabled')) {
$surcharge = $address->getSurchargePriceAmount();
if(isset($surcharge) && $surcharge > 0) {
$address->addTotal(array(
'code' => $this->getCode(),
'title' => Mage::getStoreConfig('*****/surcharges/surcharge_label'),
'value' => $surcharge
));
}
}
return $this;
}
/**
* Get Surcharge label
*
* #return string
*/
public function getLabel()
{
return Mage::getStoreConfig('*****/surcharges/surcharge_label');
}
}

Resources