Sending Emails with Templates Real Easy in Magento (with attachments)
Ooooo sending emails in Magento is painful! Grrrrrr.
Or is it?
Firstly a use case.
I generate report data from cron and I need a simple way of sending the reports on email to a recipient. I do not want to use just the regular php mail() command. It is not reliable and I want it to fit within the Magento way of sending emails.
A popular Mandrill module that I use will also continue to work by making sure we use the in built magento email sending functions.
Okay, so first we need to declare our email so we can load it later on.
Assuming you already have a module…
... Continue reading →Securing System Configuration Data in Magento
It is sometimes necessary to store sensitive information in Magento. Noteably within the system configuration.
A password perhaps?
There is a lovely way to do this.
When defining your field in the system.xml, you can use the following backend model;
... Continue reading →Investigating rsync
Syncing files and folders from local to remote;
So basically sync ./media/ to the remote directory public_html/media.
See a list of the options used (-Pvrax) here.
... Continue reading →The / at the end of media is important. Leaving it off will create another media directory inside the remote media directory resulting in media/media.
Filtering a Shipping Method in Magento
What if we want to only show a certain shipping method to certain customers?
For this we need to tap in to the
collectCarrierRates()
function located in Mage_Shipping_Model_Shipping class.Unfortunately the only way for us to do this is with a rewrite.
... Continue reading →Filtering a Payment Method in Magento
When Magento is checking to see if a payment method is “available” it dispatches an event called
payment_method_is_active
passing in aStdClass
that holds a local variable calledisAvailable
.We only need to change this variable in our own custom logic to affect wether or not the method is available.
Here is how.
... Continue reading →Testing the Magento Soap API Using Curl
So I had a third party sending SOAP requests to Magento but something was broken.
I needed a way to test it.
They had already sent me the xml data they were pushing to the API, I just had to “pretend” to be their service and call the api with the data provided.
Here’s how.
... Continue reading →Creating a Magento 1.x Widget
The widget I am going to create is fairly simple; It will output a twitter profile link.
Firstly we need to describe our widget.
We do this using widget.xml located inside our app/code/[codePool]/[Vendor]/[ModuleName]/etc directory.
Before we do we should note that to output the link will require a twitter handle. We should provide a way of giving that information to the widget.
... Continue reading →Detecting Advert Blockers with Javascript
I (as many others do) use an ad blocker.
Recently I visited a website that detected I was using an ad blocker and hid the content from me.
Slightly annoying (if not expected) but as I discovered this is simply done with JavaScript and with some quick disabling of the JavaScript I was able to read the article.
Sneaky.
... Continue reading →Developing the Checkout Onepage Success Page in Magento
Of course what I am talking about here is the order confirmation page.
That is the page you see once you have placed your order confirming your order number.
It is however a single use page.
Once you refresh it you are taken back to an empty cart and that is all fine in production but what if you are a developer in need of modifying the success page?
... Continue reading →Run bin/magento from Anywhere in Your Magento 2 Installation
Just a little script I threw together so I could run
... Continue reading →bin/magento
from anywhere inside my Magento 2 installation.Creating EAV Product Attributes in Magento 2 Programmatically
Everything that follows will go in the
// @todo put attributes here
bit.There are a number of entities EAV attributes can be added to; products, categories and customers.
... Continue reading →Observers in Magento (and when not to use them)
Observers are great.
Little code points that allow the developer to hook in to allowing some custom logic to be performed in line with current program flow.
For example, in Magento 2 you might have something like;
... Continue reading →Custom File Uploads in Magento 2
I have focused here on uploading files in the admin area. The same technique could be applied to the frontend though.
First, here is a code sample to add a field to a form of type file;
This will render a html field on your form similar to the following;
... Continue reading →Adding Functionality to an Existing Magento 2 FrontName
Scenario;
You want to add some additional functionality to the customer section and you want it to reside under the customer frontname created by the magento-customer module.
How do you do this?
In app/code/[codePool]/[Vendor]/[ModuleName]/etc/frontend/routes.xml:
... Continue reading →Manipulating Magento 2 Admin Grid Buttons
I have used the following technique to add a new button to an existing grid.
The same technique could be used to remove or reorder buttons too.
Grid containers extend
Magento\Backend\Block\Widget\Container
. During_prepareLayout
, any buttons that have been added to the grid get pushed to a toolbar model ($this->toolbar->pushButtons($this, $this->buttonList);
).Because the
... Continue reading →pushButtons()
method is public we can use it to “plugin” to and modify the buttons array.Adding a Custom Tab to the Product Edit Admin in Magento 2
In view/adminhtml/layout/catalog_product_new.xml
Tip: If you just wanted to add the new tab for a particular product type you can put the following in a file specific to that type.
catalog_product_configurable.xml
for example.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="product_tabs"> <action method="addTabAfter"> <argument name="tabId" xsi:type="string">custom-id</argument> <argument name="tab" xsi:type="array"> <item name="label" xsi:type="string" translate="true">Custom Label</item> <item name="class" xsi:type="string">ajax</item> <item name="url" xsi:type="url" path="*/*/custom"/> <item name="group_code" xsi:type="string">advanced</item> </argument> <argument name="after" xsi:type="string">related</argument> </action> </referenceBlock> </body> </page>
There are a number of action methods we could have used. Noteable
... Continue reading →addTab
andaddTabAfter
.Fun at the Magento 2 Playground
Here is a code playground file I use to quickly test my code.
In playground.php (in your public folder)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
<?php require __DIR__ . '/app/bootstrap.php'; class PlaygroundApp extends \Magento\Framework\App\Http implements \Magento\Framework\AppInterface { public function launch() { // test code here // must return the response return $this->_response; } public function catchException(\Magento\Framework\App\Bootstrap $bootstrap, \Exception $exception) { return false; } } $bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER); /** @var \Magento\Framework\App\Http $app */ $app = $bootstrap->createApplication('PlaygroundApp'); $bootstrap->run($app);
Any class app that implements the AppInterface must implement both the
launch()
andcatchException()
functions.The launch function must also return an object that implements the
ResponseInterface
(Line 13
). Failing to do so will cause a fatal exception from theApp/Bootstrap.php
class within therun()
function.Specifically because it is the responsibility of the run() function to gather the response and then send that response to the browser.
Put your test code inside the launch() function.
Run it with
... Continue reading →php playground.php
Using Preferences in Magento 2
Firstly, let us note that preferences are destructive.
That means to say that you tell the Magento system to use your class instead of the original one. It is akin to a rewrite in Magento 1 and doing such things can make it difficult to other module developers to make changes in the same area of code.
... Continue reading →External JS in Magento 2
Adding an external JS file in Magento 2 is very easy indeed.
In your layout file:
The src_type is the clever bit that tells Magento this is an external URL.
Currently this technique is only available in the head section of your layout file. This is something to bare in mind as this will cause the browser to render block whilst the file is downloaded.
Lovely job.
... Continue reading →Seriously, why not MailChimp?
MailChimp.
I love it and so should you!
This is not a railroading. I haven’t arrived at this conclusion on a whim either. It is the culmination of 12(ish) years of pain working with other email platforms and through one reason or another, them falling short of expectation in one or more areas (sometimes every area). Those areas we will discuss shortly but I would like to start with saying that every single person I have recommended or integrated to MailChimp to date, has either stuck with MailChimp or after a brief spell elsewhere have opted to come back.
Why?
Because MailChimp is pretty fucking awesome.
... Continue reading →Always www.
I wanted to make sure not to serve duplicate urls on my site (with and without the www) and decided I would make sure my urls always have www.
In my .htaccess:
Note that because my entire site runs under https I just forward directly to that.
... Continue reading →Creating a Custom Frontend Route in Magento 2
This is a well trodden subject but in Magento 2 I hit a stumbling block (discussed later) so documenting it seemed the right thing to do :)
So what do we want to achieve?
We want to be able to go to a custom url like http://www.yourwebsite.co.uk/[frontName]/
[frontName] for purposes of this post is going to be “custom”; http://www.yourwebsite.co.uk/custom/
... Continue reading →Achieving 100 / 100 on Google PageSpeed Insights (using Jekyll)
100 / 100Suggestions Summary
Congratulations! No issues found.
It all started as a little (but quite fierce) competition between myself and Jake Cobley.
The goal was simple; who could achieve the illusive 100/100 on Google PageSpeed Insights.
As it turned out, through some collaboration with one another we both did.
Can I get a woop woop?
It has also been a very useful learning exercise.
But how?
... Continue reading →Adding Custom Dynamic Layout Handles Globally in Magento 2
My use case for this was that I needed a mechanism to change layout based on the customer group.
So with that in mind i decided adding a customer group layout handle was the way to go and that would allow me to use regular XML to change what I needed to.
So how?
To do this I used a plugin but I needed to know where to plug in to.
... Continue reading →How to Create a New Product Type in Magento 2
Creating a new product type in Magento 2 is actually relatively easy.
Yay!
As with most of these tutorials I make the assumption that you have a valid module registered with Magento. If this is not the case you should create one before you continue if you wish to try out the code.
You first you need to declare your new product type using the product_types.xml located in the etc folder of your module.
... Continue reading →Adding Custom JavaScript with RequireJs in Magento 2
Magento 2 uses RequireJs.
Custom js files live in app/code/[codePool]/[Vendor]/[ModuleName]/view/frontend/web/js
These custom js files are referred to as “modules” and are self contained.
Let’s look at a basic js module.
In [modulename].js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
define([ 'jquery', 'jquery/ui' ], function($) { $.widget('[ns].[modulename]', { _create: function() { if (console) { console.log(this.element); } } }); return $.[ns].[modulename]; });
Here we are creating a module using a jQuery widget that will log the current element to the console.
... Continue reading →Magento 2 Module Uninstall Scripts
Any module installed using composer can be uninstalled using
bin/magento module:uninstall [Vendor]_[ModuleName]
During the uninstall process Magento looks for an uninstall class located in the module being uninstalled. Specifically for Setup/Uninstall.php. It does this in the \Magento\Setup\Model\UninstallCollector.php class (collectUninstall()).
If it finds an Uninstall file and that file is a subclass of Magento\Framework\Setup\UninstallInterface it will run it very similar to how it runs install files.
... Continue reading →Understanding Sample Data Deployment in Magento 2
It begins with running
bin/magento sampledata:deploy
from your magento root install directory.Some magic then happens…
Hold on, I get an error deploying the sample data similar to:
No problem! This can sometimes happen. Magento uses a lot of memory when installing the sample data. You can remedy this by increasing the available memory temporarily whilst installing the sample data by running the above command with some additional PHP;
Okay. So what is this magic?
... Continue reading →Adding a new console command to Magento 2
Today is create a new Magento 2 console command day!
Woop woop!
Out of the box Magento 2 comes with quite a number of console commands for things like clearing cache, setting developer modes etc. To see them all fire up a command prompt, go to your magento root directory and run:
Give it a few seconds then you will see a list of all available commands.
... Continue reading →Magento 2 Events List
This is a bit of a long one…
... Continue reading →Unit Testing in Magento 2
Before we begin
If you are unfamiliar with unit testing and specifically PHPUnit (the testing framework used by Magento) I suggest you read the https://phpunit.de/Here we go.
Scenario: We have decided to extend the core Breadcrumbs block class with some additional functionality.
A basic first test would be that our new class extends the original class.
... Continue reading →Magento 2 Module Basics
Let’s do this!
The aim here is just to get a module registered with Magento 2. Nothing fancy.
Assuming you now have a installation of Magento 2 (if not see Creating a Magento 2 project with Composer), the first job is to let it know about your new module. You can do this with just two files.
Firstly create your module structure; app/code/[codePool]/[Vendor]/[ModuleName]
Hang on one second! What is [Vendor] and [ModuleName]? [Vendor] is your unique name. It defines your namespace. In my case, I use “Smartie”. [ModuleName] is erm, well, your module name :)
... Continue reading →Creating a Magento 2 Project with Composer
Before we begin… System Requirements and don’t have composer? Get Composer
… and GO!
Note: The following is based on my current Magento 2 experience and is really my preferred way of working with the platform to date. You may or may not find it useful.
If you haven’t already, create a directory you want to install Magento 2.
I put all my sites in ~/Sites.
... Continue reading →