Accessing Magento data from Laravel

Laravel, Magento

Recently I was in the process of migrating a Magento webshop to a SaaS webshop solution. Normally I would access the product and other data by using the API. In this case this was a problem as there was a lot of data that I was not able to access. I needed the output of blocks and some custom modules which where not exposed to the API.

I had 2 options:

  1. Write code to expose those data to the API.

  2. Access the data from Laravel.

As I already needed Laravel for this specific project I tried the second approach. From this point there are 2 possible paths: Access the data directly in the database, or access the Magento code base and access the data that way. The latter has my preference as blocks needs parsing before I can transfer them. For example, an image is saved in the database in this way:

<img title="image404" src="{{media url="wysiwyg/404.jpg'}}" alt="Page not found" />
MageTested.com (ad)

Do you want your Magento store to be more reliable? Tired of things that suddenly break the checkout process without anyone noticing? You can hire my services to kickstart End-2-End testing for your Magento store. This way you know for sure that your store is behaving as expected before releasing that new feature or that update.

View MageTested.com for more information.

Preparation

Before we can get to the fun stuf we need some preparation. For this approach to work we need 2 environments: a working Laravel environment and a working Magento environment. You don't need to be able to access the Magento environment from the webbrowser, this can be Headless™. You could even connect the environment to the production database if you wanted to, but I would not recommend that. The 2 installations must be on the same system as we need to include the Magento source files into Laravel. My setup look something like this:

/Root
-- /Laravel
-- /Magento

Magento and Laravel has an overlap in 2 functions which will give you a fatal error: __() and now(). As I don't need that functions I commented them out in staging/app/code/core/Mage/Core/functions.php.

Service Provider

The most logical approach for this is to use a service provider which binds to the container. This way Magento is only bootstrapped when you actually need the data and not on every request. I did add this Service Provider:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class MagentoServiceProvider extends ServiceProvider
{
    /**
    * Bootstrap services.
    *
    * @return void
    */
    public function boot()
    {
        //
    }

    /**
    * Register services.
    *
    * @return void
    */
    public function register()
    {
        $this->app->bind('Magento', function () {
            require_once '../../path-to-your-magento-installation/app/Mage.php';
            return \Mage::app();
        });
    }
}

Now we can access the block contents in the same way we normally would do when working in Magento:

app('Magento');
$blockid = 'main-image-404-page';
$layout = \Mage::app()->getLayout();
$block = $layout->createBlock('cms/block')->setBlockId($blockid)->toHtml()

How safe is this?

I did test this only in a closed environment. I made a copy of the Magento code and database and setup a local copy. I then transferred the data to the new SaaS webshop which was not online yet.

Want to respond?