Categories


Archives


Recent Posts


Categories


Installing OpenMage: Bridging a Generational Gap

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

This entry is part 3 of 3 in the series Checking in on OpenMage and Magento in 2020. Earlier posts include Checking in on OpenMage and Magento in 2020, and Composer Plugins and Installers. This is the most recent post in the series.

Magento 1 was one of the last big PHP platforms that didn’t embrace composer as a distribution model — probably because Magento’s initial release predates the release of composer by a few years. Magento 1 comes from an era where source code was distributed as an archive and moved to a server via SFTP or direct export from a source control repository.

This creates a challenge for the OpenMage project. In the twelve plus years since Magento 1’s release, Composer’s become a de-facto standard in the PHP community. If a platform doesn’t use composer, that platform will be invisible to a lot of people.

OpenMage’s getting started page currently has two competing set of code snippets for using OpenMage with Composer. Today we’re going to take a look at them and how they might surprise someone used to a more developer oriented composer workflow.

OpenMage Installers

If we head over to the the OpenMage install page, we see a few different things.

First, we have a suggestion on how to install OpenMage

The suggested way to install this Magento 1 Fork is via composer. For this we know of two working installers with support for the magento core as dependency.

and then two JSON snippets.

{
    "require": {
        "aydin-hassan/magento-core-composer-installer": "*",
        "openmage/magento-lts": "19.4.6"
    },
    "extra": {
        "magento-core-package-type": "magento-source",
        "magento-root-dir": "htdocs"
    }
}

// --------------------------------------------------

{
    "require": {
        "aoepeople/composer-installers": "*",
        "openmage/magento-lts": "19.4.6"
    }
}

It may not be obvious to someone who’s not already conversant in composer, but these are meant to be starting composer.json files. Create a composer.json with these contents, run composer install, and you’ll have the OpenMage source.

The first snippet is a starter for the aydin-hassan/magento-core-composer-installer package, which is a personal project from Aydin Hassan.

The second snippet is from the aoepeople/composer-installers package, which is a small (README-less?) project from Fabrizio Branca under the AOE GitHub organization.

Before we begin, if you’re not familiar with composer plugins and composer installers, you may want to brush up on these concepts via our recent intro post. This article assumes you have a passing familiarity with both.

AEO People

Looking at the aoepeople/composer-installers package first, we see this configuration.

// File: composer.json
{
    "require": {
        "aoepeople/composer-installers": "*",
        "openmage/magento-lts": "19.4.6"
    }
}

This installs the aoepeople/composer-installers package and the OpenMage composer package (openmage/magento-lts) to your vendor folder.

If you create a composer.json file with the above contents (minus the file name comment), and run

$ composer.phar install

you’ll end up with the following directory contents.

$ ls
composer.json   composer.lock   htdocs      vendor

The aoepeople/composer-installers package appears to be designed to look for an installed Magento source package (openmage/magento-lts), and then copy that package out of vendor and into htdocs.

We say appears because how the aoepeople/composer-installers works is a little unclear. If we look at its composer.json file, we see it’s not a composer plugin. Instead, its package type is composer-installer, and it registers a plugin via the extra configuration.

{
    "name": "aoepeople/composer-installers",
    "type": "composer-installer",
    /* ... */
    "extra": {
        "class": "Aoepeople\\ComposerInstallers\\Installer"
    },
}

If we look at the class registered as a plugin we see it extends a Composer\Installer\LibraryInstaller that we haven’t seen before. It turns out this aoepeople/composer-installers package is based on a very early version of the composer installer feature/API.

In addition to (or perhaps because of) being a bit of mystery code, this installer has another curious property. When responding to a composer update command the aoepeople/composer-installers package will reinstall Magento to the htdocs folder, overwriting any updates you’ve made there. If this is the intended behavior, it would appear that this installer works best when it’s part of a larger workflow that copies or symlinks configuration, theme, and modules into the main Magento source repository.

Because of its destructive behavior with regards to updates and its reliance on a very old, possibly never officially supported, version of the installer API, I’d recommend staying away from this installer.

Aydin Hassan Installer

If we look at the aydin-hassan/magento-core-composer-installer configuration, we see a few additional configuration fields. Similar to the aoepeople/composer-installers installer, we have the the main installer composer package (aydin-hassan/magento-core-composer-installer) configured, as well as a Magento source package (openmage/magento-lts). However, we also have these two items.

{
    /* ... */,
    "extra": {
        "magento-core-package-type": "magento-source",
        "magento-root-dir": "htdocs"
    }
}

The magento-core-package-type configuration tells the installer which composer type identifiers another package as a Magento source package. This is magento-source because the magento/magento-lts package’s type is magento-source. The aydin-hassan/magento-core-composer-installer package is designed to install any composer packaged Magento source, not just OpenMage.

The magento-root-dir configuration tells the installer which folder to install the Magento source into.

What it Does

If we create this composer.json file.

// File: composer.json
{
    "require": {
        "aydin-hassan/magento-core-composer-installer": "*",
        "openmage/magento-lts": "19.4.6"
    },
    "extra": {
        "magento-core-package-type": "magento-source",
        "magento-root-dir": "htdocs"
    }
}

