Okay lets say I have a basic demographic content type (Client) that I am saving as a node.
I need to make a key for an external database that we occasionally need to work with.
I want Drupal to take the fragments of three fields being collected in the Client content type and join them into a single field to be saved within the Client content type. Ideally this should be done when I create a new (Client) node.
The new field should contain the following
First 3 letters of firstname
First 3 letters of lastname
and last 4 digits of Social Security Number.
For example
firstname: John
lastname: Doe
SSN: 123-45-6789
A new field should be created, let’s call it fk_database. Using the example above the field >created would be -> johdoe6789
Can this be done via Rules module, or should I approach this in a different way? If I need to do this via a PHP script where exactly should that be added in the Drupal structure?
The easiest way would probably be to use the Computed Field module, it's pretty much built for exactly what you want to do:
Computed Field is a very powerful CCK field module that lets you add a custom "computed fields" to your content types. These computed fields are populated with values that you define via PHP code. You may draw on anything available to Drupal, including other fields, the current user, database tables, you name it.
If you do need to do it in code though, have a look into hook_entity_presave() which would probably be the best place to run your code from.
I personally would build a custom module to handle this and make use of the node API to handle the custom fields if you want to build them on the fly?
Modules could be created either in the modules directory on the 'root' or really they should be in sites > all > modules
You'll have to switch it on in the backend under site building > modules to enable it
You will be able to hook into the API and handle requests via the case statements e.g.
function hook_node_load($node, $types) {
//do something on node load
}
function hook_node_update($node) {
//do something on node update
}
function hook_node_insert($node) {
//do something on node insert
}
Related
I have an app using React + Redux and coupled with Firebase for the backend.
Often times, I will want to add some new attributes to existing objects.
When doing so, existing objects won't get the attribute until they're modified with the new version of the app that handles those new attributes.
For example, let's say I have a /categories/ node, in there I've got objects such as this :
{
name: "Medical"
}
Now let's say I want to add an icon field with a default of "
Is it possible to update all categories at once so that field always exists with the default value?
Or do you handle this in the client code?
Right now I'm always testing the values to see if they're here or not, but it doesn't seem like a very good way to go about it. I'd like to have one place to define defaults.
It seems like having classes for each object type would be interesting but I'm not sure how to go about this in Redux.
Do you just use the reducer to turn all categories into class instances when you fetch them for example? I'm worried this would be heavy performance wise.
Any write operation to the Firebase Database requires that you know the exact path to the node that you're writing.
There is no built-in operation to bulk update nodes with a path that is only partially known.
You can either keep your client-side code robust enough to handle the missing properties, or you can indeed run a migration script to add the new property to each relevant node. But since that script will have to know the exact path of each node to write, it will likely first have to read/query the database to determine those paths. Depending on the number of items to update, it could possibly use multi-location updates after that to update multiple nodes in one call. E.g.
firebase.database().ref("categories").update({
"idOfMedicalCategory/icon": "newIconForMedical",
"idOfCommercialCategory/icon": "newIconForCommercial"
"idOfTechCategory/icon": "newIconForTech"
})
I have a content type which has a lot of fields 50+. 30 or so are required fields. I want my user to be able so save the node before all the required fields have been filled in. The node can not be published until all the required fields have been filled in. Is there a way I can do this.
Not directly. Required fields are exactly that. You'll need to make your fields optional and handle the node save event and prevent publishing until each of the fields has been filled in. If you don't feel like all that php, Rules module can handle this kind of thing very nicely - http://drupal.org/project/rules.
Another alternative is that you might be better off with something like a webform - http://drupal.org/project/webform, though I don't know if it has any save and resume functionality out of the box so you might need to check that out first.
This module will do the job:
http://drupal.org/project/multistep
You can split your form to steps and only the fields in the current step have to be filled by the user.
The simple versoin of my question: I need a CCK Node reference field to search on two different fields in a node. What's the best way to do this?
Some Background
I run a calendar for a physical therapy program. Each lecture has a reading list. Readings are their own content type and the lecture has a autosuggest node reference field that currently only searches the reading's title. I need it also to search on an additional cck field, the readings author.
I attempted to do this a custom view, but I need a very simple title OR author search, and we're stuck with AND for a little bit longer. Is there a workaround? Do I need to create a small module to do this? If so, wheres a good place to start to learn how to do that? (I've made custom modules before but none that involve interfacing with views/cck). I'm not really sure where to go with this right now.
Thanks for the help!
There isn't really a neat way to accomplish this, because searching only in the title is a "feature" of the Node Reference module (which is part of CCK). However, you can create a custom View to provide the results for the autocomplete, and use hook_views_query_alter() to change the query that the View execute. The view you create should be selected in the configuration page of the field.
Below is a sample implementation that changes the query to search both the title and the body of nodes. You'll probably need to customize it a little bit to get exactly what you want.
function mymodule_views_query_alter(&$view, &$query) {
if ($view->name == 'my_custom_view' && $view->current_display == 'content_references_1') {
// Remove the original title constraint
unset($query->where[0]['clauses'][2]);
// Duplicate the argument (keyword to search for), so
// it is passed to both the title and the other field
$query->where[0]['args'][] = $query->where[0]['args'][1];
// Add the custom where clause
$view->query->add_where(0, "(node.title LIKE '%%%s%%' OR node_revisions.body LIKE '%%%s%%')");
}
}
I'm building a Drupal based site that requires the communication of a node ID to a seperate web service. This web service handles the uploading of files to a seperate server (from the one Drupal is on).
This creates a problem where in if I create a new node, the Node ID is not generated until the form is submitted - meaning I can't attach the files until I save the node and open it back up to edit it. I'd like to remove that step.
Is it possible to create a two step node creation process where the basics of the node are submitted and saved, and then the form re-directs to step two where I can attach the files?
I'd also consider an AJAX enabled node submission form - but that seems to add even more complexity to the situation.
Any advice, examples will be appreciated!
you could do this with a multi-step form. see http://pingv.com/blog/ben-jeavons/2009/multi-step-forms-drupal-6-using-variable-functions for the canonical way to do this (besides the code, also check the comments).
you could also do it by adding a second submit handler to the form. the first, default one (node_form_submit) saves your node (including the attached file) the standard Drupal way. the second handler could upload the file to the separate server, do upload error checking, delete the file from the Drupal DB, etc. you can add an additional submit handler to a Drupal 6 form by adding it to the form's #submit property, either in the form definition or via hook_form_alter / hook_form_FORM_ID_alter.
Depending on what exactly you want to do, you might use hook_nodeapi on its 'insert' operation. It is fired after successful node creation, so the node object will contain the newly assigned nid there already.
NOTE: The wording of the API documentation is a bit ambiguous concerning the 'insert' and 'update' operations:
"insert": The node is being created
(inserted in the database).
This sounds like it is right in the middle of the process, whereas the node has already been created at this point.
I guess the node_save function can help you.
I ran into exactly this same issue and did it the wrong way. I added the hook myself.
http://drupal.org/node/313389
I need a form which will allow creation of several related nodes at the same time. All of the nodes involve CCK fields.
I would like to use as much of CCK's built-in validation, submission, input widget, and security functionality as possible/practical.
What is the best way to accomplish this in Drupal 6? Are there 'best practices' or docs anywhere?
Here are 3 possibilities I can see. I would love feedback on whether any of these would work, or if there are even better options.
1.
start with the standard node creation form for content type foo.
modify the form by adding fields for content type bar, using hook form_alter [can cck widgets for content type bar be inserted directly?]
use a custom submit handler to create node of type bar when the form is submitted
[can the standard cck handler be called? or do i need to 'manually' construct the node object, do my own validation, and use node_save?]
2.
create a new, custom form that concatenates the 'normal' node creation forms for the relevant content types.
then use hook form_alter to modify the forms as necessary.
allow standard cck submit handlers to do the work of creating the nodes.
3.
create a custom form from scratch
create the nodes in my own submit handlers, using node prepare, node save, etc.
If found documentation on re-using the standard node creation form, but creating multiple nodes at the same time is not mentioned.
Using hook nodeapi and hook form_alter is documented in a post on advomatic's site, but the particular method descrube seems to require polluting one of the content types with 'dummy' fields.
Thank you very much for your help!
The advomatic guys posted a nice solution to this.
http://www.advomatic.com/blogs/jonathan-delaigle/multiple-nodes-single-node-submission
why not just use hook_nodeapi to handle the node creation for certain content types.
just set up a test condition to see if $node->type = 'foo', and then run a function to create two nodes or however many, using the values from the predefined fields. you can even set hook_nodeapi to only run when the $op is almost ready to insert the node into the database, thus ensuring the object has been run through appropriate validation before being passed on to the new nodes that need to be created.
http://api.drupal.org/api/function/hook_nodeapi/6 this page has a list of all available operations for the $op variable and what they do.
I hope that helps
If the 2nd type bar needs only one or two additional inputs (fields) from the user, I would go with your approach one.
But given your clarification it seems that foo and bar are sufficiently different and complex, so your approach two seems more reasonable.
Concatenate both forms into one and hide the bar fields that you want to populate from the foo fields (or node, after you created it). In the forms validate and submit functions, you'll have to separate the forms again so that you can call the standard validation/submit handlers for both separately.
I have not done this yet, so I'm not sure how well this will play with the cck functionality, but I would expect it to work reasonably well to give it a try.