Manipulate Zend_Paginator Data - php

I want to add product variations to my product view table which uses the Zend_Paginator.
With this code I get my products.
$select = $productModel->select() ... (so on)
With this code I create the paginator
$adapter = new Zend_Paginator_Adapter_DbSelect($select);
$paginator = new Zend_Paginator($adapter);
And now I'm trying to add the product_variationsto the product data. I was trying to do this:
foreach($paginator as $key => $product) {
// get variations
$variations = $productModel->getProductVariants($product['ID']);
// overwrite $product add variations
$product['Variations'] = $variations;
$paginator->$key = $product;
}
But in my view controller only the product_data will be shown. The array (Variations) is missing.
How can I handle this?
TIA
FRGTV10

See this: Adding items to a paginator already created.
foreach($paginator as $key => &$product) {
// get variations
$variations = $productModel->getProductVariants($product['ID']);
// overwrite $product add variations
$product['Variations'] = $variations;
}
unset($product);
Notice the & in foreach() - pass by reference. Then you change the referenced $product and don't need to assign anything back to $paginator.

Related

How to update Prestashop product state programically?

I trying to learn PS and i want to simple update all Prestsahop products state by external script.
I have something like this to disable all products by the supplier (example):
<?php
include(dirname(__FILE__).'/config/config.inc.php');
include(dirname(__FILE__).'/init.php');
$default_lang = Configuration::get('PS_LANG_DEFAULT');
$product = new Product();
if ($product->id_supplier = 2) {
$product->active = 0;
$product->update();
}
But it failed throwing PrestaShopDatabaseException
It seems that you create a new product and don't fill the required fields. If you want to change the existing product you need to set its id during a product object creation.
So your code should be like
$product = new Product($id_product, true, $default_lang); // if you want to get certain language, if ont skip the last parameter
if ($product->id_supplier = 2) {
$product->active = 0;
$product->update();
}
as i understood you want to disable all products for a specific supplier
first you want to get list of all product ids from table ps_product in database. then instantiate a product object by each id_product and disable it if it has the id_supplier condition that you mentioned
require(dirname(__FILE__).'/../config/config.inc.php');
// getting list of product_id
$product_ids = Db::getInstance()->executeS('select id_product from ps_product');
foreach($product_ids as $item) {
$product = new Product($item['id_product']);
if ($product->id_supplier == 2) {
$product->active = false;
$product->update();
}
}

Create a new Prestashop cart in custom php

