easychart.module in Easychart 7.2
Same filename and directory in other branches
Easychart module file.
File
easychart.moduleView source
<?php
/**
* @file
* Easychart 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 using the world\'s best web charting tool: Highcharts'),
'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',
),
'required' => TRUE,
),
);
}
/**
* Implements hook_form().
*/
function easychart_form($node, $form_state) {
return node_content_form($node, $form_state);
}
/**
* Implements hook_admin_paths().
*/
function easychart_admin_paths() {
return array(
'easychart-charts' => TRUE,
);
}
/**
* 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 TRUE;
}
else {
return FALSE;
}
}
/**
* Implements hook_field_validate().
*/
function easychart_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
// Only validate on node edit e.g. not on field settings edit.
if (arg(0) == 'node') {
foreach ($items as $delta => $item) {
// The hidden config field should not be empty when set to be required
if ($instance['required'] == 1 && empty($item['config'])) {
$errors[$field['field_name']][$langcode][$delta][] = array(
'error' => 'easychart_empty',
'message' => t('Please create an Easychart chart before saving'),
);
}
}
}
}
/**
* 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(
'highchart_ui_options' => str_replace("\r\n", '', variable_get('highchart_ui_options', '')),
);
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',
'recommended' => array(
'version' => '4.1.9',
// 4.1.x and up
'uri' => 'http://code.highcharts.com/zips/Highcharts-4.1.9.zip',
),
'version arguments' => array(
'file' => 'js/highcharts.js',
// Could be any file with version info
'pattern' => '/Highcharts JS v(\\d\\.\\d\\.\\d)/',
'lines' => 2,
),
'files' => array(
'js' => array(
'js/highcharts.js',
'js/highcharts-3d.js',
'js/highcharts-more.js',
'js/modules/data.js',
'js/modules/funnel.js',
'js/modules/heatmap.js',
'js/modules/no-data-to-display.js',
'js/modules/solid-gauge.js',
'js/modules/treemap.js',
'js/modules/exporting.js',
),
),
);
$libraries['easychart'] = array(
'name' => 'Easychart',
'vendor url' => 'http://www.easychart.org',
'download url' => '',
'recommended' => array(
'version' => '2.2.2',
'uri' => 'https://api.github.com/repos/bestuurszaken/easychart/tarball/v2.2.2',
),
'version arguments' => array(
'file' => 'scripts/jquery.easychart.js',
// Could be any file with version info
'pattern' => '/Easychart JS v(\\d\\.\\d\\.\\d)/',
'lines' => 2,
),
'files' => array(
'js' => array(
'scripts/utils/jscolor/jscolor.js',
'scripts/utils/opentip.min.js',
'scripts/utils/papaparse.min.js',
'scripts/utils/highchartsConfigurationOptions.js',
'scripts/jquery.easychart.helper.js',
'scripts/jquery.easychart.js',
),
'css' => array(
'styles/opentip.css',
'styles/screen.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'])) {
// check if url is relative
if (!preg_match("/^ht{2}ps?\\:\\/{2}/", $item['csv_url'])) {
// if so, prepend base-url
$url = url(NULL, array(
'absolute' => TRUE,
)) . $item['csv_url'];
}
else {
$url = $item['csv_url'];
}
$csv = file_get_contents($url);
// TODO: turn into array.
$csv = str_replace("\r\n", 'EC_EOL', $csv);
$csv = str_replace("\n", 'EC_EOL', $csv);
}
else {
if (!empty($item['csv'])) {
$csv = $item['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() {
return array(
'admin/config/media/easychart' => array(
'title' => 'Easychart',
'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 Easychart settings',
),
'type' => MENU_NORMAL_ITEM,
),
'easycharts/chart-options/%node' => array(
'page callback' => 'easychart_chart_options',
'page arguments' => array(
2,
),
'access callback' => 'node_access',
'access arguments' => array(
'view',
2,
),
'type' => MENU_NORMAL_ITEM,
),
);
}
/*
* Implements hook_permission().
*/
function easychart_permission() {
return array(
'administer Easychart settings' => array(
'title' => t('Administer Easychart settings'),
'description' => t('Configure default settings for the Easychart popup.'),
),
);
}
function easychart_chart_options($chartNode) {
if (!empty($chartNode->easychart[LANGUAGE_NONE][0]['config'])) {
drupal_json_output(array(
'options' => $chartNode->easychart[LANGUAGE_NONE][0]['config'],
));
}
else {
drupal_not_found();
}
}
/*
* Returns a form with configuration options.
*/
function easychart_admin($form, $form_state) {
if (!isset($form_state['storage']['confirm'])) {
$form = array();
$form['highchart_ui_options'] = array(
'#type' => 'textarea',
'#title' => t('Available UI options'),
'#default_value' => variable_get('highchart_ui_options', '
{
"panels": [
{
"panelTitle": "Chart settings",
"pane": [
{
"title": "Chart type and interaction",
"options": [{"name":"chart.type","defaults":"column"},"chart.inverted","chart.zoomType"]
},
{
"title": "Size and margins",
"options": ["chart.width","chart.height","chart.spacingTop","chart.spacingRight","chart.spacingBottom","chart.spacingLeft"]
}
]
},
{
"panelTitle": "Colors and borders",
"pane": [
{
"title": "default colors",
"options":["colors"]
},
{
"title": "Chart area",
"options": ["chart.backgroundColor","chart.borderWidth","chart.borderRadius","chart.borderColor"]
},
{
"title": "Plot area",
"options": ["chart.plotBackgroundColor","chart.plotBackgroundImage","chart.plotBorderWidth","chart.plotBorderColor"]
}
]
},
{
"panelTitle": "Titles",
"pane": [
{
"title":"Titles",
"options": ["title.text","subtitle.text","yAxis.title.text","xAxis.title.text"]
},
{
"title":"Title advanced",
"options": ["title.style"]
}
]
},
{
"panelTitle": "Axes",
"pane": [
{
"title":"Axes setup",
"options": []
},
{
"title":"X axis",
"options": [{"name":"xAxis.type","defaults":"category"},"xAxis.min","xAxis.opposite","xAxis.reversed","xAxis.tickInterval","xAxis.labels.format","xAxis.labels.rotation","xAxis.labels.align"]
},
{
"title":"Value axis",
"options": ["yAxis.type","yAxis.min","yAxis.opposite","yAxis.reversed","yAxis.labels.format","yAxis.labels.rotation"]
}
]
},
{
"panelTitle": "Legend",
"pane": [
{
"title":"General",
"options": ["legend.enabled","legend.layout"]
},
{
"title":"Placement",
"options": ["legend.align","legend.verticalAlign"]
},
{
"title":"Color and border",
"options": []
}
]
},
{
"panelTitle": "Tooltip",
"pane": [
{
"title":"General",
"options": ["tooltip.headerFormat","tooltip.pointFormat","tooltip.valuePrefix","tooltip.valueSuffix"]
},
{
"title":"Color and border",
"options": []
}
]
},
{
"panelTitle": "Exporting",
"pane": [
{
"title":"Exporting",
"options": ["exporting.enabled"]
}
]
}
]
}
'),
'#description' => t("These Highcharts options will be configurable in the Easychart interface when creating/editing a chart. See !url for all available options.", array(
'!url' => l('http://api.highcharts.com/highcharts', 'http://api.highcharts.com/highcharts', array(
'attributes' => array(
'target' => '_blank',
),
)),
)),
'#required' => TRUE,
'#rows' => 15,
);
$form['global_highchart_options'] = array(
'#type' => 'textarea',
'#title' => t('Global Options'),
'#default_value' => variable_get('global_highchart_options', ""),
'#description' => t("Warning: these options will be applied to all Highcharts based charts on this website."),
'#rows' => 10,
);
// Add the reset button.
$form['actions']['reset'] = array(
'#type' => 'submit',
'#value' => t('Reset to defaults'),
'#submit' => array(
'easychart_admin_submit',
),
'#limit_validation_errors' => array(),
'#weight' => 100,
);
}
else {
return confirm_form($form, t('Are you sure you want to reset the options to their default values?'), current_path());
}
return system_settings_form($form);
}
/**
* Form submit handler
*/
function easychart_admin_submit($form, &$form_state) {
if (!isset($form_state['storage']['confirm'])) {
$form_state['storage']['values'] = $form_state['values'];
$form_state['storage']['confirm'] = TRUE;
$form_state['rebuild'] = TRUE;
}
else {
// Exclude unnecessary elements.
form_state_values_clean($form_state);
foreach ($form_state['storage']['values'] as $key => $value) {
variable_del($key);
}
drupal_set_message(t('The configuration options have been reset to their default values.'));
}
}
/**
* Implements hook_wysiwyg_include_directory().
*
* 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 Easychart 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;
}
}
function _get_lib_info($lib) {
switch ($lib) {
case 'highcharts':
$url = 'https://api.github.com/repos/highslide-software/highcharts.com/tags';
// no release-info on https://api.github.com/repos/highslide-software/highcharts.com/releases
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'highslide-software/highcharts.com');
$data = curl_exec($ch);
curl_close($ch);
break;
case 'easychart':
$url = 'https://api.github.com/repos/bestuurszaken/easychart/releases';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, 'bestuurszaken/easychart');
$data = curl_exec($ch);
curl_close($ch);
break;
default:
drush_log(dt('No library chosen.'), 'error');
return false;
}
$output = array();
$output['current_lib_info'] = libraries_detect($lib);
/* if ($data) {
$output['available'] = json_decode($data);
} */
return $output;
}