Magento 2 How to get category by url_key - php

I try to get a category in Magento 2.0 by it url_key.
Now I've got :
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$categoryFactory = $objectManager->create('Magento\Catalog\Model\CategoryFactory');
$category = $categoryFactory->create()
->addAttributeToFilter('url_key','my_category_url_key');
It returns me this error :
Error filtering template: Invalid method
Magento\Catalog\Model\Category\Interceptor::addAttributeToFilter(Array
( [0] => url_key [1] => my_category_url_key ) )
Thanks.

/**
* #var \Magento\Catalog\Model\CategoryFactory
****** inject in constructor ******
*/
protected $categoryFactory;
---------
---------
---------
$categories = $this->categoryFactory->create()
->getCollection()
->addAttributeToFilter('url_key','devops')
->addAttributeToSelect(['entity_id']);
echo "<pre>";
print_r($categories->getFirstItem()->getEntityId());

I know this is an old question, but in case anybody wonders...
All answers here use the ObjectManager. That's bad practice. The correct way to implement this, is as follows:
namespace Vendor\Module\Model;
use Magento\Catalog\Model\CategoryFactory;
class MyClass {
private $categoryFactory;
public function __construct(
CategoryFactory $categoryFactory
} {
$this->categoryFactory = $categoryFactory;
}
public function MyFunction() {
$categoryFactory = $this->categoryFactory->create();
$category = $categoryFactory->loadByAttribute('url_key', 'my_category_key');
$categoryId = $category->getId(); // E.g. if you want the ID.
}
In this example, category will contain the object of the category with URL-key 'my_category_key'.

addAttributeToFilter is a method of collections.
You should execute in on a category collection, not on a category instance.

Try this below code, i hope you will get your result.
<?php
$objectManagerr = \Magento\Framework\App\ObjectManager::getInstance();
$categoryFactory = $objectManagerr->create('Magento\Catalog\Model\ResourceModel\Category\CollectionFactory');
$categoryy = $categoryFactory->create()
->addAttributeToFilter('url_key','your_category_url_key')
->addAttributeToSelect('*');
foreach ($categoryy as $productt){
echo $productt->getName().'<br>';
echo $productt->getId();
}
?>

Based on your code, you missed the correct method in order to get a category via url_key.
Right now we can use method loadByAttribute, so you code should be something like this:
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$categoryFactory = $objectManager->create('Magento\Catalog\Model\CategoryFactory');
$category = $categoryFactory->create()->loadByAttribute('url_key','my_category_url_key');

Related

Get product name and price from product collection

I am trying to get product(s) name and price from product collection for that I have created a custom script for test.
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get('\Magento\Framework\App\State');
$state->setAreaCode('adminhtml');
$collection = $objectManager->create('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory')->create();
try {
echo $collection->addAttributeToSelect(['name','sku'])->getSelect();
} catch (Exception $exception) {
echo $exception->getMessage()."\n";
}
but when I run this script to check MySQL query I am getting below output:
SELECT `e`.* FROM `catalog_product_entity` AS `e`;
How can I get only product name and price instead of whole data?
As you're trying to get a product collection it's automatically going to get the main product entity table. It would need this in the query as a minimum as it needs the entity Id to be able to join with other tables to get the attributes required for the collection. You would not be able to retrieve your name attribute otherwise.
Note that this table is quite small and doesn't include any other attributes apart from the sku code.
If you dunp the data returned you'll see it doesn't actually grab all of the attributes, but it does need the main table.
If you have a specific need for only those two fields it would be better to use a custom query rather than a product collection.
I suggest you try this
public function getProductCollection()
{
$collection = $this->_productCollectionFactory->create();
$collection->addAttributeToSelect('*');
$collection->setPageSize(3); // fetching only 3 products
foreach ($productCollection as $product) {
$productPrice = $product->getPrice();
$productName = $product->getName();
}
}
Try this,
<?php
namespace BRINDA\HelloWorld\Block;
class HelloWorld extends \Magento\Framework\View\Element\Template
{
protected $productCollectionFactory;
protected $categoryFactory;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Catalog\Model\CategoryFactory $categoryFactory,
array $data = []
) {
$this->productCollectionFactory = $productCollectionFactory;
$this->categoryFactory = $categoryFactory;
parent::__construct($context, $data);
}
public function getProductCollection()
{
$collection = $this->productCollectionFactory->create();
$collection->setPageSize(3);
foreach ($collection as $product)
{
echo "<pre>";
print_r($product->getPrice());
print_r($product->getName());
}
return $collection;
}
}
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productCollection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
$collection = $productCollection->create()->addAttributeToSelect('*')->load();
foreach ($collection as $product){
echo 'Name = '.$product->getName().'<br>';
echo 'Price = '.$product->getFinalPrice().'<br>';
echo 'Url = '.$product->getProductUrl().'<br>';
echo 'Image = '.$product->getImage().'<br>';
}
?>
Try This.....

