]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/backend/dumb/LinkSearchIter.php
Remove svn:keywords
[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         while (1) {
74         if (!isset($this->_links) or count($this->_links) == 0) {
75         $page = $this->_next_page(); // initialize all links of this page
76         if (!$page) return false;
77         } else {
78             $page = $this->_page;
79         }
80         // iterate the links. the links are pushed into the handy triple by _get_links
81         while ($link = array_shift($this->_links)) {
82         // unmatching relations are already filtered out
83         if ($this->search->match($link['linkvalue'])) { //pagename or attr-value
84             if ($link['linkname'])
85             return array('pagename' => $page,
86                      'linkname' => $link['linkname'],
87                      'linkvalue'=> $link['linkvalue']);
88             else
89             return array('pagename' => $page,
90                      'linkvalue'=> $link['linkvalue']);
91         }
92         }
93         // no links on this page anymore.
94         }
95     }
96
97     // initialize the links also
98     function _next_page() {
99     unset($this->_links);
100     if (!($next = $this->_pages->next()))
101         return false;
102     $this->_page = $next['pagename'];
103     while(!($this->_links = $this->_get_links($this->_page))) {
104         if (!($next = $this->_pages->next()))
105             return false;
106         $this->_page = $next['pagename'];
107     }
108     return $this->_page;
109     }
110
111     // get the links of each page in advance
112     function _get_links($pagename) {
113     $links = array();
114     if ($this->linktype == 'attribute') {
115         $page = $this->_dbi->getPage($pagename);
116         $attribs = $page->get('attributes');
117         if ($attribs) {
118           foreach ($attribs as $attribute => $value) {
119           if ($this->relation and !$this->relation->match($attribute)) continue;
120           // The logical operator and unit unification (not yet) is encoded into
121           // a seperate search object.
122           if (!$this->search->match($value)) continue;
123           $links[] = array('pagename'  => $pagename,
124                    'linkname'  => $attribute,
125                    'linkvalue' => $value);
126           }
127         }
128         unset($attribs);
129     } else {
130         $link_iter = $this->_backend->get_links($pagename, $this->_reverse, true,
131                             $this->sortby, $this->limit,
132                             $this->exclude, $this->_want_relations);
133         // we already stepped through all links. make use of that.
134         if ($this->_want_relations
135             and isset($link_iter->_options['found_relations'])
136         and $link_iter->_options['found_relations'] == 0)
137         {
138         $link_iter->free();
139         return $links;
140         }
141         while ($link = $link_iter->next()) {
142             if (empty($link[$this->_field])) continue;
143         if ($this->_want_relations and $this->relation
144             and !$this->relation->match($link['linkrelation'])) continue;
145         // check hash values, with/out want_relations
146         $links[] = array('pagename'  => $pagename,
147                          'linkname'  => $this->_want_relations ? $link['linkrelation'] : '',
148                  'linkvalue' => $link['pagename']);
149         }
150         $link_iter->free();
151     }
152     return $links;
153     }
154
155     function free() {
156     $this->_page = false;
157     unset($this->_links);
158         $this->_pages->free();
159     }
160 }
161
162 // Local Variables:
163 // mode: php
164 // tab-width: 8
165 // c-basic-offset: 4
166 // c-hanging-comment-ender-p: nil
167 // indent-tabs-mode: nil
168 // End:
169