Magento SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry ‘000000254’ for key ‘UNQ_SALES_FLAT_ORDER_INCREMENT_ID’

In some cases, customers encounter this error on your website :

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '000000254' for key 'UNQ_SALES_FLAT_ORDER_INCREMENT_ID'

You don’t understand and drive you crazy ?
Don’t worry, I will help you.

First, this error probably happend when customer quit violenty the payment page, without canceling, so your order is not “finished” and your quote is not “released” (is_active = 1 in db). Customer come back, recover his quote and try to proceed it again.
The reserved_increment_id is not updated and when magento try to create the order, mySQL give him the previous error.

How a so obvious bug like this can exist ? and why does it crash only on my website, it seems to work fine on other website ?
Let me guest, your client (clients always have weird needs …) ask you to start order number at 0 instead of 100000000, or ask you to put a letter into it.

So, why does this reserved_increment_id is not updated ?
Let check on the function which update the reserved_increment_id field :

// /app/code/core/Mage/Sales/Model/Resource/Quote.php
    /**
     * Check is order increment id use in sales/order table
     *
     * @param int $orderIncrementId
     * @return boolean
     */
    public function isOrderIncrementIdUsed($orderIncrementId)
    {
        $adapter   = $this->_getReadAdapter();
        $bind      = array(':increment_id' => (int)$orderIncrementId);
        $select    = $adapter->select();
        $select->from($this->getTable('sales/order'), 'entity_id')
            ->where('increment_id = :increment_id');
        $entity_id = $adapter->fetchOne($select, $bind);
        if ($entity_id > 0) {
            return true;
        }

        return false;
    }

You see it, the little (int) in this line $bind = array(‘:increment_id’ => (int)$orderIncrementId); ?
This transform your increment_id in your request from “000000254” to “254”, mySQL doesn’t find an order with the increment_id “254” and your quote is not updated.

To fix it, override this function :
In your Sales/etc/config.xml file, add

<global>
  <model>
    <sales_resource>
                <rewrite>
                    <quote>Adin_Sales_Model_Resource_Sales_Quote</quote>
                </rewrite>
            </sales_resource>
   </model>
</global>

And create the new class file /app/code/local/Adin/Sales/Model/Resource/Sales/Quote.php

class Adin_Sales_Model_Resource_Sales_Quote extends Mage_Sales_Model_Resource_Quote {

    /**
     * Check is order increment id use in sales/order table
     *
     * @param int $orderIncrementId
     * @return boolean
     */
    public function isOrderIncrementIdUsed($orderIncrementId)
    {
        $adapter   = $this->_getReadAdapter();
        $bind      = array(':increment_id' => $orderIncrementId);
        $select    = $adapter->select();
        $select->from($this->getTable('sales/order'), 'entity_id')
            ->where('increment_id = :increment_id');
        $entity_id = $adapter->fetchOne($select, $bind);
        if ($entity_id > 0) {
            return true;
        }

        return false;
    }

}

That should do the tricks.

Magento render cms/block with widgets

You create a cms static block (cms/block) and dynamise it with widget, here an example:

 <div class="confirmation">
        <img src="{{skin url='images/image-order.jpg'}}" alt="" />
 </div>

You then render this block :

echo Mage::getModel('cms/block')
            ->setStoreId(Mage::app()->getStore()->getId())
            ->load(self::confirmationCmsBlockName)->render();

But the widget {{skin url=’images/image-order.jpg’}} is not executed and is display as {{skin url=’images/image-order.jpg’}}.

To execute the widget, you need to render as HTML a block and not a model

echo  Mage::app()->getLayout()->createBlock('cms/block')->setBlockId(self::confirmationCmsBlockName)->toHtml();

Magento get simple products from configurable product

This is how you can get all simple products linked from a configurable product

$configurableProduct = Mage::getModel('catalog/product')->load(1); 
$childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null,$configurableProduct);   
foreach($childProducts as $child) {
    echo $child->getId();
}

If you only need ids of the child product, you can do this

$childProductsId = Mage::getModel('catalog/product_type_configurable')->getChildrenIds(1);

Magento get configurable product from simple product

If you need to get the configurable product from a simple one, you can do this

$simpleProductId = 666;
$parentIds = Mage::getResourceSingleton('catalog/product_type_configurable')
                  ->getParentIdsByChild($simpleProductId);
$configurableProduct = Mage::getModel('catalog/product')->load($parentIds[0]);
echo $configurableProduct->getId(); 

Make a PDF into magento using zend_pdf

Here my code to generate a PDF file into Magento using the zend_pdf embeded library.

