View source
<?php
define('SLICKGRID_CALLBACK_PATH', 'slickgrid/callback');
function slickgrid_init() {
global $conf;
if (module_exists('lightbox2')) {
if (arg(0) == 'slickgrid' && arg(1) == 'callback') {
$conf['lightbox2_lite'] = TRUE;
}
else {
$menu_item = menu_get_item();
if ($menu_item['page_callback'] == 'views_page') {
$view = views_get_view($menu_item['page_arguments'][0]);
if ($view->display['default']->display_options['style_plugin'] == 'slickgrid') {
$conf['lightbox2_lite'] = TRUE;
}
}
}
}
}
function slickgrid_menu() {
$items[SLICKGRID_CALLBACK_PATH . '/%'] = array(
'page callback' => 'slickgrid_callback',
'page arguments' => array(
2,
),
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
'file' => 'slickgrid.callbacks.inc',
);
return $items;
}
function slickgrid_menu_alter(&$items) {
$items['content/js_add_more']['page callback'] = 'slickgrid_content_add_more_js';
$items['content/js_add_more']['file'] = 'slickgrid.ahah.inc';
$items['content/js_add_more']['file path'] = drupal_get_path('module', 'slickgrid');
$items['filefield/ahah/%/%/%']['page callback'] = 'slickgrid_filefield_js';
$items['filefield/ahah/%/%/%']['file'] = 'slickgrid.ahah.inc';
$items['filefield/ahah/%/%/%']['file path'] = drupal_get_path('module', 'slickgrid');
$items['nodereference/autocomplete']['page callback'] = 'slickgrid_nodereference_autocomplete';
$items['nodereference/autocomplete']['file'] = 'slickgrid.ahah.inc';
$items['nodereference/autocomplete']['file path'] = drupal_get_path('module', 'slickgrid');
}
function slickgrid_views_api() {
return array(
'api' => 2,
);
}
function slickgrid_views_pre_view(&$view, $display_id) {
global $conf;
if ($view->display_handler
->get_option('style_plugin') == 'slickgrid') {
$conf['preprocess_js'] = 0;
$style_options = $view->display_handler
->get_option('style_options');
if ($view->display_handler
->get_option('use_pager')) {
$view->display_handler
->set_option('use_pager', FALSE);
$style_options['pager'] = TRUE;
}
$view->display_handler
->set_option('style_options', $style_options);
if ($style_options['collapsible_taxonomy_field']) {
$parent_relationship = array(
'label' => t('Slickgrid parent'),
'required' => 0,
'id' => 'parent',
'table' => 'term_hierarchy',
'field' => 'parent',
);
$view
->set_item($display_id, 'relationship', 'slickgrid_parent_relationship', $parent_relationship);
$parent_tid_field = array(
'exclude' => 1,
'id' => 'slickgrid_parent_tid',
'table' => 'term_data',
'field' => 'tid',
'relationship' => 'slickgrid_parent_relationship',
);
$view
->set_item($display_id, 'field', 'slickgrid_parent_tid', $parent_tid_field);
$tid_field = array(
'exclude' => 1,
'id' => 'slickgrid_tid',
'table' => 'term_data',
'field' => 'tid',
);
$view
->set_item($display_id, 'field', 'slickgrid_tid', $tid_field);
$existing_sorts = $view
->get_items('sort');
foreach (array_keys($existing_sorts) as $existing_sort_id) {
$view
->set_item($display_id, 'sort', $existing_sort_id, null);
}
foreach (array(
'slickgrid_parent_relationship',
'none',
) as $relationship) {
$id = 'slickgrid_sort_' . $relationship;
$sort = array(
'order' => 'ASC',
'id' => $relationship,
'table' => 'term_data',
'field' => 'weight',
'relationship' => $relationship,
);
$view
->set_item($display_id, 'sort', $id, $sort);
}
foreach ($existing_sorts as $existing_sort_id => $existing_sort) {
$view
->set_item($display_id, 'sort', $existing_sort_id, $existing_sort);
}
}
}
}
function slickgrid_theme() {
return array(
'slickgrid' => array(
'arguments' => array(
'options' => array(),
'columns' => array(),
'data' => array(),
),
),
'slickgrid_views_plugin_table' => array(
'arguments' => array(
'form' => array(),
),
),
);
}
function slickgrid_slickgrid_plugins() {
$path = drupal_get_path('module', 'slickgrid');
$plugins = array(
'TextCellEditor' => array(
'description' => t('Text cell'),
'js' => $path . '/js/slickgrid.editors.js',
'css' => $path . '/css/slickgrid.editors.css',
'field_type' => array(
'node_title',
'date_text',
),
'plugin_type' => 'editor',
),
'LongTextCellEditor' => array(
'description' => t('Simple textarea'),
'js' => $path . '/js/slickgrid.editors.js',
'css' => $path . '/css/slickgrid.editors.css',
'field_type' => array(
'text_textarea',
'node_revisions_body',
),
'plugin_type' => 'editor',
),
'nodeFormEditor' => array(
'description' => t('Popup node form'),
'js' => $path . '/js/slickgrid.editors.js',
'css' => $path . '/css/slickgrid.editors.css',
'plugin_type' => 'editor',
),
'requiredFieldValidator' => array(
'description' => t('Required field'),
'js' => $path . '/js/slickgrid.validators.js',
'plugin_type' => 'validator',
),
'textFilter' => array(
'description' => t('Text filter'),
'js' => $path . '/js/slickgrid.filters.js',
'plugin_type' => 'filter',
),
);
return $plugins;
}
function slickgrid_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'delete':
slickgrid_delete_settings(array(
'uid' => $account->uid,
));
break;
}
}
function slickgrid_form_alter(&$form, $form_state, $form_id) {
global $user;
switch ($form_id) {
case 'views_ui_rearrange_form':
$form['buttons']['submit']['#submit'][] = 'slickgrid_views_ui_rearrange_form_submit';
break;
}
if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id && arg(0) == 'slickgrid') {
$form['#pre_render'][] = 'slickgrid_node_form_pre_render';
}
}
function slickgrid_preprocess_views_view_slickgrid(&$vars) {
global $user;
module_load_include('inc', 'node', 'node.pages');
$view = $vars['view'];
$view->style_plugin->options['settings'] = (array) slickgrid_get_settings($user->uid, $view->name) + (array) $view->style_plugin->options['settings'];
$view->style_plugin->options['headerHeight'] = 42;
$view->style_plugin->options['enableCellNavigation'] = $view->style_plugin->options['editable'];
$view->style_plugin->options['enableAddRow'] = false;
if (is_numeric($view->style_plugin->options['settings']['viewport_height'])) {
$view->style_plugin->options['viewport_height'] = $view->style_plugin->options['settings']['viewport_height'];
}
if (isset($view->style_plugin->options['settings']['forceFitColumns'])) {
$view->style_plugin->options['forceFitColumns'] = (int) $view->style_plugin->options['settings']['forceFitColumns'];
}
$result = $vars['rows'];
$handler = $view->style_plugin;
$handlers = $view->style_plugin->display->handler
->get_handlers('field');
$fields =& $view->field;
$ordered_columns = array();
$unordered_columns = array();
foreach ($handlers as $field => $handler) {
if ($handler->options['exclude']) {
continue;
}
if (!($name = $handler
->label())) {
$name = $handler
->ui_name();
}
$handler->content_field['field_name'] ? $field_name = $handler->content_field['field_name'] : ($field_name = $field);
if ($view->style_plugin->options['settings']['column_width'][$field]) {
$column_width = $view->style_plugin->options['settings']['column_width'][$field];
}
elseif ($view->style_plugin->options['columns'][$field]['width']) {
$column_width = $view->style_plugin->options['columns'][$field]['width'];
}
else {
$column_width = 100;
}
$column = array(
'id' => $field,
'name' => $name,
'field' => $field_name,
'width' => $column_width,
'cssClass' => 'cell-title',
'resizable' => $view->style_plugin->options['enableColumnResize'] ? 1 : 0,
);
if (is_array($handler->options['vids']) && ($vid = slickgrid_taxonomy_field_get_vid($handler))) {
$column['vid'] = $vid;
}
if ($view->style_plugin->options['columns'][$field]['filter']) {
$view->style_plugin->options['has_filters'] = TRUE;
if ($view->style_plugin->options['collapsible_taxonomy_field'] != $field) {
$view->style_plugin->options['showHeaderRow'] = TRUE;
}
}
foreach (array_keys(slickgrid_get_plugin_types()) as $plugin_type) {
if ($view->style_plugin->options['columns'][$field][$plugin_type]) {
$column[$plugin_type] = $view->style_plugin->options['columns'][$field][$plugin_type];
if ($plugin_type == 'editor') {
$view->style_plugin->options['editable'] = TRUE;
$view->style_plugin->options['enableCellNavigation'] = TRUE;
}
}
}
if ($view->style_plugin->options['columns'][$field]['sortable'] & !$view->style_plugin->options['collapsible_taxonomy_field']) {
$view->style_plugin->options['sortable_columns'] = TRUE;
$column['sortable'] = 1;
}
if ($view->style_plugin->options['collapsible_taxonomy_field'] == $field) {
$view->style_plugin->options['columns'][$field]['filter'] = $column['filter'] = 'collapsibleFilter';
$view->style_plugin->options['columns'][$field]['formatter'] = $column['formatter'] = 'collapsibleFormatter';
$view->style_plugin->options['has_filters'] = true;
}
$view->style_plugin->options['columns'][$field]['label'] = $name;
if (is_array($view->style_plugin->options['settings']['ordered_columns']) && is_numeric($ordered_column_position = array_search($field, $view->style_plugin->options['settings']['ordered_columns']))) {
$ordered_columns[$ordered_column_position] = $column;
}
else {
$unordered_columns[] = $column;
}
}
ksort($ordered_columns);
$columns = array_merge($ordered_columns, $unordered_columns);
drupal_alter('slickgrid', $data, 'columns', $view);
$keys = array_keys($view->field);
$parents = array();
$data = array();
if (is_array($result)) {
$ids = array();
foreach ($result as $count => $row) {
if (in_array($row->nid, $ids)) {
drupal_set_message(t('There are duplicate nodes in this grid - each row must be unique.'), 'error');
watchdog('slickgrid', t('Duplicate nodes - @id is not unique.'), array(
'@id' => $row->{$view->base_field},
), WATCHDOG_ERROR);
break;
}
else {
foreach ($columns as $column) {
if (!$view->field[$column['field']]->options['exclude']) {
$data[$count][$column['field']] = $view->field[$column['id']]
->theme($row);
}
}
$data[$count]['id'] = $row->nid;
if (property_exists($row, $view->field['slickgrid_tid']->field_alias) && ($slickgrid_tid = $row->{$view->field['slickgrid_tid']->field_alias})) {
if ($parent = $parents[$row->{$view->field['slickgrid_parent_tid']->field_alias}]) {
$data[$count]['indent'] = $parent['indent'] + 1;
$data[$count]['parent'] = $parent['nid'];
}
else {
$data[$count]['indent'] = 0;
$data[$count]['parent'] = 0;
}
$parents[$slickgrid_tid] = array(
'nid' => $row->nid,
'indent' => $data[$count]['indent'],
);
}
}
}
}
drupal_alter('slickgrid', $data, 'data', $view);
$vars['slickgrid'] = theme('slickgrid', $view->style_plugin->options, $columns, $data, $view);
}
function theme_slickgrid($options, $columns, $data, $view) {
$output = '';
_slickgrid_add_files($options, $columns);
$js = array();
$js[] = 'var options = ' . drupal_to_js($options) . ';';
$js[] = 'var data = [];';
if (count($data)) {
$js[] = 'data = ' . drupal_to_js($data) . ';';
}
$js[] = 'var columns = ' . _slickgrid_drupal_to_js($columns) . ';';
$js[] = 'var slickgrid;';
$js[] = '$(function() {';
$js[] = 'slickgrid = new Slickgrid("#slickgrid", "' . $view->name . '", "' . $view->current_display . '", "' . url(SLICKGRID_CALLBACK_PATH) . '");';
$js[] = '})';
drupal_add_js(implode("\n", $js), 'inline');
$output .= '<div id="slickgrid" style="width:100%;height:' . $options['viewport_height'] . 'px;" class="hideCols hideRows ' . ($options['editable'] ? 'editable' : '') . '"></div>';
$output .= '<div id="controls">';
if ($options['pager']) {
$output .= '<div id="slickgrid-pager"></div>';
}
if ($options['undo']) {
$output .= '<div id="slickgrid-undo" title="Undo"></div>';
}
$output .= '<div id="slickgrid-status"></div>';
$output .= '<div id="slickgrid-loading-bar"></div>';
$output .= '</div>';
if ($options['delete_nodes']) {
$output .= '<div id="slickgrid-delete" style="display:none;position:absolute"><h6>Delete node</h6><p>Are you sure you want to delete this node? This action cannot be undone!</p><p class="buttons"><input type="button" value="Delete" id="slickgrid-delete-button" /><input type="button" value="Cancel" id="slickgrid-cancel-delete" /></p></div>';
}
return $output;
}
function theme_slickgrid_views_plugin_table($form) {
$output = drupal_render($form['description_markup']);
$header = array(
t('Field'),
t('Width'),
t('Sortable'),
);
$rows = array();
$plugin_types = slickgrid_get_plugin_types();
$header += $plugin_types;
foreach (element_children($form['columns']) as $id) {
$row = array();
$row[] = drupal_render($form['columns'][$id]['name']);
$row[] = drupal_render($form['columns'][$id]['width']);
$row[] = drupal_render($form['columns'][$id]['sortable']);
foreach (array_keys($plugin_types) as $plugin_type) {
$row[] = drupal_render($form['columns'][$id][$plugin_type]);
}
$rows[] = $row;
}
$output .= theme('table', $header, $rows);
$output .= drupal_render($form);
return $output;
}
function slickgrid_set_settings($uid, $view_name, $settings) {
$record = new stdClass();
$record->uid = $uid;
$record->view_name = $view_name;
if ($record->settings = slickgrid_get_settings($uid, $view_name)) {
$update = array(
'uid',
'view_name',
);
}
else {
$update = array();
}
foreach ($settings as $setting => $value) {
$record->settings[$setting] = $value;
}
$record->settings = serialize($record->settings);
drupal_write_record('slickgrid', $record, $update);
}
function slickgrid_get_settings($uid, $view_name, $setting = null) {
$settings = unserialize(db_result(db_query("SELECT settings FROM {slickgrid} WHERE uid = %d AND view_name = '%s'", $uid, $view_name)));
if ($setting) {
return $settings[$setting];
}
else {
return $settings;
}
}
function slickgrid_delete_settings($params) {
$conj = '';
if (count($params)) {
$sql = 'DELETE FROM {slickgrid} WHERE ';
foreach ($params as $field => $param) {
$sql .= $conj . $field . ' = "%s"';
$conj = ' AND ';
}
db_query($sql, $params);
}
}
function _slickgrid_add_files($options, $columns) {
$path = drupal_get_path('module', 'slickgrid');
drupal_add_js($path . '/js/slickgrid/lib/jquery-1.4.3.min.js');
drupal_add_js($path . '/js/slickgrid/lib/firebugx.js');
drupal_add_js($path . '/js/slickgrid/lib/jquery.event.drag-2.0.min.js');
drupal_add_js($path . '/js/slickgrid/slick.core.js');
drupal_add_js($path . '/js/slickgrid/slick.dataview.js');
drupal_add_js($path . '/js/slickgrid/slick.grid.js');
drupal_add_css($path . '/js/slickgrid/slick.grid.css');
drupal_add_js($path . '/js/slickgrid/lib/jquery-ui-1.8.5.custom.min.js');
drupal_add_css($path . '/js/slickgrid/css/smoothness/jquery-ui-1.8.5.custom.css');
drupal_add_js($path . '/js/slickgrid/plugins/slick.checkboxselectcolumn.js');
drupal_add_js($path . '/js/slickgrid/plugins/slick.rowselectionmodel.js');
if ($options['pager']) {
drupal_add_js($path . '/js/slickgrid/controls/slick.pager.js');
drupal_add_css($path . '/js/slickgrid/controls/slick.pager.css');
}
if ($options['select_columns']) {
drupal_add_js($path . '/js/slickgrid/controls/slick.columnpicker.js');
drupal_add_css($path . '/js/slickgrid/controls/slick.columnpicker.css');
}
if ($options['grouping_field']) {
drupal_add_js($path . '/js/slickgrid.groups-ui.js');
}
if ($options['collapsible_taxonomy_field']) {
drupal_add_js($path . '/js/slickgrid.collapsible.js');
}
$slickgrid_plugins = slickgrid_get_plugins();
foreach ($columns as $column) {
foreach (array_keys(slickgrid_get_plugin_types()) as $plugin_type) {
if (isset($column[$plugin_type])) {
if (isset($slickgrid_plugins[$column[$plugin_type]]['js'])) {
drupal_add_js($slickgrid_plugins[$column[$plugin_type]]['js']);
}
if (isset($slickgrid_plugins[$column[$plugin_type]]['css'])) {
drupal_add_css($slickgrid_plugins[$column[$plugin_type]]['css']);
}
}
}
}
drupal_add_js($path . '/js/slickgrid.js');
drupal_add_css($path . '/css/slickgrid.css');
beautytips_add_beautytips();
if (module_exists('wysiwyg')) {
$filter_formats = filter_formats();
foreach ($filter_formats as $filter_format) {
wysiwyg_get_profile($filter_format->format);
}
}
}
function _slickgrid_drupal_to_js($elements, $additional_function_names = array()) {
$function_names = array(
'formatter',
'validator',
'editor',
'setValueHandler',
'resizable',
);
if (count($additional_function_names)) {
$function_names += $additional_function_names;
}
if (count($elements)) {
$js_string = '[';
foreach ($elements as $element) {
$js_string .= $outer_conjunction . '{';
foreach ($element as $element_name => $element_value) {
$js_string .= $inner_conjunction;
if (in_array($element_name, $function_names) || is_numeric($element_value) || is_bool($element_value)) {
$js_string .= $element_name . ': ' . $element_value;
}
else {
$js_string .= $element_name . ': ' . drupal_to_js($element_value);
}
$inner_conjunction = ', ';
}
$js_string .= '}';
$inner_conjunction = ' ';
$outer_conjunction = ', ';
}
$js_string .= ']';
return $js_string;
}
}
function slickgrid_plugins_list($reset = FALSE) {
static $plugins;
if (!isset($plugins) || $reset) {
$editors = module_invoke_all('slickgrid_plugins');
drupal_alter('slickgrid_plugins', $editors);
}
return (array) $editors;
}
function slickgrid_get_plugins($filters = array()) {
$plugins = slickgrid_plugins_list();
if (is_array($filters)) {
$plugins = slickgrid_filter_plugins($plugins, $filters);
}
return $plugins;
}
function slickgrid_filter_plugins($plugins, $filters) {
foreach ($plugins as $plugin_type => $plugin) {
foreach ($filters as $property => $value) {
if (is_array($plugin[$property]) && !in_array($value, $plugin[$property]) || is_string($plugin[$property]) && $plugin[$property] != $value) {
unset($plugins[$plugin_type]);
break;
}
}
}
return $plugins;
}
function slickgrid_get_plugin_types() {
return array(
'formatter' => t('Formatter'),
'editor' => t('Editor'),
'validator' => t('Validator'),
'filter' => t('Filter'),
);
}
function slickgrid_json($var = NULL) {
drupal_set_header('Content-Type: text/javascript; charset=utf-8');
if (isset($var)) {
echo json_encode($var);
}
exit;
}
function slickgrid_taxonomy_field_get_vid($handler) {
$vids = array_filter($handler->options['vids']);
if (count($vids) == 1) {
return current($vids);
}
return FALSE;
}
function slickgrid_views_ui_rearrange_form_submit($form, $form_state) {
global $user;
$settings = slickgrid_get_settings($user->uid, $form_state['view']->name);
if (is_array($settings)) {
slickgrid_set_settings($user->uid, $form_state['view']->name, array(
'hidden_columns' => null,
'ordered_columns' => null,
));
}
}
function slickgrid_node_form_pre_render(&$form, &$form_state) {
if ($_POST['vid']) {
$vid = $_POST['vid'];
$vocabularies = taxonomy_get_vocabularies($form['#node']->type);
if ($vocabularies[$vid]->tags) {
$form['#field_name'] = 'taxonomy[tags][' . $vid . ']';
}
else {
$form['#field_name'] = 'taxonomy[' . $vid . ']';
}
}
elseif ($_POST['field_name'] == 'group_nid') {
$form['#field_name'] = 'og_groups';
}
elseif ($_POST['field_name'] == 'body') {
$form['#field_name'] = 'body_field';
}
else {
$form['#field_name'] = $_POST['field_name'];
}
drupal_alter('slickgrid_field', $form, $form['#field_name']);
if (!slickgrid_callback_get_form_element($form, $form['#field_name'])) {
drupal_set_message(t('Field not found'), 'error');
}
return $form;
}
function slickgrid_callback_get_form_element(&$form, $field_name) {
static $element_exists;
foreach (element_children($form) as $key) {
if ($key === $field_name || $form[$key]['#name'] == $field_name) {
if ($form['#type'] == 'fieldset') {
unset($form['#type']);
}
$element_exists = true;
}
else {
if (count(element_children($form[$key]))) {
slickgrid_callback_get_form_element($form[$key], $field_name);
}
if (!count(element_children($form[$key]))) {
if (!in_array($key, array(
'form_build_id',
'form_id',
)) || is_numeric($key)) {
unset($form[$key]);
}
}
}
}
return $element_exists;
}