How to run composer.phar on Dreamhost

Dreamhost’s shared hosting offers up some challenges to get Composer’s composer.phar running.

  1. Even if your websites are setup to use PHP 5.3 or 5.4, the CLI version of php might be PHP 5.2, which is too old and doesn’t include phar. You can check this by logging into your account with a terminal via SSH and the command
    php --version
  2. Since this is a shared hosting environment, you can’t change things the way you would in own Vagrant Ubuntu box or local dev environment.

You’ll have to get through these to run Laravel 4 and other applications that rely on Composer.

GitHub user Braunson has the best walkthrough on setting up composer.phar on DreamHost that I have found. These instructions worked on my account. I did have to do the extra step of putting phprc into a 5.4 folder. After logging out of SSH and logging back in, the phar extension worked, and I could use composer.

Another way to check if phar is available is to run

php -i | grep phar

, which will pull out phar-related config info. A server with phar enabled will look like this:

Configure Command =>  './configure'  '--prefix=/usr/local/php54' '--datadir=/usr/local/php54/share' '--localstatedir=/usr/local/php54/var' '--without-pear' '--with-config-file-path=/etc/php54' '--with-config-file-scan-dir=/etc/php54/conf.d' '--with-zend-vm=GOTO' '--enable-cgi' '--enable-fpm' '--enable-libxml=shared' '--enable-bcmath=shared' '--enable-calendar=shared' '--enable-ctype=shared' '--enable-dom=shared' '--enable-exif=shared' '--enable-fileinfo=shared' '--enable-filter=shared' '--enable-ftp=shared' '--enable-hash=shared' '--enable-intl=shared' '--enable-json=shared' '--enable-mbstring' '--enable-mbregex' '--enable-mbregex-backtrack' '--enable-pcntl=shared' '--enable-pdo' '--enable-phar=shared' '--enable-posix=shared' '--enable-session=shared' '--enable-shmop=shared' '--enable-simplexml=shared' '--enable-soap=shared' '--enable-sockets=shared' '--enable-sysvmsg=shared' '--enable-sysvsem=shared' '--enable-sysvshm=shared' '--enable-tokenizer
=shared' '--enable-wddx=shared' '--enable-xml=shared' '--enable-xmlreader=shared' '--enable-xmlwriter=shared' '--enable-zip=shared' '--with-openssl=shared' '--with-kerberos' '--with-pcre-regex' '--with-sqlite3' '--with-zlib=shared' '--with-bz2=shared' '--with-curl=shared' '--with-gd=shared' '--with-jpeg-dir=/usr' '--with-png-dir=/usr' '--with-zlib-dir=/usr' '--with-xpm-dir=/usr' '--with-freetype-dir=/usr' '--with-gettext=shared' '--with-gmp=shared' '--with-mhash=shared' '--with-iconv=shared' '--with-imap=shared' '--with-imap-ssl' '--with-ldap=shared' '--with-mcrypt=shared' '--with-msql=shared' '--with-mysql=shared,mysqlnd' '--with-mysql-sock=/No-MySQL-hostname-was-specified' '--with-mysqli=shared,mysqlnd' '--with-pdo-mysql=shared,mysqlnd' '--with-pdo-pgsql=shared' '--with-pdo-sqlite' '--with-pgsql=shared' '--with-pspell=shared' '--with-readline=shared' '--with-tidy=shared' '--with-xmlrpc=shared' '--with-xsl=shared'
Registered PHP Streams => compress.bzip2, php, file, glob, data, http, ftp, http
s, ftps, zip, compress.zlib, phar
Phar-based phar archives => enabled
Tar-based phar archives => enabled
ZIP-based phar archives => enabled
phar.cache_list => no value => no value
phar.readonly => On => On
phar.require_hash => On => On

Notice all the lines towards the bottom that show phar is available.

Safari, 3rd party cookies, and Facebook apps

The default settings for the Safari web browser block 3rd party cookies. This means that web apps hosted on https://mysite.com will not be able to set cookies when displayed within an iframe in a Canvas App (https://apps.facebook.com/myappdomain) or Page Tab. Problems ensue when the web app relies on cookies for sessions and CSRF checks.

