Tuesday, January 29, 2013

New Year, New Work


It's been a little while since my last post! Thankfully, work has been keeping me off of the streets. I've launched or relaunched a few web sites since then, and produced quite a few print projects as well. For the billions of you out there who don't already know this, my company, originally PrintElectric, Inc., was rebranded as Pumphouse Creative last year. Same great taste, new bottle, you know how it goes.


PMC Connection






This web site was actually relaunched last June, but I've been too busy to talk about it. It was my first e-commerce project, and the first of what I hope will be many Magento sites. In addition to the web site itself, we've been included in a nice little blog post by our client.


The web site is doing very well, with site visits up 69%, pageviews up 497%, and bounce rate down 42% since the relaunch. Overall, I'd say our experience with Magento has been a great one. It definitely takes time and real, serious hair-pulling work to get things where you want them, but there are so many things that work so well out of the box, I think it's well worth the effort. One issue that has remained difficult is getting extensions to perform as advertised. So far I've had success with only the simplest of extensions, and have had some well reviewed extensions fail to work at all, much less as intended.


I would advise potential Magento shop owners to think carefully about specific features that they might want, which might not be included in a standard Magento installation, and to test any 3rd party extensions very carefully before committing to use them in a production environment.

Tuesday, April 17, 2012

Magento Custom CMS Layouts


http://www.pulsestorm.net/nofrills-layout-chapter-six/

Thursday, January 26, 2012

Installing Zend Framework on Plesk server

I've been playing with Zend Framework recently, and have a small project that I think would be a good fit for it. So I'm going to try tossing Zend on my Plesk server and see if it's as simple to set up as they say it is.

Poking around my phpinfo output and my server, I'm opting to install to /usr/share/zend/ and update my PHP include path to reflect that. Looking at other posts on similar installations, I think I will also have to update php's open_basedir setting, which I should be able to do for each of the vhosts that will use Zend.

Crossing fingers now...

OK! A couple of adjustments required, but all things considered, pretty painless. First of all, the default application framework created by the zend command line tool (ie. zf create project projectname) will try to load the Zend libraries with an require_once("Zend/Application.php") and drill down from there. To make this work out, I moved the Zend libraries from /usr/share/zend to /usr/share/zend/Zend and then added :/usr/share/zend to the include_path in /etc/php.ini.

So download and uncompress Zend, and then put the contents of the Library folder here:

/usr/share/zend/Zend

On the average Unix install, the php.ini file to edit is:

/etc/php.ini
Just search for "include_path" and add the following after whatever is already there, in between the quotes of course:
:/usr/share/zend

You could opt to leave your files in /usr/share/zend or wherever, and add :/usr/share to your include path, but I don't want PHP to be able to include files from everywhere inside my /usr/share folder, which I think is the only other option.

In order for the virtual hosts under Plesk to be configured to work with a default Zend project, you'll need a vhost.conf file here:

/var/www/vhosts/yourhostname/conf/vhost.conf

Here's the contents of my vhost.conf file:

DocumentRoot /var/www/vhosts/yourdomain.com/httpdocs/public
<Directory /var/www/vhosts/yourdomain.com/httpdocs>
    <IfModule sapi_apache2.c>
            php_admin_flag engine on
            php_admin_flag safe_mode off
            php_admin_value open_basedir "/var/www/vhosts/yourdomain.com/httpdocs:/tmp:/usr/share/zend"
    </IfModule>
    <IfModule mod_php5.c>
            php_admin_flag engine on
            php_admin_flag safe_mode off
            php_admin_value open_basedir "/var/www/vhosts/yourdomain.com/httpdocs:/tmp:/usr/share/zend"
    </IfModule>
</Directory>

This does a couple of things to override the default httpd.include file (which Plesk writes to configure Apache for your vhost).

