<?php
/**
* @file classes/institution/Repository.php
*
* Copyright (c) 2022 Simon Fraser University
* Copyright (c) 2022 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 institutions.
*/
namespace PKP\institution;
use APP\core\Request;
use APP\core\Services;
use Illuminate\Support\Facades\App;
use Illuminate\Support\LazyCollection;
use PKP\core\PKPString;
use PKP\plugins\Hook;
use PKP\services\PKPSchemaService;
use PKP\validation\ValidatorFactory;
class Repository
{
public DAO $dao;
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 = []): Institution
{
$object = $this->dao->newDataObject();
if (!empty($params)) {
$object->setAllData($params);
}
return $object;
}
/** @copydoc DAO::exists() */
public function exists(int $id, int $contextId = null): bool
{
return $this->dao->exists($id, $contextId);
}
/** @copydoc DAO::get() */
public function get(int $id, int $contextId = null): ?Institution
{
return $this->dao->get($id, $contextId);
}
/** @copydoc DAO::getSoftDeleted() */
public function getSoftDeleted(Collector $query): LazyCollection
{
return $this->dao->getSoftDeleted($query);
}
/** @copydoc DAO::getCollector() */
public function getCollector(): Collector
{
return App::make(Collector::class);
}
/**
* Get an instance of the map class for mapping
* institutions to their schema
*/
public function getSchemaMap(): maps\Schema
{
return app('maps')->withExtensions($this->schemaMap);
}
/**
* Validate properties for an institution
*
* Perform validation checks on data used to add or edit an institution.
*
* @param Institution|null $object Institution being edited. Pass `null` if creating a new submission
* @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(?Institution $object, array $props, array $allowedLocales, string $primaryLocale): array
{
$errors = [];
$validator = ValidatorFactory::make(
$props,
$this->schemaService->getValidationRules($this->dao->schema, $allowedLocales)
);
// Check required fields if we're adding an institution
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);
// The contextId must match an existing context
$validator->after(function ($validator) use ($props) {
if (isset($props['contextId']) && !$validator->errors()->get('contextId')) {
$institutionContext = Services::get('context')->get($props['contextId']);
if (!$institutionContext) {
$validator->errors()->add('contextId', __('manager.institutions.noContext'));
}
}
if (!empty($props['ipRanges']) && !$validator->errors()->get('ipRanges')) {
foreach ($props['ipRanges'] as $ipRange) {
if (!PKPString::regexp_match(
'/^' .
// IP4 address (with or w/o wildcards) or IP4 address range (with or w/o wildcards) or CIDR IP4 address
'((([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5]|[' . Institution::IP_RANGE_WILDCARD . '])([.]([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5]|[' . Institution::IP_RANGE_WILDCARD . '])){3}((\s)*[' . Institution::IP_RANGE_RANGE . '](\s)*([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5]|[' . Institution::IP_RANGE_WILDCARD . '])([.]([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5]|[' . Institution::IP_RANGE_WILDCARD . '])){3}){0,1})|(([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5])([.]([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5])){3}([\/](([3][0-2]{0,1})|([1-2]{0,1}[0-9])))))' .
'$/i',
trim($ipRange)
)) {
$validator->errors()->add('ipRanges', __('manager.institutions.invalidIPRange'));
break;
}
}
}
});
if ($validator->fails()) {
$errors = $this->schemaService->formatValidationErrors($validator->errors());
}
Hook::call('Institution::validate', [&$errors, $object, $props, $allowedLocales, $primaryLocale]);
return $errors;
}
/** @copydoc DAO::insert() */
public function add(Institution $institution): int
{
$id = $this->dao->insert($institution);
Hook::call('Institution::add', [$institution]);
return $id;
}
/** @copydoc DAO::update() */
public function edit(Institution $institution, array $params): void
{
$newInstitution = clone $institution;
$newInstitution->setAllData(array_merge($newInstitution->_data, $params));
Hook::call('Institution::edit', [$newInstitution, $institution, $params]);
$this->dao->update($newInstitution);
}
/** @copydoc DAO::delete() */
public function delete(Institution $institution): void
{
Hook::call('Institution::delete::before', [$institution]);
$this->dao->delete($institution);
Hook::call('Institution::delete', [$institution]);
}
/**
* Delete a collection of institutions
*/
public function deleteMany(Collector $collector): void
{
foreach ($collector->getMany() as $institution) {
$this->delete($institution);
}
}
}
|