DrupalBin
Submit Code
About
Recent Posts
Fix for Code
Code
Code
Fix for YesCT make an acronym
YesCT make an acronym
Code
block_menu
Node lookup
Fix for Video tag RegExp
Video tag RegExp
more
User login
Log in using OpenID:
What is OpenID?
Username:
*
Password:
*
Log in using OpenID
Cancel OpenID login
Create new account
Request new password
Tags
CCK
drupal
fapi
jquery
menu
module
Panels
simpletest
test
theme
user
views
more tags
Home
›
A custom node type for vehicles using taxonomy to manage make / model details
Fix for A custom node type for vehicles using taxonomy to manage make / model details
View
Fix
Fixes are not saved to the database until you submit.
Summary:
Tags:
Any tags you'd like to associate with your code, delimitered by commas (example: Views, CCK, Module, etc).
Show summary in full view
<?php // $Id: vehicle.module,v 1.26 2008/10/9 13:40:00 michaelphipps Exp $ /** * @node_vehicle * This module defines a custom node type with a custom make / model form element * that is managed via taxonomy. * * No Database required */ /** * Implementation of hook_node_info(). */ function node_vehicle_node_info() { return array( 'vehicle' => array( 'name' => t('Vehicle'), 'module' => 'node_vehicle', 'description' => t("This is an Vehicle type with a few fields."), 'has_title' => TRUE, 'title_label' => t('Example Title'), 'has_body' => TRUE, 'body_label' => t('Example Body'), ) ); } /** * Implementation of hook_menu(). * * Provide a simple menu hook to access the javascript function. */ function node_vehicle_menu() { $items['vehicle/js'] = array( 'type' => 'MENU_CALLBACK', 'page callback' => 'node_vehicle_makemodel_javascript', 'access arguments' => array('access content'), ); return $items; } /** * Implementation of hook_access(). */ function node_vehicle_access($op, $node, $account) { if ($op == 'create') { return user_access('create vehicle content', $account); } if ($op == 'update') { if (user_access('edit any vehicle content', $account) || (user_access('edit own vehicle content', $account) && ($account->uid == $node->uid))) { return TRUE; } } if ($op == 'delete') { if (user_access('delete any vehicle content', $account) || (user_access('delete own vehicle content', $account) && ($account->uid == $node->uid))) { return TRUE; } } } /** * Implementation of hook_perm(). */ function node_vehicle_perm() { return array( 'create vehicle content', 'delete own vehicle content', 'delete any vehicle content', 'edit own vehicle content', 'edit any vehicle content', ); } /** * Implementation of hook_elements(). */ function node_vehicle_elements() { $type['makemodel'] = array( '#input' => TRUE, '#process' => array('node_vehicle_makemodel_expand'), '#element_validate' => array('node_vehicle_makemodel_validate'), '#default_value' => array('make' => '', 'model' => ''), ); return $type; } /** * The process callback to expand the makemodel control. */ function node_vehicle_makemodel_expand($element) { $element['#tree'] = TRUE; if ( !isset($element['#value']) ) { $element['#value'] = array('make' => '', 'model' => ''); } // Get the list of makes from the make/models vocabulary $vid = 1;// Should the user choose their Taxonomy category? $parent = 0; $max_depth = 1; $makes = taxonomy_get_tree($vid, $parent, -1, $max_depth); foreach ($makes as $make) { $make_options[$make->tid] = $make->name; } if ( isset($element['#value']['make']) ) { $models = taxonomy_get_tree($vid, $element['#value']['make'], -1, $max_depth); foreach ($models as $model) { $model_options[$model->tid] = $model->name; } } else { $model_options = array(); } $element['make'] = array( '#type' => 'select', '#value' => $element['#value']['make'], '#options' => $make_options, '#attributes' => array('onchange' => 'changeModel();'), ); $element['model'] = array( '#type' => 'select', '#value' => $element['#value']['model'], '#options' => $model_options, ); return $element; } /** * Our element's validation function. * * Not currently being used, because I'm unsure what validation I need to do on taxonomy * data and if it is even needed at all. */ function node_vehicle_makemodel_validate($form, &$form_state) { if ( isset($form['#value']['make']) ) { if (0 == 1) { form_error($form['make'], t('Please select a make.')); } } if ( isset($form['#value']['model']) ) { if (0 == 1) { form_error($form['model'], t('Please select a model.')); } } return $form; } /** * Theme function to format the output. * * We use the container-inline class so that all three of the HTML elements * are placed next to each other, rather than on separate lines. */ function theme_makemodel($element) { return theme('form_element', $element, '<div class="container-inline">'. $element['#children'] .'</div>'); } function node_vehicle_makemodel_javascript() { // Getting the list of makes from the make/models vocabulary $vid = 1 ; // Should the user choose their Taxonomy category? $parent = 0; $max_depth = 1; $makes = taxonomy_get_tree($vid, $parent, -1, $max_depth); foreach ($makes as $make) { $make_options[$make->tid ] = $make->name; } unset($temp); $content .= "model = new Array();\n"; $result = db_query("SELECT term_data.tid AS id, term_hierarchy.parent AS parentid, term_data.name AS model FROM {term_data} join {term_hierarchy} ON (term_data.tid = term_hierarchy.tid) WHERE term_data.vid=1 AND term_hierarchy.parent >0 ORDER BY parentid, model"); while ($models = db_fetch_object($result)) { if ( $temp == $models->parentid ) { $content .= ","; } else { if ( isset($temp) ) $content .= ");\n"; $temp=$models->parentid; $content .= "model[$temp] = new Array(\n"; } $content .= "'". $models->model ."',". $models->id ."\n"; } $content .= ");\n"; $content .= '//change model function changeModel(){ var objMake = document.getElementById("edit-makemodel-make"); var objModel = document.getElementById("edit-makemodel-model"); var make_id = objMake[objMake.selectedIndex].value; //clear model select oldLength = objModel.length; for (i = oldLength; i >= 0; i--) objModel.options[i] = null; //build model select if (make_id=="") objModel.options[0] = new Option("Any model",""); else for (i = 0; i <= model[make_id].length-1; i=i+2) objModel.options[i/2] = new Option(model[make_id][i],model[make_id][i+1]); } '; header("Content-type: text/javascript"); print $content; exit(); } /** * Implementation of hook_form(). * * Describe the form for collecting vehicle information. */ function node_vehicle_form(&$node) { // The site admin can decide if this node type has a title and body, and how // the fields should be labeled. We need to load these settings so we can // build the node form correctly. $type = node_get_types('type', $node); if ($type->has_title) { $form['title'] = array( '#type' => 'textfield', '#title' => check_plain($type->title_label), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5 ); } if ($type->has_body) { $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count); } // Add the javascript to make the make/model selection work properly drupal_add_js('vehicle/js'); // Now we define the form elements specific to our node type. $form['makemodel']= array( '#type' => 'makemodel', '#title' => t("Make/Model"), '#default_value' => array('make' => $node->make, 'model' => $node->model), '#description' => t('Select a vehicle make and model.'), ); return $form; } /** * Implementation of hook_validate(). * * Again, unsure if I need this since I am collecting taxonomy tids from select boxes. */ function node_vehicle_validate(&$node) { // include validation logic (if required) } /** * Implementation of hook_insert(). * * Saves the taxonomy details from the makemodel field. */ function node_vehicle_insert($node) { taxonomy_node_save($node, $node->makemodel); } /** * Implementation of hook_update(). * * Saves the taxonomy details from the makemodel field */ function node_vehicle_update($node) { // if this is a new node or we're adding a new revision, if ($node->revision) { node_vehicle_insert($node); } taxonomy_node_save($node, $node->makemodel); } /** * Implementation of hook_nodeapi(). * * When a node revision is deleted, we need to remove the corresponding record * from our table. The only way to handle revision deletion is by implementing * hook_nodeapi(). */ function node_vehicle_nodeapi(&$node, $op, $teaser, $page) { switch ($op) { case 'delete revision': // Do taxonomy terms get removed automatically? If so, nothing is required here break; } } /** * Implementation of hook_delete(). * * When a node is deleted, we need to remove all related records from out table. */ function node_vehicle_delete($node) { // No logic is required here at this moment } /** * Implementation of hook_load(). * * Need to separate the vehicle terms into separate make / model elements * so they can be used to populate existing nodes */ function node_vehicle_load($node) { $vid=1; $make_model_array = taxonomy_node_get_terms_by_vocabulary($node, $vid); foreach ($make_model_array as $key => $value) { if ( taxonomy_get_parents($value->tid) ) { $model=$key; } else { $make=$key; } } $additions = new stdClass(); $additions->make = $make; $additions->model = $model; return $additions; } /** * Implementation of hook_view(). * * This is a typical implementation that simply runs the node text through * the output filters. * * Do I need this? */ function node_vehicle_view($node, $teaser = FALSE, $page = FALSE) { $node = node_prepare($node, $teaser); return $node; } /** * Implementation of hook_theme(). * * Tell Drupal about theme functions and their arguments. */ function node_vehicle_theme() { return array( 'makemodel' => array( 'arguments' => array('element'), ), ); }
Syntax highlighting mode:
ActionScript
ColdFusion
Diff
Drupal 5
Drupal 6
HTML
INI
Javascript
MySQL
PHP
Python
robots.txt
SQL
Text
Select the syntax highlighting mode to use.
See Also:
Order
Title:
URL:
-1
0
1
Title:
URL:
-1
0
1
Any links you'd like to have associated with the post (Drupal.org issue, Wikipedia article, etc).
File attachments
Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.
Attach new file:
The maximum upload size is
1 MB
. Only files with the following extensions may be uploaded:
jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp
.
Submit Fix
Summary:
Tags:
Any tags you'd like to associate with your code, delimitered by commas (example: Views, CCK, Module, etc).
Show summary in full view
<?php // $Id: vehicle.module,v 1.26 2008/10/9 13:40:00 michaelphipps Exp $ /** * @node_vehicle * This module defines a custom node type with a custom make / model form element * that is managed via taxonomy. * * No Database required */ /** * Implementation of hook_node_info(). */ function node_vehicle_node_info() { return array( 'vehicle' => array( 'name' => t('Vehicle'), 'module' => 'node_vehicle', 'description' => t("This is an Vehicle type with a few fields."), 'has_title' => TRUE, 'title_label' => t('Example Title'), 'has_body' => TRUE, 'body_label' => t('Example Body'), ) ); } /** * Implementation of hook_menu(). * * Provide a simple menu hook to access the javascript function. */ function node_vehicle_menu() { $items['vehicle/js'] = array( 'type' => 'MENU_CALLBACK', 'page callback' => 'node_vehicle_makemodel_javascript', 'access arguments' => array('access content'), ); return $items; } /** * Implementation of hook_access(). */ function node_vehicle_access($op, $node, $account) { if ($op == 'create') { return user_access('create vehicle content', $account); } if ($op == 'update') { if (user_access('edit any vehicle content', $account) || (user_access('edit own vehicle content', $account) && ($account->uid == $node->uid))) { return TRUE; } } if ($op == 'delete') { if (user_access('delete any vehicle content', $account) || (user_access('delete own vehicle content', $account) && ($account->uid == $node->uid))) { return TRUE; } } } /** * Implementation of hook_perm(). */ function node_vehicle_perm() { return array( 'create vehicle content', 'delete own vehicle content', 'delete any vehicle content', 'edit own vehicle content', 'edit any vehicle content', ); } /** * Implementation of hook_elements(). */ function node_vehicle_elements() { $type['makemodel'] = array( '#input' => TRUE, '#process' => array('node_vehicle_makemodel_expand'), '#element_validate' => array('node_vehicle_makemodel_validate'), '#default_value' => array('make' => '', 'model' => ''), ); return $type; } /** * The process callback to expand the makemodel control. */ function node_vehicle_makemodel_expand($element) { $element['#tree'] = TRUE; if ( !isset($element['#value']) ) { $element['#value'] = array('make' => '', 'model' => ''); } // Get the list of makes from the make/models vocabulary $vid = 1;// Should the user choose their Taxonomy category? $parent = 0; $max_depth = 1; $makes = taxonomy_get_tree($vid, $parent, -1, $max_depth); foreach ($makes as $make) { $make_options[$make->tid] = $make->name; } if ( isset($element['#value']['make']) ) { $models = taxonomy_get_tree($vid, $element['#value']['make'], -1, $max_depth); foreach ($models as $model) { $model_options[$model->tid] = $model->name; } } else { $model_options = array(); } $element['make'] = array( '#type' => 'select', '#value' => $element['#value']['make'], '#options' => $make_options, '#attributes' => array('onchange' => 'changeModel();'), ); $element['model'] = array( '#type' => 'select', '#value' => $element['#value']['model'], '#options' => $model_options, ); return $element; } /** * Our element's validation function. * * Not currently being used, because I'm unsure what validation I need to do on taxonomy * data and if it is even needed at all. */ function node_vehicle_makemodel_validate($form, &$form_state) { if ( isset($form['#value']['make']) ) { if (0 == 1) { form_error($form['make'], t('Please select a make.')); } } if ( isset($form['#value']['model']) ) { if (0 == 1) { form_error($form['model'], t('Please select a model.')); } } return $form; } /** * Theme function to format the output. * * We use the container-inline class so that all three of the HTML elements * are placed next to each other, rather than on separate lines. */ function theme_makemodel($element) { return theme('form_element', $element, '<div class="container-inline">'. $element['#children'] .'</div>'); } function node_vehicle_makemodel_javascript() { // Getting the list of makes from the make/models vocabulary $vid = 1 ; // Should the user choose their Taxonomy category? $parent = 0; $max_depth = 1; $makes = taxonomy_get_tree($vid, $parent, -1, $max_depth); foreach ($makes as $make) { $make_options[$make->tid ] = $make->name; } unset($temp); $content .= "model = new Array();\n"; $result = db_query("SELECT term_data.tid AS id, term_hierarchy.parent AS parentid, term_data.name AS model FROM {term_data} join {term_hierarchy} ON (term_data.tid = term_hierarchy.tid) WHERE term_data.vid=1 AND term_hierarchy.parent >0 ORDER BY parentid, model"); while ($models = db_fetch_object($result)) { if ( $temp == $models->parentid ) { $content .= ","; } else { if ( isset($temp) ) $content .= ");\n"; $temp=$models->parentid; $content .= "model[$temp] = new Array(\n"; } $content .= "'". $models->model ."',". $models->id ."\n"; } $content .= ");\n"; $content .= '//change model function changeModel(){ var objMake = document.getElementById("edit-makemodel-make"); var objModel = document.getElementById("edit-makemodel-model"); var make_id = objMake[objMake.selectedIndex].value; //clear model select oldLength = objModel.length; for (i = oldLength; i >= 0; i--) objModel.options[i] = null; //build model select if (make_id=="") objModel.options[0] = new Option("Any model",""); else for (i = 0; i <= model[make_id].length-1; i=i+2) objModel.options[i/2] = new Option(model[make_id][i],model[make_id][i+1]); } '; header("Content-type: text/javascript"); print $content; exit(); } /** * Implementation of hook_form(). * * Describe the form for collecting vehicle information. */ function node_vehicle_form(&$node) { // The site admin can decide if this node type has a title and body, and how // the fields should be labeled. We need to load these settings so we can // build the node form correctly. $type = node_get_types('type', $node); if ($type->has_title) { $form['title'] = array( '#type' => 'textfield', '#title' => check_plain($type->title_label), '#required' => TRUE, '#default_value' => $node->title, '#weight' => -5 ); } if ($type->has_body) { $form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count); } // Add the javascript to make the make/model selection work properly drupal_add_js('vehicle/js'); // Now we define the form elements specific to our node type. $form['makemodel']= array( '#type' => 'makemodel', '#title' => t("Make/Model"), '#default_value' => array('make' => $node->make, 'model' => $node->model), '#description' => t('Select a vehicle make and model.'), ); return $form; } /** * Implementation of hook_validate(). * * Again, unsure if I need this since I am collecting taxonomy tids from select boxes. */ function node_vehicle_validate(&$node) { // include validation logic (if required) } /** * Implementation of hook_insert(). * * Saves the taxonomy details from the makemodel field. */ function node_vehicle_insert($node) { taxonomy_node_save($node, $node->makemodel); } /** * Implementation of hook_update(). * * Saves the taxonomy details from the makemodel field */ function node_vehicle_update($node) { // if this is a new node or we're adding a new revision, if ($node->revision) { node_vehicle_insert($node); } taxonomy_node_save($node, $node->makemodel); } /** * Implementation of hook_nodeapi(). * * When a node revision is deleted, we need to remove the corresponding record * from our table. The only way to handle revision deletion is by implementing * hook_nodeapi(). */ function node_vehicle_nodeapi(&$node, $op, $teaser, $page) { switch ($op) { case 'delete revision': // Do taxonomy terms get removed automatically? If so, nothing is required here break; } } /** * Implementation of hook_delete(). * * When a node is deleted, we need to remove all related records from out table. */ function node_vehicle_delete($node) { // No logic is required here at this moment } /** * Implementation of hook_load(). * * Need to separate the vehicle terms into separate make / model elements * so they can be used to populate existing nodes */ function node_vehicle_load($node) { $vid=1; $make_model_array = taxonomy_node_get_terms_by_vocabulary($node, $vid); foreach ($make_model_array as $key => $value) { if ( taxonomy_get_parents($value->tid) ) { $model=$key; } else { $make=$key; } } $additions = new stdClass(); $additions->make = $make; $additions->model = $model; return $additions; } /** * Implementation of hook_view(). * * This is a typical implementation that simply runs the node text through * the output filters. * * Do I need this? */ function node_vehicle_view($node, $teaser = FALSE, $page = FALSE) { $node = node_prepare($node, $teaser); return $node; } /** * Implementation of hook_theme(). * * Tell Drupal about theme functions and their arguments. */ function node_vehicle_theme() { return array( 'makemodel' => array( 'arguments' => array('element'), ), ); }
Syntax highlighting mode:
ActionScript
ColdFusion
Diff
Drupal 5
Drupal 6
HTML
INI
Javascript
MySQL
PHP
Python
robots.txt
SQL
Text
Select the syntax highlighting mode to use.
See Also:
Order
Title:
URL:
-1
0
1
Title:
URL:
-1
0
1
Any links you'd like to have associated with the post (Drupal.org issue, Wikipedia article, etc).
File attachments
Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.
Attach new file:
The maximum upload size is
1 MB
. Only files with the following extensions may be uploaded:
jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp
.