Skip to content

Commit

Permalink
Merge pull request #42 from die-wegmeister/feature/remove-resources-o…
Browse files Browse the repository at this point in the history
…n-delete

feat: Add option to also delete attached resources on delete
  • Loading branch information
Benjamin-K authored Dec 3, 2024
2 parents eec0d76 + bfc1abe commit ef36288
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 62 deletions.
30 changes: 16 additions & 14 deletions Classes/Controller/DatabaseStorageController.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
use Neos\Flow\I18n\Translator;
use Neos\Flow\Mvc\Controller\ActionController;

use Wegmeister\DatabaseStorage\Domain\Model\DatabaseStorage;
use Wegmeister\DatabaseStorage\Domain\Repository\DatabaseStorageRepository;

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;

use Wegmeister\DatabaseStorage\Domain\Model\DatabaseStorage;
use Wegmeister\DatabaseStorage\Domain\Repository\DatabaseStorageRepository;
use Wegmeister\DatabaseStorage\Service\DatabaseStorageService;

/**
Expand Down Expand Up @@ -158,10 +158,12 @@ public function showAction(string $identifier)
*
* @return void
*/
public function deleteAction(DatabaseStorage $entry)
{
public function deleteAction(
DatabaseStorage $entry,
bool $removeAttachedResources = false
) {
$identifier = $entry->getStorageidentifier();
$this->databaseStorageRepository->remove($entry);
$this->databaseStorageRepository->remove($entry, $removeAttachedResources);
$this->addFlashMessage(
$this->translator->translateById(
'storage.flashmessage.entryRemoved',
Expand All @@ -180,16 +182,17 @@ public function deleteAction(DatabaseStorage $entry)
*
* @param string $identifier The storage identifier for the entries to be removed.
* @param bool $redirect Redirect to index?
* @param bool $removeAttachedResource Remove attached resources?
*
* @return void
*/
public function deleteAllAction(string $identifier, bool $redirect = false)
public function deleteAllAction(string $identifier, bool $redirect = false, bool $removeAttachedResources = false)
{
$count = 0;
foreach ($this->databaseStorageRepository->findByStorageidentifier($identifier) as $entry) {
$this->databaseStorageRepository->remove($entry);
$count++;
}
$count = $this->databaseStorageRepository->deleteByStorageIdentifierAndDateInterval(
$identifier,
null,
$removeAttachedResources
);

$this->view->assign('identifier', $identifier);
$this->view->assign('count', $count);
Expand Down Expand Up @@ -310,5 +313,4 @@ public function exportAction(string $identifier, string $writerType = 'Xlsx', bo
$writer->save('php://output');
exit;
}

}
50 changes: 32 additions & 18 deletions Classes/Domain/Repository/DatabaseStorageRepository.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Repository to load database storage entries.
*
Expand All @@ -17,6 +18,7 @@

use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityNotFoundException;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Persistence\Exception\IllegalObjectTypeException;
use Neos\Flow\Persistence\Exception\InvalidQueryException;
Expand Down Expand Up @@ -52,9 +54,9 @@ class DatabaseStorageRepository extends Repository
/**
* List of identifiers.
*
* @var array
* @var ?array
*/
protected $identifiers = [];
protected $identifiers = null;

/**
* @Flow\Inject
Expand All @@ -70,7 +72,7 @@ class DatabaseStorageRepository extends Repository
*/
public function findStorageidentifiers()
{
if ($this->identifiers === []) {
if ($this->identifiers === null) {
$this->identifiers = $this->getStorageIdentifiers();
}

Expand All @@ -87,8 +89,11 @@ public function findStorageidentifiers()
* @throws IllegalObjectTypeException
* @throws InvalidQueryException
*/
public function deleteByStorageIdentifierAndDateInterval(string $storageIdentifier, \DateInterval $dateInterval = null, $removeAttachedResource = false): int
{
public function deleteByStorageIdentifierAndDateInterval(
string $storageIdentifier,
\DateInterval $dateInterval = null,
$removeAttachedResources = false
): int {
$query = $this->createQuery();
$constraints = [
$query->equals('storageidentifier', $storageIdentifier)
Expand All @@ -104,37 +109,46 @@ public function deleteByStorageIdentifierAndDateInterval(string $storageIdentifi
$entries = $query->execute();
$count = 0;
foreach ($entries as $entry) {
if ($removeAttachedResource) {
$this->removeResourceFromEntry($entry);
}
$this->remove($entry);
$this->remove($entry, $removeAttachedResources);
$count++;
}

return $count;
}

/**
* Checks if the given storage entry has a property with a resource.
* If a resource property is found, the resource will be deleted.
* Removes an object from this repository.
*
* If $removeAttachedResources is true, checks if the given storage entry
* has a property with a resource. If a resource property is found,
* the resource will be deleted.
*
* @param DatabaseStorage $entry
* @param object $object The object to remove
* @param bool $removeAttachedResources Also remove all attached resources?
* @return void
* @throws IllegalObjectTypeException
* @api
*/
protected function removeResourceFromEntry(DatabaseStorage $entry): void
public function remove($entry, bool $removeAttachedResources = false): void
{
try {
if ($removeAttachedResources) {
foreach ($entry->getProperties() as $property) {
if (!$property instanceof PersistentResource) {
continue;
}

$this->resourceManager->deleteResource($property);
try {
$this->resourceManager->deleteResource($property);
} catch (EntityNotFoundException $exception) {
// Maybe the entry is already deleted and therefore not found.
// Therefore we will ignore this exception and continue
// with the next property.
continue;
}
}
} catch (\Doctrine\ORM\EntityNotFoundException $exception) {
// Maybe the entry is already deleted and therefore not found
return;
}

parent::remove($entry);
}

/**
Expand Down
16 changes: 3 additions & 13 deletions Resources/Private/Layouts/Default.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><f:render section="Title" /></title>
<f:flashMessages class="flashmessages" />

</head>
<body>
<f:flashMessages class="flashmessages" />

<h1><f:render section="Title" /></h1>
<f:render section="Content" />
</body>
</html>
<f:render section="Title" />
<f:render section="Content" />
5 changes: 4 additions & 1 deletion Resources/Private/Templates/DatabaseStorage/DeleteAll.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{namespace neos=Neos\Neos\ViewHelpers}
<f:layout name="Default" />

<f:section name="title">{neos:backend.translate(id: 'storage.databaseStorage')} - {neos:backend.translate(id: 'storage.deleteAll.deleteEntries')}</f:section>
<f:section name="title"><h1>{neos:backend.translate(id: 'storage.databaseStorage')} - {neos:backend.translate(id: 'storage.deleteAll.deleteEntries')}</h1></f:section>

<f:section name="content">
<style>
.neos h1 {font-size: 150%; margin: 1em 0;}
</style>
<section>
<h3>{neos:backend.translate(id: 'storage.deleteAll.successTitle')}</h3>
<p>{neos:backend.translate(id: 'storage.deleteAll.successTitle', arguments: {0: count, 1: identifier})}</p>
Expand Down
34 changes: 28 additions & 6 deletions Resources/Private/Templates/DatabaseStorage/Index.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
{namespace neos=Neos\Neos\ViewHelpers}
<f:layout name="Default" />

<f:section name="Title">{neos:backend.translate(id: 'storage.databaseStorage')}</f:section>
<f:section name="Title"><h1>{neos:backend.translate(id: 'storage.databaseStorage')}</h1></f:section>

<f:section name="Content">
<style>
.neos h1 {font-size: 150%; margin: 1em 0;}
.size-sm {width: 150px;}
.neos .buttons {
display: flex;
align-items: flex-start;
gap: 8px;
margin-top: 1em;
}
.buttons .neos-button {
height: auto;
line-height: 1.2;
margin-left: 0!important;
padding: 0.8em 1em;
}
</style>

<div class="neos-row-fluid">
Expand Down Expand Up @@ -71,12 +84,21 @@
</div>
</div>
<div class="neos-modal-footer">
<a href="#" class="neos-button" data-dismiss="modal">{neos:backend.translate(id: 'cancel', value: 'Cancel', package: 'Neos.Neos')}</a>
<f:form action="deleteAll" arguments="{identifier: identifier}" class="neos-inline">
<f:form action="deleteAll" arguments="{identifier: identifier}">
<f:form.hidden name="redirect" value="1" />
<button type="submit" class="neos-button neos-button-danger" title="{neos:backend.translate(id: 'storage.deleteModal.buttonTitle')}">
{neos:backend.translate(id: 'storage.deleteModal.buttonText', arguments: {0: identifier})}
</button>
<div>
<label class="neos-checkbox">
<f:form.checkbox name="removeAttachedResources" value="1" />
<span></span>
{neos:backend.translate(id: 'storage.deleteModal.removeAttachedResources')}
</label>
</div>
<div class="buttons">
<a href="#" class="neos-button" data-dismiss="modal">{neos:backend.translate(id: 'cancel', value: 'Cancel', package: 'Neos.Neos')}</a>
<button type="submit" class="neos-button neos-button-danger" title="{neos:backend.translate(id: 'storage.deleteModal.buttonTitle')}">
{neos:backend.translate(id: 'storage.deleteModal.buttonText', arguments: {0: identifier})}
</button>
</div>
</f:form>
</div>
</div>
Expand Down
40 changes: 30 additions & 10 deletions Resources/Private/Templates/DatabaseStorage/Show.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,32 @@

<f:section name="Title">
<p><f:link.action action="index" class="neos-button">{neos:backend.translate(id: 'storage.backToIdentifiers')}</f:link.action></p>
<div class="neos-row-fluid">
<legend>
{neos:backend.translate(id: 'storage.databaseStorage')} - [{f:if(condition: '{entries -> f:count()} > 0', then: '{entries -> f:count()}')}] {neos:backend.translate(id: 'storage.entriesForX', arguments: {0: identifier})}
</legend>
</div>
<h1>
{neos:backend.translate(id: 'storage.databaseStorage')} - [{f:if(condition: '{entries -> f:count()} > 0', then: '{entries -> f:count()}')}] {neos:backend.translate(id: 'storage.entriesForX', arguments: {0: identifier})}
</h1>
</f:section>

<f:section name="Content">
<style>
.neos h1 {font-size: 150%; margin: 1em 0;}
.scrollable-table {overflow-x: auto; width: 100%;}
.scrollable-table .neos-table {min-width: 100%; max-width: none;}
.size-sm {width: 50px;}
.neos.neos-module table.neos-table td,
.neos.neos-module table.neos-table th {line-height: 24px; padding: 8px 16px;}
.neos.neos-module table td a {text-decoration: underline;}
.neos .buttons {
display: flex;
align-items: flex-start;
gap: 8px;
margin-top: 1em;
}
.buttons .neos-button {
height: auto;
line-height: 1.2;
margin-left: 0!important;
padding: 0.8em 1em;
}
</style>

<div class="neos-row-fluid">
Expand Down Expand Up @@ -55,11 +66,20 @@
</div>
</div>
<div class="neos-modal-footer">
<a href="#" class="neos-button" data-dismiss="modal">{neos:backend.translate(id: 'cancel', value: 'Cancel', package: 'Neos.Neos')}</a>
<f:form action="delete" object="{entry}" objectName="entry" class="neos-inline">
<button type="submit" class="neos-button neos-button-danger" title="{neos:backend.translate(id: 'storage.deleteSingleModal.buttonTitle')}">
{neos:backend.translate(id: 'storage.deleteSingleModal.buttonTitle')}
</button>
<f:form action="delete" object="{entry}" objectName="entry">
<div>
<label class="neos-checkbox">
<f:form.checkbox name="removeAttachedResources" value="1" />
<span></span>
{neos:backend.translate(id: 'storage.deleteModal.removeAttachedResources')}
</label>
</div>
<div class="buttons">
<a href="#" class="neos-button" data-dismiss="modal">{neos:backend.translate(id: 'cancel', value: 'Cancel', package: 'Neos.Neos')}</a>
<button type="submit" class="neos-button neos-button-danger" title="{neos:backend.translate(id: 'storage.deleteSingleModal.buttonTitle')}">
{neos:backend.translate(id: 'storage.deleteSingleModal.buttonTitle')}
</button>
</div>
</f:form>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions Resources/Private/Translations/de/Main.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
<source>This will delete all entries for identifier "{0}" and cannot be undone. Your data will be gone!</source>
<target>Hierdurch werden alle Einträge der ID "{0}" entgültig gelöscht. Dieser Vorgang kann nicht rückgangig gemacht werden.</target>
</trans-unit>
<trans-unit id="storage.deleteModal.removeAttachedResources" xml:space="preserve">
<source>Remove attached resources</source>
<target>Zugehörige Dateien löschen</target>
</trans-unit>
<trans-unit id="storage.deleteModal.buttonTitle" xml:space="preserve">
<source>Delete entries</source>
<target>Einträge löschen</target>
Expand Down
3 changes: 3 additions & 0 deletions Resources/Private/Translations/en/Main.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
<trans-unit id="storage.deleteModal.text" xml:space="preserve">
<source>This will delete all entries for identifier "{0}" and cannot be undone. Your data will be gone!</source>
</trans-unit>
<trans-unit id="storage.deleteModal.removeAttachedResources" xml:space="preserve">
<source>Remove attached resources</source>
</trans-unit>
<trans-unit id="storage.deleteModal.buttonTitle" xml:space="preserve">
<source>Delete entries</source>
</trans-unit>
Expand Down

0 comments on commit ef36288

Please sign in to comment.