<?php

/**
 * 7.x
 *
 * femail.module
 */
/**
 * Implementation of hook_permission
 *
 * States the roles that are allowed to email the site.
 */
function femail_permission(){
  return array(
    'post by femail' => array(
      'title' => t('Post forum topics to the site using their email.')
    ),
    'administer femail' => array(
      'title' => t('Administer FEMail')
    )
  );
}

/**
 * Implements hook_menu_local_tasks_alter().
 *
 * Much of the following code is ripped straight from the same hook in the forum
 * module.
 */
function femail_menu_local_tasks_alter(&$data, $router_item, $root_path){
  // Are we viewing a forum?
  if($root_path == 'forum' || $root_path == 'forum/%'){
    $tid = (isset($router_item['page_arguments'][0]) ? $router_item['page_arguments'][0]->tid : 0);
    if($tid){
      $forum_term = forum_forum_load($tid);
      // We're viewing a Forum, or a Container, lets check this isn't a container
      if(!in_array($tid, variable_get('forum_containers', array())) && $forum_term){
        $vid = variable_get('forum_nav_vocabulary', 0);
        $vocabulary = taxonomy_vocabulary_load($vid);
        $links = array();
        // Loop through all bundles for forum taxonomy vocabulary field.
        $field = field_info_field('taxonomy_' . $vocabulary->machine_name);
        $emails = variable_get('femail_emails', array());
        if(isset($emails[$tid])){
          if(user_access('post by femail')){
            $field = field_info_field('taxonomy_' . $vocabulary->machine_name);
            foreach($field['bundles']['node'] as $type){
              $links[$type . '_femail'] = array(
                '#theme' => 'menu_local_action',
                '#link' => array(
                  'title' => t('Add new @node_type by email', array(
                    '@node_type' => node_type_get_name($type)
                  )),
                  'href' => 'mailto:' . $emails[$tid]
                ),
                '#weight' => 100
              );
            }
          }
        }else{
          // This should be set, we need to warn the admin
          watchdog('femail', 'Femail address not set %term_id', array(
            '%term_id',
            $tid
          ));
        }
        $data['actions']['output'] = array_merge($data['actions']['output'], $links);
      }
    }
  }
}

/**
 * Implements hook_cron().
 */
function femail_cron(){
  // Delete the oldest 50 anonymously created forum topics that are unpublished.
  // Note, we only do this if anon does not have the permission to create
  // forum topics.
  $account = user_load(0);
  if(!user_access('create forum content', $account)){
    $nids = db_select('node', 'n')->fields('n', array(
      'nid'
    ))->condition('type', 'forum')->condition('uid', 0)->condition('status', 0)->condition('created', time() - 604800, '<')->orderBy('nid')->range(0, 50)->execute()->fetchCol();
    node_delete_multiple($nids);
  }
}

/**
 * Implementation of hook_menu
 */
function femail_menu(){
  return array(
    'user/%user/femail' => array(
      'title' => 'Forum/E-mail integration',
      'page callback' => 'femail_user_settings',
      'page arguments' => array(
        1
      ),
      'access callback' => 'user_edit_access',
      'access arguments' => array(
        1
      ),
      'type' => MENU_LOCAL_TASK,
      'file' => 'femail.pages.inc'
    ),
    'femail/verify/%/%' => array(
      'title' => 'Forum/E-mail integration',
      'page callback' => 'femail_email_verify',
      'page arguments' => array(
        2,
        3
      ),
      'access arguments' => array(
        'access content'
      ),
      'type' => MENU_CALLBACK,
      'file' => 'femail.pages.inc'
    ),
    'femail/remove/%user/%' => array(
      'title' => 'Forum/E-mail integration',
      'page callback' => 'femail_email_remove',
      'page arguments' => array(
        2,
        3
      ),
      'access callback' => 'user_edit_access',
      'access arguments' => array(
        2
      ),
      'type' => MENU_CALLBACK,
      'file' => 'femail.pages.inc'
    ),
    'admin/config/system/femail' => array(
      'title' => 'Forum/E-mail integration',
      'description' => 'Reset the email addresses for your site.',
      'page callback' => 'drupal_get_form',
      'page arguments' => array(
        'femail_reset_emails_form'
      ),
      'file' => 'femail.pages.inc',
      'access arguments' => array(
        'administer femail'
      )
    )
  );
}

