On my product.tpl in Opencart, I am trying to display a "Warranty Included" icon.
My problem is, every product on my store doesnt have a Warranty, only specific Products do. On each of my products I have a whole list of Attributes (Specifications). I was wondering if there was some PHP code that I could wrap around the image that I would be able to use an IF statement to say something like this:
Single Statement:
<?php if (products attributes "Product type = Computer") {
//Do this
} ?>
Multiple Statement:
<?php if (products attributes "Product type = Computer" & "Screen Size = 56") {
//Do this
} ?>
I know thats not the code above, but I was wondering if there was away to use PHP if statements with Opencart Attributes.
Thanks in Advance!!
Method 1 : (Dirty method)
if ($attribute_groups) {
foreach ($attribute_groups as $attribute_group) {
foreach ($attribute_group['attribute'] as $attribute) {
if($attribute['name']=='warranty' && $attribute['text']=="yes")
{
// display image
// stop the loop if you don't need it further
}
}
}
}
Method 2 : create a function in model/catalog/product.php like checkProductWarranty() which may return a Boolean value
In this method basically you need to join tables product_attribute and attribute_description on attribute_id put name="warranty" in where clause and do your thing
for reference you can see public function getProductAttributes($product_id) in the same model file
Method 1 works but it will loop through all attributes which might not be efficient thing to do
Related
I am having difficulty sorting my data results alphabetically when matching them with the User that has placed the item in their "Locker".
I have two queries; the first one searches the database for all of the items that the user placed in their 'locker', and the second query pulls the details of the item and sorts them into a list by which brand the items are.
I feel like there is a better way to do this rather than forcing the page to run the query once for each item, but am not sure the proper way to write out the mySQL in the most efficient way that works.
I think the solution would be to pull all IDs as an array, then somehow search and sort all of their associated brands in the second query.
I currently have:
//$lockerid is pulled earlier in the code based on which locker number is associated with this user
// Pull all of the items and their ids that are in this users locker
$userlockerquery= mysql_query("SELECT DISTINCT item_id FROM lockers WHERE user_id = '$profile_userid' AND locker_id ='$lockerid' ");
while($lockeritems=mysql_fetch_array($userlockerquery)){
$indi_item=$lockeritems[item_id];
$lockeritemdetails = mysql_query("SELECT DISTINCT brand FROM inventory WHERE id = '$indi_item' ");
$brands=mysql_fetch_array($lockeritemdetails );
$brandname=$brands[brand];
echo '<div>'.$brandname.'</div>';
}
Although the results do show up with all of the brands, My problem seems to be that since the query is ran once for each items id, it cannot have the list results talk to each other, and thus cannot have them ordered by ASC alphabetically, since the query is ran once per each item.
Also because of this, the DISTINCT flag does not have any effect, since it is not matching against any other results.
As an example, my results would return in divs in order of ID instead of brand, and repeating:
Nike
Puma
Puma
Converse
Rather than
Converse
Nike
Puma
Adding the ORDER BY flag to the second query did not help, so I figured I would try to ask here for some ideas. Please let me know if any other details are needed!
Maybe try something like this class. See if it will work for your needs. It's hard to check it without trying the sql queries, but provided I've written it properly, it should work.
class MyLocker
{
// Protected means that you can't use this variable outside of the functions/class
// so you can not use $myLocker->_array; It will throw an error
protected $_array;
// Construct is basically used as an auto-function. It will execute automatically
// when you create a new instance of the class so as soon as you do this:
// $myLocker = new MyLocker($_locker); you initiate the __construct
// When you label as public, you allow it to be used outside of itself
public function __construct($_array)
{
// When you set this variable, it is now open to use in all
// other functions in this class.
$this->_array = $_array;
}
// This is the method that will do everything
public function LockerContents()
{
// Loop through query. Since the $_array was set in the __construct
// it is available in this function as $this->_array
while($lockeritems = mysql_fetch_array($this->_array)){
// $brand is something we want to use in other functions but not
// outside the class so it is set here for use in the Fetch() function
$this->brand = $lockeritems['item_id'];
// We ant to use our Fetch() function to return our brand
$_brand = $this->Fetch();
// If brand available, set it to an array
if(!empty($_brand))
$array[] = $_brand;
}
if(isset($array)) {
// Sort the array
asort($array);
// Finally, we use the Display() function for the final output
$this->Display($array);
}
else { ?>
<div>Locker is empty.</div><?php
}
}
// Establish this as an in-class variable
protected $brand;
// Establish this as a public function incase we want to use it by itself
// To do so you would write $myLocker->Fetch(); outside of the class.
// Since you need $brand for this function to work, you would need to turn
// $brand from "protected" to "public" and write $myLocker->brand = 'whatever';
// before you run the $myLocker->Fetch();
public function Fetch()
{
$query = mysql_query("SELECT DISTINCT brand FROM inventory WHERE id = '".$this->brand."'");
$brands = mysql_fetch_array($query);
// Return brand
return (isset($brands['brand']))? $brands['brand']:"";
}
protected function Display($array)
{
if(is_array($array)) {
foreach($array as $object) { ?>
<div><?php echo $object; ?></div><?php
}
}
}
}
// You should be using mysqli_ or PDO for your db connections/functions.
$_locker = mysql_query("SELECT DISTINCT item_id FROM lockers WHERE user_id = '$profile_userid' AND locker_id ='$lockerid' ");
// If there are more than 0 rows, create locker.
if(mysql_num_rows($_locker) > 0) {
// Create new instance of the locker app
$myLocker = new MyLocker($_locker);
// Display the results
$myLocker->LockerContents();
}
Trying to get child of a specific category which is active. Please help. I am having trouble doing it. I'm currently able to show them all but not specifically. Would appreciate any help.
$category = Mage::getModel('catalog/category')->load(2);
$category->getChildCategories();
$tree = $category->getTreeModel();
$tree->load();
$ids = $tree->getCollection()->getAllIds();
here is code to load active category
/* Load category by id*/
$cat = Mage::getModel('catalog/category')->load($id);
/*Returns comma separated ids*/
$subcats = $cat->getChildren();
//Print out categories string
#print_r($subcats);
foreach(explode(',',$subcats) as $subCatid)
{
$_category = Mage::getModel('catalog/category')->load($subCatid);
if($_category->getIsActive())
{
$caturl = $_category->getURL();
$catname = $_category->getName();
if($_category->getImageUrl())
{
$catimg = $_category->getImageUrl();
}
echo '<h2><img src="'.$catimg.'" alt="" />'.$catname.'</h2>';
}
}
?>
hope this is sure help you.
As mentioned by mhaupt, it is faster to load a collection rather than each category in a loop. But, as far as I am concerned, there is no need to manually load the child categories. Basically this is what $category->getChildrenCategories() already does.
There is also a filter to get active categories only. Just call addIsActiveFilter() on the collection.
a.) Load active child categories via getChildren()
// 1. Get a list of all child category ids (e.g "12,23,11,42")
$subcategoryIds = $category->getChildren();
// 2. Create collection
$categoryCollection = Mage::getModel('catalog/category')->getCollection();
// 3. Add all attributes to select, otherwise you can not
// access things like $cat->getName() etc.
$categoryCollection->addAttributeToSelect('*');
// 4. Filter by ids
$categoryCollection->addIdFilter($subcategoryIds);
// 5. Add filter to collection to get active categories only
$categoryCollection->addIsActiveFilter();
b.) Load active child categories with getChildrenCategories()
// 1. Load collection
$categoryCollection= $category->getChildrenCategories();
// 2. Add filter to collection to get active categories only
$categoryCollection->addIsActiveFilter();
The collection will be loaded form the database as soon as it is accessed. If the collection is not loaded and $subcategories->count() is called only a "SELECT count(*)" will be fired against the database (in contrast to count($subcategories) which will force the collection to load itself).
Iterating the collection
foreach($categoryCollection as $category) {
echo $category->getName();
}
If you add more filters to the collection after accessing it, the collection will not load itself again automatically. To apply changes to the collection, just call $categoryCollection->load() to reload the collection from the database.
Those who are saying to use getAllChildren() instead of getChildren() are simply wrong.
Both methods return the exact same thing, with one difference, getAllChildren(true) will return an array instead of a comma delimited string. getAllChildren($bool asArray) defaults to false. My point being that either way you're going to have to use
Mage::getModel('catalog/category')->load($catId);
inside of a loop unless you use the function below.
private function fetchCatsById($onlyThese)
{
$cats = Mage::getModel('catalog/category')
->getCollection(true)
->addAttributeToSelect('*')
->addIdFilter($onlyThese)
->addAttributeToFilter('level','2')
->addIsActiveFilter();
return $cats;
}
$cats = $this->fetchCatsById($onlyThese);
The one answer liyakat wrote, should not be used in professional shops, because it raises a performance issue, because of the multiple n time loads of the category object, rather use the collection of categories for that, get all children
$cat->getAllChildren()
, then limit the category collection by the needed category ids like
$coll->addIdFilter($idFilter);
then you won't have to load n times against the database.
Please do keep in mind that loads within loops are one of the most often used bad code examples in any Magento projects and to avoid them!
Hello you will see below code
$category_model = Mage::getModel('catalog/category');
$_category = $category_model->load(13);
$all_child_categories = $category_model->getResource()->getAllChildren($_category);
print_r($all_child_categories);
If you want any number of subcategories of parent category than Click here http://magentoo.blogspot.com/2014/01/get-all-subcategories-of-parent-category-magento.html
I am using PrestaShop version 1.5.4.1
Currently, my cart has separate delete buttons for each product.
How can I remove all the products in one action? I just need to empty the cart in one click.
I have used this code in ordercontroller and call the function from themes/defaulte/shoopin-cart.tpl
public function emptybag()
{
$products = $this->getProducts();
foreach ($products as $product) {
$this->deleteProduct($product->id);
}
}
Many things :
$this->getProducts() won't work in the order controler. Use get it with the context instead
getProducts() method doesn't return product object, but a collection of product array. You can't get informations with -> use [] instead
There is your correct function :
public function emptybag()
{
$products = $this->context->cart->getProducts();
foreach ($products as $product) {
$this->context->cart->deleteProduct($product["id_product"]);
}
}
To make it easier, add your function to your overrided file of the front controler, like that you will be able to call it from everywhere in the front. Then override the init function and add these line to the end of the function (not before because we need the cart attribute to be initialised) :
if (isset($_GET['emptybag'])){
$this->emptybag();
}
Then, add a link to your template where you want :
{l s='Clear cart'}
And this is it!
To have a clean url in your navigation you can add this line after your condition "emptybag"
Tools::redirect($this->context->link->getPageLink('order', true, NULL));
to redirect page on order.
$this->context->cart->delete();
Simple!
I'm using the catalogsearch module of Magento. I have 2 stores. When searching "test" on the first one, I get 5 results. When searching "test" on the second one, I get 3 results.
I'd like to add the results of the second store (just the number of results) when I search in the first one.
I added a block and a template, all I need is the code to retrieve the number of the results in the second store, and that's where I'm stucked.
I tried to get the controller code, but it always returns me the number of results in the first store :
private function
_getStoreQuery($storeId) {
$query = Mage::helper('catalogSearch')->getQuery();
$query->setStoreId(7);
if ($query->getQueryText()) {
if (Mage::helper('catalogSearch')->isMinQueryLength())
{
$query->setId(0)
->setIsActive(1)
->setIsProcessed(1);
}
else {
if ($query->getId()) {
$query->setPopularity($query->getPopularity()+1);
}
else {
$query->setPopularity(1);
}
$query->prepare();
}
Mage::helper('catalogSearch')->checkNotes();
if (!Mage::helper('catalogSearch')->isMinQueryLength())
{
$query->save();
}
}
var_dump($query);
return $query;
}
I also tried to change the store context before, but no luck:
Mage::app()->setCurrentStore($secondStoreId);
Do you have any idea? Thanks
Probably the reason the first set of results is returned on your second try is because you are reusing the Mage_Catalogsearch_Model_Query object. You need to create a new set of results instead. Here the collection will create those, you just need to iterate through $collection to get them.
$queryText = Mage::helper('catalogSearch')->getQueryText();
$collection = Mage::getResourceModel('catalogsearch/query_collection')
->setStoreId($storeId)
->setQueryFilter($queryText);
I want to check if some products are in stock but whatever I do the isInStock() method always returns TRUE. My products are configurable products with no associated products and under the "Inventory" tab "Stock Availability" is set to "Out of Stock".
What am I doing wrong?
Thanks!
Magento has a lot of history at this point, so it's a good idea to not always
trust that method names will do what "seems obvious". Obvious now wasn't obvious a few years ago.
If you look at the following two methods on the Mage_Catalog_Model_Product class
public function isInStock()
{
return $this->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_ENABLED;
}
public function getStatus()
{
return $this->_getData('status');
}
You can see that isInStock checks the status attribute, set in the "General" section of the Product admin.
Try this instead
$stockItem = $product->getStockItem();
if($stockItem->getIsInStock())
{
//in stock!
}
else
{
//not in stock!
}
$qtyStock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty();
<?php if ((int) Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty()>0) { ?>
<?php } else {} ?>
It worked for the simple product category view.