Setting Magento to use SMTP

In my new work we run a Magento eCommerce store. As such, I’ve set up a fresh Vagrant Box through http://www.puphpet.com (try it!) and installed Magento into one of the vHosts. Stupidly, I forgot my password almost immediately, which highlighted a problem! Mail wasn’t sending out.

Of course, Zend_Mail defaults to using Zend_Mail_Transport_Sendmail and not Zend_Mail_Transport_Smtp, so I looked around for how to set this in Magento. Everyone on IRC told me to use 3rd party software! I checked it out, and the thing is totally insecure! https://github.com/aschroder/Magento-SMTP-Pro-Email-Extension/issues
So I decided against that.

The real answer lies in the way that Magento overrides existing classes. I told the guys in the #magento IRC channel that I refused to use the above insecure library, and would rather just hack the core ZF class.

It turns out that you can create a local directory in /app/code. So for a completely customised Zend_Mail without touching third party vendor files (ie. the ZF lib), you create /app/code/local/Zend/Mail.php, and tweak away to your liking!

line 1175 is the culprit . Change

$transport = new Zend_Mail_Transport_Sendmail();   // the ZF default
to
$transport = new Zend_Mail_Transport_Smtp();

Lastly, if you need to set a custom port (on my dev box, I wanted all my mail going through port 1025 so that Mailcatcher would stop development mails going out), then run the following SQL query on your DB:

INSERT INTO `core_config_data` (`config_id`, `scope`, `scope_id`, `path`, `value`) VALUES (NULL, 'default', 0, 'system/smtp/port', '1025');

If you set a  db prefix then tweak the above table name to suit. That should be you ready to rock! Have fun!

Advertisements

PHP Developers notes when upgrading to Mac OS X Mavericks

Yay! Free OS upgrade! But oh! Something’s bound to be affected, my apache or php or something. And you’d be right. So here are my list of issues I had, and how I overcame them.

First up, Mavericks looks really cool, and seems to zip along a lot faster than lion did. Nice one! A few other nice looking things, I’ll get into those later, but are my sites loading? I open Safari, type in one of my vhosts, and then it displays a white web page with a times new roman bold h1 tag claiming ‘It works!’. Yes, Apache is working, but not a lot else! :-s

When I finally realised a while back that all-in-one things like XAMPP are actually no good for serious development, I got my PHP running with the built in Apache, and the same tweaks apply here. Edit /etc/apache2/httpd.conf :

#LoadModule php5_module libexec/apache2/libphp5.so
to
LoadModule php5_module libexec/apache2/libphp5.so

And allow use of .htaccess to override:

AllowOverride All

That should bring you back up. I wasn’t getting any db connection, so I checked to see if my MySQL server was still running. It reported so, so I fired up SequelPro and was able to get access to my data. Hmm.

My next thought that possibly more modules for apache were needing installed or something. I checked a phpinfo();  It was running v5.4.17, with no debug or anything installed, so I guessed it was the Mavericks installed PHP. I thought, well, if I’m updating, we might as well have PHP 5.5 installed, so I went to work on that.

The terminal command ‘port’ experienced difficulties, and I quickly realised that I would need to update Xcode, and Xcode Developer Command Line Tools. Once you have done that, open Xcode up, and agree to the terms and conditions, then close it. If you don’t do this some of the terminal commands will fail.  Then you can run :

sudo port self update
sudo port upgrade outdated

I came across a hanging point when it was trying to build a thing called ‘boost’. Apparently other people on the net were complaining about the same thing but no one had an answer. After failing a few times I decided I would concentrate on just upgrading packages that I needed, so I typed this to see what was already installed: (results listed to give you an idea of what i have running)