First of all, it points the document root down to the public/ directory, which is where the Zend framework expects to find the contents of your web site (css, images, javascript files -  anything that needs to load into the browser and doesn't come from a database).

Secondly, it overrides the default value for open_basedir, which would otherwise restrict PHP from loading the Zend libraries (and anything else not under httpdocs). You can set this to "none" if you're brave, but I preferred to only punch a hole through to the Zend libraries. This should keep PHP from accessing any other files on the server that it shouldn't, which is good for security. Otherwise, a malicious (or just poorly built!) script could have access to your entire server. No thanks!

Following these adjustments, I was able to upload the project folders that the zf tool created on my local test server to the "httpdocs" folder, and get the blue-and-green Zend screen of happiness. Yeah!

Just to be completely clear about that last part, the Zend project goes in "httpdocs", not the "public" folder that you specified in the document root. If you've already been using Zend, this will make sense, if not, it will eventually.

Monday, November 7, 2011

Permissions settings for Joomla

I'm working on a new installation of Joomla Version 1.7.1. For those of you who don't know this, Joomla needs access to several directories in order to read and write cache files, upload images, and install plugins and extensions. If Joomla does not have read and write privileges to those directories, certain functions (some of them vital) will fail. I'm going to give Joomla the access it needs on my Red Hat EL 5.6 server using access control lists.
IMPORTANT: Use at your own risk. I'm sort of a newbie when it comes to server admin issues. I'm running a RHEL 5.6 server hosted with Softlayer, so I have people to call if I happen to screw something up. My server is also running Plesk, and I'm not sure how that changes the specifics (user IDs, default permissions, whether or not ACLs are enabled). I am NOT covering how to enable and disable access control list support on your drive here. My understanding is that ACLs must be enabled on the drive when it is mounted, and that the drive must be unmounted and remounted in order to turn them on if necessary. Mine were already on, so I'm just covering how to add access control lists to individual files / folders within my Joomla installation.
Step one is probably to find out whether or not you need this. I'm a big advocate of doing absolutely nothing that you don't have to do to your web server. So log in to Joomla as an admin or super admin. Then go to Site -> System Information -> Directory Permissions. You should see a long list of directories, each with a "Status" out to the right, which will either be Writable (good), or Unwritable (bad). For my particular installation, all of these directories ended up being Unwritable, so the commands that follow will add access control lists to enable Joomla (via PHP, via Apache) to read and write to all of these directories.
EXAMPLE
setfacl -m u:apache:rwx administrator/components 
The first directory on my list was administrator/components, so my first example should add read, write, and execute privileges to that directory. Breaking it down as follows:
  • setfacl -- this calls the setfacl utility if it is available on your system
  • -m -- tells setfacl that we're going to modify an access control list (in this case we're adding, but -m seems to be the appropriate command for either modifying or adding, from my research)
  • u: -- we're going to add/modify permissions for a user. If you wished to add/modify permissions for a group instead, this would be 'g:'
  • apache: -- the name of the user that we're modifying permissions for (followed by a colon). This may be different on your system. I haven't been able to uncover the command to list process names, so you're on your own finding out the name of your apache process. Common values are apache, www, _www - depending on your system. My understanding is that you should be able to find this with
    ps -au | grep httpd
    , but I haven't been able to get that to work on my system. Maybe some nice person will throw that in a comment for us.
  • rwx -- the permissions that we wish to enable. I think we could have gotten by with rw instead of rwx here, and this might be safer from a security standpoint. This probably calls for some more research...
  • administrator/components -- the name of the directory and or file that you're modifying permissions for
That about wraps it up. So without further beating around the bush:
setfacl -m u:apache:rwx administrator/language
setfacl -m u:apache:rwx administrator/language/en-GB
setfacl -m u:apache:rwx administrator/language/overrides
setfacl -m u:apache:rwx administrator/manifests/files
setfacl -m u:apache:rwx administrator/manifests/libraries
setfacl -m u:apache:rwx administrator/manifests/packages
setfacl -m u:apache:rwx administrator/modules
setfacl -m u:apache:rwx administrator/templates
setfacl -m u:apache:rwx components
setfacl -m u:apache:rwx images
setfacl -m u:apache:rwx language
setfacl -m u:apache:rwx language/en-GB
setfacl -m u:apache:rwx language/overrides
setfacl -m u:apache:rwx libraries
setfacl -m u:apache:rwx media
setfacl -m u:apache:rwx modules
setfacl -m u:apache:rwx plugins
setfacl -m u:apache:rwx plugins/authentication
setfacl -m u:apache:rwx plugins/content
setfacl -m u:apache:rwx plugins/editors
setfacl -m u:apache:rwx plugins/editors-xtd
setfacl -m u:apache:rwx plugins/extension
setfacl -m u:apache:rwx plugins/search
setfacl -m u:apache:rwx plugins/system
setfacl -m u:apache:rwx plugins/user
setfacl -m u:apache:rwx templates
setfacl -m u:apache:rwx configuration.php
setfacl -m u:apache:rwx administrator/cache
If you've done any editing at all on your new site, you will have multiple subdirectories in your 'cache' folder. So I'm going to run the ACL addition for the cache directory again with the -R flag for recursive:
setfacl -R -m u:apache:rwx cache
This allowed me to clear the cache successfully from Site -> Maintenance -> Clear Cache, which I had been unable to do previously. If you still encounter errors, you might need to re-run additional entries here with the -R flag set.

