You are here

uc_product_panes.module in Ubercart Product Checkout Panes 6

Same filename and directory in other branches
  1. 7 uc_product_panes.module

uc_product_panes.module

Ubercart Product Checkout Panes.

File

uc_product_panes.module
View source
<?php

/**
 * @file uc_product_panes.module
 * 
 * Ubercart Product Checkout Panes.
 */

/**
 * Implementation of hook_form_alter().
 */
function uc_product_panes_form_alter(&$form, &$form_state, $form_id) {

  // Add default Panes settings to the product class form
  if ($form_id == 'uc_product_class_form') {
    $pcid = $form['pcid']['#value'];

    // Build the core fieldset
    $form['ucpp'] = array(
      '#type' => 'fieldset',
      '#title' => t('Default Product Panes'),
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#weight' => 7,
    );
    $form['ucpp']['default_ucpp'] = array(
      '#type' => 'checkbox',
      '#title' => t('Check this box to set the default panes for every product of this class.'),
      '#default_value' => variable_get('ucpp_class_' . $pcid, 0),
    );

    // Get the panes and build the table display
    $panes = _checkout_pane_list();
    $form['ucpp']['panes'] = array(
      '#theme' => 'uc_pane_sort_table',
      '#pane_prefix' => 'uc_pane',
      '#summary callback' => '_uc_cart_panes_summarize',
      '#summary arguments' => array(
        $panes,
      ),
    );

    // Set the default values for each pane
    foreach ($panes as $pane) {
      $form['ucpp']['panes'][$pane['id']]['uc_pane_' . $pane['id'] . '_enabled'] = array(
        '#type' => 'checkbox',
        '#title' => $pane['title'],
        '#default_value' => variable_get('ucpp_class_' . $pcid . '_pane_' . $pane['id'] . '_enabled', variable_get('uc_pane_' . $pane['id'] . '_enabled', TRUE)),
      );
      $form['ucpp']['panes'][$pane['id']]['uc_pane_' . $pane['id'] . '_weight'] = array(
        '#value' => variable_get('uc_pane_' . $pane['id'] . '_weight', 0),
      );
    }
    $form['#submit'][] = 'uc_product_panes_product_class_submit';
    $form['submit']['#weight'] = 10;
  }
}

/**
 * Submit handler for the product class default Panes form.
 */
