Skip to content
commerce_popular_products.module 8.51 KiB
Newer Older
Anthony Lindsay's avatar
Anthony Lindsay committed
<?php

/**
 * @file
Anthony Lindsay's avatar
Anthony Lindsay committed
 * Block content based upon popular products this month
 */

/**
 * Build up a query based upon settings and retrieve products.
 */
Anthony Lindsay's avatar
Anthony Lindsay committed
function commerce_popular_products_get_product() {
  $output = '';
  // Fetch settings for use.
Anthony Lindsay's avatar
Anthony Lindsay committed
  $time = variable_get('commerce_popular_products_time', $default = 'month');
  $number = variable_get('commerce_popular_products_number', $default = '1');
  $products = variable_get('commerce_popular_products_products');
    // Gather information on all the Commerce product reference fields in use.
    $fields = field_info_fields();
    $product_references = array();
    foreach ($fields as $key => $field) {
      if ($field['type'] == 'commerce_product_reference') {
        if ($key != 'commerce_product') {
          $product_references[] = $key;
        }
Anthony Lindsay's avatar
Anthony Lindsay committed
      }
    }
    // Turn the time period into something we can use with FROM_UNIXTIME().
    $time_period = '';
Anthony Lindsay's avatar
Anthony Lindsay committed
    switch ($time) {
      case 'day':
Anthony Lindsay's avatar
Anthony Lindsay committed
        break;
Anthony Lindsay's avatar
Anthony Lindsay committed
      case 'week':
Anthony Lindsay's avatar
Anthony Lindsay committed
        break;
Anthony Lindsay's avatar
Anthony Lindsay committed
      case 'month':
Anthony Lindsay's avatar
Anthony Lindsay committed
        break;
    // Create an array to hold all our results for different product types.
    $all_results = array();
    // For each product reference type.
    foreach ($product_references as $table) {
      // Build query to find the most bought product for the current month.
      $query = db_select('commerce_order', 'co');
      $query->join('commerce_line_item', 'cli', 'cli.order_id = co.order_id');
      $query->join('commerce_product', 'cp', 'cp.sku = cli.line_item_label');
      // Add in joins to field data tables for all the product reference fields.
      $query->rightJoin('field_data_' . $table, $table, $table . '.' . $table . '_product_id = cp.product_id');
      $query->addField($table, 'entity_id', 'entity_id');
      // Continue building the query.
      $query->addExpression(
        'FROM_UNIXTIME(co.changed, :M1)',
        'order_time',
        array(':M1' => $time_period));
      $query->fields('cp', array('product_id', 'title'));
      $query->addExpression('SUM(cli.quantity)', 'sum');
      $query->condition(
        'co.status',
        array('pending', 'complete', 'checkout_complete'),
        'in');
      $query->condition(
        'co.status',
        array('pending', 'complete', 'checkout_complete'),
        'in');
      $product_types = array();
      foreach ($products as $key => $product) {
        $product_types[] = $product;
      }
      $query->condition('cli.type', $product_types);
      // Deal with the different time periods.
          $query->where("co.changed > (unix_timestamp(now()) - 86400)  ");
          $query->where("co.changed > (unix_timestamp(now()) - 604800)  ");
          $query->where("co.changed > (unix_timestamp(now()) - 2629743)  ");
      $query->groupBy('order_time');
      $query->groupBy('cp.product_id');
      $query->groupBy('cp.title');
      $result = $query->execute();
      foreach ($result as $record) {
        $product = $record->entity_id;
        $count = $record->sum;
        $all_results[] = array('id' => $product, 'count' => $count);
Anthony Lindsay's avatar
Anthony Lindsay committed
      }
    }
    // Sort the Array.
    $count = array();
    foreach ($all_results as $key => $row) {
      $count[$key]  = $row['count'];
    }
    array_multisort($count, SORT_DESC, $all_results);
    // Call the views to display N items.
    while ($i < $number) {
      // For each returned row, get the product's ID and go fetch the View.
      if (isset($all_results[$i])) {
        $product = $all_results[$i]['id'];
        $view = views_embed_view('popular_commerce_products', 'popular_products_block', $product);
        $output .= $view;
        $view_count++;
Anthony Lindsay's avatar
Anthony Lindsay committed
}

/**
 * Implements hook_block_info().
 */
function commerce_popular_products_block_info() {
  // A block To display a popular product.
  $blocks['popular-product-block'] = array(
    'info' => t('Commerce Popular Products display block'),
Anthony Lindsay's avatar
Anthony Lindsay committed
    'weight' => '-50',
  );
  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function commerce_popular_products_block_view($delta = '') {
Anthony Lindsay's avatar
Anthony Lindsay committed
  $block = array();
  switch ($delta) {
    case 'popular-product-block':
      $title = variable_get('commerce_popular_products_title');
      $title = check_plain($title);
      $block['subject'] = t($title);
Anthony Lindsay's avatar
Anthony Lindsay committed
      $block['content'] = commerce_popular_products_get_product();
Anthony Lindsay's avatar
Anthony Lindsay committed
  }
  return $block;
}

/**
 * Implements hook_menu().
 */
function commerce_popular_products_menu() {
  $items['admin/commerce/config/popular-products'] = array(
    'title' => 'Popular Commerce Products settings',
    'description' => 'Manage settings for defining a popular products block.',
    'page callback' => 'commerce_popular_products_settings',
    'access arguments' => array('Configure store settings '),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/**
 * Menu callback to produce the Settings Page.
 */
function commerce_popular_products_settings() {
  $output = t('<p>Here you can define which product types are ranked for popularity & the period over which they are ranked.</p>');
  $form = drupal_get_form('commerce_popular_products_settings_form');
  $output .= render(&$form);
Anthony Lindsay's avatar
Anthony Lindsay committed
  return $output;
}

/**
 * Implements hook_form().
Anthony Lindsay's avatar
Anthony Lindsay committed
 * Produces the Settings Page form.
 */
function commerce_popular_products_settings_form($form, &$form_state) {
  $time = variable_get('commerce_popular_products_time', $default = 'month');
  $number = variable_get('commerce_popular_products_number', $default = '1');
  $products = variable_get('commerce_popular_products_products');
  $title = variable_get('commerce_popular_products_title', 'Popular Products This Month');
  $form['block_title'] = array(
    '#type' => 'textfield',
    '#title' => t('Block title.'),
    '#description' => t('The title of the "popular products" block as shown to users.'),
    '#default_value' => $title,
Anthony Lindsay's avatar
Anthony Lindsay committed
  $form['product_types'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Product Types.'),
    '#description' => t('Product nodes to include in the popularity check.'),
    '#default_value' => $products,
  $product_types = commerce_popular_products_get_product_types();
  $options = array();
  foreach ($product_types as $type) {
    $options[$type] = $type;
  }
Anthony Lindsay's avatar
Anthony Lindsay committed
  $form['product_types']['#options'] = $options;
  $form['time_period'] = array(
    '#type' => 'radios',
    '#title' => t('Timeframe.'),
    '#description' => t('The timeframe within which to calculate popularity.'),
    '#options' => array(
      'day' => t('Day'),
      'week' => t('Week'),
      'month' => t('Month'),
      'year' => t('Year'),
    ),
    '#default_value' => $time,
Anthony Lindsay's avatar
Anthony Lindsay committed
  $form['number_display'] = array(
    '#type' => 'select',
    '#title' => t('Display.'),
    '#description' => t('How may ranked popular products would you like included in the display?'),
    '#options' => array(
      '1' => '1',
      '2' => '2',
      '3' => '3',
      '4' => '4',
      '5' => '5',
    ),
    '#default_value' => $number,
  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));;
Anthony Lindsay's avatar
Anthony Lindsay committed
  return $form;
}

/**
 * Custom submit handler for settings form: saves values to Variable table.
 */
function commerce_popular_products_settings_form_submit($form, &$form_state) {
  $values = $form_state['values'];
  $products = $values['product_types'];
  $time = $values['time_period'];
  $number = $values['number_display'];
  $title = $values['block_title'];
  variable_set('commerce_popular_products_title', $title);
  variable_set('commerce_popular_products_time', $time);
  variable_set('commerce_popular_products_number', $number);
  variable_set('commerce_popular_products_products', $products);
  drupal_set_message(t('Your settings have been saved.'));
}

/**
 * A simple query to return all the Commerce product types in the database.
 */
function commerce_popular_products_get_product_types() {
  $products = commerce_product_types();
  foreach ($products as $item) {
    $names[] = $item['name'];
  }
  return $names;
Anthony Lindsay's avatar
Anthony Lindsay committed
}


/**
 * Implements hook_views_api().
 *
 * Makes hooking into Views possible.
 */
function commerce_popular_products_views_api() {
Anthony Lindsay's avatar
Anthony Lindsay committed

  return array(
    'api' => 3,
    'path' => drupal_get_path('module', 'commerce_popular_products'),
  );