source: branches/1.2/workflow/inc/class.CachedLDAP.inc.php @ 1349

Revision 1349, 11.0 KB checked in by niltonneto, 15 years ago (diff)

Ticket #561 - Inclusão do módulo Workflow faltante nessa versão.

Line 
1<?php
2/**************************************************************************\
3* eGroupWare                                                               *
4* http://www.egroupware.org                                                *
5* --------------------------------------------                             *
6*  This program is free software; you can redistribute it and/or modify it *
7*  under the terms of the GNU General Public License as published by the   *
8*  Free Software Foundation; either version 2 of the License, or (at your  *
9*  option) any later version.                                              *
10\**************************************************************************/
11
12/**
13* Gera um cache do LDAP (em banco de dados) para não perder informações no caso de exclusão de um funcionário
14* @author Sidnei Augusto Drovetto Junior - drovetto@gmail.com
15* @version 1.0
16* @license http://www.gnu.org/copyleft/gpl.html GPL
17* @package Workflow
18*/
19class CachedLDAP
20{
21        /**
22        * @var int $OPERATION_MODE_NORMAL Modo de operação normal (acessa primeiro o BD e, se necessário, acessa o LDAP e atualiza o BD)
23        * @access public
24        */
25        public $OPERATION_MODE_NORMAL = 0;
26
27        /**
28        * @var int $OPERATION_MODE_LDAP Modo de operação LDAP (acessa o LDAP e atualiza o BD)
29        * @access public
30        */
31        public $OPERATION_MODE_LDAP = 1;
32
33        /**
34        * @var int $OPERATION_MODE_DATABASE Modo de operação banco de dados (acessa somente o BD)
35        * @access public
36        */
37        public $OPERATION_MODE_DATABASE = 2;
38
39        /**
40        * @var int $OPERATION_MODE_LDAP_DATABASE Modo de operação LDAP e banco de dados. Acessa primeiro o LDAP e, somente se o usuário não existir no LDAP que o banco de dados será consultado.
41        * @access public
42        */
43        public $OPERATION_MODE_LDAP_DATABASE = 3;
44
45        /**
46        * @var string $userContext Contexto do usuário (LDAP)
47        * @access protected
48        */
49        protected $userContext;
50
51        /**
52        * @var string $groupContext Contexto do grupo (LDAP)
53        * @access protected
54        */
55        protected $groupContext;
56
57        /**
58        * @var resource $dataSource Conexão com o LDAP
59        * @access protected
60        */
61        protected $dataSource;
62
63        /**
64        * @var int $operationMode Modo de operação da classe
65        * @access private
66        */
67        private $operationMode;
68
69        /**
70        * @var array $entryAttributes Os atributos que serão buscados (LDAP ou Banco de Dados)
71        * @access private
72        */
73        private $entryAttributes = array('uid', 'cn', 'givenname', 'mail', 'sn', 'accountstatus', 'uidnumber', 'dn', 'employeenumber', 'cpf', 'telephonenumber');
74
75        /**
76        * @var resource $DBLink Link com o banco de dados
77        * @access protected
78        */
79        protected $DBLink = null;
80
81        /**
82        * @var int $cacheDays O número de dias antes do cache ser renovado
83        * @access private
84        */
85        private $cacheDays = 5;
86
87        /**
88        * Estabelece uma conexão com o LDAP
89        * @return void
90        * @access protected
91        */
92        protected function loadLDAP()
93        {
94                /* check if the information was already loaded */
95                if (!empty($this->userContext))
96                        return;
97
98                /* load the information and establish a connection */
99                $tmpLDAP = &$GLOBALS['workflow']['factory']->getInstance('WorkflowLDAP');
100                $this->userContext  = $tmpLDAP->getUserContext();
101                $this->groupContext = $tmpLDAP->getGroupContext();
102                $this->dataSource = &$GLOBALS['workflow']['workflowObjects']->getLDAP();
103        }
104
105        /**
106        * Estabelece uma conexão com o Banco de Dados
107        * @return void
108        * @access protected
109        */
110        protected function loadDB()
111        {
112                /* check if the information was already loaded */
113                if (!is_null($this->DBLink))
114                        return;
115
116                /* establish a connection */
117                $this->DBLink = &$GLOBALS['workflow']['workflowObjects']->getDBGalaxia()->Link_ID;
118        }
119
120        /**
121        * Executa uma query no LDAP e, retorna o seu resultado
122        * @param string $ldapQuery A query do LDAP que será executada
123        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
124        * @access private
125        */
126        private function runLDAP($ldapQuery)
127        {
128                /* load the information and establish the connection */
129                $this->loadLDAP();
130
131                /* perform the search */
132                $resourceIdentifier = ldap_search($this->dataSource, $this->userContext, $ldapQuery, $this->entryAttributes);
133                $entries = ldap_get_entries($this->dataSource, $resourceIdentifier);
134
135                /* check the returned data */
136                if ($entries['count'] != 1)
137                        return false;
138
139                /* format the output */
140                $output = array();
141                foreach ($this->entryAttributes as $attribute)
142                        if ($attribute == 'dn')
143                                $output[$attribute] = $entries[0][$attribute];
144                        else
145                                $output[$attribute] = $entries[0][$attribute][0];
146
147                /* insert the timestamp of the last update */
148                $output['last_update'] = mktime();
149
150                return $output;
151        }
152
153        /**
154        * Executa uma query no Banco de Dados para encontrar um usuário
155        * @param string $bdQuery A cláusula WHERE da query
156        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query
157        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
158        * @access private
159        */
160        private function runBD($bdQuery, $bindVariables)
161        {
162                /* establish the connection */
163                $this->loadDB();
164
165                /* perform the search */
166                $resultSet = $this->DBLink->query('SELECT ' . implode(', ', $this->entryAttributes) . ', EXTRACT(EPOCH FROM last_update) AS last_update FROM egw_wf_user_cache WHERE ' . $bdQuery, $bindVariables);
167
168                return $resultSet->fetchRow();
169        }
170
171        /**
172        * Atualiza, em Banco de Dados, os atributos de um usuário
173        * @param mixed $entry Uma array associativa contendo os atributos de um usuário (pode ser um boolean false)
174        * @param string $bdQuery A cláusula WHERE da query
175        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query
176        * @return void
177        * @access private
178        */
179        private function updateDB($entry, $bdQuery, $bindVariables)
180        {
181                /* establish the connection */
182                $this->loadDB();
183
184
185                if ($entry == false)
186                {
187                        /* the user doesn't exist in LDAP anymore */
188                        $this->DBLink->query('UPDATE egw_wf_user_cache SET last_update = NULL WHERE ' . $bdQuery, $bindVariables);
189                }
190                else
191                {
192                        /* unset the timestamp */
193                        unset($entry['last_update']);
194
195                        /* insert/update the user info */
196                        $this->DBLink->query('DELETE FROM egw_wf_user_cache WHERE (uidnumber = ?)', array($entry['uidnumber']));
197                        $this->DBLink->query('INSERT INTO egw_wf_user_cache (' . implode(', ', array_keys($entry)) . ') VALUES (' . implode(', ', array_fill(0, count($entry), '?')) . ')', array_values($entry));
198                }
199        }
200
201        /**
202        * Faz a busca pelo usuário. Levando-se em conta o modo de operação selecionado
203        * @param string $ldapQuery A query do LDAP que será executada
204        * @param string $bdQuery A cláusula WHERE da query (se for utilizado o Banco de Dados)
205        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query de Banco de Dados
206        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
207        * @access private
208        */
209        private function run($ldapQuery, $bdQuery, $bindVariables)
210        {
211                /* LDAP operation mode: load the user info in LDAP and then update the user info in the Database */
212                if (($this->operationMode == $this->OPERATION_MODE_LDAP) || ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE))
213                {
214                        $entry = $this->runLDAP($ldapQuery);
215                        $this->updateDB($entry, $bdQuery, $bindVariables);
216
217                        /* return only the LDAP info when in LDAP operation mode, or if the user was found (when using the LDAP_DATABASE operation mode) */
218                        if (($this->operationMode == $this->OPERATION_MODE_LDAP) || (($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE) && ($entry !== false)))
219                                return $entry;
220                }
221
222                /* load the user information from the Database */
223                $entry = $this->runBD($bdQuery, $bindVariables);
224
225                /* return the database info when in LDAP_DATABASE operation mode (since the user wasn't found in the LDAP) */
226                if ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE)
227                        return $entry;
228
229                /* normal operation mode: verify if the information in the Database is still valid; otherwise check it in LDAP */
230                if ($this->operationMode == $this->OPERATION_MODE_NORMAL)
231                {
232                        /* if the user was found in the Database and if the user doesn't exist in LDAP anymore or the information is updated, then return the info. Otherwise update it with LDAP info */
233                        if (($entry !== false) && ((is_null($entry['last_update'])) || (($entry['last_update'] + ($this->cacheDays * 24 * 60 * 60)) > mktime())))
234                                return $entry;
235
236                        /* we need to load info from the LDAP and update the Database record */
237                        $newEntry = $this->runLDAP($ldapQuery);
238                        $this->updateDB($newEntry, $bdQuery, $bindVariables);
239
240                        /* return the information from LDAP if the user was found; otherwise return the entry from the database */
241                        if ($newEntry !== false)
242                                return $newEntry;
243                        else
244                                return $entry;
245                }
246
247                return $entry;
248        }
249
250        /**
251        * Construtor da classe CachedLDAP
252        * @return object Objeto da classe CachedLDAP
253        * @access public
254        */
255        function CachedLDAP()
256        {
257                /* set the default operation mode */
258                $this->setOperationMode($this->OPERATION_MODE_NORMAL);
259        }
260
261        /**
262        * Define o modo como a classe vai operar (se busca somente no LDAP, no Banco de Dados, etc.)
263        * @param int $operationMode O modo de operação da classe
264        * @return void
265        * @access public
266        */
267        function setOperationMode($operationMode)
268        {
269                /* make sure it's an integer */
270                $operationMode = (int) $operationMode;
271                $availableOptions = array(
272                        $this->OPERATION_MODE_LDAP,
273                        $this->OPERATION_MODE_DATABASE,
274                        $this->OPERATION_MODE_NORMAL,
275                        $this->OPERATION_MODE_LDAP_DATABASE);
276
277                /* check if the value is valid and set it */
278                if (in_array($operationMode, $availableOptions, true))
279                        $this->operationMode = $operationMode;
280        }
281
282        /**
283        * Prepara os parâmetros para buscar o usuário
284        * @param string $field O nome do campo pelo qual a busca será feita
285        * @param string $value O valor que será utilizao na busca
286        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
287        * @access private
288        */
289        private function getEntry($field, $value)
290        {
291                /* build the queries */
292                $ldapQuery = "(&({$field}={$value})(phpgwaccounttype=u))";
293                $bdQuery = "({$field} = ?)";
294                $bindVariables = array($value);
295
296                return $this->run($ldapQuery, $bdQuery, $bindVariables);
297        }
298
299        /**
300        * Busca um usuário pelo seu ID
301        * @param int $userID O ID do usuário
302        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
303        * @access public
304        */
305        function getEntryByID($userID)
306        {
307                return $this->getEntry('uidnumber', (int) $userID);
308        }
309
310        /**
311        * Busca um usuário pelo seu CPF
312        * @param string $CPF O CPF do usuário
313        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
314        * @access public
315        */
316        function getEntryByCPF($CPF)
317        {
318                return $this->getEntry('cpf', $CPF);
319        }
320
321        /**
322        * Busca um usuário pelo seu e-mail
323        * @param string $email O e-mail do usuário
324        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
325        * @access public
326        */
327        function getEntryByEmail($email)
328        {
329                return $this->getEntry('mail', $email);
330        }
331
332        /**
333        * Busca um usuário pela sua matrícula
334        * @param int $employNumber A matrícula do usuário
335        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
336        * @access public
337        */
338        function getEntryByEmployeeNumber($employNumber)
339        {
340                return $this->getEntry('employeenumber', (int) $employNumber);
341        }
342}
343?>
Note: See TracBrowser for help on using the repository browser.