Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkp/pkp-lib#7131 Refactor file service to use Laravel container #7137

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions api/v1/submissions/PKPSubmissionFileHandler.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
*
*/

use Illuminate\Support\Facades\App;
use PKP\core\FileService;
use PKP\file\FileManager;
use PKP\handler\APIHandler;
use PKP\security\authorization\ContextAccessPolicy;
Expand All @@ -27,6 +29,8 @@

class PKPSubmissionFileHandler extends APIHandler
{
protected FileService $fileService;

/**
* Constructor
*/
Expand Down Expand Up @@ -69,6 +73,8 @@ public function __construct()
],
];
parent::__construct();

$this->fileService = App::make(FileService::class);
}

//
Expand Down Expand Up @@ -267,7 +273,7 @@ public function add($slimRequest, $response, $args)
$extension = $fileManager->parseFileExtension($_FILES['file']['name']);

$submissionDir = Services::get('submissionFile')->getSubmissionDir($request->getContext()->getId(), $submission->getId());
$fileId = Services::get('file')->add(
$fileId = $this->fileService->add(
$_FILES['file']['tmp_name'],
$submissionDir . '/' . uniqid() . '.' . $extension
);
Expand Down Expand Up @@ -389,7 +395,7 @@ public function edit($slimRequest, $response, $args)
$fileManager = new FileManager();
$extension = $fileManager->parseFileExtension($_FILES['file']['name']);
$submissionDir = Services::get('submissionFile')->getSubmissionDir($request->getContext()->getId(), $submission->getId());
$fileId = Services::get('file')->add(
$fileId = $this->fileService->add(
$_FILES['file']['tmp_name'],
$submissionDir . '/' . uniqid() . '.' . $extension
);
Expand Down
5 changes: 2 additions & 3 deletions classes/core/AppServiceProvider.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ class AppServiceProvider extends ServiceProvider
*/
public function register()
{
$this->app->singleton('maps', function ($app) {
return new MapContainer();
});
$this->app->singleton(FileService::class, FileService::class);
$this->app->singleton('maps', MapContainer::class);
$this->app->singleton(PKPSchemaService::class, function ($app) {
return Services::get('schema');
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,69 +1,62 @@
<?php
/**
* @file classes/services/PKPFileService.php
* @file classes/core/FileService.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPFileService
* @ingroup services
* @class FileService
* @ingroup core
*
* @brief Helper class that encapsulates business logic for publications
* @brief Provides methods to read and write to file storage. Uses Flysystem
* to support storage adaptors for local and remote file systems.
*
* @see AppServiceProvider::register
* @see https://flysystem.thephpleague.com
*/

namespace PKP\services;
namespace PKP\core;

use APP\core\Application;
use Exception;
use Illuminate\Support\Facades\DB;

use League\Flysystem\Adapter\Local;

use League\Flysystem\Filesystem;
use PKP\config\Config;
use PKP\file\FileManager;
use PKP\plugins\HookRegistry;
use stdClass;

class PKPFileService
class FileService
{
/** @var Filesystem */
public $fs;
public FileSystem $fs;

/**
* Initialize and configure flysystem
*/
public function __construct()
{
$adapter = new Local(
Config::getVar('files', 'files_dir'),
LOCK_EX,
Local::DISALLOW_LINKS,
[
'file' => [
'public' => FileManager::FILE_MODE_MASK,
'private' => FileManager::FILE_MODE_MASK,
],
'dir' => [
'public' => DIRECTORY_MODE_MASK,
'private' => DIRECTORY_MODE_MASK,
$this->fs = new FileSystem(
new Local(
Config::getVar('files', 'files_dir'),
LOCK_EX,
Local::DISALLOW_LINKS,
[
'file' => [
'public' => FileManager::FILE_MODE_MASK,
'private' => FileManager::FILE_MODE_MASK,
],
'dir' => [
'public' => FileManager::DIRECTORY_MODE_MASK,
'private' => FileManager::DIRECTORY_MODE_MASK,
]
]
]
)
);

HookRegistry::call('File::adapter', [&$adapter, $this]);

$this->fs = new Filesystem($adapter);
}

/**
* Get a file by its id
*
* @param int $id
*
* @return stdObject
*/
public function get($id)
public function get(int $id): stdClass
{
$file = DB::table('files')
->where('file_id', '=', $id)
Expand All @@ -78,9 +71,9 @@ public function get($id)
* @param string $from absolute path to file
* @param string $to relative path in file dir
*
* @return int file id
* @return int The new file id
*/
public function add($from, $to)
public function add(string $from, string $to): int
{
$stream = fopen($from, 'r+');
if (!$stream) {
Expand Down Expand Up @@ -110,12 +103,8 @@ public function add($from, $to)

/**
* Delete an uploaded file
*
* @param int $id
*
* @return File
*/
public function delete($id)
public function delete(int $id)
{
$file = $this->get($id);
if (!$file) {
Expand All @@ -140,7 +129,7 @@ public function delete($id)
* @param string $filename Filename to give to the downloaded file
* @param boolean $inline Whether to stream the file to the browser
*/
public function download($fileId, $filename, $inline = false)
public function download(int $fileId, string $filename, $inline = false)
{
$file = $this->get($fileId);
$dispatcher = Application::get()->getRequest()->getDispatcher();
Expand Down Expand Up @@ -177,10 +166,8 @@ public function download($fileId, $filename, $inline = false)
*
* @param string $path Path to the file
* @param string $filename Source filename to sanitize
*
* @return string
*/
public function formatFilename($path, $filename)
public function formatFilename(string $path, string $filename): string
{
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$newFilename = $filename;
Expand All @@ -196,11 +183,9 @@ public function formatFilename($path, $filename)
/**
* Get document type based on the mimetype
*
* @param string $mimetype
*
* @return string One of the FileManager::DOCUMENT_TYPE_ constants
*/
public function getDocumentType($mimetype)
public function getDocumentType(string $mimetype): string
{
switch ($mimetype) {
case 'application/pdf':
Expand Down Expand Up @@ -260,13 +245,11 @@ public function getDocumentType($mimetype)
/**
* Get a pretty file size string
*
* Examples: 82B, 12KB, 2MB, 2GB
*
* @param integer $size File size in bytes
*
* @return string
* @return string Examples: 82B, 12KB, 2MB, 2GB
*/
public function getNiceFileSize($size)
public function getNiceFileSize(int $size): string
{
$niceFileSizeUnits = ['B', 'KB', 'MB', 'GB'];
for ($i = 0; $i < 4 && $size > 1024; $i++) {
Expand Down
1 change: 0 additions & 1 deletion classes/core/PKPContainer.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ public function registerCoreContainerAliases()
'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class],
'db' => [\Illuminate\Database\DatabaseManager::class, \Illuminate\Database\ConnectionResolverInterface::class],
'db.connection' => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class],
'maps' => [MapContainer::class, MapContainer::class],
'events' => [\Illuminate\Events\Dispatcher::class, \Illuminate\Contracts\Events\Dispatcher::class],
'queue' => [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class],
'queue.connection' => [\Illuminate\Contracts\Queue\Queue::class],
Expand Down
7 changes: 5 additions & 2 deletions classes/file/PKPFile.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

namespace PKP\file;

use APP\core\Services;
use Illuminate\Support\Facades\App;
use PKP\core\FileService;

class PKPFile extends \PKP\core\DataObject
{
Expand Down Expand Up @@ -124,10 +125,12 @@ public function setFileSize($fileSize)
* Return pretty file size string (in B, KB, MB, or GB units).
*
* @return string
*
* @deprecated 3.4
*/
public function getNiceFileSize()
{
return Services::get('file')->getNiceFileSize($this->getFileSize());
return App::make(FileService::class)->getNiceFileSize($this->getFileSize());
}


Expand Down
6 changes: 6 additions & 0 deletions classes/install/Installer.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@
use APP\i18n\AppLocale;

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use PKP\cache\CacheManager;
use PKP\config\Config;
use PKP\core\Core;
use PKP\core\FileService;
use PKP\core\PKPApplication;
use PKP\db\DAORegistry;
use PKP\db\DBDataXMLParser;
Expand Down Expand Up @@ -100,6 +102,8 @@ class Installer
/** @var array List of migrations executed already */
public $migrations = [];

protected FileService $fileService;

/**
* Constructor.
*
Expand Down Expand Up @@ -168,6 +172,8 @@ public function preInstall()
$this->dataXMLParser = new DBDataXMLParser();
}

$this->fileService = App::make(FileService::class);

$result = true;
HookRegistry::call('Installer::preInstall', [$this, &$result]);

Expand Down
7 changes: 4 additions & 3 deletions classes/migration/upgrade/PKPv3_3_0UpgradeMigration.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
use APP\core\Services;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use PKP\config\Config;
use PKP\core\FileService;
use PKP\db\DAORegistry;
use PKP\db\XMLDAO;

use PKP\db\XMLDAO;
use PKP\file\FileManager;
use PKP\submission\SubmissionFile;

Expand Down Expand Up @@ -357,7 +358,6 @@ private function _migrateSubmissionFiles()
'date_uploaded',
'original_file_name'
]);
$fileService = Services::get('file');
$submissionFileService = Services::get('submissionFile');
foreach ($rows as $row) {
// Reproduces the removed method SubmissionFile::_generateFileName()
Expand All @@ -378,6 +378,7 @@ private function _migrateSubmissionFiles()
$this->_fileStageToPath($row->file_stage),
$filename
);
$fileService = App::make(FileService::class);
if (!$fileService->fs->has($path)) {
error_log("A submission file was expected but not found at ${path}.");
}
Expand Down
3 changes: 2 additions & 1 deletion classes/security/Validation.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use PKP\db\DAORegistry;

use PKP\session\SessionManager;
use Stringy\Stringy;

class Validation
{
Expand Down Expand Up @@ -410,7 +411,7 @@ public static function suggestUsername($givenName, $familyName = null)
$name = $initial . $familyName;
}

$suggestion = PKPString::regexp_replace('/[^a-zA-Z0-9_-]/', '', Stringy\Stringy::create($name)->toAscii()->toLowerCase());
$suggestion = PKPString::regexp_replace('/[^a-zA-Z0-9_-]/', '', Stringy::create($name)->toAscii()->toLowerCase());
$userDao = DAORegistry::getDAO('UserDAO'); /** @var UserDAO $userDao */
for ($i = ''; $userDao->userExistsByUsername($suggestion . $i); $i++);
return $suggestion . $i;
Expand Down
14 changes: 11 additions & 3 deletions classes/services/PKPSubmissionFileService.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use APP\facades\Repo;
use APP\notification\NotificationManager;
use PKP\core\Core;
use PKP\core\FileService;
use PKP\db\DAORegistry;
use PKP\db\DAOResultFactory;
use PKP\log\SubmissionEmailLogEntry;
Expand All @@ -39,6 +40,13 @@

class PKPSubmissionFileService implements EntityPropertyInterface, EntityReadInterface, EntityWriteInterface
{
protected FileService $fileService;

public function __construct(FileService $fileService)
{
$this->fileService = $fileService;
}

/**
* @copydoc \PKP\services\interfaces\EntityReadInterface::get()
*/
Expand Down Expand Up @@ -168,7 +176,7 @@ public function getProperties($submissionFile, $props, $args = null)
$values[$prop] = $dependentFiles;
break;
case 'documentType':
$values[$prop] = Services::get('file')->getDocumentType($submissionFile->getData('mimetype'));
$values[$prop] = $this->fileService->getDocumentType($submissionFile->getData('mimetype'));
break;
case 'revisions':
$files = [];
Expand All @@ -178,7 +186,7 @@ public function getProperties($submissionFile, $props, $args = null)
continue;
}
$files[] = [
'documentType' => Services::get('file')->getDocumentType($revision->mimetype),
'documentType' => $this->fileService->getDocumentType($revision->mimetype),
'fileId' => $revision->fileId,
'mimetype' => $revision->mimetype,
'path' => $revision->path,
Expand Down Expand Up @@ -600,7 +608,7 @@ public function delete($submissionFile)
'includeDependentFiles' => true,
]);
if (!$countFileShares) {
Services::get('file')->delete($revision->fileId);
$this->fileService->delete($revision->fileId);
}
}

Expand Down
Loading