Add Filesystem storage backend and store photo via backend

This commit is contained in:
fabrixxm 2018-11-21 09:38:54 +01:00 committed by Hypolite Petovan
parent 0ada604c7d
commit 12dd7b552f
3 changed files with 111 additions and 2 deletions

3
.gitignore vendored
View file

@ -71,3 +71,6 @@ venv/
#ignore .htaccess
.htaccess
#ignore filesystem storage default path
/storage

View file

@ -202,6 +202,17 @@ class Photo extends BaseObject
$existing_photo = DBA::selectFirst('photo', ['id'], ['resource-id' => $rid, 'uid' => $uid, 'contact-id' => $cid, 'scale' => $scale]);
// Get defined storage backend.
// if no storage backend, we use old "data" column in photo table.
$data = "";
$backend_ref = "";
$backend_class = Config::get("storage", "class", "");
if ($backend_class==="") {
$data = $Image->asString();
} else {
$backend_ref = $backend_class::put($Image->asString());
}
$fields = [
'uid' => $uid,
'contact-id' => $cid,
@ -215,14 +226,16 @@ class Photo extends BaseObject
'height' => $Image->getHeight(),
'width' => $Image->getWidth(),
'datasize' => strlen($Image->asString()),
'data' => $Image->asString(),
'data' => $data,
'scale' => $scale,
'profile' => $profile,
'allow_cid' => $allow_cid,
'allow_gid' => $allow_gid,
'deny_cid' => $deny_cid,
'deny_gid' => $deny_gid,
'desc' => $desc
'desc' => $desc,
'backend-class' => $backend_class,
'backend-ref' => $backend_ref
];
if (DBA::isResult($existing_photo)) {

View file

@ -0,0 +1,93 @@
<?php
/**
* @file src/Model/Storage/Filesystem.php
* @brief Storage backend system
*/
namespace Friendica\Model\Storage;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Core\Logger;
use Friendica\Util\Strings;
/**
* @brief Filesystem based storage backend
*
* This class manage data on filesystem.
* Base folder for storage is set in storage.filesystem_path.
* Best would be for storage folder to be outside webserver folder, we are using a
* folder relative to code tree root as default to ease things for users in shared hostings.
* Each new resource gets a value as reference and is saved in a
* folder tree stucture created from that value.
*/
class Filesystem implements IStorage
{
// Default base folder
const DEFAULT_BASE_FOLDER="storage";
private static function getBasePath()
{
return Config::get("storage", "filesystem_path", self::DEFAULT_BASE_FOLDER);
}
/**
* @brief Split data ref and return file path
* @param string $ref Data reference
* @return string
*/
private static function pathForRef($ref)
{
$base = self::getBasePath();
$fold1 = substr($ref,0,2);
$fold2 = substr($ref,2,2);
$file = substr($ref,4);
return "{$base}/{$fold1}/{$fold2}/{$file}";
}
/*
}
*/
public static function get($ref)
{
$file = self::pathForRef($ref);
if (!is_file($file)) return "";
return file_get_contents($file);
}
public static function put($data, $ref = null)
{
if (is_null($ref)) {
$ref = Strings::getRandomHex();
}
$file = self::pathForRef($ref);
$path = dirname($file);
if (!is_dir($path)) {
if (!mkdir($path, 0770, true)) {
Logger::log("Failed to create dirs {$path}");
echo L10n::t("Filesystem storage failed to create '%s'. Check you write permissions.", $path);
killme();
}
}
$r = file_put_contents($file, $data);
if ($r === FALSE) {
Logger::log("Failed to write data to {$file}");
echo L10n::t("Filesystem storage failed to save data to '%s'. Check your write permissions", $file);
killme();
}
return $ref;
}
public static function delete($ref)
{
$file = self::pathForRef($ref);
return unlink($file);
}
}