3ad5dec293c7b16c4335b248573d236ae8a88173
[squirrelmail.git] / functions / abook_local_file.php
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 ?>