$ port -qv installed
  apache2 @2.2.22_2+preforkmpm platform='darwin 11' archs='x86_64'
  apache2 @2.2.25_0+preforkmpm (active) platform='darwin 13' archs='x86_64'
  apr @1.4.6_1 platform='darwin 11' archs='x86_64'
  apr @1.4.8_0 (active) platform='darwin 13' archs='x86_64'
  apr-util @1.4.1_0 platform='darwin 11' archs='x86_64'
  apr-util @1.5.2_1 (active) platform='darwin 13' archs='x86_64'
  autoconf @2.69_0 platform='darwin 11' archs='noarch'
  autoconf @2.69_2 (active) platform='darwin 13' archs='noarch'
  automake @1.12_0 platform='darwin 11' archs='noarch'
  automake @1.14_0 (active) platform='darwin 13' archs='noarch'
  boost @1.50.0_0+no_single+no_static (active) platform='darwin 11' archs='x86_64'
  bzip2 @1.0.6_0 (active) platform='darwin 13' archs='x86_64'
  corkscrew @2.0_0 (active) platform='darwin 11' archs='x86_64'
  cppunit @1.12.1_0 (active) platform='darwin 11' archs='x86_64'
  curl @7.27.0_1+ssl (active) platform='darwin 11' archs='x86_64'
  curl-ca-bundle @7.27.0_0 (active) platform='darwin 11' archs='noarch'
  db46 @4.6.21_6 platform='darwin 11' archs='x86_64'
  db46 @4.6.21_8 (active) platform='darwin 13' archs='x86_64'
  db_select @0.1_2 (active) platform='darwin 13' archs='noarch'
  dirac @1.0.2_1 (active) platform='darwin 11' archs='x86_64'
  docbook-xml @5.0_0 (active) platform='darwin 11' archs='noarch'
  docbook-xml-4.1.2 @4.1.2_1 (active) platform='darwin 11' archs='noarch'
  docbook-xml-4.2 @4.2_0 (active) platform='darwin 11' archs='noarch'
  docbook-xml-4.3 @4.3_0 (active) platform='darwin 11' archs='noarch'
  docbook-xml-4.4 @4.4_0 (active) platform='darwin 11' archs='noarch'
  docbook-xml-4.5 @4.5_0 (active) platform='darwin 11' archs='noarch'
  docbook-xml-5.0 @5.0_0 (active) platform='darwin 11' archs='noarch'
  docbook-xsl @1.76.1_1 (active) platform='darwin 11' archs='noarch'
  dyld-headers @239.3_0 (active) platform='darwin 13' archs='noarch'
  expat @2.1.0_0 (active) platform='darwin 13' archs='x86_64'
  ffmpeg @0.7.13_2+gpl2+mmx (active) platform='darwin 11' archs='x86_64'
  fftw-3 @3.3.2_0 (active) platform='darwin 11' archs='x86_64'
  fontconfig @2.9.0_1 (active) platform='darwin 11' archs='x86_64'
  freetype @2.4.10_0 (active) platform='darwin 11' archs='x86_64'
  gdbm @1.10_1 platform='darwin 11' archs='x86_64'
  gdbm @1.10_2 (active) platform='darwin 13' archs='x86_64'
  gettext @0.18.1.1_2 platform='darwin 11' archs='x86_64'
  gettext @0.18.3.1_1 (active) platform='darwin 13' archs='x86_64'
  ghostscript @9.05_3 (active) platform='darwin 11' archs='x86_64'
  glib2 @2.32.4_0 (active) platform='darwin 11' archs='x86_64'
  gperf @3.0.4_2 (active) platform='darwin 13' archs='x86_64'
  gsed @4.2.1_2 (active) platform='darwin 11' archs='x86_64'
  help2man @1.40.5_3 platform='darwin 11' archs='x86_64'
  help2man @1.40.10_0 (active) platform='darwin 11' archs='x86_64'
  htop @0.8.2.1_0 (active) platform='darwin 11' archs='x86_64'
  icu @4.8.1_0 platform='darwin 11' archs='x86_64'
  icu @51.2_1 (active) platform='darwin 13' archs='x86_64'
  ImageMagick @6.7.9-0_1+q16 (active) platform='darwin 11' archs='x86_64'
  ircii @20111115_0 (active) platform='darwin 11' archs='x86_64'
  jbig2dec @0.11_1 (active) platform='darwin 11' archs='x86_64'
  jbigkit @2.0_2 (active) platform='darwin 11' archs='x86_64'
  jpeg @8d_0 (active) platform='darwin 11' archs='x86_64'
  lame @3.99.5_0 (active) platform='darwin 11' archs='x86_64'
  lcms2 @2.3_0 (active) platform='darwin 11' archs='x86_64'
  libedit @20120601-3.0_0 platform='darwin 11' archs='x86_64'
  libedit @20121213-3.0_0 (active) platform='darwin 13' archs='x86_64'
  libffi @3.0.11_0 (active) platform='darwin 11' archs='x86_64'
  libiconv @1.14_0 (active) platform='darwin 13' archs='x86_64'
  libidn @1.25_0 (active) platform='darwin 11' archs='x86_64'
  libmcrypt @2.5.8_1 (active) platform='darwin 11' archs='x86_64'
  libogg @1.3.0_1 (active) platform='darwin 11' archs='x86_64'
  libpaper @1.1.24_0 (active) platform='darwin 11' archs='x86_64'
  libpcap @1.2.1_0 (active) platform='darwin 11' archs='x86_64'
  libpng @1.5.12_0 (active) platform='darwin 11' archs='x86_64'
  libsdl @1.2.15_0+x11 (active) platform='darwin 11' archs='x86_64'
  libtheora @1.1.1_1 (active) platform='darwin 11' archs='x86_64'
  libtool @2.4.2_0 platform='darwin 11' archs='x86_64'
  libtool @2.4.2_2 platform='darwin 11' archs='x86_64'
  libtool @2.4.2_3 (active) platform='darwin 13' archs='x86_64'
  libunwind-headers @35.1_1 (active) platform='darwin 13' archs='noarch'
  libvorbis @1.3.3_0 (active) platform='darwin 11' archs='x86_64'
  libvpx @1.1.0_0 (active) platform='darwin 11' archs='x86_64'
  libxml2 @2.8.0_0 (active) platform='darwin 11' archs='x86_64'
  libxslt @1.1.26_0 (active) platform='darwin 11' archs='x86_64'
  lynx @2.8.7rel.1_1+ssl (active) platform='darwin 11' archs='x86_64'
  lzo2 @2.05_1 (active) platform='darwin 11' archs='x86_64'
  m4 @1.4.16_0 (active) platform='darwin 13' archs='x86_64'
  mhash @0.9.9.9_0 (active) platform='darwin 11' archs='x86_64'
  ncurses @5.9_1 platform='darwin 11' archs='x86_64'
  ncurses @5.9_2 (active) platform='darwin 13' archs='x86_64'
  nspr @4.8.9_0 (active) platform='darwin 11' archs='x86_64'
  openjpeg @1.5.0_3 (active) platform='darwin 11' archs='x86_64'
  openssl @1.0.1b_0 platform='darwin 11' archs='x86_64'
  openssl @1.0.1c_0 platform='darwin 11' archs='x86_64'
  openssl @1.0.1e_1 (active) platform='darwin 13' archs='x86_64'
  orc @0.4.16_0 (active) platform='darwin 11' archs='x86_64'
  p5.12-locale-gettext @1.50.0_6 platform='darwin 11' archs='x86_64'
  p5.12-locale-gettext @1.50.0_7 (active) platform='darwin 11' archs='x86_64'
  pcre @8.31_0 platform='darwin 11' archs='x86_64'
  pcre @8.33_0 (active) platform='darwin 13' archs='x86_64'
  perl5 @5.12.3_1+perl5_12 platform='darwin 11' archs='noarch'
  perl5 @5.12.4_0+perl5_12 (active) platform='darwin 13' archs='noarch'
  perl5.12 @5.12.4_0 platform='darwin 11' archs='x86_64'
  perl5.12 @5.12.4_1 platform='darwin 11' archs='x86_64'
  perl5.12 @5.12.4_2 (active) platform='darwin 13' archs='x86_64'
  php53 @5.3.16_1+libedit (active) platform='darwin 11' archs='x86_64'
  php53-curl @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-ftp @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-iconv @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-mbstring @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-mcrypt @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-mongo @1.2.12_0 (active) platform='darwin 11' archs='x86_64'
  php53-mysql @5.3.16_1+mysqlnd (active) platform='darwin 11' archs='x86_64'
  php53-openssl @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-soap @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-sqlite @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-xdebug @2.2.1_0 (active) platform='darwin 11' archs='x86_64'
  php53-xsl @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php53-zip @5.3.16_1 (active) platform='darwin 11' archs='x86_64'
  php54 @5.4.6_1+libedit (active) platform='darwin 11' archs='x86_64'
  php54-apache2handler @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-curl @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-ftp @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-gd @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-iconv @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-mbstring @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-mcrypt @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-mongo @1.2.12_0 (active) platform='darwin 11' archs='x86_64'
  php54-mysql @5.4.6_1+mysqlnd (active) platform='darwin 11' archs='x86_64'
  php54-openssl @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-soap @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-sqlite @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-xdebug @2.2.1_0 (active) platform='darwin 11' archs='x86_64'
  php54-xsl @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php54-zip @5.4.6_1 (active) platform='darwin 11' archs='x86_64'
  php_select @1.0_0 (active) platform='darwin 11' archs='noarch'
  pkgconfig @0.27_0 (active) platform='darwin 11' archs='x86_64'
  python27 @2.7.3_0 platform='darwin 11' archs='x86_64'
  python27 @2.7.6_0 (active) platform='darwin 13' archs='x86_64'
  python_select @0.3_1 platform='darwin 11' archs='noarch'
  python_select @0.3_3 (active) platform='darwin 13' archs='noarch'
  re2c @0.13.5_0 (active) platform='darwin 11' archs='x86_64'
  readline @6.2.000_0 (active) platform='darwin 11' archs='x86_64'
  schroedinger @1.0.11_0 (active) platform='darwin 11' archs='x86_64'
  scons @2.2.0_0 (active) platform='darwin 11' archs='noarch'
  snappy @1.0.5_0 (active) platform='darwin 11' archs='x86_64'
  speex @1.2rc1_0 (active) platform='darwin 11' archs='x86_64'
  spidermonkey @1.7.0_5 (active) platform='darwin 11' archs='x86_64'
  sqlite3 @3.7.14_1 platform='darwin 11' archs='x86_64'
  sqlite3 @3.8.0.2_0 (active) platform='darwin 13' archs='x86_64'
  tiff @3.9.5_0 (active) platform='darwin 11' archs='x86_64'
  urw-fonts @1.0.7pre44_0 (active) platform='darwin 11' archs='noarch'
  webp @0.2.0_1 (active) platform='darwin 11' archs='x86_64'
  x264 @20111210_0 (active) platform='darwin 11' archs='x86_64'
  xmlcatmgr @2.2_1 (active) platform='darwin 11' archs='x86_64'
  xorg-kbproto @1.0.6_0 (active) platform='darwin 11' archs='noarch'
  xorg-libice @1.0.8_0 (active) platform='darwin 11' archs='x86_64'
  xorg-libpthread-stubs @0.3_0 (active) platform='darwin 11' archs='noarch'
  xorg-libsm @1.2.1_0 (active) platform='darwin 11' archs='x86_64'
  xorg-libX11 @1.5.0_0 (active) platform='darwin 11' archs='x86_64'
  xorg-libXau @1.0.7_0 (active) platform='darwin 11' archs='x86_64'
  xorg-libxcb @1.8.1_2+python27 (active) platform='darwin 11' archs='x86_64'
  xorg-libXdmcp @1.1.1_0 (active) platform='darwin 11' archs='x86_64'
  xorg-libXext @1.3.1_0 (active) platform='darwin 11' archs='x86_64'
  xorg-libXrandr @1.3.2_0 (active) platform='darwin 11' archs='x86_64'
  xorg-libXt @1.1.3_0 (active) platform='darwin 11' archs='x86_64'
  xorg-randrproto @1.4.0_0 (active) platform='darwin 11' archs='noarch'
  xorg-renderproto @0.11.1_0 (active) platform='darwin 11' archs='noarch'
  xorg-xcb-proto @1.7.1_0+python27 (active) platform='darwin 11' archs='noarch'
  xorg-xextproto @7.2.1_0 (active) platform='darwin 11' archs='noarch'
  xorg-xproto @7.0.23_0 (active) platform='darwin 11' archs='noarch'
  xrender @0.9.7_0 (active) platform='darwin 11' archs='x86_64'
  XviD @1.3.2_3 (active) platform='darwin 11' archs='x86_64'
  xz @5.0.3_0 platform='darwin 11' archs='x86_64'
  xz @5.0.4_0 platform='darwin 11' archs='x86_64'
  xz @5.0.5_0 (active) platform='darwin 13' archs='x86_64'
  zlib @1.2.6_0 platform='darwin 11' archs='x86_64'
  zlib @1.2.7_0 platform='darwin 11' archs='x86_64'
  zlib @1.2.8_0 (active) platform='darwin 13' archs='x86_64'

