Category Archives: Open Source

Bits & bobs about open source software

Leicestershire Point of Sale website launched

home page imageLast week Carter Design Group’s new website was ‘soft’ launched. Carter Design Group, based in the small Leicestershire village of Foxton, are point of sale display designers, manufactures and installers.

The website was designed by Wavy at The Mitchesons, while we worked on the site’s architecture and turning the design into a responsive WordPress template.

UPDATE

Less than a month since going live, the search engine results are very pleasing. For terms such as “point of sale designer” and “point of sale design” they rank 3rd and 5th in Google respectively. For “grocery merchandising” they are #2.

While this represents a great start to our SEO efforts, there is still much to do!

 

Magento 503 maintenance flag error

Today visiting one of the Magento sites I look after returned the 503 Server error, with the message that the server was down for maintenance or was out of resources. This was true for both the front end and the admin area.

Looking in my error logs returned this error message:

client denied by server configuration: MAGENTO_DIR/app/etc/local.xml

Google returned several possible solutions. But then I remembered I’d been in the back end, using Magento Connect Manager to upload a language pack. This had failed for some reason. It then dawned on me that Magento puts the store (CE 1.7.0.2) into maintenance mode when performing updates, etc. So, its probable that Magento did not return the site to live mode after the upload failed.

A quick look in the root showed that a file called “maintenance.flag” was there. Renaming the file meant both front and backend were now working as expected.

Writing a Joomla plugin

I’ve been working on a Joomla! project recently & have needed to write several plugins so I thought I’d write about how I wrote one that notified administrator when a user updates their JomSocial profile.

About Plugins

Joomla! plugins are code that implements additional features without the need to hack core code. Often they ‘plugin’ into system events (or hooks) & therefore enable developers to fire custom code at certain points in the execution cycle.

If you look under the plugins folder of your Joomla! installation, you’ll see that Joomla! ships with quite a few plugins, under folders such as ‘authentication’, ‘search’, ‘system’, etc. Each folder groups similar types of plugins & you’ll often find that a component will install its own plugins and/or folder of plugins.

Look within these folders and you’ll see that plugins follow a convention. There is a minimum of two files: a .php & a .xml file. Sometimes there is a blank index.html file (to prevent directory browsing) and sometimes a language file. We will deal with these files when we look at our example below.

The Requirement

The website I’ve been developing uses JomSocial & the administrator wanted to be alerted every time a member updated their JomSocial profile. Joomla! plugins are well suited to satisfy this type of requirement. The key is to find if JomSocial has any event or hook that we can call when the user saves their profile update.

Fortunately JomSocial has such an event: onAfterProfileUpdate($userId, $saveSuccess). So, the next stage is to figure out how to write a plugin that calls this code.

When you install JomSocial it creates a ‘community’ sub-folder with the plugin directory. There you will find several plugins, depending on the JomSocial feature set you have included.

So that’s the obvious place for us to include our plugin. I named my plugin notify, so it will sit under joomla/plugins/community/notify. It consists of 5 files: notify.php, notify.xml. index.html & then two language files under joomla/plugins/community/language/en-GB called en-GB.plg_community_notify.ini &  en-GB.plg_community_notify.sys.ini. These two ini files are not mandatory, but they provide a way of translating message strings if required.

So, to the two essential files: notify.php & notify.xml. The xml file is the easiest to create, since it follows a standard convention. It’s a file that tells Joomla! how & where to install your plugin & what files are dependencies of the plugin. Here’s the code within notify.xml:

<?xml version="1.0"?>
<extension version="2.5" type="plugin" group="community" method="upgrade">
 <name>Notify Administrator Jom Social Community Plugin</name>
 <version>1.1.1</version>
 <creationDate>Sept 2012</creationDate>
 <author>Eddie May</author>
 <authorEmail>ecm@freshwebservices.com</authorEmail>
 <authorUrl>http://www.freshwebservices.com/</authorUrl>
 <copyright>@freshwebservices</copyright>
 <license>GNU GPL v2.0</license>
 <description>This plugin alerts admin each time a user updates their JomSocial profile.</description>
 <files> 
 <filename plugin="notify">notify.php</filename>
 <filename>index.html</filename>
 <folder>language</folder>
 </files>
 <config>
 <fields name="params">
 <fieldset name="basic">
 <field
 name="admin_id"
 type="text"
 default=""
 label="PLG_COMMUNITY_NOTIFY_ADMIN_ID_LABEL"
 description="PLG_COMMUNITY_NOTIFY_ADMIN_ID_DESC"
 required="true"
 filter="string"
 size="50" />
 <field
 name="email_subject"
 type="text"
 default=""
 label="PLG_COMMUNITY_NOTIFY_EMAIL_SUBJECT_LABEL"
 description="PLG_COMMUNITY_NOTIFY_EMAIL_SUBJECT_DESC"
 required="true"
 filter="string"
 size="50" />
<field
 name="email_text"
 type="text"
 default=""
 label="PLG_COMMUNITY_NOTIFY_ADMIN_EMAIL_TEXT_LABEL"
 description="PLG_COMMUNITY_NOTIFY_ADMIN_EMAIL_TEXT_DESC"
 required="true"
 filter="string"
 size="50" />
 </fieldset>
 </fields>
 </config>
</extension>

Essentially this file tells Joomla! and the administrator what it is, who wrote it, what it does, what dependencies the plugin has (under the files bit) and that it has three fields that the administrator must complete: admin_id, email_subject, email_text. This is data that will be passed to the plugin to use when it executes.

You’ll notice that the convention is that required files have the same naming convention: notify in this example. They sit under a folder called notify, & there is notify.xml & notify.php. Let’s look at notify.php.

<?php
/**
 * This class notifies named site administrator who/when a profile is updated
 * 
 * @author Eddie May
 * @date Sept 20212
 */
// no direct access
defined('_JEXEC') or die;
jimport( 'joomla.plugin.plugin' );
jimport('joomla.mail.helper');
class plgCommunitynotify extends JPlugin{
 function onAfterProfileUpdate($userId, $saveSuccess){
 if(empty($saveSuccess)){
 return;
 }

 $adminID = $this->params->get('admin_id');
 $subject = $this->params->get('email_subject');
 $emailText = $this->params->get('email_text');

 if ($adminID == null || $adminID == '')
 {
 throw new Exception(JText::_('No Admin User ID - cannot send email notification without it'));
 }

 $user = JFactory::getUser($adminID);
 $userEmail = $user->get('email');
 $fromName = $user->get('username');
 $updatedUser = JFactory::getUser($userId);
 $updatedName = $updatedUser->get('username');
 $body = 'Hi, the following user ' . $updatedName .' with user id of ' . $userId .' ';
 $body .= 'has just updated their profile. ';
 $body .= 'Please review and update their public fields accordingly. ';
 $body .= ' '. $emailText . ' ';
 JFactory::getMailer()->sendMail($userEmail, $fromName, $userEmail, $subject, $body);
 return true; 
 }
}//eof class

So, we’ll examine this class is a little more detail. We start with a non-mandatory comment section, telling any future developer about the file. Then we have the  security call: defined(‘_JEXEC’) or die; This prevents the file from being called outside of the Joomla! application.

