]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/SqlResult.php
function run: @return mixed
[SourceForge/phpwiki.git] / lib / plugin / SqlResult.php
1 <?php
2
3 /*
4  * Copyright 2004 $ThePhpWikiProgrammingTeam
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 along
19  * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 /**
24  * This plugin displays results of arbitrary SQL select statements
25  * in table form.
26  * The database definition, the DSN, must be defined in the local file
27  * config/SqlResult.ini
28  *   A simple textfile with alias = dsn lines.
29  *
30  * Optional template file to format the result and handle some logic.
31  * Template vars: %%where%%, %%sortby%%, %%limit%%
32  * TODO: paging
33  *
34  * Usage:
35  *   <<SqlResult alias=mysql
36  *            SELECT 'mysql password for string "xx":',
37  *                   PASSWORD('xx')
38  *   >>
39  *   <<SqlResult alias=videos template=videos
40  *            SELECT rating,title,date
41  *                   FROM video
42  *                   ORDER BY rating DESC
43  *                   LIMIT 5
44  *   >>
45  *   <<SqlResult alias=imdb template=imdbmovies where||="Davies, Jeremy%"
46  *   SELECT m.title, m.date, n.name, c.role
47  *     FROM movies as m, names as n, jobs as j, characters as c
48  *     WHERE n.name LIKE "%%where%%"
49  *     AND m.title_id = c.title_id
50  *     AND n.name_id = c.name_id
51  *     AND c.job_id = j.job_id
52  *     AND j.description = 'Actor'
53  *     ORDER BY m.date DESC
54  *   >>
55  *
56  * @author: ReiniUrban
57  */
58
59 require_once 'lib/PageList.php';
60
61 class WikiPlugin_SqlResult
62     extends WikiPlugin
63 {
64     public $_args;
65
66     function getDescription()
67     {
68         return _("Display arbitrary SQL result tables.");
69     }
70
71     function getDefaultArguments()
72     {
73         return array(
74             'alias' => false, // DSN database specification
75             'ordered' => false, // if to display as <ol> list: single col only without template
76             'template' => false, // use a custom <theme>/template.tmpl
77             'where' => false, // custom filter for the query
78             'sortby' => false, // for paging, default none
79             'limit' => "0,50", // for paging, default: only the first 50
80         );
81     }
82
83     function getDsn($alias)
84     {
85         $ini = parse_ini_file(FindFile("config/SqlResult.ini"));
86         return $ini[$alias];
87     }
88
89     /** Get the SQL statement from the rest of the lines
90      */
91     function handle_plugin_args_cruft($argstr, $args)
92     {
93         $this->_sql = str_replace("\n", " ", $argstr);
94     }
95
96     /**
97      * @param WikiDB $dbi
98      * @param string $argstr
99      * @param WikiRequest $request
100      * @param string $basepage
101      * @return mixed
102      */
103     function run($dbi, $argstr, &$request, $basepage)
104     {
105         global $DBParams;
106         //$request->setArg('nocache','1');
107         extract($this->getArgs($argstr, $request));
108         if (!$alias)
109             return $this->error(_("No DSN alias for SqlResult.ini specified"));
110         $sql = $this->_sql;
111
112         // apply custom filters
113         if ($where and strstr($sql, "%%where%%"))
114             $sql = str_replace("%%where%%", $where, $sql);
115         // TODO: use a SQL construction library?
116         if ($limit) {
117             $pagelist = new PageList();
118             $limit = $pagelist->limit($limit);
119             if (strstr($sql, "%%limit%%"))
120                 $sql = str_replace("%%limit%%", $limit, $sql);
121             else {
122                 if (strstr($sql, "LIMIT"))
123                     $sql = preg_replace("/LIMIT\s+[\d,]+\s+/m", "LIMIT " . $limit . " ", $sql);
124             }
125         }
126         if (strstr($sql, "%%sortby%%")) {
127             if (!$sortby)
128                 $sql = preg_replace("/ORDER BY .*%%sortby%%\s/m", "", $sql);
129             else
130                 $sql = str_replace("%%sortby%%", $sortby, $sql);
131         } elseif (PageList::sortby($sortby, 'db')) { // add sorting: support paging sortby links
132             if (preg_match("/\sORDER\s/", $sql))
133                 $sql = preg_replace("/ORDER BY\s\S+\s/m", "ORDER BY " . PageList::sortby($sortby, 'db'), $sql);
134             else
135                 $sql .= " ORDER BY " . PageList::sortby($sortby, 'db');
136         }
137
138         $inidsn = $this->getDsn($alias);
139         if (!$inidsn)
140             return $this->error(sprintf(_("No DSN for alias %s in SqlResult.ini found"),
141                 $alias));
142         // adodb or pear? adodb as default, since we distribute per default it.
143         // for pear there may be overrides.
144         // TODO: native PDO support (for now we use ADODB)
145         if ($DBParams['dbtype'] == 'SQL') {
146             $dbh = DB::connect($inidsn);
147             $all = $dbh->getAll($sql);
148             if (DB::isError($all)) {
149                 return $this->error($all->getMessage() . ' ' . $all->userinfo);
150             }
151         } else { // unless PearDB use the included ADODB, regardless if dba, file or PDO, ...
152             if ($DBParams['dbtype'] != 'ADODB') {
153                 require_once 'lib/WikiDB/backend/ADODB.php';
154             }
155             $parsed = parseDSN($inidsn);
156             $dbh = &ADONewConnection($parsed['phptype']);
157             $conn = $dbh->Connect($parsed['hostspec'], $parsed['username'],
158                 $parsed['password'], $parsed['database']);
159             if (!$conn)
160                 return $this->error($dbh->errorMsg());
161             $GLOBALS['ADODB_FETCH_MODE'] = ADODB_FETCH_ASSOC;
162             $dbh->SetFetchMode(ADODB_FETCH_ASSOC);
163
164             $all = $dbh->getAll($sql);
165
166             $GLOBALS['ADODB_FETCH_MODE'] = ADODB_FETCH_NUM;
167             $dbh->SetFetchMode(ADODB_FETCH_NUM);
168             if (!$all)
169                 return $this->error($dbh->errorMsg());
170         }
171         $args = array();
172         if ($limit) { // fill paging vars (see PageList)
173             $args = $pagelist->pagingTokens(count($all), count($all[0]), $limit);
174             if (!$args) $args = array();
175         }
176
177         if ($template) {
178             $args = array_merge(
179                 array('SqlResult' => $all, // the resulting array of rows
180                     'ordered' => $ordered, // whether to display as <ul>/<dt> or <ol>
181                     'where' => $where,
182                     'sortby' => $sortby,
183                     'limit' => $limit),
184                 $args); // paging params override given params
185             return Template($template, $args);
186         } else {
187             if ($ordered) {
188                 $html = HTML::ol(array('class' => 'sqlresult'));
189                 if ($all)
190                     foreach ($all as $row) {
191                         $html->pushContent(HTML::li(array('class' => $i++ % 2 ? 'evenrow' : 'oddrow'), $row[0]));
192                     }
193             } else {
194                 $html = HTML::table(array('class' => 'sqlresult'));
195                 $i = 0;
196                 if ($all)
197                     foreach ($all as $row) {
198                         $tr = HTML::tr(array('class' => $i++ % 2 ? 'evenrow' : 'oddrow'));
199                         if ($row)
200                             foreach ($row as $col) {
201                                 $tr->pushContent(HTML::td($col));
202                             }
203                         $html->pushContent($tr);
204                     }
205             }
206         }
207         // do paging via pagelink template
208         if (!empty($args['NUMPAGES'])) {
209             $paging = Template("pagelink", $args);
210             $html = $table->pushContent(HTML::thead($paging),
211                 HTML::tbody($html),
212                 HTML::tfoot($paging));
213         }
214         if (0 and DEBUG) { // test deferred error/warning/notice collapsing
215             trigger_error("test notice", E_USER_NOTICE);
216             trigger_error("test warning", E_USER_WARNING);
217         }
218
219         return $html;
220     }
221
222 }
223
224 // Local Variables:
225 // mode: php
226 // tab-width: 8
227 // c-basic-offset: 4
228 // c-hanging-comment-ender-p: nil
229 // indent-tabs-mode: nil
230 // End: