By collegegirl on
Hey guys I'm relatively new to drupal and have a quick question. Does anyone know how to deny duplicate node titles? I am making a website to review different kinds of food and I don't want users to double post the same food. I am using cck for my "food" node. When the user goes to add a new food I want an error to pop up and deny them submission if the food name already exists. Any modules for this? I'm a noob so I need pretty clear instructions...thanks guys!
Comments
don't deny a user, redirect them.
If the food already exists, redirect them to the page. Popup denials makes the user feel like they've done something wrong.
how do i do that?
how do i make it so the system recognizes the dupe? right now if the food apple exists, you can enter in the food apple again. then there will be two foods with the same name...i just don't want dupes.
One way to handle the duplicate title
You could write a small module that implement the nodeapi hook and have it handle the validate case. The code for would look something like (I have called the module noduptitles).
Under the modules directory create a directory called noduptitles, in noduptitles create a file called noduptitles.module and place the code above in the module. You will need to change the type you want to restrict duplicate titles on. Enable the module and you should be good to go (tested under 4.7.3)
thank you so much...going to
thank you so much...worked perfectly. didn't work first time b/c i defined my type as "food" instead of "content_food" i'm guessing that has something to do with cck. anyways, thanks a lot, and you should post this module somewhere. i spent hours trying to find it.
Found this in a search,
Found this in a search, looked like exactly what I wanted, but It didn't seem to be working for me.
Realized after the fact that it's a 4.7 fix, and I'm running 5.x, duh.
What would need to be done differently to run it under 5.x?
What do you mean by it does not work in Drupal 5.0
Other than the need to add a .info file it should work as is. What sort of problem are you having?
Thanks for being willing to
Thanks for being willing to help me with this.
Sorry it took so long to respond, I haven't been feeling well.
The problem is that I attempted to follow your instructions, and yet the uploaded "module" does not appear in my modules list to be activated.
Is that because it needs an .info file?
What would an .info file look like?
Minimal .info file
Place the following in noduptitles.info
Excellent validation
Excellent validation code.
----
Darly
This module is great!
This module is great! Thanks.
Does anyone know how I can get rid of this?
See %link.', array('%type' => $type, '%title' => $node->title, '%link' => $link)));
I really don't need a link to the existing node, and the error response link does not work.
I think i missed something
I created the .module and the .info for 5.x, loaded them up and activated the module.
... but nothing happens when i create a duplicate node of the type i want to restrict.
Do i have to put the 'validate' anywhere?
Are you sure you have the correct type?
After this line
add
which will list the node type for each node viewed to make sure you have $type set correctly.
Added the code,
... all i see is "Type is" and nothing more. It doesn´t matter what type of node i´m viewing.
Well that would explain why you are having problems :)
Can you either post the version of the code you are using (or email using my contact form). There is nothing in the original code that would explain $node->type being empty.
The code:
Ok, just to double check
You have the code above in a file called noduptitles.module in a directory called noduptitles, have added a file noduptitles.info and enabled the module? Is that correct?
You are creating nodes from the user interface, 'Create Content' -> 'Story'?
I ask because the code works fine for me, after
if ( $op == 'validate' ) {try addingso we can see what the node looks like (it is odd that title is not set).
All checked:
Yes, yes, yes, yes. Correct!
Yes.
Code added, nothing more to see than before.
When you say nothing more
do you mean nothing prints after the word 'NODE'? That would imply that nodeapi is being called either incorrectly or from somewhere other than the node module. It gets called through node_invoke_nodeapi() which the only call I can find for the validate case is in node_validate() (calls at end of function). You could add a
drupal_set_message("Validate: <pre>" . print_r($node, TRUE) . '</pre>');to see what $node looks like at that point.can we make this a module?
can we make this a module?
switch syntax for multiple content types?
hey guys, I want to start-off by saying how happy I am that this code is here. I am working on a project where I want to allow all of my users to post particular content types, but really cannot have any dupes in the database. I think this bit of code will go a long way in getting that capability. Thank you AndreasST for posting the original code. I'm commenting because I am hoping you guys can check the switch-case I added into the original function to have it check multiple types of nodes. If it is good, I also hope that others will be able to use it. So here's the modified function:
Also, is there a way to check on multiple fields and not just the title?
Thanks in advance for any help here.
Code probably does not work
You have a switch on $type which is not set. I think you want your code structured like this
All the types can use the same code so there is no need to replicate that, we just make sure we use $node->type where the original code used $type.
As for using other fields it is possible but that will generally mean content type specific table and tests.
thank you nevets
Thank you for your help nevets. I'm quite new to PHP and I still am struggling along. I've seen your snippets in several threads I've been using to get my site the way I would like it. You are an awesome person. Thank you so much for helping all of us noobs out.
One problem.. simple.. HELP!
Great module!! I have been wanting this and it works except for one simple thing that I am sure anyone with marginal php/drupal experience can solve.. I am using the original code. When I do try to enter a dupe the error message given to user looks like this...
There is already a bar called Test, see <a href="/biz/node/4">existing <em>bar</em></a>.It appears that the link just isnt working.. I'm using Drupal 5.
Any help greatly appreciated.
can this be tweaked?
can this be tweaked to do a slightly different validation?
I have similar issues. However, my site allows users to post links to other sites. I want to check for duplicates by checking one of the fields in the node being submitted against the content in the db fields.
so, instead of checking the node titles, i am checking a DB field. can i use this same code? where do i make the substitutions?
thanks!
j
You could use it as a starting point
You would need to change
So it uses the table with the link data (instead of the node table), return the nid and link field from the table (instead of n.title and n.nid). Then it would need to change the WHERE clause to compare using the link field. If you want to restrict the type as in the example, instead of changing the table you would need to do a join with your other table. Lastly in db_query you would need to change $node->title to the link field (and possibly drop $type if you drop it from there WHERE clause
Using link as the field name and my_table as the table name with the link field, keeping the type check it would look something like
I can't get the above code to work
I'm trying to get the above code to work, but I could use a little help.
I used CCK and the link field-type module to create a custom URL field for my Drupal forum submissions. I don't want people submitting duplicate URLs in this field. The URL is stored as the field "field_map_link_url" in the table "content_type_forum" of the MySQL database.
I've tried modifying the above code, but I can't get it to work. No matter what I enter in the URL field I get an error saying it's a duplicate. I think I'm screwing up the database query. This is my first time trying to write a custom module. I'd really appreciate if someone could show me how to get the code right. Thanks.
You should be able to change the sql and instances of title
You should be able to change the sql and instances of 'title' to 'field_map_link_url'. For the sql change
to
(This assumes field_map_link_url is a string)
Then change instances of 'title' to 'field_map_link_url' and you should be good to go.
Thanks, but...
I'm still getting the error message no matter what I enter as a url. Also, the error message is blank where the URL variable is supposed to be. Do I need to change anything else because field_map_link_url is under the content_type_forum table instead of the node table? In phpmyadmin the field_map_link_url has a type of varchar(255).
Here's my code:
Some questions and something to try
The fact the field is blank is why the test alway fails, the query matches nothing and the result is to compare two empty strings.
Is the 'field_map_link_url' required or optional, if optional you will want to change
if ( $node->type == $type ) {toif ( $node->type == $type && trim($node->field_map_link_url) ) {so the check only runs if the url is provided.The other thing to do is check that the field name is correct and showing up as part of $node, right before
$sql = ...add the linewhich will show all of the fields for the node in the message area.
Different now
The URL field is required for new submissions, but there are older ones that don't have it.
I added the two segments of code above and now it's not giving me an error, but it's not detecting duplicates either. I'm not seeing anything from the drupal_set_message?
I got the name of the field and the table it's in from phpMyAdmin. BTW- only new forum topics with this URL field end up with their nid in the "content_type_forum" table. The "field_map_link_url" field is in that table and not the "node" table. Thanks for all the help.
Try moving the call to drupal_set_message
Try moving the call to drupal_set_message so it is before the 'if' test on the content type. You might also change the call to something like
to insure something will print as long as drupal_set_message() is called.
This is what I got
I entered Google as the URL and got a bunch of info including:
Apparently, it's an array. Do I need to be referencing the field differently?
Yes, you need to reference the field differently
From you description so far it sounds like there is only one instance of the field so you can reference it as
$node->field_map_link[0]['url'].Thanks so much!
I finally got it working perfectly. I appreciate the help.
Do you mind posting your
Do you mind posting your finished code for your custom cck field?
I've been messing about with this and can't seem to get it to work, if I could see your finished version, it'll very likely help me a lot, thanks.
This is my code - I've got a
This is my code - I've got a custom Integer field called 'field_prefixation_value' within my content type's database table.
With this, I get the error message about existent values returned no matter what, even if the value does not exist. Following the above, I really am baffled as to why I can't get this to work. Help is appreciated.
value-substitute in $sql looks wrong
Hey bsuttis, I know this is old but I'm mostly new here, and it looks like you question is still unanswered, so I'll offer a tip.
In your
$sql =line you havefield_prefixation_value = '%s'. Since you mentioned that field_prefixation is an integer, you should change the '%s' (for a string) to %d (for a decimal).I'm too new at this to tell if anything else is off, but I did notice that.
Hope it helps...
Can't get it to work with Automatic Nodetitles
I'm trying to use the original code above with a content type 'product'. The content type has its title generated automatically using a combination of the token and auto nodetitles modules from a taxonomy field and a CCK field. I've added the line of code to see all the node data after creation and can see that the title is being generated correctly. I've also tried using the module weight module to make sure that this fires after both token and autonodetitles.
I also tried it with another content type that doesn't use autonodetitles and it works fine(except for the link output is weird-I'll worry about that later).
Can anyone offer any suggestions? Thank you so much. This is just what I need and seems to be soooooo close to working.
Checking title and a field.
OK guys,
I think I have the code written now so that the function will check both the title and a specified field for a given content_type. I added the field check to the title check because it seems to me that you could still get dupes if the titles did not EXACTLY match. In other words, a new node titled "The Cars" would not be equal to "the cars" or "teh cars". By checking on a required field in addition to the title, I'm hoping to catch typos, and punctuation differences as well. Please correct me if I'm wrong with the above assumption.
In my version, I need to check 3 different content_types, so with the help of nevets, I set up a switch to check each of the 3 types.
The first and second cases in the switch are equivalent except for the name of the URL field that they are checking.
The third case in the switch is different, because in that case, I need to check that the title AND the field BOTH do not match an existing node. In other words, the title can match an existing node as long as the field does not also match, and vice-versa.
So here's the code:
A word of caution to you: I am very new to PHP and drupal, so I can't say that the logic or code or syntax is perfect. It's probably very "cludgey". I have the greatest doubts about the third case... But hopefully we can work together to make it rock!
Thanks.
edit:
I also changed the link data, so the link shouldn't display weird anymore. Take a look and see if it will work for you.
/edit
A comment on your sql and the last case
I suspect this code does not even work,
field_show_url[0]['url']is PHP syntax for a field and will not work as part of an SQL statement. I am guessing you should be using justfield_show_url.For the case where you want to see if to things are both true, you probably want one sql statement, something like this
I will let you adjust the message part as needed.
thanks again nevets
Thanks nevets. I noticed that also. i am testing the module now on my drupal install. Right now it's not working. So I am going to remove the code I posted above until I get this sorted out.
Ah, i see I can't edit the above post now that there are replies to it.
OK, so anyone reading this thread, ignore the code I posted above. I'll post the final version once I have this all sorted out.
thanks again nevets. You've been a big help.
revised SELECT query
Thanks to nevets' help. I now see how the $sql query can be used to get everything needed in one shot. I'm cleaning-up the cases I made before, and will try it a couple times on my drupal install. If all goes as planned, I'll post the revised module here with how it works.
Fixed error message and link for dupe titles
Hey guys,
I'm still working on a more robust version of this function to check more than just titles, but for now I wanted to let you know that I have fixed the error message and link for when a dupe title is found.
Here is the code:
The result of this is a single line that reads:
"There is already a [your content type] called [content type's title]. Here is a link to view the existing [your content type]."
Where [your content type] is the name of your content type, and [content type's title] is the node's title.
I have tested this feature out, and the link html and the link value are correct now.
Hope that helps...
slight correction to above
If you want to drop the if() I wrote right into the function that nevets wrote above, then replace all of the
$node->typewith$type... ah heck, I'll just give you the whole thing ;)Hope that helps.
CCK node types and validation
I have figured out why my extra features have not been working. I don't know how much people who read this know about CCK types but I thought I'd share what I found so if someone is trying something similar to what I've been trying, they might find this helpful.
When you are calling $node->type you can use the "machine-readable" type for any node type. This includes CCK type nodes. You can find the machine-readable type for CCK nodes by looking at your content types in the admin section.
For an example: a CCK content type with the name "Foo Bar" might have a machine-readable type of "foobar"
That's all very straightforward. So what's the big deal?
Well, If you need to do a SQL query that checks a CCK node type, you can't just use the machine-readable name. You see, CCK types are stored in the database as content_type_*. So if we use our above example, we would have the following:
CCK Name = Foo Bar, machine-readable type = foobar, and db table = content_type_foobar
So when writing a function to query the db based on a particular CCK type, you would have something like this:
The same holds true for CCK Multiple Value fields, where as example:
CCK Label = First Name, machine-readable name = field_first_name, and db table = content_field_first_name
This was really screwing me up before, so I wanted to post this to help others who might also be having trouble.
title and field check... almost there
Hey guys,
I am so close to having the enhanced version of dupe check working I can smell it. There is just one last issue which I can't see how to fix in the code. I'm hoping someone can give me a pointer.
So here is what's happening:
1) When a new node is created, and the title and URL match an existing node, an error displays with both fields being in error.
That is what I want.
2) But, when the title is changed to be unique, but the URL is still the same as an existing node, the node passes and is created. Basically, the URL is not triggering an error by itself, but it does trigger correctly when the title also triggers.
Which is not what I want.
Here's the part of the code in question:
You see, the title and URL are being checked independently, but the URL is only caught if the title is also.
Any help here would be really appreciated. Thanks.
follow-up to above
would writing the two if() conditions inside the parent if() condition as "if ... endif;" rather than "if {...}" help anything?
The issue is here
This part of the sql is where the issue is
Since it only finds a node where the title AND the url are the same. One way to deal with that is to change the AND to an OR but that also requires adding a loop (since one node might have the same title, another the same URL)
So which rule to you want to code
Title not the same AND url not the same
Title not the same OR url not the same
(In this case no two items may have the same title
or no two items may have the same URL
So if there existed one item with title = 'blue' and url = 'http://red,org'
and another with title = 'red' and url = 'http://blue,org'
Some one could not add title = 'blue' and url = 'http://blue,org'
and they could not add title = 'blue' and url = any value
or add title = 'red' and URL = any value
or add title = any title and url = 'http://blue,org'
or add title = any title and url = 'http://red,org'
and the light shines through
thank you once again nevets. I see exactly how that's happening now.
For this specific node type, the title OR field_provider condition is what I want.
So if title = example and url = example.com, then no other node of the same type can have either title = example or url = example.com.
Now that I know, I can make the adjustments to the rest of the function and test. Then I'll post the code so other's can use it.
We have a working prototype
Hey gang.
I have a version of the function working which is checking title, field, and/or a combination of title and field. Because i still have some things I'd like to see done with this, and because i feel bad cluttering-up this thread, I have started a new topic over in the module-development forum. You can see the code I have and post replies here: http://drupal.org/node/182860
Thanks to nevets for all of the help.
I hope my work can be used by others here.
Hi, Could this code also be
Hi,
Could this code also be used to implement the validation of a url with links_weblink.module?
I had code for this, but this doesn't work anymore after implementing location.module. I don't know why. See the code here:
Could somebody help with this. Can this be implemented in the 'module'?
Thanks a lot in advance for your remarks in advance!
greetings,
Martijn
unique_field module
I've released a module called unique_field, which provides an interface for requiring that node titles or CCK fields have unique values. It is available from:
http://drupal.org/project/unique_field
I'd appreciate any comments or suggestions.
Why don't have the same
Why don't have the same option for "body" field ?
I use nodecomments module, comment are nodes, nodes boddy are the comments and the titre is always the same, so I will need to prevent posting the same comment (the same node boddy) twice.
Subscribing...
Subscribing...
How create this in Drupal 6 ?
Hi, I'm a newbie and i'm using drupal 6. I have a "wiki" content type and I just confused how to prevent duplicate title in drupal 6. Anyone can help me ? pls..
See the post just above for
See the post just above for unique field.