Remove Related Objects MIGXdb CMP

Hi All

Have slight issue related to a custom db i have created, i have a one to many relationship set up using migxdb and everything is working fine.

So i have my CMP, i have both tables hooked up together in a relationship so that if i call the object->remove() in a snippet for that package it removes the primary entry and all of its related items in the related table.

the issue i have is that i want to replicate this functionality in the MIGXdb CMP so then if i mark something for deletion and then “empty trash” it will then remove those entries and the related objects in its related table. Is there some “hook” or block of code i can put somewhere in the migx config setup to trigger on empty trash to trigger the related items to be removed also as per the schema.

many thanks in advance

    <object class="Assessments" table="assessments" extends="xPDOSimpleObject">
    <field key="user_id" dbtype="int" phptype="integer" precision="10" null="false" default="" />
    <field key="lifestyle" dbtype="decimal" precision="7,3" phptype="float" null="false" default="0" />
    <field key="body" dbtype="decimal" precision="7,3" phptype="float" null="false" default="0" />
    <field key="mind" dbtype="decimal" precision="7,3" phptype="float" null="false" default="0" />
    <field key="about" dbtype="decimal" precision="7,3" phptype="float" null="false" default="0" />
    <field key="status" dbtype="int" phptype="integer" precision="10" null="false" default="0" />
    <field key="deleted" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
    <composite alias="answers" class="AssessAnswers" local="id" foreign="assessment_id" cardinality="many" owner="local" />
</object>

<object class="AssessAnswers" table="assessmentAnswers" extends="xPDOSimpleObject">
    <field key="assessment_id" dbtype="int" phptype="integer" precision="10" null="false" default="" />
    <field key="question_id" dbtype="int" phptype="integer" precision="10" null="false" default="" />
    <field key="answer_id" dbtype="varchar" precision="128" phptype="string" null="false" default="0" />
    <field key="answer" dbtype="varchar" precision="256" phptype="string" null="false" default="0" />
    <field key="deleted" dbtype="tinyint" precision="1" attributes="unsigned" phptype="integer" null="false" default="0" />
    <aggregate alias="assessment" class="Assessments" local="assessment_id" foreign="id" cardinality="one" owner="foreign" />
</object>

Schema is above if that helps but i know the schema is working due to the functionality of remove objects from a snippet working as expected

seems, it wasn’t a good idea to use xpdo-exec here


and needs to be fixed
you could use a custom default/emptytrash - processor in your own package for now, where you iterate over a collection, filterd by deleted items and use object->remove in the loop

Hi Bruno

Thanks for the super prompt reply, how would i go about doing that, i have created a package already for my project. Are you saying that i should replicate the structure used in the migx package such as mypackage/processor/mgr/default/emptytrash.php in my own package?

How would i then get my custom emptytrash to be read by my migx CMP when someone presses the empty trash button? Does this happen automatically because i have the right structure?

Also, would i use something in my own custom emptytrash similar to how you are clearing the cache in the default?

$assessment = $modx->getCollection('mypackageclassname' array('deleted' => 1));
foreach ($assessment as $item) {
    $item->remove();
}

Sorry if this seems painfully obvious but i’m struggling to find documentation on this in particular

many thanks again.

1 Like

yeah, just create that one custom processor at
mypackage/processors/mgr/default/emptytrash.php

and migx should call that one automatically instead of the
migx/processors/mgr/default/emptytrash.php - processor

and just replace

$xpdo->exec("delete from {$tablename} where deleted = 1");

with

$c = $xpdo->newQuery($classname);
$c->where(array('deleted' => 1));
$collection = $xpdo->getCollection($classname, $c);
foreach ($collection as $object) {
    $object->remove();
}
1 Like

Awesome! i will give that ago at some point and edit this post with my result :slight_smile:

1 Like

Hi again

Just got round to looking at this again, and I’m not sure if i want to go the route of creating another emptytrash for my package.

Reason being is that i have multiple related tables in this package and when i empty the trash of some of them i don’t want it to delete the related objects for those particular tables (even though they are related in my schema).

Is there an alternative way of triggering the same functionality but only for the migxdb config i want it to work on.

I saw that in my migx config is a section for extra handlers and specifically emptyTrash

image

Also i saw the section within my migxdb settings for hook snippets.

Can i create an emptyTrash hook snippet as below

{"emptyTrash ":"myemptyTrash _snippet"}

That has the same functionality you mentioned above but this way it only triggers my extra code for this classkey as apposed to the alternative that would trigger across my entire package of related tables whenever i emptied that trash for one of those tables?

Hope all of this makes sense? .

if you create your own processor, you could check for the configs or the classname, before running the process

and only related composites are removed, not aggregates

Perfect, yep i could make that work. Just tried the following and i think its doing the job

if ($classname == "myclasskey"){
    $c = $xpdo->newQuery($classname);
    $c->where(array('deleted' => 1));
    $collection = $xpdo->getCollection($classname, $c);
    foreach ($collection as $object) {
        $object->remove();
    }  
}
else {
  $xpdo->exec("delete from {$tablename} where deleted = 1");  
}
1 Like