As you can see I have quite a few! But I was incredibly lucky, I typed in :

sudo port upgrade curl

And it installed, also fixing the boost problem, allowing me to continue with ‘sudo port upgrade outdated’ without the error happening!

Be prepared to wait a while for all of this compiling to go on! Once you are bang up to date we can install PHP 5.5. First lets get rid of all the old stuff compiled for your old OS (actually this works when if you put a -u flag on the sudo port -u upgrade outdated):

sudo port uninstall inactive

Now for 5.5! Feel free to add more PHP modules, full list available at the macports website.

sudo port install php55 php55-curl php55-ftp php55-iconv php55-mbstring php55-mcrypt php55-mongo php55-mysql php55-openssl php55-soap php55-sqlite php55-xdebug php55xsl php55-zip php55-apache2handler

cd /opt/local/apache2/modules
sudo /opt/local/apache2/bin/apxs -a -e -n php5 mod_php55.so

Now edit your httpd.conf to load 5.5:

LoadModule php5_module /opt/local/apache2/modules/mod_php55.so

sudo apachectl restart

Job done. My thoughts on all this? First you had all in one nonsense like MAMP and XAMPP. No good. Then we have the option of using a package manager such as MacPorts or Homebrew (macports in my case), but in all honesty I really think manually compiling and configuring everything is a much better idea, as per my other posts regarding the Ubuntu server in my work.

