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

Revision 1998, 74.4 KB checked in by fpcorrea, 14 years ago (diff)

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