]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/wikilens/RatingsDb.php
Simpler SQL query
[SourceForge/phpwiki.git] / lib / wikilens / RatingsDb.php
1 <?php
2
3 /*
4  * @author:  Dan Frankowski (wikilens group manager), Reini Urban (as plugin)
5  *
6  * TODO:
7  * - fix RATING_STORAGE = WIKIPAGE (dba, file)
8  * - fix smart caching
9  * - finish mysuggest.c (external engine with data from mysql)
10  * - add the various show modes (esp. TopN queries in PHP)
11  */
12 /*
13  CREATE TABLE rating (
14         dimension INT(4) NOT NULL,
15         raterpage INT(11) NOT NULL,
16         rateepage INT(11) NOT NULL,
17         ratingvalue FLOAT NOT NULL,
18         rateeversion INT(11) NOT NULL,
19         isPrivate ENUM('yes','no'),
20         tstamp TIMESTAMP(14) NOT NULL,
21         PRIMARY KEY (dimension, raterpage, rateepage)
22  );
23 */
24
25 // For other than SQL backends. dba + adodb SQL ratings are allowed but deprecated.
26 // We will probably drop this hack.
27 if (!defined('RATING_STORAGE'))
28     // for DATABASE_TYPE=dba and forced RATING_STORAGE=SQL we must use ADODB,
29     // but this is problematic.
30     define('RATING_STORAGE', $GLOBALS['request']->_dbi->_backend->isSQL() ? 'SQL' : 'WIKIPAGE');
31 //define('RATING_STORAGE','WIKIPAGE');   // not fully supported yet
32
33 // leave undefined for internal, slow php engine.
34 //if (!defined('RATING_EXTERNAL'))
35 //    define('RATING_EXTERNAL',PHPWIKI_DIR . 'suggest.exe');
36
37 // Dimensions
38 if (!defined('EXPLICIT_RATINGS_DIMENSION'))
39     define('EXPLICIT_RATINGS_DIMENSION', 0);
40 if (!defined('LIST_ITEMS_DIMENSION'))
41     define('LIST_ITEMS_DIMENSION', 1);
42 if (!defined('LIST_OWNER_DIMENSION'))
43     define('LIST_OWNER_DIMENSION', 2);
44 if (!defined('LIST_TYPE_DIMENSION'))
45     define('LIST_TYPE_DIMENSION', 3);
46
47 //TODO: split class into SQL and metadata backends
48 class RatingsDb extends WikiDB
49 {
50
51     function RatingsDb()
52     {
53         global $request;
54         $this->_dbi = &$request->_dbi;
55         $this->_backend = &$this->_dbi->_backend;
56         $this->dimension = null;
57         if (RATING_STORAGE == 'SQL') {
58             if (isa($this->_backend, 'WikiDB_backend_PearDB')) {
59                 $this->_sqlbackend = &$this->_backend;
60                 $this->dbtype = "PearDB";
61             } elseif (isa($this->_backend, 'WikiDB_backend_ADODOB')) {
62                 $this->_sqlbackend = &$this->_backend;
63                 $this->dbtype = "ADODB";
64             } else {
65                 include_once 'lib/WikiDB/backend/ADODB.php';
66                 // It is not possible to decouple a ref from the source again. (4.3.11)
67                 // It replaced the main request backend. So we don't initialize _sqlbackend before.
68                 //$this->_sqlbackend = clone($this->_backend);
69                 $this->_sqlbackend = new WikiDB_backend_ADODB($GLOBALS['DBParams']);
70                 $this->dbtype = "ADODB";
71             }
72             $this->iter_class = "WikiDB_backend_" . $this->dbtype . "_generic_iter";
73
74             extract($this->_sqlbackend->_table_names);
75             if (empty($rating_tbl)) {
76                 $rating_tbl = (!empty($GLOBALS['DBParams']['prefix'])
77                     ? $GLOBALS['DBParams']['prefix'] : '') . 'rating';
78                 $this->_sqlbackend->_table_names['rating_tbl'] = $rating_tbl;
79             }
80         } else {
81             $this->iter_class = "WikiDB_Array_PageIterator";
82         }
83     }
84
85     // this is a singleton.  It ensures there is only 1 ratingsDB.
86     function & getTheRatingsDb()
87     {
88         static $_theRatingsDb;
89
90         if (!isset($_theRatingsDb)) {
91             $_theRatingsDb = new RatingsDb();
92         }
93         //echo "rating db is $_theRatingsDb";
94         return $_theRatingsDb;
95     }
96
97
98 /// *************************************************************************************
99 // FIXME
100 // from Reini Urban's RateIt plugin
101     function addRating($rating, $userid, $pagename, $dimension)
102     {
103         if (RATING_STORAGE == 'SQL') {
104             $page = $this->_dbi->getPage($pagename);
105             $current = $page->getCurrentRevision();
106             $rateeversion = $current->getVersion();
107             $this->sql_rate($userid, $pagename, $rateeversion, $dimension, $rating);
108         } else {
109             $this->metadata_set_rating($userid, $pagename, $dimension, $rating);
110         }
111     }
112
113     function deleteRating($userid = null, $pagename = null, $dimension = null)
114     {
115         if (is_null($dimension)) $dimension = $this->dimension;
116         if (is_null($userid)) $userid = $this->userid;
117         if (is_null($pagename)) $pagename = $this->pagename;
118         if (RATING_STORAGE == 'SQL') {
119             $this->sql_delete_rating($userid, $pagename, $dimension);
120         } else {
121             $this->metadata_set_rating($userid, $pagename, $dimension, -1);
122         }
123     }
124
125     function getRating($userid = null, $pagename = null, $dimension = null)
126     {
127         if (RATING_STORAGE == 'SQL') {
128             $ratings_iter = $this->sql_get_rating($dimension, $userid, $pagename);
129             if ($rating = $ratings_iter->next() and isset($rating['ratingvalue'])) {
130                 return $rating['ratingvalue'];
131             } else
132                 return false;
133         } else {
134             return $this->metadata_get_rating($userid, $pagename, $dimension);
135         }
136     }
137
138     function getUsersRated($dimension = null, $orderby = null)
139     {
140         if (is_null($dimension)) $dimension = $this->dimension;
141         //if (is_null($userid))    $userid = $this->userid;
142         //if (is_null($pagename))  $pagename = $this->pagename;
143         if (RATING_STORAGE == 'SQL') {
144             $ratings_iter = $this->sql_get_users_rated($dimension, $orderby);
145             if ($rating = $ratings_iter->next() and isset($rating['ratingvalue'])) {
146                 return $rating['ratingvalue'];
147             } else
148                 return false;
149         } else {
150             return $this->metadata_get_users_rated($dimension, $orderby);
151         }
152     }
153
154     /**
155      * Get ratings.
156      *
157      * @param dimension  The rating dimension id.
158      *                   Example: 0
159      *                   [optional]
160      *                   If this is null (or left off), the search for ratings
161      *                   is not restricted by dimension.
162      *
163      * @param rater  The page id of the rater, i.e. page doing the rating.
164      *               This is a Wiki page id, often of a user page.
165      *               Example: "DanFr"
166      *               [optional]
167      *               If this is null (or left off), the search for ratings
168      *               is not restricted by rater.
169      *               TODO: Support an array
170      *
171      * @param ratee  The page id of the ratee, i.e. page being rated.
172      *               Example: "DudeWheresMyCar"
173      *               [optional]
174      *               If this is null (or left off), the search for ratings
175      *               is not restricted by ratee.
176      *
177      * @param orderby An order-by clause with fields and (optionally) ASC
178      *                or DESC.
179      *               Example: "ratingvalue DESC"
180      *               [optional]
181      *               If this is null (or left off), the search for ratings
182      *               has no guaranteed order
183      *
184      * @param pageinfo The type of page that has its info returned (i.e.,
185      *               'pagename', 'hits', and 'pagedata') in the rows.
186      *               Example: "rater"
187      *               [optional]
188      *               If this is null (or left off), the info returned
189      *               is for the 'ratee' page (i.e., thing being rated).
190      *
191      * @return DB iterator with results
192      */
193     function get_rating($dimension = null, $rater = null, $ratee = null,
194                         $orderby = null, $pageinfo = "ratee")
195     {
196         if (RATING_STORAGE == 'SQL') {
197             $ratings_iter = $this->sql_get_rating($dimension, $rater, $pagename);
198             if ($rating = $ratings_iter->next() and isset($rating['ratingvalue'])) {
199                 return $rating['ratingvalue'];
200             } else
201                 return false;
202         } else {
203             return $this->metadata_get_rating($rater, $pagename, $dimension);
204         }
205     }
206
207     /* UR: What is this for? NOT USED!
208        Maybe the list of users (ratees) who rated on this page.
209      */
210     function get_users_rated($dimension = null, $pagename = null, $orderby = null)
211     {
212         if (RATING_STORAGE == 'SQL') {
213             $ratings_iter = $this->sql_get_users_rated($dimension, $pagename, $orderby);
214             // iter as userid
215             $users = array();
216             while ($rating = $ratings_iter->next()) {
217                 $users[] = $rating['userid'];
218             }
219             return $users;
220         } else {
221             return $this->metadata_get_users_rated($dimension, $pagename, $orderby);
222         }
223     }
224
225     /**
226      * Like get_rating(), but return a WikiDB_PageIterator
227      * FIXME!
228      */
229     function get_rating_page($dimension = null, $rater = null, $ratee = null,
230                              $orderby = null, $pageinfo = "ratee")
231     {
232         if (RATING_STORAGE == 'SQL') {
233             return $this->sql_get_rating($dimension, $rater, $ratee, $orderby, $pageinfo);
234         } else {
235             // empty dummy iterator
236             $pages = array();
237             return new WikiDB_Array_PageIterator($pages);
238         }
239     }
240
241     /**
242      * Delete a rating.
243      *
244      * @param rater  The page id of the rater, i.e. page doing the rating.
245      *               This is a Wiki page id, often of a user page.
246      * @param ratee  The page id of the ratee, i.e. page being rated.
247      * @param dimension  The rating dimension id.
248      *
249      * @access public
250      *
251      * @return true upon success
252      */
253     function delete_rating($rater, $ratee, $dimension)
254     {
255         if (RATING_STORAGE == 'SQL') {
256             $this->sql_delete_rating($rater, $ratee, $dimension);
257         } else {
258             $this->metadata_set_rating($rater, $ratee, $dimension, -1);
259         }
260     }
261
262     /**
263      * Rate a page.
264      *
265      * @param rater  The page id of the rater, i.e. page doing the rating.
266      *               This is a Wiki page id, often of a user page.
267      * @param ratee  The page id of the ratee, i.e. page being rated.
268      * @param rateeversion  The version of the ratee page.
269      * @param dimension  The rating dimension id.
270      * @param rating The rating value (a float).
271      *
272      * @access public
273      *
274      * @return true upon success
275      */
276     function rate($rater, $ratee, $rateeversion, $dimension, $rating)
277     {
278         if (RATING_STORAGE == 'SQL') {
279             $page = $this->_dbi->getPage($pagename);
280             $current = $page->getCurrentRevision();
281             $rateeversion = $current->getVersion();
282             $this->sql_rate($userid, $pagename, $rateeversion, $dimension, $rating);
283         } else {
284             $this->metadata_set_rating($userid, $pagename, $dimension, $rating);
285         }
286     }
287
288     //function getUsersRated(){}
289
290 //*******************************************************************************
291     // TODO:
292     // Use wikilens/RatingsUser.php for the php methods.
293     //
294     // Old:
295     // Currently we have to call the "suggest" CGI
296     //   http://www-users.cs.umn.edu/~karypis/suggest/
297     // until we implement a simple recommendation engine.
298     // Note that "suggest" is only free for non-profit organizations.
299     // I am currently writing a binary CGI mysuggest using suggest, which loads
300     // data from mysql.
301     function getPrediction($userid = null, $pagename = null, $dimension = null)
302     {
303         if (is_null($dimension)) $dimension = $this->dimension;
304         if (is_null($userid)) $userid = $this->userid;
305         if (is_null($pagename)) $pagename = $this->pagename;
306
307         if (RATING_STORAGE == 'SQL') {
308             $dbh = &$this->_sqlbackend;
309             if (isset($pagename))
310                 $page = $dbh->_get_pageid($pagename);
311             else
312                 return 0;
313             if (isset($userid))
314                 $user = $dbh->_get_pageid($userid);
315             else
316                 return 0;
317         }
318         if (defined('RATING_EXTERNAL') and RATING_EXTERNAL) {
319             // how call mysuggest.exe? as CGI or natively
320             //$rating = HTML::Raw("<!--#include virtual=".RATING_ENGINE." -->");
321             $args = "-u$user -p$page -malpha"; // --top 10
322             if (isset($dimension))
323                 $args .= " -d$dimension";
324             $rating = passthru(RATING_EXTERNAL . " $args");
325         } else {
326             $rating = $this->php_prediction($userid, $pagename, $dimension);
327         }
328         return $rating;
329     }
330
331     /**
332      * Slow item-based recommendation engine, similar to suggest RType=2.
333      * Only the SUGGEST_EstimateAlpha part
334      * Take wikilens/RatingsUser.php for the php methods.
335      */
336     function php_prediction($userid = null, $pagename = null, $dimension = null)
337     {
338         if (is_null($dimension)) $dimension = $this->dimension;
339         if (is_null($userid)) $userid = $this->userid;
340         if (is_null($pagename)) $pagename = $this->pagename;
341         if (empty($this->buddies)) {
342             require_once 'lib/wikilens/RatingsUser.php';
343             require_once 'lib/wikilens/Buddy.php';
344             $user = RatingsUserFactory::getUser($userid);
345             $this->buddies = getBuddies($user, $GLOBALS['request']->_dbi);
346         }
347         return $user->knn_uu_predict($pagename, $this->buddies, $dimension);
348     }
349
350     function getNumUsers($pagename = null, $dimension = null)
351     {
352         if (is_null($dimension)) $dimension = $this->dimension;
353         if (is_null($pagename)) $pagename = $this->pagename;
354         if (RATING_STORAGE == 'SQL') {
355             $ratings_iter = $this->sql_get_rating($dimension, null, $pagename,
356                 null, "ratee");
357             return $ratings_iter->count();
358         } else {
359             if (!$pagename) return 0;
360             $page = $this->_dbi->getPage($pagename);
361             $data = $page->get('rating');
362             if (!empty($data[$dimension]))
363                 return count($data[$dimension]);
364             else
365                 return 0;
366         }
367     }
368
369     function getAvg($pagename = null, $dimension = null)
370     {
371         if (is_null($dimension)) $dimension = $this->dimension;
372         if (is_null($pagename)) $pagename = $this->pagename;
373         if (RATING_STORAGE == 'SQL') {
374             $dbi = &$this->_sqlbackend;
375             if (isset($pagename) || isset($dimension)) {
376                 $where = "WHERE";
377             }
378             if (isset($pagename)) {
379                 $raterid = $this->_sqlbackend->_get_pageid($pagename, true);
380                 $where .= " raterpage=$raterid";
381             }
382             if (isset($dimension)) {
383                 if (isset($pagename)) $where .= " AND";
384                 $where .= " dimension=$dimension";
385             }
386             extract($dbi->_table_names);
387             $query = "SELECT AVG(ratingvalue) as avg FROM $rating_tbl r, $page_tbl p " . $where . " GROUP BY raterpage";
388             $result = $dbi->_dbh->query($query);
389             $iter = new $this->iter_class($this, $result);
390             $row = $iter->next();
391             return $row['avg'];
392         } else {
393             if (!$pagename) return 0;
394             $page = $this->_dbi->getPage($pagename);
395             $data = $page->get('rating');
396             if (!empty($data[$dimension]))
397                 // hash of userid => rating
398                 return array_sum(array_values($data[$dimension])) / count($data[$dimension]);
399             else
400                 return 0;
401         }
402     }
403
404 //*******************************************************************************
405
406     /**
407      * Get ratings.
408      *
409      * @param dimension  The rating dimension id.
410      *                   Example: 0
411      *                   [optional]
412      *                   If this is null (or left off), the search for ratings
413      *                   is not restricted by dimension.
414      *
415      * @param rater  The page id of the rater, i.e. page doing the rating.
416      *               This is a Wiki page id, often of a user page.
417      *               Example: "DanFr"
418      *               [optional]
419      *               If this is null (or left off), the search for ratings
420      *               is not restricted by rater.
421      *               TODO: Support an array
422      *
423      * @param ratee  The page id of the ratee, i.e. page being rated.
424      *               Example: "DudeWheresMyCar"
425      *               [optional]
426      *               If this is null (or left off), the search for ratings
427      *               is not restricted by ratee.
428      *               TODO: Support an array
429      *
430      * @param orderby An order-by clause with fields and (optionally) ASC
431      *                or DESC.
432      *               Example: "ratingvalue DESC"
433      *               [optional]
434      *               If this is null (or left off), the search for ratings
435      *               has no guaranteed order
436      *
437      * @param pageinfo The type of page that has its info returned (i.e.,
438      *               'pagename', 'hits', and 'pagedata') in the rows.
439      *               Example: "rater"
440      *               [optional]
441      *               If this is null (or left off), the info returned
442      *               is for the 'ratee' page (i.e., thing being rated).
443      *
444      * @return DB iterator with results
445      */
446     function sql_get_rating($dimension = null, $rater = null, $ratee = null,
447                             $orderby = null, $pageinfo = "ratee")
448     {
449         if (is_null($dimension)) $dimension = $this->dimension;
450         $result = $this->_sql_get_rating_result($dimension, $rater, $ratee, $orderby, $pageinfo);
451         return new $this->iter_class($this, $result);
452     }
453
454     function sql_get_users_rated($dimension = null, $pagename = null, $orderby = null)
455     {
456         if (is_null($dimension)) $dimension = $this->dimension;
457         $result = $this->_sql_get_rating_result($dimension, null, $pagename, $orderby, "rater");
458         return new $this->iter_class($this, $result);
459     }
460
461     // all users who rated this page resp if null all pages.. needed?
462     function metadata_get_users_rated($dimension = null, $pagename = null, $orderby = null)
463     {
464         if (is_null($dimension)) $dimension = $this->dimension;
465         $users = array();
466         if (!$pagename) {
467             // TODO: all pages?
468             return new WikiDB_Array_PageIterator($users);
469         }
470         $page = $this->_dbi->getPage($pagename);
471         $data = $page->get('rating');
472         if (!empty($data[$dimension])) {
473             //array($userid => (float)$rating);
474             return new WikiDB_Array_PageIterator(array_keys($data[$dimension]));
475         }
476         return new WikiDB_Array_PageIterator($users);
477     }
478
479     /**
480      * @access private
481      * @return result ressource, suitable to the iterator
482      */
483     function _sql_get_rating_result($dimension = null, $rater = null, $ratee = null,
484                                     $orderby = null, $pageinfo = "ratee")
485     {
486         // pageinfo must be 'rater' or 'ratee'
487         if (($pageinfo != "ratee") && ($pageinfo != "rater"))
488             return;
489         $dbi = &$this->_sqlbackend;
490         if (is_null($dbi))
491             return;
492         //$dbh = &$this->_dbi;
493         extract($dbi->_table_names);
494         $where = "WHERE r." . $pageinfo . "page = p.id";
495         if (isset($dimension)) {
496             $where .= " AND dimension=$dimension";
497         }
498         if (isset($rater)) {
499             $raterid = $dbi->_get_pageid($rater, true);
500             $where .= " AND raterpage=$raterid";
501         }
502         if (isset($ratee)) {
503             if (is_array($ratee)) {
504                 $where .= " AND (";
505                 for ($i = 0; $i < count($ratee); $i++) {
506                     $rateeid = $dbi->_get_pageid($ratee[$i], true);
507                     $where .= "rateepage=$rateeid";
508                     if ($i != (count($ratee) - 1)) {
509                         $where .= " OR ";
510                     }
511                 }
512                 $where .= ")";
513             } else {
514                 $rateeid = $dbi->_get_pageid($ratee, true);
515                 $where .= " AND rateepage=$rateeid";
516             }
517         }
518         $orderbyStr = "";
519         if (isset($orderby)) {
520             $orderbyStr = " ORDER BY " . $orderby;
521         }
522         if (isset($rater) or isset($ratee)) $what = '*';
523         // same as _get_users_rated_result()
524         else {
525             $what = 'DISTINCT p.pagename';
526             if ($pageinfo == 'rater')
527                 $what = 'DISTINCT p.pagename as userid';
528         }
529
530         $query = "SELECT $what"
531             . " FROM $rating_tbl r, $page_tbl p "
532             . $where
533             . $orderbyStr;
534         $result = $dbi->_dbh->query($query);
535         return $result;
536     }
537
538     /**
539      * Delete a rating.
540      *
541      * @param rater  The page id of the rater, i.e. page doing the rating.
542      *               This is a Wiki page id, often of a user page.
543      * @param ratee  The page id of the ratee, i.e. page being rated.
544      * @param dimension  The rating dimension id.
545      *
546      * @access public
547      *
548      * @return true upon success
549      */
550     function sql_delete_rating($rater, $ratee, $dimension)
551     {
552         //$dbh = &$this->_dbi;
553         $dbi = &$this->_sqlbackend;
554         extract($dbi->_table_names);
555
556         $dbi->lock();
557         $raterid = $dbi->_get_pageid($rater, true);
558         $rateeid = $dbi->_get_pageid($ratee, true);
559         $where = "WHERE raterpage=$raterid and rateepage=$rateeid";
560         if (isset($dimension)) {
561             $where .= " AND dimension=$dimension";
562         }
563         $dbi->_dbh->query("DELETE FROM $rating_tbl $where");
564         $dbi->unlock();
565         return true;
566     }
567
568     /**
569      * Rate a page.
570      *
571      * @param rater  The page id of the rater, i.e. page doing the rating.
572      *               This is a Wiki page id, often of a user page.
573      * @param ratee  The page id of the ratee, i.e. page being rated.
574      * @param rateeversion  The version of the ratee page.
575      * @param dimension  The rating dimension id.
576      * @param rating The rating value (a float).
577      *
578      * @access public
579      *
580      * @return true upon success
581      */
582     //               ($this->userid, $this->pagename, $page->version, $this->dimension, $rating);
583     function sql_rate($rater, $ratee, $rateeversion, $dimension, $rating)
584     {
585         $dbi = &$this->_sqlbackend;
586         extract($dbi->_table_names);
587         if (empty($rating_tbl))
588             $rating_tbl = $this->_dbi->getParam('prefix') . 'rating';
589
590         $dbi->lock();
591         $raterid = $dbi->_get_pageid($rater, true);
592         $rateeid = $dbi->_get_pageid($ratee, true);
593         assert($raterid);
594         assert($rateeid);
595         //mysql optimize: REPLACE if raterpage and rateepage are keys
596         $dbi->_dbh->query("DELETE from $rating_tbl WHERE dimension=$dimension AND raterpage=$raterid AND rateepage=$rateeid");
597         $where = "WHERE raterpage='$raterid' AND rateepage='$rateeid'";
598         $insert = "INSERT INTO $rating_tbl (dimension, raterpage, rateepage, ratingvalue, rateeversion)"
599             . " VALUES ('$dimension', $raterid, $rateeid, '$rating', '$rateeversion')";
600         $dbi->_dbh->query($insert);
601
602         $dbi->unlock();
603         return true;
604     }
605
606     function metadata_get_rating($userid, $pagename, $dimension)
607     {
608         if (!$pagename) return false;
609         $page = $this->_dbi->getPage($pagename);
610         $data = $page->get('rating');
611         if (!empty($data[$dimension][$userid]))
612             return (float)$data[$dimension][$userid];
613         else
614             return false;
615     }
616
617     function metadata_set_rating($userid, $pagename, $dimension, $rating = -1)
618     {
619         if (!$pagename) return false;
620         $page = $this->_dbi->getPage($pagename);
621         $data = $page->get('rating');
622         if ($rating == -1)
623             unset($data[$dimension][$userid]);
624         else {
625             if (empty($data[$dimension]))
626                 $data[$dimension] = array($userid => (float)$rating);
627             else
628                 $data[$dimension][$userid] = (float)$rating;
629         }
630         $page->set('rating', $data);
631     }
632
633 }
634
635 /*
636 class RatingsDB_backend_PearDB
637 extends WikiDB_backend_PearDB {
638     function get_rating($dimension=null, $rater=null, $ratee=null,
639                         $orderby=null, $pageinfo = "ratee") {
640         $result = $this->_get_rating_result(
641                          $dimension, $rater, $ratee, $orderby, $pageinfo);
642         return new WikiDB_backend_PearDB_generic_iter($this, $result);
643     }
644
645     function get_users_rated($dimension=null, $orderby=null) {
646         $result = $this->_get_users_rated_result(
647                          $dimension, $orderby);
648         return new WikiDB_backend_PearDB_generic_iter($this, $result);
649     }
650
651     function get_rating_page($dimension=null, $rater=null, $ratee=null,
652                              $orderby=null, $pageinfo = "ratee") {
653         $result = $this->_get_rating_result(
654                          $dimension, $rater, $ratee, $orderby, $pageinfo);
655         return new WikiDB_backend_PearDB_iter($this, $result);
656     }
657
658     function _get_rating_result($dimension=null, $rater=null, $ratee=null,
659                                 $orderby=null, $pageinfo = "ratee") {
660         // pageinfo must be 'rater' or 'ratee'
661         if (($pageinfo != "ratee") && ($pageinfo != "rater"))
662             return;
663
664         $dbh = &$this->_dbh;
665         extract($this->_table_names);
666
667         $where = "WHERE r." . $pageinfo . "page = p.id";
668         if (isset($dimension)) {
669             $where .= " AND dimension=$dimension";
670         }
671         if (isset($rater)) {
672             $raterid = $this->_get_pageid($rater, true);
673             $where .= " AND raterpage=$raterid";
674         }
675         if (isset($ratee)) {
676             if(is_array($ratee)){
677                 $where .= " AND (";
678                 for($i = 0; $i < count($ratee); $i++){
679                     $rateeid = $this->_get_pageid($ratee[$i], true);
680                     $where .= "rateepage=$rateeid";
681                     if($i != (count($ratee) - 1)){
682                         $where .= " OR ";
683                     }
684                 }
685                 $where .= ")";
686             } else {
687                 $rateeid = $this->_get_pageid($ratee, true);
688                 $where .= " AND rateepage=$rateeid";
689             }
690         }
691
692         $orderbyStr = "";
693         if (isset($orderby)) {
694             $orderbyStr = " ORDER BY " . $orderby;
695         }
696
697         $query = "SELECT *"
698             . " FROM $rating_tbl r, $page_tbl p "
699             . $where
700             . $orderbyStr;
701
702         $result = $dbh->query($query);
703
704         return $result;
705     }
706
707     function _get_users_rated_result($dimension=null, $orderby=null) {
708         $dbh = &$this->_dbh;
709         extract($this->_table_names);
710
711         $where = "WHERE p.id=r.raterpage";
712         if (isset($dimension)) {
713             $where .= " AND dimension=$dimension";
714         }
715         $orderbyStr = "";
716         if (isset($orderby)) {
717             $orderbyStr = " ORDER BY " . $orderby;
718         }
719
720         $query = "SELECT DISTINCT p.pagename"
721             . " FROM $rating_tbl r, $page_tbl p "
722             . $where
723             . $orderbyStr;
724
725         $result = $dbh->query($query);
726
727         return $result;
728     }
729     function delete_rating($rater, $ratee, $dimension) {
730         $dbh = &$this->_dbh;
731         extract($this->_table_names);
732
733         $this->lock();
734         $raterid = $this->_get_pageid($rater, true);
735         $rateeid = $this->_get_pageid($ratee, true);
736
737         $dbh->query("DELETE FROM $rating_tbl WHERE raterpage=$raterid and rateepage=$rateeid and dimension=$dimension");
738         $this->unlock();
739         return true;
740     }
741
742     function rate($rater, $ratee, $rateeversion, $dimension, $rating, $isPrivate = 'no') {
743         $dbh = &$this->_dbh;
744         extract($this->_table_names);
745
746         $this->lock();
747         $raterid = $this->_get_pageid($rater, true);
748         $rateeid = $this->_get_pageid($ratee, true);
749
750         $dbh->query("DELETE FROM $rating_tbl WHERE raterpage=$raterid and rateepage=$rateeid and dimension=$dimension and isPrivate='$isPrivate'");
751         // NOTE: Leave tstamp off the insert, and MySQL automatically updates it
752         $dbh->query("INSERT INTO $rating_tbl (dimension, raterpage, rateepage, ratingvalue, rateeversion, isPrivate) VALUES ($dimension, $raterid, $rateeid, $rating, $rateeversion, '$isPrivate')");
753         $this->unlock();
754         return true;
755     }
756 }
757 */
758
759 // Local Variables:
760 // mode: php
761 // tab-width: 8
762 // c-basic-offset: 4
763 // c-hanging-comment-ender-p: nil
764 // indent-tabs-mode: nil
765 // End: