<?php
// $Id$

/**
 * @file
 * Main simple_subscription module file.
 */


/**
 * Implements hook_help().
 */
function simple_subscription_help($path, $arg) {
  switch ($path) {
    case 'admin/help#simple_subscription':
      $output = '<p>' . t('This module provides a block with a simple newsletter subscription form, i.e., an text input field (validated as an e-mail address) and a submit button. In the <a href="@block_configuration">block configuration page</a> you can add a header, a label and a footer to the form, as well as a small text appearing in the input field(usually used as a replacement to the field label. You can also choose a path to redirect the user after a successful submission.', array('@block_configuration' => '/admin/structure/block/configure/simple_subscription/0')) . '</p>';
      $output .= '<p>' . t("Simple subscription integrates with the trigger module to send site administrators (or anybody else) the submitted. It can be used with only the core action module for notifications, but the <a href='@token_url'>Token module</a> should also be installed for complete costumisation of the notification e-mails.", array('@token_url' => 'http://drupal.org/project/token')) . '</p>';
      return $output;
  }
}


/**
 * Implements hook_block_info().
 */
function simple_subscription_block_info() {
  $blocks['subscribe'] = array(
    'info' => t('Subscription Block'),
  );

  return $blocks;
}


/**
 * Implements hook_block_configure().
 */
function simple_subscription_block_configure($delta = '') {
  $form = array();

  if ($delta == 'subscribe') {
    $form = simple_subscription_block_config_form();
  }

  return $form;
}


/**
 * Implements hook_block_save().
 */
function simple_subscription_block_save($delta = '', $edit = array()) {
  if ($delta == 'subscribe') {
    $default_config = simple_subscription_get_default_values();

      variable_set('simple_subscription_config', array(
        'form_header'     => $edit['simple_subscription_form_header'],
        'form_footer'     => $edit['simple_subscription_form_footer'],
        'input_label'     => $edit['simple_subscription_input_label'],
        'input_size'      => $edit['simple_subscription_input_size'],
        'input_content'   => $edit['simple_subscription_input_content'],
        'submit_value'    => empty($edit['simple_subscription_submit_value']) ?
                              $default_config['submit_value'] :
                              $edit['simple_subscription_submit_value'],
        'success_message' => $edit['simple_subscription_success_message'],
        'redirect_path'   => $edit['simple_subscription_redirect_path'],
      ));
  }
}


/**
 * Implements hook_block_view().
 */
function simple_subscription_block_view($delta = '') {

  $return = array(
    'subject' => t('Subscription'),
    'content' => drupal_get_form('simple_subscription_form'),
  );

  return $return;
}


/**
 * Implements hook_trigger_info().
 */
function simple_subscription_trigger_info() {
  return array(
    'user' => array(
      'simple_subscription_submit' => array(
        'label' => t('A user subscribed an e-mail address using the simple_subscription block'),
      ),
    ),
  );
}


/**
 * Implements hook_token_info().
 */
function simple_subscription_token_info() {
  $tokens = array(
    'types'  => array(
      'simple-subscription' => array(
        'name'         => 'Simple subscription',
        'description'  => t('Simple subscription form data'),
        'needs-data'   => 'simple-subscription',
      ),
    ),
    'tokens' => array(
      'simple-subscription' => array(
        'email' => array(
          'name'  => t('Submitted email address'),
          'description' => t('Email address submitted using the <em>Simple subscription</em> block.'),
        ),
      ),
    ),
  );

  return $tokens;
}


/**
 * Implements hook_tokens().
 */
function simple_subscription_tokens($type, $tokens, array $data = array(), array $options = array()) {

  $return = array();
  if (($type != 'simple-subscription') || (!isset($data['simple-subscription']))) {
    return $return;
  }

  foreach ($tokens as $machine_name => $raw_text) {
    switch ($machine_name) {
      case 'email':
        if (isset($data['simple-subscription']['email'])) {
          $return[$raw_text] = $data['simple-subscription']['email'];
        }
        break;
      default:
        break;
    }
  }

  return $return;
}


/**
 * Returns the config form for our block
 *
 * If Token module is available, adds the standard fieldset with the available tokens
 *
 * @return
 *   The form array
 */
