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

Revision 2090, 74.7 KB checked in by amuller, 14 years ago (diff)

Ticket #930 - Correção do problema adicionando uma flag no método

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