Skip to content

Android: Diving In

Starting to work on Android application development on the side. I have an iPhone through work, but I picked Android for two main reasons:

-I used to be ok at Java and I’ve never learned any Objective C. In my new job, I’m doing front-endy stuff on top of java code, for the most part. Since android runs on java, it’s an opportunity to blow off the dust, and let the Java stuff that I learn in Android help me at my main gig, and vice versa.

-Apple’s gated community approach to application development isn’t the way that I like to work. I don’t want to have to pay for their developer license and I don’t want them have absolute authority over whether my apps live or die. I think that there’s space for multiple approaches in mobile just like with desktop OS; if Android winds up in a Linux-y type place, I think I’m ok with that.

Some notes from my first half-day with mucking with this:

-There’s some confusion out there about which version of Eclipse to use-the one tailored for Java, or the Classic. The Android website recommends the Classic, some blogs (e.g. this one) recommend Java specific. It appears that some of the Java tools were buggy for Android development in E3.5; I downloaded 3.61 and I can’t find good information about whether this has changed. It is possible to develop Android apps without Eclipse, but you don’t get to use the Android Development Tools (ADT) plugin for Eclipse, that simplifies project creation and the build process, allows easy access to the Android emulator, and full access to the Davlik (like the JVM for Android) logs.

-When I first created a new project, I included an apostrophe in the application name-Kevin’s First Test. This isn’t automatically escaped and will cause build errors-I assume that you can change the value from one of the configuration xml files, but I just deleted the project and started over.

I’m working from Reto Meier’s Professional Android 2 Development to ease myself in. I’ll continue to post as I make progress and run into difficulties 🙂

Magento Models: Standard vs. EAV

Because Magento models include so many useful, extensible methods, it can be easy to forget that there are two quite different kinds of Magento models. There are basic, one model/one table models-these are fairly easy to create and maintain, and almost all of the “How to create a Magento Model” tutorials out there will show you how to create one of these. But there are also Entity Attribute Value Models, which have their object data spread across multiple, “tall and skinny” database tables, and though the two models share some methods, they differ in some important, easy to forget ways. For example, I wrote the following code to grab a Magento Collection of all customer models in a particular customer group that were created more than three days ago:

$three_days_ago = Mage::getModel('core/date')->date('Y-m-d H:i:s',strtotime('-72 hours'));
$collection = Mage::getModel('customer/customer')->getCollection()
    ->addAttributeToSelect( '*' )
    ->addFieldToFilter( 'group_id','6')
    ->addFieldToFilter('created_at',array('lt'=>$three_days_ago));

I then re-used this code in a custom module. But I had forgotten that customer/customer is an EAV model and the model in my custom module was basic. Since the addAttributeToSelect method is only available for EAV models, the code didn’t work until I removed it. It’s easy to forget about the two distinct kinds of Magento models, as for many applications they function identically. The mistake was difficult to find.

As usual, Alan Storm has the best explanation of the difference between the two Magento model flavors and a discussion of how to create an EAV model of your own, located here.

View Source on Chrome

Ran into something interesting yesterday. On Chrome, when you view source, Chrome does a GET request on the current URL. However, on a dynamic page that was reached by a POST request, that often won’t work. For example, Magento’s order success page is reached by a PHP POST request. When you do a GET on that page, Magento redirects you to the (now empty) cart page. So a view source request on the success page won’t show up. If you’re trying to do something like add a tracking pixel to the page, this can trip you up.

The proper way to ‘view source’ on Chrome is to use the firebug-like Javascript Console (View->Developer->Javascript Console)

Autoload and Extended Magento Core Controllers

You’ll spend a lot of time extending existing classes when you work with Magento to take advantage of the copious built-in functionality. Here is a ‘gotcha’ when extending controllers:

If you’re extending a ‘core’ factory controller, like so:

class YourPackage_YourModule_IndexController extends Mage_Adminhtml_Controller_Action

…then Adminhtml controller will autoload. However, if you’re extending a controller class that is itself extended from a ‘core’ factory controller, like so:

class YourPackage_YourModule_IndexController extends Mage_Adminhtml_Report_SalesController

…then the SalesController will not autoload. You must include it, like:

//refuses to autoload
require_once("Mage/Adminhtml/controllers/Report/SalesController.php");

class YourPackage_YourModule_IndexController extends Mage_Adminhtml_Report_SalesController

If you’re having trouble getting access to the controller class that you’ve extended, this may be the problem.

Overriding core files: the definitive guide

At prattski.com.

Overriding usually isn’t the best solution for adding new functionality, since you can only override each core file one time. However, for a quick fix, with a core Magento file that you are unlikely to need to change, it can be fine. This blog post collects the syntax for overriding each type of file in one place-useful!

Magento: No theming system for Admin phtml files

