2018-08-16 22:30:59 +00:00
|
|
|
<?php
|
2022-03-04 17:10:24 +00:00
|
|
|
|
2018-08-16 22:30:59 +00:00
|
|
|
/*
|
2024-01-13 20:03:36 +00:00
|
|
|
* Copyright (c) 2010-2024 Tim Düsterhus.
|
2018-08-16 22:30:59 +00:00
|
|
|
*
|
|
|
|
* Use of this software is governed by the Business Source License
|
|
|
|
* included in the LICENSE file.
|
|
|
|
*
|
2024-03-04 19:42:52 +00:00
|
|
|
* Change Date: 2028-03-14
|
2018-08-16 22:30:59 +00:00
|
|
|
*
|
|
|
|
* On the date above, in accordance with the Business Source
|
|
|
|
* License, use of this software will be governed by version 2
|
|
|
|
* or later of the General Public License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace wcf\system\package\plugin;
|
|
|
|
|
2022-03-04 17:10:24 +00:00
|
|
|
use chat\data\command\CommandEditor;
|
|
|
|
use chat\system\command\ICommand;
|
|
|
|
use wcf\system\devtools\pip\IIdempotentPackageInstallationPlugin;
|
|
|
|
use wcf\system\exception\SystemException;
|
|
|
|
use wcf\system\WCF;
|
2018-08-16 22:30:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Installs, updates and deletes chat commands.
|
|
|
|
*/
|
2022-03-04 17:10:24 +00:00
|
|
|
class ChatCommandPackageInstallationPlugin extends AbstractXMLPackageInstallationPlugin implements IIdempotentPackageInstallationPlugin
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
public $className = CommandEditor::class;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
public $application = 'chat';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removing this and relying on table name guessing breaks uninstallation
|
|
|
|
* as the application autoloader is unavailable there.
|
|
|
|
*
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
public $tableName = 'command';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
protected function handleDelete(array $items)
|
|
|
|
{
|
|
|
|
$sql = "DELETE FROM {$this->application}" . WCF_N . "_{$this->tableName}
|
|
|
|
WHERE packageID = ?
|
|
|
|
AND identifier = ?";
|
|
|
|
$statement = WCF::getDB()->prepare($sql);
|
|
|
|
|
|
|
|
WCF::getDB()->beginTransaction();
|
|
|
|
foreach ($items as $item) {
|
|
|
|
$statement->execute([
|
|
|
|
$this->installation->getPackageID(),
|
|
|
|
$item['attributes']['name'],
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
WCF::getDB()->commitTransaction();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
protected function getElement(\DOMXPath $xpath, array &$elements, \DOMElement $element)
|
|
|
|
{
|
|
|
|
$nodeValue = $element->nodeValue;
|
|
|
|
|
|
|
|
if ($element->tagName === 'triggers') {
|
|
|
|
$nodeValue = [ ];
|
|
|
|
$triggers = $xpath->query('child::*', $element);
|
|
|
|
|
|
|
|
foreach ($triggers as $trigger) {
|
|
|
|
$nodeValue[] = $trigger->nodeValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$elements[$element->tagName] = $nodeValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
protected function prepareImport(array $data)
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'identifier' => $data['attributes']['name'],
|
|
|
|
'className' => $data['elements']['classname'],
|
|
|
|
'triggers' => $data['elements']['triggers'] ?? [ ],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
protected function validateImport(array $data)
|
|
|
|
{
|
|
|
|
if ($data['identifier'] === '') {
|
|
|
|
throw new SystemException('Command identifier (name attribute) may not be empty');
|
|
|
|
}
|
|
|
|
if (!\class_exists($data['className'])) {
|
|
|
|
throw new SystemException("'" . $data['className'] . "' does not exist.");
|
|
|
|
}
|
|
|
|
if (!\wcf\util\ClassUtil::isInstanceOf($data['className'], ICommand::class)) {
|
|
|
|
throw new SystemException("'" . $data['className'] . "' does not implement '\\chat\\system\\command\\ICommand.'");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
protected function findExistingItem(array $data)
|
|
|
|
{
|
|
|
|
$sql = "SELECT *
|
|
|
|
FROM {$this->application}" . WCF_N . "_{$this->tableName}
|
|
|
|
WHERE packageID = ?
|
|
|
|
AND identifier = ?";
|
|
|
|
$parameters = [
|
|
|
|
$this->installation->getPackageID(),
|
|
|
|
$data['identifier'],
|
|
|
|
];
|
|
|
|
|
|
|
|
return [
|
|
|
|
'sql' => $sql,
|
|
|
|
'parameters' => $parameters,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
protected function import(array $row, array $data)
|
|
|
|
{
|
|
|
|
$triggers = $data['triggers'];
|
|
|
|
unset($data['triggers']);
|
|
|
|
|
|
|
|
$result = parent::import($row, $data);
|
|
|
|
|
|
|
|
if (empty($row)) {
|
|
|
|
// import initial triggers
|
|
|
|
$sql = "INSERT INTO {$this->application}" . WCF_N . "_command_trigger
|
|
|
|
(commandTrigger, commandID)
|
|
|
|
VALUES (?, ?)";
|
|
|
|
$statement = WCF::getDB()->prepare($sql);
|
|
|
|
|
|
|
|
try {
|
|
|
|
WCF::getDB()->beginTransaction();
|
|
|
|
|
|
|
|
foreach ($triggers as $trigger) {
|
|
|
|
try {
|
|
|
|
$statement->execute([
|
|
|
|
$trigger,
|
|
|
|
$result->commandID,
|
|
|
|
]);
|
|
|
|
} catch (\wcf\system\database\DatabaseException $e) {
|
|
|
|
// Duplicate key errors don't cause harm.
|
|
|
|
if ((string)$e->getCode() !== '23000') {
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WCF::getDB()->commitTransaction();
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
WCF::getDB()->rollBackTransaction();
|
|
|
|
throw $e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @inheritDoc
|
|
|
|
*/
|
|
|
|
public static function getSyncDependencies()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'file',
|
|
|
|
];
|
|
|
|
}
|
2018-08-16 22:30:59 +00:00
|
|
|
}
|