1 | <?php |
---|
2 | /**************************************************************************\ |
---|
3 | * eGroupWare API - VFS * |
---|
4 | * This file written by Jason Wies (Zone) <zone@phpgroupware.org> * |
---|
5 | * This class handles file/dir access for eGroupWare * |
---|
6 | * Copyright (C) 2001 Jason Wies * |
---|
7 | * -------------------------------------------------------------------------* |
---|
8 | * This library is part of the eGroupWare API * |
---|
9 | * http://www.egroupware.org/api * |
---|
10 | * ------------------------------------------------------------------------ * |
---|
11 | * This library is free software; you can redistribute it and/or modify it * |
---|
12 | * under the terms of the GNU Lesser General Public License as published by * |
---|
13 | * the Free Software Foundation; either version 2.1 of the License, * |
---|
14 | * or any later version. * |
---|
15 | * This library is distributed in the hope that it will be useful, but * |
---|
16 | * WITHOUT ANY WARRANTY; without even the implied warranty of * |
---|
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * |
---|
18 | * See the GNU Lesser General Public License for more details. * |
---|
19 | * You should have received a copy of the GNU Lesser General Public License * |
---|
20 | * along with this library; if not, write to the Free Software Foundation, * |
---|
21 | * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * |
---|
22 | \**************************************************************************/ |
---|
23 | |
---|
24 | |
---|
25 | /*! |
---|
26 | @class vfs |
---|
27 | @abstract Virtual File System with SQL backend |
---|
28 | @description Authors: Zone |
---|
29 | */ |
---|
30 | |
---|
31 | /* These are used in calls to extra_sql () */ |
---|
32 | define ('VFS_SQL_SELECT', 1); |
---|
33 | define ('VFS_SQL_DELETE', 2); |
---|
34 | define ('VFS_SQL_UPDATE', 4); |
---|
35 | |
---|
36 | class vfs extends vfs_shared |
---|
37 | { |
---|
38 | var $working_id; |
---|
39 | var $working_lid; |
---|
40 | var $meta_types; |
---|
41 | var $now; |
---|
42 | var $file_actions; |
---|
43 | |
---|
44 | /*! |
---|
45 | @function vfs |
---|
46 | @abstract constructor, sets up variables |
---|
47 | */ |
---|
48 | function vfs () |
---|
49 | { |
---|
50 | $this->vfs_shared (); |
---|
51 | $this->basedir = $GLOBALS['phpgw_info']['server']['files_dir']; |
---|
52 | $this->working_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
53 | $this->working_lid = $GLOBALS['phpgw']->accounts->id2name($this->working_id); |
---|
54 | $this->now = date ('Y-m-d'); |
---|
55 | |
---|
56 | /* |
---|
57 | File/dir attributes, each corresponding to a database field. Useful for use in loops |
---|
58 | If an attribute was added to the table, add it here and possibly add it to |
---|
59 | set_attributes () |
---|
60 | |
---|
61 | set_attributes now uses this array(). 07-Dec-01 skeeter |
---|
62 | */ |
---|
63 | |
---|
64 | $this->attributes[] = 'deleteable'; |
---|
65 | $this->attributes[] = 'content'; |
---|
66 | |
---|
67 | /* |
---|
68 | Decide whether to use any actual filesystem calls (fopen(), fread(), |
---|
69 | unlink(), rmdir(), touch(), etc.). If not, then we're working completely |
---|
70 | in the database. |
---|
71 | */ |
---|
72 | $this->file_actions = $GLOBALS['phpgw_info']['server']['file_store_contents'] == 'filesystem' || |
---|
73 | !$GLOBALS['phpgw_info']['server']['file_store_contents']; |
---|
74 | |
---|
75 | // test if the files-dir is inside the document-root, and refuse working if so |
---|
76 | // |
---|
77 | if ($this->file_actions && $this->in_docroot($this->basedir)) |
---|
78 | { |
---|
79 | $GLOBALS['phpgw']->common->phpgw_header(); |
---|
80 | if ($GLOBALS['phpgw_info']['flags']['noheader']) |
---|
81 | { |
---|
82 | echo parse_navbar(); |
---|
83 | } |
---|
84 | echo '<p align="center"><font color="red"><b>'.lang('Path to user and group files HAS TO BE OUTSIDE of the webservers document-root!!!')."</b></font></p>\n"; |
---|
85 | $GLOBALS['phpgw']->common->phpgw_exit(); |
---|
86 | } |
---|
87 | /* |
---|
88 | These are stored in the MIME-type field and should normally be ignored. |
---|
89 | Adding a type here will ensure it is normally ignored, but you will have to |
---|
90 | explicitly add it to acl_check (), and to any other SELECT's in this file |
---|
91 | */ |
---|
92 | |
---|
93 | $this->meta_types = array ('journal', 'journal-deleted'); |
---|
94 | |
---|
95 | /* We store the linked directories in an array now, so we don't have to make the SQL call again */ |
---|
96 | if ($GLOBALS['phpgw_info']['server']['db_type']=='mssql' |
---|
97 | || $GLOBALS['phpgw_info']['server']['db_type']=='sybase') |
---|
98 | { |
---|
99 | $query = $GLOBALS['phpgw']->db->query ("SELECT directory, name, link_directory, link_name FROM phpgw_vfs WHERE CONVERT(varchar,link_directory) != '' AND CONVERT(varchar,link_name) != ''" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__,__FILE__); |
---|
100 | } |
---|
101 | else |
---|
102 | { |
---|
103 | $query = $GLOBALS['phpgw']->db->query ("SELECT directory, name, link_directory, link_name FROM phpgw_vfs WHERE (link_directory IS NOT NULL or link_directory != '') AND (link_name IS NOT NULL or link_name != '')" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__,__FILE__); |
---|
104 | } |
---|
105 | |
---|
106 | $this->linked_dirs = array (); |
---|
107 | while ($GLOBALS['phpgw']->db->next_record ()) |
---|
108 | { |
---|
109 | $this->linked_dirs[] = $GLOBALS['phpgw']->db->Record; |
---|
110 | } |
---|
111 | } |
---|
112 | |
---|
113 | /*! |
---|
114 | @function in_docroot |
---|
115 | @abstract test if $path lies within the webservers document-root |
---|
116 | */ |
---|
117 | function in_docroot($path) |
---|
118 | { |
---|
119 | $docroots = array(PHPGW_SERVER_ROOT,$_SERVER['DOCUMENT_ROOT']); |
---|
120 | |
---|
121 | foreach ($docroots as $docroot) |
---|
122 | { |
---|
123 | $len = strlen($docroot); |
---|
124 | |
---|
125 | if ($docroot == substr($path,0,$len)) |
---|
126 | { |
---|
127 | $rest = substr($path,$len); |
---|
128 | |
---|
129 | if (!strlen($rest) || $rest[0] == DIRECTORY_SEPARATOR) |
---|
130 | { |
---|
131 | return True; |
---|
132 | } |
---|
133 | } |
---|
134 | } |
---|
135 | return False; |
---|
136 | } |
---|
137 | |
---|
138 | /*! |
---|
139 | @function extra_sql |
---|
140 | @abstract Return extra SQL code that should be appended to certain queries |
---|
141 | @param query_type The type of query to get extra SQL code for, in the form of a VFS_SQL define |
---|
142 | @result Extra SQL code |
---|
143 | */ |
---|
144 | function extra_sql ($data) |
---|
145 | { |
---|
146 | if (!is_array ($data)) |
---|
147 | { |
---|
148 | $data = array ('query_type' => VFS_SQL_SELECT); |
---|
149 | } |
---|
150 | |
---|
151 | if ($data['query_type'] == VFS_SQL_SELECT || $data['query_type'] == VFS_SQL_DELETE || $data['query_type'] = VFS_SQL_UPDATE) |
---|
152 | { |
---|
153 | $sql = ' AND (('; |
---|
154 | |
---|
155 | foreach ($this->meta_types as $num => $type) |
---|
156 | { |
---|
157 | if ($num) |
---|
158 | $sql .= ' AND '; |
---|
159 | |
---|
160 | $sql .= "mime_type != '$type'"; |
---|
161 | } |
---|
162 | |
---|
163 | $sql .= ') OR mime_type IS NULL)'; |
---|
164 | } |
---|
165 | |
---|
166 | return ($sql); |
---|
167 | } |
---|
168 | |
---|
169 | /*! |
---|
170 | @function add_journal |
---|
171 | @abstract Add a journal entry after (or before) completing an operation, |
---|
172 | and increment the version number. This function should be used internally only |
---|
173 | @discussion Note that state_one and state_two are ignored for some VFS_OPERATION's, for others |
---|
174 | they are required. They are ignored for any "custom" operation |
---|
175 | The two operations that require state_two: |
---|
176 | operation state_two |
---|
177 | VFS_OPERATION_COPIED fake_full_path of copied to |
---|
178 | VFS_OPERATION_MOVED fake_full_path of moved to |
---|
179 | |
---|
180 | If deleting, you must call add_journal () before you delete the entry from the database |
---|
181 | @param string File or directory to add entry for |
---|
182 | @param relatives Relativity array |
---|
183 | @param operation The operation that was performed. Either a VFS_OPERATION define or |
---|
184 | a non-integer descriptive text string |
---|
185 | @param state_one The first "state" of the file or directory. Can be a file name, size, |
---|
186 | location, whatever is appropriate for the specific operation |
---|
187 | @param state_two The second "state" of the file or directory |
---|
188 | @param incversion Boolean True/False. Increment the version for the file? Note that this is |
---|
189 | handled automatically for the VFS_OPERATION defines. |
---|
190 | i.e. VFS_OPERATION_EDITED would increment the version, VFS_OPERATION_COPIED |
---|
191 | would not |
---|
192 | @result Boolean True/False |
---|
193 | */ |
---|
194 | function add_journal ($data) |
---|
195 | { |
---|
196 | if (!is_array ($data)) |
---|
197 | { |
---|
198 | $data = array (); |
---|
199 | } |
---|
200 | |
---|
201 | $default_values = array |
---|
202 | ( |
---|
203 | 'relatives' => array (RELATIVE_CURRENT), |
---|
204 | 'state_one' => False, |
---|
205 | 'state_two' => False, |
---|
206 | 'incversion' => True |
---|
207 | ); |
---|
208 | |
---|
209 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
210 | |
---|
211 | $account_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
212 | |
---|
213 | $p = $this->path_parts (array ('string' => $data['string'], 'relatives' => array ($data['relatives'][0]))); |
---|
214 | |
---|
215 | /* We check that they have some sort of access to the file other than read */ |
---|
216 | if (!$this->acl_check (array ('string' => $p->fake_full_path, 'relatives' => array ($p->mask), 'operation' => PHPGW_ACL_WRITE)) && |
---|
217 | !$this->acl_check (array ('string' => $p->fake_full_path, 'relatives' => array ($p->mask), 'operation' => PHPGW_ACL_EDIT)) && |
---|
218 | !$this->acl_check (array ('string' => $p->fake_full_path, 'relatives' => array ($p->mask), 'operation' => PHPGW_ACL_DELETE))) |
---|
219 | { |
---|
220 | return False; |
---|
221 | } |
---|
222 | |
---|
223 | if (!$this->file_exists (array ('string' => $p->fake_full_path, 'relatives' => array ($p->mask)))) |
---|
224 | { |
---|
225 | return False; |
---|
226 | } |
---|
227 | |
---|
228 | $ls_array = $this->ls (array ( |
---|
229 | 'string' => $p->fake_full_path, |
---|
230 | 'relatives' => array ($p->mask), |
---|
231 | 'checksubdirs' => False, |
---|
232 | 'mime_type' => False, |
---|
233 | 'nofiles' => True |
---|
234 | ) |
---|
235 | ); |
---|
236 | $file_array = $ls_array[0]; |
---|
237 | |
---|
238 | $sql = 'INSERT INTO phpgw_vfs ('; |
---|
239 | $sql2 .= ' VALUES ('; |
---|
240 | |
---|
241 | for ($i = 0; list ($attribute, $value) = each ($file_array); $i++) |
---|
242 | { |
---|
243 | if ($attribute == 'file_id' || $attribute == 'content') |
---|
244 | { |
---|
245 | continue; |
---|
246 | } |
---|
247 | |
---|
248 | if ($attribute == 'owner_id') |
---|
249 | { |
---|
250 | $value = $account_id; |
---|
251 | } |
---|
252 | |
---|
253 | if ($attribute == 'created') |
---|
254 | { |
---|
255 | $value = $this->now; |
---|
256 | } |
---|
257 | |
---|
258 | if ($attribute == 'modified' && !$modified) |
---|
259 | { |
---|
260 | unset ($value); |
---|
261 | } |
---|
262 | |
---|
263 | if ($attribute == 'mime_type') |
---|
264 | { |
---|
265 | $value = 'journal'; |
---|
266 | } |
---|
267 | |
---|
268 | if ($attribute == 'comment') |
---|
269 | { |
---|
270 | switch ($data['operation']) |
---|
271 | { |
---|
272 | case VFS_OPERATION_CREATED: |
---|
273 | $value = 'Created'; |
---|
274 | $data['incversion'] = True; |
---|
275 | break; |
---|
276 | case VFS_OPERATION_EDITED: |
---|
277 | $value = 'Edited'; |
---|
278 | $data['incversion'] = True; |
---|
279 | break; |
---|
280 | case VFS_OPERATION_EDITED_COMMENT: |
---|
281 | $value = 'Edited comment'; |
---|
282 | $data['incversion'] = False; |
---|
283 | break; |
---|
284 | case VFS_OPERATION_COPIED: |
---|
285 | if (!$data['state_one']) |
---|
286 | { |
---|
287 | $data['state_one'] = $p->fake_full_path; |
---|
288 | } |
---|
289 | if (!$data['state_two']) |
---|
290 | { |
---|
291 | return False; |
---|
292 | } |
---|
293 | $value = 'Copied '.$data['state_one'].' to '.$data['state_two']; |
---|
294 | $data['incversion'] = False; |
---|
295 | break; |
---|
296 | case VFS_OPERATION_MOVED: |
---|
297 | if (!$data['state_one']) |
---|
298 | { |
---|
299 | $data['state_one'] = $p->fake_full_path; |
---|
300 | } |
---|
301 | if (!$data['state_two']) |
---|
302 | { |
---|
303 | return False; |
---|
304 | } |
---|
305 | $value = 'Moved '.$data['state_one'].' to '.$data['state_two']; |
---|
306 | $data['incversion'] = False; |
---|
307 | break; |
---|
308 | case VFS_OPERATION_DELETED: |
---|
309 | $value = 'Deleted'; |
---|
310 | $data['incversion'] = False; |
---|
311 | break; |
---|
312 | default: |
---|
313 | $value = $data['operation']; |
---|
314 | break; |
---|
315 | } |
---|
316 | } |
---|
317 | |
---|
318 | /* |
---|
319 | Let's increment the version for the file itself. We keep the current |
---|
320 | version when making the journal entry, because that was the version that |
---|
321 | was operated on. The maximum numbers for each part in the version string: |
---|
322 | none.99.9.9 |
---|
323 | */ |
---|
324 | if ($attribute == 'version' && $data['incversion']) |
---|
325 | { |
---|
326 | $version_parts = split ("\.", $value); |
---|
327 | $newnumofparts = $numofparts = count ($version_parts); |
---|
328 | |
---|
329 | if ($version_parts[3] >= 9) |
---|
330 | { |
---|
331 | $version_parts[3] = 0; |
---|
332 | $version_parts[2]++; |
---|
333 | $version_parts_3_update = 1; |
---|
334 | } |
---|
335 | elseif (isset ($version_parts[3])) |
---|
336 | { |
---|
337 | $version_parts[3]++; |
---|
338 | } |
---|
339 | |
---|
340 | if ($version_parts[2] >= 9 && $version_parts[3] == 0 && $version_parts_3_update) |
---|
341 | { |
---|
342 | $version_parts[2] = 0; |
---|
343 | $version_parts[1]++; |
---|
344 | } |
---|
345 | |
---|
346 | if ($version_parts[1] > 99) |
---|
347 | { |
---|
348 | $version_parts[1] = 0; |
---|
349 | $version_parts[0]++; |
---|
350 | } |
---|
351 | |
---|
352 | for ($i = 0; $i < $newnumofparts; $i++) |
---|
353 | { |
---|
354 | if (!isset ($version_parts[$i])) |
---|
355 | { |
---|
356 | break; |
---|
357 | } |
---|
358 | |
---|
359 | if ($i) |
---|
360 | { |
---|
361 | $newversion .= '.'; |
---|
362 | } |
---|
363 | |
---|
364 | $newversion .= $version_parts[$i]; |
---|
365 | } |
---|
366 | |
---|
367 | $this->set_attributes (array( |
---|
368 | 'string' => $p->fake_full_path, |
---|
369 | 'relatives' => array ($p->mask), |
---|
370 | 'attributes' => array( |
---|
371 | 'version' => $newversion |
---|
372 | ) |
---|
373 | ) |
---|
374 | ); |
---|
375 | } |
---|
376 | |
---|
377 | if (isset ($value)) |
---|
378 | { |
---|
379 | if ($i > 1) |
---|
380 | { |
---|
381 | $sql .= ', '; |
---|
382 | $sql2 .= ', '; |
---|
383 | } |
---|
384 | |
---|
385 | $sql .= "$attribute"; |
---|
386 | $sql2 .= "'" . $this->clean_string (array ('string' => $value)) . "'"; |
---|
387 | } |
---|
388 | } |
---|
389 | |
---|
390 | $sql .= ')'; |
---|
391 | $sql2 .= ')'; |
---|
392 | |
---|
393 | $sql .= $sql2; |
---|
394 | |
---|
395 | /* |
---|
396 | These are some special situations where we need to flush the journal entries |
---|
397 | or move the 'journal' entries to 'journal-deleted'. Kind of hackish, but they |
---|
398 | provide a consistent feel to the system |
---|
399 | */ |
---|
400 | if ($data['operation'] == VFS_OPERATION_CREATED) |
---|
401 | { |
---|
402 | $flush_path = $p->fake_full_path; |
---|
403 | $deleteall = True; |
---|
404 | } |
---|
405 | |
---|
406 | if ($data['operation'] == VFS_OPERATION_COPIED || $data['operation'] == VFS_OPERATION_MOVED) |
---|
407 | { |
---|
408 | $flush_path = $data['state_two']; |
---|
409 | $deleteall = False; |
---|
410 | } |
---|
411 | |
---|
412 | if ($flush_path) |
---|
413 | { |
---|
414 | $flush_path_parts = $this->path_parts (array( |
---|
415 | 'string' => $flush_path, |
---|
416 | 'relatives' => array (RELATIVE_NONE) |
---|
417 | ) |
---|
418 | ); |
---|
419 | |
---|
420 | $this->flush_journal (array( |
---|
421 | 'string' => $flush_path_parts->fake_full_path, |
---|
422 | 'relatives' => array ($flush_path_parts->mask), |
---|
423 | 'deleteall' => $deleteall |
---|
424 | ) |
---|
425 | ); |
---|
426 | } |
---|
427 | |
---|
428 | if ($data['operation'] == VFS_OPERATION_COPIED) |
---|
429 | { |
---|
430 | /* |
---|
431 | We copy it going the other way as well, so both files show the operation. |
---|
432 | The code is a bad hack to prevent recursion. Ideally it would use VFS_OPERATION_COPIED |
---|
433 | */ |
---|
434 | $this->add_journal (array( |
---|
435 | 'string' => $data['state_two'], |
---|
436 | 'relatives' => array (RELATIVE_NONE), |
---|
437 | 'operation' => 'Copied '.$data['state_one'].' to '.$data['state_two'], |
---|
438 | 'state_one' => NULL, |
---|
439 | 'state_two' => NULL, |
---|
440 | 'incversion' => False |
---|
441 | ) |
---|
442 | ); |
---|
443 | } |
---|
444 | |
---|
445 | if ($data['operation'] == VFS_OPERATION_MOVED) |
---|
446 | { |
---|
447 | $state_one_path_parts = $this->path_parts (array( |
---|
448 | 'string' => $data['state_one'], |
---|
449 | 'relatives' => array (RELATIVE_NONE) |
---|
450 | ) |
---|
451 | ); |
---|
452 | |
---|
453 | $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET mime_type='journal-deleted' WHERE directory='". |
---|
454 | $GLOBALS['phpgw']->db->db_addslashes($state_one_path_parts->fake_leading_dirs_clean)."' AND name='". |
---|
455 | $GLOBALS['phpgw']->db->db_addslashes($state_one_path_parts->fake_name_clean)."' AND mime_type='journal'"); |
---|
456 | |
---|
457 | /* |
---|
458 | We create the file in addition to logging the MOVED operation. This is an |
---|
459 | advantage because we can now search for 'Create' to see when a file was created |
---|
460 | */ |
---|
461 | $this->add_journal (array( |
---|
462 | 'string' => $data['state_two'], |
---|
463 | 'relatives' => array (RELATIVE_NONE), |
---|
464 | 'operation' => VFS_OPERATION_CREATED |
---|
465 | ) |
---|
466 | ); |
---|
467 | } |
---|
468 | |
---|
469 | /* This is the SQL query we made for THIS request, remember that one? */ |
---|
470 | $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__); |
---|
471 | |
---|
472 | /* |
---|
473 | If we were to add an option of whether to keep journal entries for deleted files |
---|
474 | or not, it would go in the if here |
---|
475 | */ |
---|
476 | if ($data['operation'] == VFS_OPERATION_DELETED) |
---|
477 | { |
---|
478 | $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET mime_type='journal-deleted' WHERE directory='". |
---|
479 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
480 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."' AND mime_type='journal'"); |
---|
481 | } |
---|
482 | |
---|
483 | return True; |
---|
484 | } |
---|
485 | |
---|
486 | /*! |
---|
487 | @function flush_journal |
---|
488 | @abstract Flush journal entries for $string. Used before adding $string |
---|
489 | @discussion flush_journal () is an internal function and should be called from add_journal () only |
---|
490 | @param string File/directory to flush journal entries of |
---|
491 | @param relatives Realtivity array |
---|
492 | @param deleteall Delete all types of journal entries, including the active Create entry. |
---|
493 | Normally you only want to delete the Create entry when replacing the file |
---|
494 | Note that this option does not effect $deleteonly |
---|
495 | @param deletedonly Only flush 'journal-deleted' entries (created when $string was deleted) |
---|
496 | @result Boolean True/False |
---|
497 | */ |
---|
498 | function flush_journal ($data) |
---|
499 | { |
---|
500 | if (!is_array ($data)) |
---|
501 | { |
---|
502 | $data = array (); |
---|
503 | } |
---|
504 | |
---|
505 | $default_values = array |
---|
506 | ( |
---|
507 | 'relatives' => array (RELATIVE_CURRENT), |
---|
508 | 'deleteall' => False, |
---|
509 | 'deletedonly' => False |
---|
510 | ); |
---|
511 | |
---|
512 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
513 | |
---|
514 | $p = $this->path_parts (array( |
---|
515 | 'string' => $data['string'], |
---|
516 | 'relatives' => array ($data['relatives'][0]) |
---|
517 | ) |
---|
518 | ); |
---|
519 | |
---|
520 | $sql = "DELETE FROM phpgw_vfs WHERE directory='". |
---|
521 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
522 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'"; |
---|
523 | |
---|
524 | if (!$data['deleteall']) |
---|
525 | { |
---|
526 | $sql .= " AND (mime_type != 'journal' AND comment != 'Created')"; |
---|
527 | } |
---|
528 | |
---|
529 | $sql .= " AND (mime_type='journal-deleted'"; |
---|
530 | |
---|
531 | if (!$data['deletedonly']) |
---|
532 | { |
---|
533 | $sql .= " OR mime_type='journal'"; |
---|
534 | } |
---|
535 | |
---|
536 | $sql .= ")"; |
---|
537 | |
---|
538 | $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__); |
---|
539 | |
---|
540 | if ($query) |
---|
541 | { |
---|
542 | return True; |
---|
543 | } |
---|
544 | else |
---|
545 | { |
---|
546 | return False; |
---|
547 | } |
---|
548 | } |
---|
549 | |
---|
550 | /* |
---|
551 | * See vfs_shared |
---|
552 | */ |
---|
553 | function get_journal ($data) |
---|
554 | { |
---|
555 | if (!is_array ($data)) |
---|
556 | { |
---|
557 | $data = array (); |
---|
558 | } |
---|
559 | |
---|
560 | $default_values = array |
---|
561 | ( |
---|
562 | 'relatives' => array (RELATIVE_CURRENT), |
---|
563 | 'type' => False |
---|
564 | ); |
---|
565 | |
---|
566 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
567 | |
---|
568 | $p = $this->path_parts (array( |
---|
569 | 'string' => $data['string'], |
---|
570 | 'relatives' => array ($data['relatives'][0]) |
---|
571 | ) |
---|
572 | ); |
---|
573 | |
---|
574 | if (!$this->acl_check (array( |
---|
575 | 'string' => $p->fake_full_path, |
---|
576 | 'relatives' => array ($p->mask) |
---|
577 | ))) |
---|
578 | { |
---|
579 | return False; |
---|
580 | } |
---|
581 | |
---|
582 | $sql = "SELECT * FROM phpgw_vfs WHERE directory='". |
---|
583 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
584 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'"; |
---|
585 | |
---|
586 | if ($data['type'] == 1) |
---|
587 | { |
---|
588 | $sql .= " AND mime_type='journal'"; |
---|
589 | } |
---|
590 | elseif ($data['type'] == 2) |
---|
591 | { |
---|
592 | $sql .= " AND mime_type='journal-deleted'"; |
---|
593 | } |
---|
594 | else |
---|
595 | { |
---|
596 | $sql .= " AND (mime_type='journal' OR mime_type='journal-deleted')"; |
---|
597 | } |
---|
598 | |
---|
599 | $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__); |
---|
600 | |
---|
601 | while ($GLOBALS['phpgw']->db->next_record ()) |
---|
602 | { |
---|
603 | $rarray[] = $GLOBALS['phpgw']->db->Record; |
---|
604 | } |
---|
605 | |
---|
606 | return $rarray; |
---|
607 | } |
---|
608 | |
---|
609 | /* |
---|
610 | * See vfs_shared |
---|
611 | */ |
---|
612 | function acl_check ($data) |
---|
613 | { |
---|
614 | if (!is_array ($data)) |
---|
615 | { |
---|
616 | $data = array (); |
---|
617 | } |
---|
618 | |
---|
619 | $default_values = array |
---|
620 | ( |
---|
621 | 'relatives' => array (RELATIVE_CURRENT), |
---|
622 | 'operation' => PHPGW_ACL_READ, |
---|
623 | 'must_exist' => False |
---|
624 | ); |
---|
625 | |
---|
626 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
627 | |
---|
628 | /* Accommodate special situations */ |
---|
629 | if ($this->override_acl || $data['relatives'][0] == RELATIVE_USER_APP) |
---|
630 | { |
---|
631 | return True; |
---|
632 | } |
---|
633 | |
---|
634 | if (!$data['owner_id']) |
---|
635 | { |
---|
636 | $p = $this->path_parts (array( |
---|
637 | 'string' => $data['string'], |
---|
638 | 'relatives' => array ($data['relatives'][0]) |
---|
639 | ) |
---|
640 | ); |
---|
641 | |
---|
642 | /* Temporary, until we get symlink type files set up */ |
---|
643 | if ($p->outside) |
---|
644 | { |
---|
645 | return True; |
---|
646 | } |
---|
647 | |
---|
648 | /* Read access is always allowed here, but nothing else is */ |
---|
649 | if ($data['string'] == '/' || $data['string'] == $this->fakebase) |
---|
650 | { |
---|
651 | if ($data['operation'] == PHPGW_ACL_READ) |
---|
652 | { |
---|
653 | return True; |
---|
654 | } |
---|
655 | else |
---|
656 | { |
---|
657 | return False; |
---|
658 | } |
---|
659 | } |
---|
660 | |
---|
661 | /* If the file doesn't exist, we get ownership from the parent directory */ |
---|
662 | if (!$this->file_exists (array( |
---|
663 | 'string' => $p->fake_full_path, |
---|
664 | 'relatives' => array ($p->mask) |
---|
665 | )) |
---|
666 | ) |
---|
667 | { |
---|
668 | if ($data['must_exist']) |
---|
669 | { |
---|
670 | return False; |
---|
671 | } |
---|
672 | |
---|
673 | $data['string'] = $p->fake_leading_dirs; |
---|
674 | $p2 = $this->path_parts (array( |
---|
675 | 'string' => $data['string'], |
---|
676 | 'relatives' => array ($p->mask) |
---|
677 | ) |
---|
678 | ); |
---|
679 | |
---|
680 | if (!$this->file_exists (array( |
---|
681 | 'string' => $data['string'], |
---|
682 | 'relatives' => array ($p->mask) |
---|
683 | )) |
---|
684 | ) |
---|
685 | { |
---|
686 | return False; |
---|
687 | } |
---|
688 | } |
---|
689 | else |
---|
690 | { |
---|
691 | $p2 = $p; |
---|
692 | } |
---|
693 | |
---|
694 | /* |
---|
695 | We don't use ls () to get owner_id as we normally would, |
---|
696 | because ls () calls acl_check (), which would create an infinite loop |
---|
697 | */ |
---|
698 | $query = $GLOBALS['phpgw']->db->query ("SELECT owner_id FROM phpgw_vfs WHERE directory='". |
---|
699 | $GLOBALS['phpgw']->db->db_addslashes($p2->fake_leading_dirs_clean)."' AND name='". |
---|
700 | $GLOBALS['phpgw']->db->db_addslashes($p2->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__); |
---|
701 | $GLOBALS['phpgw']->db->next_record (); |
---|
702 | |
---|
703 | $owner_id = $GLOBALS['phpgw']->db->Record['owner_id']; |
---|
704 | } |
---|
705 | else |
---|
706 | { |
---|
707 | $owner_id = $data['owner_id']; |
---|
708 | } |
---|
709 | |
---|
710 | /* This is correct. The ACL currently doesn't handle undefined values correctly */ |
---|
711 | if (!$owner_id) |
---|
712 | { |
---|
713 | $owner_id = 0; |
---|
714 | } |
---|
715 | |
---|
716 | $user_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
717 | |
---|
718 | /* They always have access to their own files */ |
---|
719 | if ($owner_id == $user_id) |
---|
720 | { |
---|
721 | return True; |
---|
722 | } |
---|
723 | |
---|
724 | /* Check if they're in the group */ |
---|
725 | $memberships = $GLOBALS['phpgw']->accounts->membership ($user_id); |
---|
726 | |
---|
727 | if (is_array ($memberships)) |
---|
728 | { |
---|
729 | foreach ($memberships as $group_array) |
---|
730 | { |
---|
731 | if ($owner_id == $group_array['account_id']) |
---|
732 | { |
---|
733 | $group_ok = 1; |
---|
734 | break; |
---|
735 | } |
---|
736 | } |
---|
737 | } |
---|
738 | |
---|
739 | $acl = CreateObject ('phpgwapi.acl', $owner_id); |
---|
740 | $acl->account_id = $owner_id; |
---|
741 | $acl->read_repository (); |
---|
742 | |
---|
743 | $rights = $acl->get_rights ($user_id); |
---|
744 | |
---|
745 | /* Add privileges from the groups this user belongs to */ |
---|
746 | if (is_array ($memberships)) |
---|
747 | { |
---|
748 | foreach ($memberships as $group_array) |
---|
749 | { |
---|
750 | $rights |= $acl->get_rights ($group_array['account_id']); |
---|
751 | } |
---|
752 | } |
---|
753 | |
---|
754 | if ($rights & $data['operation']) |
---|
755 | { |
---|
756 | return True; |
---|
757 | } |
---|
758 | elseif (!$rights && $group_ok) |
---|
759 | { |
---|
760 | $conf = CreateObject('phpgwapi.config', 'phpgwapi'); |
---|
761 | $conf->read_repository(); |
---|
762 | if ($conf->config_data['acl_default'] == 'grant') |
---|
763 | { |
---|
764 | return True; |
---|
765 | } |
---|
766 | else |
---|
767 | { |
---|
768 | return False; |
---|
769 | } |
---|
770 | } |
---|
771 | else |
---|
772 | { |
---|
773 | return False; |
---|
774 | } |
---|
775 | } |
---|
776 | |
---|
777 | /* |
---|
778 | * See vfs_shared |
---|
779 | */ |
---|
780 | function read ($data) |
---|
781 | { |
---|
782 | if (!is_array ($data)) |
---|
783 | { |
---|
784 | $data = array (); |
---|
785 | } |
---|
786 | |
---|
787 | $default_values = array |
---|
788 | ( |
---|
789 | 'relatives' => array (RELATIVE_CURRENT) |
---|
790 | ); |
---|
791 | |
---|
792 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
793 | |
---|
794 | $p = $this->path_parts (array( |
---|
795 | 'string' => $data['string'], |
---|
796 | 'relatives' => array ($data['relatives'][0]) |
---|
797 | ) |
---|
798 | ); |
---|
799 | |
---|
800 | if (!$this->acl_check (array( |
---|
801 | 'string' => $p->fake_full_path, |
---|
802 | 'relatives' => array ($p->mask), |
---|
803 | 'operation' => PHPGW_ACL_READ |
---|
804 | )) |
---|
805 | ) |
---|
806 | { |
---|
807 | return False; |
---|
808 | } |
---|
809 | |
---|
810 | $conf = CreateObject('phpgwapi.config', 'phpgwapi'); |
---|
811 | $conf->read_repository(); |
---|
812 | if ($this->file_actions || $p->outside) |
---|
813 | { |
---|
814 | if ($fp = fopen ($p->real_full_path, 'rb')) |
---|
815 | { |
---|
816 | $contents = fread ($fp, filesize ($p->real_full_path)); |
---|
817 | fclose ($fp); |
---|
818 | } |
---|
819 | else |
---|
820 | { |
---|
821 | $contents = False; |
---|
822 | } |
---|
823 | } |
---|
824 | else |
---|
825 | { |
---|
826 | $ls_array = $this->ls (array( |
---|
827 | 'string' => $p->fake_full_path, |
---|
828 | 'relatives' => array ($p->mask), |
---|
829 | ) |
---|
830 | ); |
---|
831 | |
---|
832 | $contents = $ls_array[0]['content']; |
---|
833 | } |
---|
834 | |
---|
835 | return $contents; |
---|
836 | } |
---|
837 | |
---|
838 | /* |
---|
839 | * See vfs_shared |
---|
840 | */ |
---|
841 | function write ($data) |
---|
842 | { |
---|
843 | if (!is_array ($data)) |
---|
844 | { |
---|
845 | $data = array (); |
---|
846 | } |
---|
847 | |
---|
848 | $default_values = array |
---|
849 | ( |
---|
850 | 'relatives' => array (RELATIVE_CURRENT), |
---|
851 | 'content' => '' |
---|
852 | ); |
---|
853 | |
---|
854 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
855 | |
---|
856 | $p = $this->path_parts (array( |
---|
857 | 'string' => $data['string'], |
---|
858 | 'relatives' => array ($data['relatives'][0]) |
---|
859 | ) |
---|
860 | ); |
---|
861 | |
---|
862 | if ($this->file_exists (array ( |
---|
863 | 'string' => $p->fake_full_path, |
---|
864 | 'relatives' => array ($p->mask) |
---|
865 | )) |
---|
866 | ) |
---|
867 | { |
---|
868 | $acl_operation = PHPGW_ACL_EDIT; |
---|
869 | $journal_operation = VFS_OPERATION_EDITED; |
---|
870 | } |
---|
871 | else |
---|
872 | { |
---|
873 | $acl_operation = PHPGW_ACL_ADD; |
---|
874 | } |
---|
875 | |
---|
876 | if (!$this->acl_check (array( |
---|
877 | 'string' => $p->fake_full_path, |
---|
878 | 'relatives' => array ($p->mask), |
---|
879 | 'operation' => $acl_operation |
---|
880 | )) |
---|
881 | ) |
---|
882 | { |
---|
883 | return False; |
---|
884 | } |
---|
885 | |
---|
886 | umask(0177); |
---|
887 | |
---|
888 | /* |
---|
889 | If 'string' doesn't exist, touch () creates both the file and the database entry |
---|
890 | If 'string' does exist, touch () sets the modification time and modified by |
---|
891 | */ |
---|
892 | $this->touch (array( |
---|
893 | 'string' => $p->fake_full_path, |
---|
894 | 'relatives' => array ($p->mask) |
---|
895 | ) |
---|
896 | ); |
---|
897 | |
---|
898 | $conf = CreateObject('phpgwapi.config', 'phpgwapi'); |
---|
899 | $conf->read_repository(); |
---|
900 | if ($this->file_actions) |
---|
901 | { |
---|
902 | if ($fp = fopen ($p->real_full_path, 'wb')) |
---|
903 | { |
---|
904 | fwrite ($fp, $data['content']); |
---|
905 | fclose ($fp); |
---|
906 | $write_ok = 1; |
---|
907 | } |
---|
908 | } |
---|
909 | |
---|
910 | if ($write_ok || !$this->file_actions) |
---|
911 | { |
---|
912 | if ($this->file_actions) |
---|
913 | { |
---|
914 | $set_attributes_array = array( |
---|
915 | 'size' => filesize ($p->real_full_path) |
---|
916 | ); |
---|
917 | } |
---|
918 | else |
---|
919 | { |
---|
920 | $set_attributes_array = array ( |
---|
921 | 'size' => strlen ($data['content']), |
---|
922 | 'content' => $data['content'] |
---|
923 | ); |
---|
924 | } |
---|
925 | |
---|
926 | |
---|
927 | $this->set_attributes (array |
---|
928 | ( |
---|
929 | 'string' => $p->fake_full_path, |
---|
930 | 'relatives' => array ($p->mask), |
---|
931 | 'attributes' => $set_attributes_array |
---|
932 | ) |
---|
933 | ); |
---|
934 | |
---|
935 | if ($journal_operation) |
---|
936 | { |
---|
937 | $this->add_journal (array( |
---|
938 | 'string' => $p->fake_full_path, |
---|
939 | 'relatives' => array ($p->mask), |
---|
940 | 'operation' => $journal_operation |
---|
941 | ) |
---|
942 | ); |
---|
943 | } |
---|
944 | |
---|
945 | return True; |
---|
946 | } |
---|
947 | else |
---|
948 | { |
---|
949 | return False; |
---|
950 | } |
---|
951 | } |
---|
952 | |
---|
953 | /* |
---|
954 | * See vfs_shared |
---|
955 | */ |
---|
956 | function touch ($data) |
---|
957 | { |
---|
958 | if (!is_array ($data)) |
---|
959 | { |
---|
960 | $data = array (); |
---|
961 | } |
---|
962 | |
---|
963 | $default_values = array |
---|
964 | ( |
---|
965 | 'relatives' => array (RELATIVE_CURRENT) |
---|
966 | ); |
---|
967 | |
---|
968 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
969 | |
---|
970 | $account_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
971 | $currentapp = $GLOBALS['phpgw_info']['flags']['currentapp']; |
---|
972 | |
---|
973 | $p = $this->path_parts (array( |
---|
974 | 'string' => $data['string'], |
---|
975 | 'relatives' => array ($data['relatives'][0]) |
---|
976 | ) |
---|
977 | ); |
---|
978 | |
---|
979 | umask (0177); |
---|
980 | |
---|
981 | if ($this->file_actions) |
---|
982 | { |
---|
983 | /* |
---|
984 | PHP's touch function will automatically decide whether to |
---|
985 | create the file or set the modification time |
---|
986 | */ |
---|
987 | $rr = @touch ($p->real_full_path); |
---|
988 | |
---|
989 | if ($p->outside) |
---|
990 | { |
---|
991 | return $rr; |
---|
992 | } |
---|
993 | } |
---|
994 | |
---|
995 | /* We, however, have to decide this ourselves */ |
---|
996 | if ($this->file_exists (array( |
---|
997 | 'string' => $p->fake_full_path, |
---|
998 | 'relatives' => array ($p->mask) |
---|
999 | )) |
---|
1000 | ) |
---|
1001 | { |
---|
1002 | if (!$this->acl_check (array( |
---|
1003 | 'string' => $p->fake_full_path, |
---|
1004 | 'relatives' => array ($p->mask), |
---|
1005 | 'operation' => PHPGW_ACL_EDIT |
---|
1006 | ))) |
---|
1007 | { |
---|
1008 | return False; |
---|
1009 | } |
---|
1010 | |
---|
1011 | $vr = $this->set_attributes (array( |
---|
1012 | 'string' => $p->fake_full_path, |
---|
1013 | 'relatives' => array ($p->mask), |
---|
1014 | 'attributes' => array( |
---|
1015 | 'modifiedby_id' => $account_id, |
---|
1016 | 'modified' => $this->now |
---|
1017 | ) |
---|
1018 | ) |
---|
1019 | ); |
---|
1020 | } |
---|
1021 | else |
---|
1022 | { |
---|
1023 | if (!$this->acl_check (array( |
---|
1024 | 'string' => $p->fake_full_path, |
---|
1025 | 'relatives' => array ($p->mask), |
---|
1026 | 'operation' => PHPGW_ACL_ADD |
---|
1027 | )) |
---|
1028 | ) |
---|
1029 | { |
---|
1030 | return False; |
---|
1031 | } |
---|
1032 | |
---|
1033 | $query = $GLOBALS['phpgw']->db->query ("INSERT INTO phpgw_vfs (owner_id, directory, name) VALUES ($this->working_id, '". |
---|
1034 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."', '". |
---|
1035 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."')", __LINE__, __FILE__); |
---|
1036 | |
---|
1037 | $this->set_attributes(array( |
---|
1038 | 'string' => $p->fake_full_path, |
---|
1039 | 'relatives' => array ($p->mask), |
---|
1040 | 'attributes' => array ( |
---|
1041 | 'createdby_id' => $account_id, |
---|
1042 | 'created' => $this->now, |
---|
1043 | 'size' => 0, |
---|
1044 | 'deleteable' => 'Y', |
---|
1045 | 'app' => $currentapp |
---|
1046 | ) |
---|
1047 | ) |
---|
1048 | ); |
---|
1049 | $this->correct_attributes (array( |
---|
1050 | 'string' => $p->fake_full_path, |
---|
1051 | 'relatives' => array ($p->mask) |
---|
1052 | ) |
---|
1053 | ); |
---|
1054 | |
---|
1055 | $this->add_journal (array( |
---|
1056 | 'string' => $p->fake_full_path, |
---|
1057 | 'relatives' => array ($p->mask), |
---|
1058 | 'operation' => VFS_OPERATION_CREATED |
---|
1059 | ) |
---|
1060 | ); |
---|
1061 | } |
---|
1062 | |
---|
1063 | if ($rr || $vr || $query) |
---|
1064 | { |
---|
1065 | return True; |
---|
1066 | } |
---|
1067 | else |
---|
1068 | { |
---|
1069 | return False; |
---|
1070 | } |
---|
1071 | } |
---|
1072 | |
---|
1073 | /* |
---|
1074 | * See vfs_shared |
---|
1075 | * If $data['symlink'] the file is symlinked instead of copied |
---|
1076 | */ |
---|
1077 | function cp ($data) |
---|
1078 | { |
---|
1079 | if (!is_array ($data)) |
---|
1080 | { |
---|
1081 | $data = array (); |
---|
1082 | } |
---|
1083 | |
---|
1084 | $default_values = array |
---|
1085 | ( |
---|
1086 | 'relatives' => array (RELATIVE_CURRENT, RELATIVE_CURRENT) |
---|
1087 | ); |
---|
1088 | |
---|
1089 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
1090 | |
---|
1091 | $account_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
1092 | |
---|
1093 | $f = $this->path_parts (array( |
---|
1094 | 'string' => $data['from'], |
---|
1095 | 'relatives' => array ($data['relatives'][0]) |
---|
1096 | ) |
---|
1097 | ); |
---|
1098 | |
---|
1099 | $t = $this->path_parts (array( |
---|
1100 | 'string' => $data['to'], |
---|
1101 | 'relatives' => array ($data['relatives'][1]) |
---|
1102 | ) |
---|
1103 | ); |
---|
1104 | |
---|
1105 | if (!$this->acl_check (array( |
---|
1106 | 'string' => $f->fake_full_path, |
---|
1107 | 'relatives' => array ($f->mask), |
---|
1108 | 'operation' => PHPGW_ACL_READ |
---|
1109 | )) |
---|
1110 | ) |
---|
1111 | { |
---|
1112 | return False; |
---|
1113 | } |
---|
1114 | |
---|
1115 | if ($exists = $this->file_exists (array( |
---|
1116 | 'string' => $t->fake_full_path, |
---|
1117 | 'relatives' => array ($t->mask) |
---|
1118 | )) |
---|
1119 | ) |
---|
1120 | { |
---|
1121 | if (!$this->acl_check (array( |
---|
1122 | 'string' => $t->fake_full_path, |
---|
1123 | 'relatives' => array ($t->mask), |
---|
1124 | 'operation' => PHPGW_ACL_EDIT |
---|
1125 | )) |
---|
1126 | ) |
---|
1127 | { |
---|
1128 | return False; |
---|
1129 | } |
---|
1130 | } |
---|
1131 | else |
---|
1132 | { |
---|
1133 | if (!$this->acl_check (array( |
---|
1134 | 'string' => $t->fake_full_path, |
---|
1135 | 'relatives' => array ($t->mask), |
---|
1136 | 'operation' => PHPGW_ACL_ADD |
---|
1137 | )) |
---|
1138 | ) |
---|
1139 | { |
---|
1140 | return False; |
---|
1141 | } |
---|
1142 | } |
---|
1143 | |
---|
1144 | umask(0177); |
---|
1145 | |
---|
1146 | if ($this->file_type (array( |
---|
1147 | 'string' => $f->fake_full_path, |
---|
1148 | 'relatives' => array ($f->mask) |
---|
1149 | )) != 'Directory' |
---|
1150 | ) |
---|
1151 | { |
---|
1152 | if ($this->file_actions) |
---|
1153 | { |
---|
1154 | if (@$data['symlink']) |
---|
1155 | { |
---|
1156 | if ($exists) |
---|
1157 | { |
---|
1158 | @unlink($t->real_full_path); |
---|
1159 | } |
---|
1160 | if (!symlink($f->real_full_path, $t->real_full_path)) |
---|
1161 | { |
---|
1162 | return False; |
---|
1163 | } |
---|
1164 | } |
---|
1165 | elseif (!copy ($f->real_full_path, $t->real_full_path)) |
---|
1166 | { |
---|
1167 | return False; |
---|
1168 | } |
---|
1169 | |
---|
1170 | $size = filesize ($t->real_full_path); |
---|
1171 | } |
---|
1172 | else |
---|
1173 | { |
---|
1174 | $content = $this->read (array( |
---|
1175 | 'string' => $f->fake_full_path, |
---|
1176 | 'relatives' => array ($f->mask) |
---|
1177 | ) |
---|
1178 | ); |
---|
1179 | |
---|
1180 | $size = strlen ($content); |
---|
1181 | } |
---|
1182 | |
---|
1183 | if ($t->outside) |
---|
1184 | { |
---|
1185 | return True; |
---|
1186 | } |
---|
1187 | |
---|
1188 | $ls_array = $this->ls (array( |
---|
1189 | 'string' => $f->fake_full_path, |
---|
1190 | 'relatives' => array ($f->mask), |
---|
1191 | 'checksubdirs' => False, |
---|
1192 | 'mime_type' => False, |
---|
1193 | 'nofiles' => True |
---|
1194 | ) |
---|
1195 | ); |
---|
1196 | $record = $ls_array[0]; |
---|
1197 | |
---|
1198 | if ($this->file_exists (array( |
---|
1199 | 'string' => $data['to'], |
---|
1200 | 'relatives' => array ($data['relatives'][1]) |
---|
1201 | )) |
---|
1202 | ) |
---|
1203 | { |
---|
1204 | $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET owner_id='$this->working_id', directory='". |
---|
1205 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."', name='". |
---|
1206 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."' WHERE owner_id='$this->working_id' AND directory='". |
---|
1207 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."' AND name='". |
---|
1208 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."'" . $this->extra_sql (VFS_SQL_UPDATE), __LINE__, __FILE__); |
---|
1209 | |
---|
1210 | $set_attributes_array = array ( |
---|
1211 | 'createdby_id' => $account_id, |
---|
1212 | 'created' => $this->now, |
---|
1213 | 'size' => $size, |
---|
1214 | 'mime_type' => $record['mime_type'], |
---|
1215 | 'deleteable' => $record['deleteable'], |
---|
1216 | 'comment' => $record['comment'], |
---|
1217 | 'app' => $record['app'] |
---|
1218 | ); |
---|
1219 | |
---|
1220 | if (!$this->file_actions) |
---|
1221 | { |
---|
1222 | $set_attributes_array['content'] = $content; |
---|
1223 | } |
---|
1224 | |
---|
1225 | $this->set_attributes(array( |
---|
1226 | 'string' => $t->fake_full_path, |
---|
1227 | 'relatives' => array ($t->mask), |
---|
1228 | 'attributes' => $set_attributes_array |
---|
1229 | ) |
---|
1230 | ); |
---|
1231 | |
---|
1232 | $this->add_journal (array( |
---|
1233 | 'string' => $t->fake_full_path, |
---|
1234 | 'relatives' => array ($t->mask), |
---|
1235 | 'operation' => VFS_OPERATION_EDITED |
---|
1236 | ) |
---|
1237 | ); |
---|
1238 | } |
---|
1239 | else |
---|
1240 | { |
---|
1241 | $this->touch (array( |
---|
1242 | 'string' => $t->fake_full_path, |
---|
1243 | 'relatives' => array ($t->mask) |
---|
1244 | ) |
---|
1245 | ); |
---|
1246 | |
---|
1247 | $set_attributes_array = array ( |
---|
1248 | 'createdby_id' => $account_id, |
---|
1249 | 'created' => $this->now, |
---|
1250 | 'size' => $size, |
---|
1251 | 'mime_type' => $record['mime_type'], |
---|
1252 | 'deleteable' => $record['deleteable'], |
---|
1253 | 'comment' => $record['comment'], |
---|
1254 | 'app' => $record['app'] |
---|
1255 | ); |
---|
1256 | |
---|
1257 | if (!$this->file_actions) |
---|
1258 | { |
---|
1259 | $set_attributes_array['content'] = $content; |
---|
1260 | } |
---|
1261 | |
---|
1262 | $this->set_attributes(array( |
---|
1263 | 'string' => $t->fake_full_path, |
---|
1264 | 'relatives' => array ($t->mask), |
---|
1265 | 'attributes' => $set_attributes_array |
---|
1266 | ) |
---|
1267 | ); |
---|
1268 | } |
---|
1269 | $this->correct_attributes (array( |
---|
1270 | 'string' => $t->fake_full_path, |
---|
1271 | 'relatives' => array ($t->mask) |
---|
1272 | ) |
---|
1273 | ); |
---|
1274 | } |
---|
1275 | else /* It's a directory */ |
---|
1276 | { |
---|
1277 | /* First, make the initial directory */ |
---|
1278 | $this->mkdir (array( |
---|
1279 | 'string' => $data['to'], |
---|
1280 | 'relatives' => array ($data['relatives'][1]) |
---|
1281 | ) |
---|
1282 | ); |
---|
1283 | |
---|
1284 | /* Next, we create all the directories below the initial directory */ |
---|
1285 | foreach($this->ls (array( |
---|
1286 | 'string' => $f->fake_full_path, |
---|
1287 | 'relatives' => array ($f->mask), |
---|
1288 | 'checksubdirs' => True, |
---|
1289 | 'mime_type' => 'Directory' |
---|
1290 | )) as $entry) |
---|
1291 | { |
---|
1292 | $newdir = ereg_replace ("^$f->fake_full_path", "$t->fake_full_path", $entry['directory']); |
---|
1293 | $this->mkdir (array( |
---|
1294 | 'string' => $newdir.'/'.$entry['name'], |
---|
1295 | 'relatives' => array ($t->mask) |
---|
1296 | ) |
---|
1297 | ); |
---|
1298 | } |
---|
1299 | |
---|
1300 | /* Lastly, we copy the files over */ |
---|
1301 | foreach($this->ls (array( |
---|
1302 | 'string' => $f->fake_full_path, |
---|
1303 | 'relatives' => array ($f->mask) |
---|
1304 | )) as $entry) |
---|
1305 | { |
---|
1306 | if ($entry['mime_type'] == 'Directory') |
---|
1307 | { |
---|
1308 | continue; |
---|
1309 | } |
---|
1310 | |
---|
1311 | $newdir = ereg_replace ("^$f->fake_full_path", "$t->fake_full_path", $entry['directory']); |
---|
1312 | $this->cp (array( |
---|
1313 | 'from' => "$entry[directory]/$entry[name]", |
---|
1314 | 'to' => "$newdir/$entry[name]", |
---|
1315 | 'relatives' => array ($f->mask, $t->mask) |
---|
1316 | ) |
---|
1317 | ); |
---|
1318 | } |
---|
1319 | } |
---|
1320 | |
---|
1321 | if (!$f->outside) |
---|
1322 | { |
---|
1323 | $this->add_journal (array( |
---|
1324 | 'string' => $f->fake_full_path, |
---|
1325 | 'relatives' => array ($f->mask), |
---|
1326 | 'operation' => VFS_OPERATION_COPIED, |
---|
1327 | 'state_one' => NULL, |
---|
1328 | 'state_two' => $t->fake_full_path |
---|
1329 | ) |
---|
1330 | ); |
---|
1331 | } |
---|
1332 | |
---|
1333 | return True; |
---|
1334 | } |
---|
1335 | |
---|
1336 | /* |
---|
1337 | * See vfs_shared |
---|
1338 | */ |
---|
1339 | function mv ($data) |
---|
1340 | { |
---|
1341 | if (!is_array ($data)) |
---|
1342 | { |
---|
1343 | $data = array (); |
---|
1344 | } |
---|
1345 | |
---|
1346 | $default_values = array |
---|
1347 | ( |
---|
1348 | 'relatives' => array (RELATIVE_CURRENT, RELATIVE_CURRENT) |
---|
1349 | ); |
---|
1350 | |
---|
1351 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
1352 | |
---|
1353 | $account_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
1354 | |
---|
1355 | $f = $this->path_parts (array( |
---|
1356 | 'string' => $data['from'], |
---|
1357 | 'relatives' => array ($data['relatives'][0]) |
---|
1358 | ) |
---|
1359 | ); |
---|
1360 | |
---|
1361 | $t = $this->path_parts (array( |
---|
1362 | 'string' => $data['to'], |
---|
1363 | 'relatives' => array ($data['relatives'][1]) |
---|
1364 | ) |
---|
1365 | ); |
---|
1366 | |
---|
1367 | if (!$this->acl_check (array( |
---|
1368 | 'string' => $f->fake_full_path, |
---|
1369 | 'relatives' => array ($f->mask), |
---|
1370 | 'operation' => PHPGW_ACL_READ |
---|
1371 | )) |
---|
1372 | || !$this->acl_check (array( |
---|
1373 | 'string' => $f->fake_full_path, |
---|
1374 | 'relatives' => array ($f->mask), |
---|
1375 | 'operation' => PHPGW_ACL_DELETE |
---|
1376 | )) |
---|
1377 | ) |
---|
1378 | { |
---|
1379 | return False; |
---|
1380 | } |
---|
1381 | |
---|
1382 | if (!$this->acl_check (array( |
---|
1383 | 'string' => $t->fake_full_path, |
---|
1384 | 'relatives' => array ($t->mask), |
---|
1385 | 'operation' => PHPGW_ACL_ADD |
---|
1386 | )) |
---|
1387 | ) |
---|
1388 | { |
---|
1389 | return False; |
---|
1390 | } |
---|
1391 | |
---|
1392 | if ($this->file_exists (array( |
---|
1393 | 'string' => $t->fake_full_path, |
---|
1394 | 'relatives' => array ($t->mask) |
---|
1395 | )) |
---|
1396 | ) |
---|
1397 | { |
---|
1398 | if (!$this->acl_check (array( |
---|
1399 | 'string' => $t->fake_full_path, |
---|
1400 | 'relatives' => array ($t->mask), |
---|
1401 | 'operation' => PHPGW_ACL_EDIT |
---|
1402 | )) |
---|
1403 | ) |
---|
1404 | { |
---|
1405 | return False; |
---|
1406 | } |
---|
1407 | } |
---|
1408 | |
---|
1409 | umask (0177); |
---|
1410 | |
---|
1411 | /* We can't move directories into themselves */ |
---|
1412 | if (($this->file_type (array( |
---|
1413 | 'string' => $f->fake_full_path, |
---|
1414 | 'relatives' => array ($f->mask) |
---|
1415 | ) == 'Directory')) |
---|
1416 | && ereg ("^$f->fake_full_path", $t->fake_full_path) |
---|
1417 | ) |
---|
1418 | { |
---|
1419 | if (($t->fake_full_path == $f->fake_full_path) || substr ($t->fake_full_path, strlen ($f->fake_full_path), 1) == '/') |
---|
1420 | { |
---|
1421 | return False; |
---|
1422 | } |
---|
1423 | } |
---|
1424 | |
---|
1425 | if ($this->file_exists (array( |
---|
1426 | 'string' => $f->fake_full_path, |
---|
1427 | 'relatives' => array ($f->mask) |
---|
1428 | )) |
---|
1429 | ) |
---|
1430 | { |
---|
1431 | /* We get the listing now, because it will change after we update the database */ |
---|
1432 | $ls = $this->ls (array( |
---|
1433 | 'string' => $f->fake_full_path, |
---|
1434 | 'relatives' => array ($f->mask) |
---|
1435 | ) |
---|
1436 | ); |
---|
1437 | |
---|
1438 | if ($this->file_exists (array( |
---|
1439 | 'string' => $t->fake_full_path, |
---|
1440 | 'relatives' => array ($t->mask) |
---|
1441 | )) |
---|
1442 | ) |
---|
1443 | { |
---|
1444 | $this->rm (array( |
---|
1445 | 'string' => $t->fake_full_path, |
---|
1446 | 'relatives' => array ($t->mask) |
---|
1447 | ) |
---|
1448 | ); |
---|
1449 | } |
---|
1450 | |
---|
1451 | /* |
---|
1452 | We add the journal entry now, before we delete. This way the mime_type |
---|
1453 | field will be updated to 'journal-deleted' when the file is actually deleted |
---|
1454 | */ |
---|
1455 | if (!$f->outside) |
---|
1456 | { |
---|
1457 | $this->add_journal (array( |
---|
1458 | 'string' => $f->fake_full_path, |
---|
1459 | 'relatives' => array ($f->mask), |
---|
1460 | 'operation' => VFS_OPERATION_MOVED, |
---|
1461 | 'state_one' => $f->fake_full_path, |
---|
1462 | 'state_two' => $t->fake_full_path |
---|
1463 | ) |
---|
1464 | ); |
---|
1465 | } |
---|
1466 | |
---|
1467 | /* |
---|
1468 | If the from file is outside, it won't have a database entry, |
---|
1469 | so we have to touch it and find the size |
---|
1470 | */ |
---|
1471 | if ($f->outside) |
---|
1472 | { |
---|
1473 | $size = filesize ($f->real_full_path); |
---|
1474 | |
---|
1475 | $this->touch (array( |
---|
1476 | 'string' => $t->fake_full_path, |
---|
1477 | 'relatives' => array ($t->mask) |
---|
1478 | ) |
---|
1479 | ); |
---|
1480 | $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET size=$size WHERE directory='". |
---|
1481 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."' AND name='". |
---|
1482 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE)), __LINE__, __FILE__); |
---|
1483 | } |
---|
1484 | elseif (!$t->outside) |
---|
1485 | { |
---|
1486 | $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET name='". |
---|
1487 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."', directory='". |
---|
1488 | $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."' WHERE directory='". |
---|
1489 | $GLOBALS['phpgw']->db->db_addslashes($f->fake_leading_dirs_clean)."' AND name='". |
---|
1490 | $GLOBALS['phpgw']->db->db_addslashes($f->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE)), __LINE__, __FILE__); |
---|
1491 | } |
---|
1492 | |
---|
1493 | $this->set_attributes(array( |
---|
1494 | 'string' => $t->fake_full_path, |
---|
1495 | 'relatives' => array ($t->mask), |
---|
1496 | 'attributes' => array ( |
---|
1497 | 'modifiedby_id' => $account_id, |
---|
1498 | 'modified' => $this->now |
---|
1499 | ) |
---|
1500 | ) |
---|
1501 | ); |
---|
1502 | |
---|
1503 | $this->correct_attributes (array( |
---|
1504 | 'string' => $t->fake_full_path, |
---|
1505 | 'relatives' => array ($t->mask) |
---|
1506 | ) |
---|
1507 | ); |
---|
1508 | |
---|
1509 | if ($this->file_actions) |
---|
1510 | { |
---|
1511 | $rr = rename ($f->real_full_path, $t->real_full_path); |
---|
1512 | } |
---|
1513 | |
---|
1514 | /* |
---|
1515 | This removes the original entry from the database |
---|
1516 | The actual file is already deleted because of the rename () above |
---|
1517 | */ |
---|
1518 | if ($t->outside) |
---|
1519 | { |
---|
1520 | $this->rm (array( |
---|
1521 | 'string' => $f->fake_full_path, |
---|
1522 | 'relatives' => $f->mask |
---|
1523 | ) |
---|
1524 | ); |
---|
1525 | } |
---|
1526 | } |
---|
1527 | else |
---|
1528 | { |
---|
1529 | return False; |
---|
1530 | } |
---|
1531 | |
---|
1532 | if ($this->file_type (array( |
---|
1533 | 'string' => $t->fake_full_path, |
---|
1534 | 'relatives' => array ($t->mask) |
---|
1535 | )) == 'Directory' |
---|
1536 | ) |
---|
1537 | { |
---|
1538 | /* We got $ls from above, before we renamed the directory */ |
---|
1539 | foreach ($ls as $entry) |
---|
1540 | { |
---|
1541 | $newdir = ereg_replace ("^$f->fake_full_path", $t->fake_full_path, $entry['directory']); |
---|
1542 | $newdir_clean = $this->clean_string (array ('string' => $newdir)); |
---|
1543 | |
---|
1544 | $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET directory='". |
---|
1545 | $GLOBALS['phpgw']->db->db_addslashes($newdir_clean)."' WHERE file_id='$entry[file_id]'" . |
---|
1546 | $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE)), __LINE__, __FILE__); |
---|
1547 | $this->correct_attributes (array( |
---|
1548 | 'string' => "$newdir/$entry[name]", |
---|
1549 | 'relatives' => array ($t->mask) |
---|
1550 | ) |
---|
1551 | ); |
---|
1552 | } |
---|
1553 | } |
---|
1554 | |
---|
1555 | $this->add_journal (array( |
---|
1556 | 'string' => $t->fake_full_path, |
---|
1557 | 'relatives' => array ($t->mask), |
---|
1558 | 'operation' => VFS_OPERATION_MOVED, |
---|
1559 | 'state_one' => $f->fake_full_path, |
---|
1560 | 'state_two' => $t->fake_full_path |
---|
1561 | ) |
---|
1562 | ); |
---|
1563 | |
---|
1564 | return True; |
---|
1565 | } |
---|
1566 | |
---|
1567 | /* |
---|
1568 | * See vfs_shared |
---|
1569 | */ |
---|
1570 | function rm ($data) |
---|
1571 | { |
---|
1572 | if (!is_array ($data)) |
---|
1573 | { |
---|
1574 | $data = array (); |
---|
1575 | } |
---|
1576 | |
---|
1577 | $default_values = array |
---|
1578 | ( |
---|
1579 | 'relatives' => array (RELATIVE_CURRENT) |
---|
1580 | ); |
---|
1581 | |
---|
1582 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
1583 | |
---|
1584 | $p = $this->path_parts (array( |
---|
1585 | 'string' => $data['string'], |
---|
1586 | 'relatives' => array ($data['relatives'][0]) |
---|
1587 | ) |
---|
1588 | ); |
---|
1589 | |
---|
1590 | if (!$this->acl_check (array( |
---|
1591 | 'string' => $p->fake_full_path, |
---|
1592 | 'relatives' => array ($p->mask), |
---|
1593 | 'operation' => PHPGW_ACL_DELETE |
---|
1594 | )) |
---|
1595 | ) |
---|
1596 | { |
---|
1597 | return False; |
---|
1598 | } |
---|
1599 | |
---|
1600 | if (!$this->file_exists (array( |
---|
1601 | 'string' => $data['string'], |
---|
1602 | 'relatives' => array ($data['relatives'][0]) |
---|
1603 | )) |
---|
1604 | ) |
---|
1605 | { |
---|
1606 | if ($this->file_actions) |
---|
1607 | { |
---|
1608 | $rr = unlink ($p->real_full_path); |
---|
1609 | } |
---|
1610 | else |
---|
1611 | { |
---|
1612 | $rr = True; |
---|
1613 | } |
---|
1614 | |
---|
1615 | if ($rr) |
---|
1616 | { |
---|
1617 | return True; |
---|
1618 | } |
---|
1619 | else |
---|
1620 | { |
---|
1621 | return False; |
---|
1622 | } |
---|
1623 | } |
---|
1624 | |
---|
1625 | if ($this->file_type (array( |
---|
1626 | 'string' => $data['string'], |
---|
1627 | 'relatives' => array ($data['relatives'][0]) |
---|
1628 | )) != 'Directory' |
---|
1629 | ) |
---|
1630 | { |
---|
1631 | $this->add_journal (array( |
---|
1632 | 'string' => $p->fake_full_path, |
---|
1633 | 'relatives' => array ($p->mask), |
---|
1634 | 'operation' => VFS_OPERATION_DELETED |
---|
1635 | ) |
---|
1636 | ); |
---|
1637 | |
---|
1638 | $query = $GLOBALS['phpgw']->db->query ("DELETE FROM phpgw_vfs WHERE directory='". |
---|
1639 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
1640 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'".$this->extra_sql (array ('query_type' => VFS_SQL_DELETE)), __LINE__, __FILE__); |
---|
1641 | |
---|
1642 | if ($this->file_actions) |
---|
1643 | { |
---|
1644 | $rr = unlink ($p->real_full_path); |
---|
1645 | } |
---|
1646 | else |
---|
1647 | { |
---|
1648 | $rr = True; |
---|
1649 | } |
---|
1650 | |
---|
1651 | if ($query || $rr) |
---|
1652 | { |
---|
1653 | return True; |
---|
1654 | } |
---|
1655 | else |
---|
1656 | { |
---|
1657 | return False; |
---|
1658 | } |
---|
1659 | } |
---|
1660 | else |
---|
1661 | { |
---|
1662 | $ls = $this->ls (array( |
---|
1663 | 'string' => $p->fake_full_path, |
---|
1664 | 'relatives' => array ($p->mask) |
---|
1665 | ) |
---|
1666 | ); |
---|
1667 | |
---|
1668 | /* First, we cycle through the entries and delete the files */ |
---|
1669 | foreach($ls as $entry) |
---|
1670 | { |
---|
1671 | if ($entry['mime_type'] == 'Directory') |
---|
1672 | { |
---|
1673 | continue; |
---|
1674 | } |
---|
1675 | |
---|
1676 | $this->rm (array( |
---|
1677 | 'string' => "$entry[directory]/$entry[name]", |
---|
1678 | 'relatives' => array ($p->mask) |
---|
1679 | ) |
---|
1680 | ); |
---|
1681 | } |
---|
1682 | |
---|
1683 | /* Now we cycle through again and delete the directories */ |
---|
1684 | foreach ($ls as $entry) |
---|
1685 | { |
---|
1686 | if ($entry['mime_type'] != 'Directory') |
---|
1687 | { |
---|
1688 | continue; |
---|
1689 | } |
---|
1690 | |
---|
1691 | /* Only the best in confusing recursion */ |
---|
1692 | $this->rm (array( |
---|
1693 | 'string' => "$entry[directory]/$entry[name]", |
---|
1694 | 'relatives' => array ($p->mask) |
---|
1695 | ) |
---|
1696 | ); |
---|
1697 | } |
---|
1698 | |
---|
1699 | /* If the directory is linked, we delete the placeholder directory */ |
---|
1700 | $ls_array = $this->ls (array( |
---|
1701 | 'string' => $p->fake_full_path, |
---|
1702 | 'relatives' => array ($p->mask), |
---|
1703 | 'checksubdirs' => False, |
---|
1704 | 'mime_type' => False, |
---|
1705 | 'nofiles' => True |
---|
1706 | ) |
---|
1707 | ); |
---|
1708 | $link_info = $ls_array[0]; |
---|
1709 | |
---|
1710 | if ($link_info['link_directory'] && $link_info['link_name']) |
---|
1711 | { |
---|
1712 | $path = $this->path_parts (array( |
---|
1713 | 'string' => $link_info['directory'] . '/' . $link_info['name'], |
---|
1714 | 'relatives' => array ($p->mask), |
---|
1715 | 'nolinks' => True |
---|
1716 | ) |
---|
1717 | ); |
---|
1718 | |
---|
1719 | if ($this->file_actions) |
---|
1720 | { |
---|
1721 | rmdir ($path->real_full_path); |
---|
1722 | } |
---|
1723 | } |
---|
1724 | |
---|
1725 | /* Last, we delete the directory itself */ |
---|
1726 | $this->add_journal (array( |
---|
1727 | 'string' => $p->fake_full_path, |
---|
1728 | 'relatives' => array ($p->mask), |
---|
1729 | 'operaton' => VFS_OPERATION_DELETED |
---|
1730 | ) |
---|
1731 | ); |
---|
1732 | |
---|
1733 | $query = $GLOBALS['phpgw']->db->query ("DELETE FROM phpgw_vfs WHERE directory='". |
---|
1734 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
1735 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . |
---|
1736 | $this->extra_sql (array ('query_type' => VFS_SQL_DELETE)), __LINE__, __FILE__); |
---|
1737 | |
---|
1738 | if ($this->file_actions) |
---|
1739 | { |
---|
1740 | rmdir ($p->real_full_path); |
---|
1741 | } |
---|
1742 | |
---|
1743 | return True; |
---|
1744 | } |
---|
1745 | } |
---|
1746 | |
---|
1747 | /* |
---|
1748 | * See vfs_shared |
---|
1749 | */ |
---|
1750 | function mkdir ($data) |
---|
1751 | { |
---|
1752 | if (!is_array ($data)) |
---|
1753 | { |
---|
1754 | $data = array (); |
---|
1755 | } |
---|
1756 | |
---|
1757 | $default_values = array |
---|
1758 | ( |
---|
1759 | 'relatives' => array (RELATIVE_CURRENT) |
---|
1760 | ); |
---|
1761 | |
---|
1762 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
1763 | |
---|
1764 | $account_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
1765 | $currentapp = $GLOBALS['phpgw_info']['flags']['currentapp']; |
---|
1766 | |
---|
1767 | $p = $this->path_parts (array( |
---|
1768 | 'string' => $data['string'], |
---|
1769 | 'relatives' => array ($data['relatives'][0]) |
---|
1770 | ) |
---|
1771 | ); |
---|
1772 | |
---|
1773 | if (!$this->acl_check (array( |
---|
1774 | 'string' => $p->fake_full_path, |
---|
1775 | 'relatives' => array ($p->mask), |
---|
1776 | 'operation' => PHPGW_ACL_ADD) |
---|
1777 | ) |
---|
1778 | ) |
---|
1779 | { |
---|
1780 | return False; |
---|
1781 | } |
---|
1782 | |
---|
1783 | /* We don't allow /'s in dir names, of course */ |
---|
1784 | if (ereg ("/", $p->fake_name)) |
---|
1785 | { |
---|
1786 | return False; |
---|
1787 | } |
---|
1788 | |
---|
1789 | umask (077); |
---|
1790 | |
---|
1791 | if ($this->file_actions) |
---|
1792 | { |
---|
1793 | if (!@is_dir($p->real_leading_dirs_clean)) // eg. /home or /group does not exist |
---|
1794 | { |
---|
1795 | if (!@mkdir($p->real_leading_dirs_clean,0770)) // ==> create it |
---|
1796 | { |
---|
1797 | return False; |
---|
1798 | } |
---|
1799 | } |
---|
1800 | if (@is_dir($p->real_full_path)) // directory already exists |
---|
1801 | { |
---|
1802 | $this->update_real($data,True); // update its contents |
---|
1803 | } |
---|
1804 | elseif (!@mkdir ($p->real_full_path, 0770)) |
---|
1805 | { |
---|
1806 | return False; |
---|
1807 | } |
---|
1808 | } |
---|
1809 | |
---|
1810 | if (!$this->file_exists (array( |
---|
1811 | 'string' => $p->fake_full_path, |
---|
1812 | 'relatives' => array ($p->mask) |
---|
1813 | )) |
---|
1814 | ) |
---|
1815 | { |
---|
1816 | $query = $GLOBALS['phpgw']->db->query ("INSERT INTO phpgw_vfs (owner_id, name, directory) VALUES ($this->working_id, '". |
---|
1817 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."', '". |
---|
1818 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."')", __LINE__, __FILE__); |
---|
1819 | |
---|
1820 | $this->set_attributes(array( |
---|
1821 | 'string' => $p->fake_full_path, |
---|
1822 | 'relatives' => array ($p->mask), |
---|
1823 | 'attributes' => array ( |
---|
1824 | 'createdby_id' => $account_id, |
---|
1825 | 'size' => 4096, |
---|
1826 | 'mime_type' => 'Directory', |
---|
1827 | 'created' => $this->now, |
---|
1828 | 'deleteable' => 'Y', |
---|
1829 | 'app' => $currentapp |
---|
1830 | ) |
---|
1831 | ) |
---|
1832 | ); |
---|
1833 | |
---|
1834 | $this->correct_attributes (array( |
---|
1835 | 'string' => $p->fake_full_path, |
---|
1836 | 'relatives' => array ($p->mask) |
---|
1837 | ) |
---|
1838 | ); |
---|
1839 | |
---|
1840 | $this->add_journal (array( |
---|
1841 | 'string' => $p->fake_full_path, |
---|
1842 | 'relatives' => array ($p->mask), |
---|
1843 | 'operation' => VFS_OPERATION_CREATED |
---|
1844 | ) |
---|
1845 | ); |
---|
1846 | } |
---|
1847 | else |
---|
1848 | { |
---|
1849 | return False; |
---|
1850 | } |
---|
1851 | |
---|
1852 | return True; |
---|
1853 | } |
---|
1854 | |
---|
1855 | /* |
---|
1856 | * See vfs_shared |
---|
1857 | */ |
---|
1858 | function make_link ($data) |
---|
1859 | { |
---|
1860 | if (!is_array ($data)) |
---|
1861 | { |
---|
1862 | $data = array (); |
---|
1863 | } |
---|
1864 | |
---|
1865 | $default_values = array |
---|
1866 | ( |
---|
1867 | 'relatives' => array (RELATIVE_CURRENT, RELATIVE_CURRENT) |
---|
1868 | ); |
---|
1869 | |
---|
1870 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
1871 | |
---|
1872 | $account_id = $GLOBALS['phpgw_info']['user']['account_id']; |
---|
1873 | $currentapp = $GLOBALS['phpgw_info']['flags']['currentapp']; |
---|
1874 | |
---|
1875 | $vp = $this->path_parts (array( |
---|
1876 | 'string' => $data['vdir'], |
---|
1877 | 'relatives' => array ($data['relatives'][0]) |
---|
1878 | ) |
---|
1879 | ); |
---|
1880 | |
---|
1881 | $rp = $this->path_parts (array( |
---|
1882 | 'string' => $data['rdir'], |
---|
1883 | 'relatives' => array ($data['relatives'][1]) |
---|
1884 | ) |
---|
1885 | ); |
---|
1886 | |
---|
1887 | if (!$this->acl_check (array( |
---|
1888 | 'string' => $vp->fake_full_path, |
---|
1889 | 'relatives' => array ($vp->mask), |
---|
1890 | 'operation' => PHPGW_ACL_ADD |
---|
1891 | )) |
---|
1892 | ) |
---|
1893 | { |
---|
1894 | return False; |
---|
1895 | } |
---|
1896 | |
---|
1897 | if ((!$this->file_exists (array( |
---|
1898 | 'string' => $rp->real_full_path, |
---|
1899 | 'relatives' => array ($rp->mask) |
---|
1900 | ))) |
---|
1901 | && !mkdir ($rp->real_full_path, 0770)) |
---|
1902 | { |
---|
1903 | return False; |
---|
1904 | } |
---|
1905 | |
---|
1906 | if (!$this->mkdir (array( |
---|
1907 | 'string' => $vp->fake_full_path, |
---|
1908 | 'relatives' => array ($vp->mask) |
---|
1909 | )) |
---|
1910 | ) |
---|
1911 | { |
---|
1912 | return False; |
---|
1913 | } |
---|
1914 | |
---|
1915 | $size = $this->get_size (array( |
---|
1916 | 'string' => $rp->real_full_path, |
---|
1917 | 'relatives' => array ($rp->mask) |
---|
1918 | ) |
---|
1919 | ); |
---|
1920 | |
---|
1921 | $this->set_attributes(array( |
---|
1922 | 'string' => $vp->fake_full_path, |
---|
1923 | 'relatives' => array ($vp->mask), |
---|
1924 | 'attributes' => array ( |
---|
1925 | 'link_directory' => $rp->real_leading_dirs, |
---|
1926 | 'link_name' => $rp->real_name, |
---|
1927 | 'size' => $size |
---|
1928 | ) |
---|
1929 | ) |
---|
1930 | ); |
---|
1931 | |
---|
1932 | $this->correct_attributes (array( |
---|
1933 | 'string' => $vp->fake_full_path, |
---|
1934 | 'relatives' => array ($vp->mask) |
---|
1935 | ) |
---|
1936 | ); |
---|
1937 | |
---|
1938 | return True; |
---|
1939 | } |
---|
1940 | |
---|
1941 | /* |
---|
1942 | * See vfs_shared |
---|
1943 | */ |
---|
1944 | function set_attributes ($data) |
---|
1945 | { |
---|
1946 | if (!is_array ($data)) |
---|
1947 | { |
---|
1948 | $data = array (); |
---|
1949 | } |
---|
1950 | |
---|
1951 | $default_values = array |
---|
1952 | ( |
---|
1953 | 'relatives' => array (RELATIVE_CURRENT), |
---|
1954 | 'attributes' => array () |
---|
1955 | ); |
---|
1956 | |
---|
1957 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
1958 | |
---|
1959 | $p = $this->path_parts (array( |
---|
1960 | 'string' => $data['string'], |
---|
1961 | 'relatives' => array ($data['relatives'][0]) |
---|
1962 | ) |
---|
1963 | ); |
---|
1964 | |
---|
1965 | /* |
---|
1966 | This is kind of trivial, given that set_attributes () can change owner_id, |
---|
1967 | size, etc. |
---|
1968 | */ |
---|
1969 | if (!$this->acl_check (array( |
---|
1970 | 'string' => $p->fake_full_path, |
---|
1971 | 'relatives' => array ($p->mask), |
---|
1972 | 'operation' => PHPGW_ACL_EDIT |
---|
1973 | )) |
---|
1974 | ) |
---|
1975 | { |
---|
1976 | return False; |
---|
1977 | } |
---|
1978 | |
---|
1979 | if (!$this->file_exists (array( |
---|
1980 | 'string' => $data['string'], |
---|
1981 | 'relatives' => array ($data['relatives'][0]) |
---|
1982 | )) |
---|
1983 | ) |
---|
1984 | { |
---|
1985 | return False; |
---|
1986 | } |
---|
1987 | |
---|
1988 | /* |
---|
1989 | All this voodoo just decides which attributes to update |
---|
1990 | depending on if the attribute was supplied in the 'attributes' array |
---|
1991 | */ |
---|
1992 | |
---|
1993 | $ls_array = $this->ls (array( |
---|
1994 | 'string' => $p->fake_full_path, |
---|
1995 | 'relatives' => array ($p->mask), |
---|
1996 | 'checksubdirs' => False, |
---|
1997 | 'nofiles' => True |
---|
1998 | ) |
---|
1999 | ); |
---|
2000 | $record = $ls_array[0]; |
---|
2001 | |
---|
2002 | $sql = 'UPDATE phpgw_vfs SET '; |
---|
2003 | |
---|
2004 | $change_attributes = 0; |
---|
2005 | |
---|
2006 | foreach ($this->attributes as $attribute) |
---|
2007 | { |
---|
2008 | if (isset ($data['attributes'][$attribute])) |
---|
2009 | { |
---|
2010 | /* |
---|
2011 | Indicate that the EDITED_COMMENT operation needs to be journaled, |
---|
2012 | but only if the comment changed |
---|
2013 | */ |
---|
2014 | if ($attribute == 'comment' && $data['attributes'][$attribute] != $record[$attribute]) |
---|
2015 | { |
---|
2016 | $edited_comment = 1; |
---|
2017 | } |
---|
2018 | |
---|
2019 | if ($change_attributes > 0) |
---|
2020 | { |
---|
2021 | $sql .= ', '; |
---|
2022 | } |
---|
2023 | |
---|
2024 | // RalfBecker 2004/07/24: |
---|
2025 | // this is only a hack to fix bug [ 991222 ] Error uploading file |
---|
2026 | // the whole class need to be reworked with the new db-functions |
---|
2027 | if (!isset($this->column_defs)) |
---|
2028 | { |
---|
2029 | $table_defs = $GLOBALS['phpgw']->db->get_table_definitions('phpgwapi','phpgw_vfs'); |
---|
2030 | $this->column_defs = $table_defs['fd']; |
---|
2031 | } |
---|
2032 | $sql .= $attribute.'=' .$GLOBALS['phpgw']->db->quote($data['attributes'][$attribute],$this->column_defs[$attribute]['type']); |
---|
2033 | |
---|
2034 | $change_attributes++; |
---|
2035 | } |
---|
2036 | } |
---|
2037 | |
---|
2038 | if (!$change_attributes) |
---|
2039 | { |
---|
2040 | return True; // nothing to do |
---|
2041 | } |
---|
2042 | $sql .= ' WHERE file_id='.(int) $record['file_id']; |
---|
2043 | $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE)); |
---|
2044 | $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__); |
---|
2045 | |
---|
2046 | if ($query) |
---|
2047 | { |
---|
2048 | if ($edited_comment) |
---|
2049 | { |
---|
2050 | $this->add_journal (array( |
---|
2051 | 'string' => $p->fake_full_path, |
---|
2052 | 'relatives' => array ($p->mask), |
---|
2053 | 'operation' => VFS_OPERATION_EDITED_COMMENT |
---|
2054 | ) |
---|
2055 | ); |
---|
2056 | } |
---|
2057 | |
---|
2058 | return True; |
---|
2059 | } |
---|
2060 | else |
---|
2061 | { |
---|
2062 | return False; |
---|
2063 | } |
---|
2064 | } |
---|
2065 | |
---|
2066 | /*! |
---|
2067 | @function correct_attributes |
---|
2068 | @abstract Set the correct attributes for 'string' (e.g. owner) |
---|
2069 | @param string File/directory to correct attributes of |
---|
2070 | @param relatives Relativity array |
---|
2071 | @result Boolean True/False |
---|
2072 | */ |
---|
2073 | function correct_attributes ($data) |
---|
2074 | { |
---|
2075 | if (!is_array ($data)) |
---|
2076 | { |
---|
2077 | $data = array (); |
---|
2078 | } |
---|
2079 | |
---|
2080 | $default_values = array |
---|
2081 | ( |
---|
2082 | 'relatives' => array (RELATIVE_CURRENT) |
---|
2083 | ); |
---|
2084 | |
---|
2085 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2086 | |
---|
2087 | $p = $this->path_parts (array( |
---|
2088 | 'string' => $data['string'], |
---|
2089 | 'relatives' => array ($data['relatives'][0]) |
---|
2090 | ) |
---|
2091 | ); |
---|
2092 | |
---|
2093 | if ($p->fake_leading_dirs != $this->fakebase && $p->fake_leading_dirs != '/') |
---|
2094 | { |
---|
2095 | $ls_array = $this->ls (array( |
---|
2096 | 'string' => $p->fake_leading_dirs, |
---|
2097 | 'relatives' => array ($p->mask), |
---|
2098 | 'checksubdirs' => False, |
---|
2099 | 'nofiles' => True |
---|
2100 | ) |
---|
2101 | ); |
---|
2102 | $set_attributes_array = Array( |
---|
2103 | 'owner_id' => $ls_array[0]['owner_id'] |
---|
2104 | ); |
---|
2105 | } |
---|
2106 | elseif (preg_match ("+^$this->fakebase\/(.*)$+U", $p->fake_full_path, $matches)) |
---|
2107 | { |
---|
2108 | $set_attributes_array = Array( |
---|
2109 | 'owner_id' => $GLOBALS['phpgw']->accounts->name2id ($matches[1]) |
---|
2110 | ); |
---|
2111 | } |
---|
2112 | else |
---|
2113 | { |
---|
2114 | $set_attributes_array = Array( |
---|
2115 | 'owner_id' => 0 |
---|
2116 | ); |
---|
2117 | } |
---|
2118 | |
---|
2119 | $this->set_attributes (array( |
---|
2120 | 'string' => $p->fake_full_name, |
---|
2121 | 'relatives' => array ($p->mask), |
---|
2122 | 'attributes' => $set_attributes_array |
---|
2123 | ) |
---|
2124 | ); |
---|
2125 | |
---|
2126 | return True; |
---|
2127 | } |
---|
2128 | |
---|
2129 | /* |
---|
2130 | * See vfs_shared |
---|
2131 | */ |
---|
2132 | function file_type ($data) |
---|
2133 | { |
---|
2134 | if (!is_array ($data)) |
---|
2135 | { |
---|
2136 | $data = array (); |
---|
2137 | } |
---|
2138 | |
---|
2139 | $default_values = array |
---|
2140 | ( |
---|
2141 | 'relatives' => array (RELATIVE_CURRENT) |
---|
2142 | ); |
---|
2143 | |
---|
2144 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2145 | |
---|
2146 | $p = $this->path_parts (array( |
---|
2147 | 'string' => $data['string'], |
---|
2148 | 'relatives' => array ($data['relatives'][0]) |
---|
2149 | ) |
---|
2150 | ); |
---|
2151 | |
---|
2152 | if (!$this->acl_check (array( |
---|
2153 | 'string' => $p->fake_full_path, |
---|
2154 | 'relatives' => array ($p->mask), |
---|
2155 | 'operation' => PHPGW_ACL_READ, |
---|
2156 | 'must_exist' => True |
---|
2157 | )) |
---|
2158 | ) |
---|
2159 | { |
---|
2160 | return False; |
---|
2161 | } |
---|
2162 | |
---|
2163 | if ($p->outside) |
---|
2164 | { |
---|
2165 | if (is_dir ($p->real_full_path)) |
---|
2166 | { |
---|
2167 | return ('Directory'); |
---|
2168 | } |
---|
2169 | |
---|
2170 | /* |
---|
2171 | We don't return an empty string here, because it may still match with a database query |
---|
2172 | because of linked directories |
---|
2173 | */ |
---|
2174 | } |
---|
2175 | |
---|
2176 | /* |
---|
2177 | We don't use ls () because it calls file_type () to determine if it has been |
---|
2178 | passed a directory |
---|
2179 | */ |
---|
2180 | $db2 = $GLOBALS['phpgw']->db; |
---|
2181 | $db2->query ("SELECT mime_type FROM phpgw_vfs WHERE directory='". |
---|
2182 | $db2->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
2183 | $db2->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__); |
---|
2184 | $db2->next_record (); |
---|
2185 | $mime_type = $db2->Record['mime_type']; |
---|
2186 | if(!$mime_type) |
---|
2187 | { |
---|
2188 | $mime_type = $this->get_ext_mime_type (array ('string' => $data['string'])); |
---|
2189 | { |
---|
2190 | $db2->query ("UPDATE phpgw_vfs SET mime_type='$mime_type' WHERE directory='". |
---|
2191 | $db2->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
2192 | $db2->db_addslashes($p->fake_name_clean)."'" . |
---|
2193 | $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__); |
---|
2194 | } |
---|
2195 | } |
---|
2196 | |
---|
2197 | return $mime_type; |
---|
2198 | } |
---|
2199 | |
---|
2200 | /* |
---|
2201 | * See vfs_shared |
---|
2202 | */ |
---|
2203 | function file_exists ($data) |
---|
2204 | { |
---|
2205 | if (!is_array ($data)) |
---|
2206 | { |
---|
2207 | $data = array (); |
---|
2208 | } |
---|
2209 | |
---|
2210 | $default_values = array |
---|
2211 | ( |
---|
2212 | 'relatives' => array (RELATIVE_CURRENT) |
---|
2213 | ); |
---|
2214 | |
---|
2215 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2216 | |
---|
2217 | $p = $this->path_parts (array( |
---|
2218 | 'string' => $data['string'], |
---|
2219 | 'relatives' => array ($data['relatives'][0]) |
---|
2220 | ) |
---|
2221 | ); |
---|
2222 | |
---|
2223 | if ($p->outside) |
---|
2224 | { |
---|
2225 | $rr = file_exists ($p->real_full_path); |
---|
2226 | |
---|
2227 | return $rr; |
---|
2228 | } |
---|
2229 | |
---|
2230 | $db2 = $GLOBALS['phpgw']->db; |
---|
2231 | $db2->query ("SELECT name FROM phpgw_vfs WHERE directory='". |
---|
2232 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
2233 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__); |
---|
2234 | |
---|
2235 | if ($db2->next_record ()) |
---|
2236 | { |
---|
2237 | return True; |
---|
2238 | } |
---|
2239 | else |
---|
2240 | { |
---|
2241 | return False; |
---|
2242 | } |
---|
2243 | } |
---|
2244 | |
---|
2245 | /* |
---|
2246 | * See vfs_shared |
---|
2247 | */ |
---|
2248 | function get_size ($data) |
---|
2249 | { |
---|
2250 | if (!is_array ($data)) |
---|
2251 | { |
---|
2252 | $data = array (); |
---|
2253 | } |
---|
2254 | |
---|
2255 | $default_values = array |
---|
2256 | ( |
---|
2257 | 'relatives' => array (RELATIVE_CURRENT), |
---|
2258 | 'checksubdirs' => True |
---|
2259 | ); |
---|
2260 | |
---|
2261 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2262 | |
---|
2263 | $p = $this->path_parts (array( |
---|
2264 | 'string' => $data['string'], |
---|
2265 | 'relatives' => array ($data['relatives'][0]) |
---|
2266 | ) |
---|
2267 | ); |
---|
2268 | |
---|
2269 | if (!$this->acl_check (array( |
---|
2270 | 'string' => $p->fake_full_path, |
---|
2271 | 'relatives' => array ($p->mask), |
---|
2272 | 'operation' => PHPGW_ACL_READ, |
---|
2273 | 'must_exist' => True |
---|
2274 | )) |
---|
2275 | ) |
---|
2276 | { |
---|
2277 | return False; |
---|
2278 | } |
---|
2279 | |
---|
2280 | /* |
---|
2281 | WIP - this should run through all of the subfiles/directories in the directory and tally up |
---|
2282 | their sizes. Should modify ls () to be able to return a list for files outside the virtual root |
---|
2283 | */ |
---|
2284 | if ($p->outside) |
---|
2285 | { |
---|
2286 | $size = filesize ($p->real_full_path); |
---|
2287 | |
---|
2288 | return $size; |
---|
2289 | } |
---|
2290 | |
---|
2291 | foreach($this->ls (array( |
---|
2292 | 'string' => $p->fake_full_path, |
---|
2293 | 'relatives' => array ($p->mask), |
---|
2294 | 'checksubdirs' => $data['checksubdirs'], |
---|
2295 | 'nofiles' => !$data['checksubdirs'] |
---|
2296 | )) as $file_array) |
---|
2297 | { |
---|
2298 | /* |
---|
2299 | Make sure the file is in the directory we want, and not |
---|
2300 | some deeper nested directory with a similar name |
---|
2301 | */ |
---|
2302 | /* |
---|
2303 | if (@!ereg ('^' . $file_array['directory'], $p->fake_full_path)) |
---|
2304 | { |
---|
2305 | continue; |
---|
2306 | } |
---|
2307 | */ |
---|
2308 | |
---|
2309 | $size += $file_array['size']; |
---|
2310 | } |
---|
2311 | |
---|
2312 | if ($data['checksubdirs']) |
---|
2313 | { |
---|
2314 | $query = $GLOBALS['phpgw']->db->query ("SELECT size FROM phpgw_vfs WHERE directory='". |
---|
2315 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
2316 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . |
---|
2317 | $this->extra_sql (array ('query_text' => VFS_SQL_SELECT))); |
---|
2318 | $GLOBALS['phpgw']->db->next_record (); |
---|
2319 | $size += $GLOBALS['phpgw']->db->Record[0]; |
---|
2320 | } |
---|
2321 | |
---|
2322 | return $size; |
---|
2323 | } |
---|
2324 | |
---|
2325 | /*! |
---|
2326 | @function checkperms |
---|
2327 | @abstract Check if $this->working_id has write access to create files in $dir |
---|
2328 | @discussion Simple call to acl_check |
---|
2329 | @param string Directory to check access of |
---|
2330 | @param relatives Relativity array |
---|
2331 | @result Boolean True/False |
---|
2332 | */ |
---|
2333 | function checkperms ($data) |
---|
2334 | { |
---|
2335 | if (!is_array ($data)) |
---|
2336 | { |
---|
2337 | $data = array (); |
---|
2338 | } |
---|
2339 | |
---|
2340 | $default_values = array |
---|
2341 | ( |
---|
2342 | 'relatives' => array (RELATIVE_CURRENT) |
---|
2343 | ); |
---|
2344 | |
---|
2345 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2346 | |
---|
2347 | $p = $this->path_parts (array( |
---|
2348 | 'string' => $data['string'], |
---|
2349 | 'relatives' => array ($data['relatives'][0]) |
---|
2350 | ) |
---|
2351 | ); |
---|
2352 | |
---|
2353 | if (!$this->acl_check (array( |
---|
2354 | 'string' => $p->fake_full_path, |
---|
2355 | 'relatives' => array ($p->mask), |
---|
2356 | 'operation' => PHPGW_ACL_ADD |
---|
2357 | )) |
---|
2358 | ) |
---|
2359 | { |
---|
2360 | return False; |
---|
2361 | } |
---|
2362 | else |
---|
2363 | { |
---|
2364 | return True; |
---|
2365 | } |
---|
2366 | } |
---|
2367 | |
---|
2368 | /* |
---|
2369 | * See vfs_shared |
---|
2370 | * If $data['readlink'] then a readlink is tryed on the real file |
---|
2371 | * If $data['file_id'] then the file_id is used instead of a path |
---|
2372 | */ |
---|
2373 | function ls ($data) |
---|
2374 | { |
---|
2375 | if (!is_array ($data)) |
---|
2376 | { |
---|
2377 | $data = array (); |
---|
2378 | } |
---|
2379 | |
---|
2380 | $default_values = array |
---|
2381 | ( |
---|
2382 | 'relatives' => array (RELATIVE_CURRENT), |
---|
2383 | 'checksubdirs' => True, |
---|
2384 | 'mime_type' => False, |
---|
2385 | 'nofiles' => False, |
---|
2386 | 'orderby' => 'directory' |
---|
2387 | ); |
---|
2388 | |
---|
2389 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2390 | |
---|
2391 | $p = $this->path_parts (array( |
---|
2392 | 'string' => $data['string'], |
---|
2393 | 'relatives' => array ($data['relatives'][0]) |
---|
2394 | ) |
---|
2395 | ); |
---|
2396 | $dir = $p->fake_full_path; |
---|
2397 | |
---|
2398 | /* If they pass us a file or 'nofiles' is set, return the info for $dir only */ |
---|
2399 | if (@$data['file_id'] |
---|
2400 | || ((($type = $this->file_type (array( |
---|
2401 | 'string' => $dir, |
---|
2402 | 'relatives' => array ($p->mask) |
---|
2403 | )) != 'Directory')) |
---|
2404 | || ($data['nofiles'])) && !$p->outside |
---|
2405 | ) |
---|
2406 | { |
---|
2407 | /* SELECT all, the, attributes */ |
---|
2408 | $sql = 'SELECT '; |
---|
2409 | |
---|
2410 | foreach ($this->attributes as $num => $attribute) |
---|
2411 | { |
---|
2412 | if ($num) |
---|
2413 | { |
---|
2414 | $sql .= ', '; |
---|
2415 | } |
---|
2416 | |
---|
2417 | $sql .= $attribute; |
---|
2418 | } |
---|
2419 | |
---|
2420 | $sql .= " FROM phpgw_vfs WHERE "; |
---|
2421 | if (@$data['file_id']) |
---|
2422 | { |
---|
2423 | $sql .= 'file_id='.(int)$data['file_id']; |
---|
2424 | } |
---|
2425 | else |
---|
2426 | { |
---|
2427 | $sql .= "directory='".$GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean). |
---|
2428 | "' AND name='".$GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'". |
---|
2429 | $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)); |
---|
2430 | } |
---|
2431 | $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__); |
---|
2432 | |
---|
2433 | $GLOBALS['phpgw']->db->next_record (); |
---|
2434 | $record = $GLOBALS['phpgw']->db->Record; |
---|
2435 | |
---|
2436 | /* We return an array of one array to maintain the standard */ |
---|
2437 | $rarray = array (); |
---|
2438 | foreach($this->attributes as $attribute) |
---|
2439 | { |
---|
2440 | if ($attribute == 'mime_type' && !$record[$attribute]) |
---|
2441 | { |
---|
2442 | $db2 = $GLOBALS['phpgw']->db; |
---|
2443 | $record[$attribute] = $this->get_ext_mime_type (array( |
---|
2444 | 'string' => $p->fake_name_clean |
---|
2445 | ) |
---|
2446 | ); |
---|
2447 | |
---|
2448 | if($record[$attribute]) |
---|
2449 | { |
---|
2450 | $db2->query ("UPDATE phpgw_vfs SET mime_type='".$record[$attribute]."' WHERE directory='". |
---|
2451 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
2452 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__); |
---|
2453 | } |
---|
2454 | } |
---|
2455 | |
---|
2456 | $rarray[0][$attribute] = $record[$attribute]; |
---|
2457 | } |
---|
2458 | if ($this->file_actions && @$data['readlink']) // test if file is a symlink and get it's target |
---|
2459 | { |
---|
2460 | $rarray[0]['symlink'] = @readlink($p->real_full_path); |
---|
2461 | } |
---|
2462 | |
---|
2463 | return $rarray; |
---|
2464 | } |
---|
2465 | |
---|
2466 | //WIP - this should recurse using the same options the virtual part of ls () does |
---|
2467 | /* If $dir is outside the virutal root, we have to check the file system manually */ |
---|
2468 | if ($p->outside) |
---|
2469 | { |
---|
2470 | if ($this->file_type (array( |
---|
2471 | 'string' => $p->fake_full_path, |
---|
2472 | 'relatives' => array ($p->mask) |
---|
2473 | )) == 'Directory' |
---|
2474 | && !$data['nofiles'] |
---|
2475 | ) |
---|
2476 | { |
---|
2477 | $dir_handle = opendir ($p->real_full_path); |
---|
2478 | while ($filename = readdir ($dir_handle)) |
---|
2479 | { |
---|
2480 | if ($filename == '.' || $filename == '..') |
---|
2481 | { |
---|
2482 | continue; |
---|
2483 | } |
---|
2484 | |
---|
2485 | $rarray[] = $this->get_real_info (array( |
---|
2486 | 'string' => $p->real_full_path . SEP . $filename, |
---|
2487 | 'relatives' => array ($p->mask) |
---|
2488 | ) |
---|
2489 | ); |
---|
2490 | } |
---|
2491 | } |
---|
2492 | else |
---|
2493 | { |
---|
2494 | $rarray[] = $this->get_real_info (array( |
---|
2495 | 'string' => $p->real_full_path, |
---|
2496 | 'relatives' => array ($p->mask) |
---|
2497 | ) |
---|
2498 | ); |
---|
2499 | } |
---|
2500 | |
---|
2501 | return $rarray; |
---|
2502 | } |
---|
2503 | |
---|
2504 | /* $dir's not a file, is inside the virtual root, and they want to check subdirs */ |
---|
2505 | /* SELECT all, the, attributes FROM phpgw_vfs WHERE file=$dir */ |
---|
2506 | $sql = 'SELECT '; |
---|
2507 | |
---|
2508 | foreach($this->attributes as $num => $attribute) |
---|
2509 | { |
---|
2510 | if ($num) |
---|
2511 | { |
---|
2512 | $sql .= ", "; |
---|
2513 | } |
---|
2514 | |
---|
2515 | $sql .= $attribute; |
---|
2516 | } |
---|
2517 | |
---|
2518 | $dir_clean = $this->clean_string (array ('string' => $dir)); |
---|
2519 | $sql .= " FROM phpgw_vfs WHERE directory LIKE '".$GLOBALS['phpgw']->db->db_addslashes($dir_clean)."%'"; |
---|
2520 | $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)); |
---|
2521 | |
---|
2522 | if ($data['mime_type']) |
---|
2523 | { |
---|
2524 | $sql .= " AND mime_type='".$data['mime_type']."'"; |
---|
2525 | } |
---|
2526 | |
---|
2527 | $sql .= ' ORDER BY '.$data['orderby']; |
---|
2528 | |
---|
2529 | $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__); |
---|
2530 | |
---|
2531 | $rarray = array (); |
---|
2532 | for ($i = 0; $GLOBALS['phpgw']->db->next_record (); $i++) |
---|
2533 | { |
---|
2534 | $record = $GLOBALS['phpgw']->db->Record; |
---|
2535 | |
---|
2536 | /* Further checking on the directory. This makes sure /home/user/test won't match /home/user/test22 */ |
---|
2537 | if (@!ereg ("^$dir(/|$)", $record['directory'])) |
---|
2538 | { |
---|
2539 | continue; |
---|
2540 | } |
---|
2541 | |
---|
2542 | /* If they want only this directory, then $dir should end without a trailing / */ |
---|
2543 | if (!$data['checksubdirs'] && ereg ("^$dir/", $record['directory'])) |
---|
2544 | { |
---|
2545 | continue; |
---|
2546 | } |
---|
2547 | |
---|
2548 | foreach($this->attributes as $attribute) |
---|
2549 | { |
---|
2550 | if ($attribute == 'mime_type' && !$record[$attribute]) |
---|
2551 | { |
---|
2552 | $db2 = $GLOBALS['phpgw']->db; |
---|
2553 | $record[$attribute] = $this->get_ext_mime_type (array( |
---|
2554 | 'string' => $p->fake_name_clean |
---|
2555 | ) |
---|
2556 | ); |
---|
2557 | |
---|
2558 | if($record[$attribute]) |
---|
2559 | { |
---|
2560 | $db2->query ("UPDATE phpgw_vfs SET mime_type='".$record[$attribute]."' WHERE directory='". |
---|
2561 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
2562 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__); |
---|
2563 | } |
---|
2564 | } |
---|
2565 | |
---|
2566 | $rarray[$i][$attribute] = $record[$attribute]; |
---|
2567 | } |
---|
2568 | } |
---|
2569 | |
---|
2570 | return $rarray; |
---|
2571 | } |
---|
2572 | |
---|
2573 | /* |
---|
2574 | * See vfs_shared |
---|
2575 | */ |
---|
2576 | function update_real ($data,$recursive = False) |
---|
2577 | { |
---|
2578 | if (!is_array ($data)) |
---|
2579 | { |
---|
2580 | $data = array (); |
---|
2581 | } |
---|
2582 | |
---|
2583 | $default_values = array |
---|
2584 | ( |
---|
2585 | 'relatives' => array (RELATIVE_CURRENT) |
---|
2586 | ); |
---|
2587 | |
---|
2588 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2589 | |
---|
2590 | $p = $this->path_parts (array( |
---|
2591 | 'string' => $data['string'], |
---|
2592 | 'relatives' => array ($data['relatives'][0]) |
---|
2593 | ) |
---|
2594 | ); |
---|
2595 | |
---|
2596 | if (file_exists ($p->real_full_path)) |
---|
2597 | { |
---|
2598 | if (is_dir ($p->real_full_path)) |
---|
2599 | { |
---|
2600 | $dir_handle = opendir ($p->real_full_path); |
---|
2601 | while ($filename = readdir ($dir_handle)) |
---|
2602 | { |
---|
2603 | if ($filename == '.' || $filename == '..') |
---|
2604 | { |
---|
2605 | continue; |
---|
2606 | } |
---|
2607 | |
---|
2608 | $rarray[] = $this->get_real_info (array( |
---|
2609 | 'string' => $p->fake_full_path . '/' . $filename, |
---|
2610 | 'relatives' => array (RELATIVE_NONE) |
---|
2611 | ) |
---|
2612 | ); |
---|
2613 | } |
---|
2614 | } |
---|
2615 | else |
---|
2616 | { |
---|
2617 | $rarray[] = $this->get_real_info (array( |
---|
2618 | 'string' => $p->fake_full_path, |
---|
2619 | 'relatives' => array (RELATIVE_NONE) |
---|
2620 | ) |
---|
2621 | ); |
---|
2622 | } |
---|
2623 | |
---|
2624 | if (!is_array ($rarray)) |
---|
2625 | { |
---|
2626 | $rarray = array (); |
---|
2627 | } |
---|
2628 | |
---|
2629 | foreach($rarray as $num => $file_array) |
---|
2630 | { |
---|
2631 | $p2 = $this->path_parts (array( |
---|
2632 | 'string' => $file_array['directory'] . '/' . $file_array['name'], |
---|
2633 | 'relatives' => array (RELATIVE_NONE) |
---|
2634 | ) |
---|
2635 | ); |
---|
2636 | |
---|
2637 | /* Note the mime_type. This can be "Directory", which is how we create directories */ |
---|
2638 | $set_attributes_array = Array( |
---|
2639 | 'size' => $file_array['size'], |
---|
2640 | 'mime_type' => $file_array['mime_type'] |
---|
2641 | ); |
---|
2642 | |
---|
2643 | if (!$this->file_exists (array( |
---|
2644 | 'string' => $p2->fake_full_path, |
---|
2645 | 'relatives' => array (RELATIVE_NONE) |
---|
2646 | )) |
---|
2647 | ) |
---|
2648 | { |
---|
2649 | $this->touch (array( |
---|
2650 | 'string' => $p2->fake_full_path, |
---|
2651 | 'relatives' => array (RELATIVE_NONE) |
---|
2652 | ) |
---|
2653 | ); |
---|
2654 | } |
---|
2655 | $this->set_attributes (array( |
---|
2656 | 'string' => $p2->fake_full_path, |
---|
2657 | 'relatives' => array (RELATIVE_NONE), |
---|
2658 | 'attributes' => $set_attributes_array |
---|
2659 | ) |
---|
2660 | ); |
---|
2661 | if ($recursive && $file_array['mime_type'] == 'Directory') |
---|
2662 | { |
---|
2663 | $dir_data = $data; |
---|
2664 | $dir_data['string'] = $file_array['directory'] . '/' . $file_array['name']; |
---|
2665 | $this->update_real($dir_data,$recursive); |
---|
2666 | } |
---|
2667 | } |
---|
2668 | } |
---|
2669 | } |
---|
2670 | |
---|
2671 | /* Helper functions */ |
---|
2672 | |
---|
2673 | /* This fetchs all available file system information for string (not using the database) */ |
---|
2674 | function get_real_info ($data) |
---|
2675 | { |
---|
2676 | if (!is_array ($data)) |
---|
2677 | { |
---|
2678 | $data = array (); |
---|
2679 | } |
---|
2680 | |
---|
2681 | $default_values = array |
---|
2682 | ( |
---|
2683 | 'relatives' => array (RELATIVE_CURRENT) |
---|
2684 | ); |
---|
2685 | |
---|
2686 | $data = array_merge ($this->default_values ($data, $default_values), $data); |
---|
2687 | |
---|
2688 | $p = $this->path_parts (array( |
---|
2689 | 'string' => $data['string'], |
---|
2690 | 'relatives' => array ($data['relatives'][0]) |
---|
2691 | ) |
---|
2692 | ); |
---|
2693 | |
---|
2694 | if (is_dir ($p->real_full_path)) |
---|
2695 | { |
---|
2696 | $mime_type = 'Directory'; |
---|
2697 | } |
---|
2698 | else |
---|
2699 | { |
---|
2700 | $mime_type = $this->get_ext_mime_type (array( |
---|
2701 | 'string' => $p->fake_name |
---|
2702 | ) |
---|
2703 | ); |
---|
2704 | |
---|
2705 | if($mime_type) |
---|
2706 | { |
---|
2707 | $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET mime_type='".$mime_type."' WHERE directory='". |
---|
2708 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='". |
---|
2709 | $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . |
---|
2710 | $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__); |
---|
2711 | } |
---|
2712 | } |
---|
2713 | |
---|
2714 | $size = filesize ($p->real_full_path); |
---|
2715 | $rarray = array( |
---|
2716 | 'directory' => $p->fake_leading_dirs, |
---|
2717 | 'name' => $p->fake_name, |
---|
2718 | 'size' => $size, |
---|
2719 | 'mime_type' => $mime_type |
---|
2720 | ); |
---|
2721 | |
---|
2722 | return ($rarray); |
---|
2723 | } |
---|
2724 | } |
---|
2725 | ?> |
---|