Magento has a nice theming system for front-end files: you can define different theme folders for front end components, and Magento will look in the defined folders for needed view files before defaulting to its default folders. This makes it easy to override front-end phtml files. However, I didn’t realize until today that this system is not in place for adminhtml files. So, for example, I wanted to change a default coupon code value this morning. If I change the default file, my changes will be overwritten when we upgrade to a new version of Magento. Bad news!

This wiki post explains how to effect upgrade adminhtml changes by overriding the Adminhtml block class.

http://www.magentocommerce.com/wiki/4_-_themes_and_template_customization/admin/changing_the_adminhtml_template

Quite straightforward-but not as easy as the front end theming system. Hopefully in future versions, that system will be migrated to the admin side-it would be great to be able to change admin views without having to override a core class.

Xdebug

New version of Xdebug released at the end of June; I missed it. More here.

Debugging PHP can be quite difficult, and Xdebug makes it a little easier.

Naming Conventions are Important

By default, Magento’s UPS module doesn’t report product dimensions to UPS for shipping calculations: a big problem when oversize products can result in a $50 large package fee, or even force a move to LTL.

Looking over the UPS.php file, I can see the following:

$r->getProduct();

($r being the raw xml request object). Now, if you know a little bit about Magento programming, you might think that (if you’re lucky) you have access to a Product clas and can call you dimensional product attributes with $r->getProduct()->getLength() or (if you’re unlucky) that you at least have access to a product ID, or anything at all to do with a product, from which you can suss out the right class with a little digging.

You’d be wrong, though. $r->getProduct() actually contains…a string about the type of shipping and destination, in my test case “GNDRES” for GrouND Shipping to a RESidential address. So, why is it called ‘Product’, again?

Overriding a Magento Controller

Magento uses an MVC design pattern, and provides facilities to override functionality of each part without overwriting the core code-leaving you in a position to make changes to the site code that won’t be overwritten by upgrades. Since we have moved to Magento Enterprise Edition for a new project (and are now contractually obligated to upgrade to the newest software version immediately), this functionality is more important than ever.

Recently, I needed to change the Customer Account Controller, to keep new customers from being automatically signed in when they signed up for the site. I’ve made changes to Magento Core Models and Views before; for those, all you have to do is copy the file structure under /app/code/Mage to /app/code/local/. For example, if you want to override the Catalog/Product model, put your new file at /app/code/local/Catalog/Model/Product/Product.php. Magento will look first for files in the local folder, so it will use your new Product.php in place of the default. I tried to use the same method to override the Account Controller-recreating the file structure and making the necessary changes to my new file with no luck. To override a controller, I found out, you need to create a new module.

There are two ways to do this. One method uses regular expressions to rewrite the path to the controller file from the default to your file, described here. I chose a slightly cleaner second method, in which you use the ‘before’ attribute to give higher priority to one module over another in a frontname space, described here.

After some futzing with the xml (and creating a nice ‘hello world’ module based on Alan Storm’s excellent tutorial), I ran into a problem that I had a hard time solving. The script kept crashing…but I’d done everything right!

Debugging revealed that my include statement was crashing the script. I wanted to include_once() the default Account controller, because I only wanted to override one function in it, and didn’t want to reproduce the rest of the code unnecessarily. Was my php include path misconfigured? No, it looks ok. Say, I wonder what the Magento include path might be? Oh…er, oh.

I never cleaned up my mess from my earlier attempt to solve the problem-I still had AccountController.php sitting in /app/code/local. And since /app/code/local is higher in the Magento include path than /app/code/core, my local AccountController.php is the one that’s getting included in my new module. And that one still doesn’t have the right configuration information. Once I deleted that file, my new overrided controller worked perfectly.

Lessons:
1) Computers always do what you tell them to do, no more and no less (I like to think of this as “The Grand Lesson”).
2) Be sure that your current problem isn’t a symptom of your earlier “solution”.

Grader Snapshot

As I mentioned in the last post, the Project Blog has started to get a lot of spam comments, which means that it’s been crawled by Google. The Project Blog is a plain-jane WordPress install; I haven’t done any SEO on the site whatsoever. I ran the site through the useful SEO tool www.websitegrader.com this morning to see where we’re at. Website Grader takes a snapshot of your websites search engine optimization status; here is a link to the report.

My grade is 48, which isn’t terrible but isn’t good. There’s work to do. More important than the score is the report-looking it over, it looks like WordPress does a poor job optimizing the on-page content out of the box-page titles are not SEO-friendly, meta descriptions and alt texts on images are not present. I don’t have any incoming links, which matter a lot-if you enjoy the content here, link me! I don’t have any social media tied to the page either-no twitter or facebook. That’s unlikely to change.

This HeadSpace2 wordpress extension claims to solve my title and meta description problem. My sense of the search engine landscape is that titles and meta descriptions are necessary for ranking well in search, but aren’t going to make the difference between ranking well and not all by themselves. I’ll install this plug-in and configure the titles, meta information, and image alt tags, and report back tomorrow!