<p>You can use the <code>onBeforeDeleteEntry</code> event in an 'init' method  defined in your plugin's main file to: intercept the delete process; retrieve the related books; check each book for more than one author; and if only one author, delete the book. </p>

<p>Not tested.</p>

<pre><code>public function init()
{
    parent::init();

    craft()-&gt;on('entries.onBeforeDeleteEntry', function(Event $event)
    {
        $entry = $event-&gt;params['entry'];
        $section = $entry-&gt;getSection()-&gt;handle;

        if ($section == 'myAuthorsSectionHandle') {

            // get related book entries
            $criteria = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
            $criteria-&gt;section   = 'myBooksSectionHandle';
            $criteria-&gt;relatedTo = array(
                'targetElement' =&gt; $entry,
                'field'         =&gt; 'myBooksSectionRelatedAuthorsFieldHandle'
            );
            $books = $criteria-&gt;find();

            foreach ($books as $book) {
                $authors = $book-&gt;myBooksSectionRelatedAuthorsFieldHandle;
                if (count($authors) == 1) {
                    // delete the book entry
                    craft()-&gt;entries-&gt;deleteEntry([$book]);
                } else if (count($authors) &gt; 1) {
                    // decide what you want to do when more than one author found.
                    // use `$event-&gt;performAction = false;` to cancel the original delete operation if you need to
                } else {
                    throw new Exception('No authors found. This is impossible, my code must have an error somewhere.');
                }
            }

        }
    });

}
</code></pre>

<p><strong>Update</strong> It appears as though the <code>onBeforeDeleteEntry</code> event does not get raised when deleting multiple entries from the entry index page (as I would think it should), presumably because it is using elements->deleteElementById() to do so, thus bypassing the EntriesService event. In any rate, you might try the following instead.</p>

