You are here

easychart.module in Easychart 7

Same filename and directory in other branches
  1. 8.3 easychart.module
  2. 7.3 easychart.module
  3. 7.2 easychart.module

Easy Chart module file.

File

easychart.module
View source
<?php

/**
 * @file
 * Easy Chart module file.
 */

/**
 * Implements hook_node_info().
 */
function easychart_node_info() {
  return array(
    'easychart' => array(
      'name' => t('Chart'),
      'base' => 'node_content',
      'description' => t('Create a chart based on your CSV data.'),
      'locked' => TRUE,
    ),
  );
}

/**
 * Implements hook_node_type_insert().
 */
function easychart_node_type_insert($content_type) {
  if ($content_type->type == 'easychart') {
    $body_instance = node_add_body_field($content_type, t('Chart description'));

    // Save our changes to the body field instance.
    field_update_instance($body_instance);

    // Create all the fields we are adding to our content type.
    foreach (_easychart_installed_fields() as $field) {
      field_create_field($field);
    }

    // Create all the instances for our fields.
    foreach (_easychart_installed_instances() as $instance) {
      $instance['entity_type'] = 'node';
      $instance['bundle'] = 'easychart';
      field_create_instance($instance);
    }
  }
}

/**
 * Define the fields for our content type.
 *
 * @return array
 *   An associative array specifying the fields we wish to add to our
 *   new node type.
 *
 * @see easychart_node_type_insert().
 */
function _easychart_installed_fields() {
  return array(
    'easychart' => array(
      'field_name' => 'easychart',
      'cardinality' => 1,
      'type' => 'easychart',
    ),
  );
}

/**
 * Define the field instances for our content type.
 *
 * @return array
 *   An associative array specifying the instances we wish to add to our new
 *   node type.
 *
 * @see easychart_node_type_insert().
 */
function _easychart_installed_instances() {
  return array(
    'easychart' => array(
      'field_name' => 'easychart',
      'label' => t('Chart'),
      'type' => 'easychart',
      'widget' => array(
        'type' => 'easychart',
      ),
    ),
  );
}

/**
 * Implements hook_form().
 */
function easychart_form($node, $form_state) {
  return node_content_form($node, $form_state);
}

/**
 * Implements hook_field_info().
 */
function easychart_field_info() {
  return array(
    // We name our field as the associative name of the array.
    'easychart' => array(
      'label' => t('Chart'),
      'default_widget' => 'easychart',
      'default_formatter' => 'easychart_default',
    ),
  );
}

/**
 * Implements hook_field_is_empty().
 */
function easychart_field_is_empty($item, $field) {
  if (!empty($item['config'])) {
    return FALSE;
  }
  else {
    return TRUE;
  }
}

/**
 * Implements hook_field_widget_info().
 */
function easychart_field_widget_info() {
  return array(
    'easychart' => array(
      'label' => t('Chart'),
      'field types' => array(
        'easychart',
      ),
    ),
  );
}

/**
 * Implements hook_field_widget_form().
 */