function simple_subscription_block_config_form() {

  $default_config = simple_subscription_get_default_values();
  $config = variable_get('simple_subscription_config', $default_config);

  $form = array();

  $form['simple_subscription_form_header'] = array(
    '#type'          => 'textarea',
    '#title'         => t('Form header'),
    '#default_value' => $config['form_header'],
    '#description'   => t('This text will be displayed before the form elements (leave empty for none). You may use Html tags.'),
  );

  $form['simple_subscription_form_footer'] = array(
    '#type'          => 'textarea',
    '#title'         => t('Form footer'),
    '#default_value' => $config['form_footer'],
    '#description'   => t('This text will be displayed after the form elements (leave empty for none). You may use Html tags.'),
  );

  $form['token_help'] = array(
    '#title'       => t('Replacement patterns for the text fields above'),
    '#type'        => 'fieldset',
    '#collapsible' => TRUE,
    '#collapsed'   => TRUE,
  );

  if (module_exists('token')) {
    $form['token_help']['token_tree'] = array(
      '#theme'        => 'token_tree',
      '#token_types' => token_get_global_token_types(),
    );
  }
  else {
    $form['token_help']['install_token'] = array(
      '#markup' => t('<p>Install the <a href="http://drupal.org/project/token" title="Token module project page">Token module</a> to see a list of the available tokens</p>'),
    );
  }

  $form['simple_subscription_input_label'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Input field label'),
    '#size'          => 20,
    '#default_value' => $config['input_label'],
    '#description'   => t('A label for the e-mail input field (Leave empty for none).'),
  );

  $form['simple_subscription_input_size'] = array(
    '#type'          => 'select',
    '#title'         => t('Input field size'),
    '#default_value' => $config['input_size'],
    '#description'   => t('Html size attribute for the e-mail input field.'),
    '#options'       => array(
      15  =>  '15',
      20  =>  '20',
      25  =>  '25',
      30  =>  '30',
      35  =>  '35',
      40  =>  '40',
      45  =>  '45',
      50  =>  '50'
    ),
  );

  $form['simple_subscription_input_content'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Input field text'),
    '#size'          => 20,
    '#default_value' => $config['input_content'],
    '#description'   => t('A short string to display inside the input field. This text is added by javascript and will only be visible if the field is empty and not focused (only on browsers with javascript activated). Be careful not to repeat the information you added in the field label above.'),
  );

  $form['simple_subscription_submit_value'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Submit button value'),
    '#size'          => 20,
    '#default_value' => $config['submit_value'],
    '#description'   => t('Contents for the form submit button. Cannot be empty and defaults to <em>@default_value</em>. No tokens are allowed.', array('@default_value' => $default_config['submit_value'])),
  );

  $form['simple_subscription_success_message'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Success message'),
    '#size'          => 60,
    '#default_value' => $config['success_message'],
    '#description'   => t('The message to display on successful e-mail submission (leave empty for none). You may use Html tags and you may use the aditionnal <em>[simple-subscription:email]</em> token.'),
  );

  $form['simple_subscription_redirect_path'] = array(
    '#type'             => 'textfield',
    '#title'            => t('Redirect path'),
    '#size'             => 60,
    '#default_value'    => $config['redirect_path'],
    '#description'      => t("The internal path to redirect the user to after a successful login. Use '/' for the front page, leave empty to stay on the same page."),
    '#element_validate' => array('simple_subscription_redirect_path_validate'),
  );

  return $form;
}


/**
 * Validation function for the redirect path field in the block configuration form.
 *
 * We don't accept external URLs (seems logical in this context, but I might be wrong).
 *
 * @param $element
 * @param $form_state
 */
function simple_subscription_redirect_path_validate($element, &$form_state) {
  if (!$element['#value']) {
    return;
  }
  else {
    $normal_path = drupal_get_normal_path($element['#value']);
    if (url_is_external($normal_path)) {
      form_set_error('simple_subscription_redirect_path',
        t("Invalid redirect path <em>@redirect_path</em>. Only internal redirections can be added.", array(
          '@redirect_path' => $element['#value']
          ))
      );
    }
  }
}


/**
 * The simple_subscription form.
 *
 * As will all forms in D7, you can theme this one by declaring a
 * 'simple_subscription_form' theme function or template in your
 * theme layer.
 *
 * @return
 *   The form array.
 */
