Spaces:
No application file
No application file
File size: 5,045 Bytes
d2897cd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
<?php
namespace Mautic\PluginBundle\Bundle;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\ORM\Tools\SchemaTool;
use Mautic\CoreBundle\Factory\MauticFactory;
use Mautic\PluginBundle\Entity\Plugin;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* Base Bundle class which should be extended by addon bundles.
*/
abstract class PluginBundleBase extends Bundle
{
/**
* @throws \Exception
*
* @deprecated To be removed in 5.0. Listen to PluginEvents::ON_PLUGIN_INSTALL instead
*/
public static function onPluginInstall(Plugin $plugin, MauticFactory $factory, $metadata = null, $installedSchema = null): void
{
if (null !== $metadata) {
self::installPluginSchema($metadata, $factory, $installedSchema);
}
}
/**
* Install plugin schema based on Doctrine metadata.
*
* @throws \Exception
*/
public static function installPluginSchema(array $metadata, MauticFactory $factory, $installedSchema = null): void
{
if (null !== $installedSchema) {
// Schema already exists, so no need to proceed
return;
}
$db = $factory->getDatabase();
$schemaTool = new SchemaTool($factory->getEntityManager());
$installQueries = $schemaTool->getCreateSchemaSql($metadata);
foreach ($installQueries as $q) {
// Check if the query is a DDL statement
if (self::isDDLStatement($q)) {
// Execute DDL statements outside of a transaction
$db->executeQuery($q);
} else {
// For non-DDL statements, use transactions
try {
$db->beginTransaction();
$db->executeQuery($q);
$db->commit();
} catch (\Exception $e) {
// Rollback only for non-DDL statements
if ($db->isTransactionActive()) {
$db->rollBack();
}
throw $e;
}
}
}
}
private static function isDDLStatement(string $query): bool|int
{
return preg_match('/^(CREATE|ALTER|DROP|RENAME|TRUNCATE|COMMENT)\s/i', $query);
}
/**
* Called by PluginController::reloadAction when the addon version does not match what's installed.
*
* @throws \Exception
*
* @deprecated To be removed in 5.0. Listen to PluginEvents::ON_PLUGIN_UPDATE instead
*/
public static function onPluginUpdate(
Plugin $plugin,
MauticFactory $factory,
$metadata = null,
Schema $installedSchema = null
): void {
// Not recommended although availalbe for simple schema changes - see updatePluginSchema docblock
// self::updatePluginSchema($metadata, $installedSchema, $factory);
}
/**
* Update plugin schema based on Doctrine metadata.
*
* WARNING - this is not recommended as Doctrine does not guarantee results. There is a risk
* that Doctrine will generate an incorrect query leading to lost data. If using this method,
* be sure to thoroughly test the queries Doctrine generates
*
* @throws \Doctrine\DBAL\ConnectionException
* @throws \Exception
*/
public static function updatePluginSchema(array $metadata, Schema $installedSchema, MauticFactory $factory): void
{
$db = $factory->getDatabase();
$schemaTool = new SchemaTool($factory->getEntityManager());
$toSchema = $schemaTool->getSchemaFromMetadata($metadata);
$comparator = (new Comparator())->compareSchemas($installedSchema, $toSchema);
$databasePlatform = $db->getDatabasePlatform();
$queries = $databasePlatform->getAlterSchemaSQL($comparator);
$db->beginTransaction();
try {
foreach ($queries as $q) {
$db->executeQuery($q);
}
$db->commit();
} catch (\Exception $e) {
$db->rollback();
throw $e;
}
}
/**
* Not used yet :-).
*/
public static function onPluginUninstall(Plugin $plugin, MauticFactory $factory, $metadata = null): void
{
}
/**
* Drops plugin's tables based on Doctrine metadata.
*
* @throws \Doctrine\DBAL\ConnectionException
* @throws \Exception
*/
public static function dropPluginSchema(array $metadata, MauticFactory $factory): void
{
$db = $factory->getDatabase();
$schemaTool = new SchemaTool($factory->getEntityManager());
$dropQueries = $schemaTool->getDropSchemaSQL($metadata);
$db->beginTransaction();
try {
foreach ($dropQueries as $q) {
$db->executeQuery($q);
}
$db->commit();
} catch (\Exception $e) {
$db->rollback();
throw $e;
}
}
}
|