| Server IP : 127.0.1.1 / Your IP : 216.73.216.83 Web Server : Apache/2.4.58 (Ubuntu) System : Linux nepub 6.8.0-88-generic #89-Ubuntu SMP PREEMPT_DYNAMIC Sat Oct 11 01:02:46 UTC 2025 x86_64 User : root ( 0) PHP Version : 8.2.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/public_html/lib/pkp/classes/services/ |
Upload File : |
<?php
/**
* @file classes/services/PKPSiteService.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 PKPSiteService
* @ingroup services
*
* @brief Helper class that encapsulates business logic for the overall site
*/
namespace PKP\Services;
use \Application;
use \DAORegistry;
use \Services;
use \PKP\Services\interfaces\EntityPropertyInterface;
use \PKP\Services\interfaces\EntityWriteInterface;
class PKPSiteService implements EntityPropertyInterface {
/**
* @copydoc \PKP\Services\interfaces\EntityPropertyInterface::getProperties()
*/
public function getProperties($site, $props, $args = null) {
$request = $args['request'];
$router = $request->getRouter();
$dispatcher = $request->getDispatcher();
$values = array();
foreach ($props as $prop) {
$values[$prop] = $site->getData($prop);
}
$values = Services::get('schema')->addMissingMultilingualValues(SCHEMA_SITE, $values, $site->getSupportedLocales());
\HookRegistry::call('Site::getProperties', array(&$values, $site, $props, $args));
ksort($values);
return $values;
}
/**
* @copydoc \PKP\Services\interfaces\EntityPropertyInterface::getSummaryProperties()
*/
public function getSummaryProperties($site, $args = null) {
return $this->getFullProperties($site, $args);
}
/**
* @copydoc \PKP\Services\interfaces\EntityPropertyInterface::getFullProperties()
*/
public function getFullProperties($site, $args = null) {
$props = Services::get('schema')->getFullProps(SCHEMA_SITE);
return $this->getProperties($site, $props, $args);
}
/**
* Validate the properties of a site
*
* Passes the properties through the SchemaService to validate them, and
* performs any additional checks needed to validate a site.
*
* This does NOT authenticate the current user to perform the action.
*
* @param $props array The data to validate
* @param $allowedLocales array Which locales are allowed for this context
* @param $primaryLocale string
* @return array List of error messages. The array keys are property names
*/
public function validate($props, $allowedLocales, $primaryLocale) {
\AppLocale::requireComponents(
LOCALE_COMPONENT_PKP_ADMIN,
LOCALE_COMPONENT_APP_ADMIN,
LOCALE_COMPONENT_PKP_MANAGER,
LOCALE_COMPONENT_APP_MANAGER
);
$schemaService = Services::get('schema');
import('lib.pkp.classes.validation.ValidatorFactory');
$validator = \ValidatorFactory::make(
$props,
$schemaService->getValidationRules(SCHEMA_SITE, $allowedLocales),
[
'primaryLocale.regex' => __('validator.localeKey'),
'supportedLocales.regex' => __('validator.localeKey'),
]
);
// Check required fields
\ValidatorFactory::required(
$validator,
VALIDATE_ACTION_EDIT,
$schemaService->getRequiredProps(SCHEMA_PUBLICATION),
$schemaService->getMultilingualProps(SCHEMA_PUBLICATION),
$allowedLocales,
$primaryLocale
);
// Check for input from disallowed locales
\ValidatorFactory::allowedLocales(
$validator,
$schemaService->getMultilingualProps(SCHEMA_SITE),
$allowedLocales
);
// If a new file has been uploaded, check that the temporary file exists and
// the current user owns it
$user = Application::get()->getRequest()->getUser();
\ValidatorFactory::temporaryFilesExist(
$validator,
['pageHeaderTitleImage', 'styleSheet'],
['pageHeaderTitleImage'],
$props,
$allowedLocales,
$user ? $user->getId() : null
);
// If sidebar blocks are passed, ensure the block plugin exists and is
// enabled
$validator->after(function($validator) use ($props) {
if (!empty($props['sidebar']) && !$validator->errors()->get('sidebar')) {
$plugins = \PluginRegistry::loadCategory('blocks', true);
foreach ($props['sidebar'] as $pluginName) {
if (empty($plugins[$pluginName])) {
$validator->errors()->add('sidebar', __('manager.setup.layout.sidebar.invalidBlock', ['name' => $pluginName]));
}
}
}
});
// Ensure the theme plugin is installed and enabled
$validator->after(function($validator) use ($props) {
if (!empty($props['themePluginPath']) && !$validator->errors()->get('themePluginPath')) {
$plugins = \PluginRegistry::loadCategory('themes', true);
$found = false;
foreach ($plugins as $plugin) {
if ($props['themePluginPath'] === $plugin->getDirName()) {
$found = true;
break;
}
}
if (!$found) {
$validator->errors()->add('themePluginPath', __('manager.setup.theme.notFound'));
}
}
});
if ($validator->fails()) {
$errors = $schemaService->formatValidationErrors($validator->errors(), $schemaService->get(SCHEMA_SITE), $allowedLocales);
}
\HookRegistry::call('Site::validate', array(&$errors, $props, $allowedLocales, $primaryLocale));
return $errors;
}
/**
* Edit the site
*
* This does not check if the user is authorized to edit the site, or validate or sanitize
* the new content.
*
* @param $site Context The context to edit
* @param $params Array Key/value array of new data
* @param $request Request
* @return Site
*/
public function edit($site, $params, $request) {
$siteDao = DAORegistry::getDAO('SiteDAO'); /* @var $siteDao SiteDAO */
// Move uploaded files into place and update the params
$userId = $request->getUser() ? $request->getUser()->getId() : null;
$supportedLocales = $site->getSupportedLocales();
if (array_key_exists('pageHeaderTitleImage', $params)) {
foreach ($supportedLocales as $localeKey) {
if (!array_key_exists($localeKey, $params['pageHeaderTitleImage'])) {
continue;
}
$params['pageHeaderTitleImage'][$localeKey] = $this->_saveFileParam($site, $params['pageHeaderTitleImage'][$localeKey], 'pageHeaderTitleImage', $userId, $localeKey, true);
}
}
if (array_key_exists('styleSheet', $params)) {
$params['styleSheet'] = $this->_saveFileParam($site, $params['styleSheet'], 'styleSheet', $userId);
}
$newSite = $siteDao->newDataObject();
$newSite->_data = array_merge($site->_data, $params);
\HookRegistry::call('Site::edit', array(&$newSite, $site, $params, $request));
$siteDao->updateObject($newSite);
$newSite = $siteDao->getSite();
return $newSite;
}
/**
* Move a temporary file to the site's public directory
*
* @param $context Context
* @param $temporaryFile TemporaryFile
* @param $fileNameBase string Unique identifier to use for the filename. The
* Extension and locale will be appended.
* @param $userId int ID of the user who uploaded the temporary file
* @param $localeKey string Example: en_US. Leave empty for a file that is
* not localized.
* @return string|boolean The new filename or false on failure
*/
public function moveTemporaryFile($context, $temporaryFile, $fileNameBase, $userId, $localeKey = '') {
import('classes.file.PublicFileManager');
$publicFileManager = new \PublicFileManager();
import('lib.pkp.classes.file.TemporaryFileManager');
$temporaryFileManager = new \TemporaryFileManager();
$fileName = $fileNameBase;
if ($localeKey) {
$fileName .= '_' . $localeKey;
}
$extension = $publicFileManager->getDocumentExtension($temporaryFile->getFileType());
if (!$extension) {
$extension = $publicFileManager->getImageExtension($temporaryFile->getFileType());
}
$fileName .= $extension;
if (!$publicFileManager->copyFile($temporaryFile->getFilePath(), $publicFileManager->getSiteFilesPath() . '/' . $fileName)) {
return false;
}
$temporaryFileManager->deleteById($temporaryFile->getId(), $userId);
return $fileName;
}
/**
* Handle a site setting for an uploaded file
*
* - Moves the temporary file to the public directory
* - Resets the param value to what is expected to be stored in the db
*
* This method is protected because all operations which edit the site should
* go through the editSite method in order to ensure that the appropriate hooks are fired.
*
* @param $site Site The site being edited
* @param $value mixed The param value to be saved. Contains the temporary
* file ID if a new file has been uploaded.
* @param $settingName string The name of the setting to save, typically used
* in the filename.
* @param $userId integer ID of the user who owns the temporary file
* @param $localeKey string Optional. Used in the filename for multilingual
* properties.
* @param $isImage boolean Optional. For image files which return alt text,
* width, height, etc in the param value.
* @return string|array|null New param value or null on failure
*/
protected function _saveFileParam($site, $value, $settingName, $userId, $localeKey = '', $isImage = false) {
import('lib.pkp.classes.file.TemporaryFileManager');
$temporaryFileManager = new \TemporaryFileManager();
// If the value is null, clean up any existing file in the system
if (is_null($value)) {
$setting = $site->getData($settingName, $localeKey);
if ($setting) {
$fileName = $isImage ? $setting['uploadName'] : $setting;
import('classes.file.PublicFileManager');
$publicFileManager = new \PublicFileManager();
$publicFileManager->removeSiteFile($fileName);
}
return null;
}
// Check if there is something to upload
if (empty($value['temporaryFileId'])) {
return $value;
}
$temporaryFile = $temporaryFileManager->getFile((int) $value['temporaryFileId'], $userId);
$fileName = $this->moveTemporaryFile($site, $temporaryFile, $settingName, $userId, $localeKey);
if ($fileName) {
// Get the details for image uploads
if ($isImage) {
import('classes.file.PublicFileManager');
$publicFileManager = new \PublicFileManager();
list($width, $height) = getimagesize($publicFileManager->getSiteFilesPath() . '/' . $fileName);
$altText = !empty($value['altText']) ? $value['altText'] : '';
return [
'originalFilename' => $temporaryFile->getOriginalFileName(),
'uploadName' => $fileName,
'width' => $width,
'height' => $height,
'dateUploaded' => \Core::getCurrentDate(),
'altText' => $altText,
];
} else {
return [
'originalFilename' => $temporaryFile->getOriginalFileName(),
'uploadName' => $fileName,
'dateUploaded' => \Core::getCurrentDate(),
];
}
}
return false;
}
}