function easychart_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  switch ($instance['widget']['type']) {
    case 'easychart':

      // We keep this global to prevent issues with multiple widgets on the same page.
      static $settings;

      // Provide a wrapper and add the required js and css.
      if (empty($settings)) {
        $settings = array(
          'unwantedOptions' => variable_get('unwanted_options', 'global, lang, exporting, series, labels, navigation, loading, pane, plotOptions, xAxis-plotLines'),
          'unwantedReturnTypes' => variable_get('unwanted_return_types', 'Function, CSSObject, null'),
          'optionsStep1' => variable_get('options_step1', 'chart--type'),
          'optionsStep2' => variable_get('options_step2', 'title--text, chart--backgroundColor, subtitle--text, yAxis-title--text'),
          'defaultColors' => variable_get('default_colors', ''),
        );
        drupal_add_js(array(
          'easychart' => $settings,
        ), 'setting');
      }
      $element = array(
        '#prefix' => '<div class="easychart-wrapper clearfix">',
        '#suffix' => '</div>',
        '#attached' => array(
          // Add highcharts plugin.
          'libraries_load' => array(
            array(
              'highcharts',
            ),
            array(
              'easychart',
            ),
          ),
          'js' => array(
            drupal_get_path('module', 'easychart') . '/js/easychart.js',
          ),
          'css' => array(
            drupal_get_path('module', 'easychart') . '/css/easychart.admin.css',
          ),
        ),
      );
      $element['config'] = array(
        '#description' => t('The configuration options as described at http://api.highcharts.com/highcharts'),
        '#type' => 'hidden',
        '#default_value' => isset($items[$delta]['config']) ? $items[$delta]['config'] : NULL,
        '#attributes' => array(
          'class' => array(
            'easychart-config',
          ),
        ),
      );
      $element['stored'] = array(
        '#type' => 'hidden',
        '#default_value' => isset($items[$delta]['stored']) ? $items[$delta]['stored'] : NULL,
        '#attributes' => array(
          'class' => array(
            'easychart-stored',
          ),
        ),
      );
      $element['csv'] = array(
        '#description' => t('Your chart data in CSV format'),
        '#type' => 'hidden',
        '#default_value' => isset($items[$delta]['csv']) ? $items[$delta]['csv'] : NULL,
        '#attributes' => array(
          'class' => array(
            'easychart-csv',
          ),
        ),
      );
      $element['csv_url'] = array(
        '#description' => t('The URL to a CSV file'),
        '#type' => 'hidden',
        '#default_value' => isset($items[$delta]['csv_url']) ? $items[$delta]['csv_url'] : NULL,
        '#attributes' => array(
          'class' => array(
            'easychart-csv-url',
          ),
        ),
      );

      // Edit/add/configure links for the popup.
      $delete_link = l(t('Delete chart'), '#', array(
        'attributes' => array(
          'class' => array(
            'easychart-delete-link',
            'element-hidden',
          ),
        ),
      ));
      $configure_link = l(t('Add chart'), '#', array(
        'attributes' => array(
          'class' => array(
            'button',
            'easychart-configure-link',
          ),
        ),
      ));
      $popup = '<div class="easychart-popup"><div class="easychart-bar"><a href="#" class="close">Save and close popup</a> <a href="#" class="cancel">Cancel</a></div><div class="easychart-popup-content"></div></div>';
      $element['link'] = array(
        '#markup' => $configure_link . $delete_link . $popup,
        '#prefix' => '<div class="easychart-left">',
        '#suffix' => '</div>',
      );

      // Preview placeholder. Actual preview is rendered in easychart.js.
      $element['preview'] = array(
        '#title' => t('Chart preview'),
        '#markup' => '',
        '#prefix' => '<div class="easychart-preview">',
        '#suffix' => '</div>',
      );
      break;
  }
  return $element;
}

/**
 * Implements hook_field_formatter_info().
 */
