Laravel 3 : Move codes from document root directory

タグ: Laravel3  

It is easy way to upload your web application made by Laravel3, just it put all directories/files on production server. It is easy to maintenance because it keep file structure as same as your development environment.

But if you uploaded many Laravel 3 applications on your production server, it become too busy to update cores for every application. Also every PHP codes on document root directories, when you use shard hosting.

So, I made a shell script to handle this situation. This script change directories/files structure from :

/home
    /yourhome
        /public_html <= Typical Document root of cPanel hosting ;)
            /site_a <= Virtual host ( Subdomain or Addon Domain of cPanel)
                /application
                /bundle
                /laravel
                /public
                    /bundle
                    /css
                    /img
                    /js
                    index.php
                /storage
                artisan
                paths.php
            /site_b <= Virtual host
                /application
                /bundle
                /laravel
                /public
                /bundle
                    /css
                    /img
                    /js
                    index.php
                /storage
                artisan
                paths.php

to :

/home
    /yourhome
        /laravel_dir
            /laravel <= Laravel's core, it became to common for all sites.
            /sites
                /site_a <= codes and storage of virtual host A.
                    /application
                    /bundle
                    /storage
                    artisan
                    paths.php
                /site_b <= codes and storage of virtual host A.
                    /application
                    /bundle
                    /storage
                    artisan
                    paths.php
        /public_html
            /site_a <= Only remained public contents.
                /bundle
                /css
                /img
                /js
                index.php
            /site_b <= Only remained public contents.
                /bundle
                /css
                /img
                /js
                index.php

Of cause, automatically set directories' paths for your index.php and paths.php.

How to use

Type command like this:

laravel3-code-unite Your-Taget-Public-Directory-Name

For example, for above structures, do following commands :

laravel3-code-unite site_a
laravel3-code-unite site_b

It is easy.

The shell code

Make a file 'laravel3-code-unite' ( or you favored name ) and put somewhere been set execution path.

Set execution permission ( chmod u+x laravel3-code-unite ).

Open it and set those codes :

# !/usr/bin/sh

set -e

# Please set your html document root
publichtml=/home/Your-Home-Directory/public_html

# Please set your directory to collect core/core files/directories
codedir=/home/Your-Home-Directory/laravel-dirs

laravelcore="${codedir}/laravel"
sitesdir="${codedir}/sites"
distdir="${sitesdir}/$1"

targetdir="${publichtml}/$1"

if [ $publichtml = '/home/Your-Home-Directory/public_html' ]
then
    echo Error! Please open this script with a editor, and set your document root to 'publichtml'.
    exit 10
fi

if [ $codedir = '/home/Your-Home-Directory/laravel-dirs' ]
then
    echo Error! Please open this script with a editor, and set you directory that collect your codes to 'codedir'.
fi

if [ $# != 1 ]
then
    echo
    echo Unite Laravel file structure into out of web document root.
    echo
    echo Usage: $0 Target-directory-name
    echo
    echo Note: Before first run this command, please set your directories to fit your host envrionments.
    echo
    exit 1
fi

if [ ! -d $targetdir ]
then
    echo Error! Target directory is not found. \($targetdir\)
    exit 2
fi

if [ ! -f "${targetdir}/paths.php" ]
then
    echo Error! Maybe already united. No paths.php in $targetdir
    exit 3
fi

if [ ! -d $codedir ]
then
    mkdir $codedir
fi

if [ ! -d $sitesdir ]
then
    mkdir $sitesdir
fi

# move laravel root folder to united directory
mv $targetdir $sitesdir

# move back public folder to document root.
mv "${distdir}/public" $targetdir

# copy core folder if not exist in united directory.
if [ ! -d $laravelcore ]
then
    cp -fa "${distdir}/laravel/" $laravelcore
    echo Notice : Copied Laravel core direcotry to $laravelcore.
fi

# remove core folder
rm -R "${distdir}/laravel"

# replace paths.php path in index.php

sed -i -e "
    s+../paths.php+${distdir}/paths.php+
" "${targetdir}/index.php"

# replace public/sys path in paths.php
sed -i -e "
    s+paths[ \n\r\f\t]*[[ \n\r\f\t]*'sys'[ \n\r\f\t]*][ \n\r\f\t]*=[ \n\r\f\t]*'laravel'+paths['sys'] = '${laravelcore}'+
    s+paths[ \n\r\f\t]*[[ \n\r\f\t]*'public'[ \n\r\f\t]*][ \n\r\f\t]*=[ \n\r\f\t]*'public'+paths['public'] = '${targetdir}'+
"  "${distdir}/paths.php"

echo "Successfully completed."
exit 0

Please modify two line before you execute this command. Set your full path of server for document root, and directory where unite your codes.

Set your virtual doc root again

By this command execution, no more 'public' directory on each site's root folder.

Maybe before, you set 'Site_A/public' for each virtual site setting ( in cPanel, you set this from Subdomain or Addon Domain items ).

Now you must set only 'Site_A' for it. Because no more 'public' on each site direcotoies anymore.

Caution!!

You must do this for working you production sites without test. You must do test first on your server.

Put new dummy Laravel environment on your server, and do for that dummy site. And check it properly work. Then do for your production site.

Of cause you must take backups for your site before execute command for your production sites.

No shell access? So ...

Obviously, if you don't have shell access permission ( most of case, it is SSH ) from you server manager, you can't use this command.

Don't worry. I had made another shell command for you.

Look this article.