In Prestashop, I've created a custom form where I show a list with all products and the user can fill the corresponding quantities. By submitting the form, I clear the cart and fill it with the new values and finally redirect to the checkout page.
Everything's working fine, but only when the cart already exists. In a case of an empty cart (cart_id==null), I cannot add the products. I tried with several ways to create a $cart but I didn't manage to do so.
I don't get any exceptions, the code is executed without errors, it's just that at the end, in the checkout page, the cart remains empty; I repeat, only when the cart was already empty. In the case of a cart with products in it, then the process is just perfect!
I would appreciate some help on this.
Here is my small controller that gets the products and quantities from the form and adds them in the cart:
include('../../config/config.inc.php');
include('../../header.php');
// Filling the array of products
$products = array();
foreach ($_POST as $key => $value)
if (substr($key, 0, 9) === 'quantity_')
$products[substr($key, 9)] = $value;
// First of all, we remove all products
$prods = $cart->getProducts();
foreach ($prods as $prod)
$cart->deleteProduct($prod['id_product']);
// Adding the new products
foreach ($products as $product_id => $quantity)
if ($quantity > 0)
$cart->updateQty($quantity, $product_id);
// Redirecting to the checkout page.
header("Location: " . $_POST['redirect']);
exit();`
Thank you in advance!
I had the same problem with Prestashop not correctly creating a new cart upon calling the CartCore in many different ways - neither context or direct calls did work out.
Found this gem from someone else over here:
// get cart id if exists
if ($this->context->cookie->id_cart)
{
$cart = new Cart($this->context->cookie->id_cart);
}
// create new cart if needed
if (!isset($cart) OR !$cart->id)
{
$cart = new Cart();
$cart->id_customer = (int)($this->context->cookie->id_customer);
$cart->id_address_delivery = (int) (Address::getFirstCustomerAddressId($cart->id_customer));
$cart->id_address_invoice = $cart->id_address_delivery;
$cart->id_lang = (int)($this->context->cookie->id_lang);
$cart->id_currency = (int)($this->context->cookie->id_currency);
$cart->id_carrier = 1;
$cart->recyclable = 0;
$cart->gift = 0;
$cart->add();
$this->context->cookie->id_cart = (int)($cart->id);
$cart->update();
}
This is working for me now. As you see it goes a little more in depth than just asking the context to retrieve or create a new cart. hth.
You probably need to include this line when you are outside of a class
$context = Context::getContext();
And then add a cart variable that defines cart attributes ( in ur case assigns a id )
$cart = $context->cart; // gets the cart id or creates a new one
Should work fine now
BR's ( dont forget to accept the answer if it helps you :) )
As a complement to previous posts.
If you set that configuration : Configuration::updateValue('PS_CART_FOLLOWING', 1) (display the last cart of the customer instead of creating a new one each time).
You will always get the cart id $this->context->cart->id at NULL when trying to create a new cart at the customer's first log in (after creating a new account) using the following code:
if (is_null($this->context->cart)) {
$this->context->cart =
new Cart($this->context->cookie->id_cart);
}
I manage to solve the problem by adding some code to after the invalid cart creation.
/**
* Manage the possible errors when trying to create
* a new cart for a customer.
*
* The new cart is saved in the current context ($this->context->cart).
*/
private function createCart()
{
if (is_null($this->context->cart)) {
$this->context->cart =
new Cart($this->context->cookie->id_cart);
}
if (is_null($this->context->cart->id_lang)) {
$this->context->cart->id_lang = $this->context->cookie->id_lang;
}
if (is_null($this->context->cart->id_currency)) {
$this->context->cart->id_currency = $this->context->cookie->id_currency;
}
if (is_null($this->context->cart->id_customer)) {
$this->context->cart->id_customer = $this->context->cookie->id_customer;
}
if (is_null($this->context->cart->id_guest)) {
if (empty($this->context->cookie->id_guest)){
$this->context->cookie->__set(
'id_guest',
Guest::getFromCustomer($this->context->cookie->id_customer)
);
}
$this->context->cart->id_guest = $this->context->cookie->id_guest;
}
if (is_null($this->context->cart->id)) {
$this->context->cart->add();
$this->context->cookie->__set('id_cart', $this->context->cart->id);
}
}
After initializing the cart that way, I'm now able to add products to the cart with no problem.
Good success everyone

How to get a Product's Category?

New to PHP so I apologise for the apparent simplicity of this problem.
I understand that you can get a product's categories by doing this:
//load the product
$product = Mage::getModel('catalog/product')->load($productId);
//load the categories of this product
$categoryCollection = $product->getCategoryCollection();
But how to do I get just the first product of the category?
The getCategoryCollectionn function returns a Magento collection containing all of the product's categories. The items in the category collection are Magento category objects, and a category has a method (getProductsCollection) that returns a collection containing all of the products in the category. Magento collections have a fairly rich API that can be used to fetch specific items from the collection, in this case we want getFirstItem(). To put that all together:
$product = Mage::getModel('catalog/product')->load($productId);
$categoryCollection = $product->getCategoryCollection();
foreach ($categoryCollection as $category) {
$products = $category->getProductsCollection();
// Here we have the first product
$firstProduct = $products->getFirstItem();
}
If all you want is the first product in the first category for you current product, you could avoid the loop and do this instead:
$product = Mage::getModel('catalog/product')->load($productId);
$categoryCollection = $product->getCategoryCollection();
$category = $categoryCollection()->getFirstItem();
$products = $category->getProductsCollection();
// Here we have the first product
$firstProduct = $products->getFirstItem();
Note: Neigher of these code samples are particularly efficient, but without knowing exactly what you're trying to do, I can't propose a more efficient solution.
$product = Mage::getModel('catalog/product')->load($productId);
$cats = $product->getCategoryIds();
foreach ($cats as $category_id) {
$_cat = Mage::getModel('catalog/category')->load($category_id) ;
echo $_cat->getName();
}

Magento: Build custom product collection of all configurable products in stock

I'm trying to build a product collection of all configurable products which are 'in-stock' or 'is-saleable'. These require two different models to be used. My working method is:
$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')->addAttributeToFilter('type_id', array('eq' => 'configurable'));
foreach ($collectionConfigurable as $_configurableproduct) {
$product = Mage::getModel('catalog/product')->load($_configurableproduct->getId());
if ($product->isSaleable()) {
// do something
}
}
However this script is REALLY slow and I have a feeling it's wasting resources running as it will be loading and going through EVERY configurable product.
What I'm trying to achieve is to get the $collectionConfigurable and make it in-stock items only.
Another resource cites this as a method to get in stock items.
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($this->_productCollection);
But I'm not sure how to combine them or use it properly, I've tried this:
$collectionConfigurable = Mage::getResourceModel('catalog/product_collection')->addAttributeToFilter('type_id', array('eq' => 'configurable'));
$instockConfigs = Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collectionconfigurable);
This returns with the following error:
Fatal error: Call to a member function joinField() on a non-object in /srv/magento/app/code/core/Mage/CatalogInventory/Model/Resource/Stock.php on line 197
My "naive to the finer details of the stock system" approach would be to
Create a stock item collection, grabbing only the in stock items.
Use that collection to create an array of instock product IDs
Create a product collection with the configurable filter, as well as an entity_id filter using the collected product IDs
The code for that would look like this.
//create a stock item collection with a `is_in_stock` filter
$collection = Mage::getModel('cataloginventory/stock')
->getItemCollection()
->addFieldToFilter('is_in_stock');
//capture the product ids of the in stock stock items
$product_ids = array();
foreach($collection as $item)
{
$product_ids[] = $item->getProductId();
}
$products = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addFieldToFilter('entity_id',array('in'=>$product_ids))
->addFieldToFilter('type_id','configurable');
foreach($products as $product)
{
var_dump($product->getData());
}
That said, your code is slow, in part, because you're reloading each product inside the loop, generating a new series of SQL statements
$product = Mage::getModel('catalog/product')->load($_configurableproduct->getId());
Also, the addInStockFilterToCollection only works with a Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Product_Collection collection. Take a look at the doc block on the method.
/**
* Adds filtering for collection to return only in stock products
*
* #param Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Link_Product_Collection $collection
* #return Mage_CatalogInventory_Model_Stock $this
*/
public function addInStockFilterToCollection($collection)
{
$this->getResource()->setInStockFilterToCollection($collection);
return $this;
}

get quote's product attribute

Hi I'm trying to get a product attribute admin value or id (since it's multilanguage) from the cart items. I've tried many versions of code like this one:
$session = Mage::getSingleton('checkout/session');
foreach ($session->getQuote()->getAllItems() as $item) {
$_product = Mage::getModel('catalog/product')->load($item->getId());
$attribute = $_product->getAttribute('producttype');
}
But I only ever get false or null. Also how can I be sure to not get the store specific language value, but the attributes admin value/id? Maybe there's an even better way to read out the item attributes directly from the quote items without having to load the product first? Thanks in advance!
Solved with:
$session = Mage::getSingleton('checkout/session');
foreach ($session->getQuote()->getAllVisibleItems() as $_item)
{
$_product = Mage::getModel('catalog/product')->load($_item->getProductId());
$attributeId = $_product->getProducttype();
}
and comparing by value ID instead of text.
If you need to get the product's value for a specific shop, while the items in the quote belong to a different store view, you can do the folowing:
$_product = Mage::getModel('catalog/product')
->setStoreId($adminStoreId)
->load($item->getId());
$value = $_product->getData('producttype');

Categories