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