diff --git a/actions/README.txt b/actions/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..7580d66f8ea1a60ea61265721eee9dbe83f62706 --- /dev/null +++ b/actions/README.txt @@ -0,0 +1,210 @@ +Overview: +--------- +The ad_actions module provides triggers for the following +advertisement events: + - an advertisement has been clicked + - an advertisement has been approved + - an advertisement has been activated + - an advertisement has been denied + - an advertisement has been marked as pending + - an advertisement has been taken offline + - an advertisement has been created + - an advertisement has been updated + - an advertisement has been deleted + - an advertisement has expired + - an advertisement has an approaching scheduled activation + - an advertisement has been activated through scheduling + - an advertisement has an approaching scheduled expiration + - an advertisement has expired through scheduling + +The triggers can be configured to cause any of the following +actions: + - generate an email + - display a custom message to the user + - override the ad's redirect + +Two advanced actions are provided by this module. The first is +named 'Send e-mail before automated ad trigger', and can be used +to send emails before an advertisement is scheduled to be +activated or expired. The second is named 'Send e-mail on or +after ad trigger' and can be used with any of the triggers defined +by this module. + +This module depends on the token module, allowing you to create +dynamic notifications. + + +Permissions: +------------ +In order to configure ad triggers, users must be in a role that +has the 'administer ad triggers' permission. + + +Examples: +--------- +This documentation offers two examples of how you can use the +triggers and advanced actions provided by this module. It also +explains how you can provide per-user configuration options +for disabling notification emails. + + + Click notification: + ------------------- + The following example shows you how to send an email to the + owner of an advertisement whenever the advertisement is + clicked. In this example, we configure the action to send + no more than one email in every 24-hour period. + + Part I) + ------- + 1) Go to Administer >> Site configuration >> Actions and + in the "Make a new advanced action available" section + toward the bottom of the screen select "Send e-mail on + or after ad trigger" from the drop down menu and click + Create. + 2) Enter something descriptive in the description field, + for example you could enter "Send email after + advertisement is clicked". + 3) Enter "[owner_email]" in the Recipient field. This is + a token that will automatically be replaced when the + notification is sent. For a complete list of + available tokens click the "Placeholder tokens" link. + 4) Enter "Ad [title] has been clicked" in the Subject + field. + 5) Enter the following into the Message field: + Hello [owner_name], + Your advertisement has been viewed [today_impressions] + times and clicked [today_clicks] times today. + - The [site-name] team. + 6) Set the 'When to send' field set to '1 day after'. + 7) Click the 'Save' button. + + Part II) + -------- + 1) Go to Administer >> Site building >> Triggers and + in the "After an advertisement has been clicked" + section click the "Choose an action" menu and select + the action you created in Part I above. + 2) Click the 'Assign' button. + + With the above action defined and assigned to the click + trigger, once an advertisement is clicked a notification + to the ad's owner is added to a queue. If the + advertisement is clicked again during the next 24 hours + no additional notification is added to the queue. 24 + hours after the ad was first clicked, the notification + email is sent out. The token replacement happens when + the email is sent, so all subsequent clicks are reflected + in the notification email. + + + Allowing users to disable notifications: + ---------------------------------------- + It is possible to allow individual users to disable the + notifications generated by the advanced actions defined + by this module. + + Part I) + ------- + 1) Enable the profile module, which is part of the core + Drupal installation. + 2) Go to Administer >> User management >> Profiles and + click "checkbox" under the 'Add new field' heading. + 3) Enter 'Advertisements' for the Category. + 4) Enter 'Disable click notifications' for the Title. + 5) Enter 'profile_disable_click_notifications' for the + Form name. + 6) Enter 'Check this box to disable click notification + emails. When this box is unchecked, you will + receive email notifications once every 24 hours when + your advertisements are clicked.' + 7) Set the Visibility to 'Private field, content only + available to privileged users.' + 8) Click 'Save field'. + + Part II) + -------- + 1) Go to Administer >> Site configuration >> Actions and + click 'configure' next to the advanced action you + created in the above example. + 2) Scroll down and select 'Disable click notifications' + for the 'Profile field used to disable notifications' + (This option will only be visible after you have + enabled the profile module and created at least one + user profile field. + 3) Click 'Save'. + + Part III) + --------- + 1) Users with proper permissions can now click 'My + account' in the navigation block, then click + the 'Edit' tab, and finally click the + 'Advertisements' subtab. On the subsequent + screen they can disable notification emails for + their account. + + The above is just one example of how you may allow + users to disable notifications. You may wish to use + something other than a checkbox for the user's profile + field -- the field type is not important, though + notifications will only be disabled when the user + sets the field to a non-empty non-zero value. + + You can re-use the same profile field with multiple + actions, thereby providing a single checkbox to + disable all notifications. Or, you can create a + unique profile field for each advanced action + providing your users with more granular control + over the notification emails. + + It would be a good idea to explain to your users how + they can disable notifications in each notification + email that is sent. + + + Notify that an ad is about to expire: + ------------------------------------- + The following example shows you how to send an email to all + owners of an advertisement 1 week before the advertisement + is scheduled to be automatically expired. + + Part I) + ------- + 1) Go to Administer >> Site configuration >> Actions and + in the "Make a new advanced action available" section + toward the bottom of the screen select "Send e-mail + before automated ad trigger" from the drop down menu + and click Create. + 2) Enter something descriptive in the description field, + for example you could enter "Send email 1 week before + advertisement expires." + 3) Enter "[all_owner_emails]" in the Recipient field. This + is a token that will automatically be replaced with a list + of all email addresses for all owners of a given + advertisement when the email is generated. For a complete + list of available tokens click the "Placeholder tokens" + link. (The [ad_owner_emails] token is only available if + you have enabled the ad_owners module.) + 4) Enter "Ad [title] will expire in 1 week" in the Subject + field. + 5) Enter the following into the Message field: + Hello [owner_name], + To date, your advertisement has been viewed + [global_impressions] times and clicked [global_clicks] + times. Your advertisement will expire in about + 1 week, on [autoexpire_large]. + - The [site-name] team. + 6) Set the 'When to send' field set to '1 week before'. + 7) Click the 'Save' button. + + Part II) + -------- + 1) Go to Administer >> Site building >> Triggers and + in the "Scheduled expiration" section click the + "Choose an action" menu and select the action you + created in Part I above. + 2) Click the 'Assign' button. + + With the above action defined and assigned to the scheduled + expiration trigger, a notification email will be sent to + all of the ad's owners 1 week before it will expire. diff --git a/actions/ad_actions.info b/actions/ad_actions.info new file mode 100644 index 0000000000000000000000000000000000000000..9184024dbfa79cc07d910b4a1207c13ee91c6f57 --- /dev/null +++ b/actions/ad_actions.info @@ -0,0 +1,7 @@ +; $Id$ +name = Ad actions +package = Ad +dependencies[] = trigger +dependencies[] = token +description = Enable ad triggers and actions, useful for creating notification emails. +core = 6.x diff --git a/actions/ad_actions.install b/actions/ad_actions.install new file mode 100644 index 0000000000000000000000000000000000000000..d8accf2497a4307d4159773dfeb275c34dbfce93 --- /dev/null +++ b/actions/ad_actions.install @@ -0,0 +1,81 @@ +. + */ + +/** + * Implementation of hook_schema(). + */ +function ad_actions_schema() { + $schema['ad_actions_queue'] = array( + 'description' => 'The ad_notify table stores notifications data such as recepient, message body, event, etc.', + 'fields' => array( + 'qid' => array( + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'aid' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'recipient' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ), + 'scheduled' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'period' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'sent' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + ), + 'context' => array( + 'type' => 'text', + 'not null' => FALSE, + ), + ), + 'primary key' => array('qid'), + 'unique keys' => array( + 'aid_period_recipient' => array('aid', 'period', 'recipient'), + ), + 'indexes' => array( + 'period_scheduled' => array('period', 'scheduled'), + 'sent_period' => array('sent', 'period'), + ), + ); + return $schema; +} + +/** + * ad_actions module installation. + */ +function ad_actions_install() { + drupal_install_schema('ad_actions'); +} + +/** + * Allow complete uninstallation of the ad_actions module. + */ +function ad_actions_uninstall() { + // Remove tables. + drupal_uninstall_schema('ad_actions'); +} + diff --git a/actions/ad_actions.module b/actions/ad_actions.module new file mode 100644 index 0000000000000000000000000000000000000000..185201a57cd0dfeadc9620f4c83ea0dd21804a84 --- /dev/null +++ b/actions/ad_actions.module @@ -0,0 +1,451 @@ +. + */ + +/** + * Implementation of hook_help(). + */ +function ad_actions_help($path, $arg) { + $output = ''; + switch ($path) { + case 'admin/help#ad_actions': + $output = '

'. t('The ad_actions module provides triggers and actions allowing administrators to create notifications for the ad module.') .'

'; + break; + } + return $output; +} + +/** + * Implementation of hook_cron(). + */ +function ad_actions_cron() { + // if time, send queued notification emails + $result = db_query('SELECT qid, context FROM {ad_actions_queue} WHERE period >= 0 AND scheduled <= %d', time()); + while ($notify = db_fetch_object($result)) { + db_query('DELETE FROM {ad_actions_queue} WHERE qid = %d', $notify->qid); + _ad_actions_send_email(unserialize($notify->context)); + } + // trigger "autoactivated" actions, they will end up in the queue + $activate = array(); + $result = db_query('SELECT aid, autoactivate FROM {ads} WHERE autoactivate > 0'); + while ($ad = db_fetch_array($result)) { + module_invoke_all('ad_actions_trigger', 'autoactivated', $ad); + $activate[$ad['aid']] = $ad['autoactivate']; + } + // trigger "autoexpired" actions, they will end up in the queue + $expire = array(); + $result = db_query('SELECT aid, autoexpire FROM {ads} WHERE autoexpire > 0'); + while ($ad = db_fetch_array($result)) { + module_invoke_all('ad_actions_trigger', 'autoexpired', $ad); + $expire[$ad['aid']] = $ad['autoexpire']; + } + // if time, send queued "autoactivated" and "autoexpired" notification emails + if (!empty($activate) || !empty($expire)) { + $result = db_query('SELECT qid, aid, period, context FROM {ad_actions_queue} WHERE sent = 0 AND period < 0'); + while ($notify = db_fetch_object($result)) { + if (isset($expire[$notify->aid])) { + // minus a minus is a plus... + if ((time() - $notify->period) >= $expire[$notify->aid]) { + db_query('UPDATE {ad_actions_queue} SET sent = 1 WHERE qid = %d', $notify->qid); + _ad_actions_send_email(unserialize($notify->context)); + } + } + else { + // autoexpiration is no longer enabled for this ad, + // remove action from queue. + db_query('DELETE FROM {ad_actions_queue} WHERE qid = %d', $notify->qid); + } + } + } +} + +/** + * Implementation of hook_perm(). + */ +function ad_actions_perm() { + return array('administer ad triggers'); +} + +/** + * Implementation of hook_adapi(). + */ +function ad_actions_adapi($op, &$node) { + if ($op == 'statistics_increment') { + // trigger whenever statistics are incremented + module_invoke_all('ad_actions_trigger', $node['action'], $node); + } +} + +/** + * Implementation of hook_action_info(). + * Define new advanced actions and the triggers that can invoke them. + */ +function ad_actions_action_info() { + return array( + 'ad_actions_send_email_action_before' => array( + 'description' => t('Send e-mail before automated ad trigger'), + 'type' => 'system', + 'configurable' => TRUE, + 'hooks' => array( + 'ad_actions' => array('autoactivated', 'autoexpired'), + ) + ), + 'ad_actions_send_email_action_after' => array( + 'description' => t('Send e-mail on or after ad trigger'), + 'type' => 'system', + 'configurable' => TRUE, + 'hooks' => array( + 'ad_actions' => array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'), + ) + ), + ); +} + + +/** + * Return a form definition so the advanced email action can be configured. + * + * @param $context + * Default values (if we are editing an existing action instance). + * @return + * Form definition. + */ +function ad_actions_send_email_action_before_form($context) { + $form = _ad_actions_email_form($context); + $options = array(-31449600 => t('1 year before'), -9676800 => t('16 weeks before'), -4838400 => t('8 weeks before'), -2419200 => t('4 weeks before'), -1814400 => t('3 weeks before'), -1209600 => t('2 weeks before'), -604800 => t('1 week before'), -432000 => t('5 days before'), -259200 => t('3 days before'), -86400 => t('1 day before'), -43200 => t('12 hours before'), -21600 => t('6 hours before'), -10800 => t('3 hours before'), -3600 => t('1 hour before')); + $form = array_merge($form, _ad_actions_email_ad_form($context, $options, 'before', -604800)); + $form = array_merge($form, _ad_actions_email_tokens_form($context)); + return $form; +} + +/** + * Collect action configuration, stored serialized in the + * database. + */ +function ad_actions_send_email_action_before_submit($form, &$form_state) { + $params = array( + 'recipient' => $form_state['values']['recipient'], + 'subject' => $form_state['values']['subject'], + 'message' => $form_state['values']['message'], + 'before' => $form_state['values']['before'], + 'disable_notifications' => $form_state['values']['disable_notifications'], + ); + return $params; +} + +/** + * Implementation of a configurable Drupal action. + * Schedules an email, sent before scheduled actions. + */ +function ad_actions_send_email_action_before($object, $context) { + if ($context['before']) { + if (!db_result(db_query_range("SELECT 1 FROM {ad_actions_queue} WHERE aid = %d AND period = %d AND recipient = '%s'", $object->aid, $context['before'], $context['recipient'], 0, 1))) { + db_query("INSERT INTO {ad_actions_queue} (aid, recipient, period, scheduled, context) VALUES(%d, '%s', %d, %d, '%s')", $object->aid, $context['recipient'], $context['before'], time() + $context['before'], serialize($context)); + watchdog('action', 'Queued email for scheduled trigger to %recipient', array('%recipient' => $context['recipient'])); + } + } +} + +/** + * Return a form definition so the advanced email action can be configured. + * + * @param $context + * Default values (if we are editing an existing action instance). + * @return + * Form definition. + */ +function ad_actions_send_email_action_after_form($context) { + $form = _ad_actions_email_form($context); + $options = array(0 => t('immediately'), 3600 => t('1 hour after'), 10800 => t('3 hours after'), 21600 => t('6 hours after'), 43200 => t('12 hours after'), 86400 => t('1 day after'), 259200 => t('3 days after'), 432000 => t('5 days after'), 604800 => t('1 week after'), 1209600 => t('2 weeks after'), 1814400 => t('3 weeks after'), 2419200 => t('4 weeks after'), 4838400 => t('8 weeks after'), 9676800 => t('16 weeks after'), 31449600 => t('1 year after')); + $form = array_merge($form, _ad_actions_email_ad_form($context, $options, 'after')); + $form = array_merge($form, _ad_actions_email_tokens_form($context)); + return $form; +} + +/** + * Collect action configuration, stored serialized in the + * database. + */ +function ad_actions_send_email_action_after_submit($form, &$form_state) { + // Process the HTML form to store configuration. The keyed array that + // we return will be serialized to the database. + $params = array( + 'recipient' => $form_state['values']['recipient'], + 'subject' => $form_state['values']['subject'], + 'message' => $form_state['values']['message'], + 'after' => $form_state['values']['after'], + 'disable_notifications' => $form_state['values']['disable_notifications'], + ); + return $params; +} + +/** + * Implementation of a configurable Drupal action. + * Schedules an email, sent before scheduled actions. + */ +function ad_actions_send_email_action_after($object, $context) { + if ($context['after']) { + // send delayed notification email + if (!db_result(db_query_range("SELECT 1 FROM {ad_actions_queue} WHERE aid = %d AND period = %d AND recipient = '%s'", $object->aid, $context['after'], $context['recipient'], 0, 1))) { + db_query("INSERT INTO {ad_actions_queue} (aid, recipient, period, scheduled, context) VALUES(%d, '%s', %d, %d, '%s')", $object->aid, $context['recipient'], $context['after'], time() + $context['after'], serialize($context)); + watchdog('action', 'Queued email to %recipient', array('%recipient' => $context['recipient'])); + } + } + else { + // send instant notification email + _ad_actions_send_email($context); + } +} + +/** + * Implementation of hook_hook_info(). + * Define all available ad triggers. + */ +function ad_actions_hook_info() { + return array( + 'ad_actions' => array( + 'ad_actions' => array( + 'click' => array( + 'runs when' => t('An advertisement has been clicked.'), + ), + 'approved' => array( + 'runs when' => t('An advertisement has been approved.'), + ), + 'pending' => array( + 'runs when' => t('An advertisement has been marked as pending.'), + ), + 'offline' => array( + 'runs when' => t('An advertisement has been marked as offline.'), + ), + 'denied' => array( + 'runs when' => t('An advertisement has been denied.'), + ), + 'active' => array( + 'runs when' => t('An advertisement has been activated.'), + ), + 'expired' => array( + 'runs when' => t('An advertisement has expired.'), + ), + 'created' => array( + 'runs when' => t('An advertisement has been created.'), + ), + 'update' => array( + 'runs when' => t('An advertisement has been updated.'), + ), + 'delete' => array( + 'runs when' => t('An advertisement has been deleted.'), + ), + 'autoactivated' => array( + 'runs when' => t('Scheduled activation.'), + ), + 'autoexpired' => array( + 'runs when' => t('Scheduled expiration.'), + ), + ), + ), + ); +} + +/** + * Implementation of hook_action_info_alter + * Allow ad module triggers to trigger other actions. + */ +function ad_actions_action_info_alter(&$info) { + // Add this modules's triggers to the core system email action + if (isset($info['system_send_email_action']['hooks']['ad_actions'])) { + array_merge($info['system_send_email_action']['hooks']['ad_actions'], array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete')); + } else { + $info['system_send_email_action']['hooks']['ad_actions'] = array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'); + } + + // Add this modules's triggers to the core system message action + if (isset($info['system_message_action']['hooks']['ad_actions'])) { + array_merge($info['system_message_action']['hooks']['ad_actions'], array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete')); + } else { + $info['system_message_action']['hooks']['ad_actions'] = array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'); + } + + // Add this modules's triggers to the core system goto action + if (isset($info['system_goto_action']['hooks']['ad_actions'])) { + array_merge($info['system_goto_action']['hooks']['ad_actions'], array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete')); + } else { + $info['system_goto_action']['hooks']['ad_actions'] = array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'); + } + + // Add this modules's triggers to the token message action + if (isset($info['token_actions_message_action']['hooks']['ad_actions'])) { + array_merge($info['token_actions_message_action']['hooks']['ad_actions'], array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete')); + } else { + $info['token_actions_message_action']['hooks']['ad_actions'] = array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'); + } + + // Add this modules's triggers to the token send email action + if (isset($info['token_actions_send_email_action']['hooks']['ad_actions'])) { + array_merge($info['token_actions_send_email_action']['hooks']['ad_actions'], array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete')); + } else { + $info['token_actions_send_email_action']['hooks']['ad_actions'] = array('click', 'approvated', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'); + } + + // Add this modules's triggers to the token goto action + if (isset($info['token_actions_goto_action']['hooks']['ad_actions'])) { + array_merge($info['token_actions_goto_action']['hooks']['ad_actions'], array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete')); + } else { + $info['token_actions_goto_action']['hooks']['ad_actions'] = array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'); + } +} + +/** + * Implementation of hook_menu_alter + */ +function ad_actions_menu_alter(&$items) { + // In theory we can define this title in HOOK_hook_info(), + // but as that doesn't seem to work we're overriding it here. + $items['admin/build/trigger/ad_actions']['title'] = 'Advertisements'; + // Use a custom permissions + $items['admin/build/trigger/ad_actions']['access arguments'] = array('administer ad triggers'); +} + +/** + * Implementation of hook_trigger_name(). + * Trigger event, launch all appropriate actions. + */ +function ad_actions_ad_actions_trigger($op, $ad) { + global $user; + if (!in_array($op, array('click', 'approved', 'pending', 'offline', 'denied', 'active', 'autoactivated', 'expired', 'autoexpired', 'created', 'update', 'delete'))) { + return; + } + $aids = _trigger_get_hook_aids('ad_actions', $op); + $node = node_load($ad['aid']); + $context = array( + 'hook' => 'ad_actions', + 'op' => $op, + 'user' => $user, + 'node' => $node, + 'ad' => $node, + ); + actions_do(array_keys($aids), $node, $context); +} + +/** + * A helper function for building ad action forms. + */ +function _ad_actions_email_form($context) { + $form = array(); + $form['recipient'] = array( + '#type' => 'textfield', + '#title' => t('Recipient'), + '#default_value' => isset($context['recipient']) ? $context['recipient'] : '', + '#size' => '20', + '#maxlength' => '254', + '#description' => t('The email address to which the message should be sent. Tokens are allowed. Separate multiple email addresses with commas.'), + ); + $form['subject'] = array( + '#type' => 'textfield', + '#title' => t('Subject'), + '#default_value' => isset($context['subject']) ? $context['subject'] : '', + '#size' => '20', + '#maxlength' => '254', + '#description' => t('The subject of the message. Tokens are allowed.'), + ); + $form['message'] = array( + '#type' => 'textarea', + '#title' => t('Message'), + '#default_value' => isset($context['message']) ? $context['message'] : '', + '#cols' => '80', + '#rows' => '20', + '#description' => t('The message that should be sent. Tokens are allowed.'), + ); + + return $form; +} + +/** + * A helper function for building ad action forms. + */ +function _ad_actions_email_ad_form($context, $options, $key, $default = 0) { + $form = array(); + $form[$key] = array( + '#type' => 'select', + '#title' => t('When to send'), + '#options' => $options, + '#description' => t('Specify when you would like the email sent. Sending your email any time other than immediately requires cron. Only one delayed email will be generated per advertisement per recipient per configured period even if the trigger event happens multiple times during the delay period.'), + '#default_value' => isset($context[$key]) ? $context[$key] : $default, + ); + if (db_table_exists('profile_fields')) { + $field = ''; + $result = db_query('SELECT category, name, title FROM {profile_fields}'); + $first = TRUE; + while ($row = db_fetch_object($result)) { + if ($first) { + $fields = array('-1' => '- '. t('select a profile field') .' -'); + $first = FALSE; + } + $fields[$row->category][$row->name] = $row->title . ' (' . $row->name . ')'; + } + if (!empty($fields)) { + $form['disable_notifications'] = array( + '#type' => 'select', + '#title' => t('Profile field used to disable notifications'), + '#options' => $fields, + '#default_value' => isset($context['disable_notifications']) ? $context['disable_notifications'] : -1, + '#description' => t("Optionally select a profile field which can be used to disable notifications on a per-user basis for this action. If a user assigns a non-empty value or 0 value to this field, notification emails will be disabled. It is recommended that you assign a checkbox field that when checked will disable all notifications generated by this action to the recipient. Notifications can only be disabled when they are sent to email addresses associated with users on your website."), + ); + } + } + return $form; +} + +/** + * A helper function for building ad action forms. + */ +function _ad_actions_email_tokens_form($context) { + $form = array(); + $form['help'] = array( + '#type' => 'fieldset', + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#title' => t('Placeholder tokens'), + '#description' => t("The following placeholder tokens can be used in to generate the URL path. Some tokens may not be available, depending on the context in which the action is triggered."), + ); + $form['help']['tokens'] = array( + '#value' => theme('token_help', 'all'), + ); + return $form; +} + +function _ad_actions_send_email($context) { + token_normalize_context($context); + $params['from'] = variable_get('site_mail', ini_get('sendmail_from')); + $recipient = token_replace_multiple($context['recipient'], $context); + $params['subject'] = str_replace(array("\r", "\n"), '', token_replace_multiple($context['subject'], $context)); + $params['body'] = token_replace_multiple($context['message'], $context); + + // we allow multiple comma separated recipients + $recipients = explode(',', $recipient); + foreach ($recipients as $recipient) { + $recipient = trim($recipient); + if (isset($context['disable_notifications']) && $context['disable_notifications'] != '-1') { + $account = user_load(array('mail' => $recipient)); + $field = $context['disable_notifications']; + if (!empty($account->$field)) { + watchdog('action', 'Notifications to %recipient are disabled, notification not sent', array('%recipient' => $recipient)); + continue; + } + } + + if (drupal_mail('ad_actions', 'ad_actions_send_email', $recipient, language_default(), $params)) { + watchdog('action', 'Sent email to %recipient', array('%recipient' => $recipient)); + } + else { + watchdog('error', 'Unable to send email to %recipient', array('%recipient' => $recipient)); + } + } +} + diff --git a/ad.module b/ad.module index 8a9b09fead7298c1c5af259927c78eb7b3a86b63..cb6b598d6775a7382c54a495b65e09ab8a35e04c 100644 --- a/ad.module +++ b/ad.module @@ -225,13 +225,8 @@ function ad_redirect($aid, $group = NULL) { $extra = isset($_GET['extra']) ? $_GET['extra'] : ''; if (function_exists('click_filter_status')) { $status = click_filter_status($aid, $hostid); - if ($status == CLICK_VALID) { - ad_statistics_increment($aid, 'click', $group, $hostid); - } } else { - // We're not filtering clicks, so all clicks are valid. - ad_statistics_increment($aid, 'click', $group, $hostid); $status = 0; } // Allow source url to be passed in. @@ -240,7 +235,14 @@ function ad_redirect($aid, $group = NULL) { $url = referer_uri(); } db_query("INSERT INTO {ad_clicks} (aid, uid, status, hostname, user_agent, adgroup, extra, hostid, url, timestamp) VALUES (%d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', %d)", $aid, $user->uid, $status, ip_address(), $_SERVER['HTTP_USER_AGENT'], $group, $extra, $hostid, $url, time()); - + watchdog('ad', 'Clicked %type ad aid %aid hostid %hostid.', array('%type' => $adtype, '%aid' => $aid, '%hostid' => $hostid)); + if (function_exists('click_filter_status') && ($status == CLICK_VALID)) { + ad_statistics_increment($aid, 'click', $group, $hostid); + } + else if (!function_exists('click_filter_status')) { + // We're not filtering clicks, so all clicks are valid. + ad_statistics_increment($aid, 'click', $group, $hostid); + } // Determine where we're supposed to redirect the user. $adtype = db_result(db_query('SELECT adtype FROM {ads} WHERE aid = %d', $aid)); @@ -248,7 +250,6 @@ function ad_redirect($aid, $group = NULL) { $node->hostid = $hostid; $url = module_invoke('ad_'. $adtype, 'adapi', 'redirect', $node); if (isset($url)) { - watchdog('ad', 'Clicked %type ad aid %aid hostid %hostid.', array('%type' => $adtype, '%aid' => $aid, '%hostid' => $hostid)); header('Location: '. $url); } else { @@ -962,11 +963,11 @@ function ad_nodeapi(&$node, $op, $teaser, $page) { break; case 'delete': - db_query("DELETE FROM {ads} WHERE aid = %d", $node->nid); - db_query("DELETE FROM {ad_statistics} WHERE aid = %d", $node->nid); // All that's left of the ad is a single timestamp as to when it was // deleted. ad_statistics_increment($node->nid, 'delete'); + db_query("DELETE FROM {ads} WHERE aid = %d", $node->nid); + db_query("DELETE FROM {ad_statistics} WHERE aid = %d", $node->nid); break; case 'view': @@ -1384,85 +1385,6 @@ function ad_groups_list($object = FALSE, $tid = NULL) { } } -/** - * Implement ad notify api _hook. - */ -function ad_adnotifyapi($op, $arg1 = NULL, $arg2 = NULL) { - switch ($op) { - // Make the following events available for notification. - case 'register': - return array( - '-expired' => t('Email @when before the advertisement will expire.'), - 'expired' => t('Email @when after the advertisement is expired.'), - '-active' => t('Email @when before the advertisement will be activated (if scheduled).'), - 'active' => t('Email @when after the advertisement is activated.'), - 'offline' => t('Email @when after the advertisement is taken offline.'), - 'click' => t('Email @when after the advertisement is clicked.'), - 'approved' => t('Email @when after the advertisement is approved.'), - 'denied' => t('Email @when after the advertisement is denied.'), - 'update' => t('Email @when after the advertisement is updated.'), - ); - break; - case '-expired': - $node = node_load($arg1->aid); - if (isset($node->autoexpire) && $node->autoexpire) { - if ((time() + $arg1->delay >= $node->autoexpire) && - ($arg1->sent + $arg1->delay < $node->autoexpire)) { - return array('-expired' => 1); - } - } - break; - case '-active': - $node = node_load($arg1->aid); - if (isset($node->autoactivate) && $node->autoactivate) { - if ((time() + $arg1->delay >= $node->autoactivate) && - ($arg1->sent + $arg1->delay < $node->autoactivate)) { - return array('-active' => 1); - } - } - break; - case 'mail_text': - switch ($arg1) { - case 'expired': - return array( - 'subject' => t('[%site-name ad] %event notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" that was being displayed on the %site-name website has expired.\n\n Your advertisement was viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - case '-expired': - return array( - 'subject' => t('[%site-name ad] expiration notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" that is being displayed on the %site-name website will expire on %autoexpire_large.\n\n Your advertisement has been viewed %today_impressions times and clicked %today_clicks times today. It was viewed %yesterday_impressions times and clicked %yesterday_clicks times yesterday. It has been viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - case 'active': - return array( - 'subject' => t('[%site-name ad] %event notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" is now actively being displayed on the %site-name website.\n\n Your advertisement has been viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - case '-active': - return array( - 'subject' => t('[%site-name ad] activation notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" will be actively displayed on the %site-name website on %autoactivate_large.\n\n You can view statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - case 'click': - return array( - 'subject' => t('[%site-name ad] %event notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been clicked.\n\n Your advertisement has been viewed %today_impressions times and clicked %today_clicks times today. It was viewed %yesterday_impressions times and clicked %yesterday_clicks times yesterday. It has been viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You will receive this %frequency You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - case 'approved': - return array( - 'subject' => t('[%site-name ad] %event notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been approved.\n\n You can view statistics about this advertisement at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - case 'denied': - return array( - 'subject' => t('[%site-name ad] %event notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification to inform you that your advertisement \"%title\" on the %site-name website has been denied and will not be displayed.\n\n You can view statistics about this advertisement at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - } - break; - } -} - function _ad_check_installation() { // Verify serve.php exists and is readable. $adserve = variable_get('adserve', ''); diff --git a/ad_token.inc b/ad_token.inc index 804a889412444fccc863f120610ba3dcb87166b1..90b2fc6f4fa258d6146300d9935115627669b2c1 100644 --- a/ad_token.inc +++ b/ad_token.inc @@ -17,23 +17,18 @@ function ad_token_values($type, $object = NULL, $options = array()) { case 'ad': if (isset($object)) { $node = $object; - $notifications = module_invoke_all('adnotifyapi', 'register'); module_load_include('pages.inc', 'ad'); - $values['aid'] = $node->nid; - $values['title'] = $node->title; - $values['description'] = $node->body; - $values['log_message'] = $node->log; - $values['type'] = $node->adtype; - $values['status'] = $node->adstatus; - $values['url'] = url('node/'. $node->nid, array('absolute' => TRUE)); - $values['redirect'] = url($node->redirect, array('absolute' => TRUE)); - $values['comments'] = $node->comment_count; - - if (isset($node->notification)) { - $values['event'] = $node->notification->event; - $values['frequency'] = t(strtolower($notifications[$node->notification->event]), array('@when' => format_interval($node->notification->delay))); - } + $values['ad'] = $node->ad; + $values['aid'] = $node->nid; + $values['title'] = $node->title; + $values['description'] = $node->body; + $values['log_message'] = $node->log; + $values['type'] = $node->adtype; + $values['status'] = $node->adstatus; + $values['url'] = url('node/'. $node->nid, array('absolute' => TRUE)); + $values['redirect'] = url($node->redirect, array('absolute' => TRUE)); + $values['comments'] = $node->comment_count; $values['created_small'] = format_date($node->created, 'small'); $values['created_medium'] = format_date($node->created, 'medium'); @@ -47,9 +42,15 @@ function ad_token_values($type, $object = NULL, $options = array()) { $values['autoactivate_small'] = $node->autoactivate ? format_date($node->autoactivate, 'small') : t('never'); $values['autoactivate_medium'] = $node->autoactivate ? format_date($node->autoactivate, 'medium') : t('never'); $values['autoactivate_large'] = $node->autoactivate ? format_date($node->autoactivate, 'large') : t('never'); + $values['autoactivated_small'] = $node->autoactivated ? format_date($node->autoactivated, 'small') : t('never'); + $values['autoactivated_medium'] = $node->autoactivated ? format_date($node->autoactivated, 'medium') : t('never'); + $values['autoactivated_large'] = $node->autoactivated ? format_date($node->autoactivated, 'large') : t('never'); $values['autoexpire_small'] = $node->autoexpire ? format_date($node->autoexpire, 'small') : t('never'); $values['autoexpire_medium'] = $node->autoexpire ? format_date($node->autoexpire, 'medium') : t('never'); $values['autoexpire_large'] = $node->autoexpire ? format_date($node->autoexpire, 'large') : t('never'); + $values['autoexpired_small'] = $node->autoexpired ? format_date($node->autoexpired, 'small') : t('never'); + $values['autoexpired_medium'] = $node->autoexpired ? format_date($node->autoexpired, 'medium') : t('never'); + $values['autoexpired_large'] = $node->autoexpired ? format_date($node->autoexpired, 'large') : t('never'); $statistics = ad_statistics($node->nid); // maximums @@ -82,14 +83,29 @@ function ad_token_values($type, $object = NULL, $options = array()) { // this hour statistics $values['this_hour_impressions'] = isset($statistics['this_hour']) && !empty($statistics['this_hour']) ? $statistics['this_hour']['views'] : 0; $values['this_hour_clicks'] = isset($statistics['this_hour']) && !empty($statistics['this_hour']) ? $statistics['this_hour']['clicks'] : 0; - } - break; - case 'ad_owner': - if (isset($object) && is_object($object)) { - $owner = $object; - $values['owner_name'] = $owner->name; - $values['owner_mail'] = $owner->mail; - $values['owner_uid'] = $owner->uid; + + $owner = user_load($node->uid); + $values['owner_name'] = $owner->name; + $values['owner_email'] = $owner->mail; + $values['owner_uid'] = $owner->uid; + if (db_table_exists('ad_owners')) { + $result = db_query('SELECT a.uid, u.mail, u.name FROM {ad_owners} a INNER JOIN {users} u ON a.uid = u.uid WHERE a.aid = %d', $node->nid); + $uids = $names = $emails = array(); + while ($owner = db_fetch_object($result)) { + $uids[$owner->uid] = $owner->uid; + $names[$owner->uid] = $owner->name; + $emails[$owner->uid] = $owner->mail; + } + $values['all_owner_names'] = implode(', ', $names); + $values['all_owner_emails'] = implode(', ', $emails); + $values['all_owner_uids'] = implode(', ', $uids); + unset($names[$node->uid]); + unset($emails[$node->uid]); + unset($uids[$node->uid]); + $values['secondary_owner_names'] = implode(', ', $names); + $values['secondary_owner_emails'] = implode(', ', $emails); + $values['secondary_owner_uids'] = implode(', ', $uids); + } } break; } @@ -101,57 +117,66 @@ function ad_token_values($type, $object = NULL, $options = array()) { */ function ad_token_list($type = 'all') { if ($type == 'ad' || $type == 'all') { - $tokens['ad']['aid'] = t('The ID of the advertisement.'); - $tokens['ad']['type'] = t('The type of ad.'); - $tokens['ad']['status'] = t('The status of the ad.'); - $tokens['ad']['url'] = t('The url of the advertisement.'); - $tokens['ad']['redirect'] = t('The redirection url of the advertisement.'); - $tokens['ad']['event'] = t('The type of event that has triggered this notification.'); - $tokens['ad']['frequency'] = t('A complete sentence describing the frequency this notification will be sent.'); - $tokens['ad']['title'] = t('The title of the advertisement.'); - $tokens['ad']['comments'] = t('The number of comments attached to the advertisement.'); - - $tokens['ad']['created_small'] = t('"Small" date format of when the advertisement was created.'); - $tokens['ad']['created_medium'] = t('"Medium" date format of when the advertisement was created.'); - $tokens['ad']['created_large'] = t('"Large" date format of when the advertisement was created.'); - $tokens['ad']['activated_small'] = t('"Small" date format when the advertisement was activated.'); - $tokens['ad']['activated_medium'] = t('"Medium" date format of when the advertisement was activated.'); - $tokens['ad']['activated_large'] = t('"Large" date format of when the advertisement was activated.'); - $tokens['ad']['expired_small'] = t('"Small" date format of when the advertisement was expired.'); - $tokens['ad']['expired_medium'] = t('"Medium" date format of when the advertisement was expired.'); - $tokens['ad']['expired_large'] = t('"Large" date format of when the advertisement was expired.'); - $tokens['ad']['autoactivate_small'] = t('"Small" date format of when the advertisement was automatically activated.'); - $tokens['ad']['autoactivate_medium'] = t('"Medium" date format of when the advertisement was automatically activated.'); - $tokens['ad']['autoactivate_large'] = t('"Large" date format of when the advertisement was automatically activated.'); - $tokens['ad']['autoexpire_small'] = t('"Small" date format of when the advertisement was automatically expired.'); - $tokens['ad']['autoexpire_medium'] = t('"Medium" date format of when the advertisement was automatically expired.'); - $tokens['ad']['autoexpire_large'] = t('"Large" date format of when the advertisement was automatically expired.'); - - $tokens['ad']['max_impressions'] = t('The maximum number of times this advertisement is allowed to be viewed.'); - $tokens['ad']['max_clicks'] = t('The maximum number of times this advertisement is allowed to be clicked.'); - $tokens['ad']['global_impressions'] = t('All time impression statistics'); - $tokens['ad']['global_clicks'] = t('All time click statistics.'); + $tokens['ad']['ad'] = t('The advertisement.'); + $tokens['ad']['aid'] = t('The ID of the advertisement.'); + $tokens['ad']['type'] = t('The type of ad.'); + $tokens['ad']['status'] = t('The status of the ad.'); + $tokens['ad']['url'] = t('The url of the advertisement.'); + $tokens['ad']['redirect'] = t('The redirection url of the advertisement.'); + $tokens['ad']['title'] = t('The title of the advertisement.'); + $tokens['ad']['comments'] = t('The number of comments attached to the advertisement.'); + $tokens['ad']['created_small'] = t('"Small" date format of when the advertisement was created.'); + $tokens['ad']['created_medium'] = t('"Medium" date format of when the advertisement was created.'); + $tokens['ad']['created_large'] = t('"Large" date format of when the advertisement was created.'); + $tokens['ad']['activated_small'] = t('"Small" date format when the advertisement was activated.'); + $tokens['ad']['activated_medium'] = t('"Medium" date format of when the advertisement was activated.'); + $tokens['ad']['activated_large'] = t('"Large" date format of when the advertisement was activated.'); + $tokens['ad']['expired_small'] = t('"Small" date format of when the advertisement was expired.'); + $tokens['ad']['expired_medium'] = t('"Medium" date format of when the advertisement was expired.'); + $tokens['ad']['expired_large'] = t('"Large" date format of when the advertisement was expired.'); + $tokens['ad']['autoactivate_small'] = t('"Small" date format of when the advertisement will be automatically activated.'); + $tokens['ad']['autoactivate_medium'] = t('"Medium" date format of when the advertisement will be automatically activated.'); + $tokens['ad']['autoactivate_large'] = t('"Large" date format of when the advertisement will be automatically activated.'); + $tokens['ad']['autoactivated_small'] = t('"Small" date format of when the advertisement was automatically activated.'); + $tokens['ad']['autoactivated_medium'] = t('"Medium" date format of when the advertisement was automatically activated.'); + $tokens['ad']['autoactivated_large'] = t('"Large" date format of when the advertisement was automatically activated.'); + $tokens['ad']['autoexpire_small'] = t('"Small" date format of when the advertisement will be automatically expired.'); + $tokens['ad']['autoexpire_medium'] = t('"Medium" date format of when the advertisement will be automatically expired.'); + $tokens['ad']['autoexpire_large'] = t('"Large" date format of when the advertisement will be automatically expired.'); + $tokens['ad']['autoexpired_small'] = t('"Small" date format of when the advertisement was automatically expired.'); + $tokens['ad']['autoexpired_medium'] = t('"Medium" date format of when the advertisement was automatically expired.'); + $tokens['ad']['autoexpired_large'] = t('"Large" date format of when the advertisement was automatically expired.'); + $tokens['ad']['max_impressions'] = t('The maximum number of times this advertisement is allowed to be viewed.'); + $tokens['ad']['max_clicks'] = t('The maximum number of times this advertisement is allowed to be clicked.'); + $tokens['ad']['global_impressions'] = t('All time impression statistics'); + $tokens['ad']['global_clicks'] = t('All time click statistics.'); $tokens['ad']['last_year_impressions'] = t('Ad impressions last year.'); - $tokens['ad']['last_year_clicks'] = t('Ad clicks last year.'); - $tokens['ad']['this_year_impressions'] = t('Ad impressions this year.'); - $tokens['ad']['this_year_clicks'] = t('Ad clicks this year.'); - $tokens['ad']['last_month_impressions'] = t('Ad impressions last month.'); + $tokens['ad']['last_year_clicks'] = t('Ad clicks last year.'); + $tokens['ad']['this_year_impressions'] = t('Ad impressions this year.'); + $tokens['ad']['this_year_clicks'] = t('Ad clicks this year.'); + $tokens['ad']['last_month_impressions'] = t('Ad impressions last month.'); $tokens['ad']['last_month_clicks'] = t('Ad clicks this month.'); $tokens['ad']['this_month_impressions'] = t('Ad impressions this month.'); $tokens['ad']['this_month_clicks'] = t('Ad clicks this month.'); - $tokens['ad']['yesterday_impressions'] = t('Ad impressions yesterday.'); - $tokens['ad']['yesterday_clicks'] = t('Ad clicks yesterday.'); - $tokens['ad']['today_impressions'] = t('Ad impressions today.'); - $tokens['ad']['today_clicks'] = t('Ad clicks today.'); - $tokens['ad']['last_hour_impressions'] = t('Ad impressions last hour.'); - $tokens['ad']['last_hour_clicks'] = t('Ad clicks this hour.'); - $tokens['ad']['this_hour_impressions'] = t('Ad impressions this hour.'); - $tokens['ad']['this_hour_clicks'] = t('Ad clicks this hour.'); - } - if ($type == 'ad' || $type == 'all') { - $tokens['Ad owner']['owner_name'] = t('The username of the ad owner.'); - $tokens['Ad owner']['owner_mail'] = t('The email address of the ad owner.'); - $tokens['Ad owner']['owner_uid'] = t('The user ID of the ad owner.'); + $tokens['ad']['yesterday_impressions'] = t('Ad impressions yesterday.'); + $tokens['ad']['yesterday_clicks'] = t('Ad clicks yesterday.'); + $tokens['ad']['today_impressions'] = t('Ad impressions today.'); + $tokens['ad']['today_clicks'] = t('Ad clicks today.'); + $tokens['ad']['last_hour_impressions'] = t('Ad impressions last hour.'); + $tokens['ad']['last_hour_clicks'] = t('Ad clicks this hour.'); + $tokens['ad']['this_hour_impressions'] = t('Ad impressions this hour.'); + $tokens['ad']['this_hour_clicks'] = t('Ad clicks this hour.'); + $tokens['ad']['owner_name'] = t('The username of the ad creator.'); + $tokens['ad']['owner_email'] = t('The email address of the ad creator.'); + $tokens['ad']['owner_uid'] = t('The user ID of the ad creator.'); + if (db_table_exists('ad_owners')) { + $tokens['ad']['all_owner_names'] = t("A comma separated list of usernames of all the ad's owners."); + $tokens['ad']['all_owner_emails'] = t("A comma separated list of email addresses of all the ad's owners."); + $tokens['ad']['all_owner_uids'] = t("A comma separated list of user IDs of all the ad's owners."); + $tokens['ad']['secondary_owner_names'] = t("A comma separated list of usernames of all the ad's owners minus the ad's creator."); + $tokens['ad']['secondary_owner_emails'] = t("A comma separated list of email addresses of all the ad's owners minus the ad's creator."); + $tokens['ad']['secondary_owner_uids'] = t("A comma separated list of user IDs of all the ad's owners minus the ad's creator."); + } } return $tokens; } diff --git a/documentation/CHANGELOG.txt b/documentation/CHANGELOG.txt index 0271b9b76fab9e5b2545e7a2e362c2ab887fadd7..97835fa54d824d6f0efec01aea936f45328586df 100644 --- a/documentation/CHANGELOG.txt +++ b/documentation/CHANGELOG.txt @@ -1,5 +1,16 @@ $Id$ +October 19th, 2009 + - ad_notify.module + o bug #547474: removed module, notifications can now be built with the new + ad_actions module + - ad_actions.module + o bug #547474: new module, defines numerous ad triggers and advanced + actions + - ad.module + o bug #547474: reorder logic so clicking an ad is recorded before the + trigger is called + October 7th, 2009 - ad_module.install o bug #598182: properly return array with update 7 diff --git a/notify/ad_notify.info b/notify/ad_notify.info deleted file mode 100644 index a01d1d7b2e62aea1b1514ffb73020eb700dacefa..0000000000000000000000000000000000000000 --- a/notify/ad_notify.info +++ /dev/null @@ -1,7 +0,0 @@ -; $Id$ -name = Ad notify -package = Ad -dependencies[] = ad_owners -dependencies[] = token -description = Receive email notifications regarding ads. -core = 6.x diff --git a/notify/ad_notify.install b/notify/ad_notify.install deleted file mode 100644 index 7aa333aea19b74731ba7af2fa9d30b480e0a9c43..0000000000000000000000000000000000000000 --- a/notify/ad_notify.install +++ /dev/null @@ -1,190 +0,0 @@ -. - */ - -/** - * Implementation of hook_schema(). - */ -function ad_notify_schema() { - $schema['ad_notify'] = array( - 'description' => 'The ad_notify table stores notifications data such as recepient, message body, event, etc.', - 'fields' => array( - 'notid' => array( - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ), - 'aid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'oid' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'event' => array( - 'type' => 'varchar', - 'length' => '255', - 'not null' => TRUE, - 'default' => '' - ), - 'delay' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'queued' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'sent' => array( - 'type' => 'int', - 'not null' => TRUE, - 'default' => 0, - ), - 'counter' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - 'locked' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - ), - 'expire' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - ), - 'status' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'size' => 'tiny', - 'not null' => TRUE, - 'default' => 0, - ), - 'address' => array( - 'type' => 'varchar', - 'length' => '255', - 'not null' => TRUE, - 'default' => '', - ), - 'subject' => array( - 'type' => 'varchar', - 'length' => '255', - 'not null' => TRUE, - 'default' => '', - ), - 'body' => array( - 'type' => 'text', - 'not null' => FALSE, - ), - 'roles' => array( - 'type' => 'varchar', - 'length' => '255', - 'not null' => TRUE, - 'default' => '', - ), - 'template' => array( - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'default' => 0, - ), - ), - 'primary key' => array('notid'), - 'unique keys' => array( - 'oid' => array('oid', 'event', 'delay'), - ), - 'indexes' => array( - 'delay' => array('delay'), - 'event' => array('event'), - 'oid_2' => array('oid'), - 'queued' => array('queued'), - 'sent' => array('sent'), - 'status' => array('status'), - ), - ); - - return $schema; -} - -/** - * ad_notify module installation. - */ -function ad_notify_install() { - drupal_install_schema('ad_notify'); -} - -/** - * Allow complete uninstallation of the ad_notify module. - */ -function ad_notify_uninstall() { - // Remove tables. - drupal_uninstall_schema('ad_notify'); -} - -/** - * Introduce new roles field to allow per-role notifications. - * Replace nonstandard %sitename with standard %site-name. - * Replace nonstandard %siteurl with standard %site-url. - */ -function ad_notify_update_6001() { - $ret = array(); - db_add_field($ret, 'ad_notify', 'roles', array('type' => 'varchar', 'length' => '255', 'not null' => TRUE, 'default' => '')); - - $ret[] = update_sql('UPDATE {ad_notify} SET subject = REPLACE(subject, "%sitename", "%site-name")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%siteurl", "%site-url")'); - -} - -/** - * Introduce new template field. - */ -function ad_notify_update_6002() { - $ret = array(); - db_add_field($ret, 'ad_notify', 'template', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0)); - return $ret; -} - -/** - * Replace nonstandard %sitename with standard %site-name. - * Replace nonstandard %siteurl with standard %site-url. - * (Repeating update_6001 as there were more instances of these old variables - * in the code.) - */ -function ad_notify_update_6003() { - $ret = array(); - $ret[] = update_sql('UPDATE {ad_notify} SET subject = REPLACE(subject, "%%sitename", "%%site-name")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%sitename", "%%site-name")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%max_views", "%%max_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%global_views", "%%global_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%last_year_views", "%%last_year_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%this_year_views", "%%this_year_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%last_month_views", "%%last_month_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%this_month_views", "%%this_month_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%yesterday_views", "%%yesterday_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%today_views", "%%today_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%last_hour_views", "%%last_hour_impressions")'); - $ret[] = update_sql('UPDATE {ad_notify} SET body = REPLACE(body, "%%this_hour_views", "%%this_hour_impressions")'); - return $ret; -} - diff --git a/notify/ad_notify.module b/notify/ad_notify.module deleted file mode 100644 index 6d617891ccc674daf81ab09a2a139a68fa3b714a..0000000000000000000000000000000000000000 --- a/notify/ad_notify.module +++ /dev/null @@ -1,705 +0,0 @@ -. - */ - -define('AD_NOTIFY_DISABLED', 0); -define('AD_NOTIFY_ENABLED', 1); - -/** - * Implementation of hook_help(). - */ -function ad_notify_help($path, $arg) { - $output = ''; - switch ($path) { - case 'admin/help#ad_notify': - $output = '

'. t('The ad_notify modules provides email notifications for the ad module.') .'

'; - break; - } - return $output; -} - -/** - * Implementation of hook_menu(). - */ -function ad_notify_menu() { - $items = array(); - - $items['admin/content/ad/notifications'] = array( - 'title' => 'Global notifications', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ad_notify_overview_form', '0', '0'), - 'access arguments' => array('administer advertisements'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 6, - ); - $items['admin/content/ad/notifications/%ad_notification/delete'] = array( - 'title' => 'Delete notification', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ad_notify_confirm_delete', '0', '0', 4), - 'access arguments' => array('administer advertisements'), - 'weight' => 2, - ); - - $items['node/%node/notifications'] = array( - 'title' => 'My notifications', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ad_notify_overview_form', 1), - 'access callback' => 'ad_notify_tab_access', - 'access arguments' => array(1), - 'type' => MENU_LOCAL_TASK, - 'weight' => 4, - ); - $items['node/%node/adowners/%user/notifications'] = array( - 'title callback' => 'owner_notifications_title', - 'title arguments' => array(3), - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ad_notify_overview_form', 1, 3), - 'access callback' => 'ad_permission', - 'access arguments' => array(1, 'manage owners'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 4, - ); - $items['node/%node/adowners/%user/notifications/%ad_notification/delete'] = array( - 'title' => 'Delete notification', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ad_notify_confirm_delete', 1, 3, 5), - 'access callback' => 'ad_permission', - 'access arguments' => array(1, array('manage owners', 'manage own notifications')), - 'type' => MENU_CALLBACK, - ); - - return $items; -} - -/** - * Menu item title callback - use the user name. - */ -function owner_notifications_title($account) { - if (isset($account) && is_object($account)) { - return t('!owner\'s notifications', array('!owner' => $account->name)); - } -} - -function ad_notify_tab_access($node) { - if (isset($node->adtype)) { - return (ad_permission($node->nid, 'manage owners') || ad_permission($node->nid, 'manage own notifications')); - } -} - -/** - * Implementation of hook_cron(). - * Send time based notifications and those, who has negative delay. - */ -function ad_notify_cron() { - // Walk through all configured notifications and determine if any need to be - // emailed. - $result = db_query('SELECT n.notid, o.aid, o.uid, n.oid, n.event, n.queued, n.delay, n.sent, n.expire, n.address, n.subject, n.body, n.roles FROM {ad_notify} n INNER JOIN {ad_owners} o ON n.oid = o.oid WHERE n.status = %d', AD_NOTIFY_ENABLED); - while ($notification = db_fetch_object($result)) { - $send = FALSE; - // Handle special case 'regular' notification that is simply a time-based - // status email. - if ($notification->event == 'regular') { - if ((time() - $notification->delay) >= $notification->sent) { - $send = TRUE; - $count = 1; - } - } - // Handle event based notifications based on information stored in the - // ad_statistics table. - else { - if (($event = trim($notification->event, '-')) != $notification->event) { - // Event was prefixed by a -, so time is negative. We can't pull a - // future event out of the statistics table, so we let the module that - // defined this event tell us whether or not it's happened. - $event_count = module_invoke_all('adnotifyapi', $notification->event, $notification); - if (isset($event_count[$notification->event])) { - $send = TRUE; - } - } - - else { - $count = db_result(db_query("SELECT COUNT(aid) AS count FROM {ad_statistics} WHERE aid = %d AND date > %d AND action = '%s'", $notification->aid, date('YmdH', $notification->sent), $notification->event)); - if ($count) { - // See if the notification has been queued long enough to be sent. - if (!$notification->delay || ($notification->queued && - (time() > ($notification->queued + $notification->delay)))) { - $send = TRUE; - } - else if (!$notification->queued) { - // Queue up the notification to send it at a later time. - db_query('UPDATE {ad_notify} SET queued = %d WHERE notid = %d', time(), $notification->notid); - } - } - } - } - - if ($send) { - ad_notify_send_mail($notification, $count); - if ($notification->expire) { - // Update the sent timestamp and counter, and auto-expire the - // notification so it is not sent again. - db_query('UPDATE {ad_notify} SET queued = 0, sent = %d, counter = counter + 1, status = %d WHERE notid = %d', time(), AD_NOTIFY_DISABLED, $notification->notid); - } - else { - // Simply update the sent timestamp and counter. - db_query('UPDATE {ad_notify} SET queued = 0, sent = %d, counter = counter + 1 WHERE notid = %d', time(), $notification->notid); - } - } - } -} - -function ad_notify_mail($key, &$message, $params) { - $language = $message['language']; - $message['subject'] = $params['notification']->subject; - $message['body'] = $params['notification']->body; -} - -/** - * Send email notifications. - */ -function ad_notify_send_mail($notification, $count = 0, $params = array(), $language = NULL) { - $owner = user_load($notification->uid); - - $send = TRUE; - // Send notification only for user who has a permission - if (isset($notification->roles) && !empty($notification->roles)) { - $send = FALSE; - $notification->roles = unserialize($notification->roles); - foreach ($notification->roles as $rid) { - if (isset($owner->roles[$rid])) { - $send = TRUE; - break; - } - } - } - - if ($send) { - $node = node_load($notification->aid); - $node->notification = $notification; - $replacements = array( - 'global' => NULL, - 'ad' => $node, - 'ad_owner' => $owner, - ); - $notification->body = token_replace_multiple($notification->body, $replacements, '%', ''); - $notification->subject = token_replace_multiple($notification->subject, $replacements, '%', ''); - $params['address'] = $notification->address ? $notification->address : $owner->mail; - $params['notification'] = $notification; - return drupal_mail('ad_notify', 'notification', $params['address'], $language, $params); - } -} - -/** - * Implementation of hook_adapi(). - */ -function ad_notify_adapi($op, &$node) { - $output = NULL; - switch ($op) { - case 'statistics_increment': - break; - - case 'permissions': - return array('manage own notifications' => TRUE, 'edit notification email' => TRUE); - break; - } -} - -/** - * Implementation of hook_adnotifyapi(). - */ -function ad_notify_adnotifyapi($op, $arg1 = NULL, $arg2 = NULL) { - switch ($op) { - case 'register': - return array( - 'regular' => t('Email every @when as long as the ad is active.'), - ); - break; - } -} - -/** - * Implementation of hook_adowners(). - */ -function ad_notify_adowners($op, $arg1 = NULL, $arg2 = NULL) { - switch ($op) { - case 'overview': - return l(t('notifications'), 'node/'. $arg1 .'/adowners/'. $arg2 .'/notifications'); - - case 'add': - if ($arg2['aid'] && $arg2['oid']) { - $owner = user_load($arg2['uid']); - - // Clone all template notification for new ad owner. - $result = db_query('SELECT * FROM {ad_notify} WHERE aid = 0 AND oid = 0'); - while ($template = db_fetch_object($result)) { - db_query("INSERT INTO {ad_notify} (aid, oid, event, delay, expire, locked, status, address, subject, body, roles, template) VALUES(%d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', %d)", $arg2['aid'], $arg2['oid'], $template->event, $template->delay, $template->expire, $template->locked, AD_NOTIFY_ENABLED, $owner->mail, $template->subject, $template->body, $template->roles, $template->notid); - } - } - break; - - case 'remove': - if ($arg1) { - $result = db_query('DELETE FROM {ad_notify} WHERE oid = %d', $arg1); - } - break; - } -} - -/** - * Notification overview form. - */ -function ad_notify_overview_form($form_state, $node = NULL, $owner = NULL, $notid = 0) { - global $user; - - if (isset($owner) && !is_object($owner) && $owner == 0) { - $owner = new stdClass(); - $owner->uid = 0; - } - else if (empty($owner)) { - $owner = $user; - } - if (!isset($node) || !is_object($node)) { - $node = new stdClass(); - $node->nid = 0; - } - - $oid = (int)db_result(db_query('SELECT oid FROM {ad_owners} WHERE aid = %d AND uid = %d', $node->nid, $owner->uid)); - $notifications = module_invoke_all('adnotifyapi', 'register'); - - $header = array( - array('data' => t('Last sent'), 'field' => 'sent', 'sort' => 'desc'), - array('data' => t('Notification'), 'field' => 'event'), - array('data' => t('Status'), 'field' => 'status'), - array('data' => t('Action')) - ); - - $sql = "SELECT notid, event, delay, sent, address, status, roles FROM {ad_notify} WHERE oid = %d"; - $sql .= tablesort_sql($header, 'oid DESC, '); - $result = pager_query($sql, 25, 0, NULL, $oid); - - $rows = array(); - while ($notify = db_fetch_object($result)) { - $list_notification = TRUE; - // Check if user has permission to see the notification. - if ($owner->uid && $notify->roles) { - $list_notification = FALSE; - $notify->roles = unserialize($notify->roles); - if (isset($notify->roles) && is_array($notify->roles)) { - foreach ($notify->roles as $rid => $require) { - if ($require && isset($owner->roles[$rid])) { - $list_notification = TRUE; - break; - } - } - } - } - - if ($list_notification) { - $row = array(); - $row[] = $notify->sent ? t('!time ago', array('!time' => format_interval(time() - $notify->sent))) : t('Never'); - $row[] = t($notifications[$notify->event], array('@when' => format_interval($notify->delay))); - $row[] = $notify->status == AD_NOTIFY_ENABLED ? t('enabled') : t('disabled'); - if ($node->nid) { - $row[] = l(t('edit'), 'node/'. $node->nid .'/adowners/'. $owner->uid .'/notifications/' .$notify->notid. '/edit') .' '. l(t('delete'), 'node/'. $node->nid .'/adowners/'. $owner->uid .'/notifications/'. $notify->notid .'/delete'); - } - else if (user_access('administer advertisements')) { - $row[] = l(t('edit'), 'admin/content/ad/notifications/' .$notify->notid. '/edit') .' '. l(t('delete'), 'admin/content/ad/notifications/'. $notify->notid .'/delete'); - } - else { - $row[] = 'N/A'; - } - $rows[] = $row; - } - } - $output = theme('table', $header, $rows); - $output .= theme('pager', NULL, 25, 0); - - $form = array(); - - if ($notid) { - $notification = ad_notification_load($notid); - } - - if (!isset($owner)) { - $help = '

'. t('You can configure one ore more notifications for all advertisements using the drop down menus below. Ad owners have the ability to manually disable individual global notifications.'); - } - else { - $help = '

'. t('You can configure one or more notifications for your advertisement using the drop down menus below. For example, to receive a weekly notification with information about how often your advertisement was viewed and clicked, select the email every @when as long as the ad is active event, and 1 week for when. Or, to receive a reminder that your advertisement will expire in 24 hours select the email @when before the advertisement will expire, and 1 day for when.') .'

'; - $help .= '

'. t('If you schedule a delay between an event and when you are notified and the event happens multiple times, only one notification will be sent. For example, if you create a notification for email 1 day after the advertisement is clicked and the ad is clicked 42 more times in the next 24 hours, you will only receive one email 24 hours after your ad was first clicked that notes that your ad was clicked a total of 43 times in the past 24 hours.') .'

'; - } - $form['create'] = array( - '#type' => 'fieldset', - '#description' => $help, - '#title' => $notid ? t('Edit notification') : t('Create new notification'), - '#collapsible' => TRUE, - '#collapsed' => ($rows == array() || $notid) ? FALSE : TRUE, - ); - - $form['create']['event'] = array( - '#type' => 'select', - '#title' => t('Event'), - '#options' => $notifications, - '#description' => t('Select an event for which you would like to receive a notification.'), - '#default_value' => $notid ? $notification->event : 1, - ); - - $form['create']['delay'] = array( - '#type' => 'select', - '#title' => t('When'), - '#options' => drupal_map_assoc(array(0,3600,10800,21600,43200,86400,259200,432000,604800,1209600,1814400,2419200,4838400,9676800,31536000), 'format_interval'), - '#description' => t('Select a value to replace @when in the event notification you selected above.'), - '#default_value' => $notid ? $notification->delay : 0, - ); - - $form['create']['expire'] = array( - '#type' => 'checkbox', - '#title' => t('One-time'), - '#description' => t('Check this box if this notification email should only be sent one time. If not checked, an email will be sent each time the event happens. If checked, an email will only be sent the first time the event happens, then the notification will be automatically disabled.'), - '#default_value' => $notid ? $notification->expire : 0, - ); - - if (ad_permission($node->nid, 'manage owners') && arg(2) == 'adowners' && $user->uid != arg(3)) { - $form['create']['locked'] = array( - '#type' => 'checkbox', - '#title' => t('Locked'), - '#description' => t('Check this box if you are setting up a notification for someone else, and you don\'t want them to be able to disable the notification. Only users with the manage owners permission for this ad can edit or delete a locked notification.'), - '#default_value' => $notid ? $notification->locked : 0, - ); - } - else { - $form['create']['locked'] = array( - '#type' => 'hidden', - '#value' => $notid ? $notification->locked : 0, - ); - } - - if ($notid) { - $form['create']['mail'] = array( - '#type' => 'fieldset', - '#title' => t('Message'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - } - - if (isset($owner->name)) { - // TODO: Make it possible for admins to modify email address, and even to - // enter multiple email addresses. Wrap this in a special permission, as - // it involves trust to configure notifications to unverified addresses. - $form['create']['mail']['address-display'] = array( - '#type' => 'markup', - '#value' => ''. t('Notify address') .':
'. t('The email will be sent to %address.', array('%address' => is_object($owner) ? $owner->mail : 0)), - '#prefix' => '
', - '#suffix' => '
', - ); - - $form['create']['mail']['address'] = array( - '#type' => 'hidden', - '#value' => is_object($owner) ? $owner->mail : '', - ); - } - else { - $roles = user_roles(TRUE); - $form['create']['roles'] = array( - '#type' => 'checkboxes', - '#title' => t('Notify roles'), - '#description' => t('Select one or more roles to only send this notification to specific roles. Do not select a role to send notification to all roles.'), - '#options' => $roles, - ); - } - - if ($notid) { - $form['create']['mail']['subject'] = array( - '#type' => 'textfield', - '#title' => t('Subject'), - '#required' => TRUE, - '#default_value' => $notification->subject, - ); - - $form['create']['mail']['body'] = array( - '#type' => 'textarea', - '#title' => t('Body'), - '#required' => TRUE, - '#default_value' => $notification->body, - ); - $form['create']['mail']['tokens'] = array( - '#type' => 'fieldset', - '#title' => t('Replacement patterns'), - '#collapsible' => TRUE, - '#collapsed' => TRUE, - ); - $form['create']['mail']['tokens']['list'] = array( - '#value' => theme('token_help', 'ad', '%', ''), - ); - if ($notification->roles) { - $form['create']['roles']['#default_value'] = $notification->roles; - } - } - - $form['create']['oid'] = array( - '#type' => 'hidden', - '#value' => $oid, - ); - - $form['create']['aid'] = array( - '#type' => 'hidden', - '#value' => $node->nid, - ); - - $form['create']['uid'] = array( - '#type' => 'hidden', - '#value' => $owner->uid, - ); - - if ($notid) { - $form['create']['notid'] = array( - '#type' => 'hidden', - '#value' => $notid, - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Save'), - ); - } - else { - $form['create']['submit'] = array( - '#type' => 'submit', - '#value' => t('Create notification'), - ); - } - - if ($rows != array()) { - if (!$notid) { - $form['notifications'] = array( - '#type' => 'fieldset', - '#title' => t('Notifications'), - '#collapsible' => TRUE, - ); - $form['notifications']['current'] = array( - '#type' => 'markup', - '#value' => $output, - ); - } - } - else { - $form['notifications'] = array( - '#type' => 'markup', - '#value' => '

'. t('There are no notifications configured yet.') .'

', - ); - } - - if ($node->nid && isset($owner) && is_object($owner) && isset($owner->name) && $user->name == $owner->name) { - drupal_set_title('My notifications'); - } - else { - drupal_set_title('Notifications'); - } - - return $form; -} - -/** - * Validate ad notifications before saving to database. - */ -function ad_notify_overview_form_validate($form, &$form_state) { - if ($form_state['values']['event'] == 'regular' && $form_state['values']['delay'] < 3600) { - form_set_error('form', t('You are not allowed to schedule a regular notification more frequently than once an hour.')); - } - else if (!isset($form_state['values']['notid'])) { - if (db_result(db_query("SELECT notid FROM {ad_notify} WHERE oid = %d AND event = '%s' AND delay = %d", $form_state['values']['oid'], $form_state['values']['event'], $form_state['values']['delay']))) { - form_set_error('form', t('You have already scheduled that notification.')); - } - } - else if ($form_state['values']['locked'] && !ad_permission($form_state['values']['aid'], 'manage owners')) { - form_set_error('form', t('This notification is locked, you will need to contact the site administrator to edit this notification for you.')); - } -} - -/** - * Save notifications to database. - */ -function ad_notify_overview_form_submit($form, &$form_state) { - global $user; - - // Clean up roles value before saving to DB - if (isset($form_state['values']['roles'])) { - foreach ($form_state['values']['roles'] as $rid => $require) { - if (!$require) { - unset($form_state['values']['roles'][$rid]); - } - } - if (empty($form_state['values']['roles'])) { - $form_state['values']['roles'] = NULL; - } - } - - if (isset($form_state['values']['notid'])) { - db_query("UPDATE {ad_notify} SET aid = %d, oid = %d, event = '%s', delay = %d, expire = %d, locked = %d, status = %d, address = '%s', subject = '%s', body = '%s', roles = '%s' WHERE notid = %d", $form_state['values']['aid'], $form_state['values']['oid'], $form_state['values']['event'], $form_state['values']['delay'], $form_state['values']['expire'], $form_state['values']['locked'], AD_NOTIFY_ENABLED, isset($form_state['values']['address']) ? $form_state['values']['address'] : '', $form_state['values']['subject'], $form_state['values']['body'], isset($form_state['values']['roles']) ? serialize($form_state['values']['roles']) : '', $form_state['values']['notid']); - drupal_set_message('Notification updated.'); - } - else { - // Retrieve the default mail subject and body. - $mail = module_invoke_all('adnotifyapi', 'mail_text', $form_state['values']['event']); - if ($mail == array()) { - // Default message text. - $mail = array( - 'subject' => t('[%site-name ad] %event notification'), - 'body' => t("Hello %owner_name,\n\n This is an automatically generated notification about your advertisement \"%title\" that is being displayed on the %site-name website.\n\n Your advertisement has been viewed %today_impressions times and clicked %today_clicks times today. It was viewed %yesterday_impressions times and clicked %yesterday_clicks times yesterday. It has been viewed %global_impressions times and clicked %global_clicks times since it was activated on %activated_large.\n\n You will receive this %frequency You can view additional statistics about this advertisement or update this notification at the following url:\n %url\n\nRegards,\n The %site-name Team\n\n-\n%site-url"), - ); - } - db_query("INSERT INTO {ad_notify} (aid, oid, event, delay, expire, locked, status, address, subject, body, roles) VALUES(%d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s')", $form_state['values']['aid'], $form_state['values']['oid'], $form_state['values']['event'], $form_state['values']['delay'], $form_state['values']['expire'], $form_state['values']['locked'], AD_NOTIFY_ENABLED, isset($form_state['values']['address']) ? $form_state['values']['address'] : '', $mail['subject'], $mail['body'], isset($form_state['values']['roles']) ? serialize($form_state['values']['roles']) : ''); - - // Clone new template notification for all ad owners. - if (!$form_state['values']['oid']) { - $template_id = db_last_insert_id('ad_notify', 'notid'); - - $result = db_query('SELECT ao.aid, ao.oid, u.mail FROM {ad_owners} ao LEFT JOIN {users} u ON ao.uid = u.uid'); - while ($owner = db_fetch_object($result)) { - // This INSERT can throw "duplicate key" errors in some situations, so just running it silently - @db_query("INSERT INTO {ad_notify} (aid, oid, event, delay, expire, locked, status, address, subject, body, roles, template) VALUES(%d, %d, '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', %d)", $owner->aid, $owner->oid, $form_state['values']['event'], $form_state['values']['delay'], $form_state['values']['expire'], $form_state['values']['locked'], AD_NOTIFY_ENABLED, $owner->mail, $mail['subject'], $mail['body'], isset($form_state['values']['roles']) ? serialize($form_state['values']['roles']) : '', $template_id); - } - } - drupal_set_message('Notification created.'); - } - - if ($form_state['values']['aid'] && $form_state['values']['uid'] && $user->uid != $form_state['values']['uid']) { - $form_state['redirect'] = 'node/'. $form_state['values']['aid'] .'/adowners/'. $form_state['values']['uid'] .'/notifications'; - } - else if ($form_state['values']['aid']) { - $form_state['redirect'] = 'node/'. $form_state['values']['aid'] .'/notifications'; - } - else { - $form_state['redirect'] = 'admin/content/ad/notifications'; - } -} - -/** - * Load a specified notification from the database, return as an object. - */ -function ad_notification_load($notid) { - $notification = db_fetch_object(db_query('SELECT * FROM {ad_notify} WHERE notid = %d', $notid)); - $notification->roles = unserialize($notification->roles); - return $notification; -} - -/** - * Confirm deletion of a specified notification from the database. - */ -function ad_notify_confirm_delete(&$form_state, $node, $owner, $notification) { - global $user; - $form = array(); - - $form['oid'] = array( - '#type' => 'hidden', - '#value' => $notification->oid, - ); - - $form['aid'] = array( - '#type' => 'hidden', - '#value' => isset($node->nid) ? $node->nid : 0, - ); - - $form['uid'] = array( - '#type' => 'hidden', - '#value' => is_object($owner) ? $owner->uid : 0, - ); - - $form['notid'] = array( - '#type' => 'hidden', - '#value' => $notification->notid, - ); - - $form['locked'] = array( - '#type' => 'hidden', - '#value' => $notification->locked, - ); - - $form['event'] = array( - '#type' => 'fieldset', - '#collapsible' => FALSE, - ); - $notifications = module_invoke_all('adnotifyapi', 'register'); - $form['event']['type'] = array( - '#type' => 'markup', - '#value' => t($notifications[$notification->event], array('@when' => format_interval($notification->delay))), - '#prefix' => '
', - '#suffix' => '
', - ); - - if (!$notification->oid) { - $linked = db_result(db_query('SELECT COUNT(*) FROM {ad_notify} WHERE template = %d', $notification->notid)); - if ($linked) { - $form['remove_linked'] = array( - '#type' => 'radios', - '#options' => array( - 1 => t('Completely remove this notification.'), - 0 => t('Remove from further usage, but leave existing notifications.'), - ), - '#default_value' => 1, - ); - } - } - - if (isset($node->nid) && $owner->uid && $user->uid != $owner->uid) { - $path = 'node/'. $node->nid .'/adowners/'. $owner->uid .'/notifications'; - } - else if (isset($node->nid)) { - $path = 'node/'. $node->nid .'/notifications'; - } - else { - $path = 'admin/content/ad/notifications'; - } - - $form = confirm_form( - $form, - 'Are you sure you want to delete this notification?', - $path, - 'This action cannot be undone.', - 'Delete', - 'Cancel' - ); - return $form; -} - - -/** - * Validate that the selected notification can be deleted. - */ -function ad_notify_confirm_delete_validate($form, &$form_state) { - if ($form_state['values']['locked'] && !ad_permission($form_state['values']['aid'], 'manage owners')) { - form_set_error('form', t('This notification is locked, you will need to contact the site administrator to delete this notification for you.')); - } -} - -/** - * Delete a specified notification from the database. - */ -function ad_notify_confirm_delete_submit($form, &$form_state) { - global $user; - db_query('DELETE FROM {ad_notify} WHERE notid = %d', $form_state['values']['notid']); - - if (isset($form_state['values']['remove_linked']) && $form_state['values']['remove_linked']) { - db_query('DELETE FROM {ad_notify} WHERE template = %d', $form_state['values']['notid']); - drupal_set_message('Template and all derived notifications were deleted.'); - } - else { - drupal_set_message('Notification deleted.'); - } - - if ($form_state['values']['aid'] && $form_state['values']['uid'] && $user->uid != $form_state['values']['uid']) { - $form_state['redirect'] = 'node/'. $form_state['values']['aid'] .'/adowners/'. $form_state['values']['uid'] .'/notifications'; - } - else if ($form_state['values']['aid']) { - $form_state['redirect'] = 'node/'. $form_state['values']['aid'] .'/notifications'; - } - else { - $form_state['redirect'] = 'admin/content/ad/notifications'; - } -}