Basically, I want to send out notifications of a node creation if a user is subscribed to a node that is referenced using the cck node reference. I have a couple content types called Industry and Career, which are nodes I am controlling, and I want users (who can create their own images and video) to be notified when content has been created that references careers or industries that they are subscribed to. Does that make sense? I was looking at the code, and it seems that this might be done through a hook, or through modifying the subscriptions.module around line 189 in the subscriptions_queue function. Can someone point me in the right direction here? Thanks in advance for the help.
Brett
Comments
Comment #1
salvisYes, hook_subscriptions_queue_alter() looks like a good way to do what you want. You'd check your conditions and create {subscriptions_queue} entries yourself for the users that meet your conditions.
Let us know how it goes.
Comment #2
brettev CreditAttribution: brettev commentedThanks a ton for your help. I have the logic set up, I just need to know what to add to the rows to make sure it works how I think it should.
I should set module="node", but what do I do for field and value? Do I still use the load_args and load_function as the nid and subscriptions_content_node_load like the ones in there are? Also, does is_new = 1 and last_sent = 0? I'm sure these are pretty simple questions, but for all my searching, I can't seem to find what the rows I have in my table are doing there. Shouldn't they be cleared out when the email is sent?
Brett
Comment #3
salvisfield determines which template (mailkey) you get and which mailvars_function. Try 'nid' and use the nid as value.
Yes, use load_args and load_function as given, unless you want to provide your own load_function() for some reason.
If the post is new, is_new should be 1, if it's only updated or commented, it should be 0. last_sent is copied from the user's {subscriptions_user} entry.
Yes, after cron has run and sent out the notifications, the corresponding entries in {subscriptions_queue} should be gone. All of this is done in subscriptions_cron().
Comment #4
brettev CreditAttribution: brettev commentedThis is what I have so far. The first 2 are for nodes that reference them through a single select field, and the second two are for multi selects. Thoughts? Comments? Criticisms?
Comment #5
salvisYou must check that your $event really contains a node. Then use its nid, not load_args as value, and also pass on the load_function that you get, rather than hard-coding it. Finally, as I said before, last_sent should be taken from {subscriptions_user}.
Does it work?
Comment #6
brettev CreditAttribution: brettev commentedThanks for the hints. I think I fixed them. Does this look a little better? I haven't turned the module on yet, I'm kind of waiting to pass it back and forth with some people first. I'm hoping to turn it on today though.
Comment #7
salvisI don't see any obvious problems, but that doesn't mean much. I would single-step through this kind of code in a debugger to make sure that it does what I intend, and following the flow of control and inspecting variable values often reveals bugs.
Comment #8
brettev CreditAttribution: brettev commentedhere's the working version. tested and awesome!! I had 4 fields I wanted to check against, so those are the 4 top parts.
Comment #9
salvisDid you miss the closing tag? Please try to edit #8 and make it readable...
Comment #10
brettev CreditAttribution: brettev commentedfixed
Comment #11
salvisNice work, congratulations!
Now that I think about it again, it would probably be better to call subscriptions_queue() rather than inserting directly into {subscriptions_queue}. This would give others a chance to hook_subscriptions_queue_alter (you'd get the call, too, and have to be prepared for it, of course) and insulate you a somewhat against changes in the database schema.
Comment #12
gregglesThis is _exactly_ what I need.
@brettev, are you interested in maintaining this as a module on drupal.org? If not, I would like to do so.
Comment #13
brettev CreditAttribution: brettev commentedI would maintain it, but it would have to be made generic and setup with an admin interface. I'm not sure if it would make it to drupal.org as is right now. Would you be interested in making it more generic with an admin page?
Comment #14
greggles@brettev - yes, now that I've played with it more I realize that it needs a bit more work in order to be generalized.
I'm not really sure how to make it more generic right now. I've built similar modules and think it is possible, but I'd need to dig into the CCK API again.
Comment #15
aschiwi CreditAttribution: aschiwi commentedHi brettev,
I'm hoping to have some questions answered on your code. I am no coder but I think I could take the code you posted to modify and use it for me.
Here is my scenario: People would subscribe to a node of type "one". I want them to be notified when a node of type "two" has been created that references the node they are subscribed to. I think that is what your code does, but I don't know your setup. Could you generalize and comment the top part of your code (in function sub_by_cckref_subscriptions_queue_alter) a little bit, so that I can try and use it for myself?
Comment #16
brettev CreditAttribution: brettev commentedNo problem. Happy to help. I've pulled out the 4 checks I had, and just left one of them to simplify things. It should make it easier for you to swap out.
You should leave the bottom function as is, and just modify the $node->field_main_industry[0][nid] to say $node->field_yourfieldname[0][nid].
this only works if it is a single node ref (drop down, not multiselect). The multi select you could pull off my code above.
Does this make sense?
Comment #17
aschiwi CreditAttribution: aschiwi commentedFirst of all, thank you for your quick help! Second, I didn't get it to work yet, I tried a few thinks but it's not happening. Could you take a look at my code? I changed the name of the module in the function, because I had already named it something else. I changed the name of my field (it happens to be multiselect because I need to prepopulate and hide the field for users) and figured I could leave
$industries
. In line 3 it now says$node = $event['two'];
, which is probably wrong because you didn't tell me to change that to the name of my content type. BUT, writing 'node' instead of 'two' doesn't do it either. I'm sure though that somewhere I would have to put both "one" and "two", so that the module knows which content types I'm referring to?Comment #18
brettev CreditAttribution: brettev commentedI'm guessing this should work. You are using a multi select for the field, right?
Comment #19
aschiwi CreditAttribution: aschiwi commentedYes I am using a multiselect field. Not required, because it gets filled in anyways (by prepopulate, not by user). I tried your above code, but still not working yet. Checked my field again, because I am prepopulating the field with (for example)
[nid:70]
instead of the actual title of the node. I thought that might be it. But then I tried with writing the words in and it was the same. I guess I have to tackle this again tomorrow, probably missing something small...Comment #20
brettev CreditAttribution: brettev commentedThe code is set to work with node reference type fields. It won't work with a text field where you are putting the node id in.
Comment #21
aschiwi CreditAttribution: aschiwi commentedBut it IS a node reference field... I am using the autocomplete kind. To get a node referenced, you can either type in the title of the node or type in [nid:40], "40" standing for whatever the nid is. For some reason I can't remember now, I couldn't get the title information into the nodereference field by using prepopulate. But either way, I tried the code by typing in the actual title of the referenced node and it didn't work. I have to try again today, will let you know what works out for me in the end :-)
Comment #22
aschiwi CreditAttribution: aschiwi commentedSo with some help of a friend I finally managed to do this. It was my mistake, on line 1 I didn't see that it had to be modulename_SUBSCRIPTIONS_queue_alter...
And by the way, it works wether the nodereference field has the title of the referenced node in it OR the nid (in the [nid:1] pattern). We use prepopulate to put the nid in the nodereference field because sometimes the title of a node might be too long for it, and then it wont get referenced right.
Thanks again for your help.
Comment #23
Flying Drupalist CreditAttribution: Flying Drupalist commentedHi, is this going to become a module?
Comment #24
brettev CreditAttribution: brettev commentedhttp://www.brettevanson.com/module/subscriptions-cck-node-reference
I haven't tested it as it is, but it should work. Let me know if it works for you.
Comment #25
salvisI don't understand it well enough to tell whether it's sufficiently general to become a subscriptions/contrib, nor whether brettev wants to contribute it and continue to support it, but I'm certainly open to contributions.
Comment #26
brettev CreditAttribution: brettev commentedI need a few people to use it and post feedback about whether it works for their needs or not. If enough people use it and have a good experience with it, then we can push for include into the subscriptions contrib section.
Brett
Comment #27
Flying Drupalist CreditAttribution: Flying Drupalist commentedOh, I'm on 6.6. Can't use this yet. :(
Comment #28
brettev CreditAttribution: brettev commentedI updated the module with a new table name. As far as why it's not showing up in your list, I am not sure. That's a troubleshooting issue, not an issue with this module specifically. Could you have the files in the wrong directory?
Comment #29
Flying Drupalist CreditAttribution: Flying Drupalist commentedHi, you must be seeing an old version of my post. I updated it yesterday. I'm on 6.6, and originally I was confused because I couldn't find a checkbox under the subscription category in the module listing, where I assumed it would be. Then I realized that this was a 5.x issue and I couldn't use the module in any case. A 6.x port would be appreciated, sorry for the trouble.
Comment #30
aschiwi CreditAttribution: aschiwi commentedI didn't try your module but I am using the code you provided here in a custom module. What I just realized is missing from that code is that there are no notifications sent out when the node is updated, which is something I need and added to my code. I looked at the code of your module and I think you don't have 'update' in there either (though I am by no means a coder, maybe I just didn't see).
In line 52 of your module it says
The same line is in the code I got from you before and I added the update part so now it looks like this:
Comment #31
parrottvision CreditAttribution: parrottvision commentedsubscribing - would love to see this in 6 as a part of module.
Comment #32
MJH CreditAttribution: MJH commentedThis is exactly the functionality I am looking for.
Will this be included in the Drupal 6 version of Subscriptions or will there be an external module?
Is there another "Subscription / Notification" module already working under Drupal 6, that can inform a user subscribed to a node if that node is referenced in another node?
Comment #33
gunzip CreditAttribution: gunzip commentedsubscribe ;)
Comment #34
gunzip CreditAttribution: gunzip commentedwell maybe there's a simple way with nodeapi intercepting the insert of a node with a reference field:
i think this could be merged into the subscriptions_cck nodeapi
(you have to loop through all the nids if you have a multi value field...)
Comment #35
lelizondo CreditAttribution: lelizondo commentedsubscribe
Comment #36
caponey CreditAttribution: caponey commentedi just found this, but do you use this code in template.php, or do you use it in the subscription module, or your own created module?
Comment #37
gregglesIn my opinion, this issue should be marked "fixed" since it kind of is.
There is not really a way to do this generically and I don't think it's a good long term solution. The Notifications/Messaging frameworks are better supported than Subscriptions at this point and any future solutions should be based on that (in my humble opinion...).
Comment #38
salvisIndeed I don't see any generic solution either. If anyone has one, I'll certainly be interested.
I'm leaving this issue open as a kind of forum for Subscriptions users to exchange their ideas. If we closed it, someone would probably open a new issue.
Well, it took 5 hours to implement #817342: Change weight of the Subscribe fieldset in CCK 'manage fields' page for Subscriptions, after #606454: Change weight of the notifications fieldset in CCK 'manage fields' page had been languishing for over 7 months in the Notifications queue. David Goode then copied my diff, without acknowledgment, and Jose Reyero committed it under David's name: http://drupal.org/cvs?commit=375656 (diff).
I don't have the time or interest to follow the Notifications project. They may have more critical mass, but from what I see of them, these people operate in a way that is not compatible with ours. That's how it was when Jose branched Notifications from Subscriptions, and apparently it's still the same today.
(When comparing the quality of support you should also take into account the 55 open bug reports for Notifications plus 20 for Messaging vs. 0 for Subscriptions.)
Comment #39
keremito CreditAttribution: keremito commentedHi there,
I would like to do something to update brettev's script for D6. I've downloaded the script from brettev's site (#24), and go through http://drupal.org/node/114774 to convert it to a 6.x module. It's not working now. Install script should use schema api, coder module says. When a referencing node is created system gives error. Before spending more time on,
any ideas? am I totally on a wrong way?
Comment #40
brettev CreditAttribution: brettev commentedpost your code and i'll take a peek at it, or send it to me directly
Comment #41
keremito CreditAttribution: keremito commentedHi brettev,
Thank you very much for your support. install file didnt change, and here is the new module file with minor changes after deadwood.
Comment #42
brettev CreditAttribution: brettev commentedWell, I made a couple modifications. I'm not 100% sure the subscriptions module hasn't changed its database layout, but there were a couple things in the menu system and the form stuff that I fixed. Anyone else a little more familiar with the subscriptions module could talk to the hook_subscriptions_queue_alter, and the adding the mail to the queue table?
Comment #43
salvisYes, the hook_subscriptions_queue_alter() should still work in the same way. If you don't NULL the $event, Subscriptions will queue it — don't know whether that's what you want or not.
As for INSERTing into the {subscriptions_queue} table, it would be better to call subscriptions_queue() instead, with an $event of the form as you receive it in hook_subscriptions_queue_alter(). Use devel.module's dpm() to see what it looks like.
Comment #44
keremito CreditAttribution: keremito commentedWhen I create a referencing node, drupal gives this error;
user warning: Unknown column 'last_sent' in 'field list' query
for this line in sub_by_cckref.module on line 80;
$lastsent = db_result(db_query("SELECT last_sent FROM {subscriptions_user} WHERE uid=%d",
I can hardly understand php and mysql, but when I check the database for
subscriptions, there were a table called subscriptions_last_sent. So should I change that line to;
$lastsent = db_result(db_query("SELECT last_sent FROM {subscriptions_last_sent} WHERE uid=%d",
Comment #45
brettev CreditAttribution: brettev commentedif that table has a last_sent field as well as a uid field, then that query would most likely work. as i haven't been working with subscriptions for quite a while, i'm not 100% sure, but that does seem like it would work
Comment #46
keremito CreditAttribution: keremito commentedBrettev, Salvis,
Thank you very much!
Module is working perfectly now.
I changed the table name as {subscriptions_last_sent}. I also delete the closing tag ("?>").
Besides some "leave a space" kind suggestions, Code review points to line 26 and 55;
"use quotes around a string literal array index, this is not only a style issue, but a known performance problem"
is it something important? and @salvis, I'll think about your suggestion.
The final script is below;
Comment #47
salvis(Leaving out the closing tag messes up the formatting of your post — it's needed here on d.o, but it shouldn't go on your webserver. Please edit your #46 above and add the closing tag.)
Whatever is inside the square brackets, it should be either a number or start with a $ or with a quote. When it starts with a letter, then it's wrong, except if it's a function call, i.e. a word followed by an opening parenthesis (rare).
Having the code in the form of a patch would avoid all formatting problems and make it much easier to comment (using Dreditor).
Comment #48
keremito CreditAttribution: keremito commentedSorry, I added the closing tag back.
Comment #49
Ftegg CreditAttribution: Ftegg commentedHi
I'm having trouble making this work in D6. Basically, I've downloaded the original module from Brettev's site and updated the code in the .module file to that last script from Keremito (#46). When I go to my site's admin/modules page, I have the message "This version is incompatible with the 6.19 version of Drupal core.". Is there something else that needs to be changed somewhere?
Comment #50
vince.rowe CreditAttribution: vince.rowe commentedHi there,
You need to edit the modules .info file and add the following lines:
package = "Subscriptions"
dependencies[] = subscriptions
core = 6.x
Comment #51
Ftegg CreditAttribution: Ftegg commentedThanks, Vince!
Comment #52
bulat CreditAttribution: bulat commentedI think there is a way to make a generic solution for reference modules.
Not sure if that is applicable for the 6.x but in 7.x there we have function
field_info_field_map()
that can get us to the list of reference fields (node or entity references have slight variation which I think can be handled in one module). Once that list is there it is easy to check whether module has one of the reference fields and if it does check for subscription in subscriptions table that would match the new node.In terms of db structure there should be two types of records in subscriptions table for this module to allow two scenarios:
1. Subscribe everybody to Referenced nodes (via specified reference field).
2. Allow users to subscribe to Referenced node (via specified reference field).
Comment #53
bulat CreditAttribution: bulat commentedMe and @Barinder started a generic reference module for 7.x. It requires minimum code from modules that would need to extend referenced subscriptions for their content types.
Here is the the sample hook implementation that makes it possible to subscribe to new answers for a specific question (see Answers module):
Tried to make it as simple as possible.
So the code fore the
subscriptions_reference
module goes like this:Here is API with just one hook:
Integration with Rules as a bonus:
This info file should do:
Hopefully somebody will create a separate module from this.
Comment #54
bulat CreditAttribution: bulat commentedI have created a Sandbox project for this, see project application for details - http://drupal.org/node/1990672.
Comment #55
bulat CreditAttribution: bulat commentedProject was promoted to full project - https://drupal.org/project/subscriptions_reference
Comment #56
salvisGreat news!
I'd love to get some feedback from people using Subscriptions Reference and I'll be happy to add a link on the front page.
Comment #57
mfieraru CreditAttribution: mfieraru commentedI am trying to use the https://drupal.org/project/subscriptions_reference, I am using the test for now, I first add a Parent node but when I am adding a Child node referencing the Parent node, I am getting this error:
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM WHERE (module = 'node') AND (field = 'field_test_parent') AND (value = ' at line 1: SELECT FROM {} WHERE (module = :db_condition_placeholder_0) AND (field = :db_condition_placeholder_1) AND (value = :db_condition_placeholder_2) ; Array ( [:db_condition_placeholder_0] => node [:db_condition_placeholder_1] => field_test_parent [:db_condition_placeholder_2] => 16 ) in subscriptions_get() (line 677 of ****/sites/all/modules/subscriptions/subscriptions.module).
Can you please help me? There's nothing related to this new module online and it would do exactly what I need it to do.
Comment #58
bulat CreditAttribution: bulat commentedHi @mfieraru, can you please check if patch from comment #2 in #2035667: Error when creating a child node to a parent which is subscribed to solves it.
Comment #59
mfieraru CreditAttribution: mfieraru commentedIt worked. The patch solved my problem. Thank you a lot,
Comment #60
salvis