I have a Custom Element where the Soft Delete functionality is not necessary. Right now, existing users of this plugin may have thousands of Soft Deleted Elements in their Elements table that don't need to be there.

I am writing a migration that removes those, and, making some other updates so that when they get deleted in the first place, they get hard deleted.

Where I'm not clear on what the appropriate path forward is how to delete the existing Soft Deleted Elements. As far as I can tell, running the Garbage Cleanup hardDelete method is not really the right way to do this as I can't target a specific Custom Element of my choosing - it's all or nothing. I don't want to delete Soft Deletes that may be important for users, I just want to delete the ones in our plugin.

Next,it seems I can't use deleteElementById as it doesn't give me a way to indicate I want to Hard Delete, so I need to use the deleteElement method called by the deleteElementById method and recreate any code necessary to convert the ID into an actual Element class that I can pass to the deleteElement method. Something like:

foreach ($results as $key => $elementInfo) {
    $element = Craft::$app->elements->getElementById($elementInfo['elementId'], MyCustomElement::class, $elementInfo['siteId']);

    if ($element && !Craft::$app->elements->deleteElement($element, true)) {
       // Fail

   // Success

However, this doesn't appear to work either because getElementById returns null, I expect because it's excluding Soft Deleted items from what it's retrieving.

1 Answer 1


I figured this while posting so I thought I'd just add it here anyway for others to reference.

To retrieve a Soft Deleted Element using the getElementById method you can pass the fourth argument to the getElementById method and define $criteria setting trashed to true, which will include Soft Deleted items in your results:

$element = Craft::$app->elements->getElementById($elementInfo['elementId'], MyCustomElement::class, $elementInfo['siteId'], [
    'trashed' => true

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.