/**
 * Implementation of hook_admin_paths
 */
function femail_admin_paths(){
  return array(
    'user/*/femail' => TRUE,
    'femail/remove/*' => TRUE,
    'femail/verify/*' => TRUE
  );
}

/**
 * Implementation of hook_mail
 */
function femail_mail($key, &$message, $params){
  $language = $message['language'];
  switch($key){
    case 'verify':
      $message['subject'] = t('!site requests verification', array(
        '!site' => variable_get('site_name', 'Drupal')
      ), array(
        'langcode' => $language->language
      ));
      $message['body'] = array(
        t('Please click on the following link to verify your email address'),
        url('femail/verify/' . $message['to'] . '/' . md5($message['to'] . variable_get('femail_install_time', 'INSTALLTIME')), array(
          'absolute' => TRUE
        ))
      );
      break;
  }
}

/**
 * Implementation of hook_filter_info
 */
function femail_filter_info(){
  return array(
    'femail_remove_sig' => array(
      'title' => t('Femail: Remove signature'),
      'description' => t('Hides any text marked as a signature according to <a href="http://tools.ietf.org/html/rfc3676#section-4.3">http://tools.ietf.org/html/rfc3676#section-4.3</a>'),
      'process callback' => '_femail_filter_remove_sig_process'
    ),
    'femail_blockquote_reply' => array(
      'title' => t('Femail: Blockquote reply text'),
      'description' => t('Wraps &lt;blockquote&gt tags around portions of an email message whose lines start with ">"'),
      'process callback' => '_femail_filter_blockquote_reply_process'
    )
  );
}

/**
 * Implementation of hook_filter_FILTER_process
 */
function _femail_filter_remove_sig_process($text, $filter, $format, $langcode, $cache, $cache_id){
  // Split by lines, and look for a line that starts with "--".  Anything after
  // this line is the signature
  $lines = preg_split('/[\n\r]+/', $text);
  $return_text = '';
  $started_sig = FALSE;
  foreach($lines as $line){
    if((substr($line, 0, 2) == '--' || substr($line, 0, 5) == '<p>--') && !$started_sig){
      $return_text .= '<div class="femail-signature"><p>--</p><div>';
      $line = substr($line, strpos($line, '--') + 2);
      $started_sig = TRUE;
    }
    $return_text .= $line . "\n";
  }
  if($started_sig){
    $return_text .= '</div></div>';
  }
  return $return_text;
}

/**
 * Implementation of hook_filter_FILTER_process
 */
function _femail_filter_blockquote_reply_process($text, $filter, $format, $langcode, $cache, $cache_id){
  $lines = preg_split('/[\n\r]+/', $text);
  $return_text = '';
  $started_block = FALSE;
  foreach($lines as $line){
    if(substr($line, 0, 1) == '>' || substr($line, 0, 5) == '&#62;' || substr($line, 0, 4) == '&gt;' || substr($line, 0, 8) == '<p>&#62;' || substr($line, 0, 7) == '<p>&gt;'){
      if(!$started_block){
        $return_text .= '<blockquote>';
      }
      // We'll remove the ">" if it isn't encoded, then we'll replace the first
      // instance of an html entity encoded ">"
      if(substr($line, 0, 1) == '>'){
        $line = substr($line, 1);
      }
      // replace entity encoded ">"
      $line = preg_replace("/(&#62;|&gt;)/", "", $line, 1);
      $return_text .= $line . "\n";
      $started_block = TRUE;
    }else{
      if($started_block){
        $return_text .= '</blockquote>';
        $started_block = FALSE;
      }
      $return_text .= $line . "\n";
    }
  }
  return $return_text;
}

/**
 * Implementation of hook_theme
 */
