Magento Connect, File Permissions, and myself have a rocky, inconsistent relationship. This one’s the opposite of my usual complaints — if Connect’s saying it can’t install itself due to file file permissions errors, here’s where to check which directories it thinks it can’t write to.

Magento Connect, File Permissions, and myself have a rocky, inconsistent relationship. This one’s the opposite of my usual complaints — if Connect’s saying it can’t install itself due to file file permissions errors, here’s where to check which directories it thinks it can’t write to.

A relatively straight forward article about how to collect sales tax for an ecommerce business. It’s remarkable how much hand waving there is about this from agencies representing themselves as ecommerce experts.

A relatively straight forward article about how to collect sales tax for an ecommerce business. It’s remarkable how much hand waving there is about this from agencies representing themselves as ecommerce experts.

The above does not define a class named Bar. It defines a class named “Foo\Baz\Bar”. That’s how PHP sees the class internally, and once you start thinking about classes the same way PHP does, they start making more sense, (or, at least, they did for me)

]]>If Magento 2 is your first introduction to PHP namespaces, here’s one small thought technology that might help. Consider the following

namespace Foo\Baz;
class Bar {
}

The above does not define a class named Bar. It defines a class named “Foo\Baz\Bar”. That’s how PHP sees the class internally, and once you start thinking about classes the same way PHP does, they start making more sense, (or, at least, they did for me)

]]>http://mage-page.net/2014/12/tip-for-php-namespace-newbies/feed/0Magento 2 Browser Installation Processhttp://mage-page.net/2014/12/magento-2-browser-installation-process/
http://mage-page.net/2014/12/magento-2-browser-installation-process/#commentsMon, 22 Dec 2014 03:53:00 +0000http://mage-page.net/2014/12/magento-2-browser-installation-process/If you’re trying to use the browser setup workflow in the Magento 2 beta released in December of 2014, make sure your web server is using the index.php in the root of the project and not the pub/index.php file.

It’s unclear which index.php is “the right” file to point to — the pub folder seems to be an attempt to adopt a more modern, Symfony like approach that keeps your code and your web serve-able file separate, but the root level index.php seems like an affordance for developers used to Magento’s traditional structure.

]]>If you’re trying to use the browser setup workflow in the Magento 2 beta released in December of 2014, make sure your web server is using the index.php in the root of the project and not the pub/index.php file.

It’s unclear which index.php is “the right” file to point to — the pub folder seems to be an attempt to adopt a more modern, Symfony like approach that keeps your code and your web serve-able file separate, but the root level index.php seems like an affordance for developers used to Magento’s traditional structure.

There’s still a lot of work to be done before Magento 2 is ready for general release, and a lot of that work will involve performance tuning. The old UI for enabling/disabling the built in profiler is gone, but this Stack Exchange answer from Marko Martinović tells you how to enable it. (a MAGE_PROFILER server environment variable with values of html, csv, etc)

There’s still a lot of work to be done before Magento 2 is ready for general release, and a lot of that work will involve performance tuning. The old UI for enabling/disabling the built in profiler is gone, but this Stack Exchange answer from Marko Martinović tells you how to enable it. (a MAGE_PROFILER server environment variable with values of html, csv, etc)

If you’re never used Vagrant before, it’s a program for managing and creating virtual machines from the command line. If you’ve never used virtual machines before, they’re a way to “run” another computer operating system from your main computer operating system. Two virtual computers on one physical machine. Using virtual linux machines is a popular way to manage different software stacks. ...]]>

If you’re never used Vagrant before, it’s a program for managing and creating virtual machines from the command line. If you’ve never used virtual machines before, they’re a way to “run” another computer operating system from your main computer operating system. Two virtual computers on one physical machine. Using virtual linux machines is a popular way to manage different software stacks. In other words, you can have one virtual machine with PHP 5.5 (for Magento 2) and another virtual machine with PHP 5.4 (for Magento 1).

You don’t need to use a virtual machine for Magento 2 development, but if you’re going to work on PHP projects with different version requirements, vagrant’s a smart move.

A quick Stack Overflow answer from yours truly that covers what to do when you think Magneto’s gaslighting you on configuration values you’re sure you’ve changed.

]]>http://mage-page.net/2014/07/configuration-gaslighting-checklist/feed/0Call to a member function getBackend() on a non-objecthttp://mage-page.net/2014/07/call-to-a-member-function-getbackend-on-a-non-object/
http://mage-page.net/2014/07/call-to-a-member-function-getbackend-on-a-non-object/#commentsWed, 16 Jul 2014 21:52:49 +0000http://mage-page.net/2014/07/call-to-a-member-function-getbackend-on-a-non-object/I needed to grab a few category names when all I had were the category IDs

Fatal error: Call to a member function getBackend() on a non-object in /Users/alanstorm/Sites2014/magento-1-9-0-0.dev/app/code/core/Mage/Eav/Model/Entity/Abstract.php on line 816

