5100704d |
1 | <?php |
2 | |
3 | /** |
4 | ** abook_local_file.php |
5 | ** |
6 | ** Backend for addressbook as a pipe separated file |
7 | ** |
8 | ** An array with the following elements must be passed to |
9 | ** the class constructor (elements marked ? are optional): |
10 | ** |
11 | ** filename => path to addressbook file |
12 | ** ? create => if true: file is created if it does not exist. |
13 | ** ? umask => umask set before opening file. |
14 | ** |
15 | ** NOTE. This class should not be used directly. Use the |
16 | ** "AddressBook" class instead. |
17 | **/ |
18 | |
19 | class abook_local_file extends addressbook_backend { |
20 | var $btype = "local"; |
21 | var $bname = "local_file"; |
22 | |
23 | var $filename = ""; |
24 | var $filehandle = 0; |
25 | var $create = false; |
26 | var $umask; |
27 | |
28 | // ========================== Private ======================= |
29 | |
30 | // Constructor |
31 | function abook_local_file($param) { |
32 | $this->sname = _("Personal address book"); |
33 | $this->umask = Umask(); |
34 | |
35 | if(is_array($param)) { |
36 | if(empty($param["filename"])) |
37 | return $this->set_error("Invalid parameters"); |
38 | if(!is_string($param["filename"])) |
39 | return $this->set_error($param["filename"] . ": ". |
40 | _("Not a file name")); |
41 | |
42 | $this->filename = $param["filename"]; |
43 | |
44 | if($param["create"]) |
45 | $this->create = true; |
46 | if(isset($param["umask"])) |
47 | $this->umask = $param["umask"]; |
48 | |
49 | $this->open(true); |
50 | } else { |
51 | $this->set_error(_("Invalid argument to constructor")); |
52 | } |
53 | } |
54 | |
55 | // Open the addressbook file and store the file pointer. |
56 | // Use $file as the file to open, or the class' own |
57 | // filename property. If $param is empty and file is |
58 | // open, do nothing. |
59 | function open($new = false) { |
60 | $this->error = ""; |
61 | $file = $this->filename; |
62 | $create = $this->create; |
63 | |
64 | // Return true is file is open and $new is unset |
65 | if($this->filehandle && !$new) |
66 | return true; |
67 | |
68 | // Check that new file exitsts |
69 | if((!(file_exists($file) && is_readable($file))) && !$create) |
70 | return $this->set_error("$file: " . |
71 | _("No such file or directory")); |
72 | |
73 | // Close old file, if any |
74 | if($this->filehandle) $this->close(); |
75 | |
76 | // Open file. First try to open for reading and writing, |
77 | // but fall back to read only. |
78 | umask($this->umask); |
79 | $fh = @fopen($file, "a+"); |
80 | if($fh) { |
81 | $this->filehandle = &$fh; |
82 | $this->filename = $file; |
83 | $this->writeable = true; |
84 | } else { |
85 | $fh = @fopen($file, "r"); |
86 | if($fh) { |
87 | $this->filehandle = &$fh; |
88 | $this->filename = $file; |
89 | $this->writeable = false; |
90 | } else { |
91 | return $this->set_error("$file: "._("Open failed")); |
92 | } |
93 | } |
94 | |
95 | return true; |
96 | } |
97 | |
98 | // Close the file and forget the filehandle |
99 | function close() { |
100 | @fclose($this->filehandle); |
101 | $this->filehandle = 0; |
102 | $this->filename = ""; |
103 | $this->writable = false; |
104 | } |
105 | |
106 | // ========================== Public ======================== |
107 | |
108 | // Search the file |
109 | function search($expr) { |
110 | |
111 | // To be replaced by advanded search expression parsing |
112 | if(is_array($expr)) return; |
113 | |
114 | // Make regexp from glob'ed expression |
115 | $expr = ereg_replace("\?", ".", $expr); |
116 | $expr = ereg_replace("\*", ".*", $expr); |
117 | |
118 | $res = array(); |
119 | if(!$this->open()) |
120 | return false; |
121 | |
122 | @rewind($this->filehandle); |
123 | |
124 | while ($row = @fgetcsv($this->filehandle, 2048, "|")) { |
125 | $line = join(" ", $row); |
126 | if(eregi($expr, $line)) { |
127 | array_push($res, array("nickname" => $row[0], |
128 | "name" => $row[1] . " " . $row[2], |
129 | "firstname" => $row[1], |
130 | "lastname" => $row[2], |
131 | "email" => $row[3], |
132 | "label" => $row[4], |
133 | "backend" => $this->bnum, |
134 | "source" => &$this->sname)); |
135 | } |
136 | } |
137 | |
138 | return $res; |
139 | } |
140 | |
141 | // Lookup alias |
142 | function lookup($alias) { |
143 | if(empty($alias)) |
144 | return array(); |
145 | |
146 | $alias = strtolower($alias); |
147 | |
148 | $this->open(); |
149 | @rewind($this->filehandle); |
150 | |
151 | while ($row = @fgetcsv($this->filehandle, 2048, "|")) { |
152 | if(strtolower($row[0]) == $alias) { |
153 | return array("nickname" => $row[0], |
154 | "name" => $row[1] . " " . $row[2], |
155 | "firstname" => $row[1], |
156 | "lastname" => $row[2], |
157 | "email" => $row[3], |
158 | "label" => $row[4], |
159 | "backend" => $this->bnum, |
160 | "source" => &$this->sname); |
161 | } |
162 | } |
163 | |
164 | return array(); |
165 | } |
166 | |
167 | // List all addresses |
168 | function list_addr() { |
169 | $res = array(); |
170 | $this->open(); |
171 | @rewind($this->filehandle); |
172 | |
173 | while ($row = @fgetcsv($this->filehandle, 2048, "|")) { |
174 | array_push($res, array("nickname" => $row[0], |
175 | "name" => $row[1] . " " . $row[2], |
176 | "firstname" => $row[1], |
177 | "lastname" => $row[2], |
178 | "email" => $row[3], |
179 | "label" => $row[4], |
180 | "backend" => $this->bnum, |
181 | "source" => &$this->sname)); |
182 | } |
183 | return $res; |
184 | } |
185 | |
186 | // Add address |
187 | function add($userdata) { |
188 | if(!$this->writeable) |
189 | return $this->set_error(_("Addressbook is read-only")); |
190 | |
191 | // See if user exist already |
192 | $ret = $this->lookup($userdata["nickname"]); |
193 | if(!empty($ret)) |
194 | return $this->set_error(sprintf(_("User '%s' already exist"), |
195 | $ret["nickname"])); |
196 | |
197 | // Here is the data to write |
198 | $data = sprintf("%s|%s|%s|%s|%s", $userdata["nickname"], |
199 | $userdata["firstname"], $userdata["lastname"], |
200 | $userdata["email"], $userdata["label"]); |
201 | // Strip linefeeds |
202 | $data = ereg_replace("[\r\n]", " ", $data); |
203 | // Add linefeed at end |
204 | $data = $data."\n"; |
205 | |
206 | // Reopen file, just to be sure |
207 | $this->open(true); |
208 | if(!$this->writeable) |
209 | return $this->set_error(_("Addressbook is read-only")); |
210 | |
211 | $r = fwrite($this->filehandle, $data); |
212 | if($r > 0) |
213 | return true; |
214 | |
215 | $this->set_error(_("Write to addressbook failed")); |
216 | return false; |
217 | } |
218 | |
219 | } |
220 | ?> |