first commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/galley/Collector.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2000-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class Collector
|
||||
*
|
||||
* @brief A helper class to configure a Query Builder to get a collection of galleys
|
||||
*/
|
||||
|
||||
namespace PKP\galley;
|
||||
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
use PKP\core\interfaces\CollectorInterface;
|
||||
use PKP\plugins\Hook;
|
||||
|
||||
/**
|
||||
* @template T of Galley
|
||||
*/
|
||||
class Collector implements CollectorInterface
|
||||
{
|
||||
public DAO $dao;
|
||||
|
||||
public ?array $publicationIds = null;
|
||||
|
||||
public ?array $contextIds = null;
|
||||
|
||||
public ?array $doiIds = null;
|
||||
|
||||
public function __construct(DAO $dao)
|
||||
{
|
||||
$this->dao = $dao;
|
||||
}
|
||||
|
||||
public function getCount(): int
|
||||
{
|
||||
return $this->dao->getCount($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int,int>
|
||||
*/
|
||||
public function getIds(): Collection
|
||||
{
|
||||
return $this->dao->getIds($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc DAO::getMany()
|
||||
* @return LazyCollection<int,T>
|
||||
*/
|
||||
public function getMany(): LazyCollection
|
||||
{
|
||||
return $this->dao->getMany($this);
|
||||
}
|
||||
|
||||
public function filterByPublicationIds(?array $publicationIds): self
|
||||
{
|
||||
$this->publicationIds = $publicationIds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByContextIds(?array $contextIds): self
|
||||
{
|
||||
$this->contextIds = $contextIds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByDoiIds(?array $doiIds): self
|
||||
{
|
||||
$this->doiIds = $doiIds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQueryBuilder(): Builder
|
||||
{
|
||||
$qb = DB::table($this->dao->table . ' as g')
|
||||
->select(['g.*'])
|
||||
->when(!is_null($this->publicationIds), function (Builder $qb) {
|
||||
$qb->whereIn('g.publication_id', $this->publicationIds);
|
||||
})
|
||||
->when(!is_null($this->contextIds), function (Builder $qb) {
|
||||
$qb->join('publications as p', 'p.publication_id', '=', 'g.publication_id')
|
||||
->leftJoin('submissions as s', 's.submission_id', '=', 'p.submission_id')
|
||||
->whereIn('s.context_id', $this->contextIds);
|
||||
})
|
||||
->when(!is_null($this->doiIds), function (Builder $qb) {
|
||||
$qb->whereIn('g.doi_id', $this->doiIds);
|
||||
})
|
||||
->orderBy('g.seq', 'asc');
|
||||
|
||||
Hook::call('Galley::Collector', [&$qb, $this]);
|
||||
|
||||
return $qb;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,328 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/galley/DAO.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2000-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class DAO
|
||||
*
|
||||
* @brief Read and write galleys to the database.
|
||||
*/
|
||||
|
||||
namespace PKP\galley;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use APP\publication\Publication;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
use PKP\core\EntityDAO;
|
||||
use PKP\core\traits\EntityWithParent;
|
||||
use PKP\db\DAOResultFactory;
|
||||
use PKP\identity\Identity;
|
||||
use PKP\services\PKPSchemaService;
|
||||
use PKP\submission\PKPSubmission;
|
||||
use PKP\submission\Representation;
|
||||
use PKP\submission\RepresentationDAOInterface;
|
||||
|
||||
/**
|
||||
* @template T of Galley
|
||||
* @extends EntityDAO<T>
|
||||
*/
|
||||
class DAO extends EntityDAO implements RepresentationDAOInterface
|
||||
{
|
||||
use EntityWithParent;
|
||||
|
||||
/** @copydoc EntityDAO::$schema */
|
||||
public $schema = PKPSchemaService::SCHEMA_GALLEY;
|
||||
|
||||
/** @copydoc EntityDAO::$table */
|
||||
public $table = 'publication_galleys';
|
||||
|
||||
/** @copydoc EntityDAO::$settingsTable */
|
||||
public $settingsTable = 'publication_galley_settings';
|
||||
|
||||
/** @copydoc EntityDAO::$primarykeyColumn */
|
||||
public $primaryKeyColumn = 'galley_id';
|
||||
|
||||
/** @copydoc EntityDAO::$primaryTableColumns */
|
||||
public $primaryTableColumns = [
|
||||
'submissionFileId' => 'submission_file_id',
|
||||
'id' => 'galley_id',
|
||||
'isApproved' => 'is_approved',
|
||||
'locale' => 'locale',
|
||||
'label' => 'label',
|
||||
'publicationId' => 'publication_id',
|
||||
'seq' => 'seq',
|
||||
'urlPath' => 'url_path',
|
||||
'urlRemote' => 'remote_url',
|
||||
'doiId' => 'doi_id',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the parent object ID column name
|
||||
*/
|
||||
public function getParentColumn(): string
|
||||
{
|
||||
return 'publication_id';
|
||||
}
|
||||
|
||||
public function newDataObject(): Galley
|
||||
{
|
||||
return app(Galley::class);
|
||||
}
|
||||
|
||||
public function getByUrlPath(string $urlPath, Publication $publication): ?Galley
|
||||
{
|
||||
$row = DB::table($this->table)
|
||||
->where('publication_id', $publication->getId())
|
||||
->where('url_path', $urlPath)
|
||||
->first();
|
||||
return $row ? $this->fromRow($row) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of galleys matching the configured query
|
||||
*/
|
||||
public function getCount(Collector $query): int
|
||||
{
|
||||
return $query
|
||||
->getQueryBuilder()
|
||||
->select('g.' . $this->primaryKeyColumn)
|
||||
->get()
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of ids matching the configured query
|
||||
*
|
||||
* @return Collection<int,int>
|
||||
*/
|
||||
public function getIds(Collector $query): Collection
|
||||
{
|
||||
return $query
|
||||
->getQueryBuilder()
|
||||
->select('g.' . $this->primaryKeyColumn)
|
||||
->pluck('g.' . $this->primaryKeyColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of galleys matching the configured query
|
||||
* @return LazyCollection<int,T>
|
||||
*/
|
||||
public function getMany(Collector $query): LazyCollection
|
||||
{
|
||||
$rows = $query
|
||||
->getQueryBuilder()
|
||||
->get();
|
||||
|
||||
return LazyCollection::make(function () use ($rows) {
|
||||
foreach ($rows as $row) {
|
||||
yield $row->user_id = $this->fromRow($row);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function fromRow(object $row): Galley
|
||||
{
|
||||
$galley = parent::fromRow($row);
|
||||
|
||||
if (!empty($galley->getData('doiId'))) {
|
||||
$galley->setData('doiObject', Repo::doi()->get($galley->getData('doiId')));
|
||||
}
|
||||
|
||||
return $galley;
|
||||
}
|
||||
|
||||
public function insert(Galley $galley): int
|
||||
{
|
||||
return parent::_insert($galley);
|
||||
}
|
||||
|
||||
public function update(Galley $galley)
|
||||
{
|
||||
parent::_update($galley);
|
||||
}
|
||||
|
||||
public function delete(Galley $galley)
|
||||
{
|
||||
parent::_delete($galley);
|
||||
}
|
||||
|
||||
public function getById(int $id, ?int $publicationId = null, ?int $contextId = null): ?Representation
|
||||
{
|
||||
$row = DB::table($this->table)
|
||||
->where($this->primaryKeyColumn, $id)
|
||||
->when(!is_null($publicationId), function (Builder $query) use ($publicationId) {
|
||||
$query->where('publication_id', $publicationId);
|
||||
})
|
||||
->first();
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
return $this->fromRow($row);
|
||||
}
|
||||
|
||||
/** @copydoc RepresentationDAOInterface::getByPublicationId() */
|
||||
public function getByPublicationId(int $publicationId): array
|
||||
{
|
||||
return Repo::galley()->getCollector()
|
||||
->filterByPublicationIds([$publicationId])
|
||||
->getMany()
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/** @copydoc RepresentationDAOInterface::updateObject() */
|
||||
public function updateObject(Representation $galley): void
|
||||
{
|
||||
$this->update($galley);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPPubIdPluginDAO::pubIdExists()
|
||||
*/
|
||||
public function pubIdExists($pubIdType, $pubId, $excludePubObjectId, $contextId)
|
||||
{
|
||||
$result = $this->deprecatedDao->retrieve(
|
||||
'SELECT COUNT(*) AS row_count
|
||||
FROM publication_galley_settings pgs
|
||||
INNER JOIN publication_galleys pg ON pgs.galley_id = pg.galley_id
|
||||
INNER JOIN publications p ON pg.publication_id = p.publication_id
|
||||
INNER JOIN submissions s ON p.submission_id = s.submission_id
|
||||
WHERE pgs.setting_name = ? AND pgs.setting_value = ? AND pgs.galley_id <> ? AND s.context_id = ?',
|
||||
[
|
||||
'pub-id::' . $pubIdType,
|
||||
$pubId,
|
||||
(int) $excludePubObjectId,
|
||||
(int) $contextId
|
||||
]
|
||||
);
|
||||
$row = $result->current();
|
||||
return $row ? (bool) $row->row_count : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPPubIdPluginDAO::changePubId()
|
||||
*/
|
||||
public function changePubId($pubObjectId, $pubIdType, $pubId)
|
||||
{
|
||||
DB::table('publication_galley_settings')
|
||||
->where('setting_name', 'pub-id::' . $pubIdType)
|
||||
->where('galley_id', (int) $pubObjectId)
|
||||
->update(['setting_value' => (string) $pubId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPPubIdPluginDAO::deletePubId()
|
||||
*/
|
||||
public function deletePubId($pubObjectId, $pubIdType)
|
||||
{
|
||||
$settingName = 'pub-id::' . $pubIdType;
|
||||
$this->deprecatedDao->update(
|
||||
'DELETE FROM publication_galley_settings WHERE setting_name = ? AND galley_id = ?',
|
||||
[
|
||||
$settingName,
|
||||
(int)$pubObjectId
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc PKPPubIdPluginDAO::deleteAllPubIds()
|
||||
*/
|
||||
public function deleteAllPubIds($contextId, $pubIdType)
|
||||
{
|
||||
$settingName = 'pub-id::' . $pubIdType;
|
||||
|
||||
$galleyIds = Repo::galley()
|
||||
->getCollector()
|
||||
->filterByContextIds([(int) $contextId])
|
||||
->getIds();
|
||||
|
||||
foreach ($galleyIds as $galleyId) {
|
||||
$this->deprecatedDao->update(
|
||||
'DELETE FROM publication_galley_settings WHERE setting_name = ? AND galley_id = ?',
|
||||
[$settingName, $galleyId]
|
||||
);
|
||||
}
|
||||
$this->deprecatedDao->flushCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all published submission galleys (eventually with a pubId assigned and) matching the specified settings.
|
||||
*
|
||||
* @param int $contextId optional
|
||||
* @param string $pubIdType
|
||||
* @param string $title optional
|
||||
* @param string $author optional
|
||||
* @param int $issueId optional
|
||||
* @param string $pubIdSettingName optional
|
||||
* (e.g. medra::status or medra::registeredDoi)
|
||||
* @param string $pubIdSettingValue optional
|
||||
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
||||
*
|
||||
* @deprecated 3.4.0
|
||||
*
|
||||
* @return DAOResultFactory<Galley>
|
||||
*/
|
||||
public function getExportable($contextId, $pubIdType = null, $title = null, $author = null, $issueId = null, $pubIdSettingName = null, $pubIdSettingValue = null, $rangeInfo = null)
|
||||
{
|
||||
$params = [];
|
||||
if ($pubIdSettingName) {
|
||||
$params[] = $pubIdSettingName;
|
||||
}
|
||||
$params[] = PKPSubmission::STATUS_PUBLISHED;
|
||||
$params[] = (int) $contextId;
|
||||
if ($pubIdType) {
|
||||
$params[] = 'pub-id::' . $pubIdType;
|
||||
}
|
||||
if ($title) {
|
||||
$params[] = 'title';
|
||||
$params[] = '%' . $title . '%';
|
||||
}
|
||||
if ($author) {
|
||||
array_push($params, $authorQuery = '%' . $author . '%', $authorQuery);
|
||||
}
|
||||
if ($issueId) {
|
||||
$params[] = (int) $issueId;
|
||||
}
|
||||
import('classes.plugins.PubObjectsExportPlugin'); // Constant
|
||||
if ($pubIdSettingName && $pubIdSettingValue && $pubIdSettingValue != EXPORT_STATUS_NOT_DEPOSITED) {
|
||||
$params[] = $pubIdSettingValue;
|
||||
}
|
||||
|
||||
$result = $this->deprecatedDao->retrieveRange(
|
||||
$sql = 'SELECT g.*
|
||||
FROM publication_galleys g
|
||||
LEFT JOIN publications p ON (p.publication_id = g.publication_id)
|
||||
LEFT JOIN publication_settings ps ON (ps.publication_id = p.publication_id)
|
||||
LEFT JOIN submissions s ON (s.submission_id = p.submission_id)
|
||||
LEFT JOIN submission_files sf ON (g.submission_file_id = sf.submission_file_id)
|
||||
' . ($pubIdType != null ? ' LEFT JOIN publication_galley_settings gs ON (g.galley_id = gs.galley_id)' : '')
|
||||
. ($title != null ? ' LEFT JOIN publication_settings pst ON (p.publication_id = pst.publication_id)' : '')
|
||||
. ($author != null ? ' LEFT JOIN authors au ON (p.publication_id = au.publication_id)
|
||||
LEFT JOIN author_settings asgs ON (asgs.author_id = au.author_id AND asgs.setting_name = \'' . Identity::IDENTITY_SETTING_GIVENNAME . '\')
|
||||
LEFT JOIN author_settings asfs ON (asfs.author_id = au.author_id AND asfs.setting_name = \'' . Identity::IDENTITY_SETTING_FAMILYNAME . '\')
|
||||
' : '')
|
||||
. ($pubIdSettingName != null ? ' LEFT JOIN publication_galley_settings gss ON (g.galley_id = gss.galley_id AND gss.setting_name = ?)' : '') . '
|
||||
WHERE
|
||||
s.status = ? AND s.context_id = ?
|
||||
' . ($pubIdType != null ? ' AND gs.setting_name = ? AND gs.setting_value IS NOT NULL' : '')
|
||||
. ($title != null ? ' AND (pst.setting_name = ? AND pst.setting_value LIKE ?)' : '')
|
||||
. ($author != null ? ' AND (asgs.setting_value LIKE ? OR asfs.setting_value LIKE ?)' : '')
|
||||
. ($issueId != null ? ' AND (ps.setting_name = \'issueId\' AND ps.setting_value = ? AND ps.locale = \'\'' : '')
|
||||
. (($pubIdSettingName != null && $pubIdSettingValue != null && $pubIdSettingValue == EXPORT_STATUS_NOT_DEPOSITED) ? ' AND gss.setting_value IS NULL' : '')
|
||||
. (($pubIdSettingName != null && $pubIdSettingValue != null && $pubIdSettingValue != EXPORT_STATUS_NOT_DEPOSITED) ? ' AND gss.setting_value = ?' : '')
|
||||
. (($pubIdSettingName != null && is_null($pubIdSettingValue)) ? ' AND (gss.setting_value IS NULL OR gss.setting_value = \'\')' : '') . '
|
||||
GROUP BY g.galley_id
|
||||
ORDER BY p.date_published DESC, p.publication_id DESC, g.galley_id DESC',
|
||||
$params,
|
||||
$rangeInfo
|
||||
);
|
||||
|
||||
return new DAOResultFactory($result, $this, '_fromRow', [], $sql, $params, $rangeInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/galley/Galley.php
|
||||
*
|
||||
* Copyright (c) 2014-2022 Simon Fraser University
|
||||
* Copyright (c) 2003-2022 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class galley
|
||||
*
|
||||
* @ingroup galley
|
||||
*
|
||||
* @brief A galley is a presentation version of a published submission file.
|
||||
*/
|
||||
|
||||
namespace PKP\galley;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Services;
|
||||
use APP\facades\Repo;
|
||||
use APP\statistics\StatisticsHelper;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\submission\Representation;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class Galley extends Representation
|
||||
{
|
||||
public ?SubmissionFile $_submissionFile = null;
|
||||
|
||||
//
|
||||
// Get/set methods
|
||||
//
|
||||
/**
|
||||
* Get views count.
|
||||
*
|
||||
* @deprecated 3.4
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getViews()
|
||||
{
|
||||
$fileId = $this->getData('submissionFileId');
|
||||
if (!$fileId) {
|
||||
return 0;
|
||||
}
|
||||
$filters = [
|
||||
'dateStart' => StatisticsHelper::STATISTICS_EARLIEST_DATE,
|
||||
'dateEnd' => date('Y-m-d', strtotime('yesterday')),
|
||||
'contextIds' => [Application::get()->getRequest()->getContext()->getId()],
|
||||
'submissionFileIds' => [$fileId],
|
||||
];
|
||||
$metrics = Services::get('publicationStats')
|
||||
->getQueryBuilder($filters)
|
||||
->getSum([])
|
||||
->value('metric');
|
||||
return $metrics ? $metrics : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get label/title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLabel()
|
||||
{
|
||||
return $this->getData('label');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set label/title.
|
||||
*
|
||||
* @param string $label
|
||||
*/
|
||||
public function setLabel($label)
|
||||
{
|
||||
$this->setData('label', $label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get locale.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocale()
|
||||
{
|
||||
return $this->getData('locale');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set locale.
|
||||
*
|
||||
* @param string $locale
|
||||
*/
|
||||
public function setLocale($locale)
|
||||
{
|
||||
$this->setData('locale', $locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the "best" article ID -- If a public article ID is set,
|
||||
* use it; otherwise use the internal article Id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBestGalleyId()
|
||||
{
|
||||
return strlen($urlPath = (string) $this->getData('urlPath')) ? $urlPath : $this->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the submission file corresponding to this galley.
|
||||
*
|
||||
* @deprecated 3.3
|
||||
*
|
||||
* @return SubmissionFile
|
||||
*/
|
||||
public function getFile()
|
||||
{
|
||||
if (!isset($this->_submissionFile) && $this->getData('submissionFileId')) {
|
||||
$this->_submissionFile = Repo::submissionFile()->get($this->getData('submissionFileId'));
|
||||
}
|
||||
return $this->_submissionFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file type corresponding to this galley.
|
||||
*
|
||||
* @deprecated 3.3
|
||||
*
|
||||
* @return string MIME type
|
||||
*/
|
||||
public function getFileType()
|
||||
{
|
||||
$galleyFile = $this->getFile();
|
||||
return $galleyFile ? $galleyFile->getData('mimetype') : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the galley is a PDF.
|
||||
*
|
||||
* @deprecated 3.4
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isPdfGalley()
|
||||
{
|
||||
return $this->getFileType() == 'application/pdf';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the localized galley label.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getGalleyLabel()
|
||||
{
|
||||
$label = $this->getLabel();
|
||||
if ($this->getLocale() && $this->getLocale() != Locale::getLocale()) {
|
||||
$label .= ' (' . Locale::getMetadata($this->getLocale())->getDisplayName() . ')';
|
||||
}
|
||||
return $label;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Representation::getName()
|
||||
*
|
||||
* This override exists to provide a functional getName() in order to make
|
||||
* native XML export work correctly. It is only used in that single instance.
|
||||
*
|
||||
* @param ?string $locale unused, except to match the function prototype in Representation.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getName($locale = null)
|
||||
{
|
||||
return [$this->getLocale() => $this->getLabel()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the parent class to fetch the non-localized label.
|
||||
*
|
||||
* @see Representation::getLocalizedName()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLocalizedName()
|
||||
{
|
||||
return $this->getLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc \PKP\submission\Representation::setStoredPubId()
|
||||
*/
|
||||
public function setStoredPubId($pubIdType, $pubId)
|
||||
{
|
||||
if ($pubIdType == 'doi') {
|
||||
if ($doiObject = $this->getData('doiObject')) {
|
||||
Repo::doi()->edit($doiObject, ['doi' => $pubId]);
|
||||
} else {
|
||||
$newDoiObject = Repo::doi()->newDataObject(
|
||||
[
|
||||
'doi' => $pubId,
|
||||
'contextId' => $this->getContextId()
|
||||
]
|
||||
);
|
||||
$doiId = Repo::doi()->add($newDoiObject);
|
||||
|
||||
$this->setData('doiId', $doiId);
|
||||
}
|
||||
} else {
|
||||
parent::setStoredPubId($pubIdType, $pubId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
// Required for import/export toolset
|
||||
class_alias('\PKP\galley\Galley', '\Galley');
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/galley/Repository.php
|
||||
*
|
||||
* Copyright (c) 2014-2020 Simon Fraser University
|
||||
* Copyright (c) 2000-2020 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class Repository
|
||||
*
|
||||
* @brief A repository to find and manage galleys.
|
||||
*/
|
||||
|
||||
namespace PKP\galley;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\publication\Publication;
|
||||
use APP\submission\Submission;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use PKP\plugins\Hook;
|
||||
use PKP\services\PKPSchemaService;
|
||||
use PKP\validation\ValidatorFactory;
|
||||
|
||||
class Repository
|
||||
{
|
||||
public DAO $dao;
|
||||
|
||||
/** @var string $schemaMap The name of the class to map this entity to its schemaa */
|
||||
public string $schemaMap = maps\Schema::class;
|
||||
|
||||
protected Request $request;
|
||||
|
||||
protected PKPSchemaService $schemaService;
|
||||
|
||||
|
||||
public function __construct(DAO $dao, Request $request, PKPSchemaService $schemaService)
|
||||
{
|
||||
$this->dao = $dao;
|
||||
$this->request = $request;
|
||||
$this->schemaService = $schemaService;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::newDataObject() */
|
||||
public function newDataObject(array $params = []): Galley
|
||||
{
|
||||
$object = $this->dao->newDataObject();
|
||||
if (!empty($params)) {
|
||||
$object->setAllData($params);
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::get() */
|
||||
public function get(int $id, int $publicationId = null): ?Galley
|
||||
{
|
||||
return $this->dao->get($id, $publicationId);
|
||||
}
|
||||
|
||||
/** @copydoc DAO::exists() */
|
||||
public function exists(int $id, int $publicationId = null): bool
|
||||
{
|
||||
return $this->dao->exists($id, $publicationId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a galley by "best" galley id -- url path if it exists,
|
||||
* falling back on the internal galley ID otherwise.
|
||||
*/
|
||||
public function getByBestId(string $idOrUrlPath, Publication $publication): ?Galley
|
||||
{
|
||||
return ctype_digit((string) $idOrUrlPath)
|
||||
? $this->get((int) $idOrUrlPath, $publication->getId())
|
||||
: $this->getByUrlPath($idOrUrlPath, $publication);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a publication galley by a url path
|
||||
*/
|
||||
public function getByUrlPath(string $urlPath, Publication $publication): ?Galley
|
||||
{
|
||||
return $this->dao->getByUrlPath($urlPath, $publication);
|
||||
}
|
||||
|
||||
/** @copydoc DAO::getCollector() */
|
||||
public function getCollector(): Collector
|
||||
{
|
||||
return App::make(Collector::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of the map class for mapping
|
||||
* galleys to their schema
|
||||
*
|
||||
* @param array $genres All file genres in this context
|
||||
*/
|
||||
public function getSchemaMap(Submission $submission, Publication $publication, array $genres): maps\Schema
|
||||
{
|
||||
return app('maps')->withExtensions(
|
||||
$this->schemaMap,
|
||||
[
|
||||
'submission' => $submission,
|
||||
'publication' => $publication,
|
||||
'genres' => $genres,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate properties for a galley
|
||||
*
|
||||
* Perform validation checks on data used to add or edit an galley.
|
||||
*
|
||||
* @param array $props A key/value array with the new data to validate
|
||||
* @param array $allowedLocales The context's supported locales
|
||||
* @param string $primaryLocale The context's primary locale
|
||||
*
|
||||
* @return array A key/value array with validation errors. Empty if no errors
|
||||
*/
|
||||
public function validate(?Galley $object, array $props, array $allowedLocales, string $primaryLocale): array
|
||||
{
|
||||
$validator = ValidatorFactory::make(
|
||||
$props,
|
||||
$this->schemaService->getValidationRules($this->dao->schema, $allowedLocales),
|
||||
[
|
||||
'locale.regex' => __('validator.localeKey'),
|
||||
'urlPath.regex' => __('validator.alpha_dash_period'),
|
||||
]
|
||||
);
|
||||
|
||||
// Check required fields
|
||||
ValidatorFactory::required(
|
||||
$validator,
|
||||
$object,
|
||||
$this->schemaService->getRequiredProps($this->dao->schema),
|
||||
$this->schemaService->getMultilingualProps($this->dao->schema),
|
||||
$allowedLocales,
|
||||
$primaryLocale
|
||||
);
|
||||
|
||||
// Check for input from disallowed locales
|
||||
ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
|
||||
|
||||
$errors = [];
|
||||
|
||||
// The publicationId must match an existing publication that is not yet published
|
||||
$validator->after(function ($validator) use ($props) {
|
||||
if (isset($props['publicationId']) && !$validator->errors()->get('publicationId')) {
|
||||
$publication = Repo::publication()->get($props['publicationId']);
|
||||
if (!$publication) {
|
||||
$validator->errors()->add('publicationId', __('galley.publicationNotFound'));
|
||||
} elseif (in_array($publication->getData('status'), [Submission::STATUS_PUBLISHED, Submission::STATUS_SCHEDULED])) {
|
||||
$validator->errors()->add('publicationId', __('galley.editPublishedDisabled'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if ($validator->fails()) {
|
||||
$errors = $this->schemaService->formatValidationErrors($validator->errors());
|
||||
}
|
||||
|
||||
Hook::call('Galley::validate', [&$errors, $object, $props, $allowedLocales, $primaryLocale]);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::insert() */
|
||||
public function add(Galley $galley): int
|
||||
{
|
||||
$id = $this->dao->insert($galley);
|
||||
Hook::call('Galley::add', [$galley]);
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::update() */
|
||||
public function edit(Galley $galley, array $params): void
|
||||
{
|
||||
$newGalley = clone $galley;
|
||||
$newGalley->setAllData(array_merge($newGalley->_data, $params));
|
||||
|
||||
Hook::call('Galley::edit', [$newGalley, $galley, $params]);
|
||||
|
||||
$this->dao->update($newGalley);
|
||||
}
|
||||
|
||||
/** @copydoc DAO::delete() */
|
||||
public function delete(Galley $galley): void
|
||||
{
|
||||
Hook::call('Galley::delete::before', [$galley]);
|
||||
$this->dao->delete($galley);
|
||||
|
||||
// Delete related submission files
|
||||
$submissionFiles = Repo::submissionFile()
|
||||
->getCollector()
|
||||
->filterByAssoc(Application::ASSOC_TYPE_GALLEY)
|
||||
->filterByFileIds([$galley->getId()])
|
||||
->getMany();
|
||||
|
||||
foreach ($submissionFiles as $submissionFile) {
|
||||
Repo::submissionFile()->delete($submissionFile);
|
||||
}
|
||||
|
||||
Hook::call('Galley::delete', [$galley]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/galley/maps/Schema.php
|
||||
*
|
||||
* Copyright (c) 2014-2020 Simon Fraser University
|
||||
* Copyright (c) 2000-2020 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class Schema
|
||||
*
|
||||
* @brief Map galleys to the properties defined in the galley schema
|
||||
*/
|
||||
|
||||
namespace PKP\galley\maps;
|
||||
|
||||
use APP\core\Request;
|
||||
use APP\facades\Repo;
|
||||
use APP\publication\Publication;
|
||||
use APP\submission\Submission;
|
||||
use Illuminate\Support\Enumerable;
|
||||
use PKP\context\Context;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\galley\Galley;
|
||||
use PKP\services\PKPSchemaService;
|
||||
|
||||
class Schema extends \PKP\core\maps\Schema
|
||||
{
|
||||
public Enumerable $collection;
|
||||
public array $genres = [];
|
||||
public Publication $publication;
|
||||
public string $schema = PKPSchemaService::SCHEMA_GALLEY;
|
||||
public Submission $submission;
|
||||
|
||||
public function __construct(Submission $submission, Publication $publication, array $genres, Request $request, Context $context, PKPSchemaService $schemaService)
|
||||
{
|
||||
parent::__construct($request, $context, $schemaService);
|
||||
$this->publication = $publication;
|
||||
$this->submission = $submission;
|
||||
$this->genres = $genres;
|
||||
}
|
||||
/**
|
||||
* Map a galley
|
||||
*
|
||||
* Includes all properties in the galley schema.
|
||||
*/
|
||||
public function map(Galley $item): array
|
||||
{
|
||||
return $this->mapByProperties($this->getProps(), $item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Summarize a galley
|
||||
*
|
||||
* Includes properties with the apiSummary flag in the galley schema.
|
||||
*/
|
||||
public function summarize(Galley $item): array
|
||||
{
|
||||
return $this->mapByProperties($this->getSummaryProps(), $item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a collection of galleys
|
||||
*
|
||||
* @see self::map
|
||||
*/
|
||||
public function mapMany(Enumerable $collection): Enumerable
|
||||
{
|
||||
$this->collection = $collection;
|
||||
return $collection->map(function ($item) {
|
||||
return $this->map($item);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Summarize a collection of galleys
|
||||
*
|
||||
* @see self::summarize
|
||||
*/
|
||||
public function summarizeMany(Enumerable $collection): Enumerable
|
||||
{
|
||||
$this->collection = $collection;
|
||||
return $collection->map(function ($item) {
|
||||
return $this->summarize($item);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Map schema properties of a galley to an assoc array
|
||||
*/
|
||||
protected function mapByProperties(array $props, Galley $galley): array
|
||||
{
|
||||
$output = [];
|
||||
foreach ($props as $prop) {
|
||||
switch ($prop) {
|
||||
case 'doiObject':
|
||||
if ($galley->getData('doiObject')) {
|
||||
$retVal = Repo::doi()->getSchemaMap()->summarize($galley->getData('doiObject'));
|
||||
} else {
|
||||
$retVal = null;
|
||||
}
|
||||
$output[$prop] = $retVal;
|
||||
break;
|
||||
case 'file':
|
||||
$output[$prop] = null;
|
||||
if (is_a($galley, 'Galley')) {
|
||||
if (!$galley->getData('submissionFileId')) {
|
||||
break;
|
||||
}
|
||||
|
||||
$submissionFile = Repo::submissionFile()->get($galley->getData('submissionFileId'));
|
||||
|
||||
if (empty($submissionFile)) {
|
||||
break;
|
||||
}
|
||||
|
||||
$output[$prop] = Repo::submissionFile()
|
||||
->getSchemaMap()
|
||||
->map($submissionFile, $this->genres);
|
||||
}
|
||||
break;
|
||||
case 'urlPublished':
|
||||
|
||||
$output['urlPublished'] = $this->request->getDispatcher()->url(
|
||||
$this->request,
|
||||
PKPApplication::ROUTE_PAGE,
|
||||
$this->context->getData('urlPath'),
|
||||
'article',
|
||||
'view',
|
||||
[
|
||||
$this->submission->getBestId(),
|
||||
'version',
|
||||
$this->publication->getId(),
|
||||
$galley->getBestGalleyId()
|
||||
]
|
||||
);
|
||||
break;
|
||||
default:
|
||||
$output[$prop] = $galley->getData($prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$output = $this->schemaService->addMissingMultilingualValues($this->schema, $output, $this->context->getSupportedFormLocales());
|
||||
|
||||
ksort($output);
|
||||
|
||||
return $this->withExtensions($output, $galley);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user