makemeeting.module in Make Meeting Scheduler 7
Same filename and directory in other branches
Make Meeting module
File
makemeeting.moduleView source
<?php
/**
* @file
*
* Make Meeting module
*
*/
/**
* hook_theme implementation
*/
function makemeeting_theme() {
return array(
'makemeeting_calendarselector' => array(
'render element' => 'element',
'template' => 'makemeeting-calendarselector',
),
'makemeeting_choices' => array(
'render element' => 'element',
'template' => 'makemeeting-choices',
),
'makemeeting_pollpanel' => array(
'variables' => array(
'node' => NULL,
),
'template' => 'makemeeting-pollpanel',
),
'makemeeting_poll_admin' => array(
'variables' => array(
'node' => NULL,
'admin_form' => NULL,
),
'template' => 'makemeeting-poll-admin',
),
);
}
/**
* Preprocess for makemeeting choices
*
* @param $vars
*/
function makemeeting_preprocess_makemeeting_choices(&$vars) {
global $user;
// Get the element
$element = $vars['element'];
$vars['options'] = array();
// Get the options data
foreach ($element['#attributes']['days_and_options'] as $days => $options_array) {
// Day of the option
$option = array(
'day' => check_plain(substr($days, strpos($days, "_") + 1)),
);
// Options of the day
$options = array();
foreach ($options_array as $o) {
$start = strpos($o, "_");
$options[substr($o, 0, $start)] = check_plain(substr($o, $start + 1));
}
$option['options'] = $options;
$vars['options'][] = $option;
}
$votes = $votes_stats = array();
foreach ($element['#attributes']['answers'] as $username => $vote) {
$votes[$username] = array();
foreach ($vars['options'] as $option) {
foreach ($option['options'] as $id => $data) {
// Initialize statistics
if (!isset($votes_stats[$id])) {
$votes_stats[$id] = array();
}
// Initialize vote
if (!isset($vote[$id])) {
$vote[$id] = 0;
}
// Analyse vote
switch ($vote[$id]) {
case 0:
$votes[$username][$id] = 'no';
break;
case 1:
$votes[$username][$id] = 'ok';
break;
case 2:
$votes[$username][$id] = 'maybe';
}
// Update stats
if (isset($votes_stats[$id][$vote[$id]])) {
$votes_stats[$id][$vote[$id]]++;
}
else {
$votes_stats[$id][$vote[$id]] = 1;
}
}
}
}
$vars['total_count'] = count($votes) * count(reset($votes));
$vars['votes'] = $votes;
foreach ($votes_stats as &$stats) {
$yes = isset($stats[1]) ? $stats[1] : 0;
$no = isset($stats[0]) ? $stats[0] : 0;
$maybe = isset($stats[2]) ? $stats[2] : 0;
if ($element['#attributes']['maybe_option'] == 1) {
$style = $no > $yes + $maybe ? "red" : ($yes > $no + $maybe ? "green" : "yellow");
}
else {
$style = $yes > $no ? "green" : ($yes == $no ? "yellow" : "red");
}
$stats = array(
'style' => $style,
'yes' => $yes,
'no' => $no,
'maybe' => $maybe,
);
}
$vars['votes_stats'] = $votes_stats;
$vars['choices'] = array(
'no' => t('No'),
'ok' => t('Yes'),
'maybe' => t('Maybe'),
);
$element = array(
'#type' => 'textfield',
'#name' => 'your_name',
'#attributes' => array(),
'#value' => isset($element['#value']['name']) ? $element['#value']['name'] : $user->name,
'#size' => 20,
);
$vars['input'] = drupal_render($element);
$vars['input_type'] = 'radio';
if (isset($element['#attributes']['multiple_allowed']) && $element['#attributes']['multiple_allowed'] == 0) {
$vars['input_type'] = 'checkbox';
}
}
/**
* hook_menu implementation
*/
function makemeeting_menu() {
$items['admin/config/content/makemeeting'] = array(
'title' => 'MakeMeeting',
'description' => 'Main admin panel for Make Meeting module',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'makemeeting_admin_form',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'makemeeting.admin.inc',
);
$items['makemeeting'] = array(
'title' => 'Info page',
'description' => 'The module information page',
'page callback' => 'makemeeting_infopage',
'access arguments' => array(
'view makemeeting poll',
),
'file' => 'makemeeting.pages.inc',
'type' => MENU_CALLBACK,
);
$items['makemeeting/%'] = array(
'title' => 'Question page',
'description' => 'Make a vote on the question',
'page callback' => 'makemeeting_show_pollpage',
'page arguments' => array(
1,
),
'access arguments' => array(
'view makemeeting poll',
),
'file' => 'makemeeting.pages.inc',
'type' => MENU_CALLBACK,
);
$items['makemeeting/%/log'] = array(
'title' => 'Log page',
'description' => 'Show logs',
'page callback' => 'makemeeting_logpage',
'page arguments' => array(
1,
),
'access arguments' => array(
'view makemeeting poll',
),
'file' => 'makemeeting.pages.inc',
'type' => MENU_CALLBACK,
);
$items['makemeeting/%/sendfw'] = array(
'title' => 'Send forward',
'description' => 'Send the url to your friends',
'page callback' => 'makemeeting_sendfw',
'page arguments' => array(
1,
),
'access arguments' => array(
'view makemeeting poll',
),
'file' => 'makemeeting.pages.inc',
'type' => MENU_CALLBACK,
);
$items['user/%user/makemeeting'] = array(
'title' => 'My polls',
'description' => 'List of my polls',
'page callback' => 'makemeeting_mypage',
'access callback' => '_makemeeting_access_userpolls',
'access arguments' => array(
1,
),
'file' => 'makemeeting.pages.inc',
'type' => MENU_SUGGESTED_ITEM,
);
return $items;
}
/**
* hook_perm implementation
*/
function makemeeting_permission() {
return array(
'access all polls' => array(
'title' => t("Access all makemeeting polls"),
'restrict access' => TRUE,
),
'access own polls' => array(
'title' => t("Access own makemeeting polls"),
),
'view makemeeting poll' => array(
'title' => t("Access makemeeting polls"),
),
);
}
function _makemeeting_access_userpolls($account) {
global $user;
return user_access('access all polls') || $user->uid == $account->uid && user_access('access own polls');
}
/**
* hook_elements implementation
*
* Custom form elements: calendarselector and pollpanel
*/
function makemeeting_element_info() {
$types['makemeeting_choices'] = array(
'#input' => TRUE,
'#process' => array(
'_makemeeting_choices_process',
),
'#attributes' => array(
'dates_and_options' => array(),
'answers' => NULL,
'multiple_allowed' => NULL,
'maybe_option' => NULL,
'secure' => NULL,
),
'#theme' => 'makemeeting_choices',
'#value_callback' => 'form_type_makemeeting_choices_value',
);
$types['makemeeting_calendarselector'] = array(
'#input' => TRUE,
'#process' => array(
'_makemeeting_calendarselector_process',
),
'#attributes' => array(
'selected_dates_and_options' => array(),
),
'#theme' => 'makemeeting_calendarselector',
'#value_callback' => 'form_type_makemeeting_calendarselector_value',
);
return $types;
}
/**
* Process the makemeeting_calendarselector element before rendering
*
* @param $element
*/
function _makemeeting_calendarselector_process($element) {
// Adding javascript locales and settings
$days = array(
t('Su'),
t('Mon'),
t('Tue'),
t('Wed'),
t('Th'),
t('Fr'),
t('Sat'),
);
$months = array(
t('January'),
t('Febuary'),
t('March'),
t('April'),
t('May'),
t('June'),
t('July'),
t('August'),
t('September'),
t('October'),
t('November'),
t('December'),
);
$element['#attributes']['months'] = $months;
$nav_links = array(
'p' => '«',
'n' => '»',
't' => t('Today'),
'b' => t('Add date to list'),
);
drupal_add_js(array(
'makemeeting' => array(
'days' => $days,
'months' => $months,
'navLinks' => $nav_links,
),
), 'setting');
drupal_add_js(drupal_get_path('module', 'makemeeting') . '/jcalendar-source.js');
drupal_add_css(drupal_get_path('module', 'makemeeting') . '/jcalendar.css');
return $element;
}
/**
* Fetch the values from the makemeeting_calendarselector form element
*
* @param $element
* @param bool $input
* @param null $form_state
*/
function form_type_makemeeting_calendarselector_value(&$element, $input = FALSE, $form_state = NULL) {
if (!empty($form_state['input'])) {
// collecting the selected date and options from the posted form
// and put it into the calendar element's 'value' field
$day_options = array();
$days = array();
// using preg_match to indentifing and collecting dynamicly created input fields
foreach ($form_state['input'] as $k => $v) {
preg_match("/(day_)(\\d+)/i", $k, $matches_day);
if (!empty($matches_day)) {
$days[] = $v;
$day_options[$v] = array();
}
}
foreach ($form_state['input'] as $k => $v) {
preg_match("/(day_option_)(\\d+)(_)(\\d+)/i", $k, $matches_options);
if (!empty($matches_options)) {
$field_name = $form_state['input']['day_' . $matches_options[2]];
$day_options[$field_name][] = $v;
}
}
return $day_options;
}
}
/**
* Process the makemeeting_choices element before rendering
*
* @param $element
*/
function _makemeeting_choices_process($element) {
// Adding custom css
drupal_add_css(drupal_get_path('module', 'makemeeting') . '/pollpanel.css');
return $element;
}
/**
* Fetch the values from the makemeeting_choices form element
*
* @param $element
* @param bool $input
* @param null $form_state
*/
function form_type_makemeeting_choices_value(&$element, $input = FALSE, $form_state = NULL) {
if (!empty($form_state['input'])) {
// processing posted datas
if ($element['#attributes']['maybe_option'] == 1 || $element['#attributes']['multiple_allowed'] == 1) {
$alter_ids = array();
// collects the alter_ids and the vote values
foreach ($form_state['input'] as $k => $v) {
if (preg_match("/option_(\\d+)/", $k, $matches)) {
$alter_ids[$matches[1]] = $v;
}
}
}
else {
$alter_ids = array();
// collect only the alter_ids
foreach ($form_state['input'] as $k => $v) {
if (preg_match("/option_/i", $k)) {
$alter_ids[] = $v;
}
}
}
return array(
'alter_ids' => $alter_ids,
'name' => $form_state['input']['your_name'],
);
}
return $element;
}
/**
* Implementation of hook_form_alter()
*/
function makemeeting_form_alter(&$form, $form_state, $form_id) {
// Remove preview button from makemeeting node form
if ($form_id == 'makemeeting_node_form') {
unset($form['actions']['preview']);
}
}
/**
* Implementation of hook_node_info()
*/
function makemeeting_node_info() {
return array(
'makemeeting' => array(
'name' => t('Event'),
'base' => 'node_makemeeting',
'description' => t("Create a poll for a business lunch, a meeting or a movie night."),
'has_title' => TRUE,
'title_label' => t('Your question'),
'has_body' => TRUE,
'body_label' => t('Add some description'),
),
);
}
/**
* Implementation of hook_node_access()
*/
function makemeeting_node_access($node, $op, $account) {
if (is_object($node) && $node->type == 'makemeeting') {
switch ($op) {
// disabling the edit page: we don't give access to any user
// reason: we're using custom urls to update the nodes, and only
// the owner of the poll has the custom admin url
case 'update':
return FALSE;
case 'delete':
return user_access('delete poll', $account) && $account->uid == $node->uid;
}
}
return FALSE;
}
/**
* Implementation of hook_node_form()
*/
function node_makemeeting_form(&$node) {
global $user;
$type = node_type_get_type($node);
if ($type->has_title) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -5,
);
}
if ($type->has_body) {
$form['body'] = array(
'#type' => 'textarea',
'#title' => check_plain($type->body_label),
'#default_value' => isset($node->body) ? $node->body : '',
'#rows' => 5,
);
}
if (isset($node->nid) && $node->uid == 0 || $user->uid == 0) {
$form['anonym'] = array(
'#type' => 'fieldset',
'#title' => t('Add your name and email'),
'#tree' => TRUE,
);
$form['anonym']['user_name'] = array(
'#type' => 'textfield',
'#title' => t('Your name'),
'#maxlength' => 100,
'#description' => t('This is optional.'),
);
$form['anonym']['user_email'] = array(
'#type' => 'textfield',
'#title' => t('Your e-mail'),
'#description' => t('This is optional, too. But if you add, we can send e-mail notification after every valid vote.'),
'#maxlength' => 100,
);
}
// transform the days_and_options array to the structure required by the theme funcion
if (isset($node->days_and_options) && is_array($node->days_and_options)) {
$attributes = array();
$i = 1;
foreach ($node->days_and_options as $days => $options_array) {
$start_day = strpos($days, "_");
$day_str = substr($days, $start_day + 1);
$attributes['date_' . $i] = $day_str;
foreach ($options_array as $k => $option) {
$start_option = strpos($option, "_");
$option_str = substr($option, $start_option + 1);
$attributes['option_' . $i][] = $option_str;
}
$i++;
}
}
else {
// initializing data for dates and options (options are empty)
$attributes = array(
'date_1' => date("Y-m-d"),
'option_1' => array(
"",
"",
),
);
}
$form['calendar'] = array(
'#type' => 'makemeeting_calendarselector',
'#title' => t('Calendar test'),
'#description' => t('Use the calendar above to select the days, then add the options for the days. For example select the day of tomorrow and add "AM", "PM" as options. You can use only upcoming days.'),
'#attributes' => array(
'selected_dates_and_options' => $attributes,
),
);
$form['poll_options'] = array(
'#type' => 'fieldset',
'#title' => t('Scheduler options'),
'#tree' => TRUE,
);
$form['poll_options']['secure'] = array(
'#type' => 'radios',
'#title' => t('Show previous votes'),
'#description' => t("Deny new voters to see the previous votes."),
'#options' => array(
'0' => t('Yes'),
'1' => t('No'),
),
'#default_value' => isset($node->secure) ? $node->secure : 0,
);
$form['poll_options']['maybe_option'] = array(
'#type' => 'radios',
'#title' => t('Maybe option'),
'#description' => t("Voters can select maybe as answer too."),
'#options' => array(
'0' => t('Disabled'),
'1' => t('Enabled'),
),
'#default_value' => isset($node->maybe_option) ? $node->maybe_option : 0,
);
$form['poll_options']['multiple_allowed'] = array(
'#type' => 'radios',
'#title' => t('Multiple option is selectable per answers.'),
'#options' => array(
'0' => t('Disabled'),
'1' => t('Enabled'),
),
'#default_value' => isset($node->multiple_allowed) ? $node->multiple_allowed : 0,
);
$form['email'] = array(
'#type' => 'fieldset',
'#title' => t('E-mail notification'),
);
$form['email']['email_notification'] = array(
'#type' => 'radios',
'#title' => t('Send me an e-mail after every valid vote'),
'#options' => array(
'1' => t('Yes'),
'0' => t('No'),
),
'#default_value' => isset($node->email_notification) ? $node->email_notification : 1,
);
return $form;
}
/**
* Implementation of hook_node_insert()
*/
function node_makemeeting_insert($node) {
global $user;
// Poll_head
// generate the poll urls and save them
$poll_url = _makemeeting_generate_url('url', 10);
$admin_url = _makemeeting_generate_url('admin_url', 25);
// save the poll options
$values = array(
'nid' => $node->nid,
'vid' => $node->vid,
'uid' => $user->uid,
'email_notification' => $node->email_notification,
'poll_type' => 1,
'url' => $poll_url,
'admin_url' => $admin_url,
'multiple_allowed' => $node->poll_options['multiple_allowed'],
'secure' => $node->poll_options['secure'],
'maybe_option' => $node->poll_options['maybe_option'],
);
$query = db_insert('makemeeting_poll_heads')
->fields($values);
if (isset($node->anonym)) {
$query
->fields(array(
'anonym_name' => $node->anonym['user_name'],
'anonym_email' => $node->anonym['user_email'],
));
}
$query
->execute();
// we get the selected dates and options in $node->calendar
// collecting the form datas in makemeeting_calendarselector_process()
if (isset($node->calendar)) {
foreach ($node->calendar as $day => $options_array) {
$values = array(
'nid' => $node->nid,
'answer_text' => $day,
'type' => 1,
);
$answer_id = db_insert('makemeeting_poll_rows')
->fields($values)
->execute();
foreach ($options_array as $option) {
$values = array(
'answer_id' => $answer_id,
'alter_text' => $option,
);
db_insert('makemeeting_poll_alters')
->fields($values)
->execute();
}
}
}
// setting the output texts: the url of the poll page and the admin page
drupal_set_message(l(t("Poll page URL: !url", array(
"!url" => url('makemeeting/' . $poll_url, array(
"absolute" => TRUE,
)),
)), "makemeeting/" . $poll_url));
drupal_set_message(l(t("Admin page URL: !url", array(
"!url" => url('makemeeting/' . $admin_url, array(
"absolute" => TRUE,
)),
)), "makemeeting/" . $admin_url));
// send an email message
if ($node->email_notification) {
$mail = $name = "";
if ($user->uid > 0) {
$mail = $user->mail;
}
elseif (valid_email_address($node->anonym['user_email'])) {
$mail = $node->anonym['user_email'];
}
if ($mail != "") {
if ($user->uid > 0) {
$name = $user->name;
}
elseif (isset($node->anonym['user_name'])) {
$name = $node->anonym['user_name'];
}
$params = array(
"name" => $name,
"poll_url" => $poll_url,
"admin_url" => $admin_url,
);
drupal_mail('makemeeting', 'create_new_poll', $mail, language_default(), $params);
}
}
drupal_goto('makemeeting/' . $poll_url);
}
/**
* Implementation of hook_node_delete()
*/
function node_makemeeting_delete($node) {
$res = db_query("SELECT answer_id FROM {makemeeting_poll_rows} WHERE nid = :nid", array(
':nid' => $node->nid,
));
foreach ($res as $answer_id_row) {
db_query("DELETE FROM {makemeeting_poll_alters} WHERE answer_id = :answer_id", array(
':answer_id' => $answer_id_row->answer_id,
));
}
db_query("DELETE FROM {makemeeting_poll_rows} WHERE nid = :nid", array(
':nid' => $node->nid,
));
db_query("DELETE FROM {makemeeting_poll_heads} WHERE nid = :nid", array(
':nid' => $node->nid,
));
db_query("DELETE FROM {makemeeting_poll_votes} WHERE poll_id = :poll_id", array(
':poll_id' => $node->nid,
));
}
/**
* Implementation of hook_node_load()
*/
function node_makemeeting_load(&$nodes) {
foreach ($nodes as &$node) {
// load the poll days and options
$days_and_options = array();
$poll_head = db_query("SELECT * FROM {makemeeting_poll_heads} WHERE nid = :nid", array(
':nid' => $node->nid,
))
->fetchAssoc();
$answer_result = db_query("SELECT * FROM {makemeeting_poll_rows} WHERE nid = :nid ORDER BY answer_id", array(
':nid' => $node->nid,
));
foreach ($answer_result as $answer_row) {
$options_result = db_query("SELECT * FROM {makemeeting_poll_alters} WHERE answer_id = :answer_id ORDER BY alter_id", array(
':answer_id' => $answer_row->answer_id,
));
foreach ($options_result as $options_row) {
$days_and_options[$answer_row->answer_id . "_" . $answer_row->answer_text][] = $options_row->alter_id . "_" . $options_row->alter_text;
}
}
// load answers
$answers = array();
$votes_result = db_query("SELECT * FROM {makemeeting_poll_votes} WHERE poll_id = :poll_id ORDER BY dt", array(
':poll_id' => $node->nid,
));
foreach ($votes_result as $votes_row) {
$answers[$votes_row->user_name][$votes_row->answer_id] = $votes_row->answer_value;
}
$node->days_and_options = $days_and_options;
$node->answers = $answers;
$node->poll_type = $poll_head['poll_type'];
$node->poll_url = $poll_head['url'];
$node->poll_admin_url = $poll_head['admin_url'];
$node->anonym_name = $poll_head['anonym_name'];
$node->anonym_email = $poll_head['anonym_email'];
$node->email_notification = $poll_head['email_notification'];
$node->secure = $poll_head['secure'];
$node->multiple_allowed = $poll_head['multiple_allowed'];
$node->maybe_option = $poll_head['maybe_option'];
}
}
/**
* Implementation of hook_node_view()
*/
function node_makemeeting_view($node, $view_mode) {
// We hide the poll body from the list site/node if it is not direct access
// @TODO take this to another level, maybe hook_node_access
if (!preg_match("/" . $node->poll_url . "/i", request_uri())) {
$node->content = array();
}
else {
$node->content['poll_form'] = drupal_get_form('makemeeting_pollpanel_form', $node);
$node->content['poll_panel'] = array(
"#markup" => theme('makemeeting_pollpanel', array(
'node' => $node,
)),
);
}
return $node;
}
/**
* The poll panel form
*/
function makemeeting_pollpanel_form($form, &$form_state, $node) {
$form['add_your_vote'] = array(
'#type' => 'fieldset',
'#title' => t('Add your vote'),
'#tree' => TRUE,
);
$attributes = array(
'days_and_options' => isset($node->days_and_options) ? $node->days_and_options : NULL,
'answers' => isset($node->answers) ? $node->answers : NULL,
'multiple_allowed' => isset($node->multiple_allowed) ? $node->multiple_allowed : NULL,
'maybe_option' => isset($node->maybe_option) ? $node->maybe_option : NULL,
'secure' => isset($node->secure) ? $node->secure : NULL,
);
$form['add_your_vote']['pollpanel'] = array(
'#type' => 'makemeeting_choices',
'#title' => t('Add your vote'),
'#attributes' => $attributes,
'#default_value' => $attributes,
'#description' => t('Choose your name and select the answers.'),
);
$form['node_id'] = array(
'#type' => 'value',
'#value' => $node->nid,
);
$form['poll_url'] = array(
'#type' => 'value',
'#value' => $node->poll_url,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
/**
* pollpanel_form validate function
*/
function makemeeting_pollpanel_form_validate($form, &$form_state) {
$node = node_load($form_state['values']['node_id']);
if ($form_state['values']['poll_url'] != $node->poll_url) {
form_set_error('add_your_vote', t('Hacking attempt.'));
}
if ($form_state['input']['your_name'] == "") {
form_set_error('pollpanel', t('You must enter your name.'));
}
}
/**
* pollpanel_form submit function
*/
function makemeeting_pollpanel_form_submit($form, &$form_state) {
$node = node_load($form_state['values']['node_id']);
$values = array(
'user_name' => $form_state['values']['add_your_vote']['pollpanel']['name'],
'poll_id' => $node->nid,
'dt' => REQUEST_TIME,
);
if ($node->maybe_option == 1 || $node->multiple_allowed == 1) {
// We are using $vote_value here
foreach ($form_state['values']['add_your_vote']['pollpanel']['alter_ids'] as $alter_id => $vote_value) {
$values['answer_id'] = $alter_id;
$values['answer_value'] = $vote_value;
db_insert('makemeeting_poll_votes')
->fields($values)
->execute();
}
}
else {
// $vote_value is 1 here -> checked is yes
$values['answer_value'] = 1;
foreach ($form_state['values']['add_your_vote']['pollpanel']['alter_ids'] as $alter_id) {
$values['answer_id'] = $alter_id;
db_insert('makemeeting_poll_votes')
->fields($values)
->execute();
}
}
// Log
makemeeting_insert_log($node->nid, $form_state['values']['add_your_vote']['pollpanel']['name']);
// send notification email
if ($node->email_notification == 1) {
// if anonym and has valid email address
if ($node->uid == 0) {
if (valid_email_address($node->user_email)) {
$params = array(
'name' => $node->user_name == "" ? t("user") : $node->user_name,
'poll_url' => $node->poll_url,
);
drupal_mail('makemeeting', 'new_vote', $node->user_mail, language_default(), $params);
}
}
else {
// if registered and has valid email address
$account = user_load($node->uid);
if (valid_email_address($account->mail)) {
$params = array(
'name' => $account->name,
'poll_url' => $node->poll_url,
);
drupal_mail('makemeeting', 'new_vote', $account->mail, user_preferred_language($account), $params);
}
}
}
drupal_set_message(t("Succesfull."));
return;
}
/**
* hook_mail implementation
*/
function makemeeting_mail($key, &$message, $params) {
$options = array(
'langcode' => $message['language']->language,
);
switch ($key) {
// send to friends the poll link
case 'refer':
$variables = array(
'!site' => variable_get('site_name', 'Drupal'),
'!nickname' => $params['name'],
'!poll_owner' => $params['owner_name'],
'!poll_link' => url('makemeeting/' . $params['poll_url'], array(
"absolute" => TRUE,
)),
);
$message['subject'] = t('Please vote at !site', $variables, $options);
$message['body'][] = t('Dear !nickname,
please follow the link below to answer the question of !poll_owner.
!poll_link
Greetings,
!site', $variables, $options);
break;
// send notify to poll owner
case 'new_vote':
$variables = array(
'!name' => $params['name'],
'!site' => variable_get('site_name', 'Drupal'),
'!poll_link' => url('makemeeting/' . $params['poll_url'], array(
"absolute" => TRUE,
)),
);
$message['subject'] = t('New vote on !site', $variables, $options);
$message['body'][] = t('Dear !name,
somebody voted on your poll!
Check it at the following link:
!poll_link', $variables, $options);
break;
case 'create_new_poll':
$variables = array(
'!name' => $params['name'],
'!site' => variable_get('site_name', 'Drupal'),
'!poll_link' => url('makemeeting/' . $params['poll_url'], array(
"absolute" => TRUE,
)),
'!admin_link' => url('makemeeting/' . $params['admin_url'], array(
"absolute" => TRUE,
)),
);
$message['subject'] = t('Created new poll');
$message['body'][] = t("Dear !name,\n\nyour poll created successfull!\nYour poll's link are the following:\n\nPoll link: !poll_link\nAdmin link: !admin_link", $variables, $options);
break;
}
}
/**
* makemeeting_insert_log()
*
* @return void
*/
function makemeeting_insert_log($nid, $username) {
db_insert('makemeeting_poll_logs')
->fields(array(
'nid',
'username',
'dt',
))
->values(array(
$nid,
$username,
REQUEST_TIME,
))
->execute();
}
/**
* makemeeting_update_poll()
*
* @return
*/
function makemeeting_update_poll($form, &$form_state, $node) {
$type = node_type_get_type($node);
if ($type->has_title) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -5,
);
}
if ($type->has_body) {
$form['body'] = array(
'#type' => 'textarea',
'#title' => check_plain($type->body_label),
'#default_value' => isset($node->body) ? $node->body : '',
'#rows' => 5,
);
}
if (isset($node->nid) && $node->uid == 0) {
$form['anonym'] = array(
'#type' => 'fieldset',
'#title' => t('Add your name and email'),
'#tree' => TRUE,
);
$form['anonym']['user_name'] = array(
'#type' => 'textfield',
'#title' => t('Your name'),
'#maxlength' => 100,
'#default_value' => check_plain($node->anonym_name),
'#description' => t('This is optional.'),
);
$form['anonym']['user_email'] = array(
'#type' => 'textfield',
'#title' => t('Your e-mail'),
'#description' => t('This is optional, too. But if you add, we can send e-mail notification after every valid vote.'),
'#default_value' => check_plain($node->anonym_email),
'#maxlength' => 100,
);
}
// translate the collected db datas into node data
if (is_array($node->days_and_options)) {
$attributes = array();
$i = 1;
foreach ($node->days_and_options as $days => $options_array) {
$start_day = strpos($days, "_");
$day_str = substr($days, $start_day + 1);
$attributes['date_' . $i] = $day_str;
foreach ($options_array as $k => $option) {
$start_option = strpos($option, "_");
$option_str = substr($option, $start_option + 1);
$attributes['option_' . $i][] = $option_str;
}
$i++;
}
}
else {
$attributes = array(
'date_1' => date("Y-m-d"),
'option_1' => array(
"",
"",
),
);
}
$form['calendar'] = array(
'#type' => 'makemeeting_calendarselector',
'#title' => t('Calendar test'),
'#description' => t('Use the calendar above to select the days, then add the options for the days. For example select the day of tomorrow and add "AM", "PM" as options. You can use only upcoming days.'),
'#attributes' => array(
'selected_dates_and_options' => $attributes,
),
);
$form['poll_options'] = array(
'#type' => 'fieldset',
'#title' => t('Scheduler options'),
'#tree' => TRUE,
);
$form['poll_options']['secure'] = array(
'#type' => 'radios',
'#title' => t('Show previous votes'),
'#description' => t("Deny new voters to see the previous votes."),
'#options' => array(
'0' => t('Yes'),
'1' => t('No'),
),
'#default_value' => isset($node->secure) ? $node->secure : 0,
);
$form['poll_options']['maybe_option'] = array(
'#type' => 'radios',
'#title' => t('Maybe option'),
'#description' => t("Voters can select maybe as answer too."),
'#options' => array(
'0' => t('Disabled'),
'1' => t('Enabled'),
),
'#default_value' => isset($node->maybe_option) ? $node->maybe_option : 0,
);
$form['poll_options']['multiple_allowed'] = array(
'#type' => 'radios',
'#title' => t('Multiple option is selectable per answers.'),
'#options' => array(
'0' => t('Disabled'),
'1' => t('Enabled'),
),
'#default_value' => isset($node->multiple_allowed) ? $node->multiple_allowed : 0,
);
$form['email'] = array(
'#type' => 'fieldset',
'#title' => t('E-mail notification'),
);
$form['email']['email_notification'] = array(
'#type' => 'radios',
'#title' => t('Send me an e-mail after every valid vote'),
'#options' => array(
'1' => t('Yes'),
'0' => t('No'),
),
'#default_value' => isset($node->email_notification) ? $node->email_notification : 0,
);
$form['poll_admin_url'] = array(
'#type' => 'value',
'#value' => $node->poll_admin_url,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
/**
* makemeeting_update_poll_submit()
*
* @return void
*/
function makemeeting_update_poll_submit($form, &$form_state) {
// poll head
$node_id = db_query("SELECT nid FROM {makemeeting_poll_heads} WHERE admin_url = :admin_url", array(
':admin_url' => $form_state['values']['poll_admin_url'],
))
->fetchField();
$node = node_load($node_id);
// save node options
$node->title = $form_state['values']['title'];
$node->body = $form_state['values']['body'];
node_save($node);
// save poll options
db_update('makemeeting_poll_heads')
->fields(array(
'anonym_name' => $form_state['values']['anonym']['user_name'],
'anonym_email' => $form_state['values']['anonym']['user_email'],
'email_notification' => $form_state['values']['email_notification'],
'multiple_allowed' => $form_state['values']['poll_options']['multiple_allowed'],
'secure' => $form_state['values']['poll_options']['secure'],
'maybe_option' => $form_state['values']['poll_options']['maybe_option'],
))
->condition('nid', $node_id)
->execute();
// days and options
// collect the ids of the days which are already in the db
$days_ids_result = db_query("SELECT answer_id FROM {makemeeting_poll_rows} WHERE nid = :nid", array(
':nid' => $node->nid,
));
$days_ids = array();
foreach ($days_ids_result as $row) {
$days_ids[] = $row->answer_id;
}
// insert and update days and options datas
$i = 0;
foreach ($form_state['values']['calendar'] as $day => $options_array) {
// get the first id in the db
$current_answer_id = $days_ids[$i++];
// if we have an option in this position, we updating it
if ($current_answer_id > 0) {
db_update('makemeeting_poll_rows')
->fields(array(
'answer_text' => $day,
))
->condition('answer_id', $current_answer_id)
->execute();
$answer_id = $current_answer_id;
}
else {
// else we insert a new row with the new day
$answer_id = db_insert('makemeeting_poll_rows')
->fields(array(
'nid',
'answer_text',
'type',
), array(
$node->nid,
$day,
1,
))
->execute();
}
// at here we have in $answer_id the acutal day, so we updating the day's option
// the method is the same
// collecting the options ids for the day
$options_ids_result = db_query("SELECT alter_id FROM {makemeeting_poll_alters} WHERE answer_id = :answer_id", array(
':answer_id' => $answer_id,
));
$options_ids = array();
foreach ($options_ids_result as $row) {
$options_ids[] = $row->alter_id;
}
// drive through the options array, and update the old or insert the new one
$j = 0;
foreach ($options_array as $option) {
$current_alter_id = $options_ids[$j++];
if ($current_alter_id > 0) {
db_query("UPDATE {makemeeting_poll_alters} SET alter_text = '%s' WHERE alter_id = %d", $option, $current_alter_id);
}
else {
db_query("INSERT INTO {makemeeting_poll_alters} (answer_id, alter_text) VALUES (%d, '%s')", $answer_id, $option);
}
}
// if there is some unused id in $options_ids, that's mean we deleted them
while ($j < sizeof($options_ids)) {
db_query("DELETE FROM {makemeeting_poll_alters} WHERE alter_id = :alter_id", array(
':alter_id' => $options_ids[$j],
));
$j++;
}
}
// if there is some unused id in $days_ids, that's mean we deleted them
while ($i < sizeof($days_ids)) {
db_query("DELETE FROM {makemeeting_poll_rows} WHERE answer_id = :answer_id", array(
':answer_id' => $days_ids[$i],
));
$i++;
}
drupal_set_message(t("Saved."));
drupal_goto('makemeeting/' . $form_state['values']['poll_admin_url']);
}
/**
* makemeeting_sendfw_form()
*
* @return
*/
function makemeeting_sendfw_form($form, &$form_state, $node) {
$form['sendfw'] = array(
'#type' => 'fieldset',
'#title' => t('Add your friends e-mail addresses'),
'#tree' => TRUE,
);
for ($i = 0; $i < 5; $i++) {
$form['sendfw']['address_' . $i] = array(
'#type' => 'textfield',
'#title' => t('E-mail address #@num', array(
"@num" => $i + 1,
)),
'#maxlength' => 100,
);
}
$form['sendfw']['poll_url'] = array(
'#type' => 'value',
'#value' => $node->poll_url,
);
$form['sendfw']['submit_bt'] = array(
'#type' => 'submit',
'#value' => t('Send'),
);
return $form;
}
/**
* makemeeting_sendfw_form_submit()
*
* @return void
*/
function makemeeting_sendfw_form_submit($form, &$form_state) {
// load node
$node_id = db_query("SELECT nid FROM {makemeeting_poll_heads} WHERE url = :url", array(
':url' => $form['#post']['sendfw']['poll_url'],
))
->fetchField();
$node = node_load($node_id);
// owner name
if ($node->uid == 0) {
$owner_name = $node->user_name == "" ? t("user") : $node->user_name;
}
else {
$account = user_load($node->uid);
$owner_name = $account->name;
}
// mail params
$mail_params = array(
"name" => t("user"),
"owner_name" => $owner_name,
"poll_url" => $node->poll_url,
);
// send emails
for ($i = 0; $i < 5; $i++) {
if (!empty($form['#post']['sendfw']['address_' . $i])) {
$email = $form['#post']['sendfw']['address_' . $i];
drupal_mail('makemeeting', 'refer', $email, language_default(), $mail_params);
}
}
drupal_set_message(t("Mail sent."));
}
/**
* makemeeting_sendfw_form_validate()
*
* @return void
*/
function makemeeting_sendfw_form_validate($form_id, $form_values) {
for ($i = 0; $i < 5; $i++) {
if (!empty($form_values['values']['sendfw']['address_' . $i])) {
if (!valid_email_address($form_values['values']['sendfw']['address_' . $i])) {
form_set_error('sendfw[address_' . $i . ']', t('E-mail #@count is not valid', array(
"@count" => $i + 1,
)));
}
}
}
}
/**
* Helper function to generate a unique keychain
*
* @param $field
* The field to be unique
* @param $length
* Lengh of the keychain
* @return string
*/
function _makemeeting_generate_url($field, $length) {
$url = _makemeeting_keygen($length);
$query = db_select('makemeeting_poll_heads', 'm')
->fields('m');
while ($query
->condition($field, $url)
->execute()
->rowCount() > 0) {
$url = _makemeeting_keygen($length);
}
return $url;
}
/**
* Helper function to generate a keychain
*
* @param $length
* Lengh of the keychain
* @return string
*/
function _makemeeting_keygen($length) {
$pattern = "1234567890abcdefghijklmnopqrstuvwxyz";
$key = $pattern[rand(0, 35)];
for ($i = 1; $i < $length; $i++) {
$key .= $pattern[rand(0, 35)];
}
return $key;
}
/**
* Implements hook_menu_alter()
*/
function makemeeting_menu_alter(&$items) {
$items['node/%node']['page callback'] = 'makemeeting_page_view';
}
/**
* Wrapper around node_page_view().
*/
function makemeeting_page_view($node) {
if ($node->type == 'makemeeting') {
global $user;
if ($user->uid == $node->uid || $user->uid == 1) {
return node_page_view($node);
}
else {
// Avoid display of node/NID pages to prevent data leakage
return drupal_access_denied();
}
}
else {
return node_page_view($node);
}
}