function femail_theme($existing, $type, $theme, $path){
  return array(
    'femail_box' => array(
      'variables' => array(
        'title' => NULL,
        'content' => NULL,
        'region' => 'main'
      ),
      'file' => 'femail.pages.inc'
    )
  );
}

/**
 * Implementation of hook_taxonomy_term_delete
 */
function femail_taxonomy_term_delete($term){
  $emails = variable_get('femail_emails', array());
  unset($emails[$term->tid]);
  variable_set('femail_emails', $emails);
}

/**
 * Implementation of hook_taxonomy_term_update
 */
function femail_taxonomy_term_update($term){
  // Simply call insert
  //femail_taxonomy_term_delete($term);
  femail_taxonomy_term_insert($term);
}

/**
 * Implementation of hook_taxonomy_term_insert
 */
function femail_taxonomy_term_insert($term){
  // Check that we're handling a term from the forum vocabulary.
  if($term->vid == variable_get('forum_nav_vocabulary', 0)){
    // Note, emails are set for forum containers, as the forum_container
    // variable has not been updated at this point.  This may be confusing if
    // a user creates a forum with the same name as a container, as the emails
    // will clash
    $emails = variable_get('femail_emails', array());
    unset($emails[$term->tid]);
    global $base_url;
    $parts = parse_url($base_url);
    $email = preg_replace("/[^0-9a-z-]/", "", strtolower(str_replace(" ", "-", $term->name)));
    // Make sure this email isn't already in use.
    if(array_search($email . '@' . $parts['host'], $emails)){
      $i = 2;
      while(array_search($email . "_" . $i . '@' . $parts['host'], $emails)){
        $i++;
      }
      $email = $email . "_" . $i;
    }
    // Set it and save it
    $emails[$term->tid] = $email . '@' . $parts['host'];
    variable_set('femail_emails', $emails);
  }
}

/**
 * Implementation of hook_user_delete
 */
function femail_user_delete($account){
  db_delete('femail_user_subscriptions')->condition('uid', $account->uid)->execute();
}

/**
 * Implementation of hook_node_insert
 */
function femail_node_insert($node){
  if($node->type == 'forum' && $node->status){
    // We've added/updated a forum post, lets mail it out
    // First, we'll get the forum that this has been posted to.
    //drupal_set_message('<pre>'.print_r($node, 1).'</pre>');
    $lang = field_language('node', $node, 'taxonomy_forums');
    $forum_tid = $node->taxonomy_forums[$lang][0]['tid'];
    if($forum_tid){
      module_load_include('mail.inc', 'femail');
      $files = array();
      $lang = field_language('node', $node, 'femail_files');
      if(isset($node->femail_files[$lang])){
        foreach($node->femail_files[$lang] as $file){
          $files[] = file_load($file['fid']);
        }
      }
      // Aquire node access first, before trying to send.
      node_access_acquire_grants($node);
      $lang = field_language('node', $node, 'body');
      _femail_send_message($forum_tid, $node->title, $node->body[$lang][0]['value'], $node->nid, $files);
      // We need to remove the grants from the database, as otherwise we will
      // receive an error.
      db_delete('node_access')->condition('nid', $node->nid)->execute();
    }
  }
}

/**
 * Implementation of hook_node_update
 */
function femail_node_update($node){
  // Do we want to send out a message when a node is updated?  Not sure!  We
  // may make this an option in the future, but for now, this is disabled.
  /*
   * DISABLED
   *
   * femail_node_insert($node);
   */
}

/**
 * Implementation of hook_comment
 */
function femail_comment_publish($comment){
  $node = node_load($comment->nid);
  if(isset($node->forum_tid) && $node->forum_tid){
    // Get the parent msgid so that we can set the "In-reply-to" header, Note,
  // this may not be set if there are no users subscribed to the forum, OR
  // if the only user subscribed posted the comment.  We'll still caryy on
  // trying to send the message though.
    $msgid = db_select('femail_msgs', 'f')->fields('f', array(
      'msgid'
    ))->condition('nid', $node->nid)->condition('cid', $comment->pid ? $comment->pid : 0)->execute()->fetchField();
    // Include file
    module_load_include('mail.inc', 'femail');
    $files = array();
    $lang = field_language('comment', $comment, 'femail_files');
    if(isset($comment->femail_files[$lang])){
      foreach($comment->femail_files[$lang] as $file){
        $files[] = file_load($file['fid']);
      }
    }
    $lang = field_language('comment', $comment, 'comment_body');
    _femail_send_message($node->forum_tid, $comment->subject, $comment->comment_body[$lang][0]['value'], $node->nid, $files, $comment->cid, $msgid);
  }
}

/**
 * FIXME - This needs to be altered ASAP to ensure that the plain text content
 * type is being used.
 *
 * Implementation of hook_form_alter
 */
function femail_form_alter(&$form, &$form_state, $form_id){
  if($form_id == 'forum_node_form'){
    // Add an after build to shizzle stuff up
    $form['body']['#pre_render'] = (isset($form['body']['#pre_render']) && is_array($form['body']['#pre_render'])) ? array_merge($form['body']['#pre_render'], array(
      'femail_after_build'
    )) : array(
      'femail_after_build'
    );
  }else if($form_id == 'comment_node_forum_form'){
    $form['comment_body']['#pre_render'] = (isset($form['comment_body']['#pre_render']) && is_array($form['comment_body']['#pre_render'])) ? array_merge($form['comment_body']['#pre_render'], array(
      'femail_after_build'
    )) : array(
      'femail_after_build'
    );
  }
}

/**
 * After build function to enable us to tweak shit.
 */
function femail_after_build($element){
  // FIXME - Appears to be an issue with setting the input format.
  /*$element['und'][0]['#format'] = 'plain_text';
  $new_options = array(
    $element['und'][0]['format']['format']['#options']['plain_text']
  );
  $element['und'][0]['format']['format']['#options'] = $new_options;
  $element['und'][0]['format']['format']['#default_value'] = 'plain_text';
  $element['und'][0]['format']['format']['#value'] = 'plain_text';*/
  return $element;
}

// -------------- ABOVE ARE DRUPAL 7 READY -------------------------------------
/**
 * Implementation of hook_og
 *
 * Couldn't really find much documentation for this, so this is a guess!
 *
    module_invoke_all('og', 'admin new', $node->nid, $account->uid, $message);
    module_invoke_all('og', 'user approve', $node->nid, $account->uid, $message);
    module_invoke_all('og', 'user broadcast', $node->nid, $recipients, $message);
    module_invoke_all('og', 'user delete', $gid, $uid, $args);
    module_invoke_all('og', 'user deny', $node->nid, $account->uid, $message);
    module_invoke_all('og', 'user insert', $gid, $uid, $args);
    module_invoke_all('og', 'user request', $gid, $admins, $message);
    module_invoke_all('og', 'user update', $gid, $uid, $args);
 *
 * Following function temporarily removed until it can be tested with Og 7.
function femail_og($op, $gid, $uid, $args){
  switch($op){
    case 'user insert':
      // Add the subscription if we're using og_forum
      if(module_exists('og_forum')){
        $tid = db_result(db_query('SELECT tid FROM {og_term} WHERE nid = %d', $gid));
        if($tid && $uid){
          // Use replace, incase they've already subscribed.
          db_query('REPLACE INTO {femail_user_subscriptions} (uid, tid) VALUES (%d, %d)', $uid, $tid);
        }
      }
      break;
    case 'user delete':
      // Remove the subscription if we're using og_forum
      if(module_exists('og_forum')){
        $tid = db_result(db_query('SELECT tid FROM {og_term} WHERE nid = %d', $gid));
        if($tid && $uid){
          // Use replace, incase they've already subscribed.
          db_query('DELETE FROM {femail_user_subscriptions} WHERE uid = %d AND tid = %d', $uid, $tid);
        }
      }
      break;
    case 'admin new':
    case 'user approve':
    case 'user broadcast':
    case 'user update':
    case 'user request':
    case 'user deny':
      break;
  }
}*/
