You are here

contribute.module in Contribute 6

Same filename and directory in other branches
  1. 8 contribute.module

Lets users contribute to projects

File

contribute.module
View source
<?php

/**
 * @file
 * Lets users contribute to projects
 */
function contribute_form($form_state) {
  $form['transfer'] = array(
    '#type' => 'fieldset',
    '#title' => t('contribute to project'),
    '#tree' => TRUE,
  );
  $form['transfer']['amount'] = array(
    '#type' => 'textfield',
    '#title' => t('Amount'),
    '#size' => 30,
    '#default_value' => 0,
    '#maxlength' => 64,
    '#description' => t('Enter the amount to contribute to project'),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Load'),
  );
  return $form;
}
function load_account_form() {
  $form['load_account'] = array(
    '#type' => 'fieldset',
    '#title' => t('Load a user\'s Account'),
    '#tree' => TRUE,
  );
  $form['load_account']['user'] = array(
    '#type' => 'textfield',
    '#title' => t('User'),
    '#size' => 30,
    '#maxlength' => 64,
    '#description' => t('Enter the user whose account you are going to load'),
  );
  $form['load_account']['amount'] = array(
    '#type' => 'textfield',
    '#title' => t('Amount'),
    '#size' => 30,
    '#maxlength' => 64,
    '#description' => t('Enter the amount to load into the user\'s account'),
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Load'),
  );
  return $form;
}
function load_account_form_submit($form, &$form_state) {
  $user_array = array(
    'name' => $form['load_account']['user']['#value'],
  );
  $user = user_load($user_array);
  $amount = $form['load_account']['amount']['#value'];
  contribute_update_user_balance($user->uid, $amount);
  drupal_set_message("User " . $user->name . " loaded with \$" . $amount);
}
function contribute_form_submit($form, &$form_state) {
  global $user;

  // Load the node the form was submitted from
  // Note: this only works when the node is submitted from /node/#
  // and will need to be fixed at some point to be more robust
  $nid = $form['#action'];
  $nid = $form['#parameters'][2]->nid;
  $node = node_load($nid);
  drupal_set_message("nid is {$nid}");
  dpm($form);
  $amount = $form_state['values']['transfer']['amount'];
  $balance = contribute_get_user_balance($user->uid);
  if ($amount > $balance) {
    drupal_set_message("Sorry, not enough funds");
    return;
  }
  $needed = contribute_get_node_balance($nid);
  drupal_set_message("needed = {$needed} , amount = {$amount}");
  $amount = $amount > $needed ? $needed : $amount;
  contribute_contribution($user->uid, $nid, $amount);
}
function contribute_form_validate($form, &$form_state) {
  global $user;
  $amount_to_transfer = $form_state['values']['transfer']['amount'];
  $balance = contribute_get_user_balance($user->uid);
  $minimum_contribution = variable_get(contribute_minimum_contribution, array(
    '100',
  ));
  if (!is_numeric($amount_to_transfer)) {
    form_set_error('', t('Must be numeric'));
  }
  elseif ($minimum_contribution > $amount_to_transfer) {
    form_set_error('', t('Sorry the minimum amount is @minimum', array(
      '@minimum' => $minimum_contribution,
    )));
  }
}
function contribute_nodeapi(&$node, $op, $teaser, $page) {
  global $user;
  switch ($op) {
    case 'load':
      $node->contribute_budget = contribute_get_node_budget($node->nid);
      break;
    case 'view':
      if ($user->uid == 0) {
        $node->content['contribute_form'] = array(
          '#value' => "Log in to contribute!",
        );
      }
      elseif ($page) {

        //Only proceed if the administrator has allowed contributions for this type of node
        $types_to_contribute = variable_get(contribute_node_types, array(
          'page',
        ));
        if (!in_array($node->type, $types_to_contribute, TRUE)) {
          break;
        }
        $budget = contribute_get_node_balance($node->nid);
        if ($budget > 0) {
          $node->content['contribute_form'] = array(
            '#value' => drupal_get_form('contribute_form', $node),
          );
        }
        else {
          $node->content['completed_already'] = array(
            '#value' => "This project is fully funded!. {$budget}",
          );
        }
      }
      break;
    case 'update':
      $budget = $node->budget;
      contribute_update_node_balance($node->nid, $budget);
      break;
    case 'insert':
      $budget = $node->field_budget[0]['value'];
      contribute_node_insert($node->nid, $budget);
      break;
  }
}

