silverstripe-framework/core/TempPath.php
Sam Minnee b401d39aec NEW: Move temp data into a user-specific subfolder, to stop temp-permission bugs from occurring.
Anyone who has run "sudo -u www-data ./framework/sake dev/build" knows that SilverStripe's temp
folder permissions can be very brittle.  This patch resolves this by making the temp folder
user-specific.

To minimise directory pollution it first creates a chmod 777 parent folder with the same name
as the current folder.  It then creates a subfolder of this with the same name as the current
user.

The positive impact of this change is that sake can be used without fear of messing up file
permissions.  This means, among other things, that we can put a Composer post-update-cmd into
the installer to run dev/build.  Progress!

The negative impact is that you will get two caches if you run sake as a different user.  However,
that is much better than the current situation - which is a bunch of bugs - and if you're concerned
about that, you still have the option of running sake as www-data.
2013-05-15 12:54:55 +02:00

92 lines
2.5 KiB
PHP

<?php
/**
* Returns the temporary folder path that silverstripe should use for its cache files.
*
* @param $base The base path to use for determining the temporary path
* @return string Path to temp
*/
function getTempFolder($base = null) {
$parent = getTempParentFolder($base);
// The actual temp folder is a subfolder of getTempParentFolder(), named by username
$subfolder = $parent . DIRECTORY_SEPARATOR . getTempFolderUsername();
if(!@file_exists($subfolder)) {
mkdir($subfolder);
}
return $subfolder;
}
/**
* Returns as best a representation of the current username as we can glean.
*/
function getTempFolderUsername() {
$user = getenv('APACHE_RUN_USER');
if(!$user) $user = getenv('USER');
if(!$user) $user = getenv('USERNAME');
if(!$user && function_exists('posix_getuid')) {
$userDetails = posix_getpwuid(posix_getuid());
$user = $userDetails['name'];
}
if(!$user) $user = 'unknown';
$user = preg_replace('/[^A-Za-z0-9_\-]/', '', $user);
return $user;
}
/**
* Return the parent folder of the temp folder.
* The temp folder will be a subfolder of this, named by username.
* This structure prevents permission problems.
*/
function getTempParentFolder($base = null) {
if(!$base && defined('BASE_PATH')) $base = BASE_PATH;
$tempPath = '';
$worked = true;
// first, try finding a silverstripe-cache dir built off the base path
$tempPath = $base . '/silverstripe-cache';
if(@file_exists($tempPath)) {
if((fileperms($tempPath) & 0777) != 0777) {
@chmod($tempPath, 0777);
}
return $tempPath;
}
// failing the above, try finding a namespaced silverstripe-cache dir in the system temp
$cacheFolder = '/silverstripe-cache' . str_replace(array(' ', '/', ':', '\\'), '-', $base);
$tempPath = sys_get_temp_dir() . $cacheFolder;
if(!@file_exists($tempPath)) {
$oldUMask = umask(0);
$worked = @mkdir($tempPath, 0777);
umask($oldUMask);
// if the folder already exists, correct perms
} else {
if((fileperms($tempPath) & 0777) != 0777) {
@chmod($tempPath, 0777);
}
}
// failing to use the system path, attempt to create a local silverstripe-cache dir
if(!$worked) {
$worked = true;
$tempPath = $base . '/silverstripe-cache';
if(!@file_exists($tempPath)) {
$oldUMask = umask(0);
$worked = @mkdir($tempPath, 0777);
umask($oldUMask);
}
}
if(!$worked) {
throw new Exception(
'Permission problem gaining access to a temp folder. ' .
'Please create a folder named silverstripe-cache in the base folder ' .
'of the installation and ensure it has the correct permissions'
);
}
return $tempPath;
}