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

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

Ticket #597 - Correção de arredondamento de buffer

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