Automatically publish or unplublish parent based on children

I have a about a hundred folders that may or may not have child documents. Many of the child documents will have unpublish dates set for many of them. They expire after a set date.

I want the parent to be published if there is a published child
or
if there are no children or if all the children are unpublished, I want the parent to be unpublished.

Simply put, the parent documents content is based on the child documents. So I want to show the parents only if there’s something to see.

Right now I have to do this manually. Can this be automated so when children are added the parent is automatically published and when all the children expire, the parent is automatically unpublished?

If not automatic, I would be happy to have a button to push to do this on demand.

I’m thinking this might require a custom plugin or something (which is not in my skill set).

Any ideas?

It can definitely be automated with a custom plugin connected to OnDocPublished and OnDocUnpublished. Something like this ( off the top of my head and untested):

switch ($modx->event->name) {
    
    case 'OnDocPublished':
        /* Child is being published, make sure parent 
           (if there is one) is published */

        $parentId = $resource->get('parent');

        if ($parentId) { /* not at root -- get parent object */
            $parentObject = $modx->getObject('modResource', 
                $parentId);
        }
        /* If parent is not published, publish it */
        if ($parentObject && (! $parentObject->get('published'))) {
            $parentObject->set('published', '1');
            $parentObject->save();
        }
        break;

    case 'OnDocUnpublished':
        $parentId = $resource->get('parent');
        
        if ($parentId) { 
            /* not at root -- Get count of parent's 
               published children, if any */
            $criteria = array(
                    'parent' => $parentId,
                    'published' => '1',
            );
            $count = $modx->getCount('modResource', 
                $criteria);

            if ((int)$count === 0) {
                /* No published children - unpublish parent if published */
                $parentObject = $modx->getObject('modResource',
                     $parentId);
                if ($parentObject && ($parentObject->get('published'))) {
                    $parentObject->set('published', '0');
                    $parentObject->save();
                }
            }
        }
        break;    
}

There are multiple ways a doc gets published or unpublished, e.g., autopublish and unpublish based on the pub dates, right clicking in the tree, or saving from the Create/Edit Resource panel.

In the old days (about 10 years ago), the events in the plugin did not fire in all cases when resources were published or unpublished. If that’s still true (it may not be), you’d have to add a connection to OnDocFormSave and a section of the code to compare the published field of the Resource with its value in the DB and respond appropriately if it has changed. Hopefully, that’s no longer necessary.

1 Like

Unfortunately, this is still the case.
The events OnDocPublished and OnDocUnPublished are only invoked, if the resource is published/unpublished via the context menu in the resource tree.

You’ll need to handle the event OnResourceAutoPublish in your plugin for that.

1 Like

Bob Thank you!

I created the plugin and checked the boxes for OnDocPublished, OnDocUnpublished and OnResourceAutoPublish

I created a test page under an unpublished parent and saved it. I then right clicked on the test page to publish the child and the parent document changed to published.

However, it doesn’t seem to work the other direction. If I unpublish the child either via right click, editing the document or setting an unpublished date and time a few minutes out, the child is unpublished, but not the parent.

Terry, it should be ‘unDocUnPublished’ (capital ‘P’). Changing that may make it work from the tree context menu.

It still may not work when triggered by the pub and unpub dates.
I just looked and while there is an OnResourceAutoPublish event there is no OnResourceAutoUnPublish event, which seems nuts to me.

For that matter, why doesn’t the auto pub and unpub process just call the publish and unpublish processors???

This event handles both cases and works different than OnDocPublished and OnDocUnPublished. The information which resources where published/unpublished is in the variable $results ($results['published_resources'], results['unpublished_resources']).

case 'OnResourceAutoPublish':
        $ids = array();
        foreach($results['unpublished_resources'] as $res){
            $ids[] = $res['id'];
        }        
        //query the parent ids of these resources
		if (count($ids) > 0){
			$c = $modx->newQuery('modResource');
			$c->where(array('id:IN' => $ids));
			$c->select('parent');
			$c->distinct();
			$c->prepare();      
			$c->stmt->execute();
			$parent_ids = $c->stmt->fetchAll(PDO::FETCH_COLUMN, 0);

			//handle all parent ids in the array $parent_ids similar to the 'OnDocUnPublished' case
			...
		}

Bob
2022-03-10_17-16-43

This is what I’ve checked.

halftrainedharry

I’m not sure what to do with your code. Is this instead of Bob’s code or just part of it? (sorry this stuff is a bit beyond me)

Guys

While I really appreciate your help on this, I don’t want you to spend a lot of time on this. It’s really just a “nice to have” function.

But I did come up with another solution. I’m sure it’s not very efficient, but this is a pretty low volume page/site.

I used get resources to count the number of published children in each folder and used that to add a class to each item. If the class is qty0, then the css will hide it. So it won’t display any parents with no published children.

Then I used a snippet from an old Mark Hamstra blog to check for a manager login. It adds some css to show the admin the parents with no published children.

I can also show the admin other info, a sort of diagnostic, that will help locate folders that need cleanup for old, unpublished documents.

I know it’s a bit kludgy, but it gets the job done.

Again, I appreciate all help.