function easychart_field_formatter_info() {
  return array(
    'easychart_default' => array(
      'label' => t('Default'),
      'field types' => array(
        'easychart',
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function easychart_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  switch ($display['type']) {
    case 'easychart_default':
      foreach ($items as $delta => $item) {
        $output = _easychart_print_chart($item, $delta);
        $element[$delta] = array(
          '#markup' => $output,
        );
      }
      break;
  }
  return $element;
}

/**
 * Implements hook_libraries_info().
 *
 * For defining external libraries.
 */
function easychart_libraries_info() {
  $libraries['highcharts'] = array(
    'name' => 'Highcharts',
    'vendor url' => 'http://www.highcharts.com',
    'download url' => 'http://www.highcharts.com/download',
    /*'version arguments' => array(
        'file' => 'js/highcharts.js', // Could be any file with version info
        'pattern' => '/ Highcharts JS v\d\.\d\.\d/',
        'lines' => 2,
      ),*/
    'version' => '3.0.9',
    'files' => array(
      'js' => array(
        'js/highcharts.js',
        'js/highcharts-more.js',
        'js/modules/data.js',
        'js/modules/exporting.js',
      ),
    ),
  );
  $libraries['easychart'] = array(
    'name' => 'Easy Chart Generator',
    'vendor url' => '',
    'download url' => '',
    'version' => '1.1',
    'files' => array(
      'js' => array(
        'jquery.easychart.helper.js',
        'jquery.easychart.js',
        'highchartsConfigurationOptions.js',
      ),
      'css' => array(
        'easychart.css',
      ),
    ),
  );
  return $libraries;
}

/*
 * Helper functions to print the actual chart.
*/
function _easychart_print_chart($item, $delta) {
  global $chart_count;
  $chart_count++;
  $output = '';
  if (!empty($item['config'])) {
    if ($chart_count == 1) {

      // Add the highcharts javascript.
      libraries_load('highcharts');
      libraries_load('easychart');

      // Add the easychart javascript.
      drupal_add_js(drupal_get_path('module', 'easychart') . '/js/easychart.js');
    }

    // Print a div and add inline javascript
    $output = '<div class="easychart-chart-' . $chart_count . '">';
    $output .= '</div>';

    // Get the csv data.
    if (!empty($item['csv_url'])) {
      $csv = file_get_contents($item['csv_url']);
    }
    else {
      if (!empty($item['csv'])) {
        $csv = $item['csv'];
      }
    }
    $csv = str_replace("\r\n", 'EC_EOL', $csv);
    $csv = str_replace("\n", 'EC_EOL', $csv);
    drupal_add_js('Drupal.behaviors.easyChart_' . $chart_count . ' = { attach: function() { if (jQuery(".easychart-chart-' . $chart_count . '").length > 0) { var options = ' . $item['config'] . '; options = _preprocessHighchartsData(options, "' . $csv . '"); jQuery(".easychart-chart-' . $chart_count . '").highcharts(options);}}};', array(
      'type' => 'inline',
      'scope' => 'footer',
    ));
  }
  return $output;
}

/*
 * Implements hook_menu().
 */
function easychart_menu() {
  $items = array();
  $items['admin/config/media/easychart'] = array(
    'title' => 'Easy Chart',
    'description' => t('Configure the options that will be available when creating charts.'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'easychart_admin',
    ),
    'access arguments' => array(
      'administer Easy Chart settings',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  return $items;
}

/*
 * Implements hook_permission().
 */
function easychart_permission() {
  return array(
    'administer Easy Chart settings' => array(
      'title' => t('Administer Easy Chart settings'),
      'description' => t('Configure default settings for the Easy Chart popup.'),
    ),
  );
}

/*
 * Returns a form with configuration options.
 */
function easychart_admin($form, $form_state) {
  $form = array();
  $form['global_highchart_options'] = array(
    '#type' => 'textarea',
    '#title' => t('Global Options'),
    '#default_value' => variable_get('global_highchart_options', ""),
    '#description' => t("Global options for all charts on the website."),
    '#rows' => 15,
  );
  $form['unwanted_options'] = array(
    '#type' => 'textfield',
    '#title' => t('Unwanted Options'),
    '#default_value' => variable_get('unwanted_options', "global, lang, exporting, series, labels, navigation, loading, pane, plotOptions, xAxis-plotLines"),
    '#description' => t("The options that should not be configurable. Use a comma to separate the values."),
    '#required' => TRUE,
  );
  $form['unwanted_return_types'] = array(
    '#type' => 'textfield',
    '#title' => t('Unwanted Return Types'),
    '#default_value' => variable_get('unwanted_return_types', "Function, CSSObject, null"),
    '#description' => t("The return types that should not be used. Use a comma to separate the values."),
    '#required' => TRUE,
  );
  $form['options_step1'] = array(
    '#type' => 'textfield',
    '#title' => t('Options for Step 1'),
    '#default_value' => variable_get('options_step1', "chart--type"),
    '#description' => t("The options that appear in step 1 of the configuration form. Use a comma to separate the values."),
    '#required' => TRUE,
  );
  $form['options_step2'] = array(
    '#type' => 'textfield',
    '#title' => t('Options for Step 2'),
    '#default_value' => variable_get('options_step2', "title--text, chart--backgroundColor, subtitle--text, yAxis-title--text"),
    '#description' => t("The options that appear in step 2 of the configuration form. Use a comma to separate the values."),
    '#required' => TRUE,
  );
  $form['default_colors'] = array(
    '#type' => 'textfield',
    '#title' => t('Default colours'),
    '#default_value' => variable_get('default_colors', ""),
    '#description' => t("The default colours for all charts on this website. Use a comma to separate the values. Don't use quotes around the color values."),
  );
  return system_settings_form($form);
}

/**
 * Implementing the Wysiwyg API.
 *
 * Register a directory containing Wysiwyg plugins.
 *
 * @param string $type
 *   The type of objects being collected: either 'plugins' or 'editors'.
 *
 * @return string
 *   A sub-directory of the implementing module that contains the corresponding
 *   plugin files. This directory must only contain integration files for
 *   Wysiwyg module.
 */
function easychart_wysiwyg_include_directory($type) {
  switch ($type) {
    case 'plugins':

      // You can just return $type, if you place your Wysiwyg plugins into a
      // sub-directory named 'plugins'.
      return $type;
  }
}

/**
 * Implements hook_views_api().
 */
function easychart_views_api() {
  return array(
    'api' => 3.0,
  );
}

/**
 * Implements of hook_views_pre_render().
 */
function easychart_views_pre_render(&$view) {
  if ($view->name == 'easychart_plugin' && $view->current_display == 'page') {

    // suppress other interface elements.
    module_invoke_all('suppress');
    drupal_add_js("var oEditor = window.parent.CKEDITOR;\n      if (oEditor) {\n      var instance = oEditor.currentInstance;\n      var lang = oEditor.lang;\n      var config = oEditor.config;\n      }", 'inline');
    drupal_add_js(drupal_get_path('module', 'easychart') . '/plugins/js/popup.js');
  }
}

/**
 * Implements hook_theme_registry_alter().
 */
function easychart_theme_registry_alter(&$theme_registry) {

  // Add 'html--editor-easychart.tpl.php' template file
  $theme_registry['html__easychart_charts'] = array();
  $theme_registry['html__easychart_charts']['template'] = 'html--easychart-charts';
  $theme_registry['html__easychart_charts']['path'] = drupal_get_path('module', 'easychart') . "/theme";
  $theme_registry['html__easychart_charts']['render element'] = 'html';
  $theme_registry['html__easychart_charts']['base hook'] = 'html';
  $theme_registry['html__easychart_charts']['type'] = 'module';
  $theme_registry['html__easychart_charts']['theme path'] = drupal_get_path('module', 'easychart') . "/theme";

  // Add 'page--editor-easychart.tpl.php' template file
  $theme_registry['page__easychart_charts'] = array();
  $theme_registry['page__easychart_charts']['template'] = 'page--easychart-charts';
  $theme_registry['page__easychart_charts']['path'] = drupal_get_path('module', 'easychart') . "/theme";
  $theme_registry['page__easychart_charts']['render element'] = 'page';
  $theme_registry['page__easychart_charts']['base hook'] = 'page';
  $theme_registry['page__easychart_charts']['type'] = 'module';
  $theme_registry['page__easychart_charts']['theme path'] = drupal_get_path('module', 'easychart') . "/theme";
  $theme_registry['page__easychart_charts']['override preprocess functions'] = TRUE;
}

/*
 * Implements template_preprocess_page.
 */
function easychart_preprocess_page(&$variables) {

  // Force the use of this template.
  if ($variables['theme_hook_suggestions'][0] == 'page__easychart_charts') {
    $variables['theme_hook_suggestion'] = 'page__easychart_charts';
  }
}

/**
 * Implements hook_init().
 */
function easychart_init() {

  // A global counter to be used when printing the charts.
  global $chart_count;
  $chart_count = 0;
  drupal_add_css(drupal_get_path('module', 'easychart') . '/plugins/css/plugin.css');
}

/**
 * Implements hook_filter_info().
 */
function easychart_filter_info() {
  $filters['easychart'] = array(
    'title' => t('Insert Easy Chart charts'),
    'prepare callback' => 'easychart_filter_easychart_prepare',
    'process callback' => 'easychart_filter_easychart_process',
    'tips callback' => 'easychart_filter_easychart_tips',
    'cache' => FALSE,
  );
  return $filters;
}

/**
 * Prepare callback for hook_filter
 */
function easychart_filter_easychart_prepare($text, $filter, $format, $langcode, $cache, $cache_id) {
  return $text;
}

/**
 * Process callback for hook_filter
 */
function easychart_filter_easychart_process($text, $filter, $format, $langcode, $cache, $cache_id) {
  return preg_replace_callback('/\\[\\[chart-nid:(\\d+)(\\s.*)?\\]\\]/', '_easychart_render_node', $text);
}
function easychart_libraries_info_alter(&$libraries) {

  // Add our callback to the post-load callbacks
  $libraries['highcharts']['callbacks']['post-load'][] = 'easychart_set_global_options';
}
function easychart_set_global_options() {

  // Add the global options once.
  $global_options = variable_get('global_highchart_options');
  if (!empty($global_options)) {
    drupal_add_js('Highcharts.setOptions({' . $global_options . '});', array(
      'type' => 'inline',
      'scope' => 'footer',
    ));
  }
}

/**
 * Tips callback for hook_filter
 */
function easychart_filter_easychart_tips($filter, $format, $long) {
  return t('[[chart-nid:123]] - Insert a chart');
}

/**
 * Provides the replacement html to be rendered in place of the embed code.
 *
 * Does not handle nested embeds.
 *
 * @param array $matches
 *   numeric node id that has been captured by preg_replace_callback
 *
 * @return string
 *   The rendered HTML replacing the embed code
 */
function _easychart_render_node($matches) {
  $node = node_load($matches[1]);
  if ($node == FALSE || !node_access('view', $node) || !$node->status) {
    return "[[chart-nid:{$matches[1]}]]";
  }
  else {
    $view = node_view($node);
    $render = drupal_render($view);
    return $render;
  }
}

Functions

Namesort descending Description
easychart_admin
easychart_field_formatter_info Implements hook_field_formatter_info().
easychart_field_formatter_view Implements hook_field_formatter_view().
easychart_field_info Implements hook_field_info().
easychart_field_is_empty Implements hook_field_is_empty().
easychart_field_widget_form Implements hook_field_widget_form().
easychart_field_widget_info Implements hook_field_widget_info().
easychart_filter_easychart_prepare Prepare callback for hook_filter
easychart_filter_easychart_process Process callback for hook_filter
easychart_filter_easychart_tips Tips callback for hook_filter
easychart_filter_info Implements hook_filter_info().
easychart_form Implements hook_form().
easychart_init Implements hook_init().
easychart_libraries_info Implements hook_libraries_info().
easychart_libraries_info_alter
easychart_menu
easychart_node_info Implements hook_node_info().
easychart_node_type_insert Implements hook_node_type_insert().
easychart_permission
easychart_preprocess_page
easychart_set_global_options
easychart_theme_registry_alter Implements hook_theme_registry_alter().
easychart_views_api Implements hook_views_api().
easychart_views_pre_render Implements of hook_views_pre_render().
easychart_wysiwyg_include_directory Implementing the Wysiwyg API.
_easychart_installed_fields Define the fields for our content type.
_easychart_installed_instances Define the field instances for our content type.
_easychart_print_chart
_easychart_render_node Provides the replacement html to be rendered in place of the embed code.