]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/backend/dumb/LinkSearchIter.php
Remove rcs_id
[SourceForge/phpwiki.git] / lib / WikiDB / backend / dumb / LinkSearchIter.php
1 <?php // -*-php-*-
2 // $Id$
3 /*
4  * Copyright 2007 Reini Urban
5  *
6  * This file is part of PhpWiki.
7  *
8  * PhpWiki is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * PhpWiki is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with PhpWiki; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /**
24  * Ad-hoc support for an RDF-Triple search in our link database.
25  *
26  * This iterator will work with any WikiDB_backend
27  * which has a working get_links() method with want_relation support.
28  * Currently we iterate over all pages, check for all matching links.
29  * As optimization a backend could iterate over the linktable instead
30  * and check the matching page there. There are most likely less links
31  * than pages and links are smaller than pages.
32  *
33  * This is mostly here for testing, very slow.
34  *
35  * @author Reini Urban
36  * @see WikiDB_backend::link_search
37  */
38
39 class WikiDB_backend_dumb_LinkSearchIter
40 extends WikiDB_backend_iterator
41 {
42     function WikiDB_backend_dumb_LinkSearchIter(&$backend, &$pageiter, $search, $linktype,
43                                                 $relation=false, $options=array())
44     {
45         $this->_backend  = &$backend;
46         $this->_pages    = $pageiter;
47         $this->search    = $search;   // search the linkvalue. it should be the value or pagename
48         $this->relation  = $relation; // limit the search to this linkname
49         $this->linktype  = $linktype;
50         $this->_reverse  = false;
51         $this->_want_relations = true;
52         $this->sortby  = isset($options['sortby'])  ? $options['sortby']  : '';
53         $this->limit   = isset($options['limit'])   ? $options['limit']   : '';
54         $this->exclude = isset($options['exclude']) ? $options['exclude'] : '';
55         $this->_field = 'pagename'; // the name of the linkvalue field to apply the search
56         $this->_dbi =& $GLOBALS['request']->_dbi;
57         if ($linktype == 'relation') {
58             $this->_want_relations = true;
59             $this->_field = 'linkrelation';
60         }
61         if ($linktype == 'attribute') {
62             $this->_want_relations = true;
63             $this->_field = 'attribute';
64         }
65         if ($linktype == 'linkfrom') {
66             $this->_reverse = true;
67         }
68         $this->_page = false;
69     }
70
71     // iterate a nested page-links loop. there will be multiple results per page.
72     // we must keep the page iter internally.
73     function next() {
74         while (1) {
75             if (!isset($this->_links) or count($this->_links) == 0) {
76                 $page = $this->_next_page(); // initialize all links of this page
77                 if (!$page) return false;
78             } else {
79                 $page = $this->_page;
80             }
81             // iterate the links. the links are pushed into the handy triple by _get_links
82             while ($link = array_shift($this->_links)) {
83                 // unmatching relations are already filtered out
84                 if ($this->search->match($link['linkvalue'])) { //pagename or attr-value
85                     if ($link['linkname'])
86                         return array('pagename' => $page,
87                                      'linkname' => $link['linkname'],
88                                      'linkvalue'=> $link['linkvalue']);
89                     else
90                         return array('pagename' => $page,
91                                      'linkvalue'=> $link['linkvalue']);
92                 }
93             }
94             // no links on this page anymore.
95         }
96     }
97
98     // initialize the links also
99     function _next_page() {
100         unset($this->_links);
101         if (!($next = $this->_pages->next()))
102             return false;
103         $this->_page = $next['pagename'];
104         while(!($this->_links = $this->_get_links($this->_page))) {
105             if (!($next = $this->_pages->next()))
106                 return false;
107             $this->_page = $next['pagename'];
108         }
109         return $this->_page;
110     }
111
112     // get the links of each page in advance
113     function _get_links($pagename) {
114         $links = array();
115         if ($this->linktype == 'attribute') {
116             $page = $this->_dbi->getPage($pagename);
117             $attribs = $page->get('attributes');
118             if ($attribs) {
119               foreach ($attribs as $attribute => $value) {
120                   if ($this->relation and !$this->relation->match($attribute)) continue;
121                   // The logical operator and unit unification (not yet) is encoded into
122                   // a seperate search object.
123                   if (!$this->search->match($value)) continue;
124                   $links[] = array('pagename'  => $pagename,
125                                    'linkname'  => $attribute,
126                                    'linkvalue' => $value);
127               }
128             }
129             unset($attribs);
130         } else {
131             $link_iter = $this->_backend->get_links($pagename, $this->_reverse, true,
132                                                     $this->sortby, $this->limit,
133                                                     $this->exclude, $this->_want_relations);
134             // we already stepped through all links. make use of that.
135             if ($this->_want_relations
136                 and isset($link_iter->_options['found_relations'])
137                 and $link_iter->_options['found_relations'] == 0)
138             {
139                 $link_iter->free();
140                 return $links;
141             }
142             while ($link = $link_iter->next()) {
143                 if (empty($link[$this->_field])) continue;
144                 if ($this->_want_relations and $this->relation
145                     and !$this->relation->match($link['linkrelation'])) continue;
146                 // check hash values, with/out want_relations
147                 $links[] = array('pagename'  => $pagename,
148                                  'linkname'  => $this->_want_relations ? $link['linkrelation'] : '',
149                                  'linkvalue' => $link['pagename']);
150             }
151             $link_iter->free();
152         }
153         return $links;
154     }
155
156     function free() {
157         $this->_page = false;
158         unset($this->_links);
159         $this->_pages->free();
160     }
161 }
162
163 // Local Variables:
164 // mode: php
165 // tab-width: 8
166 // c-basic-offset: 4
167 // c-hanging-comment-ender-p: nil
168 // indent-tabs-mode: nil
169 // End:
170
171 ?>