Magento – php – create csv export file, based on product values

csvmagento-1.9productscript

I currently have the following script, that change the producttitle of a product with a specific ID.

Now I want to re-write the script, so that it does not update the attributes but generates a .csv file of the entire catalog with two columns.

  1. Product_SKU
  2. $productnamingseo value

How can I achieve this?

ini_set('display_errors', 'On');
error_reporting(E_ALL);

require('../app/Mage.php');
Mage::app();

$product = Mage::getModel('catalog/product')->load(409728);
Mage::register('current_product', $product);
$seotitle = Mage::helper('seo')->getCurrentSeo();
$productnamestring = Mage::getSingleton('seo/object_product')->getTitle();

        $findseo = array('/\h+inch (?:(i[357])-\w+|\h+\w+)?/', '/(\w+)#\w+/', '/(^| )(.{4,}) (.*)\2/', '/\s*-\s*$/');
        $replaceseo = array('" $1', '$1', '$1$2 $3', '');
        $productnamingseo = preg_replace($findseo, $replaceseo, $productnamestring);

$product->setName($productnamingseo);
$product->getResource()->saveAttribute($product, 'name');

EDIT already tried this, that works for only 1 product. All other products got that $productnamingseo value of product 1, instead of their own unique value.

This create a .csv file with the following output. Only the first line is correct. All other lines got the wrong $productnamingseo of the first product.

"ACER_EY.JE001.002","Acer C120 LED - EY.JE001.002"
"ALLIEDTELESIS_AT-2701FXA/SC-001","Acer C120 LED - EY.JE001.002"
"APC_0M-0213-005","Acer C120 LED - EY.JE001.002"

Script:

ini_set('display_errors', 'On');
error_reporting(E_ALL);
ini_set('memory_limit', '4G');

require('app/Mage.php');
Mage::app();

$file_path = "var/import/productname.csv";
$mage_csv = new Varien_File_Csv();

$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*')->setPageSize(1)->setCurPage(1);

foreach ($products as $product) {
    $prod = Mage::register('current_product', $product);
    $seotitle = Mage::helper('seo')->getCurrentSeo();
    $productnamestring = Mage::getSingleton('seo/object_product')->getTitle();

    $findseo = array('/\h+inch (?:(i[357])-\w+|\h+\w+)?/', '/(\w+)#\w+/', '/(^| )(.{4,}) (.*)\2/', '/\s*-\s*$/');
    $replaceseo = array('" $1', '$1', '$1$2 $3', '');
    $productnamingseo = preg_replace($findseo, $replaceseo, $productnamestring);

    echo $productnamingseo;

    $data = array();
    $data['sku'] = $product->getSku();
    $data['name'] = $productnamingseo;
    $products_row[] = $data;

    Mage::unregister('current_product')
}

$mage_csv->saveData($file_path, $products_row);
echo 'Done!';

SEO helper Mirasvit_Seo_Model_Object_Product:

