/[drupal]/contributions/modules/wishlist/wishlist.module
ViewVC logotype

Contents of /contributions/modules/wishlist/wishlist.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.45 - (show annotations) (download) (as text)
Sat Jan 26 23:05:37 2008 UTC (22 months ago) by smclewin
Branch: MAIN
CVS Tags: DRUPAL-6--2-1, HEAD
Branch point for: DRUPAL-6--2
Changes since 1.44: +3 -3 lines
File MIME type: text/x-php
Fixed #210710 (and other similar warnings with _GET(wl_reveal))
1 <?php
2 /* $Id: wishlist.module,v 1.44 2008/01/26 23:01:53 smclewin Exp $ */
3 // Wishlist management module for Drupal
4 // Written by Scott McLewin and Melanie Paul-McLewin
5 // drupal AT mclewin DOT com
6
7
8
9 /** PHP4 compatibliibility **/
10 if (!function_exists("stripos")) {
11 function stripos($str,$needle) {
12 return strpos(strtolower($str),strtolower($needle));
13 }
14 }
15
16 /**
17 * Hook to return permission supported by this module
18 *
19 * @return
20 * create wishlists - authority to do "create content -> wishlist"
21 * edit own wishlist - authority to edit your own wishlist
22 * admin wishlist - authority to administer the wishlist module
23 * access wishlists - rights to view, purchase and return items on wishlists
24 */
25 function wishlist_perm() {
26 return array ("create wishlists", "edit own wishlist", "admin wishlist", "access wishlists", 'reveal purchase status');
27 }
28
29
30 /**
31 * load hook to bring in the wishlist specific node fields
32 *
33 * @param $node
34 * Core node record entries
35 * @return
36 * A wishlist object, which will be combined with $node
37 */
38 function wishlist_load($node) {
39 $wishlist = db_fetch_object(db_query('SELECT * FROM {wishlist} WHERE nid = %d', $node->nid));
40
41 $wishlist->item_quantity_purchased = _wishlist_get_node_quantity_purchased($node->nid);
42
43 return $wishlist;
44 }
45
46
47
48 /**
49 * node_name hook to return this module's name for nodes it creates
50 *
51 * @return
52 * Name of the node type created by this module
53 */
54 function wishlist_node_name() {
55 return 'wishlist';
56 }
57
58
59 /**
60 * node_info hook to return this module's name and description for wishlist nodes
61 *
62 * @return
63 * Name of the node type created by this module
64 */
65 function wishlist_node_info() {
66 return array(
67 'wishlist' =>
68 array(
69 'name' => t('Wishlist'),
70 'module' => 'wishlist',
71 'description' => t('A wishlist allows you maintain a collection
72 of items you want for a special occasion, such as a holiday,
73 birthday or just for the fun of it. The wishlist is just a list,
74 to purchase items users will be directed to the appropriate source.')
75 )
76 );
77 }
78
79 /**
80 * @desc Register the wishlist module's theme functions
81 */
82 function wishlist_theme() {
83 return array(
84 'wishlist_username' => array(
85 'arguments' => array('uid' => null, 'defaultname' => null)
86 ),
87 'wishlist_node_url' => array(
88 'arguments' => array('url' => null, 'node' => null)
89 )
90 );
91 }
92
93
94 /**
95 * Help hook
96 *
97 * @param $section
98 * Which help URL has been requested
99 * @return
100 * Help text to display
101 */
102 function wishlist_help($path, $arg) {
103 $output ="";
104
105 switch ($path) {
106 case 'admin/help#wishlist':
107 break;
108 case 'node/add#wishlist':
109 $output = t("Add an item to one of your wishlist categories.");
110 break;
111 }
112 return $output;
113 }
114
115
116 /**
117 * Access hook for the wishlist module
118 *
119 * @param $op
120 * Operation the user is requesting
121 * @param $node
122 * Node on which the user is requesting the operation
123 * @return
124 * TRUE/FALSE based on checking permissions
125 */
126 function wishlist_access($op, $node) {
127 global $user;
128
129 if ($op == 'create') {
130 return user_access('create wishlists');
131 }
132
133 if ($op == 'update' || $op == 'delete' || $op == 'view') {
134 if (user_access('edit own wishlist') && ($user->uid == $node->uid)) {
135 return TRUE;
136 }
137 }
138 }
139
140
141 /**
142 * Generates the optional links under the node display
143 *
144 * @param
145 * See hook_link documentation
146 * @return
147 * Array of structured links
148 */
149 function wishlist_link($type, $node = 0, $main=0) {
150 global $user;
151 $links = array();
152
153 if ($type == 'node' && $node->type == 'wishlist') {
154 // Don't display a redundant edit link if they are node administrators.
155 if (wishlist_access('update', $node) && !user_access('administer nodes')) {
156 $links['wishlist_edit_this_item'] = array(
157 'title' => t('Edit this wishlist item'),
158 'href' => "node/$node->nid/edit"
159 );
160 }
161
162 // If the user has access rights to wishlists, then add links to handle purchases
163 if (user_access('access wishlists') && !_wishlist_hide_purchase_info($node)) {
164 // Only place the purchase link up if there are any items left
165 if($node->item_quantity_purchased < $node->item_quantity_requested) {
166 $links['wishlist_get_this_gift'] = array(
167 'title' => t('Get this gift'),
168 'href' => "wishlist/item/$node->nid/purchase"
169 );
170 }
171 } else if(!$user->uid) {
172 // If the user is not logged in, then give them the opportunity to do so.
173 $links['wishlist_login_or_register'] = array(
174 'title' => t('<a href="@login">Login</a> or <a href="@register">register</a> to purchase wishlist items', array('@login' => url('user/login'), '@register' => url('user/register'))),
175 'html' => TRUE
176 );
177 }
178 }
179 return $links;
180 }
181
182
183
184 function wishlist_cron() {
185 $expire_days = variable_get('wishlist_item_expire_days', 30);
186 // If the automatic expiration feature is disabled, return.
187 if($expire_days == 0) {
188 return;
189 }
190
191 // Calculate the time before which we will go looking for items that are fully purchased.
192 $time = time() - ($expire_days*24*60*60);
193
194 watchdog('wishlist', "Removing items purchased before @dt", array('@dt' =>format_date($time)));
195
196 // Pull back all of the items that have been fully purchased where the last
197 // transaction was over 'wishlist_item_expire_days' ago and is public. Move
198 // these to the user's private list. Do this in batches of 100.
199 // For wishlist installations that pre-date the addition of the purch_date field, the bought items
200 // will be moved into the user's private list reguardless of when the last purchase was.
201 $sql = "SELECT p.*, MAX(p.purch_date) as compare_date, SUM(p.wishlist_purch_quantity) as purchased, n.title, n.nid, w.item_is_public, w.item_quantity_requested FROM {wishlist_purchased} p
202 INNER JOIN {node} n ON n.nid = p.wishlist_purch_nid
203 INNER JOIN {wishlist} w ON n.nid = w.nid
204 WHERE w.item_is_public = 1
205 AND p.purch_date != 0
206 GROUP BY n.nid
207 HAVING purchased >= w.item_quantity_requested
208 AND compare_date < %d
209 ORDER BY compare_date LIMIT 100";
210 $result = db_query($sql, $time);
211
212 while($row = db_fetch_object($result)) {
213 watchdog('wishlist', 'Hiding purchased item @title. It now appears only on the users private list.', array('@title' => $row->title.' '));
214 db_query("UPDATE {node} SET status=0 WHERE nid=%d", $row->nid);
215 db_query('UPDATE {wishlist} SET item_is_public=0 WHERE nid=%d', $row->nid);
216 }
217 }
218
219 /**
220 * Wishlist node specific form edit/entry generation through hook_form.
221 *
222 * @param $node
223 * See hook_form on http://www.drupaldocs.org for parameter details
224 * @return
225 * See hook_form on http://www.drupaldocs.org for return value details
226 */
227 function wishlist_form(&$node) {
228 $output = '';
229
230 $form['title'] = array(
231 '#type' => 'textfield',
232 '#title' => t('Title'),
233 '#default_value' => $node->title,
234 '#size' => 60,
235 '#maxlength' => 128,
236 '#description' => NULL,
237 '#attributes' => NULL,
238 '#required' => TRUE,
239 );
240
241 // In order to be able to attach taxonomy terms to this node, we need
242 // to display the appropriate form elements.
243 if (function_exists('taxonomy_node_form')) {
244 $output .= implode('', taxonomy_node_form('wishlist', $node));
245 }
246
247 // IF the item_priority field is set to 0 then assume this is a newly initialized
248 // record and set reasonable defaults on other entries as well.
249 if ($node->item_priority == 0) {
250 $node->item_priority = 3;
251 $node->item_is_public = TRUE;
252 }
253
254 if ($node->item_currency == "") {
255 $node->item_currency = variable_get("wishlist_default_currency", "USD");
256 }
257
258
259 $form["item_is_public"] = array(
260 '#type' => 'checkbox',
261 '#title' => t("Public wish list item"),
262 '#return_value' => TRUE,
263 '#default_value' => $node->item_is_public,
264 '#description' => t("Makes this item visible to anybody. If you uncheck this only you will be able to view the entry and this node will be set to 'unpublished'."),
265 );
266
267 $form["body"] = array(
268 '#type' => 'textarea',
269 '#title' => t("Item Description"),
270 '#default_value' => $node->body,
271 '#cols' => 60,
272 '#rows' => 18,
273 '#description' => t("Give a brief description of the item that you are adding to your wishlist and/or note why you want it"),
274 );
275
276 // If the admin has hidden the currency field then add the currency to the
277 // title of the estimated cost field.
278 if(false == variable_get("wishlist_show_currency", TRUE)) {
279 $est_cost_currency = t(' (in @currency)', array('@currency' => $node->item_currency));
280 } else {
281 $est_cost_currency = '';
282 }
283
284 $form["item_est_cost"] = array(
285 '#type' => 'textfield',
286 '#title' => t("Estimated Cost").$est_cost_currency,
287 '#default_value' => $node->item_est_cost,
288 '#size' => 5,
289 '#maxlength' => 5,
290 '#description' => t("If you know about how much the item will cost, enter it here."),
291 );
292
293 if(variable_get("wishlist_show_currency", TRUE)) {
294 $form["item_currency"] = array(
295 '#type' => 'textfield',
296 '#title' => t("Currency"),
297 '#default_value' => $node->item_currency,
298 '#size' => 5,
299 '#maxlength' => 5,
300 '#description' => t("Enter the three character ISO currency code for the value in the Estimated Cost field. e.g. USD for US Dollars, THB for Thai Baht, etc"),
301 );
302 } else {
303 // If the currency value is not shown we still need to pass through
304 // the default. Do that through a hidden field.
305 $form["item_currency"] = array(
306 '#type' => 'hidden',
307 '#default_value' => $node->item_currency,
308 '#size' => 5,
309 '#maxlength' => 5,
310 );
311 }
312 $form["item_url1"] = array(
313 '#type' => 'textfield',
314 '#title' => t("Primary URL"),
315 '#default_value' => $node->item_url1,
316 '#size' => 60,
317 '#maxlength' => 250,
318 '#description' => t("Enter the URL from which the item can be purchased. Use the form 'http://www.example.com'"),
319 );
320
321 $form["item_url2"] = array(
322 '#type' => 'textfield',
323 '#title' => t("Secondary URL"),
324 '#default_value' => $node->item_url2,
325 '#size' => 60,
326 '#maxlength' => 250,
327 '#description' => t("Optionally enter another URL from which the item can be purchased. Use the form 'http://www.example.com'"),
328 );
329
330 $form["item_quantity_requested"] = array(
331 '#type' => 'textfield',
332 '#title' => t("Quantity Requested"),
333 '#default_value' => $node->item_quantity_requested,
334 '#size' => 5,
335 '#maxlength' => 5,
336 '#description' => t("Enter the number of this item that you would like if one is not enough"),
337 );
338
339 $options = _wishlist_get_item_priority_array();
340
341 $form["item_priority"] = array(
342 '#type' => 'select',
343 '#title' => t("Priority"),
344 '#default_value' => $node->item_priority,
345 '#options' => $options,
346 '#description' => t("Rate the importance of this item to help your friends and family select a gift"),
347 '#extra' => FALSE,
348 );
349
350 return $form;
351 }
352
353 /**
354 * Implementation of wishlist_validate().
355 *
356 * Our "quantity" field requires a number to be entered. This hook lets
357 * us ensure that the user entered an appropriate value before we try
358 * inserting anything into the database.
359 *
360 * Errors should be signaled with form_set_error().
361 */
362 function wishlist_validate(&$node) {
363 // We allow 0 as a quantity for placeholder wishlist items, such as pointers to a wishlist
364 // on a shopping web site.
365 if($node->item_quantity_requested == '') {
366 form_set_error('item_quantity_requested', t('Please enter the quantity requested.'));
367 } else if (!is_numeric($node->item_quantity_requested)) {
368 form_set_error('item_quantity_requested', t('The requested quantity must be a number.'));
369 } else if($node->item_quantity_requested < 0) {
370 form_set_error('item_quantity_requested', t('The requested quantitiy cannot be negative.'));
371 }
372
373 if($node->item_est_cost == '') {
374 form_set_error('item_est_cost', t('You must enter a cost for this wishlist item'));
375 } else if (!is_numeric($node->item_est_cost)) {
376 form_set_error('item_est_cost', t('You must enter a numeric value for the cost.'));
377 }
378 }
379
380
381
382 /**
383 * Implementation of wishlist_insert().
384 *
385 * As a new node is being inserted into the database, we need to do our own
386 * database inserts.
387 */
388 function wishlist_insert($node) {
389 $node->item_url1 = _wishlist_correct_url($node->item_url1);
390 $node->item_url2 = _wishlist_correct_url($node->item_url2);
391
392 db_query("INSERT INTO {wishlist} (nid, item_is_public, item_est_cost, item_url1, item_url2, item_quantity_requested, item_priority, item_currency) VALUES
393 (%d, %d, %d, '%s', '%s', %d, %d, '%s')",
394 $node->nid, $node->item_is_public, $node->item_est_cost, $node->item_url1, $node->item_url2, $node->item_quantity_requested, $node->item_priority[0], $node->item_currency);
395
396
397 // If this item is not public, then unpublish it. I personally think this is a little hack,
398 // but I was unable to work out how to prevent a node from loading if it is "private". wishlist_load
399 // cannot return a value that prevents the node from being brought in. While the display logic in
400 // wishlist_view can be suppressed, that only gets rid of the wishlist specific display elements.
401 // The item name and description, which are in the node table, are both displayed.
402 // Before running this logic, test to see if the item_is_public member even exists. If it does not,
403 // then it means this call to hook_validate is taking place as the $node is being built for the first
404 // time. Don't go setting the status to unpublished in that case.
405 if (!$node->item_is_public) {
406 db_query("UPDATE {node} SET status=0 WHERE nid=%d", $node->nid);
407 }
408
409 }
410
411 /**
412 * Implementation of wishlist_update().
413 *
414 * As an existing node is being updated in the database, we need to do our own
415 * database updates.
416 */
417 function wishlist_update($node) {
418 $node->item_url1 = _wishlist_correct_url($node->item_url1);
419 $node->item_url2 = _wishlist_correct_url($node->item_url2);
420 db_query("UPDATE {wishlist} SET item_is_public= %d, item_est_cost= '%s', item_url1= '%s', item_url2= '%s', item_quantity_requested= %d, item_currency='%s', item_priority=%d WHERE nid=%d", $node->item_is_public, $node->item_est_cost, $node->item_url1, $node->item_url2, $node->item_quantity_requested, $node->item_currency, $node->item_priority[0], $node->nid);
421 // If this item is not public, then unpublish it. I personally think this is a little hack,
422 // but I was unable to work out how to prevent a node from loading if it is "private". wishlist_load
423 // cannot return a value that prevents the node from being brought in. While the display logic in
424 // wishlist_view can be suppressed, that only gets rid of the wishlist specific display elements.
425 // The item name and description, which are in the node table, are both displayed.
426 // Before running this logic, test to see if the item_is_public member even exists. If it does not,
427 // then it means this call to hook_validate is taking place as the $node is being built for the first
428 // time. Don't go setting the status to unpublished in that case.
429 if (!$node->item_is_public) {
430 db_query("UPDATE {node} SET status=0 WHERE nid=%d", $node->nid);
431 }
432 }
433
434
435
436
437 /**
438 * Implementation of wishlist_delete().
439 *
440 * When a node is deleted, we need to clean up related tables.
441 */
442 function wishlist_delete($node) {
443 db_query('DELETE FROM {wishlist_purchased} WHERE wishlist_purch_nid = %d', $node->nid);
444 db_query('DELETE FROM {wishlist} WHERE nid = %d', $node->nid);
445 }
446
447
448 /**
449 * @desc Hook_init implementation
450 *
451 * Add the wishlist css file to the page.
452 */
453 function wishlist_init() {
454 drupal_add_css(drupal_get_path('module', 'wishlist') .'/wishlist.css');
455 }
456
457 /**
458 * hook_menu implementation
459 *
460 * @param
461 * See hook_menu in http://www.drupaldocs.org for parameter details
462 * @return
463 * See hook_menu in http://www.drupaldocs.org for return code details
464 */
465 function wishlist_menu() {
466 $items['admin/settings/wishlist'] = array(
467 'title' => 'Wishlist settings',
468 'description' => 'Configure the wishlist module\'s settings.',
469 'page callback' => 'drupal_get_form',
470 'page arguments' => array('wishlist_admin_settings'),
471 'access arguments' => array('administer site configuration'),
472 'type' => MENU_NORMAL_ITEM,
473 'file' => 'wishlist.admin.inc'
474 );
475 $items['wishlist/%'] = array(
476 'title' => 'Wish lists',
477 'page callback' => 'wishlist_page',
478 'access arguments' => array('access wishlists'),
479 'type' => MENU_NORMAL_ITEM,
480 'file' => 'wishlist.page.inc'
481 );
482 $items['wishlist'] = array(
483 'title' => 'Wish lists',
484 'page callback' => 'wishlist_page',
485 'access arguments' => array('access wishlists'),
486 'type' => MENU_NORMAL_ITEM,
487 'file' => 'wishlist.page.inc'
488 );
489 $items['admin/content/wishlist'] = array(
490 'title' => 'Wishlist purchases',
491 'page callback' => 'wishlist_admin_page',
492 'access arguments' => array('admin wishlist'),
493 'description' => 'Manage and view the wishlist purchase records for your site.',
494 'type' => MENU_NORMAL_ITEM,
495 'file' => 'wishlist.admin.inc'
496 );
497 $items['admin/content/wishlist/delete'] = array(
498 'title' => 'Delete wishlist item',
499 'page callback' => '_wishlist_admin_delete_item',
500 'access arguments' => array('admin wishlist'),
501 'type' => MENU_CALLBACK,
502 'file' => 'wishlist.admin.inc'
503 );
504 return $items;
505 }
506
507 /**
508 * @desc use hook_menu_alter to put the proper permissions on the wishlist add menu
509 */
510 function wishlist_menu_alter(&$callbacks) {
511 $callbacks['node/add/wishlist']['access callback'] = 'user_access';
512 $callbacks['node/add/wishlist']['access arguments'] = array('create wishlists');
513 }
514
515
516
517
518 /**
519 * hook_block implementation
520 *
521 * @param
522 * See hook_block in http://www.drupaldocs.org for parameter details
523 * @return
524 * See hook_block in http://www.drupaldocs.org for return code details
525 */
526 function wishlist_block($op = "list", $delta = 0) {
527 if ($op == "list") {
528 $blocks[0]["info"] = t("Wishlists");
529 return $blocks;
530 }
531 elseif ($op == 'view') {
532 $result = db_query_range(db_rewrite_sql("SELECT n.nid, n.title, n.uid, u.name FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.type='%s' GROUP BY u.uid ORDER BY u.name DESC"), 'wishlist', 0, variable_get("wishlist_block_max_names", "5"));
533
534 $has_rows = false;
535 while ($account = db_fetch_object($result)) {
536 $items[] = format_wishlists($account);
537 $has_rows = true;
538 }
539 // If the site has no wishlists, then return an empty block
540 if(false == $has_rows) {
541 $block["subject"] = "";
542 $block["content"] = "";
543 return $block;
544 }
545
546
547 $block_content = theme('item_list', $items);
548
549 // add a more link to our page that displays all the links
550 $block_content .=
551 "<div class='more-link'>".
552 l(t("More"), "wishlist", array('attributes' => array("title" => t("View all wishlists."))))
553 ."</div>";
554
555 $block["subject"] = t("Wishlists");
556 $block["content"] = $block_content;
557 return $block;
558 }
559 }
560
561 /**
562 * Allows for a site to theme the username. An example reason to do this
563 * would be to display the user's real name from a site specific profile system
564 * rather than to use the name in the Drupal user record. The output will be
565 * truncated to 15 characters. It should contain no markup.
566 *
567 */
568 function theme_wishlist_username($uid, $defaultname) {
569 return $defaultname;
570 }
571
572 /**
573 * Formats the wishlist item title with (or without) appropriate links to the full record
574 *
575 * @param $object
576 * The wishlist node to format
577 * @param $append_text
578 * Optional text to tack on the end of the user's name.
579 * @return
580 * Formatted text ready for display
581 */
582 function format_wishlists($object, $append_text="") {
583 global $user;
584
585 if ($object->uid && $object->name) {
586 $fullname = theme('wishlist_username', $object->uid, $object->name);
587
588 // Shorten the name when it is too long or it will break many tables.
589 if (drupal_strlen($fullname) > 20) {
590 $name = truncate_utf8($fullname, 15) .'...';
591 } else {
592 $name = $fullname;
593 }
594
595 $output = l($name.$append_text, 'wishlist/'. $object->uid, array('title' => t('View wishlist items for ').check_plain($fullname)));
596 }
597 else if ($object->name) {
598 // Sometimes modules display content composed by people who are
599 // not registered members of the site (e.g. mailing list or news
600 // aggregator modules). This clause enables modules to display
601 // the true author of the content.
602 if ($object->homepage) {
603 $output = '<a href="'. $object->homepage .'">'. check_plain($object->name.$append_text).'</a>';
604 }
605 else {
606 $output = check_plain($object->name.$append_text);
607 }
608
609 $output .= ' ('. t('not verified') .')';
610 }
611 else {
612 $output = variable_get('anonymous', 'Anonymous');
613 }
614
615 // If the curent user is logged in, then also look for new items.
616 if($user->uid && $object->uid) {
617 $sql = "SELECT COUNT(n.nid) FROM {node} n
618 INNER JOIN {users} u ON n.uid = u.uid
619 LEFT JOIN {history} h ON n.nid = h.nid AND h.uid = %d
620 WHERE n.status = 1
621 AND u.uid = %d
622 AND n.type = 'wishlist'
623 AND n.created > %d
624 AND h.nid IS NULL";
625 $sql = db_rewrite_sql($sql);
626 $new_count = db_result(db_query($sql, $user->uid, $object->uid, NODE_NEW_LIMIT));
627 if($new_count > 0) {
628 $output .= '<span class="new-wishlist-items">'.t('@count new', array('@count' => $new_count)).'</span>';
629 }
630 }
631 return $output;
632 }
633
634
635
636
637
638
639
640
641 /**
642 * hook_view implementation
643 *
644 * @param
645 * See hook_view in http://www.drupaldocs.org for parameter details
646 * @return
647 * See hook_view in http://www.drupaldocs.org for return code details
648 */
649 function wishlist_view($node, $teaser = FALSE, $page = FALSE) {
650 $node = node_prepare($node, $teaser);
651
652 if($page) {
653 $giftee_account = user_load(array('uid' => $node->uid));
654
655 $breadcrumb[] = l(t('Home'), NULL);
656 $breadcrumb[] = l(t('All wishlists'), 'wishlist');
657 $breadcrumb[] = l(t("@name's wishlist", array('@name' => $giftee_account->name)), 'wishlist/'.$node->uid);
658 drupal_set_breadcrumb($breadcrumb);
659 }
660
661 $node->content['wishlist'] = array(
662 '#value' => _wishlist_render_view($node, $teaser),
663 '#weight' => 1
664 );
665
666 return $node;
667 }
668
669 /**
670 * Builds the primary view of a wishlist item.
671 *
672 * @param
673 * See hook_view in http://www.drupaldocs.org for parameter details
674 * @return
675 * an output buffer ready to do further processing on (such as call theme('page', ...)
676 */
677 function _wishlist_render_view($node, $teaser = FALSE) {
678 global $user;
679
680 $output = "<div class='wishlist'>";
681 $output .= '<div class="wl_spacer">&nbsp;</div>';
682 $output .= '<div class="main-body">';
683 $output .= "<div class='item_est_cost'>".t("Estimated Cost")." "._wishlist_currency_str($node->item_currency).$node->item_est_cost."</div>";
684 $output .= theme('wishlist_node_url', $node->item_url1, $node);
685 $output .= theme('wishlist_node_url', $node->item_url2, $node);
686 if(!$teaser) {
687 $output .= _wishlist_render_purchased_items($node);
688 }
689 $output .= "<div class='changed'>".t("Last updated on")." ".format_date($node->changed, "small")."</div>";
690 $output .= '</div>';
691 $output .= '<div class="purchase-info">';
692 $output .= _wishlist_get_reveal_form($node->uid);
693
694 $priority_str = _wishlist_get_item_priority_array();
695 // Depending on the context in which this is called the item priority value is either a value or an array of values
696 $output .= "<div class='priority'>".$priority_str[is_array($node->item_priority) ? $node->item_priority[0] : $node->item_priority]."</div>";
697
698
699 $output .= "<div class='requested'>".t("Requested")." ".$node->item_quantity_requested."</div>";
700 if(_wishlist_hide_purchase_info($node)) {
701 $output .= "<div class='purchased'>".t("Purchase details hidden")."</div>";
702 } else {
703 $output .= "<div class='purchased'>".t("Purchased")." ".$node->item_quantity_purchased."</div>";
704 }
705
706 // Under a preview of a new node there is nothing to see and no nid value just yet. Skip this code
707 if(!is_null($node->nid) && $node->nid > 0) {
708 // Retrieve all of the records showing what the currently logged in user purchaed on this item.
709 $result = db_query(db_rewrite_sql("SELECT p.wishlist_purch_wid, p.wishlist_purch_buyer_uid, p.wishlist_purch_quantity FROM {wishlist_purchased} p WHERE p.wishlist_purch_buyer_uid=%d AND p.wishlist_purch_nid=%d", "p", "wishlist_purch_buyer_nid"),$user->uid, $node->nid);
710
711 $header = array(
712 array('data' => t("Quantity<br>You<br>Purchased")),
713 array('data' => t("Action"))
714 );
715
716 $rows = array(); // if there were no records, we don't want an undefined variable notification
717 while($wishlist_purch = db_fetch_object($result)) {
718 if ($wishlist_purch->wishlist_purch_quantity > 1) {
719 $action_str = t("Return these items");
720 } else {
721 $action_str = t("Return this item");
722 }
723 $rows[] = array(
724 array("data" => $wishlist_purch->wishlist_purch_quantity),
725 array("data" => l($action_str, "wishlist/item/$node->nid/return/$wishlist_purch->wishlist_purch_wid"))
726 );
727
728 }
729
730 if ($rows) {
731 $output .= "<div class='wishlist_purchased'>".theme('table', $header, $rows)."</div>";
732 }
733 }
734 // end the purchase-info div
735 $output .= '</div>';
736 $output .= '<div class="wl_spacer">&nbsp;</div>';
737 // end the wishlist div
738 $output .= '</div>';
739
740 return $output;
741 }
742
743 /**
744 * Returns the HTML to display a table showing who purchased which gifts for the user, and when.
745 * This is part of the node display. It will only show for users who have 'admin wishlist' or
746 * 'reveal purchase status' permissions.
747 *
748 * @param node $node
749 */
750 function _wishlist_render_purchased_items($node) {
751 global $user;
752
753 // Don't show this during a preview.
754 if(!$node->nid) {
755 return '';
756 }
757
758 // To view this region, the user must either have reveal purchase status
759 // or be an administrator.
760 if(!user_access('admin wishlist') && !user_access('reveal purchase status')) {
761 return '';
762 }
763
764 // If this is not your entry, then you cannot see the
765 // purchase details UNLESS you are an admin.
766 if($user->uid != $node->uid) {
767 if(!user_access('admin wishlist')) {
768 return '';
769 }
770 }
771
772 // If the site is configured to hide details from the list owner
773 // then check to see if this user, the owner, has the right to reveal
774 // and reveal mode is turned on. If not, do not show this region.
775 if(variable_get("wishlist_hide_purchase_info_own", FALSE) && ($user->uid == $node->uid)) {
776 if(user_access('reveal purchase status') && isset($_GET['wl_reveal']) && ($_GET['wl_reveal'] != 1)) {
777 return '';
778 }
779 }
780
781 $sql = "SELECT p.*, u.name FROM {wishlist_purchased} p
782 INNER JOIN {users} u ON u.uid = p.wishlist_purch_buyer_uid
783 WHERE p.wishlist_purch_nid = %d";
784 $result = db_query($sql, $node->nid);
785
786 $header = array(
787 array('data' => t('Purchaser')),
788 array('data' => t('On')),
789 array('data' => t('Quantity'))
790 );
791 $rows = array();
792
793 while($row = db_fetch_object($result)) {
794 $rows[] = array(
795 array('data' => check_plain($row->name)),
796 array('data' => ($row->purch_date != 0) ? format_date($row->purch_date, 'custom', 'j M y') : t('unknown')),
797 array('data' => $row->wishlist_purch_quantity)
798 );
799 }
800
801 // If there is no purchaser record, return nothing to display
802 if(empty($rows)) {
803 return '';
804 }
805
806 $output = '<div class="who-purchased">';
807 $output .= '<fieldset><legend>'.t('Gift purchase record').'</legend>'.theme('table', $header, $rows).'</fieldset>';
808 $output .= '</div>';
809
810 return $output;
811 }
812
813
814
815
816
817 /**
818 * Returns a display string based on the currency code passed in. If the code is not known, the output is set to the input.
819 *
820 * @param $currency
821 * A three character ISO currency code to translate into display text, if possible
822 *
823 * @return
824 * A currency code to display on the page
825 */
826 function _wishlist_currency_str($currency) {
827
828 $output = $currency;
829
830 switch(drupal_strtoupper($currency)) {
831 case "USD":
832 $output = "$";
833 break;
834 case "HKD":
835 $output = "HK$";
836 break;
837 case "GBP":
838 $output = "&pound;";
839 break;
840 case "JPY":
841 $output = "&#165;";
842 break;
843 case "EUR":
844 $output = "&euro;";
845 break;
846 }
847
848 return $output;
849 }
850
851 /**
852 * Gets an associative array (suitable for form_select()) mapping item_priority values to text
853 *
854 * @return
855 * An associative array relating item_priority values to text strings.
856 */
857 function _wishlist_get_item_priority_array() {
858 // Values for the item_priority field
859 $options = array(
860 "1" => t("I really want this"),
861 "2" => t("I'd love to have this"),
862 "3" => t("Nice to have"),
863 "4" => t("Thinking about it"),
864 "5" => t("Don't get this for me")
865 );
866 return $options;
867 }
868
869
870 /**
871 * Gets display text for the URL that truncates and removes the http:// protocol header
872 *
873 * @param $url
874 * The text of the URL string from which to strip away http://
875 * @param $maxlength
876 * The maximum length for the return string. If the string will exceen this length it will be trimmed and ... added to the end
877 * @return
878 * A display ready URL fragment
879 */
880 function _wishlist_url($url, $maxlength) {
881 $url = str_replace("http://", "", drupal_strtolower(check_plain($url)));
882 if (drupal_strlen($url) > $maxlength) {
883 $url = truncate_utf8($url, $maxlength-3)."...";
884 }
885 return $url;
886 }
887
888 /**
889 * Returns the number of items purchased for the node $nid
890 *
891 * @param $nid
892 * The node to check for purchases against
893 * @return
894 * A number - the count of items from that node which have already been purchased.
895 */
896 function _wishlist_get_node_quantity_purchased($nid) {
897
898 // Retrieve the count of the number of this item that have been purchased from the wishlist and
899 // return the result
900 $result = db_query(db_rewrite_sql("SELECT SUM(wishlist_purch_quantity) as quantity_purchased FROM {wishlist_purchased} WHERE wishlist_purch_nid = %d", "p", "wishlist_purch_nid"), $nid);
901 $item_quantity_purchased = 0;
902 if($purchased = db_fetch_object($result)) {
903 if (!is_null($purchased->quantity_purchased)) {
904 $item_quantity_purchased = $purchased->quantity_purchased;
905 }
906 }
907
908 return $item_quantity_purchased;
909 }
910
911
912 /**
913 * Given a URL will check to make sure it contains http or https.
914 *
915 * @param $url Inbound url to check
916 *
917 * @return Corrected URL (or the original if no change needed)
918 */
919 function _wishlist_correct_url($url) {
920 // check the URL for http and add it if needed
921 if ($url) {
922 if((stripos($url, "http://") === false) && (stripos($url, "https://") === false)) {
923 $url = 'http://'.$url;
924 }
925 }
926
927 return $url;
928 }
929
930 /**
931 * Utility function to determine whether or not to hide information
932 * about the purchase details of a wishlist item.
933 *
934 * @param $node The active/current wishlist node
935 */
936 function _wishlist_hide_purchase_info($node) {
937 global $user;
938
939
940
941 // On private items, we don't hide anything. Only the user can see these anyway.
942 if($node->item_is_public == FALSE && $user->uid == $node->uid) {
943 return false;
944 }
945
946 // If this is an anonymous user see if we are configured to hide purchase information
947 if(!$user->uid) {
948 if(variable_get("wishlist_hide_purchase_info_anonymous", FALSE)) {
949 return true;
950 }
951 }
952
953 // if it is the user's own wishlist entry, and the site is configure to hide purchase details by
954 // default, then return true unless the user has chosen to reveal items.
955 if($user->uid == $node->uid) {
956 // If this user is authorized to reveal items, then check
957 // for the wl_reveal GET parameter. If it is non-zero, then
958 // we won't hide the purchase details.
959 if(user_access('reveal purchase status')) {
960 if(isset($_GET['wl_reveal']) && ($_GET['wl_reveal'] != 0)) {
961 return false;
962 }
963 }
964
965 if(variable_get("wishlist_hide_purchase_info_own", FALSE)) {
966 return true;
967 }
968 }
969
970 return false;
971 }
972
973
974 /**
975 * Theme function to display the links at the bottom of the node view.
976 *
977 * @param $url The URL to format
978 * @param $node The node being displayed
979 */
980 function theme_wishlist_node_url($url, $node) {
981 global $user;
982
983 if($url == '') {
984 return '';
985 }
986
987 $output = '<div class="item_url">';
988 // If purchase info is hidden, or if all of the items were purchase (if there were any!), do not show
989 // the full links to the item.
990 if((($node->item_quantity_requested != 0) && ($node->item_quantity_purchased >= $node->item_quantity_requested))
991 || _wishlist_hide_purchase_info($node)) {
992 $output .= _wishlist_url($url, 30);
993 } else {
994 if(variable_get("wishlist_url_in_new_window", FALSE)) {
995 $url_link_target["target"] = "_wishlist_url_window";
996 }
997 $output .= t("See")." ".l(_wishlist_url($url, 50), $url, array('attributes' => array('target' => $url_link_target)));
998 }
999
1000 if(_wishlist_hide_purchase_info($node)) {
1001 // If the user is anonymous, then offer a login. Otherwise we are here
1002 // because the user is attempting to view their own wishlist
1003 // and the site does not share status with them.
1004 if(!$user->uid) {
1005 $output .= ' - '.l(t("Login to see full link"), "user/login");
1006 }
1007 } else if (($node->item_quantity_purchased >= $node->item_quantity_requested) && $node->item_quantity_requested != 0) {
1008 $output .= ' - '.t('None left to purchase');
1009 }
1010
1011 $output .= '</div>';
1012
1013 return $output;
1014 }
1015
1016 /**
1017 * Returns a form that will allow the user to reval-all on their lists. This
1018 * form will only be shown when a user is viewing their own
1019 * list or items and when the site is configured to hide the purchased
1020 * status from them.
1021 */
1022 function _wishlist_get_reveal_form($wishlist_uid) {
1023 global $user;
1024
1025 // Only show the form when the list/item is for the current user
1026 if($user->uid != $wishlist_uid) {
1027 return '';
1028 }
1029
1030 // If the site is not configured to hide the purchased status, then do
1031 // not bother with this form.
1032 if(!variable_get("wishlist_hide_purchase_info_own", FALSE)) {
1033 return '';
1034 }
1035
1036 // And finally if the user is not authorized to reveal purchased
1037 // status, don't show this form.
1038 if(!user_access('reveal purchase status')) {
1039 return '';
1040 }
1041
1042
1043
1044 $output = '<div class="reveal-form">';
1045
1046 $output .= drupal_get_form('wishlist_reveal_form');
1047
1048 $output .= '</div>';
1049
1050 return $output;
1051 }
1052
1053 /*
1054 * defines the form used to show the 'Show purchase details' menu option
1055 *
1056 */
1057 function wishlist_reveal_form() {
1058 $form['wishlist_reveal'] = array(
1059 '#type' => 'select',
1060 '#name' => 'wishlist_reveal',
1061 '#title' => '',
1062 '#default_value' => (isset($_GET['wl_reveal']) ? $_GET['wl_reveal'] : 0),
1063 '#options' => array(0 => t('Hide purchase details'), 1 => t('Show purchase details')),
1064 '#description' => '',
1065 '#multiple' => $multiple = FALSE,
1066 '#required' => $required = FALSE,
1067 '#attributes' => array('onChange' => "top.location.href='/".$_GET['q']."?wl_reveal='+this.value"),
1068 );
1069
1070 return $form;
1071 }
1072
1073 /**
1074 * Implementation of hook_views_tables().
1075 *
1076 * Initial views support contributed by draco2002 http://drupal.org/user/76079
1077 */
1078 function wishlist_views_tables() {
1079 $tables['wishlist'] = array(
1080 'name' => 'wishlist',
1081 'join' => array(
1082 'left' => array(
1083 'table' => 'node',
1084 'field' => 'nid'
1085 ),
1086 'right' => array(
1087 'field' => 'nid'
1088 ),
1089 ),
1090 'fields' => array(
1091 'item_est_cost' => array(
1092 'name' => t('Wishlist: Est. Cost'),
1093 'sortable' => TRUE,
1094 ),
1095 'item_url1' => array(
1096 'name' => t('Wishlist: Item URL 1'),
1097 'sortable' => TRUE,
1098 ),
1099 'item_url2' => array(
1100 'name' => t('Wishlist: Item URL 2'),
1101 'sortable' => TRUE,
1102 ),
1103 'item_quantity_requested' => array(
1104 'name' => t('Wishlist: Quantity Requested'),
1105 'sortable' => TRUE,
1106 ),
1107 'item_currency' => array(
1108 'name' => t('Wishlist: Est. Cost Currency'),
1109 'sortable' => TRUE,
1110 ),
1111 'item_priority' => array(
1112 'name' => t('Wishlist: Display Priority'),
1113 'sortable' => TRUE,
1114 ),
1115 ),
1116 'filters' => array(
1117 'item_is_public' => array(
1118 'name' => t('Wishlist: Item Is Public'),
1119 'operator' => array('=' => t('Equals')),
1120 'list' => 'views_handler_operator_yesno',
1121 'list-type' => 'select',
1122 'help' => t('Filter items by public or private status'),
1123 ),
1124 ),
1125 'sorts' => array(
1126 'item_priority' => array(
1127 'name' => t('Wishlist: Display Priority'),
1128 'help' => t('Sort by display priority'),
1129 ),
1130 ),
1131 );
1132
1133 return $tables;
1134 }
1135
1136
1137 ?>

  ViewVC Help
Powered by ViewVC 1.1.2