Create layered navigation with custom productcollection magento2

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!

getting information from database

i'm watching a tutorials about CMS with OOP - PHP & RainTPL
on control page : (articles.php)
<?php
require_once('globals.php');
require_once(CONTROLLERS.'ArticlesController.php');
$articlesmodel = new ArticlesModel() ;
$catsmodel = new ArticlesCatsModel();
$controller = new ArticlesController($articlesmodel,$catsmodel);
$controller->show();
?>
globals.php:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
define('ROOT',dirname(__FILE__));
define('INC',ROOT.'/includes/');
define('CORE',INC.'/core/');
define('MODELS',INC.'/models/');
define('CONTROLLERS',INC.'/controllers/');
define('LIBS',INC.'/libs/');
/*
core files
*/
require_once(CORE.'config.php');
require_once(CORE.'mysql.class.php');
require_once(CORE.'raintpl.class.php');
require_once(CORE.'system.php');
System::Store('db',new mysql());
System::Store('tpl',new RainTPL()); //class RainTPL
?>
ArticlesController.php
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once(MODELS.'ArticlesModel.php');
require_once(MODELS.'ArticlesCatsModel.php');
class ArticlesController
{
private $articlesModel; //Articles Model Object
private $articlesCatsModel; //Articles Cat Model Object
//object of ArticlesModel class
public function __construct(ArticlesModel $articlesmodel,ArticlesCatsModel $catsmodel)
{
$this->articlesModel = $articlesmodel ;
$this->articlesCatsModel = $catsmodel ;
}
public function Show()
{
// array of articles from model :D
/*
he takes object from Articlesmodel.php
like private articles model
then he call the Get function
from ArticlesModel Class
*/
$articles = $this->articlesModel->Get();
$cats = $this->articlesCatsModel->Get();
//put them inside the template after getting them
System::Get('tpl')->assign('articles',$articles) ;
System::Get('tpl')->assign('cats',$cats) ;
// show them in the templatee
System::Get('tpl')->draw('blog');
}
}
Blog Where articles should be shown
but there's no problem in Blog
the problem is that $articles = $this->articlesModel->Get(); returns blank array doesn't contain the information from DB
The ArticlesCatsModel
ArticlesCatsModel includes/model
The ArticleModel
ِArticlesModel
3: http://pastebin.com/z2dzcBVc it returns blank array even there are rows in DB
This is Template i should see the articles that i get from DB
but the result is No Articles
to check where exactly the problem
i typed
in Articles.Controller.php
$articles = $this->articlesModel->Get();
var_dump($articles).'<br/>';
$cats = $this->articlesCatsModel->Get();
print_r($cats);
and if you noticed in the picture it success when i call $cats but i return blank array of $articles
Try to replace
SELETE * FROM
with
SELECT * FROM
in your Get() method in ArticlesModel.php file.

How to create magento helper class?

