This CodeLet demonstration how to create a custom node in code and use different Drupal hooks to build different features.

The CodeLet implements following Drupal hooks:
- hook_node_info
- hook_menu
- hook_perm
- hook_nodeapi
- hook_form_FORM_ID_alter

This CodeLet also creates an xml document which will then be used by the gallery to display images as slideshow.

CodeLet

<?php
//$Id$

/**
* @file
*
* Provide a gallery node where user can upload images
*
* hook = node_gallery
*
* @author Drupal Developer
*/

/**
* Implementation of hook_node_info
*
* @author Drupal Developer
*/
function node_gallery_node_info() {
return array(
'node_gallery_image' => array(
'name' => t("node image"),
'module' => 'node_gallery',
'description' => t("Add images to node gallery"),
),
);
}

/**
* Implementation of hook_menu
*
* @author Drupal Developer
*/
function node_gallery_menu() {
$items = array();

$items['gallery'] = array(
'type' => MENU_NORMAL_ITEM,
'title' => 'node Gallery',
'page callback' => 'node_gallery_gallery',
'access callback' => TRUE,
'weight' => -10,
);

$items['node-gallery/remove/%'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'node_image_tag',
'page arguments' => array(1, 2),
'access callback' => 'user_access',
);

$items['node-gallery/add/%'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'node_image_tag',
'page arguments' => array(1, 2),
'access callback' => 'user_access',
);
return $items;
}

/**
* Implementation of hook_perm()
*
* @author Drupal Developer
*/
function node_gallery_perm() {
return array(
'administer node gallery',
'access node gallery',
);
}

