first commit
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/plugins/PluginSettingsDAO.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 PluginSettingsDAO
|
||||
*
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @see Plugin
|
||||
*
|
||||
* @brief Operations for retrieving and modifying plugin settings.
|
||||
*/
|
||||
|
||||
namespace PKP\plugins;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use PKP\cache\CacheManager;
|
||||
use PKP\cache\GenericCache;
|
||||
use PKP\xml\PKPXMLParser;
|
||||
|
||||
class PluginSettingsDAO extends \PKP\db\DAO
|
||||
{
|
||||
/**
|
||||
* Get the cache for plugin settings.
|
||||
*
|
||||
* @param int $contextId Context ID
|
||||
* @param string $pluginName Plugin symbolic name
|
||||
*
|
||||
* @return GenericCache
|
||||
*/
|
||||
public function _getCache($contextId, $pluginName)
|
||||
{
|
||||
static $settingCache = [];
|
||||
return $settingCache[(int) $contextId][$pluginName] ??= CacheManager::getManager()->getCache(
|
||||
'pluginSettings-' . $contextId,
|
||||
$pluginName,
|
||||
[$this, '_cacheMiss']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a plugin setting value.
|
||||
*
|
||||
* @param int $contextId Context ID
|
||||
* @param string $pluginName Plugin symbolic name
|
||||
* @param string $name Setting name
|
||||
*/
|
||||
public function getSetting($contextId, $pluginName, $name)
|
||||
{
|
||||
// Normalize the plug-in name to lower case.
|
||||
$pluginName = strtolower_codesafe($pluginName);
|
||||
|
||||
// Retrieve the setting.
|
||||
$cache = $this->_getCache($contextId, $pluginName);
|
||||
return $cache->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the plugin setting exist.
|
||||
*
|
||||
* @param int $contextId Context ID
|
||||
* @param string $pluginName Plugin symbolic name
|
||||
* @param string $name Setting name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function settingExists($contextId, $pluginName, $name)
|
||||
{
|
||||
$pluginName = strtolower_codesafe($pluginName);
|
||||
$result = $this->retrieve(
|
||||
'SELECT COUNT(*) AS row_count FROM plugin_settings WHERE plugin_name = ? AND context_id = ? AND setting_name = ?',
|
||||
[$pluginName, (int) $contextId, $name]
|
||||
);
|
||||
$row = $result->current();
|
||||
return $row ? (bool) $row->row_count : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for a cache miss.
|
||||
*
|
||||
* @param object $cache Cache object
|
||||
* @param string $id Identifier to look up in cache
|
||||
*/
|
||||
public function _cacheMiss($cache, $id)
|
||||
{
|
||||
$contextParts = explode('-', $cache->getContext());
|
||||
$contextId = array_pop($contextParts);
|
||||
$settings = $this->getPluginSettings($contextId, $cache->getCacheId());
|
||||
if (!isset($settings[$id])) {
|
||||
// Make sure that even null values are cached
|
||||
$cache->setCache($id, null);
|
||||
return null;
|
||||
}
|
||||
return $settings[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and cache all settings for a plugin.
|
||||
*
|
||||
* @param int $contextId Context ID
|
||||
* @param string $pluginName Plugin symbolic name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPluginSettings($contextId, $pluginName)
|
||||
{
|
||||
// Normalize plug-in name to lower case.
|
||||
$pluginName = strtolower_codesafe($pluginName);
|
||||
|
||||
$result = $this->retrieve(
|
||||
'SELECT setting_name, setting_value, setting_type FROM plugin_settings WHERE plugin_name = ? AND context_id = ?',
|
||||
[$pluginName, (int) $contextId]
|
||||
);
|
||||
|
||||
$pluginSettings = [];
|
||||
foreach ($result as $row) {
|
||||
$pluginSettings[$row->setting_name] = $this->convertFromDB($row->setting_value, $row->setting_type);
|
||||
}
|
||||
|
||||
$cache = $this->_getCache($contextId, $pluginName);
|
||||
$cache->setEntireCache($pluginSettings);
|
||||
|
||||
return $pluginSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add/update a plugin setting.
|
||||
*
|
||||
* @param int $contextId Context ID
|
||||
* @param string $pluginName Symbolic plugin name
|
||||
* @param string $name Setting name
|
||||
* @param mixed $value Setting value
|
||||
* @param string $type data type of the setting. If omitted, type will be guessed
|
||||
*/
|
||||
public function updateSetting($contextId, $pluginName, $name, $value, $type = null)
|
||||
{
|
||||
// Normalize the plug-in name to lower case.
|
||||
$pluginName = strtolower_codesafe($pluginName);
|
||||
|
||||
$cache = $this->_getCache($contextId, $pluginName);
|
||||
$cache->setCache($name, $value);
|
||||
|
||||
$value = $this->convertToDB($value, $type);
|
||||
|
||||
DB::table('plugin_settings')->updateOrInsert(
|
||||
['context_id' => (int) $contextId, 'plugin_name' => $pluginName, 'setting_name' => $name],
|
||||
['setting_value' => $value, 'setting_type' => $type]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a plugin setting.
|
||||
*
|
||||
* @param int $contextId
|
||||
* @param int $pluginName
|
||||
* @param string $name
|
||||
*/
|
||||
public function deleteSetting($contextId, $pluginName, $name)
|
||||
{
|
||||
// Normalize the plug-in name to lower case.
|
||||
$pluginName = strtolower_codesafe($pluginName);
|
||||
|
||||
$cache = $this->_getCache($contextId, $pluginName);
|
||||
$cache->setCache($name, null);
|
||||
|
||||
return $this->update(
|
||||
'DELETE FROM plugin_settings WHERE plugin_name = ? AND setting_name = ? AND context_id = ?',
|
||||
[$pluginName, $name, (int) $contextId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all settings for a plugin.
|
||||
*
|
||||
* @param int $contextId
|
||||
* @param string $pluginName
|
||||
*/
|
||||
public function deleteSettingsByPlugin($contextId, $pluginName)
|
||||
{
|
||||
// Normalize the plug-in name to lower case.
|
||||
$pluginName = strtolower_codesafe($pluginName);
|
||||
|
||||
$cache = $this->_getCache($contextId, $pluginName);
|
||||
$cache->flush();
|
||||
|
||||
return $this->update(
|
||||
'DELETE FROM plugin_settings WHERE context_id = ? AND plugin_name = ?',
|
||||
[(int) $contextId, $pluginName]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all settings for a context.
|
||||
*
|
||||
* @param int $contextId
|
||||
*/
|
||||
public function deleteByContextId($contextId)
|
||||
{
|
||||
return $this->update(
|
||||
'DELETE FROM plugin_settings WHERE context_id = ?',
|
||||
[(int) $contextId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally by installSettings to perform variable and translation replacements.
|
||||
*
|
||||
* @param string $rawInput contains text including variable and/or translate replacements.
|
||||
* @param array $paramArray contains variables for replacement
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function _performReplacement($rawInput, $paramArray = [])
|
||||
{
|
||||
$value = preg_replace_callback('{{translate key="([^"]+)"}}', fn ($matches) => __($matches[1]), (string) $rawInput);
|
||||
foreach ($paramArray as $pKey => $pValue) {
|
||||
$value = str_replace('{$' . $pKey . '}', $pValue, $value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally by installSettings to recursively build nested arrays.
|
||||
* Deals with translation and variable replacement calls.
|
||||
*
|
||||
* @param object $node XMLNode <array> tag
|
||||
* @param array $paramArray Parameters to be replaced in key/value contents
|
||||
*/
|
||||
public function _buildObject($node, $paramArray = [])
|
||||
{
|
||||
$value = [];
|
||||
foreach ($node->getChildren() as $element) {
|
||||
$key = $element->getAttribute('key');
|
||||
$childArray = $element->getChildByName('array');
|
||||
if (isset($childArray)) {
|
||||
$content = $this->_buildObject($childArray, $paramArray);
|
||||
} else {
|
||||
$content = $this->_performReplacement($element->getValue(), $paramArray);
|
||||
}
|
||||
if (!empty($key)) {
|
||||
$key = $this->_performReplacement($key, $paramArray);
|
||||
$value[$key] = $content;
|
||||
} else {
|
||||
$value[] = $content;
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install plugin settings from an XML file.
|
||||
*
|
||||
* @param string $pluginName name of plugin for settings to apply to
|
||||
* @param string $filename Name of XML file to parse and install
|
||||
* @param array $paramArray Optional parameters for variable replacement in settings
|
||||
*/
|
||||
public function installSettings($contextId, $pluginName, $filename, $paramArray = [])
|
||||
{
|
||||
$xmlParser = new PKPXMLParser();
|
||||
$tree = $xmlParser->parse($filename);
|
||||
|
||||
if (!$tree) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for existing settings and leave them if they are already in place.
|
||||
$currentSettings = $this->getPluginSettings($contextId, $pluginName);
|
||||
|
||||
foreach ($tree->getChildren() as $setting) {
|
||||
$nameNode = $setting->getChildByName('name');
|
||||
$valueNode = $setting->getChildByName('value');
|
||||
|
||||
if (isset($nameNode) && isset($valueNode)) {
|
||||
$type = $setting->getAttribute('type');
|
||||
$name = $nameNode->getValue();
|
||||
|
||||
// If the setting already exists, respect it.
|
||||
if (isset($currentSettings[$name])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($type == 'object') {
|
||||
$arrayNode = $valueNode->getChildByName('array');
|
||||
$value = $this->_buildObject($arrayNode, $paramArray);
|
||||
} else {
|
||||
$value = $this->_performReplacement($valueNode->getValue(), $paramArray);
|
||||
}
|
||||
|
||||
// Replace translate calls with translated content
|
||||
$this->updateSetting($contextId, $pluginName, $name, $value, $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used internally by plugin setting installation code to perform translation
|
||||
* function.
|
||||
*
|
||||
* @param array $matches
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function _installer_plugin_regexp_callback($matches)
|
||||
{
|
||||
return __($matches[1]);
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\plugins\PluginSettingsDAO', '\PluginSettingsDAO');
|
||||
}
|
||||
Reference in New Issue
Block a user