source: trunk/phpgwapi/inc/class.vfs_sql.inc.php @ 2883

Revision 2883, 74.9 KB checked in by amuller, 14 years ago (diff)

Ticket #1094 - corrige problema de pasta vazia

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