source: trunk/workflow/inc/class.CachedLDAP.inc.php @ 3275

Revision 3275, 12.2 KB checked in by pereira.jair, 14 years ago (diff)

Ticket #1186 - Removido da query de INSERT na cachedLDAP as colunas mobile e homePhone

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 array $entryAttributesLDAP Attributes thats only exists in LDAP.
77         * The attributes mobile and homePhone are not present in databaseCache, because they may have more
78         * This is not the very best approach because the best solution should be store all attributes
79         * from Ldap into databaseCache
80         * than one value
81         * @access private
82         * */
83        private $entryAttributesLDAP = array('mobile','homephone');
84
85        /**
86        * @var resource $DBLink Link com o banco de dados
87        * @access protected
88        */
89        protected $DBLink = null;
90
91        /**
92        * @var int $cacheDays O número de dias antes do cache ser renovado
93        * @access private
94        */
95        private $cacheDays = 2;
96
97        /**
98        * Estabelece uma conexão com o LDAP
99        * @return void
100        * @access protected
101        */
102        protected function loadLDAP()
103        {
104                /* check if the information was already loaded */
105                if (!empty($this->userContext))
106                        return;
107
108                /* load the information and establish a connection */
109                $tmpLDAP =& Factory::getInstance('WorkflowLDAP');
110                $this->userContext  = $tmpLDAP->getUserContext();
111                $this->groupContext = $tmpLDAP->getGroupContext();
112                $this->dataSource =& Factory::getInstance('WorkflowObjects')->getLDAP();
113        }
114
115        /**
116        * Estabelece uma conexão com o Banco de Dados
117        * @return void
118        * @access protected
119        */
120        protected function loadDB()
121        {
122                /* check if the information was already loaded */
123                if (!is_null($this->DBLink))
124                        return;
125
126                /* establish a connection */
127                $this->DBLink =& Factory::getInstance('WorkflowObjects')->getDBGalaxia()->Link_ID;
128        }
129
130        /**
131        * Executa uma query no LDAP e, retorna o seu resultado
132        * @param string $ldapQuery A query do LDAP que será executada
133        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
134        * @access private
135        */
136        private function runLDAP($ldapQuery)
137        {
138                /* load the information and establish the connection */
139                $this->loadLDAP();
140
141                $ldapfields = array();
142
143                // Merge the arrays os attributes from databaseCache and Ldap
144                $ldapfields = array_merge($this->entryAttributes,$this->entryAttributesLDAP);
145
146                /* perform the search */
147                $resourceIdentifier = ldap_search($this->dataSource, $this->userContext, $ldapQuery, $ldapfields);
148                $entries = ldap_get_entries($this->dataSource, $resourceIdentifier);
149
150                /* check the returned data */
151                if ($entries['count'] != 1)
152                        return false;
153
154                /* format the output */
155                $output = array();
156                foreach ($ldapfields as $attribute)
157                        if ($attribute == 'dn' or $attribute == 'mobile' or $attribute == 'homePhone')
158                                // Retrieve all occurrencies of mobile and homePhone
159                                $output[$attribute] = $entries[0][$attribute];
160                        else
161                                // Retrieve first occurrence of other attributes
162                                $output[$attribute] = $entries[0][$attribute][0];
163
164                /* insert the timestamp of the last update */
165                $output['last_update'] = mktime();
166
167                return $output;
168        }
169
170        /**
171        * Executa uma query no Banco de Dados para encontrar um usuário
172        * @param string $bdQuery A cláusula WHERE da query
173        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query
174        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
175        * @access private
176        */
177        private function runBD($bdQuery, $bindVariables)
178        {
179                /* establish the connection */
180                $this->loadDB();
181
182                /* perform the search */
183                $resultSet = $this->DBLink->query('SELECT ' . implode(', ', $this->entryAttributes) . ', EXTRACT(EPOCH FROM last_update) AS last_update FROM egw_wf_user_cache WHERE ' . $bdQuery, $bindVariables);
184
185                return $resultSet->fetchRow();
186        }
187
188        /**
189        * Atualiza, em Banco de Dados, os atributos de um usuário
190        * @param mixed $entry Uma array associativa contendo os atributos de um usuário (pode ser um boolean false)
191        * @param string $bdQuery A cláusula WHERE da query
192        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query
193        * @return void
194        * @access private
195        */
196        private function updateDB($entry, $bdQuery, $bindVariables)
197        {
198                /* establish the connection */
199                $this->loadDB();
200
201
202                if ($entry == false)
203                {
204                        /* the user doesn't exist in LDAP anymore */
205                        $this->DBLink->query('UPDATE egw_wf_user_cache SET last_update = NULL WHERE ' . $bdQuery, $bindVariables);
206                }
207                else
208                {
209                        /* unset the timestamp */
210                        unset($entry['last_update']);
211                       
212                        //UNSET ALL THE ATRIBUTES THAT WILL NOT BE STORAGED IN DB.
213                        foreach ($this->entryAttributesLDAP as $unsetAttribute) {
214                                unset($entry[$unsetAttribute]);
215                        }
216
217                        /* insert/update the user info */
218                        $this->DBLink->query('DELETE FROM egw_wf_user_cache WHERE (uidnumber = ?)', array($entry['uidnumber']));
219                        $this->DBLink->query('INSERT INTO egw_wf_user_cache (' . implode(', ', array_keys($entry)) . ') VALUES (' . implode(', ', array_fill(0, count($entry), '?')) . ')', array_values($entry));
220                }
221        }
222
223        /**
224        * Faz a busca pelo usuário. Levando-se em conta o modo de operação selecionado
225        * @param string $ldapQuery A query do LDAP que será executada
226        * @param string $bdQuery A cláusula WHERE da query (se for utilizado o Banco de Dados)
227        * @param array $bindVariables Valores que substituirão o pontos de interrogação na query de Banco de Dados
228        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
229        * @access private
230        */
231        private function run($ldapQuery, $bdQuery, $bindVariables)
232        {
233                /* LDAP operation mode: load the user info in LDAP and then update the user info in the Database */
234                if (($this->operationMode == $this->OPERATION_MODE_LDAP) || ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE))
235                {
236                        $entry = $this->runLDAP($ldapQuery);
237                        $this->updateDB($entry, $bdQuery, $bindVariables);
238
239                        /* return only the LDAP info when in LDAP operation mode, or if the user was found (when using the LDAP_DATABASE operation mode) */
240                        if (($this->operationMode == $this->OPERATION_MODE_LDAP) || (($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE) && ($entry !== false)))
241                                return $entry;
242                }
243
244                /* load the user information from the Database */
245                $entry = $this->runBD($bdQuery, $bindVariables);
246
247                /* return the database info when in LDAP_DATABASE operation mode (since the user wasn't found in the LDAP) */
248                if ($this->operationMode == $this->OPERATION_MODE_LDAP_DATABASE)
249                        return $entry;
250
251                /* normal operation mode: verify if the information in the Database is still valid; otherwise check it in LDAP */
252                if ($this->operationMode == $this->OPERATION_MODE_NORMAL)
253                {
254                        /* 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 */
255                        if (($entry !== false) && ((is_null($entry['last_update'])) || (($entry['last_update'] + ($this->cacheDays * 24 * 60 * 60)) > mktime())))
256                                return $entry;
257
258                        /* we need to load info from the LDAP and update the Database record */
259                        $newEntry = $this->runLDAP($ldapQuery);
260                        $this->updateDB($newEntry, $bdQuery, $bindVariables);
261
262                        /* return the information from LDAP if the user was found; otherwise return the entry from the database */
263                        if ($newEntry !== false)
264                                return $newEntry;
265                        else
266                                return $entry;
267                }
268
269                return $entry;
270        }
271
272        /**
273        * Construtor da classe CachedLDAP
274        * @return object Objeto da classe CachedLDAP
275        * @access public
276        */
277        function CachedLDAP()
278        {
279                /* set the default operation mode */
280                $this->setOperationMode($this->OPERATION_MODE_NORMAL);
281        }
282
283        /**
284        * Define o modo como a classe vai operar (se busca somente no LDAP, no Banco de Dados, etc.)
285        * @param int $operationMode O modo de operação da classe
286        * @return void
287        * @access public
288        */
289        function setOperationMode($operationMode)
290        {
291                /* make sure it's an integer */
292                $operationMode = (int) $operationMode;
293                $availableOptions = array(
294                        $this->OPERATION_MODE_LDAP,
295                        $this->OPERATION_MODE_DATABASE,
296                        $this->OPERATION_MODE_NORMAL,
297                        $this->OPERATION_MODE_LDAP_DATABASE);
298
299                /* check if the value is valid and set it */
300                if (in_array($operationMode, $availableOptions, true))
301                        $this->operationMode = $operationMode;
302        }
303
304        /**
305        * Prepara os parâmetros para buscar o usuário
306        * @param string $field O nome do campo pelo qual a busca será feita
307        * @param string $value O valor que será utilizao na busca
308        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
309        * @access private
310        */
311        private function getEntry($field, $value)
312        {
313                /* build the queries */
314                $ldapQuery = "(&({$field}={$value})(phpgwaccounttype=u))";
315                $bdQuery = "({$field} = ?)";
316                $bindVariables = array($value);
317
318                return $this->run($ldapQuery, $bdQuery, $bindVariables);
319        }
320
321        /**
322        * Busca um usuário pelo seu ID
323        * @param int $userID O ID 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 getEntryByID($userID)
328        {
329                return $this->getEntry('uidnumber', (int) $userID);
330        }
331
332        /**
333        * Busca um usuário pelo seu CPF
334        * @param string $CPF O CPF 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 getEntryByCPF($CPF)
339        {
340                return $this->getEntry('cpf', $CPF);
341        }
342
343        /**
344        * Busca um usuário pelo seu e-mail
345        * @param string $email O e-mail do usuário
346        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
347        * @access public
348        */
349        function getEntryByEmail($email)
350        {
351                return $this->getEntry('mail', $email);
352        }
353
354        /**
355        * Busca um usuário pela sua matrícula
356        * @param int $employNumber A matrícula do usuário
357        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
358        * @access public
359        */
360        function getEntryByEmployeeNumber($employNumber)
361        {
362                return $this->getEntry('employeenumber', (int) $employNumber);
363        }
364
365        /**
366        * Busca um usuário pelo seu uid
367        * @param string $uid O uid do usuário
368        * @return mixed Uma array associativa caso o usuário seja encontrado ou false caso contrário
369        * @access public
370        */
371        function getEntryByUid($uid)
372        {
373                return $this->getEntry('uid', $uid);
374        }
375
376}
377?>
Note: See TracBrowser for help on using the repository browser.