462 lines
12 KiB
PHP
462 lines
12 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/submission/GenreDAO.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2003-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class GenreDAO
|
|
*
|
|
* @ingroup submission
|
|
*
|
|
* @see Genre
|
|
*
|
|
* @brief Operations for retrieving and modifying Genre objects.
|
|
*/
|
|
|
|
namespace PKP\submission;
|
|
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\DB;
|
|
use PKP\db\DAO;
|
|
use PKP\db\DAOResultFactory;
|
|
use PKP\db\XMLDAO;
|
|
use PKP\plugins\Hook;
|
|
|
|
class GenreDAO extends DAO
|
|
{
|
|
/**
|
|
* Retrieve a genre by type id.
|
|
*
|
|
* @param int $genreId
|
|
* @param null|mixed $contextId
|
|
*
|
|
* @return Genre
|
|
*/
|
|
public function getById($genreId, $contextId = null)
|
|
{
|
|
$params = [(int) $genreId];
|
|
if ($contextId) {
|
|
$params[] = (int) $contextId;
|
|
}
|
|
|
|
$result = $this->retrieve(
|
|
'SELECT * FROM genres WHERE genre_id = ?' .
|
|
($contextId ? ' AND context_id = ?' : '') .
|
|
' ORDER BY seq',
|
|
$params
|
|
);
|
|
$row = $result->current();
|
|
return $row ? $this->_fromRow((array) $row) : null;
|
|
}
|
|
|
|
/**
|
|
* Retrieve all genres
|
|
*
|
|
* @param int $contextId
|
|
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
|
*
|
|
* @return DAOResultFactory<Genre> containing matching genres
|
|
*/
|
|
public function getEnabledByContextId($contextId, $rangeInfo = null)
|
|
{
|
|
$result = $this->retrieveRange(
|
|
'SELECT * FROM genres
|
|
WHERE enabled = ? AND context_id = ?
|
|
ORDER BY seq',
|
|
[1, (int) $contextId],
|
|
$rangeInfo
|
|
);
|
|
|
|
return new DAOResultFactory($result, $this, '_fromRow', ['id']);
|
|
}
|
|
|
|
/**
|
|
* Retrieve genres based on whether they are dependent or not.
|
|
*
|
|
* @param bool $dependentFilesOnly
|
|
* @param int $contextId
|
|
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
|
*
|
|
* @return DAOResultFactory<Genre> containing matching genres
|
|
*/
|
|
public function getByDependenceAndContextId($dependentFilesOnly, $contextId, $rangeInfo = null)
|
|
{
|
|
$result = $this->retrieveRange(
|
|
'SELECT * FROM genres
|
|
WHERE enabled = ? AND context_id = ? AND dependent = ?
|
|
ORDER BY seq',
|
|
[1, (int) $contextId, (int) $dependentFilesOnly],
|
|
$rangeInfo
|
|
);
|
|
|
|
return new DAOResultFactory($result, $this, '_fromRow', ['id']);
|
|
}
|
|
|
|
/**
|
|
* Retrieve genres based on whether they are supplementary or not.
|
|
*
|
|
* @param bool $supplementaryFilesOnly
|
|
* @param int $contextId
|
|
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
|
*
|
|
* @return DAOResultFactory<Genre>
|
|
*/
|
|
public function getBySupplementaryAndContextId($supplementaryFilesOnly, $contextId, $rangeInfo = null)
|
|
{
|
|
$result = $this->retrieveRange(
|
|
'SELECT * FROM genres
|
|
WHERE enabled = ? AND context_id = ? AND supplementary = ?
|
|
ORDER BY seq',
|
|
[1, (int) $contextId, (int) $supplementaryFilesOnly],
|
|
$rangeInfo
|
|
);
|
|
|
|
return new DAOResultFactory($result, $this, '_fromRow', ['id']);
|
|
}
|
|
|
|
/**
|
|
* Retrieve genres that are not supplementary or dependent.
|
|
*
|
|
* @param int $contextId
|
|
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
|
*
|
|
* @return DAOResultFactory<Genre>
|
|
*/
|
|
public function getPrimaryByContextId($contextId, $rangeInfo = null)
|
|
{
|
|
$result = $this->retrieveRange(
|
|
'SELECT * FROM genres
|
|
WHERE enabled = ? AND context_id = ? AND dependent = ? AND supplementary = ?
|
|
ORDER BY seq',
|
|
[1, (int) $contextId, 0, 0],
|
|
$rangeInfo
|
|
);
|
|
|
|
return new DAOResultFactory($result, $this, '_fromRow', ['id']);
|
|
}
|
|
|
|
/**
|
|
* Retrieve all genres
|
|
*
|
|
* @param int $contextId
|
|
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
|
*
|
|
* @return DAOResultFactory<Genre> containing matching genres
|
|
*/
|
|
public function getByContextId($contextId, $rangeInfo = null)
|
|
{
|
|
$result = $this->retrieveRange(
|
|
'SELECT * FROM genres WHERE context_id = ? ORDER BY seq',
|
|
[(int) $contextId],
|
|
$rangeInfo
|
|
);
|
|
|
|
return new DAOResultFactory($result, $this, '_fromRow', ['id']);
|
|
}
|
|
|
|
/**
|
|
* Get genres that are required for a new
|
|
* submission in a context
|
|
*/
|
|
public function getRequiredToSubmit(int $contextId): Collection
|
|
{
|
|
return DB::table('genres')
|
|
->where('context_id', $contextId)
|
|
->where('required', 1)
|
|
->get()
|
|
->map(function (object $row) {
|
|
return $this->_fromRow((array) $row);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Retrieves the genre associated with a key.
|
|
*
|
|
* @param string $key the entry key
|
|
* @param int $contextId Optional context ID
|
|
*
|
|
* @return Genre
|
|
*/
|
|
public function getByKey($key, $contextId = null)
|
|
{
|
|
$params = [$key];
|
|
if ($contextId) {
|
|
$params[] = (int) $contextId;
|
|
}
|
|
|
|
$result = $this->retrieve(
|
|
'SELECT * FROM genres WHERE entry_key = ? ' .
|
|
($contextId ? ' AND context_id = ?' : ''),
|
|
$params
|
|
);
|
|
|
|
$row = $result->current();
|
|
return $row ? $this->_fromRow((array) $row) : null;
|
|
}
|
|
|
|
/**
|
|
* Get a list of field names for which data is localized.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getLocaleFieldNames()
|
|
{
|
|
return ['name'];
|
|
}
|
|
|
|
/**
|
|
* Update the settings for this object
|
|
*
|
|
* @param object $genre
|
|
*/
|
|
public function updateLocaleFields($genre)
|
|
{
|
|
$this->updateDataObjectSettings(
|
|
'genre_settings',
|
|
$genre,
|
|
['genre_id' => $genre->getId()]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Construct a new data object corresponding to this DAO.
|
|
*
|
|
* @return Genre
|
|
*/
|
|
public function newDataObject()
|
|
{
|
|
return new Genre();
|
|
}
|
|
|
|
/**
|
|
* Internal function to return a Genre object from a row.
|
|
*
|
|
* @param array $row
|
|
*
|
|
* @return Genre
|
|
*/
|
|
public function _fromRow($row)
|
|
{
|
|
$genre = $this->newDataObject();
|
|
$genre->setId((int) $row['genre_id']);
|
|
$genre->setKey($row['entry_key']);
|
|
$genre->setContextId($row['context_id']);
|
|
$genre->setCategory((int) $row['category']);
|
|
$genre->setDependent($row['dependent']);
|
|
$genre->setSupplementary($row['supplementary']);
|
|
$genre->setRequired($row['required']);
|
|
$genre->setSequence($row['seq']);
|
|
$genre->setEnabled($row['enabled']);
|
|
|
|
$this->getDataObjectSettings('genre_settings', 'genre_id', $row['genre_id'], $genre);
|
|
|
|
Hook::call('GenreDAO::_fromRow', [&$genre, &$row]);
|
|
|
|
return $genre;
|
|
}
|
|
|
|
/**
|
|
* Insert a new genre.
|
|
*
|
|
* @param Genre $genre
|
|
*
|
|
* @return int Inserted genre ID
|
|
*/
|
|
public function insertObject($genre)
|
|
{
|
|
$this->update(
|
|
'INSERT INTO genres
|
|
(entry_key, seq, context_id, category, dependent, supplementary, required)
|
|
VALUES
|
|
(?, ?, ?, ?, ?, ?, ?)',
|
|
[
|
|
$genre->getKey(),
|
|
(float) $genre->getSequence(),
|
|
(int) $genre->getContextId(),
|
|
(int) $genre->getCategory(),
|
|
$genre->getDependent() ? 1 : 0,
|
|
$genre->getSupplementary() ? 1 : 0,
|
|
$genre->getRequired() ? 1 : 0,
|
|
]
|
|
);
|
|
|
|
$genre->setId($this->getInsertId());
|
|
$this->updateLocaleFields($genre);
|
|
return $genre->getId();
|
|
}
|
|
|
|
/**
|
|
* Update an existing genre.
|
|
*
|
|
* @param Genre $genre
|
|
*/
|
|
public function updateObject($genre)
|
|
{
|
|
$this->update(
|
|
'UPDATE genres
|
|
SET entry_key = ?,
|
|
seq = ?,
|
|
dependent = ?,
|
|
supplementary = ?,
|
|
enabled = ?,
|
|
category = ?,
|
|
required = ?
|
|
WHERE genre_id = ?',
|
|
[
|
|
$genre->getKey(),
|
|
(float) $genre->getSequence(),
|
|
$genre->getDependent() ? 1 : 0,
|
|
$genre->getSupplementary() ? 1 : 0,
|
|
$genre->getEnabled() ? 1 : 0,
|
|
$genre->getCategory(),
|
|
$genre->getRequired() ? 1 : 0,
|
|
(int) $genre->getId(),
|
|
]
|
|
);
|
|
$this->updateLocaleFields($genre);
|
|
}
|
|
|
|
/**
|
|
* Delete a genre by id.
|
|
*
|
|
* @param Genre $genre
|
|
*/
|
|
public function deleteObject($genre)
|
|
{
|
|
return $this->deleteById($genre->getId());
|
|
}
|
|
|
|
/**
|
|
* Soft delete a genre by id.
|
|
*
|
|
* @param int $genreId Genre ID
|
|
*/
|
|
public function deleteById($genreId)
|
|
{
|
|
return $this->update(
|
|
'UPDATE genres SET enabled = ? WHERE genre_id = ?',
|
|
[0, (int) $genreId]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Delete the genre entries associated with a context.
|
|
* Called when deleting a Context in ContextDAO.
|
|
*
|
|
* @param int $contextId Context ID
|
|
*/
|
|
public function deleteByContextId($contextId)
|
|
{
|
|
$genres = $this->getByContextId($contextId);
|
|
while ($genre = $genres->next()) {
|
|
$this->update('DELETE FROM genre_settings WHERE genre_id = ?', [(int) $genre->getId()]);
|
|
}
|
|
$this->update(
|
|
'DELETE FROM genres WHERE context_id = ?',
|
|
[(int) $contextId]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Install default data for settings.
|
|
*
|
|
* @param int $contextId Context ID
|
|
* @param array $locales List of locale codes
|
|
*/
|
|
public function installDefaults($contextId, $locales)
|
|
{
|
|
$xmlDao = new XMLDAO();
|
|
$data = $xmlDao->parseStruct('registry/genres.xml', ['genre']);
|
|
if (!isset($data['genre'])) {
|
|
return false;
|
|
}
|
|
$seq = 0;
|
|
|
|
foreach ($data['genre'] as $entry) {
|
|
$attrs = $entry['attributes'];
|
|
// attempt to retrieve an installed Genre with this key.
|
|
// Do this to preserve the genreId.
|
|
$genre = $this->getByKey($attrs['key'], $contextId);
|
|
if (!$genre) {
|
|
$genre = $this->newDataObject();
|
|
}
|
|
$genre->setContextId($contextId);
|
|
$genre->setKey($attrs['key']);
|
|
$genre->setCategory($attrs['category']);
|
|
$genre->setDependent($attrs['dependent']);
|
|
$genre->setSupplementary($attrs['supplementary']);
|
|
$genre->setRequired((bool) ($attrs['required'] ?? false));
|
|
$genre->setSequence($seq++);
|
|
foreach ($locales as $locale) {
|
|
$genre->setName(__($attrs['localeKey'], [], $locale), $locale);
|
|
}
|
|
|
|
if ($genre->getId() > 0) { // existing genre.
|
|
$genre->setEnabled(1);
|
|
$this->updateObject($genre);
|
|
} else {
|
|
$this->insertObject($genre);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get default keys.
|
|
*
|
|
* @return array List of default keys
|
|
*/
|
|
public function getDefaultKeys()
|
|
{
|
|
$defaultKeys = [];
|
|
$xmlDao = new XMLDAO();
|
|
$data = $xmlDao->parseStruct('registry/genres.xml', ['genre']);
|
|
if (isset($data['genre'])) {
|
|
foreach ($data['genre'] as $entry) {
|
|
$attrs = $entry['attributes'];
|
|
$defaultKeys[] = $attrs['key'];
|
|
}
|
|
}
|
|
return $defaultKeys;
|
|
}
|
|
|
|
/**
|
|
* If a key exists for a context.
|
|
*
|
|
* @param string $key
|
|
* @param int $contextId
|
|
* @param int $genreId (optional) Current genre to be ignored
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function keyExists($key, $contextId, $genreId = null)
|
|
{
|
|
$params = [$key, (int) $contextId];
|
|
if ($genreId) {
|
|
$params[] = (int) $genreId;
|
|
}
|
|
$result = $this->retrieveRange(
|
|
'SELECT COUNT(*) AS row_count FROM genres WHERE entry_key = ? AND context_id = ?' . (isset($genreId) ? ' AND genre_id <> ?' : ''),
|
|
$params
|
|
);
|
|
$row = $result->current();
|
|
return $row ? (bool) $row->row_count : false;
|
|
}
|
|
|
|
/**
|
|
* Remove all settings associated with a locale
|
|
*
|
|
* @param string $locale Locale code
|
|
*/
|
|
public function deleteSettingsByLocale($locale)
|
|
{
|
|
$this->update('DELETE FROM genre_settings WHERE locale = ?', [$locale]);
|
|
}
|
|
}
|
|
|
|
if (!PKP_STRICT_MODE) {
|
|
class_alias('\PKP\submission\GenreDAO', '\GenreDAO');
|
|
}
|