Файловая система

Хранилище файлов

Расположение

Хранилище файлов Elgg расположено в dataroot сайта, который настраивается при установке, и может быть изменён через настройки сайта в интерфейсе администратора.

Структура директорий

Структура хранилища файлов связана с владением файлами сущностями Elgg. Каждый раз, когда первый файл, принадлежащий сущности, записывается в хранилище, в родительской директории-контейнере (контейнеры привязаны к 5000 guid) создаётся директория, соответствующая GUID сущности. Например, файлы, принадлежащие пользователю с guid 7777, будут находиться в 5000/7777/.

При создании файлов имена файлов могут содержать имена поддиректорий (часто упоминаемые как $prefix в коде). Например, аватары вышеуказанного пользователя можно найти в 5000/7777/profile/.

Объекты файлов

Запись файлов

Для записи файла в хранилище используется экземпляр ElggFile. Хотя ElggFile расширяет ElggObject и может храниться как настоящая сущность Elgg, это не всегда необходимо (например, при записи миниатюр изображения).

$file = new ElggFile();
$file->owner_guid = 7777;
$file->setFilename('portfolio/files/sample.txt');
$file->open('write');
$file->write('Contents of the file');
$file->close();

// to uprade this file to an entity
$file->save();

Чтение файлов

Вы можете читать содержимое файла, используя экземпляр ElggFile.

// from an Elgg entity
$file = get_entity($guid);
readfile($file->getFilenameOnFilestore());
// arbitrary file on the filestore
$file = new ElggFile();
$file->owner_guid = 7777;
$file->setFilename('portfolio/files/sample.txt');

// option 1
$file->open('read');
$contents = $file->grabFile();
$file->close();

// option 2
$contents = file_get_contents($file->getFilenameOnFilestore());

Обслуживание файлов

Вы можете обслуживать файлы из хранилища с помощью elgg_get_inline_url() и elgg_get_download_url(). Обе функции принимают 3 аргумента:

  • ``file`` Экземпляр ElggFile для обслуживания

  • ``use_cookie`` Если установлено в true, срок действия URL будет ограничен текущей сессией

  • ``expires`` Время истечения срока действия URL

Вы можете использовать аргументы use_cookie и expires как средства контроля доступа. Например, аватары пользователей в большинстве случаев имеют длительное время истечения и не нуждаются в ограничении текущей сессией — это позволит браузерам кэшировать изображения, а файловый сервис будет отправлять соответствующие заголовки Not Modified при последовательных запросах.

Поведение use_cookie по умолчанию можно контролировать на странице настроек безопасности администратора.

Для сущностей, находящихся под контролем доступа Elgg, вы можете использовать куки, чтобы убедиться, что настройки доступа соблюдаются и пользователи не делятся URL для скачивания с кем-то ещё.

Вы также можете аннулировать все ранее сгенерированные URL, обновив время изменения файла, например, с помощью touch().

Встраивание файлов

Обратите внимание, что из-за своей природы inline и download URL не подходят для встраивания. Встраиваемые URL должны быть постоянными, тогда как inline и download URL нестабильны (привязаны к сессии пользователя и времени изменения файла).

Для встраивания иконки сущности используйте elgg_get_embed_url().

Обработка загрузки файлов

Для реализации действия, сохраняющего один файл, загруженный пользователем, можно использовать следующий подход:

// in your form
echo elgg_view('input/file', [
        'name' => 'upload',
        'label' => 'Select an image to upload',
        'help' => 'Only jpeg, gif and png images are supported',
]);
// in your action
$uploaded_file = elgg_get_uploaded_file('upload');
if (!$uploaded_file) {
        return elgg_error_response("No file was uploaded");
}

$supported_mimes = [
        'image/jpeg',
        'image/png',
        'image/gif',
];

$mime_type = elgg()->mimetype->getMimeType($uploaded_file->getPathname());
if (!in_array($mime_type, $supported_mimes)) {
        return elgg_error_response("{$mime_type} is not supported");
}

$file = new ElggFile();
$file->owner_guid = elgg_get_logged_in_user_guid();
if ($file->acceptUploadedFile($uploaded_file)) {
        $file->save();
}

Если ваш ввод файла поддерживает несколько файлов, вы можете перебирать их в вашем действии:

// in your form
echo elgg_view('input/file', [
        'name' => 'upload[]',
        'multiple' => true,
        'label' => 'Select images to upload',
]);
// in your action
foreach (elgg_get_uploaded_files('upload') as $upload) {
        $file = new ElggFile();
        $file->owner_guid = elgg_get_logged_in_user_guid();
        if ($file->acceptUploadedFile($upload)) {
                $file->save();
        }
}

Примечание

Если загружаются изображения, автоматически предпринимается попытка исправить ориентацию изображения.

Временные файлы

Если вам когда-либо понадобится временный файл, вы можете использовать elgg_get_temp_file(). Вы получите экземпляр ElggTempFile, который имеет все функции файла ElggFile, но записывает свои данные во временную папку системы.

Предупреждение

Невозможно сохранить ElggTempFile в базе данных. Вы получите Elgg\Exceptions\Filesystem\IOException, если попытаетесь это сделать.