function simple_subscription_form() {

  $default_config = simple_subscription_get_default_values();
  $config = variable_get('simple_subscription_config', $default_config);

  $form = array();

  $global_token_types = module_exists('token') ?
    token_get_global_token_types() :
    array('current-date', 'current-page', 'current-user', 'default-format', 'site');

  if (!empty($config['form_header'])) {
    $form['header'] = array(
      '#prefix'   =>  '<div class="simple_subscription_header">',
      '#markup'  => token_replace($config['form_header']),
      '#suffix'   =>  '</div>',
    );
  }

  /*
   * e-mail input field
   */
  $form['input'] = array(
    '#type'           => 'textfield',
    '#default_value'  => '',
    '#maxlength'      => 255,
    '#size'           => $config['input_size'],
    '#required'       => TRUE,
    '#element_validate' => array('simple_subscription_email_validate'),
  );

  /*
   * Add JS behavior if the input_content field is not empty
   */
  $input_content = trim($config['input_content']);
  if (!empty($input_content)) {
    $form['input']['#attached']['js'][] = drupal_get_path('module', 'simple_subscription') . '/simple_subscription.js';
    $form['input']['#attached']['js'][] = array(
      'data'  => array(
        'simple_subscription' => array('input_content' => ($input_content))
      ),
      'type'  => 'setting',
    );
    $form['input']['#attached']['css'][] = drupal_get_path('module', 'simple_subscription') . '/simple_subscription.css';
  }

  if (!empty($config['form_footer'])) {
    $form['footer'] = array(
      '#prefix'   =>  '<div class="simple_subscription_footer">',
      '#markup'  => token_replace(trim($config['form_footer'])),
      '#suffix'   =>  '</div>',
    );
  }

  $form['submit'] = array(
    '#type'  => 'submit',
    '#value' => token_replace(trim($config['submit_value'])),
  );

  return $form;
}


/**
 * Validation function for the simple_subscription form.
 *
 * We validate e-mail address using the default Drupal function valid_email_address().
 *
 * @param string $form
 * @param string $form_state
 * @return void
 */
function simple_subscription_email_validate($element, &$form_state, $form) {
  if (empty($element['#value']) || !valid_email_address($element['#value'])) {
    form_set_error('input',
      t("Invalid e-mail address '@submitted_email'. Please verify your syntax.",
        array('@submitted_email' => check_plain($element['#value']))
    ));
  }
}


/**
 * Submit function for the simple_subscription form.
 *
 * We invoke all the modules hooked on hook_simple_subscription, trigger all the actions
 * associated with the form submition and display the configured success message.
 *
 * @param string $form_id
 * @param string $form_values
 * @return void
 */
function simple_subscription_form_submit($form, &$form_state) {

  $default_config = simple_subscription_get_default_values();
  $config = variable_get('simple_subscription_config', $default_config);

  $data = array(
    'simple-subscription' => array(
      'email'  => $form_state['values']['input'],
    ),
  );


  /*
   * Implements hook_simple_subscription().
   */
  module_invoke_all('simple_subscription', 'simple_subscription_submit', $data);

  $msg = trim($config['success_message']);
  if (!empty($msg)) {
    /*
     * TODO check sanitation on this.
     */
    drupal_set_message(token_replace($config['success_message'], $data));
  }

  $aids = trigger_get_assigned_actions('simple_subscription_submit');
  // prepare a basic context, indicating group and "hook", and call all the
  // actions with this context as arguments.
  $context = array(
    'group' => 'user',
    'hook'  => 'simple_subscription_submit',
  );
  $context += $data;

  actions_do(array_keys($aids), NULL, $context);

  $path = trim($config['redirect_path']);
  if ($path) {
    $form_state['redirect'] = drupal_get_normal_path($path);
  }
}


/**
 * Returns the simple_subscription default values.
 *
 * @return
 *   An array with the block's default values
 */
function simple_subscription_get_default_values() {

  return array(
    'form_header'     => t('Enter your e-mail address below.'),
    'form_footer'     => t('Opt-out instructions are included in each e-mail.'),
    'input_label'     => '',
    'input_size'      => 20,
    'input_content'   => t('e-mail address'),
    'submit_value'    => t('Subscribe'),
    'success_message' => t('Thank you for subscribing'),
    'redirect_path'   => '',
  );
}