//in my controller
public function prindPdfAction()
{
        $pdf = new Zend_Pdf();
        $page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4);
        $font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA);
        $page->setFont($font, 12);

        //add a logo
        $image = Mage::getBaseDir('media').'/logo_pdf.jpg';
        if (is_file($image)) {
            $image = Zend_Pdf_Image::imageWithPath($image);
            $x = 20;
            $y = 700;
            $page->drawImage($image, $x, $y, $x + 118, $y + 112);
        }

        //add text
        $page->setFont($font, 16);
        $titre = "Ecole ";
        $page->drawText($titre, 155, $page->getHeight()-85, "UTF-8");

        //add pages to main document
        $pdf->pages[] = $page;

        //generate pdf
        $content =  $pdf->render();

        $fileName = 'details.pdf';
        //send it to the browser to download
        $this->_prepareDownloadResponse($fileName, $content);
}

Magento link in backend redirect to dashboard

You are working on Magento backoffice and make a link to a new page but when you click on your anchor, you are redirected to the dashboard ?

Here how to make a proper link :

   echo "<a href='".Mage::helper('adminhtml')->getUrl('*/*/displaydetail', array('id' => $cour['id']))."' >".$cour['name']."</a>";

Something like

 Mage::getUrl('*/*/displaydetail/id/'.$cour['id'])

doesn’t work, even if I had the FormKey. But you can use it for ajax request

 jQuery.ajax({
        url: "<?php echo Mage::getUrl('*/*/classroomfromplaceAjax') ?>",
        type: "POST",
        dataType: 'json',
        data: 'place_id=' + place_id + '&index=' + index + '&form_key=' + window.FORM_KEY,
        success: function (data) {
            jQuery('#classroom_' + index).html(data.html);
        },
    });

Magento – add a new action in grid

Here, how to add new action in grid like ‘Edit’ link at admin grid.
On this example, we will add a “schedule” action in product admin grid.

We will overrite this class /app/code/core/Mage/Adminhtml/Block/Catalog/Product/Grid.php.

Declare the rewrite class on the /app/code/local/Adin/Catalog/etc/config.xml
and add

<global>
      <blocks>
            <adminhtml>
                <rewrite>
                    <catalog_product_grid>Adin_Catalog_Block_Adminhtml_Catalog_Product_Grid</catalog_product_grid>
                </rewrite>
            </adminhtml>
        </blocks>
</global>

Then create your rewritted class /app/code/local/Adin/Catalog/Block/Adminhtml/Catalog/Product/Grid.php.

<?php
class Adin_Catalog_Block_Adminhtml_Catalog_Product_Grid extends Mage_Adminhtml_Block_Catalog_Product_Grid {
}
?>

Now, rewrite the _prepareColumns() function, find the ‘action’ column an add an entry in the actions array

  $this->addColumn('action',
            array(
                'header'    => Mage::helper('catalog')->__('Action'),
                'width'     => '50px',
                'type'      => 'action',
                'getter'     => 'getId',
                'actions'   => array(
                    array(
                        'caption' => Mage::helper('catalog')->__('Edit'),
                        'url'     => array(
                            'base'=>'*/*/edit',
                            'params'=>array('store'=>$this->getRequest()->getParam('store'))
                        ),
                        'field'   => 'id'
                    ),
                    array(
                        'caption' => Mage::helper('catalog')->__('Schedule'),
                        'url'     => array(
                            'base'=>'*/*/schedule',
                            'params'=>array('store'=>$this->getRequest()->getParam('store'))
                        ),
                        'field'   => 'id'
                    ),
                ),
                'filter'    => false,
                'sortable'  => false,
                'index'     => 'stores',
            ));

In our example, we just add this part

array(
                        'caption' => Mage::helper('catalog')->__('Schedule'),
                        'url'     => array(
                            'base'=>'*/*/schedule',
                            'params'=>array('store'=>$this->getRequest()->getParam('store'))
                        ),
                        'field'   => 'id'
                    ),

One last thing, at the end of the _prepareColumns function, change

return parent::_prepareColumns();

by

return Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();

PHP – Use of undefined constant MCRYPT_BLOWFISH – assumed ‘MCRYPT_BLOWFISH

While your coding session, you encounter this error :

Use of undefined constant MCRYPT_BLOWFISH - assumed 'MCRYPT_BLOWFISH

You think, easy, a module should be missing on my php
So you install it :

sudo apt-get install php5-mcrypt

And restart apache.

But it still doesn’t work. In phpinfo() it seems the module is not installed.

In fact with the new version of PHP, you still need to activate the module

php5enmod -s apache2 mcrypt

The restart apache and the module should work.

apache AH01630: client denied by server configuration – error 403 forbidden

You are seting up a new website and you get an 403 forbidden error and this on apache error log :

AH01630: client denied by server configuration

You don’t understand because you already setup hundred of websites, you check chmod but you still get this error.

Don’t panic, since apache 2.4 you have to change the directory configuration:

<Directory />
  Options Indexed FollowSymLinks
  AllowOverride All
  Require all granted
</Directory>

and restart apache, that should do the trick.