/*
 * Implementation of hook_menu()
 */
function contribute_menu() {
  $items['admin/contribute'] = array(
    'title' => 'Charitable contributions',
    'description' => 'Information and settings about contributions',
    'position' => 'right',
    'weight' => -5,
    'page callback' => 'system_admin_menu_block_page',
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'system.admin.inc',
    'file path' => drupal_get_path('module', 'system'),
  );
  $items['admin/contribute/contributions'] = array(
    'title' => 'contributions',
    'description' => 'View all contributions',
    'page callback' => 'page_show_all_contributions',
    'access arguments' => array(
      'administer site configuration',
    ),
    'weight' => 0,
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/contribute/contribution_recipients'] = array(
    'title' => 'contribution Recipients',
    'description' => 'View all contribution recipients',
    'page callback' => 'page_show_all_contribution_recipients',
    'access arguments' => array(
      'administer site configuration',
    ),
    'weight' => 2,
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/contribute/settings'] = array(
    'title' => 'Settings',
    'description' => 'Modify Settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'contribute_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'weight' => 2,
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/contribute/load_account'] = array(
    'title' => 'Load User Account',
    'description' => 'Use this to load funds or credits into a users account for future contribution',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'load_account_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'weight' => 8,
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}
function contribute_settings() {
  $options = node_get_types('names');
  $form['contribute_node_types'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Users will be able to contribute to these project types'),
    '#options' => $options,
    '#default_value' => variable_get('contribute_node_types', array(
      'page',
    )),
    '#description' => t('A form will be available for users to contribute money on these content types'),
  );
  $form['minimum_maximum'] = array(
    '#type' => 'fieldset',
    '#title' => 'Minimum and Maximum Values',
  );
  $form['minimum_maximum']['contribute_minimum_contribution'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum contribution'),
    '#default_value' => variable_get('contribute_minimum_contribution', '100'),
    '#description' => t('This is the minimum amount a user can contribute, in USD'),
  );
  $form['minimum_maximum']['contribute_minimum_budget'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum budget'),
    '#default_value' => variable_get('contribute_minimum_budget', '1000'),
    '#description' => t('This is the minimum budget for a recipient node, in USD'),
  );
  $form['minimum_maximum']['contribute_maximum_budget'] = array(
    '#type' => 'textfield',
    '#title' => t('Maximum budget'),
    '#default_value' => variable_get('contribute_maximum_budget', '10000'),
    '#description' => t('This is the maximum budget for a recipient node, in USD'),
  );
  return system_settings_form($form);
}
function page_show_all_contributions() {
  $contributions = get_all_contributions();
  $output = '<table class="contribution-list">';
  $output .= '<tr class=contribution-list-header>';
  $output .= '<th>User</th><th>Uid</th><th>Title</th><th>Nid</th><th>Amount</th><th>Time</th></tr>';
  $zebra = 'odd';
  while ($contribution = db_fetch_array($contributions)) {
    $user = user_load(array(
      'uid' => $contribution['uid'],
    ));
    $node = node_load($contribution['nid']);
    $output .= '<tr class="' . $zebra . '">';
    $output .= '<td class="user">' . check_plain($user->name) . '</td>';
    $output .= '<td class="uid" align="center">' . check_plain($contribution['uid']) . '</td>';
    $output .= '<td class="title">' . check_plain($node->title) . '</td>';
    $output .= '<td class="nid" align="center">' . check_plain($contribution['nid']) . '</td>';
    $output .= '<td class="amount">$' . check_plain($contribution['amount']) . '</td>';
    $output .= '<td class="time">' . date('M d Y h:i:s', check_plain($contribution['created'])) . '</td></tr>';
    $zebra = $zebra == 'odd' ? 'even' : 'odd';
  }
  $output .= "</table>";
  return $output;
}
function get_all_contributions() {
  $result = db_query('SELECT * FROM {contribute_contributions}');
  return $result;
}
function get_all_contribution_recipients() {
  $result = db_query('SELECT * FROM {contribute_contribution_recipients}');
  return $result;
}
function page_show_all_contribution_recipients() {
  $contribution_recipients = get_all_contribution_recipients();
  $output = '<table class="contribution-recpient-list">';
  $output .= '<tr class=contribution-recipient-list-header>';
  $output .= '<th>Nid</th><th>Title</th><th>Total</th><th>Budget</th></tr>';
  $zebra = 'odd';
  while ($recipient = db_fetch_array($contribution_recipients)) {
    $node = node_load($recipient['nid']);
    $output .= '<tr class="' . $zebra . '">';
    $output .= '<td class="uid" align="center">' . check_plain($recipient['nid']) . '</td>';
    $output .= '<td class="title">' . check_plain($node->title) . '</td>';
    $output .= '<td class="total" align="center">$' . check_plain($recipient['total']) . '</td>';
    $output .= '<td class="budget">$' . check_plain($recipient['budget']) . '</td>';
    $zebra = $zebra == 'odd' ? 'even' : 'odd';
  }
  $output .= "</table>";
  return $output;
}
function contribute_get_user_contributions($user) {
  $result = db_query('SELECT * FROM {contribute_contributions} WHERE uid = %d', $user->uid);
  $contributions = array();
  $i = 0;
  while ($contribution = db_fetch_array($result)) {
    $contributions[] = $contribution;
  }
  return $contributions;
}
function contribute_get_node_contributions($nid) {
  if ($nid == 'all') {
    $result = db_query('SELECT * FROM {contribute_contributions}');
  }
  else {
    $result = db_query('SELECT * FROM {contribute_contributions} WHERE nid = %d', $nid);
  }
  $contributions = array();
  while ($contribution = db_fetch_array($result)) {
    $contributions[] = $contribution;
  }
  return $contributions;
}
function theme_contribute_user_contributions($contributions) {
  $output = '<table class="user-contribution-list">';
  $output .= '<tr class=contribution-list-header>';
  $output .= '<th>contribution ID</th><th>Nid</th><th>Title</th><th>Amount</th><th>Made On</th></tr>';
  $zebra = 'odd';
  foreach ($contributions as $contribution) {
    $node = node_load($contribution['nid']);
    $output .= '<tr class="' . $zebra . '">';
    $output .= '<td class="id" align="center">' . check_plain($contribution['id']) . '</td>';
    $output .= '<td class="nid" align="center">' . check_plain($contribution['nid']) . '</td>';
    $output .= '<td class="title">' . check_plain($node->title) . '</td>';
    $output .= '<td class="amount" align="center">$' . check_plain($contribution['amount']) . '</td>';
    $output .= '<td class="created">' . date('M d Y h:i', check_plain($contribution['created'])) . '</td>';
    $zebra = $zebra == 'odd' ? 'even' : 'odd';
  }
  $output .= "</table>";
  return $output;
}
function contribute_profile_alter(&$account) {
  $contributions = contribute_get_user_contributions($account);
}
function contribute_user($op, &$edit, &$user) {
  $contributions = contribute_get_user_contributions($user);
  switch ($op) {
    case "view":
      $user->content['summary']['contributions'] = array(
        '#type' => 'user_profile_item',
        '#title' => t('Pledges'),
        '#value' => theme_contribute_user_contributions($contributions),
        '#attributes' => array(
          'class' => 'blog',
        ),
      );
      break;
    case "insert":
      contribute_user_insert($user->uid);
      break;
  }
}
function contribute_user_insert($uid) {
  $initial_balance = 0;
  contribute_set_user_balance($uid, $initial_balance);

  //module_invoke_all('contribute_user_insert', $uid);
}
function contribute_get_node_balance($nid) {
  $result = db_query('SELECT budget-total FROM {contribute_contribution_recipients} WHERE nid =%d', $nid);
  return db_result($result);
}
function contribute_get_needed($nid) {
  $result = db_query('SELECT total,budget FROM {contribute_contribution_recipients WHERE nid=%d}', $nid);
  $values = db_fetch_array($result);
  $needed = $values['budget'] - $values['total'];
  return $needed;
}
function contribute_get_user_balance($uid) {
  $result = db_query('SELECT balance FROM {contribute_account_balances WHERE uid=%d}', $uid);
  return db_result($result);
}
function contribute_set_user_balance($uid, $amount) {
  $result = db_query('INSERT INTO {contribute_account_balances} VALUES(%d,%f) ON DUPLICATE KEY UPDATE balance=%f', $uid, $amount, $amount);
}
function contribute_update_user_balance($uid, $amount) {
  $result = db_query('INSERT INTO {contribute_account_balances} VALUES(%d,%f) ON DUPLICATE KEY UPDATE balance=%f+balance', $uid, $amount, $amount);
}
function contribute_node_insert($nid, $budget) {
  $result = db_query('INSERT INTO {contribute_contribution_recipients} VALUES(%d,0,%f)', $nid, $budget);
}
function contribute_contribution($uid, $nid, $amount) {
  $needed = contribute_get_node_balance($nid);
  contribute_update_user_balance($uid, $amount * -1);
  contribute_update_node_balance($nid, $amount);
  contribute_add_contribution_to_db($uid, $nid, $amount);
  if ($needed <= $amount) {
    drupal_set_message("uid - {$uid}, nid = {$nid}, amount = {$amount}");
    module_invoke_all('contribute_budget_reached', $nid);
  }
}
function contribute_add_contribution_to_db($uid, $nid, $amount) {
  $result = db_query('INSERT INTO {contribute_contributions} VALUES(%d,%d,%f,%d,%d)', $uid, $nid, $amount, time());
}
function contribute_contribute_budget_reached($nid) {
  dpm("Budget reached! for node " . $nid);
}
function contribute_get_node_budget($nid) {
  $result = db_query('SELECT budget FROM {contribute_contribution_recipients} WHERE nid=%d', $nid);
  return db_result($result);
}
function contribute_update_node_budget($nid, $amount) {
  $result = db_query('INSERT INTO {contribute_contribution_recipients} VALUES(%d,0,%f) ON DUPLICATE KEY UPDATE budget=%f', $nid, $amount, $amount);

  #	$result = db_query('UPDATE {contribute_contribution_recipients} SET total=%f+total WHERE nid=%d',$amount,$nid);
}
function contribute_update_node_balance($nid, $amount) {
  $result = db_query('INSERT INTO {contribute_contribution_recipients} VALUES(%d,0,%f) ON DUPLICATE KEY UPDATE total=total+%f', $nid, $amount, $amount);

  #	$result = db_query('UPDATE {contribute_contribution_recipients} SET total=%f+total WHERE nid=%d',$amount,$nid);
}
function contribute_form_alter(&$form, $form_state, $form_id) {
  $node = $form['#parameters'][2];
  $budget = $node->contribute_budget;
  $node_types = variable_get(contribute_node_types, array(
    'page',
  ));
  $add_form = in_array($form['type']['#value'], $node_types);
  if ($form['#id'] == "node-form" && $add_form && !$form_state['submitted']) {
    $form['contribute_node_form'] = array(
      '#title' => t('Contribution Settings'),
      '#type' => 'fieldset',
    );
    $form['contribute_node_form']['budget'] = array(
      '#title' => "Budget",
      '#type' => 'textfield',
      '#default_value' => $budget,
    );
  }
}

/*
 * Implemenation of hook_block
 */
function contribute_block($op = 'list', $delta = 0, $edit = array()) {
  global $user;
  switch ($op) {
    case 'list':
      $blocks[0]['info'] = t('Contribute Account Information');
      $blocks[0]['cache'] = BLOCK_CACHE_PER_PAGE;
      return $blocks;
    case 'view':
      if ($user->uid == 0) {

        //anonymous user has no account info
        $block['subject'] = t('Create an account or log in to get started!');
        $block['content'] = l('user', 'Log in!');
      }
      else {
        $block['subject'] = t('Account Summary');
        $block['content'] = _contribute_account_summary();
      }
      return $block;
  }
}
function _contribute_account_summary() {
  global $user;
  $output = "";
  $output .= '<div class="contribute-user-budget-label">Balance:</div>';
  $output .= "<div class=\"contribute-user-budget\">";
  $output .= number_format(contribute_get_user_balance($user->uid), 2);
  $output .= "</div>";
  $output .= l('Load your account', 'load_account');
  return $output;
}