Call us now on 0115 9738074

Archive for the ‘Development’ Category

Magento Q&A: How to ship orders via the API?

Wednesday, July 14th, 2010

Difficulty: Easy

Q:

I want to mark orders as shipped after we import the shipping feed from our warehouse. Is there an API for this? Or do I have to use the actual classes?

A:

Yes, of course! You can use the shipment API, to which you can connect using both SOAP and XML-RPC. The call that will be of most interest to you is shipment.create.

Here’s the sample code from magento’s site [php]:

$proxy = new SoapClient('http://magentohost/api/soap/?wsdl');
$sessionId = $proxy->login('apiUser', 'apiKey');
$notShipedOrderId  = '100000003';
 
// Create new shipment
$newShipmentId = $proxy->call($sessionId, 'sales_order_shipment.create', array($notShipedOrderId, array(), 'Shipment Created', true, true));

And here are the comments:

sales_order_shipment.create

Create new shipment for order

Return: string – shipment increment id

Arguments:

string orderIncrementId – order increment id

array itemsQty – items qty to ship as associative array (order_item_id ⇒ qty)

string comment – shipment comment (optional)

boolean email – send e-mail flag (optional)

boolean includeComment – include comment in e-mail flag (optional)

Magento Q&A: Why are some of my scheduled tasks not executed?

Friday, May 14th, 2010

Difficulty: Medium

Modification: Linux crontab

Q:

I have my scheduled tasks set up in magento and cron.php is executed periodically, however, some of the scheduled tasks are not performed. Is there anything I can do about that?

A:

We had the same problem with one of our sites. All the tasks were performed apart from sending the scheduled emails. After many discussions and when we have run out of all reasonable ideas we started looking at some more out of line ones. We noticed that the emails are sent when we access cron.php with a browser. It turns out that sometimes it is not enough to just execute your cron.php with a command line php interpretter in your linux crontab. We had to simulate a standard browser access to this php script by using wget. Here’s a sample line that you need to put in your crontab to make it work:

*/5 * * * * wget -q -O /dev/null http://.../cron.php

This line uses wget to request the cron.php file from the server and then discards the output. After putting this in place the emails were sent and they have been sending nicely ever since.

Magento Q&A: How to redirect from simple product to configurable product

Thursday, April 1st, 2010

Difficulty: Medium

Modification: Core Controller

Q:

I am trying to find a way to redirect the url for a simple product to go to the corresponding configurable product. For example if I have a link to a small blue t-shirt, it would go to the main t-shirt page where the attributes are available to select.

A:

You will need to modify the ProductController to make it look for a configurable product and display it when someone asks for a simple product.

The file you need to modify is /app/code/core/Mage/Catalog/controllers/ProductController and the method name is _initProduct().

Find the code which retrieves the product to be displayed:

$product = Mage::getModel(‘catalog/product’)

->setStoreId(Mage::app()->getStore()->getId())
->
load($productId);

And add this code after it:

if($product->type_id==“simple”)

{

$parentId=$product->loadParentProductIds()->getData('parent_product_ids');
if(isset(
$parentId[0]))
{
$product
=Mage::getModel('catalog/product')->load($parentId[0]);
}
}

That’s it, simple and elegant.

Prepare your magento site for upgrade

Thursday, February 18th, 2010

You might have heard that there is a new version of magento out there. Magento Community Edition 1.4 has just been declared stable by its creators – Varien. If you want to upgrade you must bear in mind that by doing so you will overwrite all the modifications in your core files. Normally this should not be a problem, as there shouldn’t be any core modifications. However, it is not uncommon that magento developers and designers do some quick changes in the core and then forget to move them to the local code pool or local template. The only way to make sure that your site will not loose the extra functionality or some custom styling is to track all the changes that have been applied to your core files and either move them to the local code/design files before upgrading or reapply them after the upgrade (though we would really recommend that you keep your core files free from any modifications). Now to the most important part: How to do this?

In order to find the core changes you would need to download a clean copy of magento. Be sure to download exactly the same version that you are currently running (you can check your current version in the admin panel’s footer). After download you need to extract the ‘app’ folder and place it somewhere in your filesystem. For the purpose of this example, lets assume that you put the original app file in the magento root folder and rename it to app.org.

Now you will need to make use of the linux console. The tool you will use is diff. It is a standard program for comparing files that should be present in all linux distributions. The only parameter that would need to be added is -r which switches the tool to recursive mode. The final command looks as follows for:

diff -r magento_root/app/code/core magento_root/app.org/code/core > ~/core_code_modifications.txt

diff -r magento_root/app/design/frontend/default/default/ magento_root/app.org/design/frontend/default/default/ > ~/core_design_modifications.txt

After executing those two commands you will have two files created in your home directory:

  • core_code_modifications.txt, which will list all the modifications in your core code files
  • core_design_modifications.txt, which will list all the modifications in your default template

With that knowledge your job of upgrading magento will be much simpler. Again, after you have successfully upgraded your magento store to version 1.4, do take some extra time and move the changes to the local code pool and/or your custom template. This will save you a lot of time and trouble in future upgrades and will also ensure that your store is easier to maintain by your developers and designers.

Save time customizing Magento with template hints

Friday, January 29th, 2010

So you need to do a few quick changes to the way magento displays some page. Great, but where is this page located in the file system? Have you been there? I know I have spent way too much time looking for the right files to edit.

Fortunately there is a built-in Magento feature that is designed exactly to help any programmer/designer in this situation. The feature is called template hints. You can activate it in your shop’s configuration. It is a bit tricky, however, because it is not visible by default. You need to go to System->Configuration->Advanced->Developer and open the Debug tab. By default you will only see an option to enable the Profiler. If you choose your store view from the ‘Current Configuration Scope‘ box situated in the top left part of the page you will get two extra options – ‘Template Path Hints‘ and ‘Add Block Names to Hints‘. Enabling the first option will display a path to the source file inside each block on the frontend. The second option will also add a Block Name, but it is not that useful and I would advise to keep it off for the sake of clarity.

There is one more thing worth noting here. If you would like to enable template hints on your live server you have to somehow limit them, so that they are shown only to you and your developers and not your customers. Well, you’re in luck again, because this option is also built-in. Just above the tab where you can set the template hints you will find a block called ‘Developer Client Restrictions‘. In there you can insert the IP addresses of all the machines that are allowed to view template hints. This way you can prevent your customers from seeing those hints and inevitably getting confused with your web shop.

Problems with Magento’s order item status management

Friday, January 15th, 2010

I encountered an issue with status management for order items. Each item in an order is assigned a status based on the quantities ordered, shipped, invoiced, cancelled, returned and backordered.

To my mind it would make sense to have the status equal to “Shipped” if quantity ordered = quantity shipped. This approach is also indicated on definition of the shipped status in /app/code/core/Mage/Sales/Model/Order/Item.php:

const STATUS_SHIPPED        = 2; // When qty ordered – [qty canceled + qty returned] = qty shipped

That is, however, not the case. If you have the item both invoiced and shipped, it will be set to status “Mixed”. The code responsible for this is inside the getStatusId() function in the same source file:

public function getStatusId()
{
$backordered = (float)$this->getQtyBackordered();
$canceled    = (float)$this->getQtyCanceled();
$invoiced    = (float)$this->getQtyInvoiced();
$ordered     = (float)$this->getQtyOrdered();
$refunded    = (float)$this->getQtyRefunded();
$shipped     = (float)$this->getQtyShipped();

$actuallyOrdered = $ordered – $canceled – $refunded;

if (!$invoiced && !$shipped && !$refunded && !$canceled && !$backordered) {
return self::STATUS_PENDING;
}
if ($shipped && !$invoiced && ($actuallyOrdered == $shipped)) {
return self::STATUS_SHIPPED;
}

if ($invoiced && !$shipped && ($actuallyOrdered == $invoiced)) {
return self::STATUS_INVOICED;
}

if ($backordered && ($actuallyOrdered == $backordered) ) {
return self::STATUS_BACKORDERED;
}

if ($refunded && $ordered == $refunded) {
return self::STATUS_REFUNDED;
}

if ($canceled && $ordered == $canceled) {
return self::STATUS_CANCELED;
}

if (max($shipped, $invoiced) < $actuallyOrdered) {
return self::STATUS_PARTIAL;
}

return self::STATUS_MIXED;
}

You can see that the status is set to shipped only if no invoice is present. I believe this is a bug, and it introduces confusion among shopowners. I think this code should be modified in the line assigning shipped status, like so:

if ($shipped && ($actuallyOrdered == $shipped) && ($actuallyOrdered == $invoiced)) {
return self::STATUS_SHIPPED;

}

If the number of invoiced items is different from the number of shipped items than the item will get a ‘Mixed’ status. This way, the mixed status could be considered as a sort of warning flag indicating that something is wrong.

Warning – an important security issue in Magento

Monday, November 30th, 2009

During extension installation on one of our client’s magento site we found a surprising security flaw in the system. It turns out that no matter how complicated your custom admin url is, everyone can access it, no skills necessary.
You don’t believe it? Well, we couldn’t believe this either, but it really is true. Check it out yourself. Navigate to your_magento_url/downloader, and click on the “Return to Magento Administration” link.
TADA! You are at the login page for the magento admin. Remember when you created a secret admin url to make it difficult for hackers to conduct a brute force attack on your site? At present it seems that it was unnecessary, because the downloader is available to anyone, so your admin url is actually not secret at all.

We started a discussion on this topic on the official magento forum. In there you will find a very interesting approach to securing both the downloader and the admin shared by one of the users. One of the magento team members also took part in the discussion and told us that the link to admin site will be removed from downloader login page in version 1.4.

That’s all very well, but what can be done right now to prevent downloader from revealing the admin url? The fastest and simplest solution is to get rid of the link to the admin site. You can remove it by editing the file magento_root/downloader/template/login.phtml. You will need to remove the following line:

<a href=”<?php echo htmlentities($returnUrl) ?>”>Return to Magento Administration</a>

If you prefer, you might just comment it. If you choose this approach, be sure to comment both html and php. The final outcome should look like below:

<!–<a href=”<?php //echo htmlentities($returnUrl) ?>”>Return to Magento Administration</a>–>

Not that there is a html comment (<!– –>) around the whole <a> tag as well as a php comment (//) blocking the echo statement which outputs your admin url. If you forgot about the php comment, the admin url would still be sent to the browser, but would not be rendered. However, the user would be able to read it in the source.