public function _construct()
{
    parent::_construct();
    $this->_product = Mage::registry('current_product');
    if (!$this->_product) {
        $this->_product = Mage::registry('product');
    }
    if (!$this->_product) {
        return;
    }


    $this->_parseObjects['product'] = $this->_product;

    $this->setAdditionalVariable('product', 'url', $this->_product->getProductUrl());
    $this->setAdditionalVariable('product', 'final_price', $this->_product->getFinalPrice());
    $this->setAdditionalVariable('product', 'final_price_minimal', Mage::helper('seo')->getCurrentProductFinalPrice($this->_product));
    $this->setAdditionalVariable('product', 'final_price_range', Mage::helper('seo')->getCurrentProductFinalPriceRange($this->_product));
    $this->setAdditionalVariable('product', 'stock_qty', Mage::helper('seo')->getCurrentProductStockQty($this->_product));


    $categoryId = $this->_product->getSeoCategory();
    $this->_category = Mage::registry('current_category');

    if ($this->_category && !$categoryId) {
        $this->_parseObjects['category'] = $this->_category;
    } elseif ($this->_product) {
        if (!$categoryId) {
            $categoryIds = $this->_product->getCategoryIds();
            if (count($categoryIds) > 0) {
                //we need this for multi websites configuration
                $categoryRootId = Mage::app()->getStore()->getRootCategoryId();
                $category = Mage::getModel('catalog/category')->getCollection()
                            ->addFieldToFilter('path', array('like' => "%/{$categoryRootId}/%"));

                //don't delete (for some stores need main_table)
                $stringSelect = $category->getSelect()->__toString();
                $entityIdFilter = (strpos($stringSelect, 'main_table') !== false)
                    ? 'main_table.entity_id' : 'entity_id';

                $category = $category->addFieldToFilter($entityIdFilter, $categoryIds)
                            ->setOrder('level', 'desc')
                            ->setOrder($entityIdFilter, 'desc')
                            ->getFirstItem()
                        ;
                $categoryId = $category->getId();
            }
        }
        //load category with flat data attributes
        $category = Mage::getModel('catalog/category')->load($categoryId);
        $this->_category = $category;
        $this->_parseObjects['category'] = $category;
        if (!Mage::registry('seo_current_category')) {// to be sure that register will not be done twice
            Mage::register('seo_current_category', $category);
        };
    }

    $this->_parseObjects['store'] = Mage::getModel('seo/object_store');

    $this->init();
}

getCurrentSeo() code:

public function getCurrentSeo()
{
    if (Mage::app()->getStore()->getCode() == 'admin') {
        return new Varien_Object();
    }

    $isCategory = Mage::registry('current_category') || Mage::registry('category');
    $isProduct  = Mage::registry('current_product') || Mage::registry('product');
    $isFilter   = false;

    if ($isCategory) {
        $filters = Mage::getSingleton('catalog/layer')->getState()->getFilters();
        $isFilter = count($filters) > 0;
    }

    if ($isProduct) {
        $seo = Mage::getSingleton('seo/object_product');
    } elseif ($isCategory && $isFilter) {
        $seo =  Mage::getSingleton('seo/object_filter');
    } elseif ($isCategory) {
        $seo =  Mage::getSingleton('seo/object_category');
    } else {
        $seo = new Varien_Object();
    }

    if ($seoTempalate = $this->checkTempalateRule($isProduct, $isCategory, $isFilter)) {
        foreach ($seoTempalate->getData() as $k=>$v) {
            if ($v) {
               $seo->setData($k, $v);
            }
        }
    }

    if ($seoRewrite = $this->checkRewrite()) {
        foreach ($seoRewrite->getData() as $k=>$v) {
            if ($v) {
               $seo->setData($k, $v);
            }
        }
    }

    $storeId = Mage::app()->getStore()->getStoreId();
    $page    = Mage::app()->getFrontController()->getRequest()->getParam('p');
    if (!$page) {
        $page = 1;
    }

    if ($isCategory && !$isProduct) {
        if ($this->_titlePage) {
            switch ($this->_config->getMetaTitlePageNumber($storeId)) {
                case Mirasvit_Seo_Model_Config::META_TITLE_PAGE_NUMBER_BEGIN:
                    if ($page > 1) {
                        $seo->setMetaTitle(Mage::helper('seo')->__("Page %s | %s", $page, $seo->getMetaTitle()));
                        $this->_titlePage = false;
                    }
                    break;
                case Mirasvit_Seo_Model_Config::META_TITLE_PAGE_NUMBER_END:
                    if ($page > 1) {
                        $seo->setMetaTitle(Mage::helper('seo')->__("%s | Page %s", $seo->getMetaTitle(), $page));
                        $this->_titlePage = false;
                    }
                    break;
                case Mirasvit_Seo_Model_Config::META_TITLE_PAGE_NUMBER_BEGIN_FIRST_PAGE:
                    $seo->setMetaTitle(Mage::helper('seo')->__("Page %s | %s", $page, $seo->getMetaTitle()));
                    $this->_titlePage = false;
                    break;
                case Mirasvit_Seo_Model_Config::META_TITLE_PAGE_NUMBER_END_FIRST_PAGE:
                    $seo->setMetaTitle(Mage::helper('seo')->__("%s | Page %s", $seo->getMetaTitle(), $page));
                    $this->_titlePage = false;
                    break;
            }
        }

        if ($this->_descriptionPage) {
            switch ($this->_config->getMetaDescriptionPageNumber($storeId)) {
                case Mirasvit_Seo_Model_Config::META_DESCRIPTION_PAGE_NUMBER_BEGIN:
                    if ($page > 1) {
                        $seo->setMetaDescription(Mage::helper('seo')->__("Page %s | %s", $page, $seo->getMetaDescription()));
                        $this->_descriptionPage = false;
                    }
                    break;
                case Mirasvit_Seo_Model_Config::META_DESCRIPTION_PAGE_NUMBER_END:
                    if ($page > 1) {
                        $seo->setMetaDescription(Mage::helper('seo')->__("%s | Page %s", $seo->getMetaDescription(), $page));
                        $this->_descriptionPage = false;
                    }
                    break;
                case Mirasvit_Seo_Model_Config::META_DESCRIPTION_PAGE_NUMBER_BEGIN_FIRST_PAGE:
                    $seo->setMetaDescription(Mage::helper('seo')->__("Page %s | %s", $page, $seo->getMetaDescription()));
                    $this->_descriptionPage = false;
                    break;
                case Mirasvit_Seo_Model_Config::META_DESCRIPTION_PAGE_NUMBER_END_FIRST_PAGE:
                    $seo->setMetaDescription(Mage::helper('seo')->__("%s | Page %s", $seo->getMetaDescription(), $page));
                    $this->_descriptionPage = false;
                    break;
            }
        }

        if ($page > 1) {
            $seo->setDescription(''); //set an empty description for page with number > 1 (to not have a duplicate content)
        }
    }

    if ($metaTitleMaxLength = $this->_config->getMetaTitleMaxLength($storeId)) {
        $metaTitleMaxLength = (int)$metaTitleMaxLength;
        if ($metaTitleMaxLength < Mirasvit_Seo_Model_Config::META_TITLE_INCORRECT_LENGTH) {
            $metaTitleMaxLength = Mirasvit_Seo_Model_Config::META_TITLE_MAX_LENGTH; //recommended length
        }
        $seo->setMetaTitle($this->_getTruncatedString($seo->getMetaTitle(), $metaTitleMaxLength, $page));
    }

    if ($metaDescriptionMaxLength = $this->_config->getMetaDescriptionMaxLength($storeId)) {
        $metaDescriptionMaxLength = (int)$metaDescriptionMaxLength;
        if ($metaDescriptionMaxLength < Mirasvit_Seo_Model_Config::META_DESCRIPTION_INCORRECT_LENGTH) {
            $metaDescriptionMaxLength = Mirasvit_Seo_Model_Config::META_DESCRIPTION_MAX_LENGTH; //recommended length
        }
        $seo->setMetaDescription($this->_getTruncatedString($seo->getMetaDescription(), $metaDescriptionMaxLength, $page));
    }

    return $seo;
}

Best Answer

I get a PHP Fatal error: Allowed memory size of 2147483648 bytes exhausted. I guess due to some wrong code

This is not from errors in the code, but from "waste of resources". It basically means that your script is executed without errors, but the RAM that PHP is allowed to use for this process (2G in this case) is not enough, and PHP breaks while executing.

Fast & easy solution: assign more RAM!

<?php
ini_set('memory_limit', '4G');
// rest of code [...]

But this will only help a bit. The server might become very slow while you export, or maybe you have so many SKUs and attributes that this still won't help.

It's better to use objects that are smaller, load less data etc. For example replace this:

$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*');

...with this:

$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect(['sku', 'name', 'the_name_of_your_seo_attribute']);

...to load only the attributes you really need.

If you have a lot of products, it may also be helpful to export them in chunks of, say, 10k products:

$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect(['sku', 'name', 'the_name_of_your_seo_attribute'])
->setPageSize(10000)->setCurPage(1);

(increase setCurPage() for each new set)

Hope that helps!

Related Topic