Can you spot the error now? Unless you happen to be working on a project where you’re deep inside Magento’s EAV implementation, the above error message is worse than useless when it comes to tracking down the actual error.

The problem was I used category_id — and a Magento category object has no such field. I should have used entity_id. Easy brain fart — made easier in that Magento doesn’t stick to the ...]]>

I needed to grab a few category names when all I had were the category IDs

Fatal error: Call to a member function getBackend() on a non-object in /Users/alanstorm/Sites2014/magento-1-9-0-0.dev/app/code/core/Mage/Eav/Model/Entity/Abstract.php on line 816

Can you spot the error now? Unless you happen to be working on a project where you’re deep inside Magento’s EAV implementation, the above error message is worse than useless when it comes to tracking down the actual error.

The problem was I used category_id — and a Magento category object has no such field. I should have used entity_id. Easy brain fart — made easier in that Magento doesn’t stick to the entity_id convention.

Why such a cryptic error message? Because somewhere along the line Magento’s EAV code checks if the filter attribute is or is not a static attribute.

This failed because there’s no such attribute. Magento returned false. Then Magento tried to call a method on something it expected to be an object, but ended up being a boolean.

$attrInstance->getBackend()

That’s why we got the cryptic error message. A certified or experienced developer will be able to track this sort of thing down — but to a newcomers cryptic error messages are kryptonite.

]]>http://mage-page.net/2014/07/call-to-a-member-function-getbackend-on-a-non-object/feed/0Beware of 0 Values in Primary Keyshttp://mage-page.net/2014/07/beware-of-0-values-in-primary-keys/
http://mage-page.net/2014/07/beware-of-0-values-in-primary-keys/#commentsSun, 13 Jul 2014 22:05:08 +0000http://mage-page.net/2014/07/beware-of-0-values-in-primary-keys/In a stock Magento system, there’s several tables where a row will have an ID field of 0.

In turn, there are times where the Magento application will assume these 0 ID rows exist. For example, a store ID of 0 is always interpreted as the admin store object.

In day to day operations this is no big deal — however MySQL has a bit of default behavior that might lead to some weird problems. Specifically, if you use 0 in an INSERT for a primary key, MySQL interprets that as a request to generate a new key.

Again, day to day, there won’t be any problems running Magento with these rows, since the 0 ID already exists. However, if you need to move or upgrade the data you might run into a problem. Consider an OUTFILE export of the above table.

The OUTFILE command correctly exports the ID of 0. However, if you perform an INFILE import, or create INSERTs manually from this data, the 0 will INSERT as a PRIMARY KEY request, meaning the admin store will no longer have an ID of 0, meaning Magento will break.

You can fix this during import by running the following

SET SESSION sql_mode='NO_AUTO_VALUE_ON_ZERO';

The sql_mode MySQL variable tells MySQL if it should interpret 0INSERTs as a true 0, not a PRIMARY KEY generation request.

One sharp stick in the eye for anyone who says MySQL’s lax data integrity doesn’t cause real world tradeoffs.

]]>http://mage-page.net/2014/07/beware-of-0-values-in-primary-keys/feed/0Using the Magento API to Safely Serialize as JSONhttp://mage-page.net/2014/07/using-the-magento-api-to-safely-serialize-as-json/
http://mage-page.net/2014/07/using-the-magento-api-to-safely-serialize-as-json/#commentsMon, 07 Jul 2014 05:55:25 +0000http://mage-page.net/2014/07/using-the-magento-api-to-safely-serialize-as-json/If you’re new to Magento, you may not realize that every remote API method has a native PHP equivalent. The why, how, and how to identify these models is covered elsewhere, but one thing I forget at my peril is how useful the API methods are when I need to serialize something as JSON or via PHP’s serialize function.

What’s great about the API load methods is they automatically return a simple PHP array full of scaler values. Compare that to something like this

json_encode(
Mage::getModel('catalog/product')->load($product_id)
);

While they may seem equivalent, the catalog/product object is going to have a lot of other object references — which ...]]>

If you’re new to Magento, you may not realize that every remote API method has a native PHP equivalent. The why, how, and how to identify these models is covered elsewhere, but one thing I forget at my peril is how useful the API methods are when I need to serialize something as JSON or via PHP’s serialize function.

What’s great about the API load methods is they automatically return a simple PHP array full of scaler values. Compare that to something like this

json_encode(
Mage::getModel('catalog/product')->load($product_id)
);

While they may seem equivalent, the catalog/product object is going to have a lot of other object references — which is turn may have other other object references, which in turn may circle back to the product object. This isn’t insurmountable, but is a giant pain in the butt when all you want is a JSON representation of a product’s data. The API models give you this, with the added benefits that they’re relatively stable — array keys added to an API result are much less likely to change version to version.