and then run composer install, we’ll see the following in our project folder

$ composer.phar install
// ...
$ ls
composer.json   composer.lock   htdocs      vendor

The htdocs folder now contains our copy of OpenMage.

Unlike aoepeople/composer-installers, if we update the version of OpenMage,

// File: composer.json
{
    "require": {
        "aydin-hassan/magento-core-composer-installer": "*",
        "openmage/magento-lts": "^20.0"
    },
    "extra": {
        "magento-core-package-type": "magento-source",
        "magento-root-dir": "htdocs"
    }
}

and then run composer update

$ composer.phar update

The aydin-hassan/magento-core-composer-installer installer will only update files from the source package. It will not replace new files you may have put into htdocs. However, if you’ve changed a core file, those changes will be overwritten. Also, in the unlikely (but possible) case where one of your files has the same path and name as a file in the new source package, it appears the installer will copy the source file over your file. If this is a problem, it appears there’s support for an excludes configuration that will let a system owner skip copying certain files.

Implementation

When it comes to its implementation, the aydin-hassan/magento-core-composer-installer installer is a composer plugin. You can see the package configures a plugin class via composer.json.

It is not, however, a composer custom installer. Instead, the AydinHassan\MagentoCoreComposerInstaller\CoreManager class listens for (i.e. subscribes to) a number of different composer events, and takes appropriate action to install, uninstall, or update the Magento source.

So while this plugin is an installer in the general sense (it installs Magento), it is not an example of a composer custom installer, and is not something that works on top of the composer/installers plugin/custom-installer.

One More Installer

There’s one more installer you’ll want to be aware of if you’re using OpenMage. To start, let’s try adding a package from the packages.firegento.com composer repository to our project.

First, we’ll want to configure composer globally so this repository is available.

$ composer.phar config -g repositories.firegento composer https://packages.firegento.com

Then, let’s require my old Pulse Storm Launcher package.

$ composer.phar require  astorm/pulsestorm-launcher:dev-master

After running the above command, we’ll find this extension code in the vendor folder

$ ls vendor/astorm/pulsestorm-launcher/

LICENSE.txt
README.md
app
build_launcher.bash
composer.json
magento-tar-to-connect.launcher.php
modman
skin

However, we’ll also find it inside our htdocs folder.

$ ls htdocs/app/code/community/Pulsestorm/Launcher/
Block       Model       controllers
Helper      README.md   etc

$ ls htdocs/app/design/adminhtml/default/default/template/pulsestorm_launcher/
hook.phtml  js-nav.phtml

// etc ...

You’re probably wondering what installed this module into this folder. I know I was the first time I saw this happen.

The OpenMage project has a dependency on the magento-hackathon/magento-composer-installer package. This package contains another composer plugin that recognizes packages of type magento-module and is able to install them into a Magento source repository. The magento-hackathon/magento-composer-installer package is also not a composer installer — it’s just a plain composer plugin.

Interestingly, if you attempt to install openmage/magento-lts without one of the installer packages we’ve mentioned.

$ composer.phar require openmage/magento-lts
// ...
please define your magento root dir [root]
magento root dir "root" missing! create now? [Y,n] Y
magento root dir "root" created

you will be prompted to create a root directory. This is the magento-hackathon/magento-composer-installer package at work, and will update the magento-root-dir configuration variable for you.

As long as we’re talking about weird unexpected-but-useful things, the magento-hackathon/magento-composer-installer package will also add a small code snippet to htdocs/app/Mage.php

#File: htdocs/app/Mage.php
/** AUTOLOADER PATCH **/
if (file_exists($autoloaderPath = BP . DS . 'vendor/autoload.php') ||
    file_exists($autoloaderPath = BP . DS . '../vendor/autoload.php')
) {
    require $autoloaderPath;
}
/** AUTOLOADER PATCH **/

This snippet will try to load composer’s autoloader from the following two files.

htdocs/vendor/autoload.php
vendor/autoload.php

This will give code in your Magento system the ability to use class files loaded via composer’s standard PSR-0 and PSR-4 autoloaders.

Wrap Up

So — that’s three different composer plugins, two that install Magento’s source, a third that installs Magento modules, and none of them are actually formal composer installers. This all seems like it works OK in practice — assuming you’re already familiar with Magento.

I’m not sure what you would think if you were new to Magento. While I’m sure the aydin-hassan/magento-core-composer-installer and magento-hackathon/magento-composer-installer plugins do their jobs well, to someone just learning Magento’s conventions I imagine this setup adds a tremendous amount of cognitive overhead.

Put another way — these plugins will serve an experienced Magento developer well, but will only add a layer to Magento’s already legendary impenetrableness.

Next time, as we start to wrap this series up, we’ll do a bit of speculating on what a composer create-project workflow might look like for OpenMage, and how something like this might help reduce the cognitive overhead for someone just learning Magento’s complex module and theme structures.

Series Navigation<< Composer Plugins and Installers

Copyright © Alan Storm 1975 – 2020 All Rights Reserved

Originally Posted: 23rd September 2020