Sick of having to recompile everything after an OS upgrade? Think about setting up a Ubuntu Server Virtual Machine using VirtualBox! And then your server can run on any machine with any configuration, and the pain will be a lot less in the future!

Feel free to comment on anything you may have come across during the process! Everyone’s set up is different!

Install Varnish Caching on CentOS with or without cPanel interference

Without messing with cPanel or Apache’s setup, we can still install Varnish to cache our pages a lot quicker, via the iptables firewall!

The problem was that changing the apache httpd.conf didnt work as expected, as cPanel does a lot of auto generating and tweaking of system files. yuk. i much prefer a terminal any day. Anyway! Lets have a look:

yum install varnish
nano /etc/sysconfig/varnish

comment out configuration 1, 3, and 4, uncomment config 2 and set as follows:

DAEMON_OPTS = " -a :8080 \                                          
                -T localhost:6082 \             
                -f /etc/varnish/default.vcl \              
                -S /etc/varnish/secret \             
                -s malloc,256m"

The -a line is the port varnish will run on. In a normal configuration, Varnish will take over port 80, so make it port 80. In the case of a server using cPanel, if you cant change your apache port to 8080, then you can set varnish to 8080 instead.

nano /etc/varnish/default.vcl

backend default {
    .host = "127.0.0.1";
    .port = "80";
}

