data_node.module in Data 6
Hooks and API functions for Data Node module.
File
data_node/data_node.moduleView source
<?php
/**
* @file
* Hooks and API functions for Data Node module.
*/
/**
* Implementation of hook_views_api().
*/
function data_node_views_api() {
return array(
'api' => '2.0',
'path' => drupal_get_path('module', 'data_node') . '/views',
);
}
/**
* Implementation of hook_theme().
*/
function data_node_theme() {
return array(
'data_node_label' => array(
'arguments' => array(
'table' => NULL,
'id' => NULL,
'nid' => NULL,
'title' => NULL,
),
'file' => 'data_node.theme.inc',
),
'data_node_active_form' => array(
'arguments' => array(
'form' => array(),
),
'file' => 'data_node.theme.inc',
),
);
}
/**
* Implementation of hook_block().
*/
function data_node_block($op = 'list', $delta = 0) {
switch ($op) {
case 'list':
$blocks = array();
$tables = data_get_all_tables();
foreach ($tables as $table) {
$meta = $table
->get('meta');
if (!empty($meta['data_node']['content_type'])) {
$blocks[$table
->get('name')]['info'] = t('Data node: Active node form for @table', array(
'@table' => $table
->get('title'),
));
}
}
return $blocks;
case 'view':
if (user_access('manage data relations') && ($table = data_get_table($delta))) {
// Grab the node type name
$meta = $table
->get('meta');
$names = node_get_types('names');
$type_name = check_plain($names[$meta['data_node']['content_type']]);
return array(
'subject' => t('Active !type', array(
'!type' => $type_name,
)),
'content' => drupal_get_form('data_node_active_form', $table),
);
}
}
}
/**
* Implementation of hook_menu().
*/
function data_node_menu() {
$items = array();
$items['data-node/add/%data_ui_table/%/%/%'] = array(
'page callback' => 'data_node_add_page',
'page arguments' => array(
2,
3,
4,
5,
),
'access callback' => 'user_access',
'access arguments' => array(
'manage data relations',
),
'type' => MENU_CALLBACK,
);
$items['data-node/remove/%data_ui_table/%/%/%'] = array(
'page callback' => 'data_node_remove_page',
'page arguments' => array(
2,
3,
4,
5,
),
'access callback' => 'user_access',
'access arguments' => array(
'manage data relations',
),
'type' => MENU_CALLBACK,
);
$items['data-node/active/%data_ui_table/%'] = array(
'page callback' => 'data_node_active_page',
'page arguments' => array(
2,
3,
),
'access callback' => 'user_access',
'access arguments' => array(
'manage data relations',
),
'type' => MENU_CALLBACK,
);
$items['admin/build/data/edit/%data_ui_table/node'] = array(
'title' => 'Relate to nodes',
'description' => 'Administer data tables.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'data_node_settings_form',
4,
),
'file' => 'data_node.admin.inc',
'access arguments' => array(
'administer data tables',
),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Implementation of hook_perm().
*/
function data_node_perm() {
return array(
'edit data node relations',
);
}
/**
* Form callback for setting the active node.
*/
function data_node_active_form(&$form_state, $table) {
$form = array(
'#attributes' => array(
'class' => 'data-node-active-form',
),
'#table' => $table,
'#theme' => 'data_node_active_form',
// These three are here to keep JS from doing reconstructive URL surgery.
'ajax_url' => array(
'#type' => 'hidden',
'#value' => url('data-node/active/' . $table
->get('name')),
'#attributes' => array(
'class' => 'data-node-ajax-url',
),
),
'add_url' => array(
'#type' => 'hidden',
'#value' => url('data-node/add/' . $table
->get('name')),
'#attributes' => array(
'class' => 'data-node-add-url',
),
),
'remove_url' => array(
'#type' => 'hidden',
'#value' => url('data-node/remove/' . $table
->get('name')),
'#attributes' => array(
'class' => 'data-node-remove-url',
),
),
);
$nodes = array(
0 => '--' . t('Select') . '--',
);
$nodes += data_node_get_nodes($table);
// Grab the node type name and provide a creation option
$meta = $table
->get('meta');
$names = node_get_types('names');
$type_name = check_plain($names[$meta['data_node']['content_type']]);
if (node_access('create', $meta['data_node']['content_type'])) {
$nodes['new'] = '< ' . t('New !type', array(
'!type' => $type_name,
)) . ' >';
}
$form['nid'] = array(
'#type' => 'select',
'#title' => t('Active !type', array(
'!type' => $type_name,
)),
'#options' => $nodes,
'#default_value' => data_node_get_active($table
->get('name')),
);
if (node_access('create', $meta['data_node']['content_type'])) {
$form['new'] = array(
'#tree' => FALSE,
);
$form['new']['type'] = array(
'#type' => 'value',
'#value' => $meta['data_node']['content_type'],
);
$form['new']['title'] = array(
'#type' => 'textfield',
'#size' => 20,
);
$form['new']['create'] = array(
'#type' => 'submit',
'#value' => t('Create'),
'#submit' => array(
'data_node_active_form_create_submit',
),
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Set'),
'#submit' => array(
'data_node_active_form_submit',
),
);
return $form;
}
/**
* Submit handler for form.
*/
function data_node_active_form_submit($form, &$form_state) {
data_node_set_active($form['#table']
->get('name'), $form_state['values']['nid']);
// Redirect ourselves because '#redirect' does not support queries.
$query = array();
foreach ($_GET as $k => $v) {
if ($k != 'q') {
$query[] = "{$k}={$v}";
}
}
drupal_goto($_GET['q'], implode('&', $query));
}
/**
* Create submit handler for form.
*/
function data_node_active_form_create_submit($form, &$form_state) {
$title = trim($form_state['values']['title']);
if (!empty($title)) {
global $user;
$node = new stdClass();
$node->uid = $user->uid;
$node->title = $title;
$node->type = $form_state['values']['type'];
$node->body = '';
foreach (variable_get('node_options_' . $node->type, array(
'status',
)) as $key) {
$node->{$key} = 1;
}
node_save($node);
data_node_set_active($form['#table']
->get('name'), $node->nid);
}
// Redirect ourselves because '#redirect' does not support queries.
$query = array();
foreach ($_GET as $k => $v) {
if ($k != 'q') {
$query[] = "{$k}={$v}";
}
}
drupal_goto($_GET['q'], implode('&', $query));
}
/**
* Page callback for adding.
*
* @todo: add tokenizing drupal_valid_token/drupal_get_token to prevent XSS
*/
function data_node_add_page($table, $id, $nid, $token) {
if (drupal_valid_token($token, _data_node_hash($table, $id, $nid))) {
data_node_remove($table, $id, $nid);
data_node_add($table, $id, $nid);
}
// Handle AJAX requests
if (isset($_GET['ajax'])) {
$response = array(
'status' => TRUE,
'table' => $table
->get('name'),
'id' => $id,
'nid' => $nid,
'labels' => data_node_render_labels($table, $id),
'add_link' => data_node_render_remove_link($table, $id, $nid),
'remove_link' => data_node_render_add_link($table, $id, $nid),
);
drupal_json($response);
exit;
}
drupal_goto($_GET['q']);
}
/**
* Page callback for setting the active node.
*/
function data_node_active_page($table, $nid) {
data_node_set_active($table
->get('name'), $nid);
// Handle AJAX requests
if (isset($_GET['ajax'])) {
// Generate new add/remove links to replace stale ones.
$stale = isset($_GET['stale']) ? explode('-', $_GET['stale']) : array();
$refresh = array();
foreach ($stale as $id) {
$node_list = data_node_get_nids($table, $id);
$refresh[$id] = in_array($nid, $node_list) ? data_node_render_remove_link($table, $id, $nid) : data_node_render_add_link($table, $id, $nid);
}
$response = array(
'status' => TRUE,
'table' => $table
->get('name'),
'nid' => $nid,
'refresh' => $refresh,
);
drupal_json($response);
exit;
}
drupal_goto($_GET['q']);
}
/**
* Page callback for removing.
*
* @todo: add tokenizing drupal_valid_token/drupal_get_token to prevent XSS
*/
function data_node_remove_page($table, $id, $nid, $token) {
if (drupal_valid_token($token, _data_node_hash($table, $id, $nid))) {
data_node_remove($table, $id, $nid);
}
// Handle AJAX requests
if (isset($_GET['ajax'])) {
$response = array(
'status' => TRUE,
'table' => $table
->get('name'),
'id' => $id,
'nid' => $nid,
'labels' => data_node_render_labels($table, $id),
'add_link' => data_node_render_remove_link($table, $id, $nid),
'remove_link' => data_node_render_add_link($table, $id, $nid),
);
drupal_json($response);
exit;
}
drupal_goto($_GET['q']);
}
/**
* Add a relationship between a data table and a node.
*/
function data_node_add($table, $id, $nid) {
$save = array(
'data_table_name' => $table
->get('name'),
'id' => $id,
'nid' => $nid,
);
return drupal_write_record('data_table_node', $save);
}
/**
* Get the nids for a given record.
*/
function data_node_get_nids($table, $id) {
$list = array();
$result = db_query("SELECT nid FROM {data_table_node} WHERE data_table_name = '%s' AND id = %d", $table
->get('name'), $id);
while ($row = db_fetch_object($result)) {
$list[] = $row->nid;
}
return $list;
}
/**
* Remove a relationship between a data table and a node.
*/
function data_node_remove($table, $id, $nid) {
db_query("DELETE FROM {data_table_node} WHERE data_table_name = '%s' AND id = %d AND nid = %d", $table
->get('name'), $id, $nid);
}
/**
* Get all available nodes for a specific table.
*/
function data_node_get_nodes($table) {
$nodes = array();
$meta = $table
->get('meta');
if ($meta['data_node']['content_type']) {
$result = db_query("SELECT nid, title FROM {node} WHERE type = '%s' ORDER BY title ASC", $meta['data_node']['content_type']);
while ($node = db_fetch_object($result)) {
$nodes[$node->nid] = $node->title;
}
}
return $nodes;
}
/**
* Set a specific node as the active node. This is used for the collection workflow.
*/
function data_node_set_active($table_name, $nid) {
$_SESSION['data_node_active'][$table_name] = $nid;
}
/**
* Get a the current active node. This is used for the collection workflow.
*/
function data_node_get_active($table_name) {
return $_SESSION['data_node_active'][$table_name];
}
/**
* Create a simple hash of a table name, an id and a nid.
*/
function _data_node_hash($table, $id, $nid) {
return $table
->get('name') . $id . $nid;
}
/**
* Static cache node titles to avoid unnecessary node loading.
*/
function _data_node_get_title($nid) {
static $nodes = array();
if (!isset($nodes[$nid])) {
$nodes[$nid] = check_plain(db_result(db_query("SELECT title FROM {node} WHERE nid = %d", $nid)));
}
return isset($nodes[$nid]) ? $nodes[$nid] : NULL;
}
/**
* Generate the path for a remove link for an item/node pair.
*/
function data_node_remove_path($table, $id, $nid) {
$token = drupal_get_token(_data_node_hash($table, $id, $nid));
$table_name = $table
->get('name');
return "data-node/remove/{$table_name}/{$id}/{$nid}/{$token}";
}
/**
* Generate the path for an add link for an item/node pair.
*/
function data_node_add_path($table, $id, $nid) {
$token = drupal_get_token(_data_node_hash($table, $id, $nid));
$table_name = $table
->get('name');
return "data-node/add/{$table_name}/{$id}/{$nid}/{$token}";
}
/**
* Render node-data labels for a given item.
*/
function data_node_render_labels($table, $id) {
$nids = data_node_get_nids($table, $id);
foreach ($nids as $nid) {
$title = _data_node_get_title($nid);
$output .= theme('data_node_label', $table, $id, $nid, $title);
}
$table_name = $table
->get('name');
$class = "data_node_labels-{$table_name}-{$id}";
return "<div class='{$class} clear-block'>{$output}</div>";
}
/**
* Render a placeholder when there are no active nodes that can be replaced via AJAX.
*/
function data_node_render_placeholder_link($table, $id) {
drupal_add_css(drupal_get_path('module', 'data_node') . '/data_node.css');
drupal_add_js(drupal_get_path('module', 'data_node') . '/data_node.js');
$table_name = $table
->get('name');
return "<span class='data-node-placeholder data_node_link-{$table_name}-{$id}-0'></span>";
}
/**
* Render an add link for a given item..
*/
function data_node_render_add_link($table, $id, $nid) {
drupal_add_css(drupal_get_path('module', 'data_node') . '/data_node.css');
drupal_add_js(drupal_get_path('module', 'data_node') . '/data_node.js');
$title = _data_node_get_title($nid);
$table_name = $table
->get('name');
$class = "data_node_link-{$table_name}-{$id}-{$nid}";
return l(t('Add to !title', array(
'!title' => $title,
)), data_node_add_path($table, $id, $nid), array(
'attributes' => array(
'class' => "data-node-add {$class}",
),
'query' => drupal_get_destination(),
));
}
/**
* Render a remove link for a given item.
*/
function data_node_render_remove_link($table, $id, $nid) {
drupal_add_css(drupal_get_path('module', 'data_node') . '/data_node.css');
drupal_add_js(drupal_get_path('module', 'data_node') . '/data_node.js');
$title = _data_node_get_title($nid);
$table_name = $table
->get('name');
$class = "data_node_link-{$table_name}-{$id}-{$nid}";
return l(t('Remove from !title', array(
'!title' => $title,
)), data_node_remove_path($table, $id, $nid), array(
'attributes' => array(
'class' => "data-node-remove {$class}",
),
'query' => drupal_get_destination(),
));
}
Functions
Name | Description |
---|---|
data_node_active_form | Form callback for setting the active node. |
data_node_active_form_create_submit | Create submit handler for form. |
data_node_active_form_submit | Submit handler for form. |
data_node_active_page | Page callback for setting the active node. |
data_node_add | Add a relationship between a data table and a node. |
data_node_add_page | Page callback for adding. |
data_node_add_path | Generate the path for an add link for an item/node pair. |
data_node_block | Implementation of hook_block(). |
data_node_get_active | Get a the current active node. This is used for the collection workflow. |
data_node_get_nids | Get the nids for a given record. |
data_node_get_nodes | Get all available nodes for a specific table. |
data_node_menu | Implementation of hook_menu(). |
data_node_perm | Implementation of hook_perm(). |
data_node_remove | Remove a relationship between a data table and a node. |
data_node_remove_page | Page callback for removing. |
data_node_remove_path | Generate the path for a remove link for an item/node pair. |
data_node_render_add_link | Render an add link for a given item.. |
data_node_render_labels | Render node-data labels for a given item. |
data_node_render_placeholder_link | Render a placeholder when there are no active nodes that can be replaced via AJAX. |
data_node_render_remove_link | Render a remove link for a given item. |
data_node_set_active | Set a specific node as the active node. This is used for the collection workflow. |
data_node_theme | Implementation of hook_theme(). |
data_node_views_api | Implementation of hook_views_api(). |
_data_node_get_title | Static cache node titles to avoid unnecessary node loading. |
_data_node_hash | Create a simple hash of a table name, an id and a nid. |