source: branches/2.2/phpgwapi/inc/class.vfs_sql.inc.php @ 3019

Revision 3019, 74.8 KB checked in by amuller, 14 years ago (diff)

Ticket #1135 - Corrigindo CSS e adicionando filemanager

  • 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 directory='".
794                        $GLOBALS['phpgw']->db->db_addslashes($base)."' AND name='".
795                        $GLOBALS['phpgw']->db->db_addslashes($path)."' ".$this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
796                        $GLOBALS['phpgw']->db->next_record();
797                        $owner_id = $GLOBALS['phpgw']->db->Record['owner_id'];
798                        if (!$owner_id)
799                        {
800                                $owner_id = 0;
801                        }
802                        return $owner_id;
803                }
804
805                /*used to safe memory in downloads*/
806                function print_content ($data)
807                {
808                        if (!is_array ($data))
809                        {
810                                $data = array ();
811                        }
812
813                        $default_values = array
814                                (
815                                        'relatives'     => array (RELATIVE_CURRENT)
816                                );
817
818                        $data = array_merge ($this->default_values ($data, $default_values), $data);
819
820                        $p = $this->path_parts (array(
821                                        'string'        => $data['string'],
822                                        'relatives'     => array ($data['relatives'][0])
823                                )
824                        );
825
826                        if (!$this->acl_check (array(
827                                        'string'        => $p->fake_full_path,
828                                        'relatives'     => array ($p->mask),
829                                        'operation'     => PHPGW_ACL_READ
830                                ))
831                        )
832                        {
833                                return False;
834                        }
835                                //avoid stuck request
836                                session_write_close();
837
838                                //reset time limit for big files
839                                set_time_limit(0);
840
841                                ob_end_flush();
842
843                                if ($fp = fopen ($p->real_full_path, 'rb'))
844                                {
845                                        for ($i=0; $i<=filesize($p->real_full_path); $i+=10240)
846                                        {
847                                                echo fread($fp, $i);
848                                                flush();
849                                        }
850                                        fclose ($fp);
851                                }
852                                else
853                                {
854                                        return False;
855                                }
856                        return True;
857                }
858
859                /*
860                 * See vfs_shared
861                 */
862                function read ($data)
863                {
864                        if (!is_array ($data))
865                        {
866                                $data = array ();
867                        }
868
869                        $default_values = array
870                                (
871                                        'relatives'     => array (RELATIVE_CURRENT)
872                                );
873
874                        $data = array_merge ($this->default_values ($data, $default_values), $data);
875
876                        $p = $this->path_parts (array(
877                                        'string'        => $data['string'],
878                                        'relatives'     => array ($data['relatives'][0])
879                                )
880                        );
881
882                        if (!$this->acl_check (array(
883                                        'string'        => $p->fake_full_path,
884                                        'relatives'     => array ($p->mask),
885                                        'operation'     => PHPGW_ACL_READ
886                                ))
887                        )
888                        {
889                                return False;
890                        }
891
892                        $conf = CreateObject('phpgwapi.config', 'phpgwapi');
893                        $conf->read_repository();
894                        if ($this->file_actions || $p->outside)
895                        {
896                                if ($fp = fopen ($p->real_full_path, 'rb'))
897                                {
898                                        $contents = fread ($fp, filesize ($p->real_full_path));
899                                        fclose ($fp);
900                                }
901                                else
902                                {
903                                        $contents = False;
904                                }
905                        }
906                        else
907                        {
908                                $ls_array = $this->ls (array(
909                                                'string'        => $p->fake_full_path,
910                                                'relatives'     => array ($p->mask),
911                                        )
912                                );
913
914                                $contents = $ls_array[0]['content'];
915                        }
916
917                        return $contents;
918                }
919
920                /*
921                 * See vfs_shared
922                 */
923                function write ($data)
924                {
925                        if (!is_array ($data))
926                        {
927                                $data = array ();
928                        }
929
930                        $path = explode('/',$data['string']);
931                        $quota = $this->get_quota(array('string' => '/'.$path[1].'/'.$path[2]));
932                        if ($quota > 0 && $this->get_size('/'.$path[1].'/'.$path[2]) >= $quota * 1024 * 1024)
933                                return false;
934
935
936                        $default_values = array
937                                (
938                                        'relatives'     => array (RELATIVE_CURRENT),
939                                        'content'       => ''
940                                );
941
942                        $data = array_merge ($this->default_values ($data, $default_values), $data);
943
944                        $p = $this->path_parts (array(
945                                        'string'        => $data['string'],
946                                        'relatives'     => array ($data['relatives'][0])
947                                )
948                        );
949
950                        if ($this->file_exists (array (
951                                        'string'        => $p->fake_full_path,
952                                        'relatives'     => array ($p->mask)
953                                ))
954                        )
955                        {
956                                $acl_operation = PHPGW_ACL_EDIT;
957                                $journal_operation = VFS_OPERATION_EDITED;
958                        }
959                        else
960                        {
961                                $acl_operation = PHPGW_ACL_ADD;
962                        }
963                        umask(0177);
964
965                        /*
966                           If 'string' doesn't exist, touch () creates both the file and the database entry
967                           If 'string' does exist, touch () sets the modification time and modified by
968                        */
969                        $this->touch (array(
970                                        'string'        => $p->fake_full_path,
971                                        'relatives'     => array ($p->mask)
972                                )
973                        );
974
975                        $conf = CreateObject('phpgwapi.config', 'phpgwapi');
976                        $conf->read_repository();
977                        if ($this->file_actions)
978                        {
979                                if ($fp = fopen ($p->real_full_path, 'wb'))
980                                {
981                                        fwrite ($fp, $data['content']);
982                                        fclose ($fp);
983                                        $write_ok = 1;
984                                }
985                        }
986
987                        if ($write_ok || !$this->file_actions)
988                        {
989                                if ($this->file_actions)
990                                {
991                                        $set_attributes_array = array(
992                                                'size' => filesize ($p->real_full_path)
993                                        );
994                                }
995                                else
996                                {
997                                        $set_attributes_array = array (
998                                                'size'  => strlen ($data['content']),
999                                                'content'       => $data['content']
1000                                        );
1001                                }
1002
1003
1004                                $this->set_attributes (array
1005                                        (
1006                                                'string'        => $p->fake_full_path,
1007                                                'relatives'     => array ($p->mask),
1008                                                'attributes'    => $set_attributes_array
1009                                        )
1010                                );
1011
1012                                if ($journal_operation)
1013                                {
1014                                        $this->add_journal (array(
1015                                                        'string'        => $p->fake_full_path,
1016                                                        'relatives'     => array ($p->mask),
1017                                                        'operation'     => $journal_operation
1018                                                )
1019                                        );
1020                                }
1021
1022                                return True;
1023                        }
1024                        else
1025                        {
1026                                return False;
1027                        }
1028                }
1029
1030                /*
1031                 * See vfs_shared
1032                 */
1033                function touch ($data)
1034                {
1035                        if (!is_array ($data))
1036                        {
1037                                $data = array ();
1038                        }
1039
1040                        $default_values = array
1041                                (
1042                                        'relatives'     => array (RELATIVE_CURRENT)
1043                                );
1044
1045                        $data = array_merge ($this->default_values ($data, $default_values), $data);
1046
1047                        $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
1048                        $currentapp = $GLOBALS['phpgw_info']['flags']['currentapp'];
1049
1050                        $p = $this->path_parts (array(
1051                                        'string'        => $data['string'],
1052                                        'relatives'     => array ($data['relatives'][0])
1053                                )
1054                        );
1055
1056                        umask (0177);
1057
1058                        if ($this->file_actions)
1059                        {
1060                                /*
1061                                   PHP's touch function will automatically decide whether to
1062                                   create the file or set the modification time
1063                                */
1064                                $rr = @touch ($p->real_full_path);
1065
1066                                if ($p->outside)
1067                                {
1068                                        return $rr;
1069                                }
1070                        }
1071                        /* We, however, have to decide this ourselves */
1072                        if ($this->file_exists (array(
1073                                        'string'        => $p->fake_full_path,
1074                                        'relatives'     => array ($p->mask)
1075                                ))
1076                        )
1077                        {
1078                                if (!$this->acl_check (array(
1079                                                'string'        => $p->fake_full_path,
1080                                                'relatives'     => array ($p->mask),
1081                                                'operation'     => PHPGW_ACL_EDIT
1082                                        )))
1083                                {
1084                                        return False;
1085                                }
1086
1087                                $vr = $this->set_attributes (array(
1088                                                'string'        => $p->fake_full_path,
1089                                                'relatives'     => array ($p->mask),
1090                                                'attributes'    => array(
1091                                                                        'modifiedby_id' => $account_id,
1092                                                                        'modified' => $this->now
1093                                                                )
1094                                                )
1095                                        );
1096                        }
1097                        else
1098                        {
1099                                if (!$this->acl_check (array(
1100                                                'string'        => $p->fake_full_path,
1101                                                'relatives'     => array ($p->mask),
1102                                                'operation'     => PHPGW_ACL_ADD
1103                                        ))
1104                                )
1105                                {
1106                                        return False;
1107                                }
1108
1109                                $query = $GLOBALS['phpgw']->db->query ("INSERT INTO phpgw_vfs (owner_id, directory, name) VALUES ($this->working_id, '".
1110                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."', '".
1111                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."')", __LINE__, __FILE__);
1112
1113                                $this->set_attributes(array(
1114                                        'string'        => $p->fake_full_path,
1115                                        'relatives'     => array ($p->mask),
1116                                        'attributes'    => array (
1117                                                                'createdby_id' => $account_id,
1118                                                                'created' => $this->now,
1119                                                                'size' => 0,
1120                                                                'deleteable' => 'Y',
1121                                                                'app' => $currentapp,
1122                                                                'comment' => ''
1123                                                        )
1124                                        )
1125                                );
1126                                $this->correct_attributes (array(
1127                                                'string'        => $p->fake_full_path,
1128                                                'relatives'     => array ($p->mask)
1129                                        )
1130                                );
1131       
1132                                $this->add_journal (array(
1133                                                'string'        => $p->fake_full_path,
1134                                                'relatives'     => array ($p->mask),
1135                                                'operation'     => VFS_OPERATION_CREATED
1136                                        )
1137                                );
1138                        }
1139
1140                        if ($rr || $vr || $query)
1141                        {
1142                                return True;
1143                        }
1144                        else
1145                        {
1146                                return False;
1147                        }
1148                }
1149
1150                /*
1151                 * See vfs_shared
1152                 * If $data['symlink'] the file is symlinked instead of copied
1153                 */
1154                function cp ($data)
1155                {
1156                        if (!is_array ($data))
1157                        {
1158                                $data = array ();
1159                        }
1160                        if ($data['relatives'][1] == RELATIVE_NONE)
1161                                $path = explode(SEP,$data['to']);
1162                        else
1163                                $path = explode(SEP,$this->my_home);
1164                        $quota = $this->get_quota(array('string' => SEP.$path[1].SEP.$path[2]));
1165                        $size = $this->get_size(array('string' => SEP.$path[1].SEP.$path[2], 'relatives' => $data['relatives'][1]));
1166                        if ($quota > 0 && ($quota * 1024 * 1024) < $size)
1167                                return false;
1168
1169                        $default_values = array
1170                                (
1171                                        'relatives'     => array (RELATIVE_CURRENT, RELATIVE_CURRENT)
1172                                );
1173
1174                        $data = array_merge ($this->default_values ($data, $default_values), $data);
1175
1176                        $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
1177
1178                        $f = $this->path_parts (array(
1179                                        'string'        => $data['from'],
1180                                        'relatives'     => array ($data['relatives'][0])
1181                                )
1182                        );
1183
1184                        $t = $this->path_parts (array(
1185                                        'string'        => $data['to'],
1186                                        'relatives'     => array ($data['relatives'][1])
1187                                )
1188                        );
1189
1190                        if (!$this->acl_check (array(
1191                                        'string'        => $f->fake_full_path,
1192                                        'relatives'     => array ($f->mask),
1193                                        'operation'     => PHPGW_ACL_READ
1194                                ))
1195                        )
1196                        {
1197                                return False;
1198                        }
1199
1200                        if ($exists = $this->file_exists (array(
1201                                        'string'        => $t->fake_full_path,
1202                                        'relatives'     => array ($t->mask)
1203                                ))
1204                        )
1205                        {
1206                                if (!$this->acl_check (array(
1207                                                'string'        => $t->fake_full_path,
1208                                                'relatives'     => array ($t->mask),
1209                                                'operation'     => PHPGW_ACL_EDIT
1210                                        ))
1211                                )
1212                                {
1213                                        return False;
1214                                }
1215                        }
1216                        else
1217                        {
1218                                if (!$this->acl_check (array(
1219                                                'string'        => $t->fake_full_path,
1220                                                'relatives'     => array ($t->mask),
1221                                                'operation'     => PHPGW_ACL_ADD
1222                                        ))
1223                                )
1224                                {
1225                                        return False;
1226                                }
1227                        }
1228
1229                        umask(0177);
1230
1231                        if ($this->file_type (array(
1232                                        'string'        => $f->fake_full_path,
1233                                        'relatives'     => array ($f->mask)
1234                                )) != 'Directory'
1235                        )
1236                        {
1237                                if ($this->file_actions)
1238                                {
1239                                        if (@$data['symlink'])
1240                                        {
1241                                                if ($exists)
1242                                                {
1243                                                        @unlink($t->real_full_path);
1244                                                }
1245                                                if (!symlink($f->real_full_path, $t->real_full_path))
1246                                                {
1247                                                        return False;
1248                                                }
1249                                        }
1250                                        elseif (!copy ($f->real_full_path, $t->real_full_path))
1251                                        {
1252                                                return False;
1253                                        }
1254
1255                                        $size = filesize ($t->real_full_path);
1256                                }
1257                                else
1258                                {
1259                                        $content = $this->read (array(
1260                                                        'string'        => $f->fake_full_path,
1261                                                        'relatives'     => array ($f->mask)
1262                                                )
1263                                        );
1264
1265                                        $size = strlen ($content);
1266                                }
1267
1268                                if ($t->outside)
1269                                {
1270                                        return True;
1271                                }
1272
1273                                $ls_array = $this->ls (array(
1274                                                'string'        => $f->fake_full_path,
1275                                                'relatives'     => array ($f->mask),
1276                                                'checksubdirs'  => False,
1277                                                'mime_type'     => False,
1278                                                'summary'       => True,
1279                                                'nofiles'       => True
1280                                        )
1281                                );
1282                                $record = $ls_array[0];
1283
1284                                if ($this->file_exists (array(
1285                                                'string'        => $data['to'],
1286                                                'relatives'     => array ($data['relatives'][1])
1287                                        ))
1288                                )
1289                                {
1290                                        $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET owner_id='$this->working_id', directory='".
1291                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."', name='".
1292                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."' WHERE owner_id='$this->working_id' AND directory='".
1293                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."' AND name='".
1294                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."'" . $this->extra_sql (VFS_SQL_UPDATE), __LINE__, __FILE__);
1295                               
1296                                        $set_attributes_array = array (
1297                                                'createdby_id' => $account_id,
1298                                                'created' => $this->now,
1299                                                'size' => $size,
1300                                                'mime_type' => $record['mime_type'],
1301                                                'deleteable' => $record['deleteable'],
1302                                                'comment' => $record['comment'],
1303                                                'app' => $record['app']
1304                                        );
1305
1306                                        if (!$this->file_actions)
1307                                        {
1308                                                $set_attributes_array['content'] = $content;
1309                                        }
1310
1311                                        $this->set_attributes(array(
1312                                                'string'        => $t->fake_full_path,
1313                                                'relatives'     => array ($t->mask),
1314                                                'attributes'    => $set_attributes_array
1315                                                )
1316                                        );
1317
1318                                        $this->add_journal (array(
1319                                                        'string'        => $t->fake_full_path,
1320                                                        'relatives'     => array ($t->mask),
1321                                                        'operation'     => VFS_OPERATION_EDITED
1322                                                )
1323                                        );
1324                                }
1325                                else
1326                                {       
1327                                        $this->touch (array(
1328                                                        'string'        => $t->fake_full_path,
1329                                                        'relatives'     => array ($t->mask)
1330                                                )
1331                                        );
1332
1333                                        $set_attributes_array = array (
1334                                                'createdby_id' => $account_id,
1335                                                'created' => $this->now,
1336                                                'size' => $size,
1337                                                'mime_type' => $record['mime_type'],
1338                                                'deleteable' => $record['deleteable'],
1339                                                'comment' => $record['comment'],
1340                                                'app' => $record['app']
1341                                        );
1342
1343                                        if (!$this->file_actions)
1344                                        {
1345                                                $set_attributes_array['content'] = $content;
1346                                        }
1347
1348                                        $this->set_attributes(array(
1349                                                        'string'        => $t->fake_full_path,
1350                                                        'relatives'     => array ($t->mask),
1351                                                        'attributes'    => $set_attributes_array
1352                                                ),
1353                                                true
1354                                        );
1355                                        if (!(strpos(strtoupper($record['mime_type']),'IMAGE') === FALSE))
1356                                        {               
1357                                                $this->set_summary(array(
1358                                                        'string'=> $data['to'],
1359                                                        'relatives' => array ($data['relatives'][1]),
1360                                                        'summary'=> $record['summary']
1361                                                ));
1362                                                unset($record['summary']);
1363                                        }
1364                                }
1365                                $this->correct_attributes (array(
1366                                                'string'        => $t->fake_full_path,
1367                                                'relatives'     => array ($t->mask)
1368                                        )
1369                                );
1370                        }
1371                        else    /* It's a directory */
1372                        {
1373                                /* First, make the initial directory */
1374                                $this->mkdir (array(
1375                                                'string'        => $data['to'],
1376                                                'relatives'     => array ($data['relatives'][1])
1377                                        )
1378                                );
1379
1380                                /* Next, we create all the directories below the initial directory */
1381                                foreach($this->ls (array(
1382                                                'string'        => $f->fake_full_path,
1383                                                'relatives'     => array ($f->mask),
1384                                                'checksubdirs'  => True,
1385                                                'mime_type'     => 'Directory'
1386                                        )) as $entry)
1387                                {
1388                                        $newdir = ereg_replace ("^$f->fake_full_path", "$t->fake_full_path", $entry['directory']);
1389                                        $this->mkdir (array(
1390                                                        'string'        => $newdir.'/'.$entry['name'],
1391                                                        'relatives'     => array ($t->mask)
1392                                                )
1393                                        );
1394                                }
1395
1396                                /* Lastly, we copy the files over */
1397                                foreach($this->ls (array(
1398                                                'string'        => $f->fake_full_path,
1399                                                'relatives'     => array ($f->mask)
1400                                        )) as $entry)
1401                                {
1402                                        if ($entry['mime_type'] == 'Directory')
1403                                        {
1404                                                continue;
1405                                        }
1406
1407                                        $newdir = ereg_replace ("^$f->fake_full_path", "$t->fake_full_path", $entry['directory']);
1408                                        $this->cp (array(
1409                                                        'from'  => "$entry[directory]/$entry[name]",
1410                                                        'to'    => "$newdir/$entry[name]",
1411                                                        'relatives'     => array ($f->mask, $t->mask)
1412                                                )
1413                                        );
1414                                }
1415                        }
1416
1417                        if (!$f->outside)
1418                        {
1419                                $this->add_journal (array(
1420                                                'string'        => $f->fake_full_path,
1421                                                'relatives'     => array ($f->mask),
1422                                                'operation'     => VFS_OPERATION_COPIED,
1423                                                'state_one'     => NULL,
1424                                                'state_two'     => $t->fake_full_path
1425                                        )
1426                                );
1427                        }
1428
1429                        return True;
1430                }
1431
1432                /*
1433                 * See vfs_shared
1434                 */
1435                function mv ($data)
1436                {
1437                        if (!is_array ($data))
1438                        {
1439                                $data = array ();
1440                        }
1441                        if ($data['relatives'][1] == RELATIVE_NONE)
1442                        {
1443                                $path = explode('/',$data['to']);
1444                                $quota = $this->get_quota(array('string' => '/'.$path[1].'/'.$path[2]));
1445                                $size = $this->get_size(array('string' => '/'.$path[1].'/'.$path[2], 'relatives' => $data['relatives'][1]));
1446                        }
1447                        else
1448                        {
1449                                $quota = $this->get_quota(array('string' => $this->my_home));
1450                                $size = $this->get_size(array('string' => $this->my_home, 'relatives' => $data['relatives'][1]));
1451                        }
1452                        if ($quota > 0 && $size >= $quota * 1024 * 1024)
1453                                return false;
1454
1455
1456                        $default_values = array
1457                                (
1458                                        'relatives'     => array (RELATIVE_CURRENT, RELATIVE_CURRENT)
1459                                );
1460
1461                        $data = array_merge ($this->default_values ($data, $default_values), $data);
1462
1463                        $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
1464
1465                        $f = $this->path_parts (array(
1466                                        'string'        => $data['from'],
1467                                        'relatives'     => array ($data['relatives'][0])
1468                                )
1469                        );
1470
1471                        $t = $this->path_parts (array(
1472                                        'string'        => $data['to'],
1473                                        'relatives'     => array ($data['relatives'][1])
1474                                )
1475                        );
1476
1477                        if (!$this->acl_check (array(
1478                                        'string'        => $data['to'],
1479                                        'relatives'     => array ($t->mask),
1480                                        'operation'     => PHPGW_ACL_ADD
1481                                ))
1482                        )
1483                        {
1484                                return False;
1485                        }
1486                        if (!$this->acl_check (array(
1487                                        'string'        => $data['from'],
1488                                        'relatives'     => array ($t->mask),
1489                                        'operation'     => PHPGW_ACL_DELETE
1490                                ))
1491                        )
1492                        {
1493                                return False;
1494                        }
1495
1496                        if ($this->file_exists (array(
1497                                        'string'        => $t->fake_full_path,
1498                                        'relatives'     => array ($t->mask)
1499                                ))
1500                        )
1501                        {
1502                                if (!$this->acl_check (array(
1503                                                'string'        => $data['to'],
1504                                                'relatives'     => array ($t->mask),
1505                                                'operation'     => PHPGW_ACL_EDIT
1506                                        ))
1507                                )
1508                                {
1509                                        return False;
1510                                }
1511                        }
1512
1513                        umask (0177);
1514
1515                        /* We can't move directories into themselves */
1516                        if (($this->file_type (array(
1517                                        'string'        => $f->fake_full_path,
1518                                        'relatives'     => array ($f->mask)
1519                                ) == 'Directory'))
1520                                && ereg ("^$f->fake_full_path", $t->fake_full_path)
1521                        )
1522                        {
1523                                if (($t->fake_full_path == $f->fake_full_path) || substr ($t->fake_full_path, strlen ($f->fake_full_path), 1) == '/')
1524                                {
1525                                        return False;
1526                                }
1527                        }
1528
1529                        if ($this->file_exists (array(
1530                                        'string'        => $f->fake_full_path,
1531                                        'relatives'     => array ($f->mask)
1532                                ))
1533                        )
1534                        {
1535                                /* We get the listing now, because it will change after we update the database */
1536                                $ls = $this->ls (array(
1537                                                'string'        => $f->fake_full_path,
1538                                                'relatives'     => array ($f->mask)
1539                                        )
1540                                );
1541
1542                                if ($this->file_exists (array(
1543                                                'string'        => $t->fake_full_path,
1544                                                'relatives'     => array ($t->mask)
1545                                        ))
1546                                )
1547                                {
1548                                        $this->rm (array(
1549                                                        'string'        => $t->fake_full_path,
1550                                                        'relatives'     => array ($t->mask)
1551                                                )
1552                                        );
1553                                }
1554
1555                                /*
1556                                   We add the journal entry now, before we delete.  This way the mime_type
1557                                   field will be updated to 'journal-deleted' when the file is actually deleted
1558                                */
1559                                if (!$f->outside)
1560                                {
1561                                        $this->add_journal (array(
1562                                                        'string'        => $f->fake_full_path,
1563                                                        'relatives'     => array ($f->mask),
1564                                                        'operation'     => VFS_OPERATION_MOVED,
1565                                                        'state_one'     => $f->fake_full_path,
1566                                                        'state_two'     => $t->fake_full_path
1567                                                )
1568                                        );
1569                                }
1570
1571                                /*
1572                                   If the from file is outside, it won't have a database entry,
1573                                   so we have to touch it and find the size
1574                                */
1575                                if ($f->outside)
1576                                {
1577                                        $size = filesize ($f->real_full_path);
1578
1579                                        $this->touch (array(
1580                                                        'string'        => $t->fake_full_path,
1581                                                        'relatives'     => array ($t->mask)
1582                                                )
1583                                        );
1584                                        $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET size=$size WHERE directory='".
1585                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."' AND name='".
1586                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE)), __LINE__, __FILE__);
1587                                }
1588                                elseif (!$t->outside)
1589                                {
1590                                        $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET name='".
1591                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."', directory='".
1592                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."' WHERE directory='".
1593                                                $GLOBALS['phpgw']->db->db_addslashes($f->fake_leading_dirs_clean)."' AND name='".
1594                                                $GLOBALS['phpgw']->db->db_addslashes($f->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE)), __LINE__, __FILE__);
1595                                }
1596
1597                                $this->set_attributes(array(
1598                                                'string'        => $t->fake_full_path,
1599                                                'relatives'     => array ($t->mask),
1600                                                'attributes'    => array (
1601                                                                        'modifiedby_id' => $account_id,
1602                                                                        'modified' => $this->now
1603                                                                )
1604                                        )
1605                                );
1606
1607                                $this->correct_attributes (array(
1608                                                'string'        => $t->fake_full_path,
1609                                                'relatives'     => array ($t->mask)
1610                                        )
1611                                );
1612
1613                                if ($this->file_actions)
1614                                {
1615                                        $rr = rename ($f->real_full_path, $t->real_full_path);
1616                                }
1617
1618                                /*
1619                                   This removes the original entry from the database
1620                                   The actual file is already deleted because of the rename () above
1621                                */
1622                                if ($t->outside)
1623                                {
1624                                        $this->rm (array(
1625                                                        'string'        => $f->fake_full_path,
1626                                                        'relatives'     => $f->mask
1627                                                )
1628                                        );
1629                                }
1630                        }
1631                        else
1632                        {
1633                                return False;
1634                        }
1635
1636                        if ($this->file_type (array(
1637                                        'string'        => $t->fake_full_path,
1638                                        'relatives'     => array ($t->mask)
1639                                )) == 'Directory'
1640                        )
1641                        {
1642                                /* We got $ls from above, before we renamed the directory */
1643                                foreach ($ls as $entry)
1644                                {
1645                                        $newdir = ereg_replace ("^$f->fake_full_path", $t->fake_full_path, $entry['directory']);
1646                                        $newdir_clean = $this->clean_string (array ('string' => $newdir));
1647
1648                                        $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET directory='".
1649                                                $GLOBALS['phpgw']->db->db_addslashes($newdir_clean)."' WHERE file_id='$entry[file_id]'" .
1650                                                $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE)), __LINE__, __FILE__);
1651                                        $this->correct_attributes (array(
1652                                                        'string'        => "$newdir/$entry[name]",
1653                                                        'relatives'     => array ($t->mask)
1654                                                )
1655                                        );
1656                                }
1657                        }
1658
1659                        $this->add_journal (array(
1660                                        'string'        => $t->fake_full_path,
1661                                        'relatives'     => array ($t->mask),
1662                                        'operation'     => VFS_OPERATION_MOVED,
1663                                        'state_one'     => $f->fake_full_path,
1664                                        'state_two'     => $t->fake_full_path
1665                                )
1666                        );
1667
1668                        return True;
1669                }
1670
1671                /*
1672                 * See vfs_shared
1673                 */
1674                function rm ($data)
1675                {
1676                        if (!is_array ($data))
1677                        {
1678                                $data = array ();
1679                        }
1680
1681                        $default_values = array
1682                                (
1683                                        'relatives'     => array (RELATIVE_CURRENT)
1684                                );
1685
1686                        $data = array_merge ($this->default_values ($data, $default_values), $data);
1687
1688                        $p = $this->path_parts (array(
1689                                        'string'        => $data['string'],
1690                                        'relatives'     => array ($data['relatives'][0])
1691                                )
1692                        );
1693                        if (!$this->acl_check (array(
1694                                'string'        => $p->fake_full_path,
1695                                'relatives'     => array ($p->mask),
1696                                'operation'     => PHPGW_ACL_DELETE)
1697                                )
1698                        )
1699                        {
1700                                return False;
1701                        }
1702
1703                        if (!$this->file_exists (array(
1704                                        'string'        => $data['string'],
1705                                        'relatives'     => array ($data['relatives'][0])
1706                                ))
1707                        )
1708                        {
1709                                if ($this->file_actions)
1710                                {
1711                                        $rr = unlink ($p->real_full_path);
1712                                }
1713                                else
1714                                {
1715                                        $rr = True;
1716                                }
1717
1718                                if ($rr)
1719                                {
1720                                        return True;
1721                                }
1722                                else
1723                                {
1724                                        return False;
1725                                }
1726                        }
1727
1728                        if ($this->file_type (array(
1729                                        'string'        => $data['string'],
1730                                        'relatives'     => array ($data['relatives'][0])
1731                                )) != 'Directory'
1732                        )
1733                        {
1734                                $this->add_journal (array(
1735                                                'string'        => $p->fake_full_path,
1736                                                'relatives'     => array ($p->mask),
1737                                                'operation'     => VFS_OPERATION_DELETED
1738                                        )
1739                                );
1740
1741                                $query = $GLOBALS['phpgw']->db->query ("DELETE FROM phpgw_vfs WHERE directory='".
1742                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
1743                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'".$this->extra_sql (array ('query_type' => VFS_SQL_DELETE)), __LINE__, __FILE__);
1744
1745                                if ($this->file_actions)
1746                                {
1747                                        $rr = unlink ($p->real_full_path);
1748                                }
1749                                else
1750                                {
1751                                        $rr = True;
1752                                }
1753
1754                                if ($query || $rr)
1755                                {
1756                                        return True;
1757                                }
1758                                else
1759                                {
1760                                        return False;
1761                                }
1762                        }
1763                        else
1764                        {
1765                                $ls = $this->ls (array(
1766                                                'string'        => $p->fake_full_path,
1767                                                'relatives'     => array ($p->mask)
1768                                        )
1769                                );
1770
1771                                /* First, we cycle through the entries and delete the files */
1772                                foreach($ls as $entry)
1773                                {
1774                                        if ($entry['mime_type'] == 'Directory')
1775                                        {
1776                                                continue;
1777                                        }
1778
1779                                        $this->rm (array(
1780                                                        'string'        => "$entry[directory]/$entry[name]",
1781                                                        'relatives'     => array ($p->mask)
1782                                                )
1783                                        );
1784                                }
1785
1786                                /* Now we cycle through again and delete the directories */
1787                                foreach ($ls as $entry)
1788                                {
1789                                        if ($entry['mime_type'] != 'Directory')
1790                                        {
1791                                                continue;
1792                                        }
1793
1794                                        /* Only the best in confusing recursion */
1795                                        $this->rm (array(
1796                                                        'string'        => "$entry[directory]/$entry[name]",
1797                                                        'relatives'     => array ($p->mask)
1798                                                )
1799                                        );
1800                                }
1801
1802                                /* If the directory is linked, we delete the placeholder directory */
1803                                $ls_array = $this->ls (array(
1804                                                'string'        => $p->fake_full_path,
1805                                                'relatives'     => array ($p->mask),
1806                                                'checksubdirs'  => False,
1807                                                'mime_type'     => False,
1808                                                'nofiles'       => True
1809                                        )
1810                                );
1811                                $link_info = $ls_array[0];
1812
1813                                if ($link_info['link_directory'] && $link_info['link_name'])
1814                                {
1815                                        $path = $this->path_parts (array(
1816                                                        'string'        => $link_info['directory'] . '/' . $link_info['name'],
1817                                                        'relatives'     => array ($p->mask),
1818                                                        'nolinks'       => True
1819                                                )
1820                                        );
1821
1822                                        if ($this->file_actions)
1823                                        {
1824                                                rmdir ($path->real_full_path);
1825                                        }
1826                                }
1827
1828                                /* Last, we delete the directory itself */
1829                                $this->add_journal (array(
1830                                                'string'        => $p->fake_full_path,
1831                                                'relatives'     => array ($p->mask),
1832                                                'operaton'      => VFS_OPERATION_DELETED
1833                                        )
1834                                );
1835
1836                                $query = $GLOBALS['phpgw']->db->query ("DELETE FROM phpgw_vfs WHERE directory='".
1837                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
1838                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" .
1839                                        $this->extra_sql (array ('query_type' => VFS_SQL_DELETE)), __LINE__, __FILE__);
1840
1841                                if ($this->file_actions)
1842                                {
1843                                        rmdir ($p->real_full_path);
1844                                }
1845
1846                                return True;
1847                        }
1848                }
1849
1850                /*
1851                 * See vfs_shared
1852                 */
1853                function mkdir ($data)
1854                {
1855                        if (!is_array ($data))
1856                        {
1857                                $data = array ();
1858                        }
1859
1860                        $default_values = array
1861                                (
1862                                        'relatives'     => array (RELATIVE_CURRENT)
1863                                );
1864
1865                        $data = array_merge ($this->default_values ($data, $default_values), $data);
1866
1867                        $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
1868                        $currentapp = $GLOBALS['phpgw_info']['flags']['currentapp'];
1869
1870                        $p = $this->path_parts (array(
1871                                        'string'        => $data['string'],
1872                                        'relatives'     => array ($data['relatives'][0])
1873                                )
1874                        );
1875
1876                        if (!$this->acl_check (array(
1877                                        'string'        => $p->fake_full_path,
1878                                        'relatives'     => array ($p->mask),
1879                                        'operation'     => PHPGW_ACL_ADD)
1880                                )
1881                        )
1882                        {
1883                                return False;
1884                        }
1885
1886                        /* We don't allow /'s in dir names, of course */
1887                        if (ereg ("/", $p->fake_name))
1888                        {
1889                                return False;
1890                        }
1891
1892                        umask (077);
1893
1894                        if ($this->file_actions)
1895                        {
1896                                if (!@is_dir($p->real_leading_dirs_clean))      // eg. /home or /group does not exist
1897                                {
1898                                        if (!@mkdir($p->real_leading_dirs_clean,0770))  // ==> create it
1899                                        {
1900                                                return False;
1901                                        }
1902                                }
1903                                if (@is_dir($p->real_full_path))        // directory already exists
1904                                {
1905                                        $this->update_real($data,True);         // update its contents
1906                                }
1907                                elseif (!@mkdir ($p->real_full_path, 0770))
1908                                {
1909                                        return False;
1910                                }
1911                        }
1912
1913                        if (!$this->file_exists (array(
1914                                        'string'        => $p->fake_full_path,
1915                                        'relatives'     => array ($p->mask)
1916                                ))
1917                        )
1918                        {
1919                                $query = $GLOBALS['phpgw']->db->query ("INSERT INTO phpgw_vfs (owner_id, name, directory) VALUES ($this->working_id, '".
1920                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."', '".
1921                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."')", __LINE__, __FILE__);
1922       
1923                                $this->set_attributes(array(
1924                                        'string'        => $p->fake_full_path,
1925                                        'relatives'     => array ($p->mask),
1926                                        'attributes'    => array (
1927                                                                'createdby_id' => $account_id,
1928                                                                'size' => 4096,
1929                                                                'mime_type' => 'Directory',
1930                                                                'created' => $this->now,
1931                                                                'deleteable' => 'Y',
1932                                                                'app' => $currentapp
1933                                                        )
1934                                        )
1935                                );
1936
1937                                $this->correct_attributes (array(
1938                                                'string'        => $p->fake_full_path,
1939                                                'relatives'     => array ($p->mask)
1940                                        )
1941                                );
1942
1943                                $this->add_journal (array(
1944                                                'string'        => $p->fake_full_path,
1945                                                'relatives'     => array ($p->mask),
1946                                                'operation'     => VFS_OPERATION_CREATED
1947                                        )
1948                                );
1949                        }
1950                        else
1951                        {
1952                                return False;
1953                        }
1954
1955                        return True;
1956                }
1957
1958                /*
1959                 * See vfs_shared
1960                 */
1961                function make_link ($data)
1962                {
1963                        if (!is_array ($data))
1964                        {
1965                                $data = array ();
1966                        }
1967
1968                        $default_values = array
1969                                (
1970                                        'relatives'     => array (RELATIVE_CURRENT, RELATIVE_CURRENT)
1971                                );
1972
1973                        $data = array_merge ($this->default_values ($data, $default_values), $data);
1974
1975                        $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
1976                        $currentapp = $GLOBALS['phpgw_info']['flags']['currentapp'];
1977
1978                        $vp = $this->path_parts (array(
1979                                        'string'        => $data['vdir'],
1980                                        'relatives'     => array ($data['relatives'][0])
1981                                )
1982                        );
1983
1984                        $rp = $this->path_parts (array(
1985                                        'string'        => $data['rdir'],
1986                                        'relatives'     => array ($data['relatives'][1])
1987                                )
1988                        );
1989
1990                        if (!$this->acl_check (array(
1991                                        'string'        => $vp->fake_full_path,
1992                                        'relatives'     => array ($vp->mask),
1993                                        'operation'     => PHPGW_ACL_ADD
1994                                ))
1995                        )
1996                        {
1997                                return False;
1998                        }
1999
2000                        if ((!$this->file_exists (array(
2001                                        'string'        => $rp->real_full_path,
2002                                        'relatives'     => array ($rp->mask)
2003                                )))
2004                                && !mkdir ($rp->real_full_path, 0770))
2005                        {
2006                                return False;
2007                        }
2008
2009                        if (!$this->mkdir (array(
2010                                        'string'        => $vp->fake_full_path,
2011                                        'relatives'     => array ($vp->mask)
2012                                ))
2013                        )
2014                        {
2015                                return False;
2016                        }
2017
2018                        $size = $this->get_size (array(
2019                                        'string'        => $rp->real_full_path,
2020                                        'relatives'     => array ($rp->mask)
2021                                )
2022                        );
2023
2024                        $this->set_attributes(array(
2025                                        'string'        => $vp->fake_full_path,
2026                                        'relatives'     => array ($vp->mask),
2027                                        'attributes'    => array (
2028                                                                'link_directory' => $rp->real_leading_dirs,
2029                                                                'link_name' => $rp->real_name,
2030                                                                'size' => $size
2031                                                        )
2032                                )
2033                        );
2034
2035                        $this->correct_attributes (array(
2036                                        'string'        => $vp->fake_full_path,
2037                                        'relatives'     => array ($vp->mask)
2038                                )
2039                        );
2040
2041                        return True;
2042                }
2043                function summary ($data)
2044                {
2045
2046                        if (!$this->acl_check (array(
2047                                        'string'        => $data['path'].'/'.$data['string'],
2048                                        'relatives'     => array (RELATIVE_NONE),
2049                                        'operation'     => PHPGW_ACL_READ
2050                                ))
2051                        )
2052                        {
2053                                return False;
2054                        }
2055
2056                        $query = "SELECT summary FROM phpgw_vfs WHERE directory = '"
2057                                .$data['path']."' AND name = '".$data['string']."' and mime_type != 'journal' and mime_type != 'journal-deleted' LIMIT 1";
2058                        if ($GLOBALS['phpgw']->db->query($query) && $GLOBALS['phpgw']->db->next_record()){
2059                                $val = $GLOBALS['phpgw']->db->row();
2060                                return $val['summary'];
2061                        }
2062                }
2063
2064                function set_summary($data){
2065                        if (!is_array ($data))
2066                        {
2067                                $data = array ();
2068                        }
2069
2070                        $default_values = array
2071                                (
2072                                        'relatives'     => array (RELATIVE_CURRENT),
2073                                        'attributes'    => array ()
2074                                );
2075
2076                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2077
2078                        $p = $this->path_parts (array(
2079                                        'string'        => $data['string'],
2080                                        'relatives'     => array ($data['relatives'][0])
2081                                )
2082                        );
2083                        if (!$this->acl_check (array(
2084                                        'string'        => $p->fake_full_path,
2085                                        'relatives'     => array ($p->mask),
2086                                        'operation'     => PHPGW_ACL_EDIT
2087                                ))
2088                        )
2089                        {
2090                                return False;
2091                        }
2092                        if (!$this->file_exists (array(
2093                                        'string'        => $data['string'],
2094                                        'relatives'     => array ($data['relatives'][0])
2095                                ))
2096                        )
2097                        {
2098                                return False;
2099                        }
2100                        $ls_array = $this->ls (array(
2101                                        'string'        => $p->fake_full_path,
2102                                        'relatives'     => array ($p->mask),
2103                                        'checksubdirs'  => False,
2104                                        'nofiles'       => True
2105                                )
2106                        );
2107                        $record = $ls_array[0];
2108                        $data['summary'] = pg_escape_bytea($data['summary']);
2109                        $sql = 'UPDATE phpgw_vfs SET summary = \''.$data['summary'].'\'';
2110                        $sql .= ' WHERE file_id='.(int) $ls_array[0]['file_id'];
2111                        $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE));
2112                        $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__);
2113                }
2114
2115                /*
2116                 * See vfs_shared
2117                 */
2118                function set_attributes ($data,$isNewFile = false)
2119                {
2120                        if (!is_array ($data))
2121                        {
2122                                $data = array ();
2123                        }
2124
2125                        $default_values = array
2126                                (
2127                                        'relatives'     => array (RELATIVE_CURRENT),
2128                                        'attributes'    => array ()
2129                                );
2130
2131                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2132
2133                        $p = $this->path_parts (array(
2134                                        'string'        => $data['string'],
2135                                        'relatives'     => array ($data['relatives'][0])
2136                                )
2137                        );
2138
2139                        /*
2140                           This is kind of trivial, given that set_attributes () can change owner_id,
2141                           size, etc.
2142                         */
2143                        if($isNewFile)
2144                        {
2145                                if ( !$this->acl_check (array(
2146                                        'string'        => $p->fake_full_path,
2147                                        'relatives'     => array ($p->mask),
2148                                        'operation'     => PHPGW_ACL_ADD
2149                                ))
2150                                )
2151                                {
2152                                        return False;
2153                                }
2154                        }elseif (!$this->acl_check (array(
2155                                'string'        => $p->fake_full_path,
2156                                        'relatives'     => array ($p->mask),
2157                                        'operation'     => PHPGW_ACL_EDIT
2158                                ))
2159                        )
2160                        {
2161                                return False;
2162                        }
2163
2164
2165                        if (!$this->file_exists (array(
2166                                        'string'        => $data['string'],
2167                                        'relatives'     => array ($data['relatives'][0])
2168                                ))
2169                        )
2170                        {
2171                                return False;
2172                        }
2173
2174                        /*
2175                           All this voodoo just decides which attributes to update
2176                           depending on if the attribute was supplied in the 'attributes' array
2177                        */
2178
2179                        $ls_array = $this->ls (array(
2180                                        'string'        => $p->fake_full_path,
2181                                        'relatives'     => array ($p->mask),
2182                                        'checksubdirs'  => False,
2183                                        'nofiles'       => True
2184                                )
2185                        );
2186                        $record = $ls_array[0];
2187
2188                        $sql = 'UPDATE phpgw_vfs SET ';
2189
2190                        $change_attributes = 0;
2191
2192                        foreach ($this->attributes as $attribute)
2193                        {
2194                                if (isset ($data['attributes'][$attribute]))
2195                                {
2196                                        /*
2197                                           Indicate that the EDITED_COMMENT operation needs to be journaled,
2198                                           but only if the comment changed
2199                                        */
2200                                        if ($attribute == 'comment' && $data['attributes'][$attribute] != $record[$attribute])
2201                                        {
2202                                                $edited_comment = 1;
2203                                        }
2204
2205                                        if ($change_attributes > 0)
2206                                        {
2207                                                $sql .= ', ';
2208                                        }
2209
2210                                        // RalfBecker 2004/07/24:
2211                                        // this is only a hack to fix bug [ 991222 ] Error uploading file
2212                                        // the whole class need to be reworked with the new db-functions
2213                                        if (!isset($this->column_defs))
2214                                        {
2215                                                $table_defs = $GLOBALS['phpgw']->db->get_table_definitions('phpgwapi','phpgw_vfs');
2216                                                $this->column_defs = $table_defs['fd'];
2217                                        }
2218                                        $sql .= $attribute.'=' .$GLOBALS['phpgw']->db->quote($data['attributes'][$attribute],$this->column_defs[$attribute]['type']);
2219
2220                                        $change_attributes++;
2221                                }
2222                        }
2223
2224                        if (!$change_attributes)
2225                        {
2226                                return True;    // nothing to do
2227                        }
2228                        $sql .= ' WHERE file_id='.(int) $record['file_id'];
2229                        $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE));
2230                        $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__);
2231
2232                        if ($query)
2233                        {
2234                                if ($edited_comment)
2235                                {
2236                                        $this->add_journal (array(
2237                                                        'string'        => $p->fake_full_path,
2238                                                        'relatives'     => array ($p->mask),
2239                                                        'operation'     => VFS_OPERATION_EDITED_COMMENT
2240                                                )
2241                                        );
2242                                }
2243
2244                                return True;
2245                        }
2246                        else
2247                        {
2248                                return False;
2249                        }
2250                }
2251
2252                /*!
2253                @function correct_attributes
2254                @abstract Set the correct attributes for 'string' (e.g. owner)
2255                @param string File/directory to correct attributes of
2256                @param relatives Relativity array
2257                @result Boolean True/False
2258                */
2259                function correct_attributes ($data)
2260                {
2261                        if (!is_array ($data))
2262                        {
2263                                $data = array ();
2264                        }
2265
2266                        $default_values = array
2267                                (
2268                                        'relatives'     => array (RELATIVE_CURRENT)
2269                                );
2270
2271                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2272
2273                        $p = $this->path_parts (array(
2274                                        'string'        => $data['string'],
2275                                        'relatives'     => array ($data['relatives'][0])
2276                                )
2277                        );
2278
2279                        if ($p->fake_leading_dirs != $this->fakebase && $p->fake_leading_dirs != '/')
2280                        {
2281                                $ls_array = $this->ls (array(
2282                                                'string'        => $p->fake_leading_dirs,
2283                                                'relatives'     => array ($p->mask),
2284                                                'checksubdirs'  => False,
2285                                                'nofiles'       => True
2286                                        )
2287                                );
2288                                $set_attributes_array = Array(
2289                                        'owner_id' => $ls_array[0]['owner_id']
2290                                );
2291                        }
2292                        elseif (preg_match ("+^$this->fakebase\/(.*)$+U", $p->fake_full_path, $matches))
2293                        {
2294                                $set_attributes_array = Array(
2295                                        'owner_id' => $GLOBALS['phpgw']->accounts->name2id ($matches[1])
2296                                );
2297                        }
2298                        else
2299                        {
2300                                $set_attributes_array = Array(
2301                                        'owner_id' => 0
2302                                );
2303                        }
2304
2305                        $this->set_attributes (array(
2306                                        'string'        => $p->fake_full_name,
2307                                        'relatives'     => array ($p->mask),
2308                                        'attributes'    => $set_attributes_array
2309                                )
2310                        );
2311
2312                        return True;
2313                }
2314
2315                /*
2316                 * See vfs_shared
2317                 */
2318                function file_type ($data)
2319                {
2320                        if (!is_array ($data))
2321                        {
2322                                $data = array ();
2323                        }
2324
2325                        $default_values = array
2326                                (
2327                                        'relatives'     => array (RELATIVE_CURRENT)
2328                                );
2329
2330                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2331
2332                        $p = $this->path_parts (array(
2333                                        'string'        => $data['string'],
2334                                        'relatives'     => array ($data['relatives'][0])
2335                                )
2336                        );
2337
2338                        if (!$this->acl_check (array(
2339                                        'string'        => $p->fake_full_path,
2340                                        'relatives'     => array ($p->mask),
2341                                        'operation'     => PHPGW_ACL_READ,
2342                                        'must_exist'    => True
2343                                ))
2344                        )
2345                        {
2346                                return False;
2347                        }
2348
2349                        if ($p->outside)
2350                        {
2351                                if (is_dir ($p->real_full_path))
2352                                {
2353                                        return ('Directory');
2354                                }
2355
2356                                /*
2357                                   We don't return an empty string here, because it may still match with a database query
2358                                   because of linked directories
2359                                */
2360                        }
2361
2362                        /*
2363                           We don't use ls () because it calls file_type () to determine if it has been
2364                           passed a directory
2365                        */
2366                        $db2 = $GLOBALS['phpgw']->db;
2367                        $db2->query ("SELECT mime_type FROM phpgw_vfs WHERE directory='".
2368                                $db2->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2369                                $db2->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2370                        $db2->next_record ();
2371                        $mime_type = $db2->Record['mime_type'];
2372                        if(!$mime_type)
2373                        {
2374                                $mime_type = $this->get_ext_mime_type (array ('string' => $data['string']));
2375                                {
2376                                        $db2->query ("UPDATE phpgw_vfs SET mime_type='$mime_type' WHERE directory='".
2377                                                $db2->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2378                                                $db2->db_addslashes($p->fake_name_clean)."'" .
2379                                                $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2380                                }
2381                        }
2382
2383                        return $mime_type;
2384                }
2385
2386                /*
2387                 * See vfs_shared
2388                 */
2389                function file_exists ($data)
2390                {
2391                        if (!is_array ($data))
2392                        {
2393                                $data = array ();
2394                        }
2395
2396                        $default_values = array
2397                                (
2398                                        'relatives'     => array (RELATIVE_CURRENT)
2399                                );
2400
2401                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2402
2403                        $p = $this->path_parts (array(
2404                                        'string'        => $data['string'],
2405                                        'relatives'     => array ($data['relatives'][0])
2406                                )
2407                        );
2408
2409                        if ($p->outside)
2410                        {
2411                                $rr = file_exists ($p->real_full_path);
2412
2413                                return $rr;
2414                        }
2415
2416                        $db2 = $GLOBALS['phpgw']->db;
2417                        $db2->query ("SELECT name FROM phpgw_vfs WHERE directory='".
2418                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2419                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2420
2421                        if ($db2->next_record ())
2422                        {
2423                                return True;
2424                        }
2425                        else
2426                        {
2427                                return False;
2428                        }
2429                }
2430
2431                /*
2432                 * See vfs_shared
2433                 */
2434                function get_size ($data)
2435                {
2436                        if (!is_array ($data))
2437                        {
2438                                $data = array ();
2439                        }
2440
2441                        $default_values = array
2442                                (
2443                                        'relatives'     => array (RELATIVE_CURRENT),
2444                                        'checksubdirs'  => True
2445                                );
2446
2447                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2448
2449                        $p = $this->path_parts (array(
2450                                        'string'        => $data['string'],
2451                                        'relatives'     => array ($data['relatives'][0])
2452                                )
2453                        );
2454
2455                        if (!$this->acl_check (array(
2456                                        'string'        => $p->fake_full_path,
2457                                        'relatives'     => array ($p->mask),
2458                                        'operation'     => PHPGW_ACL_READ,
2459                                        'must_exist'    => True
2460                                ))
2461                        )
2462                        {
2463                                return False;
2464                        }
2465
2466                        /*
2467                           WIP - this should run through all of the subfiles/directories in the directory and tally up
2468                           their sizes.  Should modify ls () to be able to return a list for files outside the virtual root
2469                        */
2470                        if ($p->outside)
2471                        {
2472                                $size = filesize ($p->real_full_path);
2473
2474                                return $size;
2475                        }
2476
2477                        foreach($this->ls (array(
2478                                        'string'        => $p->fake_full_path,
2479                                        'relatives'     => array ($p->mask),
2480                                        'checksubdirs'  => $data['checksubdirs'],
2481                                        'nofiles'       => !$data['checksubdirs']
2482                                )) as $file_array)
2483                        {
2484                                /*
2485                                   Make sure the file is in the directory we want, and not
2486                                   some deeper nested directory with a similar name
2487                                */
2488/*
2489                                if (@!ereg ('^' . $file_array['directory'], $p->fake_full_path))
2490                                {
2491                                        continue;
2492                                }
2493*/
2494
2495                                $size += $file_array['size'];
2496                        }
2497
2498                        if ($data['checksubdirs'])
2499                        {
2500                                $query = $GLOBALS['phpgw']->db->query ("SELECT size FROM phpgw_vfs WHERE directory='".
2501                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2502                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" .
2503                                        $this->extra_sql (array ('query_text' => VFS_SQL_SELECT)));
2504                                $GLOBALS['phpgw']->db->next_record ();
2505                                $size += $GLOBALS['phpgw']->db->Record[0];
2506                        }
2507
2508                        return $size;
2509                }
2510
2511                /*return the total number of files in path*/
2512                function count_files($data){
2513                        if (!is_array ($data))
2514                        {
2515                                $data = array ();
2516                        }
2517
2518                        $default_values = array
2519                                (
2520                                        'relatives'     => array (RELATIVE_CURRENT)
2521                                );
2522
2523                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2524
2525                        $p = $this->path_parts (array(
2526                                        'string'        => $data['string'],
2527                                        'relatives'     => RELATIVE_NONE
2528                                )
2529                        );
2530
2531                        if (!$this->acl_check (array(
2532                                'string'        => $p->fake_full_path,
2533                                'relatives'     => $p->mask,
2534                                'operation'     => PHPGW_ACL_READ
2535                        ))
2536                        )
2537                        {
2538                                return False;
2539                        }
2540                        $sql = "SELECT count(*) FROM phpgw_vfs WHERE directory = '".$GLOBALS['phpgw']->db->db_addslashes($data['string'])."'";
2541                        $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_SELECT));
2542                        $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__,__FILE__);
2543
2544                        $GLOBALS['phpgw']->db->next_record ();
2545                        $record = $GLOBALS['phpgw']->db->Record;
2546                        return $record['count'];
2547                }
2548
2549                /*
2550                 * get the quota defined for the path in sql table
2551                 */
2552                function get_quota($data){
2553                        if (!is_array ($data))
2554                        {
2555                                $data = array ();
2556                        }
2557
2558                        $default_values = array
2559                                (
2560                                        'relatives'     => array (RELATIVE_CURRENT)
2561                                );
2562
2563                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2564
2565                        $p = $this->path_parts (array(
2566                                        'string'        => $data['string'],
2567                                        'relatives'     => RELATIVE_NONE
2568                                )
2569                        );
2570
2571                        if (!$this->acl_check (array(
2572                                'string'        => $p->fake_full_path,
2573                                'relatives'     => $p->mask,
2574                                'operation'     => PHPGW_ACL_READ
2575                        ))
2576                        )
2577                        {
2578                                return False;
2579                        }
2580                        $query = $GLOBALS['phpgw']->db->query ("SELECT quota_size FROM phpgw_vfs_quota WHERE directory = '".$data['string']."' LIMIT 1;", __LINE__,__FILE__);
2581
2582                        $GLOBALS['phpgw']->db->next_record ();
2583                        $record = $GLOBALS['phpgw']->db->Record;
2584                        return $record['quota_size'];
2585                }
2586                function set_quota($data){
2587                        if (!is_array ($data))
2588                        {
2589                                $data = array ();
2590                        }
2591
2592                        $default_values = array
2593                                (
2594                                        'relatives'     => array (RELATIVE_CURRENT)
2595                                );
2596
2597                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2598
2599                        $p = $this->path_parts (array(
2600                                        'string'        => $data['string'],
2601                                        'relatives'     => array ($data['relatives'][0])
2602                                )
2603                        );
2604
2605                        if (!$this->acl_check (array(
2606                                'string'        => $p->fake_full_path,
2607                                'relatives'     => array ($p->mask),
2608                                'operation'     => PHPGW_ACL_READ
2609                        ))
2610                        )
2611                        {
2612                                return False;
2613                        }
2614                        return $GLOBALS['phpgw']->db->query("INSERT INTO phpgw_vfs_quota VALUES ('".$data['string']."',".$data['new_quota'].");", __LINE__,__FILE__);
2615                }
2616
2617
2618                /*!
2619                @function checkperms
2620                @abstract Check if $this->working_id has write access to create files in $dir
2621                @discussion Simple call to acl_check
2622                @param string Directory to check access of
2623                @param relatives Relativity array
2624                @result Boolean True/False
2625                */
2626                function checkperms ($data)
2627                {
2628                        if (!is_array ($data))
2629                        {
2630                                $data = array ();
2631                        }
2632
2633                        $default_values = array
2634                                (
2635                                        'relatives'     => array (RELATIVE_CURRENT)
2636                                );
2637
2638                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2639
2640                        $p = $this->path_parts (array(
2641                                        'string'        => $data['string'],
2642                                        'relatives'     => array ($data['relatives'][0])
2643                                )
2644                        );
2645
2646                        if (!$this->acl_check (array(
2647                                        'string'        => $p->fake_full_path,
2648                                        'relatives'     => array ($p->mask),
2649                                        'operation'     => PHPGW_ACL_ADD
2650                                ))
2651                        )
2652                        {
2653                                return False;
2654                        }
2655                        else
2656                        {
2657                                return True;
2658                        }
2659                }
2660
2661                /*
2662                 * See vfs_shared
2663                 * If $data['readlink'] then a readlink is tryed on the real file
2664                 * If $data['file_id'] then the file_id is used instead of a path
2665                 */
2666                function ls ($data)
2667                {
2668                        if (!is_array ($data))
2669                        {
2670                                $data = array ();
2671                        }
2672
2673                        $default_values = array
2674                                (
2675                                        'relatives'     => array (RELATIVE_CURRENT),
2676                                        'checksubdirs'  => True,
2677                                        'mime_type'     => False,
2678                                        'nofiles'       => False,
2679                                        'summary'       => False,
2680                                        'orderby'       => 'directory',
2681                                        'otype'         => 1
2682                                );
2683
2684                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2685
2686                        $p = $this->path_parts (array(
2687                                        'string'        => $data['string'],
2688                                        'relatives'     => array ($data['relatives'][0])
2689                                )
2690                        );
2691                        $dir = $p->fake_full_path;
2692                        if($data['summary'])
2693                                $this->attributes['summary'] = 'summary';
2694
2695                        $type = $this->file_type (array(
2696                                        'string'        => $dir,
2697                                        'relatives'     => array ($p->mask)
2698                                ));
2699                        /* If they pass us a file or 'nofiles' is set, return the info for $dir only */
2700                        if (@$data['file_id'] || ($type != 'Directory' || $data['nofiles']) && !$p->outside)
2701                        {
2702                                /* SELECT all, the, attributes */
2703                                $sql = 'SELECT ';
2704
2705                                foreach ($this->attributes as $num => $attribute)
2706                                {
2707                                        if ($num)
2708                                        {
2709                                                $sql .= ', ';
2710                                        }
2711
2712                                        $sql .= $attribute;
2713                                }
2714
2715                                $sql .= " FROM phpgw_vfs WHERE ";
2716                                if (@$data['file_id'])
2717                                {
2718                                        $sql .= 'file_id='.(int)$data['file_id'];
2719                                }
2720                                else
2721                                {
2722                                        $sql .= " directory='".$GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND".
2723                                                " name='".$GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'".
2724                                                $this->extra_sql (array ('query_type' => VFS_SQL_SELECT));
2725                                }
2726                                $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__);
2727
2728                                $GLOBALS['phpgw']->db->next_record ();
2729                                $record = $GLOBALS['phpgw']->db->Record;
2730
2731                                /* We return an array of one array to maintain the standard */
2732                                $rarray = array ();
2733                                foreach($this->attributes as $attribute)
2734                                {
2735                                        if ($attribute == 'mime_type' && !$record[$attribute])
2736                                        {
2737                                                $db2 = $GLOBALS['phpgw']->db;
2738                                                $record[$attribute] = $this->get_ext_mime_type (array(
2739                                                                'string' => $p->fake_name_clean
2740                                                        )
2741                                                );
2742
2743                                                if($record[$attribute])
2744                                                {
2745                                                        $db2->query ("UPDATE phpgw_vfs SET mime_type='".$record[$attribute]."' WHERE directory='".
2746                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2747                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2748                                                }
2749                                        }
2750
2751                                        $rarray[0][$attribute] = $record[$attribute];
2752                                }
2753                                if ($this->file_actions && @$data['readlink'])  // test if file is a symlink and get it's target
2754                                {
2755                                        $rarray[0]['symlink'] = @readlink($p->real_full_path);
2756                                }
2757                                if($data['summary'])
2758                                        unset($this->attributes['summary']);
2759
2760                                return $rarray;
2761                        }
2762
2763                        //WIP - this should recurse using the same options the virtual part of ls () does
2764                        /* If $dir is outside the virutal root, we have to check the file system manually */
2765                        if ($p->outside)
2766                        {
2767                                if ($this->file_type (array(
2768                                                'string'        => $p->fake_full_path,
2769                                                'relatives'     => array ($p->mask)
2770                                        )) == 'Directory'
2771                                        && !$data['nofiles']
2772                                )
2773                                {
2774                                        $dir_handle = opendir ($p->real_full_path);
2775                                        while ($filename = readdir ($dir_handle))
2776                                        {
2777                                                if ($filename == '.' || $filename == '..')
2778                                                {
2779                                                        continue;
2780                                                }
2781
2782                                                $rarray[] = $this->get_real_info (array(
2783                                                                'string'        => $p->real_full_path . SEP . $filename,
2784                                                                'relatives'     => array ($p->mask)
2785                                                        )
2786                                                );
2787                                        }
2788                                }
2789                                else
2790                                {
2791                                        $rarray[] = $this->get_real_info (array(
2792                                                        'string'        => $p->real_full_path,
2793                                                        'relatives'     => array ($p->mask)
2794                                                )
2795                                        );
2796                                }
2797
2798                                return $rarray;
2799                        }
2800
2801                        /* $dir's not a file, is inside the virtual root, and they want to check subdirs */
2802                        /* SELECT all, the, attributes FROM phpgw_vfs WHERE file=$dir */
2803                        $sql = 'SELECT ';
2804                        if (!$this->acl_check (array (
2805                                'string' => $p->fake_full_path,
2806                                'relatives' => array ($p->mask),
2807                                'operation' => PHPGW_ACL_PRIVATE)
2808                        ))
2809                        $query_type = " type != 1 AND";
2810                        else
2811                                $query_type = "";
2812
2813                        foreach($this->attributes as $num => $attribute)
2814                        {
2815                                if ($num)
2816                                {
2817                                        $sql .= ", ";
2818                                }
2819
2820                                $sql .= $attribute;
2821                        }
2822
2823                        $dir_clean = $this->clean_string (array ('string' => $dir));
2824                        $sql .= " FROM phpgw_vfs WHERE ".$query_type." directory = '".$GLOBALS['phpgw']->db->db_addslashes($dir_clean)."'";
2825                        $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_SELECT));
2826
2827                        if ($data['mime_type'])
2828                        {
2829                                $sql .= " AND mime_type='".$data['mime_type']."'";
2830                        }
2831                        if (strlen($data['orderby']) > 0 && $data['orderby'] != 'directory'){
2832                                $order_direction = $data['otype'] ? ' ASC' : ' DESC';
2833                                if ($data['orderby'] == 'name' || $data['orderby'] == 'comment')
2834                                        $sql .= ' ORDER BY upper('.$data['orderby'].')'.$order_direction;
2835                                else
2836                                        $sql .= ' ORDER BY '.$data['orderby'].$order_direction;
2837                                if ($data['orderby'] != 'name')
2838                                        $sql .= ', upper(name)'.$order_direction;
2839                        }
2840                        $data['offset'] = $data['offset'] ? $data['offset'] : 0;
2841                        $data['limit'] = $data['limit'] ? $data['limit'] : 10000;
2842                        if ($data['orderby'] != 'directory')
2843                                $sql .= ' LIMIT '.$data['limit'].' OFFSET '.$data['offset'];
2844                        $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__);
2845
2846                        $rarray = array ();
2847                        for ($i = 0; $GLOBALS['phpgw']->db->next_record (); $i++)
2848                        {
2849                                $record = $GLOBALS['phpgw']->db->Record;
2850                                foreach($this->attributes as $attribute)
2851                                {
2852                                        if ($attribute == 'mime_type' && !$record[$attribute])
2853                                        {
2854                                                $db2 = $GLOBALS['phpgw']->db;
2855                                                $record[$attribute] = $this->get_ext_mime_type (array(
2856                                                                'string'        => $p->fake_name_clean
2857                                                        )
2858                                                );
2859
2860                                                if($record[$attribute])
2861                                                {
2862                                                        $db2->query ("UPDATE phpgw_vfs SET mime_type='".$record[$attribute]."' WHERE directory='".
2863                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2864                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2865                                                }
2866                                        }
2867
2868                                        $rarray[$i][$attribute] = $record[$attribute];
2869                                }
2870                        }
2871
2872                        return $rarray;
2873                }
2874
2875                /*
2876                 * See vfs_shared
2877                 */
2878                function update_real ($data,$recursive = False)
2879                {
2880                        if (!is_array ($data))
2881                        {
2882                                $data = array ();
2883                        }
2884
2885                        $default_values = array
2886                                (
2887                                        'relatives'     => array (RELATIVE_CURRENT)
2888                                );
2889
2890                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2891
2892                        $p = $this->path_parts (array(
2893                                        'string'        => $data['string'],
2894                                        'relatives'     => array ($data['relatives'][0])
2895                                )
2896                        );
2897
2898                        if (file_exists ($p->real_full_path))
2899                        {
2900                                if (is_dir ($p->real_full_path))
2901                                {
2902                                        $dir_handle = opendir ($p->real_full_path);
2903                                        while ($filename = readdir ($dir_handle))
2904                                        {
2905                                                if ($filename == '.' || $filename == '..')
2906                                                {
2907                                                        continue;
2908                                                }
2909
2910                                                $rarray[] = $this->get_real_info (array(
2911                                                                'string'        => $p->fake_full_path . '/' . $filename,
2912                                                                'relatives'     => array (RELATIVE_NONE)
2913                                                        )
2914                                                );
2915                                        }
2916                                }
2917                                else
2918                                {
2919                                        $rarray[] = $this->get_real_info (array(
2920                                                        'string'        => $p->fake_full_path,
2921                                                        'relatives'     => array (RELATIVE_NONE)
2922                                                )
2923                                        );
2924                                }
2925
2926                                if (!is_array ($rarray))
2927                                {
2928                                        $rarray = array ();
2929                                }
2930
2931                                foreach($rarray as $num => $file_array)
2932                                {
2933                                        $p2 = $this->path_parts (array(
2934                                                        'string'        => $file_array['directory'] . '/' . $file_array['name'],
2935                                                        'relatives'     => array (RELATIVE_NONE)
2936                                                )
2937                                        );
2938
2939                                        /* Note the mime_type.  This can be "Directory", which is how we create directories */
2940                                        $set_attributes_array = Array(
2941                                                'size' => $file_array['size'],
2942                                                'mime_type' => $file_array['mime_type']
2943                                        );
2944
2945                                        if (!$this->file_exists (array(
2946                                                        'string'        => $p2->fake_full_path,
2947                                                        'relatives'     => array (RELATIVE_NONE)
2948                                                ))
2949                                        )
2950                                        {
2951                                                $this->touch (array(
2952                                                                'string'        => $p2->fake_full_path,
2953                                                                'relatives'     => array (RELATIVE_NONE)
2954                                                        )
2955                                                );
2956                                        }
2957                                        $this->set_attributes (array(
2958                                                        'string'        => $p2->fake_full_path,
2959                                                        'relatives'     => array (RELATIVE_NONE),
2960                                                        'attributes'    => $set_attributes_array
2961                                                )
2962                                        );
2963                                        if ($recursive && $file_array['mime_type'] == 'Directory')
2964                                        {
2965                                                $dir_data = $data;
2966                                                $dir_data['string'] = $file_array['directory'] . '/' . $file_array['name'];
2967                                                $this->update_real($dir_data,$recursive);
2968                                        }
2969                                }
2970                        }
2971                }
2972
2973                /* Helper functions */
2974
2975                /* This fetchs all available file system information for string (not using the database) */
2976                function get_real_info ($data)
2977                {
2978                        if (!is_array ($data))
2979                        {
2980                                $data = array ();
2981                        }
2982
2983                        $default_values = array
2984                                (
2985                                        'relatives'     => array (RELATIVE_CURRENT)
2986                                );
2987
2988                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2989
2990                        $p = $this->path_parts (array(
2991                                        'string'        => $data['string'],
2992                                        'relatives'     => array ($data['relatives'][0])
2993                                )
2994                        );
2995
2996                        if (is_dir ($p->real_full_path))
2997                        {
2998                                $mime_type = 'Directory';
2999                        }
3000                        else
3001                        {
3002                                $mime_type = $this->get_ext_mime_type (array(
3003                                                'string'        => $p->fake_name
3004                                        )
3005                                );
3006
3007                                if($mime_type)
3008                                {
3009                                        $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET mime_type='".$mime_type."' WHERE directory='".
3010                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
3011                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" .
3012                                                $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
3013                                }
3014                        }
3015
3016                        $size = filesize ($p->real_full_path);
3017                        $rarray = array(
3018                                'directory' => $p->fake_leading_dirs,
3019                                'name' => $p->fake_name,
3020                                'size' => $size,
3021                                'mime_type' => $mime_type
3022                        );
3023
3024                        return ($rarray);
3025                }
3026        }
3027?>
Note: See TracBrowser for help on using the repository browser.