<pre><code>craft()-&gt;on('elements.onBeforeDeleteElements', function(Event $event)
{
    $elementIds = $event-&gt;params['elementIds'];

    foreach ($elementIds as $elementId) {
        $element = craft()-&gt;elements-&gt;getElementById($elementId);
        if ($element-&gt;getElementType() == 'Entry') {
            $entry = $element;
            $section = $entry-&gt;getSection()-&gt;handle;
            if ($section == 'myAuthorsSectionHandle') {
               // rest of the code as above
            }
        }
    }
</code></pre>

CC BY-SA 3.0
2015-02-12T22:45:11.790Z
"Someone please check..." done! ;)
carlcs
CC BY-SA 3.0
2015-02-12T22:52:54.250Z
OK, so I think I had to make a couple of syntax amendments - semicolons at the end of $criteria->section   = 'books'; & $criteria->section   = 'authors';
Dr_Codswallop
CC BY-SA 3.0
2015-02-12T23:17:02.657Z
Maybe I'm doing something wrong here, but it's not working. Installed the BusinessLogic plugin, added the code into the BusinessLogicPlugin.php file. I changed a couple of parameters in the code to fit my handles - namely after the $criteria-section-> (I have 'clients' rather than 'authors' and 'books'), and also the 'field' (should this be the handle of the Author field? If so i set that to 'bookAuthor'). However when I delete a client(author) their books still remain.
Dr_Codswallop
CC BY-SA 3.0
2015-02-12T23:30:44.530Z
Good catch on the missing ';'. I fixed those. I also clarified what those strings should be in the code. See if that helps.
Douglas McDonald
CC BY-SA 3.0
2015-02-13T14:58:05.687Z
I think we're making progress thanks to @Douglas (and learning along the way!). I had to make some edits `craft()->on('**entries**.onBeforeDeleteEntry', function(Event $event)`. And then `$section = $entry->getSection()->handle` (don't know if this is correct procedure but it works. `$section = $entry->section->classHandle` was just throwing out 'Section'). The only issue I have is that this only seems to work if deleting directly from the Entry>Client>JoeBlogs form. How can I make this fire from the Entries dashboard, in order that I can be able to delete multiple Clients (and their books)?
Dr_Codswallop
CC BY-SA 3.0
2015-02-13T15:24:16.053Z
Ugh... sorry about the errors. That's too many. Good job tracking those down. This should be firing from the index page as well. If it's not that sounds like a bug that craft should be made aware of. I suspect that perhaps they are deleting using `craft()->on('elements.onBeforeDeleteElements'...` which may be inadvertently bypassing the onDeleteEntry (but shouldn't).
Douglas McDonald
CC BY-SA 3.0
2015-02-12T22:06:33.343Z
Someone please check that I got the 'targetElement' and 'field' defined correctly. I always get confused.
Douglas McDonald
CC BY-SA 3.0
2015-02-12T22:31:19.233Z
This looks great Douglas. I kinda follow it but I've never written a plugin for Craft, I wouldn't know where to start. In fact this is my first project using it.
Dr_Codswallop
CC BY-SA 3.0
2015-02-12T22:34:08.673Z
It's really easy. I would recommend starting with the [BusinessLogic Template](https://github.com/lindseydiloreto/craft-businesslogic/) plugin. Just download that and install it (place in plugins folder, goto settings, install, and activate). Then open up the main businessLogic.php file and paste in the method above. That should do it. Of course, might need to debug what I wrote. If you see an error, let me know and I'll try and fix it.
Douglas McDonald
CC BY-SA 3.0
2015-02-12T22:01:11.747Z
2015-02-13T18:47:26.103Z
2015-02-13T18:47:26.103Z
Douglas McDonald
<p>Is there a method / plugin which allows a cascading deletion?</p>

<p>I'm working on an author agency site and have set up 2 channels, Authors and Books. The Book entry section has a Field set to Entries which allows me to specify the  Author/s from the Author Channel.</p>

<p>What I want to happen is, when an Author is deleted from the system so are all their books (unless the books has more than 1 author).</p>

CC BY-SA 3.0
2015-02-12T21:31:43.390Z
I asked a [very similar question](http://craftcms.stackexchange.com/questions/6869/plugin-to-maintain-data-integrity-between-related-entries) with some possible approaches.
Douglas McDonald
<relations><deletion>
Cascading deletion
# Cascading deletion

(Asked by: username_0 on 2015-02-12)

Is there a method / plugin which allows a cascading deletion?

I'm working on an author agency site and have set up 2 channels, Authors and Books. The Book entry section has a Field set to Entries which allows me to specify the Author/s from the Author Channel.

What I want to happen is, when an Author is deleted from the system so are all their books (unless the books has more than 1 author).

**Tags:** relations, deletion
> **Comments:**
> **username_1**: I asked a [very similar question](http://craftcms.stackexchange.com/questions/6869/plugin-to-maintain-data-integrity-between-related-entries) with some possible approaches.  

---

## 1 answers

### Answer by username_1 on 2015-02-12. Score: 3

You can use the onBeforeDeleteEntry event in an 'init' method  defined in your plugin's main file to: intercept the delete process; retrieve the related books; check each book for more than one author; and if only one author, delete the book. 
Not tested.
public function init()
{
    parent::init();

    craft()->on('entries.onBeforeDeleteEntry', function(Event $event)
    {
        $entry = $event->params['entry'];
        $section = $entry->getSection()->handle;

        if ($section == 'myAuthorsSectionHandle') {

            // get related book entries
            $criteria = craft()->elements->getCriteria(ElementType::Entry);
            $criteria->section   = 'myBooksSectionHandle';
            $criteria->relatedTo = array(
                'targetElement' => $entry,
                'field'         => 'myBooksSectionRelatedAuthorsFieldHandle'
            );
            $books = $criteria->find();

            foreach ($books as $book) {
                $authors = $book->myBooksSectionRelatedAuthorsFieldHandle;
                if (count($authors) == 1) {
                    // delete the book entry
                    craft()->entries->deleteEntry([$book]);
                } else if (count($authors) > 1) {
                    // decide what you want to do when more than one author found.
                    // use `$event->performAction = false;` to cancel the original delete operation if you need to
                } else {
                    throw new Exception('No authors found. This is impossible, my code must have an error somewhere.');
                }
            }

        }
    });

}

Update It appears as though the onBeforeDeleteEntry event does not get raised when deleting multiple entries from the entry index page (as I would think it should), presumably because it is using elements->deleteElementById() to do so, thus bypassing the EntriesService event. In any rate, you might try the following instead.
craft()->on('elements.onBeforeDeleteElements', function(Event $event)
{
    $elementIds = $event->params['elementIds'];

    foreach ($elementIds as $elementId) {
        $element = craft()->elements->getElementById($elementId);
        if ($element->getElementType() == 'Entry') {
            $entry = $element;
            $section = $entry->getSection()->handle;
            if ($section == 'myAuthorsSectionHandle') {
               // rest of the code as above
            }
        }
    }

> **Comments:**
> **username_1**: Someone please check that I got the 'targetElement' and 'field' defined correctly. I always get confused.  
> **username_0**: This looks great Douglas. I kinda follow it but I've never written a plugin for Craft, I wouldn't know where to start. In fact this is my first project using it.  
> **username_1**: It's really easy. I would recommend starting with the [BusinessLogic Template](https://github.com/lindseydiloreto/craft-businesslogic/) plugin. Just download that and install it (place in plugins folder, goto settings, install, and activate). Then open up the main businessLogic.php file and paste in the method above. That should do it. Of course, might need to debug what I wrote. If you see an error, let me know and I'll try and fix it.  
> **username_2**: "Someone please check..." done! ;)  
> **username_0**: OK, so I think I had to make a couple of syntax amendments - semicolons at the end of $criteria->section   = 'books'; & $criteria->section   = 'authors';  
> **username_0**: Maybe I'm doing something wrong here, but it's not working. Installed the BusinessLogic plugin, added the code into the BusinessLogicPlugin.php file. I changed a couple of parameters in the code to fit my handles - namely after the $criteria-section-> (I have 'clients' rather than 'authors' and 'books'), and also the 'field' (should this be the handle of the Author field? If so i set that to 'bookAuthor'). However when I delete a client(author) their books still remain.  
> **username_1**: Good catch on the missing ';'. I fixed those. I also clarified what those strings should be in the code. See if that helps.  
> **username_0**: I think we're making progress thanks to @Douglas (and learning along the way!). I had to make some edits `craft()->on('**entries**.onBeforeDeleteEntry', function(Event $event)`. And then `$section = $entry->getSection()->handle` (don't know if this is correct procedure but it works. `$section = $entry->section->classHandle` was just throwing out 'Section'). The only issue I have is that this only seems to work if deleting directly from the Entry>Client>JoeBlogs form. How can I make this fire from the Entries dashboard, in order that I can be able to delete multiple Clients (and their books)?  
> **username_1**: Ugh... sorry about the errors. That's too many. Good job tracking those down. This should be firing from the index page as well. If it's not that sounds like a bug that craft should be made aware of. I suspect that perhaps they are deleting using `craft()->on('elements.onBeforeDeleteElements'...` which may be inadvertently bypassing the onDeleteEntry (but shouldn't).  

---

