nodehierarchy_widgets.module in Node Hierarchy 7.2
Same filename and directory in other branches
Alternative parent selector widgets for Node Hierarchy.
File
nodehierarchy_widgets/nodehierarchy_widgets.moduleView source
<?php
/**
* @file
* Alternative parent selector widgets for Node Hierarchy.
*/
/**
* Implements hook_menu().
*/
function nodehierarchy_widgets_menu() {
$items = array();
$items['nodehierarchy/autocomplete/parent'] = array(
'title' => 'Autocomplete',
'access arguments' => array(
'access content',
),
'page callback' => 'nodehierarchy_widgets_autocomplete_parent',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implements hook_nodehierarchy_get_parent_selector().
*/
function nodehierarchy_widgets_nodehierarchy_get_parent_selector($child_type, $pnid, $exclude = NULL) {
if (variable_get('nodehierarchy_widgets_parent_selector', 'autocomplete') == 'autocomplete') {
drupal_add_css(drupal_get_path('module', 'nodehierarchy_widgets') . '/nodehierarchy_widgets.css');
$out = array(
'#type' => 'textfield',
'#autocomplete_path' => 'nodehierarchy/autocomplete/parent/' . $child_type . '/' . $exclude,
'#child_type' => $child_type,
'#exclude' => $exclude,
'#description' => 'Enter the title of the parent node.',
'#element_validate' => array(
'_nodehierarchy_widgets_autocomplete_parent_validate',
),
'#default_value' => _nodehierarchy_widgets_autocomplete_parent_value($pnid),
);
return array(
$out,
);
}
}
/**
* Page callback for autocomplete.
*/
function nodehierarchy_widgets_autocomplete_parent($child_type = NULL, $exclude = NULL, $string = NULL) {
$nodes = array();
$length = strlen($string);
$options = _nodehierarchy_widgets_parent_autocomplete_options($child_type, $exclude, $string);
foreach ($options as $key => $item) {
$start = empty($string) ? FALSE : strpos(strtolower($item['title']), strtolower($string));
if ($start !== FALSE) {
$rendered = $item['title'];
$rendered = substr_replace($rendered, '<u>', $start, 0);
$rendered = substr_replace($rendered, '</u>', $start + $length + 3, 0);
$trail = _nodehierarchy_widgets_autocomplete_parent_heirarchy_trail($item);
if (count($trail) > 1) {
$rendered .= ' <span class="nodehierarchy-autocomplete-trail">(' . implode(' ▸ ', $trail) . ')</span>';
}
$nodes[$item['title'] . ' [nid:' . $item['nid'] . ']'] = $rendered;
}
}
drupal_json_output($nodes);
}
function _nodehierarchy_widgets_autocomplete_parent_heirarchy_trail($item) {
$out = array();
$menu_links = _nodehierarchy_get_node_primary_ancestor_menu_links($item['nid']);
$menu_links = (array) array_pop($menu_links);
$out = array();
foreach ($menu_links as $menu_link) {
if ($menu_link) {
$out[] = $menu_link['link_title'];
}
}
return $out;
}
/**
* Return a list of menu items that are valid possible parents for the given node.
*/
function _nodehierarchy_widgets_parent_autocomplete_options($child_type, $exclude = NULL, $string = NULL) {
// Get all the possible parents.
$types = nodehierarchy_get_allowed_parent_types();
foreach ($types as $i => $type) {
$types[$i] = "'{$type}'";
}
// Get the items with menu links.
$items = $mlids = $tree = array();
if ($types) {
// TODO Please convert this statement to the D7 database API syntax.
$result = db_query("SELECT n.nid, n.type as type, n.title as title, ml.*, IF(depth IS NULL, 1, depth) as depth, IF(ml.mlid IS NULL, CONCAT('nid:', n.nid), ml.mlid) as mlid, ml.mlid as linkid\n FROM {node} n\n LEFT JOIN {nodehierarchy_menu_links} nh_parent\n ON nh_parent.nid = n.nid\n LEFT JOIN {menu_links} ml\n ON ml.mlid = nh_parent.mlid\n WHERE (ml.module = 'nodehierarchy' OR ml.module IS NULL)\n AND n.type IN (" . implode(', ', $types) . ")\n AND LOWER(n.title) LIKE :title\n ORDER BY IF(p1 IS NULL, n.created, 0) ASC, p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC, p6 ASC, p7 ASC, p8 ASC, p9 ASC", array(
'title' => '%' . db_like(strtolower($string)) . '%',
), array(
'fetch' => PDO::FETCH_ASSOC,
));
}
// Flatten tree to a list of options.
$parent_types = nodehierarchy_get_allowed_parent_types($child_type);
$out = nodehierarchy_tree_data($result, $exclude, $parent_types);
return $out;
}
/**
* Return a list of menu items that are valid possible parents for the given node.
*/
function _nodehierarchy_widgets_is_invalid_parent($parent_nid, $child_nid, $child_type) {
$parent = node_load($parent_nid);
// Check for a valid parent type.
if (!$parent) {
return t('The specified parent cannot be found');
}
// Check for a valid parent type.
$types = nodehierarchy_get_allowed_parent_types($child_type);
if (!in_array($parent->type, $types)) {
return t('%title cannot be a parent of this node because %type is not an allowed parent node type.', array(
'%title' => $parent->title,
'%type' => node_type_get_name($parent->type),
));
}
// Check that the parent is not a child of itself
if ($parent_nid == $child_nid) {
return t('%title cannot be a parent of itself.', array(
'%title' => $parent->title,
));
}
// Check that the parent is not a descendant of the given node.
$ancestors = nodehierarchy_get_node_ancestor_nids($parent_nid);
if (in_array($child_nid, $ancestors)) {
return t('%title cannot be a parent of this node it is a descendant of the node.', array(
'%title' => $parent->title,
));
}
return FALSE;
}
/**
* Get the default display value for a node hierarchy autocomplete.
*/
function _nodehierarchy_widgets_autocomplete_parent_value($pnid) {
if ($pnid && ($item = node_load($pnid))) {
return $item->title . ' [nid:' . $item->nid . ']';
}
}
/**
* Validate a node hierarchy autocomplete in the format 'Tile [nid:xx]' or '[nid:xx]' or 'Title'.
*/
function _nodehierarchy_widgets_autocomplete_parent_validate($element, &$form_state) {
$child_type = $element['#child_type'];
$exclude = $element['#exclude'];
$value = $element['#value'];
$nid = NULL;
if (!empty($value)) {
preg_match('/^(?:\\s*|(.*) )?\\[\\s*nid\\s*:\\s*(\\d+)\\s*\\]$/', $value, $matches);
if (!empty($matches)) {
// Explicit [nid:n].
list(, $title, $nid) = $matches;
if (isset($form_state['values']['nid'])) {
if ($err = _nodehierarchy_widgets_is_invalid_parent($nid, $form_state['values']['nid'], $form_state['values']['type'])) {
form_error($element, $err);
}
}
}
else {
// No explicit nid.
$options = _nodehierarchy_widgets_parent_autocomplete_options($form_state['values']['type'], $form_state['values']['nid'], trim($value));
if (empty($options)) {
form_error($element, t('There are no available parents called \'%name\'', array(
'%name' => $value,
)));
}
else {
$key = key($options);
if ($err = _nodehierarchy_widgets_is_invalid_parent($options[$key]['nid'], $form_state['values']['nid'], $form_state['values']['type'])) {
form_error($element, $err);
}
else {
$nid = $key;
}
}
}
}
form_set_value($element, $nid, $form_state);
}
Functions
Name | Description |
---|---|
nodehierarchy_widgets_autocomplete_parent | Page callback for autocomplete. |
nodehierarchy_widgets_menu | Implements hook_menu(). |
nodehierarchy_widgets_nodehierarchy_get_parent_selector | Implements hook_nodehierarchy_get_parent_selector(). |
_nodehierarchy_widgets_autocomplete_parent_heirarchy_trail | |
_nodehierarchy_widgets_autocomplete_parent_validate | Validate a node hierarchy autocomplete in the format 'Tile [nid:xx]' or '[nid:xx]' or 'Title'. |
_nodehierarchy_widgets_autocomplete_parent_value | Get the default display value for a node hierarchy autocomplete. |
_nodehierarchy_widgets_is_invalid_parent | Return a list of menu items that are valid possible parents for the given node. |
_nodehierarchy_widgets_parent_autocomplete_options | Return a list of menu items that are valid possible parents for the given node. |