One last note: My local test server is a Mac, so their is no

setfacl
command in the default installation (although I've heard that you can install some additional software to make that happen). The Mac implementation is just a set of options for chmod. So this is a very different command:
chmod +a "userid permissionsToAdd" fileOrFolder
. For me, this turns out to be something like this:
chmod +a "_www allow read,write,delete" configuration.php
for files, and
chmod +a "_www allow read,write,delete,add_file,add_subdirectory" plugins
for directories. Notice the extra directory-specific commands add_file and add_subdirectory. Another thing to note about this command - it is whitespace sensitive, so make sure there are no spaces after your commas in the permission list. That screwed me up the first time around. Also, if you want to catch everything in a directory, you can add -R for recursion (chmod -R +a etc.)

Good luck, and please comment if this helped you out, or if I screwed anything up here.

Friday, October 14, 2011

Permissions Settings for Magento

I'm working on a fresh install of Magento 1.6 to do some testing for a new site, and am reminded of one of the (few) annoying aspects of the Magento installation process. Magento needs write permission to certain files and directories within the installation. This is not a problem, but instead of telling you about all of these at once, Magento tries to access them one at a time, and halts the installation at each level within the directory structure. Anyone who has looked at Magento can tell you that it's not something that you want to monkey with one file at a time, but if you install via FTP and just follow the web installer instructions, that is exactly how Magento will lead you through.

IMPORTANT NOTE: The commands below are specific to Mac OS X, and probably will not work in any other environment. These commands are being executed from the Magento root directory, so you would have to modify the paths at the end of each line if you want to run them from elsewhere. Finally, the "_www" is the user id of my local Apache server. Depending on your system, this might be different, but is probably something like www, _www, apache, etc.

NEW AND IMPROVED: I've had to do some additional work on this issue, this time for Joomla, and this time working on a virtual dedicated server running Red Hat EL 5.6. So I'm going to do a separate post which will explain how to solve this same problem on Linux, which is a different set of commands. The basic command is:

setfacl -m u:apache:rwx cache
To apply this to your own solution, 'apache' is the user ID of your web server (or whatever user you need to change permissions for), 'rwx' is short for read, write, execute, and 'cache' is the directory or file for which you need to alter privileges. More on this in a few minutes!

chmod +a "_www allow read,write,delete,add_file,add_subdirectory" app/etc/
chmod -R +a "_www allow read,write,delete,add_file,add_subdirectory" media/
chmod -R +a "_www allow read,write,delete,add_file,add_subdirectory" var/

These three lines give Magento 1.6 access to everything that it needs to complete installation. But what did I just do, you might ask? These commands are adding access control lists to three folders in your Magento site. Access Control Lists offer slightly more fine-grained control over permissions than standard Unix permissions. If you think of Unix permissions as a wall, we just removed three bricks. The commands for adding access control lists on the Mac were implemented as options for chmod (which is the standard Unix utility for modifying file permissions. Here's how it breaks down:

  • The plus sign just after chmod in the first line indicates that we are adding an access control list. Similarly, if you need to remove an access control list entry, that is done with a minus sign (-a)
  • The quoted string is the actual access control entry, which includes 3 parts, each separated by a space. First is the user for which access is being altered, second is the type of alteration (allow or deny), finally is the list of actions that are being allowed or denied for that user. In this case, the specified user is _www (which is the user that owns the httpd process). The type of alteration is "allow", as we are trying to enable additional access. The included actions are read, write, delete, add_file, and add_subdirectory. Note that this list does NOT include spaces after the commas.
  • Last but not least, we have to supply the path for the file or directory that we are asking chmod to apply these changes to
  • Also, notice the addition of the standard -R flag for the second two lines. This applies the access control list recursively to all subdirectories and files within the specified directory. Magento needs access to everything within /var and /media to do its thing...

The thing that I like about this is that it leaves the original file or folder's owner and group, and their permissions, unchanged. The access control list is an addendum to those permissions. So we don't have to worry about inadvertently enabling or denying access to any other users or groups. Additionally, if this rule doesn't work they way we expect, we can simply delete it, leaving all original ownership and permissions intact.

For more on Access Control Lists, start with this article.

Good luck!

Monday, June 20, 2011

Magento installation issues

I had a few weeks hiatus from my Magento site, but I'm getting back into the swing of it now. Since Magento is relatively complex, and new to me, I got it up and running in my Subversion repos today - so I can back up when I break my Magento installation, which seems like it might happen frequently.

The way I'm used to working on most sites that I develop is to do most of my major work on my laptop and post changes to the live site as necessary. I periodically back up databases from both locations, and sometimes make changes to data on live sites which I then dump back to my laptop, and vice-versa. Magento makes that process a little more complicated than what I'm used to. First of all, doing a full dump of Magento's database takes more than a few seconds. I did a dump after inputting my first few products, and ended up with 7500+ lines of SQL, or almost 800k. Most of that is table definitions and configuration defaults.

Secondly, much of Magento's critical configuration data for PHP is stored in database tables. I'm fine with that, but I'm much more accustomed to systems which simply load a config file full of PHP variable declarations. That approach keeps configuration separate from the SQL data, which is nice if you're dumping said data back and forth between a test server and a live server.

The most obvious issue is that my test and live servers are, of course, on different domains, and the domain names are stored in the SQL data. So dumping the database either direction breaks the configuration on the receiving end. After going through this process a few times, my solution is to do a full dump from my live server, search and replace the resulting SQL file to replace all references to mydomain.com with my local server address. Another side note, Magento does not like localhost, but is fine with 127.0.0.1. So for this operation, I'm searching and replacing mydomain.com with 127.0.0.1/mydomain.com. This works fine for the SQL data, and your local install should be up and serving pages for the front end of your site after you dump the updated SQL into your local database.

Next up, as one would, I headed straight over to the admin side of the site, and was greeted with a 404 error. The 404 error is loading on Magento's template, so I know Magento is at least routing the request and generating the 404 page (as opposed to the alternative, in which case I might have gotten a 404 from my server, but it would not have ended up in a nice pretty Magento template).

After googling several solutions to this problem,
the one that worked for me was here. I'm not sure how the solution is even related to my 404 error, but luckily there are people out there much smarter than I am who have managed to figure these things out. So per the instructions in the link above, I ran this SQL query verbatim on my local database:
SET FOREIGN_KEY_CHECKS=0;
UPDATE `core_store` SET store_id = 0 WHERE code='admin';
UPDATE `core_store_group` SET group_id = 0 WHERE name='Default';
UPDATE `core_website` SET website_id = 0 WHERE code='admin';
UPDATE `customer_group` SET customer_group_id = 0 WHERE customer_group_code='NOT LOGGED IN';
SET FOREIGN_KEY_CHECKS=1;

Worked like a charm.

So now I have my Magento install running well on both my local and remote servers, and at least a workable workflow for getting data from A to B. My next big project is to develop a custom module to create and edit a hierarchical menu for content pages. Full disclosure: there's already a very nice hierarchical menu generator here, but I'm going to suck it up and write my own. I want the experience of digging down a little deeper into Magento, and the price for this is a little much for my current clients. I'll post again once I get into the nitty gritty on the module. Bye for now!

Tuesday, May 10, 2011

Building my first ecommerce site with Magento 1.5

Baby Steps
Hello again. I've been busy with print work for most of the last couple of months, built a small Joomla site as well, but now it's time to get serious. I have an old friend who needs a new ecommerce site, and after some research, I'm taking a crack at Magento.

First of all, no I'm not crazy. I'm aware that Magento is the man eating shark of ecommerce platforms, and I ain't skeered. I'm diving in. Will it be worth the effort? I'll let you know in a bit. If not, you can read as the entire ugly saga unfolds here. I will be like one of those really awful action TV reality shows. Watched "Wipeout" in the hotel room on a business trip recently. Yeah, if I can't get this site built, it will be like that...

On to some hopefully useful information. First of all, I will say plan on installing Magento at least twice three times. There is a lot of configuration to do when you first get started, and it will take you a few trips through to get everything really buttoned up... maybe. Secondly, AFAIK there is no sample data for Magento 1.5. So what you get is a blank page once you're through the config. Get used to that feeling. Finally, I will reiterate the warnings from everything else that I've read. This is not going to be a quick, up in a week kind of venture. I've been hacking around in PHP for a good part of the last 6 years, and my first look at the Magento templating structure was pretty daunting. I'm starting to get the hang of it, after about 2 weeks of research and tweaking around on a couple of test sites. I'm hoping to have a working site up within 2-3 months.

Installation I: PHP upgrade
I'm going to focus on Plesk here, because that's what I've been stuck with. Magento 1.5 requires the following (pulled from Magento China) :

# Linux or another UNIX-compatible operating system (Windows is also supported, but see the Known Issues section below)
# Apache Web Server (1.x or 2.x)
# PHP 5.2.0 or newer, with the following extensions/addons:

* PDO/MySQL
* MySQLi
* mcrypt
* mhash
* simplexml
* DOM

# MySQL 4.1.20 or newer
# A Sendmail-compatible Mail Transfer Agent (MTA) – Magento will connect directly to an SMTP server if you don’t have an MTA

If you happen to be running Plesk 9.5.1, like me, you're in for some fun. After a failed attempt at upgrading PHP on my server, and a fun day of server down time, followed by an OS reload, I discovered the PHP package upgrade for Plesk from Atomic Corp. This was an absolute lifesaver. After backing up EVERYTHING, I was able to complete this upgrade in a couple of hours, with almost no downtime (just time enough for a server boot). The only gotcha for me was that I didn't have mcrypt loaded. I was able to get that with "yum install php-mcrypt" after completing the rest of the install using the instructions linked above. You will get a warning about a conflict with Sitebuilder somewhere along the way, but can choose to disable sitebuilder. I can't remember exactly how that worked out, but I know that "Edit in Sitebuilder" is now grayed out in my Plesk control panel. Never used it, so I don't know what I'm missing. Everything else was already good to go on my server, so on to Magento.

Installation II: Magento
If you have SSH access to your server and the right permissions, you can upload the Magento ZIp file and then unzip on the server. This will save some upload time. After it's extracted, you can either leave Magento in it's folder, or move all of the files / folders up one level to your document root. That is what I decided on, as I think Magento is enough to deal with on it's own without cluttering up the site with anything else.

If you point your browser at http://your-domain.com/, you should now see the first page of the Magento install widget. If not, Magento will probably be telling you to install additional PHP modules. Good luck with that. If you've made it to the install widget, you're golden.

At this point, you will need to install an empty database on your server, and create a user and grant some permissions for the new database. You'll need a database name, user name, and password to input so that Magento will be able to access your database and create tables. This should be very straightforward if you've ever installed Joomla / Wordpress / Mambo / etc.

A quick word on the URL issue. Complete the installation on localhost is a bit tricky. Magento does not like localhost. If you substitute 127.0.0.1 for localhost, you're good to go. If you google this, you'll find a hack that will enable you to complete the install using a localhost/domain setup, but it looked kind of cheesy to me. So far I haven't had any issues related to using the IP address for this configuration.

Installation III: The Back End
OK So I'm falling asleep now. I hope you're more entertained than me. I promise to finish this up in the next couple of days, and hopefully get to the fun part - a working store - pretty quickly. But I'm all done for tonight. Just have time for a beer and a little Medal of Honor ;)

OK. I'm back again. If you've completed the Install Wizard, and click "Go to frontend", you should be looking at something about like this:

Yeah. Before you get too excited though, make sure you can log in to the back end. Go to your backend URL, which should be something like http://127.0.0.1/mydomain.com/admin/. Plug in the username and password that you created (and hopefully wrote down) for the installation wizard. If that works, you should see the following:


There are some critical settings on the back end that you should fix before you really get rolling. Number one, make sure the base URLs are set. From the admin dashboard, go to System -> Configuration. When the Configuration page loads, you'll see a menu labeled 'Configuration' at top-left. From there, click on 'Web'. This will bring up a ton of options more or less related to the way page requests are handled. There are two things which we need to edit here, or Magento will complain. Those are the two Base URL entries, one under each of the 'Unsecure' and 'Secure' headings. I don't have an SSL cert installed on my laptop, so I'm using the same URL for both: http://127.0.0.1/mydomain.com/. So far, this has worked just fine for testing purposes. Obviously in a production environment, you will want SSL to be up and running properly, and will need to set these paths to 'httpdocs' and 'httpsdocs' (or whatever your server layout requires).

Next, I recommend that you disable Magento's caching while you're working to get your store up and running. I have not taken the time to crawl through the code and find out exactly what Magento caches and where, but with the caching enabled I found myself having to stop working and flush Magento's cache every few minutes to see my changes. Obviously, you'll want to revisit this when you migrate to a production server, but for development and testing, the cache is much more annoying than helpful.

So from the admin dashboard, go to System -> Cache Managment. Click on the "Select All" link at top left, select 'Disable' from the drop-down menu at top right, and then click 'Submit'. You should then see the following: