How to use nodeapi in drupal? - drupal

guys i have this node type -> movie. this movie has casts in it. so now i was instructed to display the number of cast in a movie. how do i achieve this by using nodeapi? please someone guide mo through this. im very new to drupal coding here. here's what ive made so far:
function count_cast_nodeapi(&$node, $op) {
switch ($op) {
case 'update index':
if ($node->type == 'movie') {
$text = '';
$q = db_query('SELECT count(field_movie_cast_nid) FROM content_field_movie_cast ' .
'WHERE nid = %d', $node->nid);
if ($r = db_fetch_object($q)) {
$text = $r->count;
}
drupal_set_message($text);
}
}
}
but i have no idea where to put this code. where to save it. do i make a module of this? and is this code even correct?
also i have only copied this code. so i dont know what that 'update index' means. and who or what function will set that parameter $op

I can suggest you follow solution:
Create new integer CCK field for content type "movie" which will store the number of casts. Name it movie_cast_number.
This field will be updating in hook_nodeapi (similar to your example). For that you need to create custom module "count_cast". Place it to sites/all/modules directory.
In hook_nodeapi need to use $op "insert" and "update". $op generating by module node and means which operation is performed with node. Insert means new node has been created and update - existing node has been updated.
If you need custom output for this content type then you need to create node-movie.tpl.php in your theme directory.
Code which update the number of casts can looks follow way:
function count_cast_nodeapi(&$node, $op) {
switch ($op) {
case 'update':
case 'insert':
if ($node->type == 'movie') {
$result = db_result(db_query('
SELECT count(field_movie_cast_nid) cnt
FROM {content_field_movie_cast}
WHERE nid = %d
', $node->nid));
$node->field_movie_cast_number[0]['value'] = $result->cnt;
}
}
}

Related

Getting Taxonomy Terms for a Node ID in Drupal 8

I'm trying to add a preprocess hook to add classes based on taxonomy name to the body css of my drupal installation. I've managed to get all the information about the node based on doing some searching around and trial and error, but I'd like to take it to the next step and get all the taxonomy terms based on the particular node id.
My current preprocess code is follows:
function custom_preprocess_html(&$variables) {
// Add the node ID and node type to the body class
$body_classes = [];
$nodeFields =\Drupal::service('current_route_match')->getParameter('node')->toArray();
if (is_array($nodeFields) && count($nodeFields) > 0) {
if (isset($nodeFields['nid'])) {
$body_classes[] = 'node-' . $nodeFields['nid'][0]['value'];
}
if (isset($nodeFields['type'])) {
$body_classes[] = $nodeFields['type'][0]['target_id'];
}
}
$variables['attributes']['class'] = $body_classes;
}
It works fine and pulls down the information regarding the node. Based on the answer here it seems like all I should have to do is add the following line to get the taxonomy terms: $taxonomyTerms = $nodefields->get('field_yourfield')->referencedEntities(); but when I do so Drupal throws an error. I'll freely admit I'm new to Drupal 8, so any suggestions about where I'm going wrong (is field_yourfield not something that exists, maybe?) would be greatly appreciated.
If you are trying to get the referenced term names and add them as body classes, your approach seems a little bit off.
This is what I use:
function CUSTOM_preprocess_html(&$variables) {
// Entity reference field name.
$field_name = 'field_tags';
// Get the node object from the visited page.
// If the page is not a node detail page, it'll return NULL.
$node = \Drupal::request()->attributes->get('node');
// Let's make sure the node has the field.
if ($node && $node->hasField($field_name)) {
$referenced_entities = $node->get($field_name)->referencedEntities();
foreach ($referenced_entities as $term) {
$variables['attributes']['class'][] = \Drupal\Component\Utility\Html::cleanCssIdentifier($term->getName());
}
}
}

is it possible to set a field in drupal to some value by using nodeapi

So I have this field named field_movie_cast_count this is a field of a content named movie so what I want is that whenever the movie is updated (like I add another cast member) the field_movie_cast_count field would be updated too. I have successfully done it using this code:
function count_cast_nodeapi(&$node, $op) {
$id = $node->nid;
if($op == 'update' && $node->type == 'movie') {
$count=count($node->field_movie_cast);
$q = db_query("update content_type_movie set field_movie_cast_count_value = '$count' WHERE nid = '$id'");
}
}
Now, my boss told me that I should not use query. So, how do I achieve this by not using a database query?
is it not possible to just set field_movie_cast_count[]['value']=$count? i tried this code it doesnt work. lol
OR SHOULD I REPHRASE THE QUESTION is there any other way of displaying the count cast? aside from my way? cause maybe i did not understand my boss right.
hook_nodeapi() has a presave operation which is invoked just before the node (and field data) is committed to the database. The definition of the operation is:
The node passed validation and is about to be saved. Modules may use this to make changes to the node before it is saved to the database.
You can use it to update a field value, without resorting to hitting the database manually (which will be overwritten anyway) like so:
function MYMODULE_nodeapi(&$node, $op) {
if ($op == 'presave' && $node->type == 'movie') {
$node->field_movie_cast_count[0]['value'] = count($node->field_movie_cast);
}
}

Drupal: automatically add new nodes to a nodequeue

Can I somehow automatically add a node to a specific nodequeue when it is created ?
(I'm using nodequeue module: drupal.org/project/nodequeue)
thanks
I needed this feature for a drupal 7 site and took the custom module solution. Let's say the setup is one nodequeue, and every 'project' nodes should be automatically added and removed to the queue. Create an empty nodequeue_auto_add directory in sites/all/modules/. This contains these two files
nodequeue_auto_add.info
name = Nodequeue auto add/remove
description = Automatically adds and remove nodes when they are created and deleted.
core = 7.x
version = 7.x-dev
package = Nodequeue
dependencies[] = nodequeue
nodequeue_auto_add.module
<?php
/**
* Implements hook_node_insert().
*/
function nodequeue_auto_add_node_insert($node) {
$nid = $node->nid;
$type = $node->type;
// only process project node
if ($type != 'project') {
return FALSE;
}
// I've only one nodequeue where a specific node type should always be
// added so this is taken from the mysql nodequeue_queue table
$queue_id = 1;
// subqueue id, exists even if we created a really basic nodequeue (from nodequeue_subqueue table)
$sqid = 1;
$queue = nodequeue_load($queue_id);
$subqueue = nodequeue_load_subqueue($sqid);
if (function_exists('views_invalidate_cache')) {
views_invalidate_cache();
}
nodequeue_subqueue_add($queue, $subqueue, $nid);
}
/**
* Implements hook_node_delete().
*/
function nodequeue_auto_add_node_delete($node) {
$nid = $node->nid;
$type = $node->type;
// only process project node
if ($type != 'project') {
return FALSE;
}
if (function_exists('views_invalidate_cache')) {
views_invalidate_cache();
}
// I've only one nodequeue where a specific node type should always be
// added so this is taken from the mysql nodequeue_queue table
$queue_id = 1;
// subqueue id, exists even if we created a really basic nodequeue (from nodequeue_subqueue table)
$sqid = 1;
nodequeue_subqueue_remove_node($sqid, $nid);
}
There is an action "Add to Nodequeue" in Rules. I've solved by creating a new rule.
There's a simple module made just for this purpose, for both Drupal 6 and Drupal 7:
http://drupal.org/project/auto_nodequeue
I'm using drupal 5 which doesn't have rules. This is how I accomplished it, I'm not using any subqueues:
if($op == 'insert'){
if($node->type == 'node_type'){
$queue = nodequeue_load(4);
$subqueue = nodequeue_load_subqueue(4);
nodequeue_subqueue_add($queue, $subqueue, $node->nid);
}
}
You cannot set it up within the admin interface, but you can do it in a custom module using hook_nodeapi op insert.
There is a module for that. Check it out and see if it helps. https://www.drupal.org/project/auto_nodequeue/project/auto_nodequeue
While this module does not exactly meet the OP "auto add" request it does allow you to configure the content type so that you can add it directly to the queue: https://www.drupal.org/sandbox/rlhawk/1444496 It is a sandbox but very stable and I use it all the time and love it.

Loading the previous revision of a node

When you get a node, how do you load the previous version (revision)?
I know how loading a revision but not how getting the previous revision number ($node->vid is the current revision).
thanks
Supposing that you have a node object $node, you can use the following code to get the previous revision.
$previous_vid = db_result(
db_query('SELECT MAX(vid) AS vid FROM {node_revisions} WHERE vid < %d AND nid = %d', $node->vid, $node->nid)
);
Once you have the previous revision, you can load the new node object with node_load(array('nid' => $node-nid, 'vid' => $previous_vid)).
The code should check if db_result() returns FALSE, in the case there isn't a previous revision.
To note that the field vid is global for each node; it doesn't contain the same value for different nodes.
Thanks all.
I found also an other solution:
$revisions = node_revision_list($node);
next($revisions);
if ($preview_key = key($revisions)) {
$preview_revision = $revisions[$preview_key];
$old_node = node_load($node->nid, $preview_revision->vid);
}
But if you have a lot of revision you get a big array.
If I understand what you're trying to do; you want to get the preview of the node after someone submits changes?
The preview button has its own submit handler, node_form_build_preview(). There, it creates a new node object using the data in $form_state and runs node_preview(), which returns the markup for the preview.
If you want to capture that preview when the user clicks the preview button, you'll need to use hook_form_alter to add another submit handler to the preview button:
$['form']['buttons']['preview']['#submit'][] = 'mymodule_custom_preview';
where mymodule_custom_preview is the name of your custom submit function. Take a look at node_form_build_preview() for guidance, but your submit function is going to look something like this:
function mymodule_custom_preview($form, &$form_state) {
$node = node_form_submit_build_node($form, $form_state);
$preview = node_preview($node);
}
Also take a look at node_form(), which gives you an idea of how the node form is structured. When you're all done, you're going to have code in your module that looks something like this:
function mymodule_form_alter(&$form, $form_state, $form_id) {
if (strstr($form_id, '_node_form') !== FALSE) {
$['form']['buttons']['preview']['#submit'][] = 'mymodule_custom_preview';
}
}
function mymodule_custom_preview($form, &$form_state) {
$node = node_form_submit_build_node($form, $form_state);
$preview = node_preview($node);
// Do what you will with $preview.
}

Custom logic for exposed filters in a Drupal view

I'm working on a Drupal site and would love some advice on this. Currently, a user enters his level for a number of different skills. This is stored in a CCK integer field and exposed to the user as a drop-down widget containing the key/value pairs 1|Beginner, 2|Intermediate, 3|Advanced.
In a view, I expose the allowed values for each skill, which are presented to the user as checkboxes (using the Better Exposed Filters module) and then listed in a sortable table. In practice, users generally search for people who have "at least knowledge level X in skill Y". Is there a module or straightforward way to display the allowed values as a drop-down and use a "greater than" operator in the query instead of a "one of"?
Any sample code or advice on how to dynamically change the filter logic or the WHERE clause of the query would be very appreciated.
You want to use hook_views_query_alter(), while I haven't specifically altered the WHERE clause, I have altered the SORTBY clause and the idea behind both should be relatively similar.
Here's a quick piece of code:
function my_module_views_query_alter(&$view, &$query) {
switch ($view->name) {
case 'view1':
$args = _my_module_get_querystring();
switch ($args['condition']) {
case 'condition1':
$query->where[0]['args'][0] = 1;
break;
case 'condition2':
$query->where[0]['args'][0] = 2;
break;
}
break;
}
}
/**
* Returns querystring as an array.
*/
function _my_module_get_querystring() {
$string = drupal_query_string_encode($_REQUEST, array_merge(array('q'), array_keys($_COOKIE)));
$args = explode('&', $string);
foreach ($args as $id => $string) {
unset($args[$id]);
$string = explode('=', $string);
$args[$string[0]] = str_replace(' ', '-', $string[1]);
}
return $args;
}
This particular piece would allow you to alter the WHERE clause using a querystring (?condition=condition1), but you could alter it to get the arguments however you wish.
Hope this helps.
Using Decipher's sample and spending a few hours reading up and playing around, I've gotten a basic module that works perfectly for my needs. Thanks again!
Here's my code if anyone else comes across a similar need:
<?php
// $Id$
/**
* #file
* Module for modifying the views query to change an EQUALS
* to a GREATER THAN for specific filters.
*/
function views_greater_than_views_query_alter(&$view, &$query) {
//only implement for views that have Search in their name
if(strstr($view->name, "search")) {
$whereclauses = $query->where[0]['clauses'];
foreach ($whereclauses as $i=>$currentrow) {
$currentrow = str_replace('= %d', '>= %d', $currentrow);
$query->where[0]['clauses'][$i] = $currentrow;
}
unset($whereclauses);
}
}

Resources