5100704d |
1 | <?php |
2 | |
3 | /** |
4 | ** addressbook.php |
5 | ** |
6 | ** Functions and classes for the addressbook system. |
7 | ** |
8 | **/ |
9 | |
10 | $addressbook_php = true; |
11 | |
12 | // Include backends here. |
13 | include("../functions/abook_local_file.php"); |
14 | include("../functions/abook_ldap_server.php"); |
15 | |
16 | // Create and initialize an addressbook object. |
17 | // Returns the created object |
0d273153 |
18 | function addressbook_init($showerr = true, $onlylocal = false) { |
5100704d |
19 | global $data_dir, $username, $ldap_server; |
20 | |
21 | // Create a new addressbook object |
22 | $abook = new AddressBook; |
23 | |
24 | // Always add a local backend |
25 | $filename = sprintf("%s%s.abook", $data_dir, $username); |
26 | $r = $abook->add_backend("local_file", Array("filename" => $filename, |
27 | "create" => true)); |
0d273153 |
28 | if(!$r && $showerr) { |
1e62e50e |
29 | printf(_("Error opening file %s"), $filename); |
5100704d |
30 | exit; |
31 | } |
0d273153 |
32 | |
33 | if($onlylocal) |
34 | return $abook; |
5100704d |
35 | |
36 | // Load configured LDAP servers |
37 | reset($ldap_server); |
799b9070 |
38 | while(list($key,$param) = each($ldap_server)) { |
39 | if(is_array($param)) { |
40 | $r = $abook->add_backend("ldap_server", $param); |
0d273153 |
41 | if(!$r && $showerr) { |
799b9070 |
42 | printf(" "._("Error initializing LDAP server %s:")."<BR>\n", |
43 | $param["host"]); |
44 | printf(" ".$abook->error); |
45 | exit; |
46 | } |
47 | } |
48 | } |
5100704d |
49 | |
50 | // Return the initialized object |
51 | return $abook; |
52 | } |
53 | |
54 | |
55 | |
56 | /** |
57 | ** This is the main address book class that connect all the |
58 | ** backends and provide services to the functions above. |
59 | ** |
60 | **/ |
61 | class AddressBook { |
62 | var $backends = array(); |
63 | var $numbackends = 0; |
64 | var $error = ""; |
ce916cdf |
65 | var $localbackend = 0; |
5100704d |
66 | |
67 | // Constructor function. |
68 | function AddressBook() { |
69 | } |
70 | |
71 | // Return an array of backends of a given type, |
72 | // or all backends if no type is specified. |
73 | function get_backend_list($type = "") { |
74 | $ret = array(); |
75 | for($i = 1 ; $i <= $this->numbackends ; $i++) { |
76 | if(empty($type) || $type == $this->backends[$i]->btype) { |
77 | array_push($ret, &$this->backends[$i]); |
78 | } |
79 | } |
80 | return $ret; |
81 | } |
82 | |
83 | |
84 | // ========================== Public ======================== |
85 | |
86 | // Add a new backend. $backend is the name of a backend |
87 | // (without the abook_ prefix), and $param is an optional |
88 | // mixed variable that is passed to the backend constructor. |
89 | // See each of the backend classes for valid parameters. |
90 | function add_backend($backend, $param = "") { |
91 | $backend_name = "abook_".$backend; |
92 | eval("\$newback = new $backend_name(\$param);"); |
93 | if(!empty($newback->error)) { |
94 | $this->error = $newback->error; |
95 | return false; |
96 | } |
97 | |
98 | $this->numbackends++; |
99 | |
100 | $newback->bnum = $this->numbackends; |
101 | $this->backends[$this->numbackends] = $newback; |
ce916cdf |
102 | |
103 | // Store ID of first local backend added |
104 | if($this->localbackend == 0 && $newback->btype == "local") |
105 | $this->localbackend = $this->numbackends; |
106 | |
5100704d |
107 | return $this->numbackends; |
108 | } |
109 | |
110 | |
111 | // Return a list of addresses matching expression in |
112 | // all backends of a given type. |
113 | function search($expression, $btype = "") { |
114 | $ret = array(); |
0d273153 |
115 | $this->error = ""; |
5100704d |
116 | |
117 | $sel = $this->get_backend_list($btype); |
0d273153 |
118 | $failed = 0; |
5100704d |
119 | for($i = 0 ; $i < sizeof($sel) ; $i++) { |
120 | $backend = &$sel[$i]; |
121 | $backend->error = ""; |
122 | $res = $backend->search($expression); |
123 | if(is_array($res)) { |
124 | $ret = array_merge($ret, $res); |
125 | } else { |
0d273153 |
126 | $this->error = $this->error . "<br>\n". $backend->error; |
127 | $failed++; |
5100704d |
128 | } |
129 | } |
130 | |
0d273153 |
131 | // Only fail if all backends failed |
132 | if($failed >= sizeof($sel)) |
133 | return false; |
134 | |
5100704d |
135 | return $ret; |
136 | } |
137 | |
138 | |
139 | // Return a sorted search |
140 | function s_search($expression, $btype = "") { |
0d273153 |
141 | |
5100704d |
142 | $ret = $this->search($expression, $btype); |
0d273153 |
143 | if(!is_array($ret)) |
144 | return $ret; |
5100704d |
145 | |
146 | // Inline function - Not nice, but still.. |
147 | function cmp($a,$b) { |
148 | if($a["backend"] > $b["backend"]) |
149 | return 1; |
150 | else if($a["backend"] < $b["backend"]) |
151 | return -1; |
152 | |
153 | return (strtolower($a["name"]) > strtolower($b["name"])) ? 1 : -1; |
154 | } |
155 | |
156 | usort($ret, 'cmp'); |
157 | return $ret; |
158 | } |
159 | |
160 | |
161 | // Lookup an address by alias. Only possible in |
162 | // local backends. |
163 | function lookup($alias) { |
164 | $ret = array(); |
165 | |
166 | $sel = $this->get_backend_list("local"); |
167 | for($i = 0 ; $i < sizeof($sel) ; $i++) { |
168 | $backend = &$sel[$i]; |
169 | $backend->error = ""; |
170 | $res = $backend->lookup($alias); |
171 | if(is_array($res)) { |
172 | return $res; |
173 | } else { |
174 | $this->error = $backend->error; |
175 | return false; |
176 | } |
177 | } |
178 | |
179 | return $ret; |
180 | } |
181 | |
182 | |
183 | // Return all addresses |
184 | function list_addr() { |
185 | $ret = array(); |
186 | |
187 | $sel = $this->get_backend_list("local"); |
188 | for($i = 0 ; $i < sizeof($sel) ; $i++) { |
189 | $backend = &$sel[$i]; |
190 | $backend->error = ""; |
191 | $res = $backend->list_addr(); |
192 | if(is_array($res)) { |
193 | $ret = array_merge($ret, $res); |
194 | } else { |
195 | $this->error = $backend->error; |
196 | return false; |
197 | } |
198 | } |
199 | |
200 | return $ret; |
201 | } |
202 | |
203 | |
204 | // Create a new address from $userdata, in backend $bnum. |
205 | // Return the backend number that the/ address was added |
206 | // to, or false if it failed. |
207 | function add($userdata, $bnum) { |
208 | |
209 | // Validate data |
210 | if(!is_array($userdata)) { |
211 | $this->error = _("Invalid input data"); |
212 | return false; |
213 | } |
cca9bc69 |
214 | if(empty($userdata["firstname"]) && |
5100704d |
215 | empty($userdata["lastname"])) { |
216 | $this->error = _("Name is missing"); |
217 | return false; |
218 | } |
219 | if(empty($userdata["email"])) { |
220 | $this->error = _("E-mail address is missing"); |
221 | return false; |
222 | } |
223 | if(empty($userdata["nickname"])) { |
224 | $userdata["nickname"] = $userdata["email"]; |
225 | } |
226 | |
227 | // Check that specified backend accept new entries |
228 | if(!$this->backends[$bnum]->writeable) { |
1e62e50e |
229 | $this->error = _("Addressbook is read-only"); |
5100704d |
230 | return false; |
231 | } |
232 | |
233 | // Add address to backend |
234 | $res = $this->backends[$bnum]->add($userdata); |
235 | if($res) { |
236 | return $bnum; |
237 | } else { |
238 | $this->error = $this->backends[$bnum]->error; |
239 | return false; |
240 | } |
241 | |
242 | return false; // Not reached |
243 | } |
244 | |
245 | } |
246 | |
247 | |
248 | /** |
249 | ** Generic backend that all other backends extend |
250 | **/ |
251 | class addressbook_backend { |
252 | |
253 | // Variables that all backends must provide. |
254 | var $btype = "dummy"; |
255 | var $bname = "dummy"; |
256 | var $sname = "Dummy backend"; |
257 | |
258 | // Variables common for all backends, but that |
259 | // should not be changed by the backends. |
260 | var $bnum = -1; |
261 | var $error = ""; |
262 | var $writeable = false; |
263 | |
264 | function set_error($string) { |
265 | $this->error = "[" . $this->sname . "] " . $string; |
266 | return false; |
267 | } |
268 | |
269 | |
270 | // ========================== Public ======================== |
271 | |
272 | function search($expression) { |
273 | $this->set_error("search not implemented"); |
274 | return false; |
275 | } |
276 | |
277 | function lookup($alias) { |
278 | $this->set_error("lookup not implemented"); |
279 | return false; |
280 | } |
281 | |
282 | function list_addr() { |
283 | $this->set_error("list_addr not implemented"); |
284 | return false; |
285 | } |
286 | |
287 | function add($userdata) { |
288 | $this->set_error("add not implemented"); |
289 | return false; |
290 | } |
291 | |
292 | } |
293 | |
294 | ?> |