I'm working on a site where I need to count the number of times a user flags a book/mag for borrowing. The book/mag details are implemented using CCK and I'm using the flag module for the users to flag the books they require. I'll need to restrict the number of books a person can borrow at a time to two. So based on the post at http://drupal.org/node/955724 I created a module which contains the code below. But it doesn't seem to be doing anything. Tried figuring out what could be wrong but haven't had the luck. Would appreciate if someone could tell me what's wrong with this code snippet.
----------------------------------------------------------------------------------------------
<?php
// $Id$
// Because of the presence of the .info file this hook is optional but is provided nevertheless
function lw_help($path, $arg) {
$output = ''; //declare your output variable
switch ($path) {
case "admin/help#lw":
$output = '
'. t("Allows subscribers to borrow only one book at a time") .'
';
break;
}
return $output;
} // function lw_help
function lw_perm() {
return array('access library');
} // function lw_perm
function lw_flag($action, $flag, $content_id, $account) {
if ($action == 'flag' && !$flag->global) {
//currently checks for all flags instead of only borrows
$count = _count_borrow_flags($flag->name, $account->uid);
$flag->flag_message = format_plural($count, "You've marked 1 book for borrowing", "You're borrowing @count book. You are allowed to borrow only one at a time");
}
} // function lw_flag
function _count_borrow_flags($flag_name, $uid = NULL, $interval = 24) {
static $cache = array();
global $user;
if (!isset($uid)) {
$uid = $user->uid;
}
if (($flag = flag_get_flag($flag_name))) {
if ($flag->global) {
$uid = 0;
}
if (!isset($cache[$flag_name][$uid][$interval])) {
$cache[$flag_name][$uid][$interval] = db_result(db_query('SELECT COUNT(*) FROM {flag_content} WHERE fid = %d AND uid = %d AND timestamp > %d', $flag->fid, $uid, time() - 60*60 * $interval));
}
return $cache[$flag_name][$uid][$interval];
}
} //function _count_borrow_flags
----------------------------------------------------------------------------------------------
Best regards
Sridhar
Comments
Comment #1
mooffie commented[I've deleted my comment: I'll return when I have more time and expand it.]
Comment #2
mooffie commented(1) You're using Flag 1.x. The hooks described in the document you linked to exist in Flag 2.x only. So they won't work for you.
(2) HOWEVER, you're going to be disappointed even after upgrading to Flag 2.x, because, as that document points out, using those hooks you can't show an error message to the user. Your users won't like it. It's one thing #952114: Have hook_flag_validate() will solve.
(3) An alternative solution: Implement hook_flag() and when you see that an item has been flagged, unflag it if more than 2 items (in your case) are already flagged. It ought to work in Flag 1.x as well. Here's code to get you started (use it as a starting point: I may have typos):
(The document you used contains a complicated code to count the items but that's only because it counts over a span of time. In your case, since you want the total count, one method call is all that's needed.)
(One disadvantage of this snippet is that if some actions are triggered in the 'flag' event (e.g., unpublishing a node), they'll have to be undone. hook_flag_validate() won't have this problem.)
Comment #3
mooffie commentedI added these clarifications to the document(s) you linked to.
Comment #4
sridharpandu commented@moffie Thanks a lot, your code works for restricting the number of borrows. Thanks once again for simplifying the approach.
However I noticed the following. When I try to flag the third book the error message is displayed as expected and the flag is not set. Behaviour is as expected.
Then I go to a previously flagged book and try to unflag it I get the following message
An HTTP error 200 occurred.
http://127.0.0.1/drupal6/?q=flag/unflag/borrow/4&destination=node%2F4&to...
Any attempt to flag a third book throws the same error after the above code is executed. I am not sure why. Will investigate and post my findings. Maybe you want to check at your end as well. I plan to improvise this module and post the code here.
Best regards
Sridhar
Comment #5
mooffie commentedThis means a PHP error occured. Something inside the if() {} is wrong.
You're clicking the link with your left mouse button. So you can't see the errors. Open the link in a new window. Or disable JavaScript. And if you see a white screen, check your server's error log.
I don't have the time for this. I already said my code is only a starting point. Let us know what errors are printed (the _real_ error(s), not the one you quoted) and we'll try to help.
Comment #6
sridharpandu commentedThanks a lot. Will check that out.
Best regards
Sridhar
Comment #7
mooffie commentedI've checked the code I gave you and it works for me. So I'm marking this "fixed".
Re-open this when you have the error message.
IMPORTANT: The code has "$flag->get_user_count($account->uid)". This will work in Flag 1.x only. If you're using Flag 2.x, change this to "$flag->get_user_count($account->uid, flag_get_sid($account->uid))". (This won't be necessary when #1011048: $flag->get_user_count(): make 'sid' optional is fixed.)
Comment #8
sridharpandu commented@mooffie, Thanks a lot. I am checking it. I've noticed I don't get this error, or rather haven't got this error till date on slicehost. On my localhost I don't get this error if I open it in a new tab or new window. My initial impression is that it seems to be a PHP memory issue. My laptop has 128M set in PHP.ini while the slicehost has unlimited memory for PHP. No entry in error logs on my laptop. But access logs have the following entries. Will try and home in on the issue.
127.0.0.1 - - [31/Dec/2010:08:27:51 +0530] "GET /drupal6/misc/jquery.js?z HTTP/1.1" 200 16055 "http://127.0.0.1/drupal6/?q=node/2" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.1$
127.0.0.1 - - [31/Dec/2010:08:27:51 +0530] "GET /drupal6/misc/drupal.js?z HTTP/1.1" 200 3912 "http://127.0.0.1/drupal6/?q=node/2" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Ubuntu/10.10 (maverick) Firefox/3.6.12$
Best regards
Sridhar
Comment #10
Anonymous (not verified) commentedAny plans to move this into a module?
Comment #11
sridharpandu commented@SuperDuperDan - Are you addressing the question to me or mooffie?
Comment #12
daniel-san commentedAfter searching for a way to create a simple voting system in which each user would only have 5 votes each, this code worked perfect. I wanted the simplicity of Flags to vote for items and did not find what I needed from any of the voting modules. This helped my tremendously. Thanks for the discussion and for sharing this code.