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

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

Ticket #597 - melhoria no tratamento de arquivos grandes

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