3 * Copyright 2007 Reini Urban
5 * This file is part of PhpWiki.
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.
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.
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.
23 * Ad-hoc support for an RDF-Triple search in our link database.
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.
32 * This is mostly here for testing, very slow.
35 * @see WikiDB_backend::link_search
38 class WikiDB_backend_dumb_LinkSearchIter
39 extends WikiDB_backend_iterator
41 function WikiDB_backend_dumb_LinkSearchIter(&$backend, &$pageiter, $search, $linktype,
42 $relation = false, $options = array())
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';
60 if ($linktype == 'attribute') {
61 $this->_want_relations = true;
62 $this->_field = 'attribute';
64 if ($linktype == 'linkfrom') {
65 $this->_reverse = true;
70 // iterate a nested page-links loop. there will be multiple results per page.
71 // we must keep the page iter internally.
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;
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']);
90 return array('pagename' => $page,
91 'linkvalue' => $link['linkvalue']);
94 // no links on this page anymore.
98 // initialize the links also
101 unset($this->_links);
102 if (!($next = $this->_pages->next()))
104 $this->_page = $next['pagename'];
105 while (!($this->_links = $this->_get_links($this->_page))) {
106 if (!($next = $this->_pages->next()))
108 $this->_page = $next['pagename'];
113 // get the links of each page in advance
114 function _get_links($pagename)
117 if ($this->linktype == 'attribute') {
118 $page = $this->_dbi->getPage($pagename);
119 $attribs = $page->get('attributes');
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 separate search object.
125 if (!$this->search->match($value)) continue;
126 $links[] = array('pagename' => $pagename,
127 'linkname' => $attribute,
128 'linkvalue' => $value);
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
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'])
149 // check hash values, with/out want_relations
150 $links[] = array('pagename' => $pagename,
151 'linkname' => $this->_want_relations ? $link['linkrelation'] : '',
152 'linkvalue' => $link['pagename']);
161 $this->_page = false;
162 unset($this->_links);
163 $this->_pages->free();
171 // c-hanging-comment-ender-p: nil
172 // indent-tabs-mode: nil