Archive for the ‘PHP’ Category

Laravel .htaccess localhost MAMP and Mac OS X

I was, like anyone, excited about the release of Laravel 4 and quickly set about following the initial installation instructions on a vanilla vhost locally to have a play around with. I quickly found that the default suggested .htaccess file was causing a server error in MAMP on OS X.

I got around it with a little trial and error and can confirm the below contents in your .htaccess file – works great for me.

Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php [L]

The offending line from the suggested .htaccess contents was

RewriteRule ^ index.php [L]

Install Laravel with symlink through terminal shell function/command mamp

I’ve been throwing together a few useful mac terminal os x shell scripts lately and this was another one of those cases today. It’s not completely finished just yet but it will do a job the first time round. I’m not sure just yet how best to have lots of different symlinks to different Library bases and how to code that so that it happens.

The below code and it’s paths are relevant to me and my setup with MAMP. You can easily edit this function to include different paths as you require.

Open up your ~/.bash_profile

sym-install-laravel () {
    echo "Installing Laravel as symlink to $1"
    mkdir -p ~/Develop && cd ~/Develop
    DIR="/Users/davidheward/Develop/Laravel"
    if [ ! -d "$DIR" ]
    then
        git clone https://github.com/laravel/laravel.git Laravel
    else
        echo "Directory already exists"
    fi
    cd /Applications/MAMP/htdocs
    ln -s ~/Develop/Laravel/public/ /Applications/MAMP/htdocs/$1
    cd /Applications/MAMP/htdocs/$1
    echo "Install complete"
}

Save it close and open a new terminal session or reload profile ./profile

Then you can simply cd into your desired directory for me it's /Applications/MAMP/htdocs/ because i'm running MAMP on my Mac OS X machine and run the following at the terminal.

$ sym-install-laravel symlara

Visit this by just hitting http://localhost/symlara/ in your browser (if you have localhost configured in this way of course).

Translating PHP application using gettext & msgfmt with .po / .mo files

Firstly install the gettext cmd line tools.

brew install gettext
brew link gettext

If your not a big fan of homebrew you can do the same using macports. Personally I really like homebrew and if you’d like to give it a try go to Homebrew. This will install useful cmds such as xgettext, msgfmt, msginit & msgmerge.

Fire up a fresh terminal and cd into your PHP apps working directory /Applications/MAMP/htdocs/my_app/ in my case.

I’d suggest getting yourself a local environment to test this on. I’m using MAMP and have created a new folder in the htdocs called localetest. Call it whatever you like and create a few PHP files with strings of echo gettext("This is translatable string"); or echo _("This is translatable string");

Once you’ve done this open up a terminal and cd into your cd /Applications/MAMP/htdocs/yourfoldername/

Once in it your going to run a command which will recursively search through the PHP files in this entire directory looking for translatable strings.

find . -name "*.php" | xargs xgettext -a --from-code=utf-8

or more simply

find . -iname "*.php" | xargs xgettext

The first part of this command will search recursively starting from the current level of directory structure for .php files. xargs builds and executes from standard input and executes the xgettext command for each file. This command searches the input from the found files for strings of gettext() or _() in a .php file and outputs them into a messages.po file.

Run the command and you’ll end up with a file a little like this one.

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSIONn"
"Report-Msgid-Bugs-To: n"
"POT-Creation-Date: 2013-01-17 10:13+0000n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONEn"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>n"
"Language-Team: LANGUAGE <LL@li.org>n"
"Language: pt_PTn"
"MIME-Version: 1.0n"
"Content-Type: text/plain; charset=UTF-8n"
"Content-Transfer-Encoding: 8bitn"
#: another.php:3
msgid "Another string in file 2"
msgstr "mumbo jumbo"
#: index.php:3
msgid "Lets make this a translatable string"
msgstr "oh mumbo jumbo la la la"
#: index.php:4
msgid "Another translatable string"
msgstr "Otra cadena traducible"
#: index.php:5
msgid "Something here"
msgstr "Algo aquí"

If you look toward the bottom of this file you’ll notice it’s picked up our translatable strings. Also, notice, I have manually filled in the language this is going to correspond to under “Language: pt_PTn” and also set the character under the content type: “Content-Type: text/plain; charset=UTF-8n”. You’ll also notice I made some mumbo jumbo translations (which are not portuguese) to illustrate the translation.

Create a directory structure in your app which is going to help you organise your translations for instance mine is something like this.

Screen Shot 2013 01 17 at 11.29.56 Translating PHP application using gettext & msgfmt with .po / .mo files

Example folder structure for gettext

Once you have created th

Once you create this you will need to fire off a few more cmd line cmds. So fire up your terminal boys…

The next cmd you will run will create a .mo file which is a machine readable binary file used by gettext in PHP to quickly provide the translations.

msgfmt -cv -o locale/pt/LC_MESSAGES/messages.mo locale/messages_pt.po

After you run this cmd you should get a response finishing in 4 translated messages. This is actually the last step in the creation of files. Next we need to configure our app to detect the locale and forcibly translate our gettext snippets on the fly for us.

This can be achieved in a multitude of different ways and my solution below will not suit all. It is mainly here for demonstration purposes only. In the top of any of your .PHP files in your local directory add the following code.

$locale = "pt_PT";
putenv("LC_ALL=$locale");
setlocale(LC_ALL, $locale);
bindtextdomain("messages", dirname(__FILE__).'/locale');
textdomain("messages");

This will force your app to use the locale pt_PT and in doing so use the translations provided by you in the .po file.

Important: Each time you provide more translations you must re-build the .mo files with the following command.

msgfmt -cv -o locale/pt/LC_MESSAGES/messages.mo locale/messages_pt.po

Edit:

I recently found that when receiving translations from Windows users (as is the case quite often) the .po files need to be re-saved with UTF-8 encoding. I also found sometimes Windows users might get .BOM extension added to the files as well. This will not be interpreted by msgfmt correctly and will result in a fatal error on compilation. A save in the correct encoding will fix this.

Also another handy tip when installing gettext for translating:

Since I wrote this post the brew formula for gettext has changed and now is ‘keg-only’ you will find it is not symlinked and symlinking it may cause issues when installing and compiling other applications.

Even though it is not symlinked you can still find the binary like so:?
/usr/local/Cellar/gettext/0.18.2/bin/msgfmt -cv -o locale/fr_FR/LC_MESSAGES/messages.mo translations/messages_fr.po

Best installation guidelines for MAMP and PHPUnit

These are the best guidelines I have found and mashed together recently for installing and configuring PEAR and PHPUnit for use with MAMP.

Firstly tell PEAR to auto discover:

sudo /Applications/MAMP/bin/php/php5.4.4/bin/pear config-set auto_discover 1

Secondly install the PHPUnit PEAR package:

sudo /Applications/MAMP/bin/php/php5.4.4/bin/pear install pear.phpunit.de/PHPUnit

Thirdly link it to your profile:

sudo ln -s /Applications/MAMP/bin/php/php5.4.4/bin/phpunit /usr/local/bin/phpunit

Lastly test it:

phpunit --version

Should output:
PHPUnit 3.7.10 by Sebastian Bergmann.

All done!