Developers coming into Magento are often put off by seemingly voodoo rituals like “Don’t directly manipulate the database tables with SQL”. This may be a ritual, but it’s a smart one, and my answer to this questions tells you why. It also includes an example SQL query for fetching all the product status values when you’re ready to dive deep on Magento’s EAV structure.

Developers coming into Magento are often put off by seemingly voodoo rituals like “Don’t directly manipulate the database tables with SQL”. This may be a ritual, but it’s a smart one, and my answer to this questions tells you why. It also includes an example SQL query for fetching all the product status values when you’re ready to dive deep on Magento’s EAV structure.

When I started using Magento the System Configuration section made me feel a little dumb — so many options, but no easy way to search for things. I’d always forget where a particular option was.

After a few months of using grep and ack to search though the system.xml files and work backwards to figure out the section, I decided to automate that process and the System Configuration Search module was the result.

Tim Reynolds had the same idea, and created a similar module named qconfig. I’ve also seen a few other implementations floating around, but I really like what Tim’s done with the search visualizations. It makes me extra embarrassed about my goofy dancing arrows. ...]]>

When I started using Magento the System Configuration section made me feel a little dumb — so many options, but no easy way to search for things. I’d always forget where a particular option was.

After a few months of using grep and ack to search though the system.xml files and work backwards to figure out the section, I decided to automate that process and the System Configuration Search module was the result.

Tim Reynolds had the same idea, and created a similar module named qconfig. I’ve also seen a few other implementations floating around, but I really like what Tim’s done with the search visualizations. It makes me extra embarrassed about my goofy dancing arrows. (although I still prefer my plain text results for discovery)

It’s a nice example of the way numerous individuals can have the same idea and pursue it independently of one another without realizing what the other people are working on.

An interesting project (also forked and improved by Magento stalwart fbrnc) that lets you replay the contents of Magento’s database log for the purpose of improving performance during a Setup Resource upgrade. I haven’t tried using it, but it looks useful.

Also, if there’s any computer science teachers out there, it’s a nice example of how eventually every system starts to recreate other systems (database transactions/bin-log replay).

An interesting project (also forked and improved by Magento stalwart fbrnc) that lets you replay the contents of Magento’s database log for the purpose of improving performance during a Setup Resource upgrade. I haven’t tried using it, but it looks useful.

Also, if there’s any computer science teachers out there, it’s a nice example of how eventually every system starts to recreate other systems (database transactions/bin-log replay).

This packages adds a deploy-all command to the Firegento Magneto composer project which (presumably) allows users to explicitly trigger an installation of their packages into their Magneto system. (As opposed to the current Composer Installer behavior, which only installs when a package is downloaded or updated)

This packages adds a deploy-all command to the Firegento Magneto composer project which (presumably) allows users to explicitly trigger an installation of their packages into their Magneto system. (As opposed to the current Composer Installer behavior, which only installs when a package is downloaded or updated)

In his soon to be referenced widely Magento Infinite Theme Fallback Fix, Eric Wiese notes that layout update XML files added via theme.xml are ignored by the parent/child theme inheritance. An XML file added to a parent’s theme.xml will not be added automatically to the child theme’s layout.

Eric’s solution is a custom module that makes theme inheritance consider these files.

If installing a module isn’t a solution available to you, here’s another option. Just specify the file from the parent theme you’d like in the child’s theme.xml.

With this in place, his new theme would pickup the corporate-base updates. Notice we haven’t added corporate-base/default.xml to the US theme — all we’ve done is configure its name in theme.xml. The fallback system takes care of the rest.

]]>http://mage-page.net/2014/05/infinite-inheritance-for-theme-xml-layout-updates/feed/0Programmatically Finding the Parent Theme in Magento 1.9http://mage-page.net/2014/05/programmatically-finding-the-parent-theme-in-magento-1-9/
http://mage-page.net/2014/05/programmatically-finding-the-parent-theme-in-magento-1-9/#commentsMon, 19 May 2014 00:03:59 +0000http://mage-page.net/2014/05/programmatically-finding-the-parent-theme-in-magento-1-9/One of the things Magento 1.9 brings to the table is unlimited theme fallback via a parent/child theme mechanism. If you ever need to find the current theme’s parent programmatically, here’s what you’ll want to do.

The core/design_config model/singleton is a new service model that’s responsible for reading the new theme.xml files. Then we fetch the area, design ...]]>

One of the things Magento 1.9 brings to the table is unlimited theme fallback via a parent/child theme mechanism. If you ever need to find the current theme’s parent programmatically, here’s what you’ll want to do.

The core/design_config model/singleton is a new service model that’s responsible for reading the new theme.xml files. Then we fetch the area, design package, and current theme. Then we use this information to query the config’s XML directly. Unfortunately, there’s no clean method for grabbing this information — direct XML reading is how it’s handled in the core code as well.