Here is an ugly but functional fix. When the page first loads within the frame, check if any cookies are set. For example, a Laravel-based site might use this PHP code in a before filter:

if (count($_COOKIE) === 0) {
     return '<script>top.location = "https://mysite.com/cookiefix"</script>';
}

This will redirect the user out of Facebook and into a page on mysite.com where the web application can set cookies as the 1st party instead of the 3rd party. With Laravel, the session token and payload cookies are set automatically at this time. Then page writes out the following code in the HTTP response to redirect the user back into the Facebook app:

'<script>top.location = "https://apps.facebook.com/myappdomain"</script>';

With a broadband connection and healthy web server, the redirect happens so fast on a speedy site that most people do not notice the URL changing to from a Facebook URL to an external URL and back. This time when the check for cookies returns a number > 0, the app continues as usual. In my experience, the app is able to make changes to the cookies now as well.

Caveats

This quick fix does not cover situations where the user is landing on a page deep in your app. If user visits https://apps.facebook.com/myappdomain/internalpage, they will be redirected back to https://apps.facebook.com/myappdomain after the cookie is set. This can be fixed by saving the full URL the user landed arrived at without cookies, and returning the user to that URL instead of https://apps.facebook.com/myappdomain.

This fix will also put users who have intentionally disabled cookies into an infinite loop of redirects between the Facebook app and /cookieredirect page. Whether or not this is an issue for your app’s audience is up to you. A way to prevent the loop may be to store the number of times the user has gone through the redirect, and send the user to a page that doesn’t redirect them again if they have gone through it more than once without the cookie being successfully set.

An Alternative

An alternative to the redirect is to briefly open a popup window containing your own site, and use a similar behaviour as the /cookiefix URL to set cookies, and then close the popup. Use an interaction like a click to open this popup, otherwise Safari may block it.

Related links:
Discussion on Stack Overflow
Another discussion on Stack Overflow

Laravel 3 Admin Area bundles

Opinions based on spending less than an hour with each bundle:

Orchestra

Orchestra screenshot

Orchestra gives you more framework to build on top of. It has its own login system and generates a few, mostly empty pages, and then creating views, models, and more for rest of your administration area is up to you. There is lots of documentation available which requires the Bundocs bundle to view. It is definitely easier to install this bundle on a fresh install of Laravel. For example, its user’s table may exist with the one in your database already.

Adminify

Adminify Screenshot

Adminify uses your Laravel models to generate a simple visualization of your tables and lets your perform simple CRUD operations on the rows. It can also view logs in your storage/logs directory, and gives you a text area to enter and execute MySQL queries from.

Administrator

Administrator lets you perform CRUD operations on the rows in your database. It uses your app’s eloquent models and additional configuration files. The configuration files make it quite powerful since it lets you set up filtering, specify different form elements for editing different table columns, create new getters, and manage some relationships between tables. Documentation is here.

 

Laravel Asset Compressor Bundle and filemtime() stat error

This appears to only be a problem with Windows. If you see an error like this while using the asset compressor:

filemtime() [function.filemtime]: stat failed for [some file path]
Location:
 
E:\www\yourapplication\laravel\file.php on line 136

know that the code probably works on Linux and OS X, but not on your own Windows machine.

Why?

OS X and Linux use / as a directory separator. Windows uses \. PHP is tolerant of this, but the Google Closure Compiler that does the heavy lifting for this bundle is not. It doesn’t work with Windows paths containing \, like the ones the Asset Compressor has generated for it to use. If you get the command that the asset compressor generates (look for exec("$java $jar $scripts_to_minify $out_script");), replace all the \ with /, and run that line through the command line, you may find it works!

The Quick Solution

Set the enabled property in the bundle’s config file to something like this to disable the compressor on Windows, and enable it on other operating systems with the right directory separator:

    'enabled' => DIRECTORY_SEPARATOR == '/',

If your live server uses Linux, the compiler will compress your assets the first time someone visits your site. This can add several additional seconds to any page load that triggers the compiler.

The Smarter Solution

Fork it, fix it, pull request it.