xref: /dokuwiki/lib/plugins/authpdo/auth.php (revision 70a89417b85aed070861be4f936ffa8844eb63dd)
1f64dbc90SAndreas Gohr<?php
2f64dbc90SAndreas Gohr/**
3f64dbc90SAndreas Gohr * DokuWiki Plugin authpdo (Auth Component)
4f64dbc90SAndreas Gohr *
5f64dbc90SAndreas Gohr * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6f64dbc90SAndreas Gohr * @author  Andreas Gohr <andi@splitbrain.org>
7f64dbc90SAndreas Gohr */
8f64dbc90SAndreas Gohr
9f64dbc90SAndreas Gohr// must be run within Dokuwiki
10f64dbc90SAndreas Gohrif(!defined('DOKU_INC')) die();
11f64dbc90SAndreas Gohr
12f64dbc90SAndreas Gohrclass auth_plugin_authpdo extends DokuWiki_Auth_Plugin {
13f64dbc90SAndreas Gohr
14f64dbc90SAndreas Gohr    /** @var PDO */
15f64dbc90SAndreas Gohr    protected $pdo;
16f64dbc90SAndreas Gohr
17f64dbc90SAndreas Gohr    /**
18f64dbc90SAndreas Gohr     * Constructor.
19f64dbc90SAndreas Gohr     */
20f64dbc90SAndreas Gohr    public function __construct() {
21f64dbc90SAndreas Gohr        parent::__construct(); // for compatibility
22f64dbc90SAndreas Gohr
23f64dbc90SAndreas Gohr        if(!class_exists('PDO')) {
24f64dbc90SAndreas Gohr            $this->_debug('PDO extension for PHP not found.', -1, __LINE__);
25f64dbc90SAndreas Gohr            $this->success = false;
26f64dbc90SAndreas Gohr            return;
27f64dbc90SAndreas Gohr        }
28f64dbc90SAndreas Gohr
29f64dbc90SAndreas Gohr        if(!$this->getConf('dsn')) {
30f64dbc90SAndreas Gohr            $this->_debug('No DSN specified', -1, __LINE__);
31f64dbc90SAndreas Gohr            $this->success = false;
32f64dbc90SAndreas Gohr            return;
33f64dbc90SAndreas Gohr        }
34f64dbc90SAndreas Gohr
35f64dbc90SAndreas Gohr        try {
36f64dbc90SAndreas Gohr            $this->pdo = new PDO(
37f64dbc90SAndreas Gohr                $this->getConf('dsn'),
38f64dbc90SAndreas Gohr                $this->getConf('user'),
39f64dbc90SAndreas Gohr                $this->getConf('pass'),
40f64dbc90SAndreas Gohr                array(
41*70a89417SAndreas Gohr                    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // always fetch as array
42*70a89417SAndreas Gohr                    PDO::ATTR_EMULATE_PREPARES => true, // emulating prepares allows us to reuse param names
43f64dbc90SAndreas Gohr                )
44f64dbc90SAndreas Gohr            );
45f64dbc90SAndreas Gohr        } catch(PDOException $e) {
46f64dbc90SAndreas Gohr            $this->_debug($e);
47f64dbc90SAndreas Gohr            $this->success = false;
48f64dbc90SAndreas Gohr            return;
49f64dbc90SAndreas Gohr        }
50f64dbc90SAndreas Gohr
51f64dbc90SAndreas Gohr        // FIXME set capabilities accordingly
52f64dbc90SAndreas Gohr        //$this->cando['addUser']     = false; // can Users be created?
53f64dbc90SAndreas Gohr        //$this->cando['delUser']     = false; // can Users be deleted?
54f64dbc90SAndreas Gohr        //$this->cando['modLogin']    = false; // can login names be changed?
55f64dbc90SAndreas Gohr        //$this->cando['modPass']     = false; // can passwords be changed?
56f64dbc90SAndreas Gohr        //$this->cando['modName']     = false; // can real names be changed?
57f64dbc90SAndreas Gohr        //$this->cando['modMail']     = false; // can emails be changed?
58f64dbc90SAndreas Gohr        //$this->cando['modGroups']   = false; // can groups be changed?
59f64dbc90SAndreas Gohr        //$this->cando['getUsers']    = false; // can a (filtered) list of users be retrieved?
60f64dbc90SAndreas Gohr        //$this->cando['getUserCount']= false; // can the number of users be retrieved?
61f64dbc90SAndreas Gohr        //$this->cando['getGroups']   = false; // can a list of available groups be retrieved?
62f64dbc90SAndreas Gohr        //$this->cando['external']    = false; // does the module do external auth checking?
63f64dbc90SAndreas Gohr        //$this->cando['logout']      = true; // can the user logout again? (eg. not possible with HTTP auth)
64f64dbc90SAndreas Gohr
65f64dbc90SAndreas Gohr        // FIXME intialize your auth system and set success to true, if successful
66f64dbc90SAndreas Gohr        $this->success = true;
67f64dbc90SAndreas Gohr    }
68f64dbc90SAndreas Gohr
69f64dbc90SAndreas Gohr    /**
70f64dbc90SAndreas Gohr     * Check user+password
71f64dbc90SAndreas Gohr     *
72f64dbc90SAndreas Gohr     * May be ommited if trustExternal is used.
73f64dbc90SAndreas Gohr     *
74f64dbc90SAndreas Gohr     * @param   string $user the user name
75f64dbc90SAndreas Gohr     * @param   string $pass the clear text password
76f64dbc90SAndreas Gohr     * @return  bool
77f64dbc90SAndreas Gohr     */
78f64dbc90SAndreas Gohr    public function checkPass($user, $pass) {
79f64dbc90SAndreas Gohr
80f64dbc90SAndreas Gohr        $data = $this->_selectUser($user);
81f64dbc90SAndreas Gohr        if($data == false) return false;
82f64dbc90SAndreas Gohr
83f64dbc90SAndreas Gohr        if(isset($data['hash'])) {
84f64dbc90SAndreas Gohr            // hashed password
85f64dbc90SAndreas Gohr            $passhash = new PassHash();
86f64dbc90SAndreas Gohr            return $passhash->verify_hash($pass, $data['hash']);
87f64dbc90SAndreas Gohr        } else {
88f64dbc90SAndreas Gohr            // clear text password in the database O_o
89f64dbc90SAndreas Gohr            return ($pass == $data['clear']);
90f64dbc90SAndreas Gohr        }
91f64dbc90SAndreas Gohr    }
92f64dbc90SAndreas Gohr
93f64dbc90SAndreas Gohr    /**
94f64dbc90SAndreas Gohr     * Return user info
95f64dbc90SAndreas Gohr     *
96f64dbc90SAndreas Gohr     * Returns info about the given user needs to contain
97f64dbc90SAndreas Gohr     * at least these fields:
98f64dbc90SAndreas Gohr     *
99f64dbc90SAndreas Gohr     * name string  full name of the user
100f64dbc90SAndreas Gohr     * mail string  email addres of the user
101f64dbc90SAndreas Gohr     * grps array   list of groups the user is in
102f64dbc90SAndreas Gohr     *
103f64dbc90SAndreas Gohr     * @param   string $user the user name
104f64dbc90SAndreas Gohr     * @param   bool $requireGroups whether or not the returned data must include groups
105f64dbc90SAndreas Gohr     * @return array containing user data or false
106f64dbc90SAndreas Gohr     */
107f64dbc90SAndreas Gohr    public function getUserData($user, $requireGroups = true) {
108f64dbc90SAndreas Gohr        $data = $this->_selectUser($user);
109f64dbc90SAndreas Gohr        if($data == false) return false;
110f64dbc90SAndreas Gohr
111*70a89417SAndreas Gohr        if(isset($data['hash'])) unset($data['hash']);
112*70a89417SAndreas Gohr        if(isset($data['clean'])) unset($data['clean']);
113f64dbc90SAndreas Gohr
114*70a89417SAndreas Gohr        if($requireGroups) {
115*70a89417SAndreas Gohr            $data['grps'] = $this->_selectUserGroups($data);
116f64dbc90SAndreas Gohr        }
117f64dbc90SAndreas Gohr
118f64dbc90SAndreas Gohr        return $data;
119f64dbc90SAndreas Gohr    }
120f64dbc90SAndreas Gohr
121f64dbc90SAndreas Gohr
122f64dbc90SAndreas Gohr    /**
123f64dbc90SAndreas Gohr     * Create a new User [implement only where required/possible]
124f64dbc90SAndreas Gohr     *
125f64dbc90SAndreas Gohr     * Returns false if the user already exists, null when an error
126f64dbc90SAndreas Gohr     * occurred and true if everything went well.
127f64dbc90SAndreas Gohr     *
128f64dbc90SAndreas Gohr     * The new user HAS TO be added to the default group by this
129f64dbc90SAndreas Gohr     * function!
130f64dbc90SAndreas Gohr     *
131f64dbc90SAndreas Gohr     * Set addUser capability when implemented
132f64dbc90SAndreas Gohr     *
133f64dbc90SAndreas Gohr     * @param  string $user
134f64dbc90SAndreas Gohr     * @param  string $pass
135f64dbc90SAndreas Gohr     * @param  string $name
136f64dbc90SAndreas Gohr     * @param  string $mail
137f64dbc90SAndreas Gohr     * @param  null|array $grps
138f64dbc90SAndreas Gohr     * @return bool|null
139f64dbc90SAndreas Gohr     */
140f64dbc90SAndreas Gohr    //public function createUser($user, $pass, $name, $mail, $grps = null) {
141f64dbc90SAndreas Gohr    // FIXME implement
142f64dbc90SAndreas Gohr    //    return null;
143f64dbc90SAndreas Gohr    //}
144f64dbc90SAndreas Gohr
145f64dbc90SAndreas Gohr    /**
146f64dbc90SAndreas Gohr     * Modify user data [implement only where required/possible]
147f64dbc90SAndreas Gohr     *
148f64dbc90SAndreas Gohr     * Set the mod* capabilities according to the implemented features
149f64dbc90SAndreas Gohr     *
150f64dbc90SAndreas Gohr     * @param   string $user nick of the user to be changed
151f64dbc90SAndreas Gohr     * @param   array $changes array of field/value pairs to be changed (password will be clear text)
152f64dbc90SAndreas Gohr     * @return  bool
153f64dbc90SAndreas Gohr     */
154f64dbc90SAndreas Gohr    //public function modifyUser($user, $changes) {
155f64dbc90SAndreas Gohr    // FIXME implement
156f64dbc90SAndreas Gohr    //    return false;
157f64dbc90SAndreas Gohr    //}
158f64dbc90SAndreas Gohr
159f64dbc90SAndreas Gohr    /**
160f64dbc90SAndreas Gohr     * Delete one or more users [implement only where required/possible]
161f64dbc90SAndreas Gohr     *
162f64dbc90SAndreas Gohr     * Set delUser capability when implemented
163f64dbc90SAndreas Gohr     *
164f64dbc90SAndreas Gohr     * @param   array $users
165f64dbc90SAndreas Gohr     * @return  int    number of users deleted
166f64dbc90SAndreas Gohr     */
167f64dbc90SAndreas Gohr    //public function deleteUsers($users) {
168f64dbc90SAndreas Gohr    // FIXME implement
169f64dbc90SAndreas Gohr    //    return false;
170f64dbc90SAndreas Gohr    //}
171f64dbc90SAndreas Gohr
172f64dbc90SAndreas Gohr    /**
173f64dbc90SAndreas Gohr     * Bulk retrieval of user data [implement only where required/possible]
174f64dbc90SAndreas Gohr     *
175f64dbc90SAndreas Gohr     * Set getUsers capability when implemented
176f64dbc90SAndreas Gohr     *
177f64dbc90SAndreas Gohr     * @param   int $start index of first user to be returned
178f64dbc90SAndreas Gohr     * @param   int $limit max number of users to be returned
179f64dbc90SAndreas Gohr     * @param   array $filter array of field/pattern pairs, null for no filter
180f64dbc90SAndreas Gohr     * @return  array list of userinfo (refer getUserData for internal userinfo details)
181f64dbc90SAndreas Gohr     */
182f64dbc90SAndreas Gohr    //public function retrieveUsers($start = 0, $limit = -1, $filter = null) {
183f64dbc90SAndreas Gohr    // FIXME implement
184f64dbc90SAndreas Gohr    //    return array();
185f64dbc90SAndreas Gohr    //}
186f64dbc90SAndreas Gohr
187f64dbc90SAndreas Gohr    /**
188f64dbc90SAndreas Gohr     * Return a count of the number of user which meet $filter criteria
189f64dbc90SAndreas Gohr     * [should be implemented whenever retrieveUsers is implemented]
190f64dbc90SAndreas Gohr     *
191f64dbc90SAndreas Gohr     * Set getUserCount capability when implemented
192f64dbc90SAndreas Gohr     *
193f64dbc90SAndreas Gohr     * @param  array $filter array of field/pattern pairs, empty array for no filter
194f64dbc90SAndreas Gohr     * @return int
195f64dbc90SAndreas Gohr     */
196f64dbc90SAndreas Gohr    //public function getUserCount($filter = array()) {
197f64dbc90SAndreas Gohr    // FIXME implement
198f64dbc90SAndreas Gohr    //    return 0;
199f64dbc90SAndreas Gohr    //}
200f64dbc90SAndreas Gohr
201f64dbc90SAndreas Gohr    /**
202f64dbc90SAndreas Gohr     * Define a group [implement only where required/possible]
203f64dbc90SAndreas Gohr     *
204f64dbc90SAndreas Gohr     * Set addGroup capability when implemented
205f64dbc90SAndreas Gohr     *
206f64dbc90SAndreas Gohr     * @param   string $group
207f64dbc90SAndreas Gohr     * @return  bool
208f64dbc90SAndreas Gohr     */
209f64dbc90SAndreas Gohr    //public function addGroup($group) {
210f64dbc90SAndreas Gohr    // FIXME implement
211f64dbc90SAndreas Gohr    //    return false;
212f64dbc90SAndreas Gohr    //}
213f64dbc90SAndreas Gohr
214f64dbc90SAndreas Gohr    /**
215f64dbc90SAndreas Gohr     * Retrieve groups [implement only where required/possible]
216f64dbc90SAndreas Gohr     *
217f64dbc90SAndreas Gohr     * Set getGroups capability when implemented
218f64dbc90SAndreas Gohr     *
219f64dbc90SAndreas Gohr     * @param   int $start
220f64dbc90SAndreas Gohr     * @param   int $limit
221f64dbc90SAndreas Gohr     * @return  array
222f64dbc90SAndreas Gohr     */
223f64dbc90SAndreas Gohr    //public function retrieveGroups($start = 0, $limit = 0) {
224f64dbc90SAndreas Gohr    // FIXME implement
225f64dbc90SAndreas Gohr    //    return array();
226f64dbc90SAndreas Gohr    //}
227f64dbc90SAndreas Gohr
228f64dbc90SAndreas Gohr    /**
229f64dbc90SAndreas Gohr     * Return case sensitivity of the backend
230f64dbc90SAndreas Gohr     *
231f64dbc90SAndreas Gohr     * When your backend is caseinsensitive (eg. you can login with USER and
232f64dbc90SAndreas Gohr     * user) then you need to overwrite this method and return false
233f64dbc90SAndreas Gohr     *
234f64dbc90SAndreas Gohr     * @return bool
235f64dbc90SAndreas Gohr     */
236f64dbc90SAndreas Gohr    public function isCaseSensitive() {
237f64dbc90SAndreas Gohr        return true;
238f64dbc90SAndreas Gohr    }
239f64dbc90SAndreas Gohr
240f64dbc90SAndreas Gohr    /**
241f64dbc90SAndreas Gohr     * Sanitize a given username
242f64dbc90SAndreas Gohr     *
243f64dbc90SAndreas Gohr     * This function is applied to any user name that is given to
244f64dbc90SAndreas Gohr     * the backend and should also be applied to any user name within
245f64dbc90SAndreas Gohr     * the backend before returning it somewhere.
246f64dbc90SAndreas Gohr     *
247f64dbc90SAndreas Gohr     * This should be used to enforce username restrictions.
248f64dbc90SAndreas Gohr     *
249f64dbc90SAndreas Gohr     * @param string $user username
250f64dbc90SAndreas Gohr     * @return string the cleaned username
251f64dbc90SAndreas Gohr     */
252f64dbc90SAndreas Gohr    public function cleanUser($user) {
253f64dbc90SAndreas Gohr        return $user;
254f64dbc90SAndreas Gohr    }
255f64dbc90SAndreas Gohr
256f64dbc90SAndreas Gohr    /**
257f64dbc90SAndreas Gohr     * Sanitize a given groupname
258f64dbc90SAndreas Gohr     *
259f64dbc90SAndreas Gohr     * This function is applied to any groupname that is given to
260f64dbc90SAndreas Gohr     * the backend and should also be applied to any groupname within
261f64dbc90SAndreas Gohr     * the backend before returning it somewhere.
262f64dbc90SAndreas Gohr     *
263f64dbc90SAndreas Gohr     * This should be used to enforce groupname restrictions.
264f64dbc90SAndreas Gohr     *
265f64dbc90SAndreas Gohr     * Groupnames are to be passed without a leading '@' here.
266f64dbc90SAndreas Gohr     *
267f64dbc90SAndreas Gohr     * @param  string $group groupname
268f64dbc90SAndreas Gohr     * @return string the cleaned groupname
269f64dbc90SAndreas Gohr     */
270f64dbc90SAndreas Gohr    public function cleanGroup($group) {
271f64dbc90SAndreas Gohr        return $group;
272f64dbc90SAndreas Gohr    }
273f64dbc90SAndreas Gohr
274f64dbc90SAndreas Gohr    /**
275f64dbc90SAndreas Gohr     * Check Session Cache validity [implement only where required/possible]
276f64dbc90SAndreas Gohr     *
277f64dbc90SAndreas Gohr     * DokuWiki caches user info in the user's session for the timespan defined
278f64dbc90SAndreas Gohr     * in $conf['auth_security_timeout'].
279f64dbc90SAndreas Gohr     *
280f64dbc90SAndreas Gohr     * This makes sure slow authentication backends do not slow down DokuWiki.
281f64dbc90SAndreas Gohr     * This also means that changes to the user database will not be reflected
282f64dbc90SAndreas Gohr     * on currently logged in users.
283f64dbc90SAndreas Gohr     *
284f64dbc90SAndreas Gohr     * To accommodate for this, the user manager plugin will touch a reference
285f64dbc90SAndreas Gohr     * file whenever a change is submitted. This function compares the filetime
286f64dbc90SAndreas Gohr     * of this reference file with the time stored in the session.
287f64dbc90SAndreas Gohr     *
288f64dbc90SAndreas Gohr     * This reference file mechanism does not reflect changes done directly in
289f64dbc90SAndreas Gohr     * the backend's database through other means than the user manager plugin.
290f64dbc90SAndreas Gohr     *
291f64dbc90SAndreas Gohr     * Fast backends might want to return always false, to force rechecks on
292f64dbc90SAndreas Gohr     * each page load. Others might want to use their own checking here. If
293f64dbc90SAndreas Gohr     * unsure, do not override.
294f64dbc90SAndreas Gohr     *
295f64dbc90SAndreas Gohr     * @param  string $user - The username
296f64dbc90SAndreas Gohr     * @return bool
297f64dbc90SAndreas Gohr     */
298f64dbc90SAndreas Gohr    //public function useSessionCache($user) {
299f64dbc90SAndreas Gohr    // FIXME implement
300f64dbc90SAndreas Gohr    //}
301f64dbc90SAndreas Gohr
302f64dbc90SAndreas Gohr    /**
303f64dbc90SAndreas Gohr     * Select data of a specified user
304f64dbc90SAndreas Gohr     *
305f64dbc90SAndreas Gohr     * @param $user
306f64dbc90SAndreas Gohr     * @return bool|array
307f64dbc90SAndreas Gohr     */
308f64dbc90SAndreas Gohr    protected function _selectUser($user) {
309f64dbc90SAndreas Gohr        $sql = $this->getConf('select-user');
310f64dbc90SAndreas Gohr
311*70a89417SAndreas Gohr        $result = $this->query($sql, array(':user' => $user));
312*70a89417SAndreas Gohr        if(!$result) return false;
313f64dbc90SAndreas Gohr
314*70a89417SAndreas Gohr        if(count($result) > 1) {
315f64dbc90SAndreas Gohr            $this->_debug('Found more than one matching user', -1, __LINE__);
316f64dbc90SAndreas Gohr            return false;
317f64dbc90SAndreas Gohr        }
318f64dbc90SAndreas Gohr
319f64dbc90SAndreas Gohr        $data = array_shift($result);
320f64dbc90SAndreas Gohr        $dataok = true;
321f64dbc90SAndreas Gohr
322f64dbc90SAndreas Gohr        if(!isset($data['user'])) {
323f64dbc90SAndreas Gohr            $this->_debug("Statement did not return 'user' attribute", -1, __LINE__);
324f64dbc90SAndreas Gohr            $dataok = false;
325f64dbc90SAndreas Gohr        }
326f64dbc90SAndreas Gohr        if(!isset($data['hash']) && !isset($data['clear'])) {
327f64dbc90SAndreas Gohr            $this->_debug("Statement did not return 'clear' or 'hash' attribute", -1, __LINE__);
328f64dbc90SAndreas Gohr            $dataok = false;
329f64dbc90SAndreas Gohr        }
330f64dbc90SAndreas Gohr        if(!isset($data['name'])) {
331f64dbc90SAndreas Gohr            $this->_debug("Statement did not return 'name' attribute", -1, __LINE__);
332f64dbc90SAndreas Gohr            $dataok = false;
333f64dbc90SAndreas Gohr        }
334f64dbc90SAndreas Gohr        if(!isset($data['mail'])) {
335f64dbc90SAndreas Gohr            $this->_debug("Statement did not return 'mail' attribute", -1, __LINE__);
336f64dbc90SAndreas Gohr            $dataok = false;
337f64dbc90SAndreas Gohr        }
338f64dbc90SAndreas Gohr
339f64dbc90SAndreas Gohr        if(!$dataok) return false;
340f64dbc90SAndreas Gohr        return $data;
341f64dbc90SAndreas Gohr    }
342f64dbc90SAndreas Gohr
343f64dbc90SAndreas Gohr    /**
344*70a89417SAndreas Gohr     * Select all groups of a user
345*70a89417SAndreas Gohr     *
346*70a89417SAndreas Gohr     * @param array $userdata The userdata as returned by _selectUser()
347*70a89417SAndreas Gohr     * @return array
348*70a89417SAndreas Gohr     */
349*70a89417SAndreas Gohr    protected function _selectUserGroups($userdata) {
350*70a89417SAndreas Gohr        global $conf;
351*70a89417SAndreas Gohr        $sql = $this->getConf('select-user-groups');
352*70a89417SAndreas Gohr
353*70a89417SAndreas Gohr        $result = $this->query($sql, $userdata);
354*70a89417SAndreas Gohr
355*70a89417SAndreas Gohr        $groups = array($conf['defaultgroup']); // always add default config
356*70a89417SAndreas Gohr        if($result) foreach($result as $row) {
357*70a89417SAndreas Gohr            if(!isset($row['group'])) continue;
358*70a89417SAndreas Gohr            $groups[] = $row['group'];
359*70a89417SAndreas Gohr        }
360*70a89417SAndreas Gohr
361*70a89417SAndreas Gohr        $groups = array_unique($groups);
362*70a89417SAndreas Gohr        sort($groups);
363*70a89417SAndreas Gohr        return $groups;
364*70a89417SAndreas Gohr    }
365*70a89417SAndreas Gohr
366*70a89417SAndreas Gohr    /**
367*70a89417SAndreas Gohr     * Executes a query
368*70a89417SAndreas Gohr     *
369*70a89417SAndreas Gohr     * @param string $sql The SQL statement to execute
370*70a89417SAndreas Gohr     * @param array $arguments Named parameters to be used in the statement
371*70a89417SAndreas Gohr     * @return array|bool The result as associative array
372*70a89417SAndreas Gohr     */
373*70a89417SAndreas Gohr    protected function query($sql, $arguments) {
374*70a89417SAndreas Gohr        // prepare parameters - we only use those that exist in the SQL
375*70a89417SAndreas Gohr        $params = array();
376*70a89417SAndreas Gohr        foreach($arguments as $key => $value) {
377*70a89417SAndreas Gohr            if(is_array($value)) continue;
378*70a89417SAndreas Gohr            if(is_object($value)) continue;
379*70a89417SAndreas Gohr            if($key[0] != ':') $key = ":$key"; // prefix with colon if needed
380*70a89417SAndreas Gohr            if(strpos($sql, $key) !== false) $params[$key] = $value;
381*70a89417SAndreas Gohr        }
382*70a89417SAndreas Gohr
383*70a89417SAndreas Gohr        // execute
384*70a89417SAndreas Gohr        try {
385*70a89417SAndreas Gohr            $sth = $this->pdo->prepare($sql);
386*70a89417SAndreas Gohr            $sth->execute($params);
387*70a89417SAndreas Gohr            $result = $sth->fetchAll();
388*70a89417SAndreas Gohr            if((int) $sth->errorCode()) {
389*70a89417SAndreas Gohr                $this->_debug(join(' ',$sth->errorInfo()), -1, __LINE__);
390*70a89417SAndreas Gohr                $result = false;
391*70a89417SAndreas Gohr            }
392*70a89417SAndreas Gohr            $sth->closeCursor();
393*70a89417SAndreas Gohr            $sth = null;
394*70a89417SAndreas Gohr        } catch(PDOException $e) {
395*70a89417SAndreas Gohr            $this->_debug($e);
396*70a89417SAndreas Gohr            $result = false;
397*70a89417SAndreas Gohr        }
398*70a89417SAndreas Gohr        return $result;
399*70a89417SAndreas Gohr    }
400*70a89417SAndreas Gohr
401*70a89417SAndreas Gohr
402*70a89417SAndreas Gohr    /**
403f64dbc90SAndreas Gohr     * Wrapper around msg() but outputs only when debug is enabled
404f64dbc90SAndreas Gohr     *
405f64dbc90SAndreas Gohr     * @param string|Exception $message
406f64dbc90SAndreas Gohr     * @param int $err
407f64dbc90SAndreas Gohr     * @param int $line
408f64dbc90SAndreas Gohr     */
409f64dbc90SAndreas Gohr    protected function _debug($message, $err = 0, $line = 0) {
410f64dbc90SAndreas Gohr        if(!$this->getConf('debug')) return;
411f64dbc90SAndreas Gohr        if(is_a($message, 'Exception')) {
412f64dbc90SAndreas Gohr            $err = -1;
413f64dbc90SAndreas Gohr            $line = $message->getLine();
414f64dbc90SAndreas Gohr            $msg = $message->getMessage();
415f64dbc90SAndreas Gohr        } else {
416f64dbc90SAndreas Gohr            $msg = $message;
417f64dbc90SAndreas Gohr        }
418f64dbc90SAndreas Gohr
419f64dbc90SAndreas Gohr        if(defined('DOKU_UNITTEST')) {
420f64dbc90SAndreas Gohr            printf("\n%s, %s:%d\n", $msg, __FILE__, $line);
421f64dbc90SAndreas Gohr        } else {
422f64dbc90SAndreas Gohr            msg('authpdo: ' . $msg, $err, $line, __FILE__);
423f64dbc90SAndreas Gohr        }
424f64dbc90SAndreas Gohr    }
425f64dbc90SAndreas Gohr}
426f64dbc90SAndreas Gohr
427f64dbc90SAndreas Gohr// vim:ts=4:sw=4:et:
428