The backend is Apache. In a normal varnish setup, this port should be 8080.  Using a reverse system using iptables, apache stays as port 80. Also, the host should become the external IP in this configuration.

Now, depending on your setup, depends what happens next.

Without cPanel, under a standard setup, you will have set Varnish to port 80 and Apache to port 8080. In this case, you must edit your apache httpd.conf, searching and replacing :80 with :8080. Then just stop and start the services as below, skipping the iptables stuff.

With cPanel, we can leave that alone and instead use an iptable rule to send all port 80 requests to varnish at port 8080. Edit ~/.bashrc, pasting this in:

alias varnishon='iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080'
alias varnishoff='iptables -t nat -D PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080'
alias varnishstatus='iptables -L -t nat |grep -q 8080; if [ "test$?" = "test0" ]; then echo "Varnish On"; else echo "Varnish Off"; fi'

 

You can now call, varnishon, varnishoff, and varnishstatus next login. So logout and login.

Restart Apache and start up varnish:

service httpd restart
service varnish start

You should be able to access your site on port 80 AND port 8080. The difference? Run a curl command to see the headers:

curl -I http://mysite.com
curl -I http://mysite.com:8080

You’ll see the port 8080 mentions varnish.

Last thing to do is enable the iptables rule: Type in your alias command you put in bashrc:

varnishon

Now port 80 is routing to port 8080, and you have varnished pages, and haven’t touched your cPanel setup!

Considerations: the header shows the page in this weird cPanel workaround setup as 301 moved permanently. Also, the site i was using captured IP addresses, but due to the proxy nature of this setup, the ips captured belonged to the server! The actual way should be to have Apache on 8080 and varnish on 80, and no ip rules at all. If you have access to WHM or cPanel, you are looking for tweak settings, and change the default apache port to 8080 in there! Good luck!

Install ImageMagick and imagick on Mac OS X Lion

If you’ve ever done any sort of image processing in your PHP applications, you’ll start to realise how limited you are when using native PHP commands such as createimagefromjpg etc. It eats your web servers memory! Nowadays, what with people carrying 5 Megapixel cameras in their phones, uploading and resizing a photo can be areal strain on resources, especially if several users on the website are doing it at the same time.

To get around this conundrum, there is a PHP library called imagick which allows you to access a program called ImageMagick. ImageMagick runs natively on the machine, and is available for Unix, Linux, Mac, and Windows, so running it shouldn’t be a problem. The only thing to take into consideration here is whether your hosting providers PHP has imagick available. If not, depending on your hosting package you may be able to SSH into your server and install it.

ImageMagick can do all sorts of crazy image editing things, and can handle pretty much whatever you throw at it! Find out more here:
http://www.imagemagick.org/script/index.php

Anyway, looks good, so let’s get cracking! If you have been following my posts you’ll see I upgraded my PHP from the old version that ships with Lion using ports. I’m also going to use ports to get ImageMagick.

sudo port install ImageMagick

This will take up to ten minutes! It gets all its dependencies, configures, and compiles from the source code specifically for your computer’s setup. Once it’s done there are several commands you can run from the terminal:

animate
compare
composite
conjure
convert
display
identify
import
mogrify
montage
stream

For more info see http://www.imagemagick.org/script/command-line-tools.php

Now that we’ve done that, we need to install the imagick PHP library that accesses it.
Depending on your luck this may work straight away for you:

sudo pecl install imagick

When it asks for the prefix, type it /opt/local.

If it fails to install, you are probably running PHP 5.4 like me. In this case, you need to tell pear to use the latest beta, which WILL compile.

sudo pear config-set preferred_state beta
sudo pecl install imagick
sudo pear config-set preferred_state stable

Last but least you should add “extension=imagick.so” to php.ini, and restart apache. Boom! now we have a very powerful tool for image manipulation!

Update: If you get this error – Please provide a path to MagickWand-config or Wand-config program.
Then – ensure “ImageMagick-devel” and NOT “ImageMagick” package is installed instead