Community Documentation

How to: auto delete private messages based on how old they are

Last updated January 25, 2011. Created by mttjn on January 21, 2011.
Log in to edit this page.

Problem: You have a site where users are sending each other private messages. These messages are accumulating and you want a way to automatically delete messages that are older than, e.g., 3 months, since they are no longer needed and are just bloating your site.

Solution:

There are 2 stages to permanently deleting old private messages from your DB.

(A)

(1) Go to "Site configuration > Private messages > Private messages"
(2) Expand "Flush deleted messages"
(3) Select the checkbox "Flush deleted messages" and configure other settings as required.

These settings means that any messages which have been deleted by users will be "flushed" - permanently erased - from the DB when cron runs. However, what about messages that are old but haven't yet been selected by a user for deletion? These old messages are just filling up users' private message inboxes and we want to force deletion of these too. So...

(B)

We need to run the following script with cron (you can find out how to create scripts to run with cron elsewhere on drupal.org). This uses a function in private message module that sets the pm_index.deleted field for a message to "1" meaning its status is "deleted". Once its status is "deleted", it will get erased when "Flush deleted messages" runs (see above).

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

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

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

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

One final thing, if your site is large and you have lots of old private messages piled up that need deleting, it's probably a good idea to limit the number of messages that are affected the first few times that the above script runs. To do this use "db_query_range" instead of "db_query". For example:

<?php
$result
= db_query_range($sql, $timestamp, 0, 500); // limit to 500 per run
?>

--
And thanks to Berdir for a great module and for generous support with questions :)

Page status

No known problems

Log in to edit this page

About this page

Drupal version
Drupal 6.x
Audience
Developers and coders

Site Building Guide

Drupal’s online documentation is © 2000-2012 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License. Comments on documentation pages are used to improve content and then deleted.
nobody click here