I would like to show "Suggestions" in my product listing in Magento. I made an attribute "Suggestion" which is Yes/No and global active. Now in the listing I would like to show the suggestions first, then some text and stuff, and then the rest of products.
I tried it like this:
$_productCollection=$this->getLoadedProductCollection()
/* .... */
$_productCollection->clear()->addAttributeToFilter('suggestion', 1)->load();
But this ends in an exception:
You cannot define a correlation name '_price_rule' more than once
Now the question is, how to solve this?
Ok, the solution for me was a custom module, which extends the List Functionality. I added the following file:
/app/code/local/Mage/Catalog/Block/Product/List.php
With the following extending code:
protected function _getProductCollectionSuggestion()
{
$layer = Mage::getSingleton('catalog/layer');
/* #var $layer Mage_Catalog_Model_Layer */
if ($this->getShowRootCategory()) {
$this->setCategoryId(Mage::app()->getStore()->getRootCategoryId());
}
// if this is a product view page
if (Mage::registry('product')) {
// get collection of categories this product is associated with
$categories = Mage::registry('product')->getCategoryCollection()
->setPage(1, 1)
->load();
// if the product is associated with any category
if ($categories->count()) {
// show products from this category
$this->setCategoryId(current($categories->getIterator()));
}
}
$origCategory = null;
if ($this->getCategoryId()) {
$category = Mage::getModel('catalog/category')->load($this->getCategoryId());
if ($category->getId()) {
$origCategory = $layer->getCurrentCategory();
$layer->setCurrentCategory($category);
}
}
$this->_productCollection = $layer->getProductCollection();
$this->_productCollection->addAttributeToFilter('suggestion', 1);
if($this->_productCollection->count()) {
foreach($this->_productCollection as $_productKey => $_product) {
if($_product->getSuggestion() == 0 || !$_product->getSuggestion()) {
}
}
}
$this->prepareSortableFieldsByCategory($layer->getCurrentCategory());
if ($origCategory) {
$layer->setCurrentCategory($origCategory);
}
return $this->_productCollection;
}
Then I loaded this method in the List.phtml and it worked :)
Thanks for reading anyway! Maybe this code helps someone!
Related
I'm using woocommerce_update_product hook to get product data once a product has been created / updated.
I'm trying to get the terms from a taxonomy called wcpv_product_vendors. On first save (as draft) I can get the other product_cat terms but the terms for wcpv_product_vendors don't appear until I next save the post.
add_action( 'woocommerce_update_product', [$this, 'dcgsql_update_product'], 50, 1);
public function dcgsql_update_product(){
$get_vendors = get_the_terms($product_id, 'wcpv_product_vendors');
if (!empty($get_vendors)) {
foreach ($get_vendors as $vendor) {
$vendorsarray[] = $vendor->term_id;
}
$vendors = implode(',',$vendorsarray);
} else {
$vendors = '';
}
}
On first save as draft, $get_vendors is always empty but I have applied one.
All other terms for product_cat are coming back fine.
Use the below codes it will work...
add_action( 'woocommerce_update_product', 'dcgsql_update_product', 50, 1);
public function dcgsql_update_product(){
$get_vendors = wp_get_post_terms($product_id, 'wcpv_product_vendors');
if (!empty($get_vendors)) {
foreach ($get_vendors as $vendor) {
$vendorsarray[] = $vendor->term_id;
}
$vendors = implode(',',$vendorsarray);
} else {
$vendors = '';
}
}
I need some help converting this code from SS3 to SS4.
I used the code below to pull my latest blog posts through to my custom homepage template. This no longer works for me in SS4. Not sure how what needs to be added to fix it.
class IndexPageController extends PageController {
public function LatestPostsHome()
{
return BlogCategory::get()
->filter('Title', 'Featured')
->relation('BlogPosts')
->sort('PublishDate', 'DESC');
}
}
Thank,
Do you have several BlogCategories with the same title?
If you only have one BlogCategory with title 'Featured' then this should work:
public function LatestPostsHome()
{
$blogCategory = BlogCategory::get()->filter('Title', 'Featured')->first();
if (!$blogCategory) {
return null;
}
// Get the corresponding has_many/many_many objects.
$blogPosts = $blogCategory->BlogPosts()->sort('PublishDate', 'DESC');
return $blogPosts;
}
If you have multiple categories with the same title, then you can maybe use something like this:
public function LatestPostsHome()
{
$blogCategories = BlogCategory::get()->filter('Title', 'Featured');
if (!$blogCategories->exists()) {
return null;
}
// Option 1 (not tested)
$categoryIDs = $blogCategories->column('ID');
$blogPosts = BlogPost::get()->byIDs($categoryIDs);
return $blogPosts;
// Option 2 (not tested)
$blogPosts = new \SilverStripe\ORM\ArrayList();
foreach ($blogCategories as $category) {
$posts = $category->BlogPosts();
$blogPosts->push($posts->toNestedArray());
}
return $blogPosts;
}
I have a block class which has:
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Helper\Category $categoryHelper,
\Magento\Catalog\Model\Indexer\Category\Flat\State $categoryFlatState,
\Magento\Catalog\Model\CategoryFactory $categoryFactory,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
....
) {
$this->_categoryHelper = $categoryHelper;
$this->_categoryFactory = $categoryFactory;
$this->_collectionFactory = $collectionFactory;
$this->categoryFlatConfig = $categoryFlatState;
$this->_productCollectionFactory = $productCollectionFactory;
parent::__construct($context);
....
}
and a function of...
public function getProductCollection($childId)
{
$categoryId = $childId;
$category = $this->_categoryFactory->create()->load($categoryId);
$collection = $this->_productCollectionFactory->create();
$collection->addAttributeToSelect('name');
$collection->addAttributeToSelect('url');
$collection->addAttributeToSelect('image');
$collection->addAttributeToSelect('price');
$collection->addAttributeToSelect('special_price');
$collection->addCategoryFilter($category);
$collection->addAttributeToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH);
$collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
return $collection;
}
How do I use this production collection to create a layered navigation which uses attributes available for the products returned, and then be able to filter through with those.
Due to the nature of the site, I have to loop through this X amount of times on a category page, as I am getting products of each subcategory on this page in a certain way due to the design.
So in my template for E.G I have:
`$products= $this->getProductCollection($idhere);
foreach ($getmeprods as $products):?>
... looping through data
<?php endforeach;?>
`
Any help would be appreciate but I am rather boggled here!
The following joomla plugin code is to select for Exclude Category from Joomla Category and I would like to know how to make it Include Category.
class plgContentExtcustomhtml extends JPlugin {
public function onContentAfterDisplay($context, &$row, &$params, $page=0) {
if($context == 'com_content.article') {
//exclude
$ext_exclude_categories = $this->params->get('ext_exclude_categories', 0);
$ext_exclude_articles = $this->params->get('ext_exclude_articles', '');
//exclude category
if(!empty($ext_exclude_categories) AND strlen(array_search($row->catid, $ext_exclude_categories))){
return false;
}
the code above is from a plugin.
It works only if the current page is to show an article and the category isnot in the excluded categories.
If you want to change the logic and force it to work only for the excluded categories, then I think that you neeed to change:
//exclude category
if(!empty($ext_exclude_categories) AND strlen(array_search($row->catid, $ext_exclude_categories))){
return false;
}
to this:
//exclude category
if(empty($ext_exclude_categories) OR !strlen(array_search($row->catid, $ext_exclude_categories))){
return false;
}
Backup your code first. :-)
I am using
{
{
block type="catalog/product_new"
name="home.catalog.product.new" alias="product_homepage"
template="catalog/product/new.phtml"
}
}
in cms page to show new products. Now it is showing only one product.
Is there any way to change it to show a specified number of products? eg : 16 products
Here is what I have:
{{block type="catalog/product_list_random" num_products="9" category_id="231" template="catalog/product/list_no_toolbar.phtml" columnCount="3"}}
num_products is the param where you say how many products to show on that page.
in app/code/local create Mage/Catalog/Block/Product/List
In your new List directory create the following file called Random.php
<?php
class Mage_Catalog_Block_Product_List_Random extends Mage_Catalog_Block_Product_List
{
protected function _getProductCollection()
{
if (is_null($this->_productCollection)) {
$categoryID = $this->getCategoryId();
if($categoryID)
{
$category = new Mage_Catalog_Model_Category();
$category->load($categoryID); // this is category id
$collection = $category->getProductCollection();
} else
{
$collection = Mage::getResourceModel('catalog/product_collection');
}
Mage::getModel('catalog/layer')->prepareProductCollection($collection);
$collection->getSelect()->order('rand()');
$collection->addStoreFilter();
$numProducts = $this->getNumProducts() ? $this->getNumProducts() : 3;
$collection->setPage(1, $numProducts)->load();
$this->_productCollection = $collection;
}
return $this->_productCollection;
}
}
$collection->getSelect()->order('rand()'); is the line that set random, you can comment this out.
Your code works fine in my site. Open /app/code/core/Mage/Catalog/Block/Product/New.php
Around line 38 you should see something like this:
const DEFAULT_PRODUCTS_COUNT = 5;
Chances are that number is set to "1". If not then look in /app/code/local/Mage/Catalog/Block/Product/New.php to make sure someone didn't create a local override of your core file.
If the number is "1" then you should create a module to change that value that extends Mage_Catalog_Block_Product_New.