Permalink
Browse files

feature(application): Allows fetching dataroot statically from Applic…

…ation

This moves the dataroot resolution from lib/configuration.php to the Application
and makes sure that create() sets/gets a singleton instance. Also updates
icondirect.php to use the new method.

Fixes #8653
  • Loading branch information...
mrclay committed Jul 1, 2015
1 parent 5646efb commit bed2e09b31945fd1cca3908a985f84294fd191f2
@@ -319,12 +319,17 @@ public function __get($name) {
}
/**
* Creates a new, trivial instance of Elgg\Application.
* Creates a new, trivial instance of Elgg\Application and set it as the singleton instance.
* If the singleton is already set, it's returned.
*
* @return self
*/
private static function create() {
return new self(new Di\ServiceProvider(new Config()));
if (self::$_instance === null) {
self::$_instance = new self(new Di\ServiceProvider(new Config()));
}
return self::$_instance;
}
/**
@@ -381,6 +386,31 @@ public function run() {
forward('', '404');
}
}
/**
* Determine the Elgg data directory with trailing slash, save it to config, and return it
*
* @todo Consider a better place for this logic? We need it before boot
*
* @return string
* @throws \InstallationException
*/
public static function getDataPath() {
$app = self::create();
$app->services->config->loadSettingsFile();
if ($GLOBALS['_ELGG']->dataroot_in_settings) {
return $app->services->config->getVolatile('dataroot');
}
$dataroot = $app->services->datalist->get('dataroot');
if (!$dataroot) {
throw new \InstallationException('The datalists table lacks a value for "dataroot".');
}
$dataroot = rtrim($dataroot, '/\\') . DIRECTORY_SEPARATOR;
$app->services->config->set('dataroot', $dataroot);
return $dataroot;
}
/**
* Returns a directory that points to the root of Elgg, but not necessarily
@@ -84,6 +84,10 @@ public function getPluginsPath() {
* {@inheritdoc}
*/
public function getDataPath() {
if (!isset($this->config->dataroot)) {
\Elgg\Application::getDataPath();
}
return $this->config->dataroot;
}
@@ -211,8 +215,13 @@ public function loadSettingsFile() {
// normalize commonly needed values
if (isset($CONFIG->dataroot)) {
$CONFIG->dataroot = rtrim($CONFIG->dataroot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$GLOBALS['_ELGG']->dataroot_in_settings = true;
} else {
$GLOBALS['_ELGG']->dataroot_in_settings = false;
}
$GLOBALS['_ELGG']->simplecache_enabled_in_settings = isset($CONFIG->simplecache_enabled);
if (!$global_is_bound) {
// must manually copy settings into our storage
foreach ($CONFIG as $key => $value) {
@@ -60,10 +60,7 @@ public function __construct(Pool $cache, Database $db, Logger $logger, $table) {
*/
function get($name) {
$name = trim($name);
// cannot store anything longer than 255 characters in db, so catch here
if (elgg_strlen($name) > 255) {
$this->logger->error("The name length for configuration variables cannot be greater than 255");
if (!$this->validateName($name)) {
return false;
}
@@ -92,14 +89,10 @@ function get($name) {
*/
function set($name, $value) {
$name = trim($name);
// cannot store anything longer than 255 characters in db, so catch before we set
if (elgg_strlen($name) > 255) {
$this->logger->error("The name length for configuration variables cannot be greater than 255");
if (!$this->validateName($name)) {
return false;
}
$escaped_name = $this->db->sanitizeString($name);
$escaped_value = $this->db->sanitizeString($value);
$success = $this->db->insertData("INSERT INTO {$this->table}"
@@ -179,4 +172,26 @@ function runFunctionOnce($functionname, $timelastupdatedcheck = 0) {
return false;
}
}
/**
* Verify a datalist name is valid
*
* @param string $name Datalist name to be checked
*
* @return bool
*/
protected function validateName($name) {
// Can't use elgg_strlen() because not available until core loaded.
if (is_callable('mb_strlen')) {
$is_valid = (mb_strlen($name) <= 255);
} else {
$is_valid = (strlen($name) <= 255);
}
if (!$is_valid) {
$this->logger->error("The name length for configuration variables cannot be greater than 255");
}
return $is_valid;
}
}
@@ -353,35 +353,16 @@ function _elgg_load_application_config() {
_elgg_services()->datalist->loadAll();
}
// allow sites to set dataroot and simplecache_enabled in settings.php
if (isset($CONFIG->dataroot)) {
$CONFIG->dataroot = sanitise_filepath($CONFIG->dataroot);
$GLOBALS['_ELGG']->dataroot_in_settings = true;
} else {
$dataroot = datalist_get('dataroot');
if (!empty($dataroot)) {
$CONFIG->dataroot = $dataroot;
}
$GLOBALS['_ELGG']->dataroot_in_settings = false;
}
if (isset($CONFIG->simplecache_enabled)) {
$GLOBALS['_ELGG']->simplecache_enabled_in_settings = true;
} else {
// make sure dataroot gets set
\Elgg\Application::getDataPath();
if (!$GLOBALS['_ELGG']->simplecache_enabled_in_settings) {
$simplecache_enabled = datalist_get('simplecache_enabled');
if ($simplecache_enabled !== false) {
$CONFIG->simplecache_enabled = $simplecache_enabled;
} else {
$CONFIG->simplecache_enabled = 1;
}
$GLOBALS['_ELGG']->simplecache_enabled_in_settings = false;
$CONFIG->simplecache_enabled = ($simplecache_enabled === false) ? 1 : $simplecache_enabled;
}
$system_cache_enabled = datalist_get('system_cache_enabled');
if ($system_cache_enabled !== false) {
$CONFIG->system_cache_enabled = $system_cache_enabled;
} else {
$CONFIG->system_cache_enabled = 1;
}
$CONFIG->system_cache_enabled = ($system_cache_enabled === false) ? 1 : $system_cache_enabled;
// needs to be set before system, init for links in html head
$CONFIG->lastcache = (int)datalist_get("simplecache_lastupdate");
View
@@ -32,56 +32,25 @@
require_once __DIR__ . '/../../vendor/autoload.php';
$app = new \Elgg\Application();
$app->loadSettings();
$data_root = call_user_func(function () use ($app) {
// TODO(evan): Remove use of global $CONFIG
global $CONFIG;
if (isset($CONFIG->dataroot)) {
return $CONFIG->dataroot;
}
// must get from DB
$db = $app->getDb();
try {
$row = $db->getDataRow("
SELECT `value`
FROM {$db->getTablePrefix()}datalists
WHERE `name` = 'dataroot'
");
if (!$row) {
return "";
}
} catch (\DatabaseException $e) {
// we're going to let the engine figure out what's happening...
return '';
}
return rtrim($row->value, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
});
if ($data_root) {
$locator = new \Elgg\EntityDirLocator($guid);
$user_path = $data_root . $locator->getPath();
$filename = $user_path . "profile/{$guid}{$size}.jpg";
$filesize = @filesize($filename);
if ($filesize) {
header("Content-type: image/jpeg");
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true);
header("Pragma: public");
header("Cache-Control: public");
header("Content-Length: $filesize");
header("ETag: \"$etag\"");
readfile($filename);
exit;
}
$data_root = \Elgg\Application::getDataPath();
$locator = new \Elgg\EntityDirLocator($guid);
$user_path = $data_root . $locator->getPath();
$filename = $user_path . "profile/{$guid}{$size}.jpg";
$filesize = @filesize($filename);
if ($filesize) {
header("Content-type: image/jpeg");
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', strtotime("+6 months")), true);
header("Pragma: public");
header("Cache-Control: public");
header("Content-Length: $filesize");
header("ETag: \"$etag\"");
readfile($filename);
exit;
}
// something went wrong so load engine and try to forward to default icon
$app->bootCore();
\Elgg\Application::start();
elgg_log("Profile icon direct failed.", "WARNING");
forward(elgg_get_simplecache_url("icons/user/default{$size}.gif"));

0 comments on commit bed2e09

Please sign in to comment.