You are here

uc_ajax_cart.module in Ubercart AJAX Cart 6.2

Same filename and directory in other branches
  1. 5 uc_ajax_cart.module
  2. 6 uc_ajax_cart.module
  3. 7.2 uc_ajax_cart.module

File

uc_ajax_cart.module
View source
<?php

define('UC_AJAX_CART_ADD_CALLBACK', 'uc_ajax_cart/add/item');
define('UC_AJAX_CART_REMOVE_CALLBACK', 'uc_ajax_cart/remove/item');
define('UC_AJAX_CART_SHOW_CALLBACK', 'uc_ajax_cart/show');
define('UC_AJAX_CART_LINK_CALLBACK', 'uc_ajax_cart/addlink');
define('UC_AJAX_CART_UPDATE_CALLBACK', 'uc_ajax_cart/update');
define('UC_AJAX_CART_SHOW_VIEW_CALLBACK', 'uc_ajax_cart/show-cart-view');
define('UC_AJAX_CART_DEFAULT_TIMEOUT', 3000);
define('UC_AJAX_CART_DEFAULT_EFFECT', 1);
define('UC_AJAX_CART_DEFAULT_PANE_EFFECT_DURATION', 200);
require_once 'uc_ajax_cart.php';
function uc_ajax_cart_perm() {
  return array(
    'show uncached cart',
    'use cart',
  );
}
function uc_ajax_cart_menu() {

  /** Default Settings URL **/
  $items['admin/store/settings/uc_ajax_cart'] = array(
    'title' => 'UC Ajax cart settings',
    'description' => 'Configure the uc ajax cart settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'uc_ajax_cart_settings_overview',
    ),
    'access arguments' => array(
      'administer store',
    ),
    'file' => 'uc_ajax_cart.admin.inc',
  );
  $items[UC_AJAX_CART_ADD_CALLBACK] = array(
    'page callback' => 'uc_ajax_cart_callback',
    'page arguments' => array(
      'add',
    ),
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  $items[UC_AJAX_CART_REMOVE_CALLBACK] = array(
    'page callback' => 'uc_ajax_cart_callback',
    'page arguments' => array(
      'remove',
    ),
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  $items[UC_AJAX_CART_SHOW_CALLBACK] = array(
    'page callback' => 'uc_ajax_cart_callback',
    'page arguments' => array(
      'show',
    ),
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  $items[UC_AJAX_CART_LINK_CALLBACK] = array(
    'page callback' => 'uc_ajax_cart_callback',
    'page arguments' => array(
      'link',
    ),
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
    'file' => 'uc_cart_links.pages.inc',
  );
  $items[UC_AJAX_CART_UPDATE_CALLBACK] = array(
    'page callback' => 'uc_ajax_cart_callback',
    'page arguments' => array(
      'update',
    ),
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  $items[UC_AJAX_CART_SHOW_VIEW_CALLBACK] = array(
    'page callback' => 'uc_ajax_cart_callback',
    'page arguments' => array(
      'show-cart-view',
    ),
    'access arguments' => array(
      'access content',
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}
function uc_ajax_cart_callback($op, $nid = NULL, $data = NULL) {

  // No caching for this URL.
  global $conf;
  $conf['cache'] = FALSE;
  header('Cache-Control: private, no-cache, no-store, must-revalidate, max-age=0');
  header('Pragma: no-cache');
  switch ($op) {
    case 'remove':
      uc_ajax_cart_remove_item($_GET['nid'], unserialize(base64_decode($_GET['data'])));
      print theme('status_messages');
      break;
    case 'add':
      uc_ajax_cart_add_item($_POST);
      print theme('status_messages');
      break;
    case 'show':
      uc_ajax_cart_show_cart();
      break;
    case 'show-cart-view':
      include_once drupal_get_path('module', 'uc_cart') . '/uc_cart.pages.inc';
      print uc_cart_view();
      break;
    case 'update':
      if ($_POST) {
        $formValues = array(
          'values' => $_POST,
        );
        $cart = new UcAjaxCart();
        $items = $cart
          ->getCartContents();
        drupal_execute('uc_cart_view_form', $formValues, $items);
        print theme('status_messages');
      }
      break;
    case 'link':
      if (module_exists('uc_cart_links')) {
        $link = array_pop(explode('/', $_GET['href']));
        uc_ajax_cart_links_process($link);
      }
      else {
        drupal_set_message(t('Sorry link is not valid'), 'error');
      }
      print theme('status_messages');
      break;
  }
}
function uc_ajax_cart_show_cart() {
  $cartContent = uc_cart_get_contents();
  if (count($cartContent) > 0) {
    print theme('uc_ajax_cart_block_content', $cartContent);
  }
  else {
    print theme('uc_ajax_cart_block_content_empty', $cartContent);
  }
}
function uc_ajax_cart_remove_item($nid, $data) {
  $cart = new UcAjaxCart();
  try {
    $cart
      ->removeItemFromCart($nid, $data);
  } catch (NoProductException $ex) {
    drupal_set_message(t('No valid product'));
  } catch (CartException $ex) {
    foreach ($ex
      ->getMessages() as $message) {
      drupal_set_message($message, 'warning');
    }
  }
}
function uc_ajax_cart_add_item($data) {

  // Protect agains bad calls.
  if (!isset($data['form_id'])) {
    return;
  }
  if (!isset($data['qty'])) {
    $data['qty'] = 1;
  }
  $formID = explode('_', $data['form_id']);
  $nodeID = array_pop($formID);
  $formID = implode('_', $formID);
  $product = node_load($nodeID);
  uc_product_load($product);
  $formValues = array(
    'values' => $data,
  );
  drupal_execute($data['form_id'], $formValues, $product);
  return;
}
function uc_ajax_cart_theme() {
  return array(
    'uc_ajax_cart_block' => array(
      'arguments' => array(
        'title' => NULL,
        'collapsible' => FALSE,
      ),
      'file' => 'uc_ajax_cart.theme.inc',
    ),
    'uc_ajax_cart_block_header' => array(
      'arguments' => array(
        'text' => NULL,
        'hasItems' => NULL,
      ),
      'file' => 'uc_ajax_cart.theme.inc',
    ),
    'uc_ajax_cart_block_content' => array(
      'arguments' => array(
        'items' => NULL,
      ),
      'template' => 'templates/uc_ajax_cart_block_content',
      'file' => 'uc_ajax_cart.theme.inc',
    ),
    'uc_ajax_cart_block_content_empty' => array(
      'arguments' => array(
        'items' => NULL,
      ),
      'template' => 'templates/uc_ajax_cart_block_content_empty',
    ),
    'uc_ajax_cart_cart_links' => array(
      'file' => 'uc_ajax_cart.theme.inc',
    ),
    'uc_ajax_cart_messages' => array(
      'arguments' => array(
        'messages' => NULL,
      ),
      'template' => 'templates/uc_ajax_cart_messages',
    ),
    'uc_ajax_cart_block_content_cached' => array(
      'arguments' => array(
        'total' => NULL,
        'collapsible' => FALSE,
      ),
      'file' => 'uc_ajax_cart.theme.inc',
    ),
  );
}
function uc_ajax_cart_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {

    // Retrieve block informations
    $blocks[0] = array(
      'info' => t('Ajax shopping cart'),
      'cache' => BLOCK_NO_CACHE,
    );
    return $blocks;
  }
  elseif ($op == 'view') {

    // Add standard JS if we are to enable ajax only when block is visible
    // Otherwise, _uc_ajax_cart_init() gets called from hook_init().
    if (variable_get('uc_ajax_cart_enably_only_when_visible', FALSE)) {
      _uc_ajax_cart_init();
    }

    //Only a wrapper to uc_cart_block
    $cartContent = uc_cart_get_contents();
    if (count($cartContent) > 0) {
      $hasItems = TRUE;
    }
    $content['subject'] = theme('uc_ajax_cart_block_header', $hasItems);
    global $user;
    $cacheEnabled = variable_get('cache', 0);
    $loadOnPageView = variable_get($user->uid ? 'uc_ajax_cart_registered_users_cart_cached_load' : 'uc_ajax_cart_cart_cached_load', 0);
    $loadOnPageViewClass = $loadOnPageView ? ' class="load-on-view"' : '';

    // Anonymous users w/ page caching caching get a cached block.
    if (!$user->uid && $cacheEnabled > 0) {
      $content['content'] = '<div id="ajaxCartUpdate" ' . $loadOnPageViewClass . '>' . theme('uc_ajax_cart_block_content_cached') . '</div>';
    }
    elseif ($hasItems == TRUE) {
      $content['content'] = '<div id="ajaxCartUpdate" ' . $loadOnPageViewClass . '>' . theme('uc_ajax_cart_block_content', $cartContent) . '</div>';
    }
    else {
      $content['content'] = '<div id="ajaxCartUpdate" ' . $loadOnPageViewClass . '>' . theme('uc_ajax_cart_block_content_empty') . '</div>';
    }
    return $content;
  }
  elseif ($op == 'configure') {
    $form['text'] = array(
      '#title' => t('Ajax cart settings'),
      '#type' => 'fieldset',
      '#description' => t('Advanced settings for ajax cart are !here', array(
        '!here' => l(t('here'), 'admin/store/settings/uc_ajax_cart'),
      )),
    );
    return $form;
  }
}
function uc_ajax_cart_get_messages() {
  $defaults = array(
    'ADD_MESSAGES' => array(
      t('Adding product to cart...'),
    ),
    'ADD_TITLE' => '',
    'REMOVE_MESSAGES' => array(
      t('Removing product from cart...'),
    ),
    'REMOVE_TITLE' => '',
    'UPDATE_MESSAGES' => array(
      t('Updating cart...'),
    ),
    'UPDATE_TITLE' => '',
    'CART_OPERATION' => '',
  );
  $messages = variable_get('uc_ajax_cart_messages', array());
  $messages += $defaults;
  return $messages;
}

/**
 * Implements hook_init().
 */
function uc_ajax_cart_init() {
  $item = menu_get_item();
  if ($item['page_callback'] == 'block_admin_display') {

    // Do not initialize on block admin page; see https://drupal.org/node/219910
    return;
  }

  // Add standard JS if we are to always enable ajax functionality
  // Otherwise, _uc_ajax_cart_init() gets called from hook_block().
  if (!variable_get('uc_ajax_cart_enably_only_when_visible', FALSE)) {
    _uc_ajax_cart_init();
  }
}

/**
 * Contains the initialization logic for uc_ajax_cart. Called upon by either
 * hook_init() (for always-enabled ajax functionality) or hook_block (for ajax
 * only when the block is present on the page).
 */
function _uc_ajax_cart_init() {
  static $loaded;
  if (isset($loaded) && $loaded === TRUE) {
    return;
  }
  drupal_add_js('misc/jquery.form.js');
  drupal_add_js(drupal_get_path('module', 'uc_ajax_cart') . '/js/jquery.blockUI.js');
  drupal_add_js(drupal_get_path('module', 'uc_ajax_cart') . '/js/uc_ajax_cart.js');
  drupal_add_js(drupal_get_path('module', 'uc_ajax_cart') . '/js/jquery.cookie.js');
  drupal_add_css(drupal_get_path('module', 'uc_ajax_cart') . '/css/uc_ajax_cart.css');
  $settings = array(
    'CALLBACK' => url(UC_AJAX_CART_ADD_CALLBACK),
    'SHOW_CALLBACK' => url(UC_AJAX_CART_SHOW_CALLBACK),
    'CART_LINK_CALLBACK' => url(UC_AJAX_CART_LINK_CALLBACK),
    'BLOCK_UI' => (int) variable_get('ajax_cart_message_effect', UC_AJAX_CART_DEFAULT_EFFECT),
    'TIMEOUT' => (int) variable_get('ajax_cart_message_timeout', UC_AJAX_CART_DEFAULT_TIMEOUT),
    'UPDATE_CALLBACK' => url(UC_AJAX_CART_UPDATE_CALLBACK),
    'UPDATE' => variable_get('uc_ajax_cart_closed_update', 0),
    'CART_VIEW_ON' => variable_get('uc_ajax_cart_cart_view', 0),
    'SHOW_VIEW_CALLBACK' => url(UC_AJAX_CART_SHOW_VIEW_CALLBACK),
    'TRACK_CLOSED_STATE' => variable_get('uc_ajax_cart_track_closed_state', 0),
    'INITIAL_CLOSED_STATE' => variable_get('uc_ajax_cart_closed_default', FALSE),
    'CART_PANE_EFFECT' => variable_get('uc_ajax_cart_pane_effect', 0),
    'CART_PANE_EFFECT_DURATION' => (int) variable_get('uc_ajax_cart_pane_effect_duration', UC_AJAX_CART_DEFAULT_PANE_EFFECT_DURATION),
    'HIDE_CART_OPERATIONS' => variable_get('uc_ajax_cart_hide_cart_op_msgs', FALSE),
    'COLLAPSIBLE_CART' => variable_get('uc_ajax_cart_closed', 0),
  );
  $settings += uc_ajax_cart_get_messages();
  if (($include_exclude = variable_get('uc_ajax_cart_include_exclude', 0)) && ($ajaxify_class = variable_get('uc_ajax_cart_ajaxify_class', ''))) {
    $settings['AJAXIFY_CLASS_EXCLUDES'] = $include_exclude - 1;
    $settings['AJAXIFY_CLASS'] = $ajaxify_class;
  }
  drupal_add_js(array(
    'uc_ajax_cart' => $settings,
  ), 'setting');
  $loaded = TRUE;
}
function uc_ajax_cart_form_uc_cart_links_settings_form_alter(&$form) {
  $form['instructions']['#value'] .= '<div><strong>' . t('Ajax Cart driven cart links') . '</strong><div>' . t('For use with Ajax Cart add class <em>ajax-cart-link</em> to links.') . '</div></div>';
}
function uc_ajax_cart_alter_cart_form(&$form, $formState, $formId) {
  if (preg_match('/^uc_catalog_buy_it_now_form_/', $formId)) {
    $ucAjaxCart = new UcAjaxCart();
    $product = node_load($form['nid']['#value']);
    uc_product_load($product);
    if ($product->type == 'product_kit') {

      //@todo: Must be implemented
    }
    else {
      if ($ucAjaxCart
        ->hasAttributes($product)) {
        $form['submit']['#value'] = t('Please choose an option');
        return;
      }
    }
  }
  if (!is_array($form['#attributes'])) {
    $form['#attributes'] = array();
  }
  $form['product-nid'] = array(
    '#type' => 'hidden',
    '#value' => $form['nid']['#value'],
  );
  $form['#attributes']['class'] .= 'ajax-cart-submit-form';
  $form['submit']['#attributes']['class'] .= ' ajax-cart-submit-form-button';
}

/**
 * Implements hook_prepreocess_block.
 *
 * Sets right block title markup when title is overriden by user.
 */
function uc_ajax_cart_preprocess_block(&$vars, $hook) {
  if ($hook == 'block' && $vars['block']->module == 'uc_ajax_cart' && !empty($vars['block']->title) && $vars['block']->title != '<none>') {
    $vars['block']->subject = _theme_uc_ajax_cart_block_header($vars['block']->title);
  }
}
function uc_ajax_cart_form_alter(&$form, $form_state, $form_id) {
  if (preg_match('/^uc_product_add_to_cart_form_/', $form_id) || preg_match('/^uc_catalog_buy_it_now_form_/', $form_id) || preg_match('/^uc_product_kit_add_to_cart_form/', $form_id)) {
    uc_ajax_cart_alter_cart_form($form, $form_state, $form_id);
  }
  elseif ('uc_cart_view_form' == $form_id) {

    // Ajaxify cart page?
    if (variable_get('uc_ajax_cart_ajaxify_cart_page', 1)) {
      drupal_add_js(array(
        'uc_ajax_cart' => array(
          'AJAXIFY_CART_PAGE' => TRUE,
        ),
      ), 'setting');

      // Hide update cart button?
      $form['update']['#attributes']['class'] .= ' ' . (variable_get('uc_ajax_cart_hide_update_cart_bt', 0) ? 'uc-ajax-cart-hidden-update-bt ' : '') . 'ajax-cart-submit-form-button';
    }
  }
}

/**
 * Implemetnation of hook_theme_registry_alter.
 *
 * Alters theme registry to use our empty shopping cart theme functions.
 */
function uc_ajax_cart_theme_registry_alter(&$theme_registry) {
  if (!empty($theme_registry['uc_empty_cart'])) {
    $theme_registry['uc_empty_cart']['function'] = 'uc_ajax_uc_empty_cart';
  }
}

/**
 * Return the text displayed for an empty shopping cart.
 *
 * It's the same from Ubercart but with cart-form-pane id added, so Aajx Cart block can locate cart form placeholder.
 * #1238594 buf fix.
 *
 * @ingroup themeable
 */
function uc_ajax_uc_empty_cart() {
  return '<p id="cart-form-pane">' . t('There are no products in your shopping cart.') . '</p>';
}

/**
* Implements hook_exit().
*
* Code from CacheExclude - http://drupal.org/project/cacheexclude
*/
function uc_ajax_cart_exit() {
  global $base_root;
  $pages = array(
    'uc_ajax_cart',
    UC_AJAX_CART_ADD_CALLBACK,
    UC_AJAX_CART_REMOVE_CALLBACK,
    UC_AJAX_CART_SHOW_CALLBACK,
    UC_AJAX_CART_LINK_CALLBACK,
    UC_AJAX_CART_UPDATE_CALLBACK,
    UC_AJAX_CART_SHOW_VIEW_CALLBACK,
  );
  $this_page = request_uri();
  foreach ($pages as $page) {
    if ($page && strstr($this_page, $page) !== FALSE) {
      cache_clear_all($base_root . $this_page, 'cache_page');
      return;
    }
  }
}

/**
 * Implements hook_add_to_cart().
 */
function uc_ajax_cart_add_to_cart($nid, $qty, $data) {
  if (module_exists('uc_attribute')) {
    $atts = uc_product_get_attributes($nid);
    if (!is_array($atts) || count($atts) == 0) {
      return;
    }
    if (!is_array($data) || !is_array($data['attributes'])) {
      $data['attributes'] = array();
    }
    $attsSubmitted = $data['attributes'];
    foreach ($atts as $key => $att) {
      if (!$att->required) {
        continue;
      }
      if (!isset($data['attributes'][$att->aid]) || empty($data['attributes'][$att->aid])) {
        return array(
          array(
            'success' => FALSE,
            'message' => t('You must specify an option for !attribute', array(
              '!attribute' => $att->name,
            )),
          ),
        );
      }
    }
  }
}