I have the following magento helper class.
class CommissionJunction extends Mage_Core_Helper_Data
{
/**
* Get SKU, quantity, price and discount amount for each product in a given order
* #param object $order
* #return array
*/
private function _getOrderProductsList($order) {
$orderItems = $order->getAllItems();
$purchasedSkus = array();
$count_orderItems = count($orderItems);
for($i = 0; $i < $count_orderItems; $i++) {
$purchasedSkus[$i] = array(
'ITEM' => $orderItems[$i]['sku'],
'QTY' => number_format($orderItems[$i]['qty_ordered'],0), // no decimals
'AMT' => number_format($orderItems[$i]['price'],2) // 2 decimal places
'DCNT' => number_format(abs($orderItems[$i]['discount_amount']),2) */
);
}
return $purchasedSkus;
}
/**
* Get the Universal Data (JSON) Object for Commission Junction.
* This object contains the order details passed on to Commission Junction for reporting purposes
* on the Checkout Success / Order Confirmation page.
* Notes:
* - CID, TYPE AND CURRENCY are hard coded
* #param string $orderId
* #return JSON object Universal Data Object for Commission Junction $json_masterTmsUdp
*/
public function getCommissionJunctionUdo($orderId) {
$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
$udo = array();
$udo['CID'] = 'XXXX';
$udo['TYPE'] = 'XXXX';
$udo['CURRENCY'] = 'USD';
$udo['OID'] = $orderId;
$udo['DISCOUNT'] = number_format(abs($order->discount_amount),2);
$order_coupon_code = $order->coupon_code;
if(!is_null($order_coupon_code) && !empty($order_coupon_code)) {
$udo['COUPON'] = $order_coupon_code;
}
$udo['PRODUCTLIST'] = self::_getOrderProductsList($order);
if(Mage::getModel('core/cookie')->get('aff_commissionjunction') == 'cjafflx') {
$udo['FIRECJ'] = "TRUE";
}
else {
$udo['FIRECJ'] = "FALSE";
}
$masterTmsUdo['CJ'] = $udo;
$json_masterTmsUdo = json_encode($masterTmsUdo);
return $json_masterTmsUdo;
}
}
And I found this site where they explain how to register a helper class
http://codegento.com/2011/02/creating-a-helper-class/
The only thing I dont know its:
Where in the magento structure should I add this php class?
Where is the config.xml I should edit?
User created classes should be placed in this folder:
app/code/community
Another issue, you should use the same naming convention for your class as Magento uses i.e.
MOduleNameSpace_ComissionJunction_Helper_Data
Also the config XML should be placed in your app/code/community/ MOduleNameSpace/ComissionJunction/etc folder

How to get parent product id in magento?

I know that in Magento 1.4.2.0 one gets parent id's like so
list( $parentId ) = Mage::getModel('catalog/product_type_configurable')
->getParentIdsByChild( $product->getId() );
My question is: if I don't know what the parent is, how do I know to use the 'catalog/product_type_configurable' vs 'catalog/product_type_grouped' model to get the id?
You can just call both and offer a fall-back as it should be one or the other:
if($product->getTypeId() == "simple"){
$parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
if(!$parentIds)
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
if(isset($parentIds[0])){
$parent = Mage::getModel('catalog/product')->load($parentIds[0]);
// do stuff here
}
}
You may use:
$product->getTypeInstance();
Which will return the type object of your product
Then you can perform your:
->getParentIdsByChild()
Giving finally:
$product->getTypeInstance()->getParentIdsByChild($child->getId());
Here is another solution for magento 1.7.2
$parentIds = Mage::getSingleton('catalog/product_type_configurable')->getParentIdsByChild($mageProduct->getId());
we can use in block file,magento 2,
protected $_catalogProductTypeConfigurable;
public function __construct(
\Magento\Catalog\Block\Product\Context $context,
//for getting parent id of simple
\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $catalogProductTypeConfigurable,
array $data = []
) {
//for getting parent id of simple
$this->_catalogProductTypeConfigurable = $catalogProductTypeConfigurable;
parent::__construct($context, $data);
}
public function getProductData($id){
$parentByChild = $this->_catalogProductTypeConfigurable->getParentIdsByChild($id);
if(isset($parentByChild[0])){
//set id as parent product id...
$id = $parentByChild[0];
}
return $id;
}
You could check the type of the product with $_product->getTypeId(); and if this returns 'configurable', take the configurable model and if it returns 'grouped' take the grouped model.
Hope this helps.

Categories