SoftDeleteableWalker.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. namespace Gedmo\SoftDeleteable\Query\TreeWalker;
  3. use Doctrine\ORM\Query\SqlWalker;
  4. use Doctrine\ORM\Query\AST\DeleteStatement;
  5. use Doctrine\ORM\Query\AST\DeleteClause;
  6. use Doctrine\ORM\Query\AST\UpdateClause;
  7. use Doctrine\ORM\Query\AST\UpdateItem;
  8. use Doctrine\ORM\Query\Exec\SingleTableDeleteUpdateExecutor;
  9. use Doctrine\ORM\Query\AST\PathExpression;
  10. use Gedmo\SoftDeleteable\SoftDeleteableListener;
  11. /**
  12. * Created by Gustavo Falco <comfortablynumb84@gmail.com>
  13. */
  14. class SoftDeleteableWalker extends SqlWalker
  15. {
  16. protected $conn;
  17. protected $platform;
  18. protected $listener;
  19. protected $alias;
  20. protected $deletedAtField;
  21. protected $meta;
  22. /**
  23. * {@inheritDoc}
  24. */
  25. public function __construct($query, $parserResult, array $queryComponents)
  26. {
  27. parent::__construct($query, $parserResult, $queryComponents);
  28. $this->conn = $this->getConnection();
  29. $this->platform = $this->conn->getDatabasePlatform();
  30. $this->listener = $this->getSoftDeleteableListener();
  31. $this->extractComponents($queryComponents);
  32. }
  33. /**
  34. * {@inheritDoc}
  35. */
  36. public function getExecutor($AST)
  37. {
  38. if (!$AST instanceof DeleteStatement) {
  39. throw new \Gedmo\Exception\UnexpectedValueException('SoftDeleteable walker should be used only on delete statement');
  40. }
  41. return parent::getExecutor($AST);
  42. }
  43. /**
  44. * Change a DELETE clause for an UPDATE clause
  45. *
  46. * @param DeleteClause
  47. * @return string The SQL.
  48. */
  49. public function walkDeleteClause(DeleteClause $deleteClause)
  50. {
  51. $em = $this->getEntityManager();
  52. $class = $em->getClassMetadata($deleteClause->abstractSchemaName);
  53. $tableName = $class->getTableName();
  54. $this->setSQLTableAlias($tableName, $tableName, $deleteClause->aliasIdentificationVariable);
  55. $quotedTableName = $class->getQuotedTableName($this->platform);
  56. $quotedColumnName = $class->getQuotedColumnName($this->deletedAtField, $this->platform);
  57. $sql = 'UPDATE '.$quotedTableName.' SET '.$quotedColumnName.' = "'.date('Y-m-d H:i:s').'"';
  58. return $sql;
  59. }
  60. /**
  61. * Get the currently used SoftDeleteableListener
  62. *
  63. * @throws \Gedmo\Exception\RuntimeException - if listener is not found
  64. * @return SoftDeleteableListener
  65. */
  66. private function getSoftDeleteableListener()
  67. {
  68. if (is_null($this->listener)) {
  69. $em = $this->getEntityManager();
  70. foreach ($em->getEventManager()->getListeners() as $event => $listeners) {
  71. foreach ($listeners as $hash => $listener) {
  72. if ($listener instanceof SoftDeleteableListener) {
  73. $this->listener = $listener;
  74. break;
  75. }
  76. }
  77. if ($this->listener) {
  78. break;
  79. }
  80. }
  81. if (is_null($this->listener)) {
  82. throw new \Gedmo\Exception\RuntimeException('The SoftDeleteable listener could not be found.');
  83. }
  84. }
  85. return $this->listener;
  86. }
  87. /**
  88. * Search for components in the delete clause
  89. *
  90. * @param array $queryComponents
  91. * @return void
  92. */
  93. private function extractComponents(array $queryComponents)
  94. {
  95. $em = $this->getEntityManager();
  96. foreach ($queryComponents as $alias => $comp) {
  97. if (!isset($comp['metadata'])) {
  98. continue;
  99. }
  100. $meta = $comp['metadata'];
  101. $config = $this->listener->getConfiguration($em, $meta->name);
  102. if ($config && isset($config['softDeleteable']) && $config['softDeleteable']) {
  103. $this->deletedAtField = $config['fieldName'];
  104. $this->meta = $meta;
  105. }
  106. }
  107. }
  108. }