summaryrefslogtreecommitdiffstats
path: root/vss_email.module
blob: 651bb2e9f3008cf533949bc7375e572c72c7a15c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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
173
174
175
176
177
178
179
180
<?php

/**
 * Implementation of hook_cron().
 */
function vss_email_cron() {
  // Detects views changes and sends email with new items.
  // Uses cron queue for scalability
  $queue  = DrupalQueue::get('vss_email');
  $result = db_query("SELECT sid, uid FROM {views_savedsearches};");
  while ($sub = $result->fetchObject()) {
    $queue->createItem($sub);
    //vss_email_search_notification($sub);
  }
}


/**
 * Implementation of hook_cron_queue_info()
 */
function vss_email_cron_queue_info() {
  $queues['vss_email'] = array(
    'worker callback' => 'vss_email_search_notification',
    'time' => 180,
  );
  return $queues;
}


/* do the actual processing of the notifications */
function vss_email_search_notification($sub) {
  // has uid seen sid before?
  // (uid's first "viewing" of sid is the baseline, and changes are
  // emailed thereafter.)
  $variable = 'vss_email_seen_' . $sub->uid . '_' . $sub->sid;
  $already_seen = variable_get($variable, FALSE);
  if (!$already_seen) variable_set($variable, TRUE);

  // load saved view info, apply filters, run query
  $savedsearch = views_savedsearches_load($sub->sid);
  $view_name   = db_query("SELECT name FROM {views_view} WHERE vid = :vid", array(':vid' => $savedsearch->vid))->fetchField();
  $view        = views_get_view($view_name);
  if (!$view) return;
  $view->set_display('page');
  $view->set_exposed_input($savedsearch->filters);
  $view->set_items_per_page(0);
  $view->build();
  $view->pre_execute();
  $view->execute();

  // Get ids in the views from the past, compare to current results
  $current_ids = vss_email_get_ids($savedsearch->sid);
  $new_items   = array();
  foreach ($view->result as $item) {
    $identifier = $item->nid;
    if (!in_array($identifier, $current_ids)) {
      $current_ids[] = $identifier;
      $new_items[] = $item;
    }
  }
  vss_email_store_ids($savedsearch->sid, $current_ids);

  // new items since last time?
  if (count($new_items) > 0 && $already_seen) {
    $titles = array();
    foreach ($new_items as $item) {
      if (isset($item->nid)) {
        $node = node_load($item->nid);
        $titles[] = l($node->title, 'node/' . $node->nid);
      }
    }
    // send an email
    $user   = user_load($sub->uid);
    $params = array(
      'user'     => $user,
      '!search_title' => check_plain(vss_email_2title($sub->sid)),
      '!search_items' => join("\n", $titles),
    );
    drupal_mail('vss_email', 'views_notification', $user->mail, user_preferred_language($user), $params);
  }
}


/**
 * Converts sid to savedsearches name
 */
function vss_email_2title($sid = 0) {
  $name = db_query("SELECT name FROM {views_savedsearches} WHERE sid = :sid", array(':sid' => $sid))->fetchField();
  return $name;
}


/**
 * Gets already known ids for the given views.
 *
 * @param $sid
 *  Id of the subscription
 */
function vss_email_get_ids($sid = 0) {
  $query = db_select('vss_email', 'b')
            ->fields('b', array('itemid'))
            ->condition('b.sid', $sid)
            ->execute();
  $ids   = array();
  while ($row = $query->fetchObject()) {
    $ids[] = $row->itemid;
  }
  return $ids;
}


/**
 * Store the item ids for the given savedsearch.
 *
 * @param $sid
 *  Id of the subscription
 * @param $ids
 *  Ids of the items in the saved view
 */
function vss_email_store_ids($sid = 0, $ids = array()) {
  // clear the decks
  $deleted = db_delete('vss_email')
    ->condition('sid', $sid)
    ->execute();

  // save items
  foreach ($ids as $id) {
    $insert = db_insert('vss_email')
              ->fields(array(
                'sid' => $sid,
                'itemid' => $id,
                ))
              ->execute();
  }
}


/* implementation of hook_mail */
function vss_email_mail($key, &$message, $params) {
  switch ($key) {
    case 'views_notification':
      $text = variable_get('vss_email_savedsearch_new', '');
      $text = token_replace($text, $params);
      $message['subject'] = t('New search results', array('langcode' => $message['language']->language));
      $message['body'][]  = t($text, $params, array('langcode' => $message['language']->language));
      break;
  }
}


/**
 * Implements hook_menu().
 */
function btmodule_menu() {
  $items = array();

  $items['admin/config/vss_email'] = array(
    'title' => 'VSS Email',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('vss_email_admin_form'),
    'access arguments' => array('access administration pages'),
    'type' => MENU_NORMAL_ITEM,
  );

  return $items;
}


function vss_email_admin_form() {
  $form = array();

  $default = "Dear [username],\n\nThere are new results for your stored search '!search_title:\n\n!search_items";
  $form[] = array(
    '#type'  => 'textarea',
    '#title' => t('VSS email template'),
    '#default_value' => t(variable_get('vss_email_savedsearch_new', $default)),
  );

  return system_settings_form($form);
}