framaforms.expiration.inc 8.05 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

/**
 * Contain Framaforms custom function related to automatic expiration of user
 * webforms.
 */

/**
* Get all webforms that will expired between now and 2 weeks in the future,
* and insert them into framaforms_expired table.
* @return void
*/
 function make_forms_expire(){
14
    $expiration_period = variable_get('framaforms_notification_period_value');
15
    // If the user set the expiration period to 0, don't make the nodes expire.
16
    if($expiration_period == 0){
17
18
19
20
21
22
      return;
    }
    $expiration_period .= ' weeks';

    $transaction = db_transaction();
    try{
23
24
      // Select nodes expiring within the two next weeks.
      // Limit query to batch of 1000 rows in order to avoid errors
25
      db_query(sprintf("
26
27
28
29
30
31
32
33
34
35
        INSERT INTO framaforms_expired (nid)
        (SELECT n.nid
        FROM node n
        INNER JOIN field_data_field_form1_expiration fex
        ON fex.entity_id = n.nid
        AND fex.field_form1_expiration_value <= date_trunc('day', NOW() + interval'{$expiration_period}')
        AND fex.entity_id NOT IN
          (SELECT nid FROM framaforms_expired)
        LIMIT 1000)
        ON CONFLICT DO NOTHING;
36
37
38
39
40
41
42
43
44
45
        ",$expiration_period));
    }
    catch(Exception $e){
      $transaction->rollback();
      watchdog('framaforms', $e);
    }

    /* Get all the webforms that are about to expire and whose owner wasn't yet notified */
    try{
      $results = db_query("
46
47
48
49
50
51
52
53
54
        SELECT fex.nid, u.mail, n.title
        FROM framaforms_expired fex
        INNER JOIN node n
        ON fex.nid = n.nid
        INNER JOIN users u
        ON u.uid = n.uid
        WHERE fex.notified = 0
        LIMIT 1000;
        ") ;
55
56

      // Notify the users of their forms expiration
57
      watchdog('framaforms', "Notifying users of their expired forms.");
58
59
60
61
62
63
64
65
66
67
68
69
70
      foreach ($results as $record){
        $user_notified = notify_user_of_expiration($record);
        // Update the database with the notification date and set notified to 1
        if($user_notified){
          db_update('framaforms_expired')
            ->fields(array(
              'notified' => 1,
              'date_notified' => time()
            ))
            ->condition('nid', $record->nid, '=')
            ->execute();
        }
      }
71
      watchdog('framaforms', "Notified all users of their expired forms.");
72
73
74
    }
    catch(Exception $e){
      $transaction->rollback();
75
      watchdog('framaforms', "There was an error notifying users.");
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
      watchdog('framaforms', $e);
    }
 }

 /**
  * Sends an email by calling drupal_mail to a user,
  * notifying them of the upcoming webform expiration.
  *
  * @param DatabaseStatementInterface $record : Single database statement containing node and user information
  * @param string $expiration_period : notification-expiration time interval
  * @param string $deletion_period : expiration-deletion time interval
  * @return void
  */
function notify_user_of_expiration ($record) {
    global $base_url;  //use the global variable of Drupal for the site's URL
    $expiration_period = variable_get('framaforms_notification_period_value') .' weeks';
    $deletion_period = variable_get('framaforms_deletion_period_value') .' weeks';
93
94
95
96
97

    $expiration_date = new DateTime();
    $expiration_date->modify("+".$expiration_period);
    $delete_date = clone $expiration_date;
    $delete_date->modify($deletion_period);
98
99
    $delete_date = date("d/m/Y", $delete_date->getTimestamp());
    $expiration_date = date("d/m/Y", $expiration_date->getTimestamp());
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
    $node_url = $base_url . url('node/'.$record->nid);
    $mail_body = variable_get('framaforms_mail_user_notification_body');
    $mail_subject = variable_get('framaforms_mail_user_notification_subject');
    // replace placeholders in the body and subject.
    $placeholders = ['[form_title]', '[form_expires_on]', '[form_delete_on]', '[form_url]'];
    $replacers = [$record->title, $expiration_date, $delete_date, $node_url];
    $mail_subject = str_replace($placeholders, $replacers, $mail_subject);
    $mail_body = str_replace($placeholders, $replacers, $mail_body);

    $mail_params = array(
        'body' => $mail_body,
        'subject' => $mail_subject,
        'headers' => array(),
    );
theo lem's avatar
theo lem committed
115
    
116
117
118
119
120
    $message = drupal_mail('framaforms', 'expired_webform', (string)$record->mail, user_preferred_language($user), $mail_params);
    return $message['send'];
}

/**
121
 * Looks up webform nodes in the database that were marked as
122
123
124
125
126
127
 * "expired" but whose expiration date * got changed by the user.
 *
 * @return void
 */
function update_modified_nodes () {
    $expiration_period = variable_get('framaforms_notification_period_value');
128
    if($expiration_period == 0){
129
130
131
132
      return;
    }
    $expiration_period .= ' weeks';
    $transaction = db_transaction();
133
    watchdog('framaforms', "Suppression des formulaires dans la table framaforms_expired après que leur date d'expiration ait été repoussée.");
134
135
136
    try{
        //Delete nodes from the framaforms_notified table if their expiration date was pushed back by the user
        $modified_nodes = db_query(sprintf("
137
138
139
140
141
142
143
144
145
            SELECT n.nid
            FROM node n
            INNER JOIN field_data_field_form1_expiration f_exdate
            ON f_exdate.entity_id = n.nid
            INNER JOIN framaforms_expired fex
            ON n.nid = fex.nid
            WHERE f_exdate.field_form1_expiration_value
              > to_timestamp(fex.date_notified) + interval'{$expiration_period}'
            AND n.nid NOT IN (SELECT nid from framaforms_expired)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
        ", $expiration_period));
        $nid_changed= 0 ;

        foreach($modified_nodes as $node){
        $nid_changed = $node->nid;
        db_delete('framaforms_expired')
            ->condition('nid', (int)$nid_changed)
            ->execute() ;
        }
    }
    catch(Exception $e){
        $transaction->rollback();
        watchdog('framaforms', $e);
    }
}

/**
 * Deletes all expired webform nodes after a period of inactivity (defined in $deletion_period).
 * If the webform's expiration date is modified by the user, the update_modified_node()
 * function will delete them from the framaforms_expired table and the rows won't be affected
 * by this function.
 *
 * @param string $deletion_period : form expiration-deletion time interval.
 * @return void
 */
function delete_expired_nodes () {
    $deletion_period = variable_get('framaforms_deletion_period_value');
theo lem's avatar
theo lem committed
173
174
175
176
177
178
179
180
    $notification_period = variable_get('framaforms_notification_period_value');
    $external_log_file = variable_get('framaforms_external_log_file', '/var/log/framaforms_logfile.log');

    // create Datetime object for logging purposes
    $current_date = new Datetime();
    $current_date = date("D d/m/Y - H:i:s", $current_date->getTimestamp());

    // if the user set the deletion period to 0, don't delete the forms
181
    if($deletion_period == 0){
182
183
        return;
    }
theo lem's avatar
theo lem committed
184

185
    $deletion_period .= ' weeks';
186
    $deleted_nodes = array();
187
    watchdog('framaforms', "Suppression des formulaires après notification.");
theo lem's avatar
theo lem committed
188

189
190
    $transaction = db_transaction();
    try{
191
        $query = db_query("
theo lem's avatar
theo lem committed
192
            SELECT fex.nid, to_timestamp(fex.date_notified) dn
193
194
            FROM framaforms_expired fex
            WHERE fex.notified = 1
theo lem's avatar
theo lem committed
195
            AND to_timestamp(fex.date_notified) <= NOW() - interval'{$deletion_period}' - interval'{$notification_period}'
196
            ");
197
198
199
200
201
202
203
        $expired_nodes= $query->fetchAll();
        foreach($expired_nodes as $record){
            node_delete($record->nid);
            // also delete it from the framaforms_expired table
            db_delete('framaforms_expired')
            ->condition('nid', $record->nid)
            ->execute();
theo lem's avatar
theo lem committed
204
            error_log("{$current_date} : Form #{$record->nid} - user notified on {$record->dn} - was deleted.\n", 3, $external_log_file);
205
            array_push($deleted_nodes, $record->nid);
206
207
208
        }

        if(!empty($deleted_nodes)){
209
            watchdog("framaforms", "Les formulaires suivant ont été supprimés : " . explode($deleted_nodes));
210
211
            return;
        }
212
        watchdog("framaforms", "Aucun formulaire à supprimer.");
213
214
215
216
217
218
    }
    catch(Exception $e){
        $transaction->rollback();
        watchdog('framaforms', $e);
    }
}