diff --git a/mass_contact.admin.inc b/mass_contact.admin.inc index db22169..a6b10e3 100644 --- a/mass_contact.admin.inc +++ b/mass_contact.admin.inc @@ -25,21 +25,20 @@ function mass_contact_admin_categories() { ->orderBy('category', 'ASC') ->execute(); foreach ($results as $category) { - $roles = array(); - - foreach (explode(',', $category->recipients) as $rid) { - $role = db_select('role', 'r') - ->fields('r', array('name')) - ->condition('rid', $rid) - ->execute() - ->fetchObject(); - $roles[] = ($role->name); + + // Execute all plugins 'mass_contact_admin_categories_callback' functions + // to prepare string for Recipients column. + ctools_include('plugins'); + $plugins = ctools_get_plugins('mass_contact', 'groupping_method'); + $recipients = array(); + foreach ($plugins as $plugin) { + $function = ctools_plugin_get_function($plugin, 'mass_contact_admin_categories_callback'); + $recipients[] = $function(unserialize($category->recipients)); } - $rolenames = implode(', ', $roles); $rows[] = array( $category->category, - $rolenames, + implode('
', array_filter($recipients)), ($category->selected ? t('Yes') : t('No')), l(t('edit'), 'admin/config/system/mass_contact/edit/' . $category->cid), l(t('delete'), 'admin/config/system/mass_contact/delete/' . $category->cid) @@ -98,25 +97,18 @@ function mass_contact_admin_edit($form, $form_state, $cid = NULL) { '#required' => TRUE, ); - // Get a list of all roles, except for the anonymous user role. - $allroles = db_select('role', 'r') - ->fields('r', array('rid', 'name')) - ->condition('rid', 1, '>') - ->orderBy('name', 'ASC') - ->execute(); - foreach ($allroles as $roleobj) { - $onerid = $roleobj->rid; - $onename = $roleobj->name; - $rolesarray[$onerid] = $onename; - } $form['recipients'] = array( - '#type' => 'checkboxes', - '#title' => t('Roles to receive email'), - '#options' => $rolesarray, - '#default_value' => explode(',', $edit['recipients']), - '#description' => t('These roles will be added to the mailing list. Note: if you check "authenticated users", other roles will not be added, as they will receive the email anyway.'), + '#tree' => TRUE, ); + // Add form elements provided by groupping_method plugins. + ctools_include('plugins'); + $plugins = ctools_get_plugins('mass_contact', 'groupping_method'); + foreach ($plugins as $plugin_name => $plugin) { + $function = ctools_plugin_get_function($plugin, 'mass_contact_admin_edit'); + $form['recipients'][$plugin_name] = $function(unserialize($edit['recipients'])); + } + $form['selected_categories'] = array( '#type' => 'fieldset', '#title' => t('Selected categories'), @@ -158,13 +150,21 @@ function mass_contact_admin_edit($form, $form_state, $cid = NULL) { * A keyed array containing the current state of the form. */ function mass_contact_admin_edit_validate($form, &$form_state) { - $recipients = $form_state['values']['recipients']; - foreach ($recipients as $checkr) { - if ($checkr > 1) { - return; + // Execute validation callbacks for each plugin. + ctools_include('plugins'); + $plugins = ctools_get_plugins('mass_contact', 'groupping_method'); + $values_empty = TRUE; + foreach ($plugins as $plugin) { + $function = ctools_plugin_get_function($plugin, 'mass_contact_admin_edit_validate'); + if ($values_empty) { + $values_empty = $function($form, $form_state); } } - form_set_error('recipients', t('You must check one or more recipients.')); + // If all validation callbacks return TRUE that means that user + // hasn't selected any selection rules. + if ($values_empty) { + form_set_error('recipients', t('You must check one or more recipients.')); + } } // End of mass_contact_admin_edit_validate(). /** @@ -183,26 +183,16 @@ function mass_contact_admin_edit_submit($form, &$form_state) { ->execute(); } - // Remove 0s for unselected roles, convert to csv. - $recipients = $form_state['values']['recipients']; - - // If all authenticated users are already added, remove all roles. - if ($recipients[2] == 2) { - foreach ($recipients as $checkr) { - if ($checkr > 2) { - $recipients[$checkr] = 0; - } - } - } - - // Remove roles that were not selected. - foreach ($recipients as $recip) { - if ($recip != 0) { - $newformrec[] = $recip; - } + // Execute submit callbacks for each plugin. Collect recipients. + ctools_include('plugins'); + $plugins = ctools_get_plugins('mass_contact', 'groupping_method'); + $recipients = array(); + foreach ($plugins as $plugin_name => $plugin) { + $function = ctools_plugin_get_function($plugin, 'mass_contact_admin_edit_submit'); + $recipients[$plugin_name] = $function($form, $form_state); } - $form_state['values']['recipients'] = implode(',', $newformrec); + $recipients = serialize($recipients); if (!isset($form_state['values']['reply'])) { $form_state['values']['reply'] = ''; @@ -211,30 +201,21 @@ function mass_contact_admin_edit_submit($form, &$form_state) { $form_state['values']['weight'] = 0; } + $record = array( + 'category' => $form_state['values']['category'], + 'recipients' => $recipients, + 'reply' => $form_state['values']['reply'], + 'weight' => $form_state['values']['weight'], + 'selected' => $form_state['values']['selected'], + ); if (arg(4) == 'add') { - db_insert('mass_contact') - ->fields(array( - 'category' => $form_state['values']['category'], - 'recipients' => $form_state['values']['recipients'], - 'reply' => $form_state['values']['reply'], - 'weight' => $form_state['values']['weight'], - 'selected' => $form_state['values']['selected'], - )) - ->execute(); + drupal_write_record('mass_contact', $record); drupal_set_message(t('Category %category has been added.', array('%category' => $form_state['values']['category']))); watchdog('mass_contact', 'Mass Contact form: category %category added.', array('%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/system/mass_contact')); } else { - db_update('mass_contact') - ->fields(array( - 'category' => $form_state['values']['category'], - 'recipients' => $form_state['values']['recipients'], - 'reply' => $form_state['values']['reply'], - 'weight' => $form_state['values']['weight'], - 'selected' => $form_state['values']['selected'], - )) - ->condition('cid', $form_state['values']['cid']) - ->execute(); + $record['cid'] = $form_state['values']['cid']; + drupal_write_record('mass_contact', $record, array('cid')); drupal_set_message(t('Category %category has been updated.', array('%category' => $form_state['values']['category']))); watchdog('mass_contact', 'Mass Contact form: category %category updated.', array('%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('view'), 'admin/config/system/mass_contact')); } diff --git a/mass_contact.info b/mass_contact.info index 4315c53..9f13c86 100644 --- a/mass_contact.info +++ b/mass_contact.info @@ -6,3 +6,5 @@ core = 7.x php = 4.3.5 package = "Mail" configure = admin/config/system/mass_contact + +dependencies[] = ctools diff --git a/mass_contact.install b/mass_contact.install index 718bd77..24aec0c 100644 --- a/mass_contact.install +++ b/mass_contact.install @@ -29,7 +29,7 @@ function mass_contact_schema() { 'default' => '', ), 'recipients' => array( - 'description' => 'A list of the users to receive the message.', + 'description' => 'Field that has information about users to receive the message.', 'type' => 'text', 'size' => 'big', 'not null' => TRUE, @@ -344,3 +344,14 @@ function mass_contact_update_7100(&$sandbox) { variable_del('mass_contact_html_format_override'); variable_del('mass_contact_nodecc_d_override'); } // End of mass_contact_update_7100(). + +/** + * Move mass_contact.recipients database field to serialized data. + */ +function mass_contact_update_7101(&$sandbox) { + $records = db_query('SELECT cid, recipients FROM {mass_contact}'); + foreach ($records as $record) { + $recipients = serialize(array('mass_contact_role' => explode(',', $record->recipients))); + db_query('UPDATE {mass_contact} SET recipients = :recipients WHERE cid = :cid', array(':cid' => $record->cid, ':recipients' => $recipients)); + } +} \ No newline at end of file diff --git a/mass_contact.module b/mass_contact.module index 57edbbf..9276d15 100644 --- a/mass_contact.module +++ b/mass_contact.module @@ -359,3 +359,22 @@ function mass_contact_mail($key, &$message, $params) { $message['body'][] = $params['body']; } } // End of mass_contact_mail(). + +/** + * Implements hook_ctools_plugin_type(). + */ +function mass_contact_ctools_plugin_type() { + return array( + 'groupping_method' => array(), + ); +} + +/** + * Implements hook_ctools_plugin_directory(). + */ +function mass_contact_ctools_plugin_directory($module, $plugin) { + if (($module == 'mass_contact') && ($plugin == 'groupping_method')) { + return 'plugins'; + } +} + diff --git a/mass_contact.page.inc b/mass_contact.page.inc index 0d30dab..a30dec5 100644 --- a/mass_contact.page.inc +++ b/mass_contact.page.inc @@ -1017,10 +1017,23 @@ function _mass_contact_create_recipient_list($category, $respect_opt_outs) { $opt_out_setting = variable_get('mass_contact_optout_d', 0); global $user; - // Get the user IDs for all the users in all the roles included in the - // category. - $query = "SELECT u.name, u.mail, u.data FROM {users} u LEFT JOIN {users_roles} ur ON u.uid = ur.uid WHERE ur.rid IN(:ur_rids) AND u.status <> 0"; - $results = db_query($query, array(':ur_rids' => $category->recipients)); + // Collect user id's by executing all plugin's + // create_recipient_list_callback functions. + ctools_include('plugins'); + $plugins = ctools_get_plugins('mass_contact', 'groupping_method'); + $user_uids = array(); + foreach ($plugins as $plugin) { + $function = ctools_plugin_get_function($plugin, 'create_recipient_list_callback'); + $user_uids += $function(unserialize($category->recipients)); + } + + $uids = array_unique(array_values($user_uids)); + if (empty($uids)) { + return array(); + } + + $query = "SELECT u.name, u.mail, u.data FROM {users} u WHERE uid IN (:uids) AND u.status <> 0"; + $results = db_query($query, array(':uids' => $uids)); foreach ($results as $account) { $account_data = unserialize($account->data); diff --git a/plugins/mass_contact_role.inc b/plugins/mass_contact_role.inc new file mode 100644 index 0000000..eff73bb --- /dev/null +++ b/plugins/mass_contact_role.inc @@ -0,0 +1,134 @@ + 'mass_contact_role_create_recipient_list', + + // Function to prepare Category description for Recipients column + // on categories list admin page. + 'mass_contact_admin_categories_callback' => 'mass_contact_role_admin_categories', + + // Next three callbacks used to maintain form of add/edit category. + 'mass_contact_admin_edit' => 'mass_contact_role_admin_edit', + 'mass_contact_admin_edit_validate' => 'mass_contact_role_admin_edit_validate', + 'mass_contact_admin_edit_submit' => 'mass_contact_role_admin_edit_submit', +); + +/** + * Callback to retrieve users by roles. + * + * Get the user IDs for all the users in all the roles included in the + * category. + */ +function mass_contact_role_create_recipient_list($recipients) { + $groups = array(); + if (isset($recipients['mass_contact_role'])) { + $groups = $recipients['mass_contact_role']; + } + + $query = "SELECT u.uid FROM {users} u LEFT JOIN {users_roles} ur ON u.uid = ur.uid WHERE ur.rid IN (:ur_rids)"; + $result = db_query($query, array(':ur_rids' => $groups))->fetchAllAssoc('uid', PDO::FETCH_ASSOC); + $uids = array(); + foreach ($result as $record) { + $uids[] = $record['uid']; + } + return $uids; +} + +/** + * Callback to prepare role names for admin/config/system/mass_contact page + * column Recipients. + */ +function mass_contact_role_admin_categories($recipients) { + $groups = array(); + if (isset($recipients['mass_contact_role']) && !empty($recipients['mass_contact_role'])) { + $groups = $recipients['mass_contact_role']; + } + else { + return; + } + + $result = db_query('SELECT name FROM {role} WHERE rid IN (:rids)', array(':rids' => $groups)); + + $role_names = array(); + foreach ($result as $record) { + $role_names[] = $record->name; + } + + return t('Roles: %roles', array('%roles' => implode(', ', $role_names))); +} + +/** + * Form element for Category add/edit page. + * + * @param array $roles + * @return type + */ +function mass_contact_role_admin_edit($recipients) { + $roles = array(); + if (isset($recipients['mass_contact_role']) && !empty($recipients['mass_contact_role'])) { + $roles = $recipients['mass_contact_role']; + } + + // Get a list of all roles, except for the anonymous user role. + $allroles = db_select('role', 'r') + ->fields('r', array('rid', 'name')) + ->condition('rid', 1, '>') + ->orderBy('name', 'ASC') + ->execute(); + foreach ($allroles as $roleobj) { + $onerid = $roleobj->rid; + $onename = $roleobj->name; + $rolesarray[$onerid] = $onename; + } + $form_element = array( + '#type' => 'checkboxes', + '#title' => t('Roles to receive email'), + '#options' => $rolesarray, + '#default_value' => $roles, + '#description' => t('These roles will be added to the mailing list. Note: if you check "authenticated users", other roles will not be added, as they will receive the email anyway.'), + ); + + return $form_element; +} + +/** + * Add/edit validation callback. Set form error and return whether selection + * is empty or not. + * + * @param array $form + * @param array $form_state + * @return bool + */ +function mass_contact_role_admin_edit_validate($form, &$form_state) { + $selected_roles = array_filter($form_state['values']['recipients']['mass_contact_role']); + return empty($selected_roles); +} + +/** + * Add/edit form submit callback. Should return piece of data that will be + * saved to mass_contact table in recepients field. + * + * @param type $form + * @param type $form_state + */ +function mass_contact_role_admin_edit_submit($form, &$form_state) { + $roles = $form_state['values']['recipients']['mass_contact_role']; + + // If all authenticated users are already added, + // simply return authenticated users rid. + if ($roles[2] == 2) { + return array(2); + } + // Remove roles that were not selected. + $roles = array_filter($roles); + + return $roles; +} diff --git a/plugins/mass_contact_taxonomy.inc b/plugins/mass_contact_taxonomy.inc new file mode 100644 index 0000000..534dfe3 --- /dev/null +++ b/plugins/mass_contact_taxonomy.inc @@ -0,0 +1,145 @@ + 'mass_contact_taxonomy_create_recipient_list', + 'mass_contact_admin_categories_callback' => 'mass_contact_taxonomy_admin_categories', + 'mass_contact_admin_edit' => 'mass_contact_taxonomy_admin_edit', + 'mass_contact_admin_edit_validate' => 'mass_contact_taxonomy_admin_edit_validate', + 'mass_contact_admin_edit_submit' => 'mass_contact_taxonomy_admin_edit_submit', +); + +/** + * Callback to retrieve users by taxonomy terms. + * + * Get the user IDs for all the users that have specified taxonomy terms + * attached to user object. + */ +function mass_contact_taxonomy_create_recipient_list($recipients) { + $tids = array(); + if (!isset($recipients['mass_contact_taxonomy']) || empty($recipients['mass_contact_taxonomy'])) { + return array(); + } + $tids = $recipients['mass_contact_taxonomy']; + + // Query to select users by term. + // Check all fields of user entity and if field is taxonomy term reference, + // add condition. + $query = new EntityFieldQuery(); + $user_fields = field_info_instances('user'); + foreach ($user_fields['user'] as $user_field_instance) { + $field = field_info_field($user_field_instance['field_name']); + if ($field['module'] == 'taxonomy') { + $query->fieldCondition($field['field_name'], 'tid', $tids, 'IN'); + } + } + $result = $query->execute(); + // Collect uids. + $uids = array(); + if (isset($result['user'])) { + $uids = array_keys($result['user']); + } + + return $uids; +} + +/** + * Callback to prepare taxonomy term names for admin/config/system/mass_contact + * page column Recipients. + */ +function mass_contact_taxonomy_admin_categories($recipients) { + $tids = array(); + if (!isset($recipients['mass_contact_taxonomy']) || empty($recipients['mass_contact_taxonomy'])) { + return; + } + $tids = $recipients['mass_contact_taxonomy']; + + $terms = taxonomy_term_load_multiple($tids); + if (empty($terms)) { + return; + } + + $term_names = array(); + foreach ($terms as $term) { + $term_names[] = $term->name; + } + + return t('Taxonomy terms: %terms', array('%terms' => implode(', ', $term_names))); +} + +/** + * Form element for Category add/edit page. + * + * @param array $terms + * @return type + */ +function mass_contact_taxonomy_admin_edit($recipients) { + // Prepare array of field_name => vocabulary of taxonomy fields. + $user_fields = field_info_instances('user'); + $taxonomy_fields = array(); + foreach ($user_fields['user'] as $user_field_instance) { + $field = field_info_field($user_field_instance['field_name']); + if ($field['module'] == 'taxonomy') { + $taxonomy_fields[$field['field_name']] = $field['settings']['allowed_values'][0]['vocabulary']; + } + } + + $form_element = array(); + foreach ($taxonomy_fields as $field_name => $vocabulary_name) { + $vocabulary = taxonomy_vocabulary_machine_name_load($vocabulary_name); + $terms = taxonomy_get_tree($vocabulary->vid); + $options = array(); + foreach ($terms as $term) { + $options[$term->tid] = check_plain($term->name); + } + $default_value = array(); + if (isset($recipients['mass_contact_taxonomy'])) { + $default_value = $recipients['mass_contact_taxonomy']; + } + $form_element[$field_name] = array( + '#type' => 'checkboxes', + '#title' => t('Taxonomy vocabulary: %vocabulary', array('%vocabulary' => $vocabulary->name)), + '#options' => $options, + '#default_value' => $default_value, + ); + } + return $form_element; +} + +/** + * Add/edit validation callback. Set form error and return whether selection + * is empty or not. + * + * @param array $form + * @param array $form_state + * @return bool + */ +function mass_contact_taxonomy_admin_edit_validate($form, &$form_state) { + foreach ($form_state['values']['recipients']['mass_contact_taxonomy'] as $term_values) { + $term_values_filtered = array_filter($term_values); + if (!empty($term_values_filtered)) { + return FALSE; + } + } + return TRUE; +} + +/** + * Add/edit form submit callback. Should return piece of data that will be + * saved to mass_contact table in recepients field. + * + * @param type $form + * @param type $form_state + */ +function mass_contact_taxonomy_admin_edit_submit($form, &$form_state) { + $terms = array(); + foreach ($form_state['values']['recipients']['mass_contact_taxonomy'] as $term_values) { + $terms += array_filter($term_values); + } + return $terms; +} \ No newline at end of file