/**
* Implementatin of hook_nodeapi
*
* @author Drupal Developer
*/
function node_gallery_nodeapi(&$node, $op, $a3, $a4) {
switch ($op) {
case 'load':
$r__result = db_query("SELECT delta, tag FROM {_image_tag} WHERE nid = %d",
$node->nid);
while ($om__result = db_fetch_object($r__result)) {
$ss__tag = db_result(db_query("SELECT name FROM {term_data}
WHERE tid = %d", $om__result->tag));

$node->field__image[$om__result->delta]['tag'][] = $ss__tag;
}
break;

case 'insert':
if (!empty($node->field__image)) {
$am__tag = preg_grep("/^selected_tag*/", array_keys($am__));

foreach ($am__tag as $ss__tag) {
$am__tags_split = preg_split("/selected_tag_/", $ss__tag, -1, PREG_SPLIT_NO_EMPTY);
$i = 0;
foreach ($am__tags_split as $ss__tag) {
if ($node->field__image[$i]['imceimage_path'] && $ss__tag) {
list($sn__delta, $tag) = preg_split("/[_]/", $ss__tag);
db_query("INSERT INTO {_image_tag} VALUES(_image_id, %d, %d, %d)",
$node->nid, ($sn__delta-1), $tag);
$i++;
}
}
}
}
break;

case 'update':
if (!empty($node->field__image)) {
$am__tag = preg_grep("/^selected_tag*/", array_keys($am__));
foreach ($am__tag as $ss__tag) {
$am__tags_split = preg_split("/selected_tag_/", $ss__tag, -1, PREG_SPLIT_NO_EMPTY);
$i = 0;
foreach ($am__tags_split as $ss__tag) {
if ($node->field__image[$i]['imceimage_path'] && $ss__tag) {
list($sn__delta, $tag) = preg_split("/[_]/", $ss__tag);
db_query("INSERT INTO {_image_tag} VALUES(_image_id, %d, %d, %d)",
$node->nid, ($sn__delta-1), $tag);
$i++;
}
}
}
}
break;

case 'delete':
if (!empty($node->field__image)) {
db_query("DELETE FROM {_image_tag} WHERE nid = %d", $node->nid);
drupal_set_message(t("image tags have been removed"));
}
node_gallery_build();
break;
}
}

/**
* node_gallery_gallery
*
* Return themed output of gallery images
*
* @author Drupal Developer
*/
function node_gallery_gallery() {
node_gallery_build();
$output = '

PREV
NEXT
play

prev

next

';
return $output;
}

/**
* Implementatino of hook_elements
*
* @author Drupal Developer
*/
function node_gallery_elements() {
return array(
'imceimage' => array(
'#process' => array('node_gallery_process'),
),
);
}

/**
* node_gallery_process
*
* @author Drupal Developer
*/
function node_gallery_process($element) {
$element['fie_image']['tag'] = array(
'#type' => 'item',
'#title' => t("Tag"),
'#value' => theme__image_tag(),
'#disabled' => TRUE,
'#weight' => 0,
);

return $element;
}

/**
* theme__image_tag()
*
* @author Drupal Developer
*/
function theme__image_tag() {
static $i;
$i++;
$form_state = array(NULL);
$sn__vid = db_result(db_query("SELECT vid FROM {vocabulary} WHERE name = '-vocabulary'"));
$am__term = array();
$form = array();

$form['field_tag_'. $i] = array(
'#type' => 'item',
'#prefix' => "",
'#suffix' => "",
);

if (arg(0) == '' && arg(2) == 'edit') {
//$form = form_get_cache($form_build_id, $form_state);
$r__result = db_query("SELECT delta, tag FROM {_image_tag} WHERE nid = %d AND delta = %d",
arg(1), $i - 1);
while ($om__result = db_fetch_object($r__result)) {
$ss__tag = db_result(db_query("SELECT name FROM {term_data}
WHERE tid = %d", $om__result->tag));
//$node->field__image[$om__result->delta]['tag'][] = $ss__tag;

$form['field_tag_'. $i]['sel_tag_'. $om__result->tag] = array(
'#type' => 'item',
'#value' => $ss__tag,
);

$sn__tag_id = $i ."_". $om__result->tag;
$form['field_tag_'. $i]['selected_tag_'. $sn__tag_id] = array (
'#type' => 'hidden',
'#value' => $om__result->tag,
);
}
}
else {
$form_id = NULL;
$form_build_id = NULL;
}

$form['remove_tag_'. $i] = array(
'#type' => 'button',
'#value' => t("Remove"),
'#attributes' => array(
'style' => 'float:left;margin-right:10px;',
'tag_id' => 'remove_tag_'. $i,
),

'#ahah' => array(
'event' => 'click',
'path' => '-gallery/remove/remove_tag_button_'. $i .'_'. arg(1),
'method' => 'replace',
'wrapper' => 'field_tag_'. $i,
'effect' => 'fade',
'progress' => array(
'type' => 'bar',
'message' => t("Removing tags") ."...",
),
),
);

$am__terms = taxonomy_get_tree($sn__vid);
foreach ($am__terms as $om__term) {
$am__term[$om__term->tid] = str_repeat('-', $om__term->depth) . $om__term->name;
}
$am__cs_term = taxonomy_get_term_by_name("Competition Series");
$am__child = taxonomy_get_children($am__cs_term[0]->tid);
$am__term[$am__cs_term[0]->tid] = $am__cs_term[0]->name;
foreach ($am__child as $tid => $o__term) {
$am__term[$tid] = '-'. $o__term->name;
}

$form['add_tag_'. $i] = array(
'#type' => 'select',
'#options' => $am__term,
'#attributes' => array(
'style' => 'float:left;margin:0 10px 0 15px;',
'tag_id' => 'add_tag_'. $i,
),
);

$form['add_tag_button_'. $i] = array(
'#type' => 'button',
'#value' => t("Add"),
'#attirbutes' => array('tag_id' => 'add_tag_button_'. $i),
'#ahah' => array(
'event' => 'click',
'path' => '-gallery/add/add_tag_button_'. $i,
'method' => 'append',
'wrapper' => 'field_tag_'. $i,
'effect' => 'fade',
'progress' => array(
'type' => 'bar',
'message' => t("Adding tags") ."...",
),
),
);

$form['description'] = array(
'#prefix' => "",
'#suffix' => "",
'#value' => t("Clicking on 'Remove' button will remove all the tags"),
);

$form['imce_help'] = array(
'#prefix' => "",
'#suffix' => "",
'#value' => t("Leave two spaeces after the string you want to display
as title below. i.e. Drupal[space][space]Drupal is community maintained CMS"),
);

return drupal_render(form_builder(NULL, $form, $form_state));
}

/**
* _image_tag
*
* Build and return image tags
*
* @param $op
* The operation being performed on the tag
* @param $ss__init
* The unique identifier of the operation initiator
* @return
* A Javascript object
* @author Drupal Developer
*/
function _image_tag($op, $ss__init) {
$output = '';
$form_build_id = $_POST['form_build_id'];
$form_id = $_POST['form_id'];
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$ss__init_num = preg_split("/[_]/", $ss__init);
$sn__inint_id = $ss__init_num[3];
$ss__selected_tag = $_POST['selected_tag_'. $sn__inint_id];
switch ($op) {
case 'remove':
$sn__nid = $ss__init_num[4];
db_query("DELETE FROM {_image_tag} WHERE nid = %d AND delta = %d", $sn__nid, $sn__inint_id - 1);
break;
case 'add':
$sn__tid = $_POST['add_tag_'. $sn__inint_id];
$ss__term_name = db_result(db_query("SELECT name from {term_data}
WHERE tid = %d", $sn__tid));

$form = form_get_cache($form_build_id, $form_state);
$form['field_tag_'. $i]['sel_tag_'. $i] = array(
'#type' => 'item',
'#value' => $ss__term_name,
);

$sn__tag_id = $sn__inint_id ."_". $sn__tid;
$form['field_tag_'. $i]['selected_tag_'. $sn__tag_id] = array (
'#type' => 'hidden',
'#value' => $sn__tid,
);

form_set_cache($form_build_id, $form, $form_state);
$form += array(
'#post' => $_POST,
'#programmed' => FALSE,
);

// Rebuild the form.
$form = form_builder($form_id, $form, $form_state);

$form_portion = $form['field_tag_'. $i];
$output = theme('status_messages') . drupal_render($form_portion);

break;
}

drupal_json(array('status' => TRUE, 'data' => $output));
}

/**
* node_gallery_build
*
* Build the gallery information and create xml file to be used by gallery js
*
* @author Drupal Developer
*/
function node_gallery_build() {
drupal_add_js(drupal_get_path('theme', '') ."/js/jquery.galleryscroll.js");

//$am__gallery = _get__gallery();
$am__filter = array();
if ($_GET['d_tid'] !== "All" && !empty($_GET['d_tid'])) {
$am__filter[] = is_numeric($_GET['d_tid']) ? $_GET['d_tid'] : NULL;
}

if (!empty($am__filter)) {
$ss__inner_join = " INNER JOIN {_image_tag} _tag
USING(nid, delta)";
$ss__tag_con = " AND _tag.tag in(%s)";
}

$ss__query = "SELECT DISTINCT field__image_imceimage_path,
field__image_imceimage_alt, created FROM {content_field__image} _image".
$ss__inner_join ." LEFT JOIN {} n ON _image.nid = n.nid WHERE
n.type = '_gallery_image' AND field__image_imceimage_path <> ''".
$ss__tag_con ." ORDER BY _image.delta";

$r__image = db_query($ss__query, !empty($am__filter) ? implode(",", $am__filter) : NULL);
$c = 0;

$path = drupal_get_path('module', '_gallery');
$om__doc = new XMLWriter();
$om__doc->openURI($path ."/inc/gallery.xml");
$om__doc->startDocument("1.0");
$om__doc->startElement("gallery");

while ($om__image = db_fetch_object($r__image)) {
if ($om__image->field__image_imceimage_path) {
$ss__date = format_date($om__image->created, 'custom', "jS ".
t("of") ." F Y | h:i A");
$ss__patern = "/[.*+\s?]\W/i";
$ss__caption = preg_split($ss__patern, $om__image->field__image_imceimage_alt);
$ss__description = $ss__caption[1] ? $ss__caption[1] : $ss__caption[0];

list($slash, $ss__path) = preg_split("/^[\/]/", $om__image->field__image_imceimage_path);
list($path, $image_name) = preg_split("/files/", $ss__path);

theme('imagecache', 'thumbnail', $ss__path);
theme('imagecache', 'main-image', $ss__path);
$main_img = $path ."files/imagecache/main-image". $image_name;
$thumb_img = $path ."files/imagecache/thumbnail". $image_name;

$om__doc->startElement("item");
$om__doc->startElement("id");
$om__doc->text($i);
$om__doc->endElement();
$om__doc->startElement("imgtitle");
$om__doc->text($ss__caption[0]);
$om__doc->endElement();
$om__doc->startElement("imgsource");
$om__doc->text($main_img);
$om__doc->endElement();
$om__doc->startElement("thumbsource");
$om__doc->text($thumb_img);
$om__doc->endElement();
$om__doc->startElement("info");
$om__doc->startElement("title");
$om__doc->text($ss__caption[0]);
$om__doc->endElement();
$om__doc->startElement("date");
$om__doc->text($ss__date);
$om__doc->endElement();
$om__doc->startElement("description");
$om__doc->text($ss__description);
$om__doc->endElement();
$om__doc->endElement();
$om__doc->endElement();
$c++;
}
}
$om__doc->endElement();
$om__doc->endDocument();
$om__doc->flush();
}

/**
* Implementation of hook_form_FORM_ID_alter()
*
* @author Drupal Developer
*/
function node_gallery_form_views_exposed_form_alter(&$form, &$form_state) {
$form['#action'] = url('gallery');
$form['d_tid']['#options']['All'] = t("Select Discipline");
$form['d_tid']['#attributes'] = array('style' => 'width:200px;', 'onchange' => 'this.form.submit()');
$form['submit']['#prefix'] = "";
$form['submit']['#suffix'] = "";
}
?>

DrupalD
Enroll to Drupal 10 Training