I have a Magento site which will contain many attributes and attribute sets. Each category will have its own set and the customer wants the category and products view to show different attributes depending on which category it is in.
This would be easy enough to do in a switch / if statement but I don't want to hard code if possible.
My idea was to add a new property to the attributes called. 'display_on_frontend' which I could then use in a loop to see if an attribute should be displayed. Would this be possible to do?
There is a property already called Visible on Product View Page on Front-end which I initially wanted to use but when I get the attribute, it's not available in the data.
Here's the code that I am using to get the attributes on the product view
$_attributes = Mage::getModel('catalog/product_attribute_api')->items($_product->getAttributeSetId());
foreach ($_attributes as $_attribute) :
$attributeFull = Mage::getResourceModel('eav/entity_attribute_collection')
->setCodeFilter($_attribute['code'])
->getFirstItem();
endforeach;
An example response of what is returned is
[_data:protected] => Array
(
[attribute_id] => 139
[entity_type_id] => 4
[attribute_code] => safe_working_load_range_tonnes
[attribute_model] =>
[backend_model] =>
[backend_type] => int
[backend_table] =>
[frontend_model] =>
[frontend_input] => select
[frontend_label] => Safe Working Load (Tonnes)
[frontend_class] =>
[source_model] => eav/entity_attribute_source_table
[is_required] => 0
[is_user_defined] => 1
[default_value] =>
[is_unique] => 0
[note] =>
)
Does anyone have any suggestions on how to extend the attribute or on a reasonable way to address the problem?
Thank you
In the back end, when you created the attribute, there's a yes/no select that's labelled "Visible on Product View Page on Front-end".
Go to Admin > Catalog > Attributes > Manage Attributes > select your attribute "display_on_frontend" > Frontend Properties > Change "Visible on Product View Page on Front-end" to "Yes".
Then to access the value of that attribute, you can simply call:
$_product->getData("display_on_frontend");
or just use the camel-case getter:
$_product->getDisplayOnFrontend();
Related
For now I have set static pagesize in my search function, but now I need to create dropdown for user to change the pagesize from front end. For e.g like 10,20,50,100.
I got the code but it is for yii previous version.
If I had to do it I will use the following approach.
Create a Dropdown for the page sizes, you can adjust the dropdown inside the layout option of the gridview if you want it between summary text and items list or add it before the gridview. like this image, you can wrap it with div to adjust the CSS for it yourself.
The main thing to do is to include the id of the drop-down to the filterSelector option so that every time the gridview is filtered the dropdown value is also submitted and also whenever you change the dropdown.
Your GridView will look like below
GridView::widget([
'dataProvider' => $dataProvider,
'layout'=>'{summary}'.Html::activeDropDownList($searchModel, 'myPageSize', [1 => 10, 2 => 20, 50 => 50, 100 => 100],['id'=>'myPageSize'])."{items}<br/>{pager}",
'filterModel' => $searchModel,
'filterSelector' => '#myPageSize',
'columns'=>[
// your column configurations.......
]
]);
Declare a public property in the searchModel
public $myPageSize
Add that property to the safe rules inside your searchModel
[['myPageSize'],'safe']
And then update you search() method inside the relative SearchModel you are using with the GridView. You should assign the pageSize option of the query inside the $dataProvider with the new property defined but make sure you add this line after the $this->load($params) statement.
See below
$dataProvider->pagination->pageSize = ($this->myPageSize !== NULL) ? $this->myPageSize : 10;`
Here we are setting the default page size equal to the minimum option inside the drop-down we created, otherwise it would be updated when ever you change the dropdown.
Now try changing the dropdown you will see it working. Hope this helps
Thank you Muhammad!
Your answer helped me, but on the layout I had to modify the array for the select:
Where you have "1 => 10, 2 => 20," I had to change it to "10 => 10, 20 => 20,". Otherwise it pagination goes one by one or two by two.
It ended up like this:
'layout'=>'{summary}'.Html::activeDropDownList($searchModel, 'myPageSize', [10 => 10, 20 => 20, 50 => 50, 100 => 100],['id'=>'myPageSize'])."{items}<br/>{pager}",
The rest worked perfect!
I'm a trying to create a module in Magento that will allow the admin to select products and categories that are eligible for a discount on shipping when using a specific shipping method.
I began by making a custom section in System->Config and adding an enable/disable option using the system.xml file for each product individually. When the rate for the shipping method is calculated, I would scan the items in the cart and if one was enabled in the admin, the discount would be applied.
My problem is that this method is only really feasible for stores with a small amount of products. I suspect that there is a better way to solve this problem within Magento, but I have not had much luck finding any information on the topic so far. Is there a better way to accomplish this task?
1) Create an attribute 'eligible_for_discount' with options Yes/No
2) Create a CSV file having product_id and assign attribute 'eligible_for_discount' with values 'Yes/No' (i.e. 1 or 0) to whichever products you want to have discount applied.
3) Import the CSV file from Magento Admin.
4) On the cart page you can check if the product contains the attribute value for 'eligible_for_discount' and if Yes, then apply discount.
While the other answer was great as a guide, there were a couple of things that gave me some trouble that I want to try and clarify. I decided to create a product attribute using an install script. I placed the following code in my mysql4-install-0.1.0.php file:
$entity = $this->getEntityTypeId('catalog_product');
$this->addAttribute($entity, 'reduced_shipping', array(
'type' => 'varchar',
'input' => 'boolean',
'label' => 'Product Qualified For Free Shipping',
'visible' => true,
'default' => '0',
'required' => true,
'used_in_forms' => array(
'adminhtml_checkout',
'adminhtml_customer',
'admin_html_customer_address',
'checkout_register',
'customer_account_create',
'customer_account_edit',
'customer_address_edit',
'customer_register_address',
)
));
While boolean is a valid form of input when creating attributes, it looks like it cannot be used to store the attribute type. This can be solved by using varchar instead. After the setup script has been run, the admin can go to Catalog->Manage Products, where they can select Yes or No for the Free Shipping attribute on each item.
Finally, I used the following in the collectRates() method of the Carrier that I created to cycle through the items in the customer's cart and see if the admin has selected them for free shipping.
$quote = Mage::getModel('checkout/session')->getQuote();
$itemList = $quote->getAllVisibleItems();
foreach($itemList as $item)
{
$product = Mage::getModel('catalog/product')->load($item->getProductId());
if($product->getReducedShipping() == 1)
{
//update the price of shipping here
}
}
I've skimmed over a couple things to keep this answer from getting too long, so let me know if there is any part that I can clarify.
I have my custom module in the admin. I have listed the values from the database in the grid. The values are store specific, so every row have the store_id. While listing the value, i also want to display the store name and website name in the row. How can i fetch the store_name and website name in the grid. e.g i have the store_id 5 inserted in the row.
I want the output like
Location Value Store
xyz xyz English
If you put below code in your module grid file then you are able to display Store name in your grid, here's a code
$this->addColumn(’store_id’, array(
‘header’ => Mage::helper(’sales’)->__(’Website’),
‘index’ => ‘store_id’,
‘type’ => ‘store’,
‘width’ => ‘100px’,
‘store_view’=> true,
‘display_deleted’ => true,
));
Further Information you can refer this Link
So you have store_id and you want to display the store name right ?
So use below code to get the store name
$storeId = 5;
$storeName = Mage::getModel('core/store')->load($storeId)->getName();
I'm trying to display all tier prices on category listing page (catalog/product/list.phtml) but only getting the basic price for a single product.
print_r($_product->getTierPrice());
returns:
Array
(
[0] => Array
(
[price] => 0.5000
[website_price] => 0.5000
[price_qty] => 1
[cust_group] => 32000
)
)
for each product. On the product info page it works w/o problems. Please advise.
ver. 1.5.0.1
UPDATE:
Here is the solution for the problem inspired with the answer below:
$resource = Mage::getSingleton('core/resource');
$query = 'SELECT * FROM ' . $resource->getTableName('catalog/product') . '_tier_price';
$_tier_prices = $resource->getConnection('core_read')->fetchAll($query);
var_dump($_tier_prices);
This is another way to get the tier prices
Mage::getResourceModel('catalog/product_attribute_backend_tierprice')
->loadPriceData($product_id,Mage::app()->getWebsite()->getId());
The response is array with prices
[0] => Array
(
[price_id] => 7
[website_id] => 0
[all_groups] => 1
[cust_group] => 0
[price] => 32.0000
[price_qty] => 6.0000
)
[1] => Array
(
[price_id] => 8
[website_id] => 0
[all_groups] => 1
[cust_group] => 0
[price] => 31.0000
[price_qty] => 12.0000
)
If you are looking for a Magento way:
$attribute = $_product->getResource()->getAttribute('tier_price');
if ($attribute) {
$attribute->getBackend()->afterLoad($_product);
$tierPrices = $_product->getTierPrice();
}
From /app/code/core/Mage/Catalog/Model/Product/Type/Price.php getTierPrice()
It's been a while since this was asked/answered, but I just needed to do this and found a better way, so as to not use direct database access.
As mentioned before, the $_product object by default doesn't contain the $_tierPrices on the product list page ... but if you set the tier_price value to null, it retrieves the actual values from the database and populates the object. So, wherever you need the tier prices, add:
$_product->setData('tier_price',null);
$_tierPrices = $this->getTierPrices($_product);
This should ensure the tier prices are populated in the object, so you can use it on any page.
Just keep in mind this does still incur the same performance hit as the direct db access.
All objects in Magento can potentially be created differently on different pages, and have different data in them. It might seem unintuitive at first. It happens that the db query that loads the data into the $_product object on the Item page has pretty much "all" the data in it. But for optimization purposes the $_product used on the category page only has some of the data - and if I remember correctly, it even pulls from different db tables. For example, the the query on the category page joins against the catalogindex* tables for some of the data that would normally be retrieved from the regular eav table.
I don't have any specifics to give to you but you can look at querying directly against the catalog_product_entity_tier_price table, which has all the tier pricing. At least that is the table name in my version of magento, which isn't 1.5. Side effect would be that the category page will take longer to load due to the extra query/queries.
I've tried the answers above and some others online and none of them worked so I put together a few hacks into 1 and this is how you can get it to work anywhere. I even have a custom Home Page Carousel that is pulling it like this.
1. You start off by making a connection somewhere near the top outside of the loop
$wh_resource = Mage::getSingleton('core/resource');
$wh_readConnection = $wh_resource->getConnection('core_read');
2. Get the customer id
$wh_customer = Mage::getSingleton('customer/session')->getCustomer();
$wh_id = $wh_customer->getGroupId();
3. Next we go into the loop where you have your price echo
Note: below im using a hard code of 2 because Wholesale is 2 by default. You can build your own if/else & queries
if($wh_id == 2){
//get id
$_eid = $_helper->productAttribute($_product, $_product->getId(), 'entity_id');
$wh_query = 'SELECT * FROM catalog_product_entity_group_price WHERE entity_id = '.$_eid.' LIMIT 1';
$wh_results = $wh_readConnection->fetchAll($wh_query);
//var_dump($wh_results);
/* var dump would look like this
array(1) { [0]=>
array(6) {
["value_id"]=> string(1) "1"
["entity_id"]=> string(1) "3"
["all_groups"]=> string(1) "0"
["customer_group_id"]=> string(1) "2"
["value"]=> string(6) "9.5000"
["website_id"]=> string(1) "0"
}
}
*/
$wh_price = substr($wh_results[0]["value"], 0, -2); // this damn database gives us extra 00
echo '<div class="price-box"><span class="regular-price"><span class="price">$'.$wh_price.'</span></span></div>';
} else {
//not wholesale
echo $this->getPriceHtml($_product, true);
}
Well, that's how I did it. Feel free to contact me if you need any help
Inside app/design/frontend/your_theme/default/template/catalog/product/list.phtml
add this inside the foreach loops for grid and/or list
<?php $this->setProduct(Mage::getModel('catalog/product')->setStoreId(Mage::app()->getStore()->getId())->load($_product->getId()))?>
<?php echo $this->getTierPriceHtml() ?>
Go to the Manage Attributes and edit the attributes that you want to appear.
Maybe the products don't appear in the product listing because they wasn't configured to do that, so, in the edit attribute page, check if this is activated:
Used in Product Listing
When using the Magento collection method addFieldToFilter is it possible to allow filtering by NULL values? I want to select all the products in a collection that have a custom attribute even if no value is assigned to the attribute.
I see you already found a solution, but there is also this option:
$collection->addFieldToFilter('parent_item_id', array('null' => true));
But if you want to use "NULL" => false, which DOESN'T WORK.
(and I noticed you can use elements such as "in", "nin", "eq", "neq", "gt"), you can do this:
$collection->addFieldToFilter('parent_item_id', array('neq' => 'NULL' ));
Hope this is still helpful...
This works for NOT NULL filters
$collection->addFieldToFilter('parent_item_id', array('notnull' => true));
Filtering a product collection by null/empty attributes has two possible solutions. Magento uses an INNER JOIN to grab the values of the attributes to filter. BUT if the product attribute is not assigned a value the join will fail, as a database table / relationship is missing.
Solution #1: Use addAttributeToFilter() and change the join type from "inner" (the default) to "left":
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('custom_attribute', array( ... condition options ..), 'left');
Solution #2: Make sure your custom attribute has a default value. Magento is conservative in this regard. Magento will only create the relationship between an attribute and a product if a value is given for the attribute. So in the absence of user-specified value or a default value the attribute will not be accessible for filtering a product even if the attribute appears in the product detail view under the admin panel.
Because the question does not match exactly the title of the question and I found the them multiple times by searching for a condition like: special VALUE OR NULL
If you want to filter a collection matching a VALUE OR NULL, then you can use:
$collection->addFieldToFilter('<attribute>', array(
array('eq' => '<value>'),
array('null' => true)
));
You don't need to use addFieldToFilter.
now the solution:
attributes name is known as code in magento, you just need to use the code below to get all of the products which have a specific attribute as an array
$prodsArray=Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('custom_attribute_code')
->getItems();
you can also specify certain conditions for attribute's value in addAttributeToFilter in the second parameter of addAttributeToFilter.
you can find this method in this file (for further study):
app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php