Download & Extend

Best way to delete messages via php?

Project:Privatemsg
Version:6.x-1.x-dev
Component:Code
Category:support request
Priority:normal
Assigned:Unassigned
Status:closed (fixed)

Issue Summary

We have a module that sends Private Messages to users when certain flags are set on content. These come from a dummy account. The problem is that these messages can really fill up this account's messaging outbox in a hurry. So we're thinking we should just automatically delete any messages that have been sent by that dummy user every 24 hours or so.

What's the best way to safely delete all of the messages for one user via the messaging api? I'm not seeing anything obvious in messaging.module. We're thinking of calling a function that does either via cron or more likely with a custom PHP call in Rules.

Comments

#1

Project:Messaging» Privatemsg
Version:6.x-2.1»

I think this is better for Privatemsg module

#2

you can set the deleted flag to 1 in pm_index through some custom cron run if required, but actual deleting of the message will be troublesome as the message subject/body and timestamp are not stored as separate entities for each user.

#3

Version:» 6.x-1.x-dev

Rules can not yet select data, unfortunatly. So you need a custom hook_cron() implementation.

Function to mark a message as deleted: http://blog.worldempire.ch/de/api/function/privatemsg_message_change_del...
Function to mark a whole thread as deleted: http://blog.worldempire.ch/de/api/function/privatemsg_thread_change_dele...

The tricky part is to select which messages should be deleted. We do not provide a query for this, so the easiest way is probably a direct SQL query like this:

<?php
$sql
= 'SELECT mid FROM {pm_message} WHERE author = %d AND timestamp < %d';

// Set the uid of the dummy account.
$author_id = 123;

// Messages older than $timestamp are deleted, example, 30 days ago.
$timestamp = time() - (30 * 86400);

$result = db_query($sql, $author_id, $timestamp);

// Fetch over all found messages and mark them as deleted
while ($row = db_fetch_object($result)) {
 
privatemsg_message_change_deleted($row->mid, TRUE);
}
?>

The code is untested and you might want to further refine it, for example, only delete a certain amount of messages per cron run by adding a LIMIT.

#4

thanks for the tips. I'll look into this stuff next week when I have some free time.

Meanwhile, I'm not clear on how exactly the messages are stored when one is marked as "deleted" is it flushed from the database at some point during a cron run, or are the messages just tagged as deleted and they linger forever?

I ask because it's possible that tens of thousands of messages per week could wind up in there, and these are pretty much throwaways that can be safely removed (in the sense that they're not critical emails) after a certain period of time.

#5

there is a flush messages cron job available, but it requires ALL the users to mark the message as deleted first as the actual message contents are on a shared table and simply deleting the message means everyone will lose that message.

#6

Calling privatemsg_message_change_delete() without an account object does delete the message for all users (automatic messages from a bot are probably only sent to a single user anyway (and the bot)) so configuring the flush cronjob should work as expected.

#7

Status:active» fixed

Setting this to fixed since there was no activity for more than a week. Feel free to re-open if you have more questions.

#8

Status:fixed» closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.