The next lines import dependencies the class requires. As I want to email the administrator, I import the Joomla! mailer functionality. Then I declare or create the class itself: class plgCommunitynotify extends JPlugin{ Note the naming convention – plg+folder+class name.

Then we’re into the functionality of the class. Essentially we build a function that calls the JomSocial event onAfterProfileUpdate($userId, $saveSuccess) which gives us two variables that we can work with. The id of the user who is updating their profile & a boolean to tell us if the update was successful.

So, we do a couple of checks – if $saveSuccess is false, it means the update failed & we don’t need to do anything else. So we exit.

If all is well, we then retrieve the information that the administrator entered when s/he installed the plugin

$adminID = $this->params->get('admin_id');
$subject = $this->params->get('email_subject');
$emailText = $this->params->get('email_text');

We bailout if the admin_id is missing: if ($adminID == null || $adminID == ”). If the information is there, we can use that later to get the administrator user.

In the next couple of lines we get the admin user, their email, etc:

$user = JFactory::getUser($adminID);
$userEmail = $user->get('email');
$fromName = $user->get('username');

& also the details of the JomSocial user:

$updatedUser = JFactory::getUser($userId);
$updatedName = $updatedUser->get('username');

Then we can construct the email that will be sent to the administrator:

$body = 'Hi, the following user ' . $updatedName .' with user id of ' . $userId .' ';
 $body .= 'has just updated their profile. ';
 $body .= 'Please review and update their public fields accordingly. ';
 $body .= ' '. $emailText . ' ';

Then we use the standard Joomla! mailer functionality to send the email:

JFactory::getMailer()->sendMail($userEmail, $fromName, $userEmail, $subject, $body);

Finally we exit our class by calling return true;

To deploy your plugin you just zip your notify folder up & install it using the Joomla! installer. You then need to publish the plugin within the Joomla! backend.

Conclusion

The key to writing such a plugin is to find the correct system or component event to call or hook into. Its worth looking at component APIs before you buy if you think that you may need to extend them with a plugin. A quick email to the component developer is a good tip – if s/he takes an age to respond, then it might be a signal that their support is not so good. If there’s no published API, that’s also a cause for concern – good software has good documentation!

Joomla Upgrade Issue

Today I upgraded a Joomla website from 2.5.4 to 2.5.6 using the Updater. However, when I went to the home page the featured article was not displaying. For some reason, the upgrade had apparently (although I could be wrong on this one) set the ‘Finish Publishing’ date to ‘0000-00-00 00:00:00’.

Clearing this setting resulted in the featured article displaying on the home page. Quite why this happened I’m not sure, since the date setting ‘0000-00-00 00:00:00’ basically means never stop publishing. However, setting it to blank and saving had the desired effect.

EU Cookie Law Clarification

On May 26th the UK implemented the EU Cookie Directive. Only hours before it became law did the Information Commissioner’s Office (ICO) clarify what website owners were expected to do about cookies!

After many scare stories about getting users to opt-in for almost every type of cookie, and of massive fines for non-compliance, this latest clarification essentially seems to say the following: we can assume “implied consent” for most “non tracking” cookies. That is, if you have a shopping cart or use Google Analytics, etc, you can cover yourself by having appropriate statements in your terms and conditions. This is how Amazon.co.uk appear to have handled the issue.

So, crisis over? Well, I’m not a lawyer, so your mileage may vary!

Magento, enable cookies & Google Analytics

I’ve just started work on a search engine optimisation campaign for a new client. They have a Magento shop, that’s been running for just over two years, and they’re obviously looking to improve its performance.

Before I start such a campaign, I first take some time analysing the market, etc, but also looking at the website itself, particularly at the conversion process and conversion rates. Its a simple question really, why send extra visitors to a website if they’re not going to convert into customers once they’re there?

The first step then is to look at the site’s Google Analytics (you are using Google Analytics, right?). What was clear is that nearly a third of the shop’s buyers were being confronted with the Magento default “enable cookies” page when checking out. I found this out by looking at the Ecommerce Product Performance report & using the “Landing Page” Secondary Dimension filter.

Landing Pages Filter, Google AnalyticsThis report shows what page the user was on immediately before they enter the checkout sales funnel. In this instance, an unacceptably large number (ie, greater than none!) were being told that they had to enable cookies in their browser and were then confronted with how to do so (“in Internet Explorer, go to Tools …..”, etc).

The cause of this issue was a poorly configured Magento shop – setting the correct cookie path & cookie domain is all that was required to overcome this issue.

This is a classic example of the need to thoroughly audit any web property before embarking upon a search engine optimisation campaign. There’s no point sending lots more traffic to a website that’s not optimised for conversion. Its also a good example of the worth of a good analytics software – without it we would not have known that so many users were being told to mess with their browser’s cookie settings.

Magento Server 500 Error

Yesterday a Magento shop owner contacted me because his shop was returning a “500 Server Error” page. Their web designer was at a loss to figure out what was going on, so the owner turned to me.

One of the main reasons for this error are file/directory permissions errors, often encountered when installing or upgrading Magento. A quick check revealed that this wasn’t the issue.

Taking a look at the configuration, I noticed that logging was turned on. So I looked at the log files, & exception.log was over 2.5 gb in size. Just turning logging off was enough to remove the server error. So, it seems Magento couldn’t write to the file any longer because of its sheer size.

So there’s something to look out for if you encounter an puzzling 500 error. Quite why the exception file was so big is another question!

If you’re looking for a midlands magento specialist, why not get in touch?

Leicester Joomla Website Design

Today we launched a new website for a longstanding client, Stanhope House Day Nursery, Leicester.

Built using the popular open source Joomla! content management system, the website includes a forum for parents, a front page image gallery and image popups to maximise screen space.

Now their website uses a content management system, nursery staff will now be able to use the website as one of the main communication channels with existing and prospective parents.

Magento – changing the body class by category

Magento updates the body class declaration on almost every page. If you look at the source code, the body class varies according to where you are on the website. This can be very useful if you wish to style different pages.

However, I was asked to produce different body backgrounds depending on the category the user was viewing. By default Magento adds body classes for categories based on the category name. So, you get something like the following for a parent category (caravan-motorhome-lighting):

<body class=” catalog-category-view categorypath-caravan-motorhome-lighting-html category-caravan-motorhome-lighting”>

and the following for a child category (mr16-leds):

<body class=” catalog-category-view categorypath-caravan-motorhome-lighting-mr16-leds-html category-mr16-leds”>

This makes styling a parent category & its child categories very difficult – since the class attributes change every time the user navigates to a child category. What was needed was a way of assigning a single class to a parent category and its children – say, ‘caravan-motorhome-lighting’.

I looked around for a solution but didn’t want to go to the bother of overriding any Mage classes, nor could I figure out how to achieve this using Magento’s layout.xml files. Then I thought about what category parameters or attributes I could add from the Admin ‘Manage Categories’ interface. This is when I lucked on the solution.

Within the Category ‘Custom Design’ is the ability to inherit or override the ‘Parent Category Settings’.  If this is set to ‘No’, you can then apply a ‘Custom Layout Update’ – which is essentially an xml snippet of the kind usually found in Magento’s layout.xml files.

By adding the following:

<reference name=”root”><action method=”addBodyClass”><className>caravan-motorhome-lighting</className></action></reference>

to the parent category, and then making each child category inherit or ‘Use Parent Category Settings’, I get the body class ‘caravan-motorhome-lighting’ added to every category/sub-category page for that category & its children.

magento layout update

Here we have set this parent category not to ‘Use Parent Category Settings’ & have added the layout update.

magento body class layout update

Now we set the sub category to ‘Use Parent Category Settings’, & it therefore gets the same body class attribute as its parent category.

The net result is now that parent and child categories share the same body class & I can then set a common background image for all of them to share. So the parent has this body class declaration:

<body class=” catalog-category-view caravan-motorhome-lighting categorypath-caravan-motorhome-lighting-htmlcaravan-motorhome-lighting”>

while its child categories have the following:

<body class=” catalog-category-view caravan-motorhome-lighting categorypath-caravan-motorhome-lighting-mr16-leds-html category-mr16-leds”>

So that both parent and child categories share a common class attribute of ‘caravan-motorhome-lighting’. Meaning I can style all these categories in the same way, while adding different background images for other categories.

You can see the technique in operation at the Aten Lighting website. If you looking for a Leicestershire magento developer, please get in contact.

Brand Reputation Management – EpiServer Fails

Online brand reputation management can be perilous & the internet is littered with failures and own goals. Here’s a recent example.

Swedish Drupal specialists NodeOne recently ran a banner campaign advertising the benefits of using Drupal over several proprietary CMS offerings. One of those compared, EpiServer, responded with a “cease and desist” letter from their lawyers, claiming that the comparison was misleading and calling on NodeOne to stop their advertising campaign. NodeOne took legal advice & then responded by publishing EpiServer’s letter (& helpfully an English translation).

EpiServer, regardless of the merits or otherwise of NodeOne’s comparison, scored several own goals by resorting to their lawyers. The appear arrogant, bullying and defensive – the perception is that they have something to hide, that NodeOne have touched a nerve. What was once a local Swedish issue is now an international one, thanks to NodeOne releasing English translations of EpiServer’s legal response.

EpiServer are now brand firefighting – they turned a product comparison into a brand defence, which is harder for people to forget. Their head of European Marketing even resorted to defending their position on NodeOne’s website – which smacks of desperation and only served to enhance NodeOne’s position as defender of free speech against an over mighty corporation.

Its a big bad world out there and companies are right to seek to protect their brand, but resorting to lawyers is rarely the best thing to do online, even when legally you may be correct. Online you have few controls over what happens and the story can spiral out of your control very quickly and messily. You have to be subtle in your responses – lawyers are not noted for their subtlety.