function uc_product_panes_product_class_submit($form, &$form_state) {
  $pcid = $form_state['values']['pcid'];
  if ($form_state['values']['default_ucpp']) {

    // Enable the feature for the class
    variable_set('ucpp_class_' . $pcid, 1);

    // Save the individual pane settings
    foreach (element_children($form['ucpp']['panes']) as $pane_id) {
      variable_set('ucpp_class_' . $pcid . '_pane_' . $pane_id . '_enabled', $form_state['values']['uc_pane_' . $pane_id . '_enabled']);
    }
  }
  else {

    // Disable the feature for the given class
    variable_del('ucpp_class_' . $pcid);

    // Clear the individual pane settings
    foreach (element_children($form['panes']) as $pane_id) {
      variable_del('ucpp_class_' . $pcid . '_pane_' . $pane_id . '_enabled');
    }
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function uc_product_panes_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {

  // Create a default product feature automatically from the default setting
  if ($op == 'insert' && uc_product_is_product($node)) {

    // If the product class has default checkout panes set
    if (variable_get('ucpp_class_' . $node->type, 0)) {

      // Prepare the data as if it were from a form submission.
      $data = array();
      $data['nid'] = $node->nid;
      $data['pfid'] = '';
      $data['class'] = $node->type;
      $form_state = array(
        'values' => $data,
      );

      // Also fake the form so that the panes can be retrieved
      $panes = _checkout_pane_list();
      foreach ($panes as $pane) {
        $form_panes[$pane['id']] = $pane['id'];
      }
      $form = array(
        'panes' => $form_panes,
      );

      // Add the feature to the product by spoofing the normal form submission.
      uc_product_panes_feature_form_submit($form, $form_state);
    }
  }

  // Remove all ucpp settings for the deleted node
  if ($op == 'delete' && uc_product_is_product($node)) {
    db_query("DELETE FROM {uc_product_panes} WHERE nid = %d", $node->nid);
  }
}

/**
 * Implementation of hook_product_feature().
 */
function uc_product_panes_product_feature() {
  $features[] = array(
    'id' => 'panes',
    'title' => t('Product Panes'),
    'callback' => 'uc_product_panes_feature_form',
    'delete' => 'uc_product_panes_feature_delete',
  );
  return $features;
}

/**
 * This form gets displayed when a product feature is added or edited for this product feature type.
 */
function uc_product_panes_feature_form($form_state, $node, $feature) {
  $form['nid'] = array(
    '#type' => 'hidden',
    '#value' => $node->nid,
  );

  // Get the panes and the saved settings
  if (!empty($feature) && $feature['pfid']) {
    $ppanes = uc_product_panes_values_load($feature['pfid']);
    $default_model = uc_product_panes_get_model($feature['pfid']);
  }

  // Get the different SKU's of the product.
  $models = uc_product_get_models($node);
  $form['model'] = array(
    '#type' => 'select',
    '#title' => t('SKU'),
    '#default_value' => $default_model ? $default_model : '',
    '#description' => t('This is the SKU of the product that show these panes.'),
    '#options' => $models,
  );

  // Build the table display
  $panes = _checkout_pane_list();
  $form['panes'] = array(
    '#theme' => 'uc_pane_sort_table',
    '#pane_prefix' => 'uc_pane',
    '#summary callback' => '_uc_cart_panes_summarize',
    '#summary arguments' => array(
      $panes,
    ),
  );

  // Set the default values for each pane
  foreach ($panes as $pane) {
    $form['panes'][$pane['id']]['uc_pane_' . $pane['id'] . '_enabled'] = array(
      '#type' => 'checkbox',
      '#title' => $pane['title'],
      '#default_value' => isset($ppanes[$pane['id']]['enabled']) ? $ppanes[$pane['id']]['enabled'] : $pane['enabled'],
    );
    $form['panes'][$pane['id']]['uc_pane_' . $pane['id'] . '_weight'] = array(
      '#value' => $pane['weight'],
    );
  }
  return uc_product_feature_form($form);
}

/**
 * Validation function for the ucpp feature form.
 */
function uc_product_panes_feature_form_validate($form, &$form_state) {

  // Check if a feature has already been added for the SKU
  if ($form_state['values']['pfid'] == 0 && ($product_roles = db_result(db_query("SELECT pfid FROM {uc_product_panes} WHERE nid = %d AND model = '%s'", $form_state['values']['nid'], $form_state['values']['model'])))) {
    form_set_error('model', t('The product panes feature is already set for this model of the product.'));
  }
}

/**
 * Submission function for the ucpp feature form.
 */
function uc_product_panes_feature_form_submit($form, &$form_state) {

  // Use the form specified pfid if available.
  if (!empty($form_state['values']['pfid'])) {
    $pfid = $form_state['values']['pfid'];
  }
  $description = t('Custom checkout panes for the product.<br />');
  $description .= !isset($form_state['values']['model']) || $form_state['values']['model'] == '' ? t('<strong>SKU:</strong> Any - This will NOT override the model-specific features.<br />') : t('<strong>SKU:</strong> !sku<br />', array(
    '!sku' => $form_state['values']['model'],
  ));
  $data = array(
    'pfid' => $form_state['values']['pfid'],
    'nid' => $form_state['values']['nid'],
    'fid' => 'panes',
    'description' => $description,
  );

  // Save the product feature and store the returned URL as our redirect.
  $form_state['redirect'] = uc_product_feature_save($data);

  // Get the panes settings
  $panes = array();
  foreach (element_children($form['panes']) as $pane_id) {
    $pane = new stdClass();
    $pane->pane_id = $pane_id;
    $pane->enabled = isset($form_state['values']['class']) ? variable_get('ucpp_class_' . $form_state['values']['class'] . '_pane_' . $pane_id . '_enabled', TRUE) : $form_state['values']['uc_pane_' . $pane_id . '_enabled'];
    $panes[] = $pane;
  }
  if (empty($pfid)) {
    $pfid = db_result(db_query("SELECT MAX(pfid) FROM {uc_product_features} WHERE nid = %d AND fid = 'panes'", $form_state['values']['nid']));
  }

  // Save the feature settings for this particular product
  $pp = new stdClass();
  $pp->pfid = $pfid;
  $pp->nid = $form_state['values']['nid'];
  $pp->model = isset($form_state['values']['model']) ? $form_state['values']['model'] : '';
  $pp->panes = $panes;
  uc_product_panes_values_save($pp);
}

/**
 * This function gets called when a feature of this type is deleted.
 */
function uc_product_panes_feature_delete($pfid) {
  db_query("DELETE FROM {uc_product_panes} WHERE pfid = %d", $pfid);
}

/**
 * Loads feature configuration values for the product.
 */
function uc_product_panes_values_load($pfid) {
  $rs = db_query("SELECT pane_id, enabled FROM {uc_product_panes} WHERE pfid = %d", $pfid);
  $ppanes = array();
  while ($row = db_fetch_object($rs)) {
    $ppanes[$row->pane_id] = get_object_vars($row);
  }
  return $ppanes;
}

/**
 * Saves feature configuration values for the product.
 *
 * @param $pp
 *   The product panes configuration object.
 */
function uc_product_panes_values_save($pp) {
  db_query("DELETE FROM {uc_product_panes} WHERE pfid = %d", $pp->pfid);
  foreach ($pp->panes as $pane) {
    $pane->pfid = $pp->pfid;
    $pane->nid = $pp->nid;
    $pane->model = $pp->model;
    drupal_write_record('uc_product_panes', $pane);
  }
}

/**
 * Get product panes feature id for a specific node.
 */
function uc_product_panes_get_pfid($nid, $model) {
  $model_pfid = db_result(db_query("SELECT pfid FROM {uc_product_features} NATURAL JOIN {uc_product_panes} WHERE nid = %d AND model = '%s' AND fid = 'panes'", $nid, $model));
  if ($model_pfid) {
    return $model_pfid;
  }
  else {
    return db_result(db_query("SELECT pfid FROM {uc_product_features} NATURAL JOIN {uc_product_panes} WHERE nid = %d AND model = '' AND fid = 'panes'", $nid));
  }
}

/**
 * Get product panes model for the given node and feature id.
 */
function uc_product_panes_get_model($pfid) {
  return db_result(db_query("SELECT model FROM {uc_product_panes} WHERE pfid = %d", $pfid));
}

/**
 * Implementation of drupal_alter('checkout_pane', $panes).
 */
function uc_product_panes_checkout_pane_alter(&$panes) {
  $items = uc_cart_get_contents();

  // If this is node feature form, create a fake items array to get the correct class
  $menu_item = menu_get_item();
  if ($menu_item['page_callback'] == 'uc_product_features' && $menu_item['page_arguments'][1] == 'panes') {
    $item = new stdClass();
    $item->nid = $menu_item['page_arguments'][0]->nid;
    $items = array(
      $item,
    );
  }

  // Disable all panes first
  foreach ($panes as $pid => $pvalues) {
    $panes[$pid]['enabled'] = 0;
  }

  // Re-enable based on either product-specific feature, class-specific settings, or default settings otherwise
  foreach ($items as $item) {

    // Load the product-specific feature, if set
    $ppanes = array();
    $node = node_load($item->nid);
    $pfid = uc_product_panes_get_pfid($item->nid, $item->model);
    if ($pfid) {
      $ppanes = uc_product_panes_values_load($pfid);
    }

    // Re-configure each pane using our settings
    foreach ($panes as $pid => $pane) {

      // Enable the pane if any of the global, class or product settings is selected
      if ($ppanes) {
        if ($ppanes[$pane['id']]['enabled']) {
          $panes[$pid]['enabled'] = 1;
        }
      }
      else {
        if (variable_get('ucpp_class_' . $node->type, 0)) {
          if (variable_get('ucpp_class_' . $node->type . '_pane_' . $pane['id'] . '_enabled', 0)) {
            $panes[$pid]['enabled'] = 1;
          }
        }
        else {
          if (variable_get('uc_pane_' . $pane['id'] . '_enabled', TRUE)) {
            $panes[$pid]['enabled'] = 1;
          }
        }
      }
    }
  }
}

Functions

Namesort descending Description
uc_product_panes_checkout_pane_alter Implementation of drupal_alter('checkout_pane', $panes).
uc_product_panes_feature_delete This function gets called when a feature of this type is deleted.
uc_product_panes_feature_form This form gets displayed when a product feature is added or edited for this product feature type.
uc_product_panes_feature_form_submit Submission function for the ucpp feature form.
uc_product_panes_feature_form_validate Validation function for the ucpp feature form.
uc_product_panes_form_alter Implementation of hook_form_alter().
uc_product_panes_get_model Get product panes model for the given node and feature id.
uc_product_panes_get_pfid Get product panes feature id for a specific node.
uc_product_panes_nodeapi Implementation of hook_nodeapi().
uc_product_panes_product_class_submit Submit handler for the product class default Panes form.
uc_product_panes_product_feature Implementation of hook_product_feature().
uc_product_panes_values_load Loads feature configuration values for the product.
uc_product_panes_values_save Saves feature configuration values for the product.