Aug 22

How to update ExpressionEngine when your system folder is outside the web root

Categories:
Tags:
, ,
Published:
9:14am on Saturday 22nd August, 2009

While they make it possible for you to move your main ExpressionEngine installation folder outside of the web root, EllisLab have neglected to allow for that possibility in their update scripts. This article shows you how to fix it with a couple of simple edits.

Given that there is even a blog entry on the EE site on the topic, you might have thought it would be accounted for in the version update script packaged with each new version. Unfortunately though the update instructions and the script itself ignore the possibility that you have moved your /system/ folder outside of the web root.

How to update EE, revised

First, ignore the instruction to copy system/update.php into your existing /system/ folder; instead, copy it into your web root folder (where your admin.php and path.php files are). It is now reachable at www.example.com/update.php - but it doesn’t work because the paths are wrong.

Editing update.php

Open update.php in your text editor. We are going to import the path information used by the rest of the site and update the paths needed for the update to run.

Add this line to the start of the file (beneath the copyright message):

require_once(’./path.php’);

Next, at the top of the file there are a series of definitions:

define(‘EXT’,		’.’.$path[‘extension’]);
define(‘PATH’,		’./’); 
define(‘PATH_DB’,	’./db/’); 
define(‘PATH_CORE’,	’./core/’);
define(‘PATH_LANG’,	’./language/’);
define(‘PATH_MOD’,	’./modules/’);
define(‘PATH_EXT’,	’./extensions/’);
define(‘PATH_PI’,	’./plugins/’);
define(‘CONFIG_FILE’,	‘config’.EXT);

Let’s update them to use the correct path information:

define(‘EXT’,		’.’.$path[‘extension’]);
define(‘PATH’,		$system_path); 
define(‘PATH_DB’,	$system_path . ‘db/’); 
define(‘PATH_CORE’,	$system_path . ‘core/’);
define(‘PATH_LANG’,	$system_path . ‘language/’);
define(‘PATH_MOD’,	$system_path . ‘modules/’);
define(‘PATH_EXT’,	$system_path . ‘extensions/’);
define(‘PATH_PI’,	$system_path . ‘plugins/’);
define(‘CONFIG_FILE’,	$system_path . ‘config’.EXT);

We’re almost done, but there’s just one more place where the path is hardcoded and needs to be fixed. In the Update() class method update_manager(), we need to use the path information one more time. Change these lines:

function update_manager()
{	
	global $DB;

Here's the revised version:

function update_manager()
{	
	global $DB, $system_path;
	$this->update_dir = $system_path . ‘updates/’;

We’re just overriding the path to the update directory with the correct path.

Now load the update script at www.example.com/update.php to run the update with no problems, despite your /system/ root not being where it ‘should’ be.

This should be in the EE trunk

Hopefully EllisLab will eventually make this hacking unnecessary and incorporate these changes into the official release, but in the meantime if you’re a security-conscious developer I hope this was useful.

I'd love to hear what you think - please use the form below to leave your comments. Some HTML is permitted: b, i, em, del, ins, strong, pre, code, blockquote, abbr. URLs or email addresses will be automatically converted into links.

Comment Form

  1. Phil's Gravatar

    Phil at 6:37am on 3rd October, 2009 #

    Thanks for putting this together - it does seem like this feature is one that was easily neglected.  You really should reach out to the team if you haven’t already to try to get this incorporated into trunk.

  2. Andy Marshall's Gravatar

    Andy Marshall at 3:34pm on 11th May, 2010 #

    Hmm… can’t get it to work.
    I’m getting the following error: “Parse error: syntax error, unexpected ’/’ in /home/beaniesw/public_html/beanies/update.php on line 20”

    when i remove the / so it says “require_once(’.path.php’);” (or other alternatives) I get: “Warning: Division by zero in /home/beaniesw/public_html/beanies/update.php on line 20

    Warning: require_once(php’) [function.require-once]: failed to open stream: No such file or directory in /home/beaniesw/public_html/beanies/update.php on line 20

    Fatal error: require_once() [function.require]: Failed opening required ‘php’’ (include_path=’.:/usr/lib/php:/usr/local/lib/php’) in /home/beaniesw/public_html/beanies/update.php on line 20”

    one thing that I didn’t quite follow in your instructions, when you say put it in the webroot with the path.php and admin.php…. presumably this is teh admin.php file that gets placed where you want to access the CP, eg sitename.com/systemfolder/admin.php

    I renamed mine to nidex.php, so i would access it at sitename.com/systemfolder/

    either way, i tried putting the update.php file in both webroot and the /systemfolder subdir and nothing seems to work.
    Any ideas?
    Sorry for turning your comments into tech support!!

  3. Matthew Pennell's Gravatar

    Matthew Pennell at 7:52pm on 13th May, 2010 #

    Andy: The update.php file needs to be in the same folder as your path.php and admin.php file (or whatever you’ve called it). The require_once() line should have a filepath that points to your path.php - so ’./path.php’ will work, assuming you have path.php in that folder.

  4. Stephen Lewis's Gravatar

    Stephen Lewis at 1:19am on 15th May, 2010 #

    Very handy article, thanks Matthew.

    I needed to make two minor additional changes when upgrading from 1.6.8 to 1.6.9.

    Around line 45, replace:
    if ( ! @include(‘config’.EXT))

    With:
    if ( ! @include(CONFIG_FILE))

    Around line 295, replace:
    if ( ! $this->is_really_writable(‘config’.EXT))

    With:
    if ( ! $this->is_really_writable(CONFIG_FILE))

    Given the declaration of the CONFIG_FILE constant, the two uses of ‘config’.EXT look like EllisLab errors to me.

    Cheers,
    Stephen

    P.S. I no idea if this is a new thing, as I’ve never done this type of upgrade before.