Friday, August 12, 2016

How to Show All Magento Orders Externally in PHP

The main objective is to show all the orders on a separate PHP page which won't be part of Magento.

So, we create a PHP script salesorders.php and put it in the root folder "public_html". We would use Magento's functionality by including its core files.

Now, let's check how we should start ...

<?php
error_reporting(1);

// Here We load Mage class
require_once 'app/Mage.php';

// BootStrap the Magento
Mage::app();

// GET ALL ORDERS
$orders = Mage::getResourceModel('sales/order_collection')
          ->addAttributeToSelect('*')
          ->addFieldToFilter('status', 
         array("in" => array('complete', 'closed'))
    )
          ->addAttributeToFilter('store_id', 
                  Mage::app()->getStore()->getId())
          ->addAttributeToSort('created_at', 'desc')
          ->load();
?>

In the above code, we are selecting all the Orders which have status either 'complete' or 'closed'. Also, we are fetching the Orders with the 'created_at' field in descending order.

Then we just need to iterate through the collection and generate an HTML. 

<?php 
foreach($orders as $order)
{
  /// GRAND TOTAL
  $grand_total = $order -> grand_total;

  /// CUSTOMER DETAILS
  $customer_email = $order -> customer_email;
  $customer_fname = $order -> customer_firstname;
  $customer_lname = $order -> customer_lastname;

  /// IF Customer names are blanks
  if($customer_fname == '' )
  {
   $billing_address_data = $order->getBillingAddress()->getData();
   $customer_fname = $billing_address_data['firstname'];
  }
  if($customer_lname == '' )
  {
    $billing_address_data = $order->getBillingAddress()->getData();
    $customer_lname = $billing_address_data['lastname'];
  }

  /// ORDER ID
  $increment_id = $order -> increment_id;
  $created_at   = $order -> created_at;

  $str  = "<tr>";
  $str .= "<td>$customer_fname $customer_lname <i>                              ($customer_email)</i></td>";
  $str .= "<td><b>$increment_id</b> Created on                              $created_at</td>";
  $str .= "<td>";

  /// GET all Visible Products
  /// purchased in the ORDER
  $items = $order->getAllVisibleItems();
  $largeItems = 0;

  /// LOOP thru ITEMs
  foreach($items as $i)
  {
    /// PRODUCT DETAILS
    $prod_id = $i->getProductId();
    $p = Mage::getModel('catalog/product')->load($prod_id);
    $sku = $p->getSku();
  
    /// Build HTML
    $str .=  "<a href='" . $p->getUrlPath() . "'>" . $i->getName() . "</a>";
  
    /// PRODUCT Options
    $prodOptions = $i->getProductOptions();
    /// LOOP thru product Options and Show Them
    foreach ( $prodOptions['attributes_info'] as $key => $val)
    {
$str .= "[" . $val['label'] . ":"; 
       $str .= $val['value'] . "] ";
    } 
  }

  $str .= "</td>";
  $str .= "</tr>";

  /// PRINT HTML
  echo $str ;
}
?>

Now check the Output we get.




Now, we can add a Search facility to our script; it will search the POSTed word with Customer name or email within the order. So, we need a <form> tag in our HTML. 

<form method="get" action="" id="search_mini_form">
    <input type="text" name="q" placeholder="Search Customer">
    <input  title="Search" type="submit" value="Search">
</form>

So, through PHP we need to receive this POSTed value and add some filtering code to the Order collection. The code is shown below. 

<?php
/// SEARCH 
if($_GET['q'] && trim($_GET['q']) != "")
{
  /// LIKE Query
  $likeStr = '%'.trim($_GET['q']).'%';

  $orders = Mage::getResourceModel('sales/order_collection')
      ->addAttributeToSelect('*')
      ->addFieldToFilter('status', array("in" => array(
           'complete', 'closed')
        ))
      ->addAttributeToFilter( 'store_id', 
               Mage::app()->getStore()->getId())
      ->addFieldToFilter( 
             array( 'customer_email', 'customer_firstname', 'customer_lastname'),
     array( array( 'like'=>$likeStr ), 
            array( 'like'=>$likeStr ), 
    array( 'like'=>$likeStr ) 
  )
)
      ->addAttributeToSort('created_at', 'desc')
      ->load();
    
  /// IF u want to show SQL
  /// uncomment below line
  /// echo $orders->getSelect()->__toString();
}
else
/// FOR Non-Search 
{
   $orders = Mage::getResourceModel('sales/order_collection')
       ->addAttributeToSelect('*')
       ->addFieldToFilter('status', array("in" => array(
            'complete', 'closed')
          ))
       ->addAttributeToFilter('store_id', 
            Mage::app()->getStore()->getId())
       ->addAttributeToSort('created_at', 'desc')
       ->load();

?>

If it is a search, then if($_GET['q'] && trim($_GET['q']) != "") is true and the first part of the if-else structure is executed. 

See, how we have captured the submitted value in variable "$likeStr" and used "addFieldToFilter" function for filtering the collection.

IF we need "AND" conditions, then we can use multiple addFieldToFilter() calls.

To use "OR", we need to modify the addFieldToFilter() as shown below.

->addFieldToFilter( 
array( 'customer_email', 
               'customer_firstname', 
               'customer_lastname'),
array( array( 'like'=>$likeStr ), 
      array( 'like'=>$likeStr ), 
       array( 'like'=>$likeStr ) 
     )
  )

above statement generates the following SQL

'customer_email' like $likeStr OR 'customer_firstname' like $likeStr OR 'customer_lastname' like $likeStr

To generate an "AND" SQL query like this :: 
'customer_email' like $likeStr AND 'customer_firstname' like $likeStr, 

we can use the following structure ::

->addFieldToFilter('customer_email',  array("like" => $likeStr))
->addFieldToFilter('customer_firstname',array('like'=>$likeStr))

You can download the full working code here.

In our next tutorial, we'll list all the products available in Magento from an external script.

No comments: