Long Awaited Update – Starting Up Again

It has been nearly a year since I have posted anything. I’d like to get posting again. The last year and a half, I have only been working on one project, which is on an older Magento code base, so I haven’t been doing many blog-worthy things.

So, as I think about blogging again, I wanted to ask all of you what sorts of topics you would like to see? Are there any things in Magento that you wish you knew how to do, but couldn’t figure out? Comment below and let me know. It will help me with ideas on what to write about.

Also – I am working on a module that I might make available free to everyone. I won’t write all the details here now, but the gist is that it will allow you inject javascript/html code anywhere on your site based on the block name that is found in the layout xml files (where it says name=”some.name”.

Posted in Magento | Leave a comment

New Online Help Service – Wizpert

Wizpert (http://wizpert.com), which is currently in private beta, is a service that provides people with direct and instant access to experts in specific fields (PHP Programming being one out of a very wide variety of topics).

Currently, you do need to sign up for an invite to use the service. I’m not sure how quickly the turn-around is on that at the moment, but it is worth checking it out.

Being that I am most proficient in Magento and that’s where I spend most of my time, I have requested that they create a Magento topic, but that is still pending.

They also recently featured me on their blog with an article I wrote for them. You can check that out here: http://blog.wizpert.com/learning-by-example/

Posted in Misc, Web Apps | Leave a comment

Magento: Adding Items to Existing Orders

Modifying existing orders is always going to be a risky task, especially since orders have multiple states and statuses. Be careful when doing anything like this.

I recently had a need to add an item to a bunch of orders that had not yet been shipped. Fortunately, it was a bit easier for me, because the situation I had to work from is that all orders with a specific SKU were missing another item (it should have been included in a bundle, but they forgot it when creating the bundle). So, it was easy to look up all orders that had that specific sku.

However you get your orders is up to you. I will walk you through what to do when you have your orders and are ready to loop through them and add the item.

I had to add the same exact item to all the orders I needed to modify. So first I loaded up a product object, and I had to set the price to zero because it would have been included for free in the bundle anyway:

// Load the Order
$product = Mage::getModel('catalog/product')->load($productId);
$product->setPrice(0);

In my case, I had an array of order ids that I looped through, so I had to load up each order:

// Load the Order
$order = Mage::getModel('sales/order')->load($orderId);

Then I had to get the quote. For some reason (not sure if a bug or something), $order->getQuote() did not work. Try that first. If that doesn’t work, try this:

// Load the Quote
$quote = Mage::getModel('sales/quote')->getCollection()->addFieldToFilter("entity_id", $order->getQuoteId())->getFirstItem();

In our case, we were finding that some orders did not have a corresponding quote (maybe a bug, maybe some of them got purged for some reason), so I had to add in some code to convert the current order to a quote:

// Create quote if no quote was found
if (!$quote->getId()) {
    $quote = Mage::getModel('sales/convert_order')
        ->toQuote($order)
        ->setIsActive(false)
        ->setReservedOrderId($order->getIncrementId())
        ->save();
}

Once we have the quote object, we can then add an item to it. Make sure you’ve loaded up your product object, because you will pass it in here. The method setProduct accepts a product object. You can also specify the qty if you need to add more than one:

// Create the item for the quote
$quoteItem = Mage::getModel('sales/quote_item')
    ->setProduct($product)
    ->setQuote($quote)
    ->setQty($qty)
    ->save();

Now that the item has been added to the quote, we need to convert the quote back to the order:

// Convert the quote item to an order item for this order
$orderItem = Mage::getModel('sales/convert_quote')
    ->itemToOrderItem($quoteItem)
    ->setOrderID($order->getId())
    ->save($orderId);

At that point, the order will then have the new item.

I couldn’t find a better way to add items to existing orders, so if you happen to know how to improve this, or a better way to do it, please let me know.

Posted in Magento, PHP | 9 Comments

Set Default Values For Attributes When Creating Products – By Product Type Too

I was asked today to change the default value of an attribute to something other than the set default just for simple products only when creating a new product through the admin. I found a very easy way to do this using an event observer. I will do my best to explain:

The event you will want to observe is: catalog_product_new_action. I named the method in the observer to ‘setNewProductDefaults’. I will provide a modified version of my method with some different examples:

public function setNewProductDefaults($observer)
{
    // Get the product object
    $product = $observer->getProduct();
 
    // Sets default for all product types
    $product->setStatus('1');
    
    // Set defaults if it is a Simple Product
    if ($product->getTypeId() == 'simple') {
        $product->setWeight('1')
            ->setTaxClassId('2');
    }
 
    // Set defaults if it is a Configurable Product
    if ($product->getTypeId() == 'configurable') {
        $product->setCustomDesign('yourcustom/design');
    } 
}

And that’s all you need to do! If you’ve implemented this correctly into a custom module, when you create new products in the admin, you will see the attributes set to what you set them to in your observer. Implementing this can save both time, and forgetfulness when setting up new products through the admin.

Posted in Magento | 1 Comment

Magento Dev Best Practices: Modifying 3rd Party Extensions

Often times there are occasions where you need to modify the functionality in a 3rd party module. If you find yourself in that situation, the best practice here is to not modify it directly. Write a module that extends the 3rd party extension! In doing this, you save headaches if you ever need to upgrade the extension, or if you find that you need to revert your changes and go back to the original, it’s easy.

Perhaps the most important aspect of properly extending a module is by setting the dependency:

Dependency

In your modules xml file in app/etc/modules, you can add a block of code to make your module depend on the 3rd party extension you are trying to extend. By doing this, you cause your new module to be loaded after the extension you are adding the dependency for. This is good because your config.xml information will be loaded afterwards, and therefore your rewrites, event observers, etc. will take priority, so there’s no need to comment out any code in the 3rd party extension’s config.xml file. Here is an example of your xml file if you were extending an extension named Awesome_Extension:

<config>
    <modules>
        <My_ModuleExtender>
            <active>true</active>
            <codePool>local</codePool>
            <depends>
                <Awesome_Extension />
            </depends>
        </My_ModuleExtender>
    </modules>
</config>

If You Must…

If there is some reason that you need to actually modify the 3rd party extension files, at least comment and document it like crazy. Keep a txt file or something in the extension’s root folder and list out every file in the module that you modified, the purpose of the modifications, the new/changed functionality introduced, etc. Also, keep all of the original code. Comment out what you are changing, add your modified code, and make sure that the code is clear as to what is new, and what is original. Keep in mind that you (or someone else) may need to undo your changes, or upgrade the extension at some point, so make it as easy as possible for someone to do that in the future.

Posted in Best Practices, Magento | 2 Comments

Magento Dev Best Practices: Module Naming Conventions

In Magento 1.x modules, there’s the potential to have files and folders dispersed all over the Magento file structure. Much of this will be resolved in Magento 2, but we don’t know when that will happen yet, and we will still be supporting and writing for 1.x for a while after 2 is released. Given that, I’d like to suggest some helpful file/folder naming conventions:

Module Name

Modules consist of a 2-part name: Namespace_Modulename. For the purpose of this article (and for all the modules I write for the community) I will be using a module named Prattski_Example, which I would put in app/code/community/Prattski/Example.

Module Blocks, Helpers, and Models

In your module’s config.xml file, you get to define the namespace used when calling blocks, helpers, and models. In many cases, people will only use the module name and exclude the module namespace. If you only use the module name, calling a model for this module would look like this: Mage::getModel(‘example/modelname’). I always suggest making it a convention to always use the namespace and module name. That way in the code, there’s no question as to what module is being used. In that case, calling the model would look like this: Mage::getModel(‘prattski_example/modelname’).

Layout XML Files

If your module introduces a new layout xml file, I always name it the full namespace and module name. As with the rest of these conventions, it makes determining which modules these files belong to really simple. If I needed a layout xml file for my module, I would name it like this: app/design/frontend/base/default/layout/prattski_example.xml

Template Folders

Just like with the above layout xml files, I always name my folders with the full namespace and module name. If I was adding some frontend template files, I would put them here: app/design/frontend/base/default/template/prattski_example/

Conclusion

The whole point here is making the code/files/folders in such a way that it keeps things more organized and clear. If you include the full module namespace and module name, it really doesn’t get much more clear what modules are responsible for your different files/folders.

If you are working on a project and creating a lot of modules for it, you’ll notice some nice benefits of all of this as well. All of your modules layout files and template folders will all be in the same place together, making finding what you are looking for much easier and more organized.

Posted in Best Practices, Magento | 7 Comments

Magento Dev Best Practices: Event Observers

This is the fourth post in the Magento Dev Best Practices series. If you don’t know about and use Event Observers already, make it a priority to learn them. Throughout Magento, there are a lot of events that are dispatched at different times. Some are specifically named, others are more dynamically named (model save before and save after events for example). Most of these events, when dispatched, provide one or more objects in them. All of these events can be observed, and the objects provided in them can be modified.

The best practice here is to follow this rule: Do not ever rewrite a core file without first making sure there is no possible way to accomplish the functionality with an event observer.

The reason for this is, as you probably already know, that you cannot rewrite the same core file more than once (without creating an extends chain). By using event observers instead, multiple modules can exist and be changing functionality all at the same time without conflicting. Technically, any number of modules can observe the same event and make changes. Conflicts can still occur, but it’s far more rare.

A fairly good list of events can be found here, but do take note that there are a lot of dynamic events not listed here. All models have a save_before and save_after for instance.

I am not going to give a tutorial on how to use them here, but if you don’t know how to use observers in Magento, then google it and learn it. It is incredibly worth knowing, and it will take your development to the next level and improve the quality and compatibility of your modules.

Posted in Magento | Leave a comment

Magento: Rewrite & Observer List Module

I am excited to announce my latest free Magento module called Prattski_ConfigXmlView. I wrote this module to solve a common problem that happens with modules and extensions: When multiple modules rewrite the same core file, or when observers share the same name. It is also a good reference to quickly see all rewrites and observers.

Rewrites List

This view provides you with all of the rewrites for all enabled modules in the local and community code pools, divided into models, blocks, and helpers sections. It will display the core class being rewritten, the new class, and the module it belongs to. If there is a conflict (the same core class being rewritten more than once), the rewrites will be highlighted in red to show you where the issue is. This will not only allow you to quickly find issues, it will also be a good reference to show you all existing rewrites to help you when creating new modules to make sure the class you want to rewrite is not already rewritten.

Observer List

This view provides you with a full list of all event observers in the local and community code pools. The list is organized and sorted by event name and provides you with the event name, module, observer name, method, and scope (global, frontend, admin). If 2 or more observers have the same name, they will be highlighted in red and a warning message will be displayed. Like the rewrites list, this provides a view of all the active observers and highlights any issues.

Just the Start

I named this module Prattski_ConfigXmlView because rewrites and observers are just the start. This module is designed to be able to gather information from module’s config.xml files in the local and community code pools. If you have an idea that you would like to see this module be able to report, please submit a feature request under the “Issues” tab at GitHub, or submit a comment for this post.

Download at Github

You can get the module at github. I encourage you to get involved. If you find any bugs or think anything should be enhanced or anything, please submit it at github for this module.

Posted in Magento | 3 Comments

Idea: Github Integration with Magento Connect

There has been some discussion about Magento Connect lately, so I wanted to help keep the momentum going with a suggestion of my own.

The current system that Magento uses isn’t horrible, but it isn’t great either. One thing I would like to see is some kind of integration with Github. Many of use use github to store our extensions because we like open source and enjoy providing them to the community. Honestly, keeping an extension updated on Magento Connect is a tedious process, especially if we already keep it all updated on Github.

One example of this is modman. It is an incredibly easy-to-use system, and it pulls all the needed files from github and installs them in the proper locations with a simple command. Through the use of the Github api, you could access the readme for the module description, see when it was last updated, see how many active issues there are, etc. Perhaps there could be a specific file that could be added to every repo that would tell Magento Connect the information it needed, similar to the way modman does it, but with additional information.

I think this would be great, and the goal ultimately would be for an extension writer to be able to add their github repo of their extension once, and then from there it’s just a matter of keeping the repo up-to-date, and all changes made to the repo master branch would update Magento Connect dynamically.

Supporter of the idea or have additional thoughts on this? I’d love to hear your comments.

Posted in Git, Magento | 8 Comments

Prattski_SimpleDevToolbar – Improvements

When I first initially released the Prattski_SimpleDevToolbar, one thing I overlooked was the ability to enable/disable it. I have now added the ability to do that, as well as added the ability to make it only viewable by specified IP addresses.

The changes are now up on Github where you can download the Prattski_SimpleDevToolbar extension.

Posted in Magento | Leave a comment