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

Revision 1928, 72.1 KB checked in by amuller, 14 years ago (diff)

Ticket #597 - Melhoria de performance, para testar posteriorente

  • 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
1066                        /* We, however, have to decide this ourselves */
1067                        if ($this->file_exists (array(
1068                                        'string'        => $p->fake_full_path,
1069                                        'relatives'     => array ($p->mask)
1070                                ))
1071                        )
1072                        {
1073                                if (!$this->acl_check (array(
1074                                                'string'        => $p->fake_full_path,
1075                                                'relatives'     => array ($p->mask),
1076                                                'operation'     => PHPGW_ACL_EDIT
1077                                        )))
1078                                {
1079                                        return False;
1080                                }
1081
1082                                $vr = $this->set_attributes (array(
1083                                                'string'        => $p->fake_full_path,
1084                                                'relatives'     => array ($p->mask),
1085                                                'attributes'    => array(
1086                                                                        'modifiedby_id' => $account_id,
1087                                                                        'modified' => $this->now
1088                                                                )
1089                                                )
1090                                        );
1091                        }
1092                        else
1093                        {
1094                                if (!$this->acl_check (array(
1095                                                'string'        => $p->fake_full_path,
1096                                                'relatives'     => array ($p->mask),
1097                                                'operation'     => PHPGW_ACL_ADD
1098                                        ))
1099                                )
1100                                {
1101                                        return False;
1102                                }
1103
1104                                $query = $GLOBALS['phpgw']->db->query ("INSERT INTO phpgw_vfs (owner_id, directory, name) VALUES ($this->working_id, '".
1105                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."', '".
1106                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."')", __LINE__, __FILE__);
1107
1108                                $this->set_attributes(array(
1109                                        'string'        => $p->fake_full_path,
1110                                        'relatives'     => array ($p->mask),
1111                                        'attributes'    => array (
1112                                                                'createdby_id' => $account_id,
1113                                                                'created' => $this->now,
1114                                                                'size' => 0,
1115                                                                'deleteable' => 'Y',
1116                                                                'app' => $currentapp
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
1161                        if ($quota > 0 && ($quota * 1024 * 1024) < $size)
1162                                return false;
1163
1164                        $default_values = array
1165                                (
1166                                        'relatives'     => array (RELATIVE_CURRENT, RELATIVE_CURRENT)
1167                                );
1168
1169                        $data = array_merge ($this->default_values ($data, $default_values), $data);
1170
1171                        $account_id = $GLOBALS['phpgw_info']['user']['account_id'];
1172
1173                        $f = $this->path_parts (array(
1174                                        'string'        => $data['from'],
1175                                        'relatives'     => array ($data['relatives'][0])
1176                                )
1177                        );
1178
1179                        $t = $this->path_parts (array(
1180                                        'string'        => $data['to'],
1181                                        'relatives'     => array ($data['relatives'][1])
1182                                )
1183                        );
1184
1185                        if (!$this->acl_check (array(
1186                                        'string'        => $f->fake_full_path,
1187                                        'relatives'     => array ($f->mask),
1188                                        'operation'     => PHPGW_ACL_READ
1189                                ))
1190                        )
1191                        {
1192                                return False;
1193                        }
1194
1195                        if ($exists = $this->file_exists (array(
1196                                        'string'        => $t->fake_full_path,
1197                                        'relatives'     => array ($t->mask)
1198                                ))
1199                        )
1200                        {
1201                                if (!$this->acl_check (array(
1202                                                'string'        => $t->fake_full_path,
1203                                                'relatives'     => array ($t->mask),
1204                                                'operation'     => PHPGW_ACL_EDIT
1205                                        ))
1206                                )
1207                                {
1208                                        return False;
1209                                }
1210                        }
1211                        else
1212                        {
1213                                if (!$this->acl_check (array(
1214                                                'string'        => $t->fake_full_path,
1215                                                'relatives'     => array ($t->mask),
1216                                                'operation'     => PHPGW_ACL_ADD
1217                                        ))
1218                                )
1219                                {
1220                                        return False;
1221                                }
1222                        }
1223
1224                        umask(0177);
1225
1226                        if ($this->file_type (array(
1227                                        'string'        => $f->fake_full_path,
1228                                        'relatives'     => array ($f->mask)
1229                                )) != 'Directory'
1230                        )
1231                        {
1232                                if ($this->file_actions)
1233                                {
1234                                        if (@$data['symlink'])
1235                                        {
1236                                                if ($exists)
1237                                                {
1238                                                        @unlink($t->real_full_path);
1239                                                }
1240                                                if (!symlink($f->real_full_path, $t->real_full_path))
1241                                                {
1242                                                        return False;
1243                                                }
1244                                        }
1245                                        elseif (!copy ($f->real_full_path, $t->real_full_path))
1246                                        {
1247                                                return False;
1248                                        }
1249
1250                                        $size = filesize ($t->real_full_path);
1251                                }
1252                                else
1253                                {
1254                                        $content = $this->read (array(
1255                                                        'string'        => $f->fake_full_path,
1256                                                        'relatives'     => array ($f->mask)
1257                                                )
1258                                        );
1259
1260                                        $size = strlen ($content);
1261                                }
1262
1263                                if ($t->outside)
1264                                {
1265                                        return True;
1266                                }
1267
1268                                $ls_array = $this->ls (array(
1269                                                'string'        => $f->fake_full_path,
1270                                                'relatives'     => array ($f->mask),
1271                                                'checksubdirs'  => False,
1272                                                'mime_type'     => False,
1273                                                'summary'       => True,
1274                                                'nofiles'       => True
1275                                        )
1276                                );
1277                                $record = $ls_array[0];
1278
1279                                if ($this->file_exists (array(
1280                                                'string'        => $data['to'],
1281                                                'relatives'     => array ($data['relatives'][1])
1282                                        ))
1283                                )
1284                                {
1285                                        $query = $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET owner_id='$this->working_id', directory='".
1286                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."', name='".
1287                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."' WHERE owner_id='$this->working_id' AND directory='".
1288                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_leading_dirs_clean)."' AND name='".
1289                                                $GLOBALS['phpgw']->db->db_addslashes($t->fake_name_clean)."'" . $this->extra_sql (VFS_SQL_UPDATE), __LINE__, __FILE__);
1290                               
1291                                        $set_attributes_array = array (
1292                                                'createdby_id' => $account_id,
1293                                                'created' => $this->now,
1294                                                'size' => $size,
1295                                                'mime_type' => $record['mime_type'],
1296                                                'deleteable' => $record['deleteable'],
1297                                                'comment' => $record['comment'],
1298                                                'app' => $record['app']
1299                                        );
1300
1301                                        if (!$this->file_actions)
1302                                        {
1303                                                $set_attributes_array['content'] = $content;
1304                                        }
1305
1306                                        $this->set_attributes(array(
1307                                                'string'        => $t->fake_full_path,
1308                                                'relatives'     => array ($t->mask),
1309                                                'attributes'    => $set_attributes_array
1310                                                )
1311                                        );
1312
1313                                        $this->add_journal (array(
1314                                                        'string'        => $t->fake_full_path,
1315                                                        'relatives'     => array ($t->mask),
1316                                                        'operation'     => VFS_OPERATION_EDITED
1317                                                )
1318                                        );
1319                                }
1320                                else
1321                                {
1322                                        $this->touch (array(
1323                                                        'string'        => $t->fake_full_path,
1324                                                        'relatives'     => array ($t->mask)
1325                                                )
1326                                        );
1327
1328                                        $set_attributes_array = array (
1329                                                'createdby_id' => $account_id,
1330                                                'created' => $this->now,
1331                                                'size' => $size,
1332                                                'mime_type' => $record['mime_type'],
1333                                                'deleteable' => $record['deleteable'],
1334                                                'comment' => $record['comment'],
1335                                                'app' => $record['app']
1336                                        );
1337
1338                                        if (!$this->file_actions)
1339                                        {
1340                                                $set_attributes_array['content'] = $content;
1341                                        }
1342
1343                                        $this->set_attributes(array(
1344                                                        'string'        => $t->fake_full_path,
1345                                                        'relatives'     => array ($t->mask),
1346                                                        'attributes'    => $set_attributes_array
1347                                                )
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)
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 (!$this->acl_check (array(
2138                                        'string'        => $p->fake_full_path,
2139                                        'relatives'     => array ($p->mask),
2140                                        'operation'     => PHPGW_ACL_EDIT
2141                                ))
2142                        )
2143                        {
2144                                return False;
2145                        }
2146
2147                        if (!$this->file_exists (array(
2148                                        'string'        => $data['string'],
2149                                        'relatives'     => array ($data['relatives'][0])
2150                                ))
2151                        )
2152                        {
2153                                return False;
2154                        }
2155
2156                        /*
2157                           All this voodoo just decides which attributes to update
2158                           depending on if the attribute was supplied in the 'attributes' array
2159                        */
2160
2161                        $ls_array = $this->ls (array(
2162                                        'string'        => $p->fake_full_path,
2163                                        'relatives'     => array ($p->mask),
2164                                        'checksubdirs'  => False,
2165                                        'nofiles'       => True
2166                                )
2167                        );
2168                        $record = $ls_array[0];
2169
2170                        $sql = 'UPDATE phpgw_vfs SET ';
2171
2172                        $change_attributes = 0;
2173
2174                        foreach ($this->attributes as $attribute)
2175                        {
2176                                if (isset ($data['attributes'][$attribute]))
2177                                {
2178                                        /*
2179                                           Indicate that the EDITED_COMMENT operation needs to be journaled,
2180                                           but only if the comment changed
2181                                        */
2182                                        if ($attribute == 'comment' && $data['attributes'][$attribute] != $record[$attribute])
2183                                        {
2184                                                $edited_comment = 1;
2185                                        }
2186
2187                                        if ($change_attributes > 0)
2188                                        {
2189                                                $sql .= ', ';
2190                                        }
2191
2192                                        // RalfBecker 2004/07/24:
2193                                        // this is only a hack to fix bug [ 991222 ] Error uploading file
2194                                        // the whole class need to be reworked with the new db-functions
2195                                        if (!isset($this->column_defs))
2196                                        {
2197                                                $table_defs = $GLOBALS['phpgw']->db->get_table_definitions('phpgwapi','phpgw_vfs');
2198                                                $this->column_defs = $table_defs['fd'];
2199                                        }
2200                                        $sql .= $attribute.'=' .$GLOBALS['phpgw']->db->quote($data['attributes'][$attribute],$this->column_defs[$attribute]['type']);
2201
2202                                        $change_attributes++;
2203                                }
2204                        }
2205
2206                        if (!$change_attributes)
2207                        {
2208                                return True;    // nothing to do
2209                        }
2210                        $sql .= ' WHERE file_id='.(int) $record['file_id'];
2211                        $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_UPDATE));
2212                        $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__);
2213
2214                        if ($query)
2215                        {
2216                                if ($edited_comment)
2217                                {
2218                                        $this->add_journal (array(
2219                                                        'string'        => $p->fake_full_path,
2220                                                        'relatives'     => array ($p->mask),
2221                                                        'operation'     => VFS_OPERATION_EDITED_COMMENT
2222                                                )
2223                                        );
2224                                }
2225
2226                                return True;
2227                        }
2228                        else
2229                        {
2230                                return False;
2231                        }
2232                }
2233
2234                /*!
2235                @function correct_attributes
2236                @abstract Set the correct attributes for 'string' (e.g. owner)
2237                @param string File/directory to correct attributes of
2238                @param relatives Relativity array
2239                @result Boolean True/False
2240                */
2241                function correct_attributes ($data)
2242                {
2243                        if (!is_array ($data))
2244                        {
2245                                $data = array ();
2246                        }
2247
2248                        $default_values = array
2249                                (
2250                                        'relatives'     => array (RELATIVE_CURRENT)
2251                                );
2252
2253                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2254
2255                        $p = $this->path_parts (array(
2256                                        'string'        => $data['string'],
2257                                        'relatives'     => array ($data['relatives'][0])
2258                                )
2259                        );
2260
2261                        if ($p->fake_leading_dirs != $this->fakebase && $p->fake_leading_dirs != '/')
2262                        {
2263                                $ls_array = $this->ls (array(
2264                                                'string'        => $p->fake_leading_dirs,
2265                                                'relatives'     => array ($p->mask),
2266                                                'checksubdirs'  => False,
2267                                                'nofiles'       => True
2268                                        )
2269                                );
2270                                $set_attributes_array = Array(
2271                                        'owner_id' => $ls_array[0]['owner_id']
2272                                );
2273                        }
2274                        elseif (preg_match ("+^$this->fakebase\/(.*)$+U", $p->fake_full_path, $matches))
2275                        {
2276                                $set_attributes_array = Array(
2277                                        'owner_id' => $GLOBALS['phpgw']->accounts->name2id ($matches[1])
2278                                );
2279                        }
2280                        else
2281                        {
2282                                $set_attributes_array = Array(
2283                                        'owner_id' => 0
2284                                );
2285                        }
2286
2287                        $this->set_attributes (array(
2288                                        'string'        => $p->fake_full_name,
2289                                        'relatives'     => array ($p->mask),
2290                                        'attributes'    => $set_attributes_array
2291                                )
2292                        );
2293
2294                        return True;
2295                }
2296
2297                /*
2298                 * See vfs_shared
2299                 */
2300                function file_type ($data)
2301                {
2302                        if (!is_array ($data))
2303                        {
2304                                $data = array ();
2305                        }
2306
2307                        $default_values = array
2308                                (
2309                                        'relatives'     => array (RELATIVE_CURRENT)
2310                                );
2311
2312                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2313
2314                        $p = $this->path_parts (array(
2315                                        'string'        => $data['string'],
2316                                        'relatives'     => array ($data['relatives'][0])
2317                                )
2318                        );
2319
2320                        if (!$this->acl_check (array(
2321                                        'string'        => $p->fake_full_path,
2322                                        'relatives'     => array ($p->mask),
2323                                        'operation'     => PHPGW_ACL_READ,
2324                                        'must_exist'    => True
2325                                ))
2326                        )
2327                        {
2328                                return False;
2329                        }
2330
2331                        if ($p->outside)
2332                        {
2333                                if (is_dir ($p->real_full_path))
2334                                {
2335                                        return ('Directory');
2336                                }
2337
2338                                /*
2339                                   We don't return an empty string here, because it may still match with a database query
2340                                   because of linked directories
2341                                */
2342                        }
2343
2344                        /*
2345                           We don't use ls () because it calls file_type () to determine if it has been
2346                           passed a directory
2347                        */
2348                        $db2 = $GLOBALS['phpgw']->db;
2349                        $db2->query ("SELECT mime_type FROM phpgw_vfs WHERE directory='".
2350                                $db2->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2351                                $db2->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2352                        $db2->next_record ();
2353                        $mime_type = $db2->Record['mime_type'];
2354                        if(!$mime_type)
2355                        {
2356                                $mime_type = $this->get_ext_mime_type (array ('string' => $data['string']));
2357                                {
2358                                        $db2->query ("UPDATE phpgw_vfs SET mime_type='$mime_type' WHERE directory='".
2359                                                $db2->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2360                                                $db2->db_addslashes($p->fake_name_clean)."'" .
2361                                                $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2362                                }
2363                        }
2364
2365                        return $mime_type;
2366                }
2367
2368                /*
2369                 * See vfs_shared
2370                 */
2371                function file_exists ($data)
2372                {
2373                        if (!is_array ($data))
2374                        {
2375                                $data = array ();
2376                        }
2377
2378                        $default_values = array
2379                                (
2380                                        'relatives'     => array (RELATIVE_CURRENT)
2381                                );
2382
2383                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2384
2385                        $p = $this->path_parts (array(
2386                                        'string'        => $data['string'],
2387                                        'relatives'     => array ($data['relatives'][0])
2388                                )
2389                        );
2390
2391                        if ($p->outside)
2392                        {
2393                                $rr = file_exists ($p->real_full_path);
2394
2395                                return $rr;
2396                        }
2397
2398                        $db2 = $GLOBALS['phpgw']->db;
2399                        $db2->query ("SELECT name FROM phpgw_vfs WHERE directory='".
2400                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2401                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2402
2403                        if ($db2->next_record ())
2404                        {
2405                                return True;
2406                        }
2407                        else
2408                        {
2409                                return False;
2410                        }
2411                }
2412
2413                /*
2414                 * See vfs_shared
2415                 */
2416                function get_size ($data)
2417                {
2418                        if (!is_array ($data))
2419                        {
2420                                $data = array ();
2421                        }
2422
2423                        $default_values = array
2424                                (
2425                                        'relatives'     => array (RELATIVE_CURRENT),
2426                                        'checksubdirs'  => True
2427                                );
2428
2429                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2430
2431                        $p = $this->path_parts (array(
2432                                        'string'        => $data['string'],
2433                                        'relatives'     => array ($data['relatives'][0])
2434                                )
2435                        );
2436
2437                        if (!$this->acl_check (array(
2438                                        'string'        => $p->fake_full_path,
2439                                        'relatives'     => array ($p->mask),
2440                                        'operation'     => PHPGW_ACL_READ,
2441                                        'must_exist'    => True
2442                                ))
2443                        )
2444                        {
2445                                return False;
2446                        }
2447
2448                        /*
2449                           WIP - this should run through all of the subfiles/directories in the directory and tally up
2450                           their sizes.  Should modify ls () to be able to return a list for files outside the virtual root
2451                        */
2452                        if ($p->outside)
2453                        {
2454                                $size = filesize ($p->real_full_path);
2455
2456                                return $size;
2457                        }
2458
2459                        foreach($this->ls (array(
2460                                        'string'        => $p->fake_full_path,
2461                                        'relatives'     => array ($p->mask),
2462                                        'checksubdirs'  => $data['checksubdirs'],
2463                                        'nofiles'       => !$data['checksubdirs']
2464                                )) as $file_array)
2465                        {
2466                                /*
2467                                   Make sure the file is in the directory we want, and not
2468                                   some deeper nested directory with a similar name
2469                                */
2470/*
2471                                if (@!ereg ('^' . $file_array['directory'], $p->fake_full_path))
2472                                {
2473                                        continue;
2474                                }
2475*/
2476
2477                                $size += $file_array['size'];
2478                        }
2479
2480                        if ($data['checksubdirs'])
2481                        {
2482                                $query = $GLOBALS['phpgw']->db->query ("SELECT size FROM phpgw_vfs WHERE directory='".
2483                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2484                                        $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" .
2485                                        $this->extra_sql (array ('query_text' => VFS_SQL_SELECT)));
2486                                $GLOBALS['phpgw']->db->next_record ();
2487                                $size += $GLOBALS['phpgw']->db->Record[0];
2488                        }
2489
2490                        return $size;
2491                }
2492                /*
2493                 * get the quota defined for the path in sql table
2494                 */
2495                function get_quota($data){
2496                        if (!is_array ($data))
2497                        {
2498                                $data = array ();
2499                        }
2500
2501                        $default_values = array
2502                                (
2503                                        'relatives'     => array (RELATIVE_CURRENT)
2504                                );
2505
2506                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2507
2508                        $p = $this->path_parts (array(
2509                                        'string'        => $data['string'],
2510                                        'relatives'     => RELATIVE_NONE
2511                                )
2512                        );
2513
2514                        if (!$this->acl_check (array(
2515                                'string'        => $p->fake_full_path,
2516                                'relatives'     => $p->mask,
2517                                'operation'     => PHPGW_ACL_READ
2518                        ))
2519                        )
2520                        {
2521                                return False;
2522                        }
2523                        $query = $GLOBALS['phpgw']->db->query ("SELECT quota_size FROM phpgw_vfs_quota WHERE directory = '".$data['string']."' LIMIT 1;", __LINE__,__FILE__);
2524
2525                        $GLOBALS['phpgw']->db->next_record ();
2526                        $record = $GLOBALS['phpgw']->db->Record;
2527                        return $record['quota_size'];
2528                }
2529                function set_quota($data){
2530                        if (!is_array ($data))
2531                        {
2532                                $data = array ();
2533                        }
2534
2535                        $default_values = array
2536                                (
2537                                        'relatives'     => array (RELATIVE_CURRENT)
2538                                );
2539
2540                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2541
2542                        $p = $this->path_parts (array(
2543                                        'string'        => $data['string'],
2544                                        'relatives'     => array ($data['relatives'][0])
2545                                )
2546                        );
2547
2548                        if (!$this->acl_check (array(
2549                                'string'        => $p->fake_full_path,
2550                                'relatives'     => array ($p->mask),
2551                                'operation'     => PHPGW_ACL_READ
2552                        ))
2553                        )
2554                        {
2555                                return False;
2556                        }
2557                        return $GLOBALS['phpgw']->db->query("INSERT INTO phpgw_vfs_quota VALUES ('".$data['string']."',".$data['new_quota'].");", __LINE__,__FILE__);
2558                }
2559
2560
2561                /*!
2562                @function checkperms
2563                @abstract Check if $this->working_id has write access to create files in $dir
2564                @discussion Simple call to acl_check
2565                @param string Directory to check access of
2566                @param relatives Relativity array
2567                @result Boolean True/False
2568                */
2569                function checkperms ($data)
2570                {
2571                        if (!is_array ($data))
2572                        {
2573                                $data = array ();
2574                        }
2575
2576                        $default_values = array
2577                                (
2578                                        'relatives'     => array (RELATIVE_CURRENT)
2579                                );
2580
2581                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2582
2583                        $p = $this->path_parts (array(
2584                                        'string'        => $data['string'],
2585                                        'relatives'     => array ($data['relatives'][0])
2586                                )
2587                        );
2588
2589                        if (!$this->acl_check (array(
2590                                        'string'        => $p->fake_full_path,
2591                                        'relatives'     => array ($p->mask),
2592                                        'operation'     => PHPGW_ACL_ADD
2593                                ))
2594                        )
2595                        {
2596                                return False;
2597                        }
2598                        else
2599                        {
2600                                return True;
2601                        }
2602                }
2603
2604                /*
2605                 * See vfs_shared
2606                 * If $data['readlink'] then a readlink is tryed on the real file
2607                 * If $data['file_id'] then the file_id is used instead of a path
2608                 */
2609                function ls ($data)
2610                {
2611                        if (!is_array ($data))
2612                        {
2613                                $data = array ();
2614                        }
2615
2616                        $default_values = array
2617                                (
2618                                        'relatives'     => array (RELATIVE_CURRENT),
2619                                        'checksubdirs'  => True,
2620                                        'mime_type'     => False,
2621                                        'nofiles'       => False,
2622                                        'summary'       => False,
2623                                        'orderby'       => 'directory'
2624                                );
2625
2626                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2627
2628                        $p = $this->path_parts (array(
2629                                        'string'        => $data['string'],
2630                                        'relatives'     => array ($data['relatives'][0])
2631                                )
2632                        );
2633                        $dir = $p->fake_full_path;
2634                        if($data['summary'])
2635                                $this->attributes['summary'] = 'summary';
2636
2637                        /* If they pass us a file or 'nofiles' is set, return the info for $dir only */
2638                        if (@$data['file_id']
2639                                || ((($type = $this->file_type (array(
2640                                        'string'        => $dir,
2641                                        'relatives'     => array ($p->mask)
2642                                )) != 'Directory'))
2643                                || ($data['nofiles'])) && !$p->outside
2644                        )
2645                        {
2646                                /* SELECT all, the, attributes */
2647                                $sql = 'SELECT ';
2648
2649                                foreach ($this->attributes as $num => $attribute)
2650                                {
2651                                        if ($num)
2652                                        {
2653                                                $sql .= ', ';
2654                                        }
2655
2656                                        $sql .= $attribute;
2657                                }
2658
2659                                $sql .= " FROM phpgw_vfs WHERE ";
2660                                if (@$data['file_id'])
2661                                {
2662                                        $sql .= 'file_id='.(int)$data['file_id'];
2663                                }
2664                                else
2665                                {
2666                                        $sql .= " directory='".$GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND".
2667                                                " name='".$GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'".
2668                                                $this->extra_sql (array ('query_type' => VFS_SQL_SELECT));
2669                                }
2670                                $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__);
2671
2672                                $GLOBALS['phpgw']->db->next_record ();
2673                                $record = $GLOBALS['phpgw']->db->Record;
2674
2675                                /* We return an array of one array to maintain the standard */
2676                                $rarray = array ();
2677                                foreach($this->attributes as $attribute)
2678                                {
2679                                        if ($attribute == 'mime_type' && !$record[$attribute])
2680                                        {
2681                                                $db2 = $GLOBALS['phpgw']->db;
2682                                                $record[$attribute] = $this->get_ext_mime_type (array(
2683                                                                'string' => $p->fake_name_clean
2684                                                        )
2685                                                );
2686
2687                                                if($record[$attribute])
2688                                                {
2689                                                        $db2->query ("UPDATE phpgw_vfs SET mime_type='".$record[$attribute]."' WHERE directory='".
2690                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2691                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2692                                                }
2693                                        }
2694
2695                                        $rarray[0][$attribute] = $record[$attribute];
2696                                }
2697                                if ($this->file_actions && @$data['readlink'])  // test if file is a symlink and get it's target
2698                                {
2699                                        $rarray[0]['symlink'] = @readlink($p->real_full_path);
2700                                }
2701                                if($data['summary'])
2702                                        unset($this->attributes['summary']);
2703
2704                                return $rarray;
2705                        }
2706
2707                        //WIP - this should recurse using the same options the virtual part of ls () does
2708                        /* If $dir is outside the virutal root, we have to check the file system manually */
2709                        if ($p->outside)
2710                        {
2711                                if ($this->file_type (array(
2712                                                'string'        => $p->fake_full_path,
2713                                                'relatives'     => array ($p->mask)
2714                                        )) == 'Directory'
2715                                        && !$data['nofiles']
2716                                )
2717                                {
2718                                        $dir_handle = opendir ($p->real_full_path);
2719                                        while ($filename = readdir ($dir_handle))
2720                                        {
2721                                                if ($filename == '.' || $filename == '..')
2722                                                {
2723                                                        continue;
2724                                                }
2725
2726                                                $rarray[] = $this->get_real_info (array(
2727                                                                'string'        => $p->real_full_path . SEP . $filename,
2728                                                                'relatives'     => array ($p->mask)
2729                                                        )
2730                                                );
2731                                        }
2732                                }
2733                                else
2734                                {
2735                                        $rarray[] = $this->get_real_info (array(
2736                                                        'string'        => $p->real_full_path,
2737                                                        'relatives'     => array ($p->mask)
2738                                                )
2739                                        );
2740                                }
2741
2742                                return $rarray;
2743                        }
2744
2745                        /* $dir's not a file, is inside the virtual root, and they want to check subdirs */
2746                        /* SELECT all, the, attributes FROM phpgw_vfs WHERE file=$dir */
2747                        $sql = 'SELECT ';
2748                        if (!$this->acl_check (array (
2749                                'string' => $p->fake_full_path,
2750                                'relatives' => array ($p->mask),
2751                                'operation' => PHPGW_ACL_PRIVATE)
2752                        ))
2753                        $query_type = " type != 1 AND";
2754                        else
2755                                $query_type = "";
2756
2757                        foreach($this->attributes as $num => $attribute)
2758                        {
2759                                if ($num)
2760                                {
2761                                        $sql .= ", ";
2762                                }
2763
2764                                $sql .= $attribute;
2765                        }
2766
2767                        $dir_clean = $this->clean_string (array ('string' => $dir));
2768                        $sql .= " FROM phpgw_vfs WHERE ".$query_type." directory = '".$GLOBALS['phpgw']->db->db_addslashes($dir_clean)."'";
2769                        $sql .= $this->extra_sql (array ('query_type' => VFS_SQL_SELECT));
2770
2771                        if ($data['mime_type'])
2772                        {
2773                                $sql .= " AND mime_type='".$data['mime_type']."'";
2774                        }
2775                        if (strlen($data['orderby']) > 0)
2776                                $sql .= ' ORDER BY '.$data['orderby'];
2777                        $query = $GLOBALS['phpgw']->db->query ($sql, __LINE__, __FILE__);
2778
2779                        $rarray = array ();
2780                        for ($i = 0; $GLOBALS['phpgw']->db->next_record (); $i++)
2781                        {
2782                                $record = $GLOBALS['phpgw']->db->Record;
2783                                foreach($this->attributes as $attribute)
2784                                {
2785                                        if ($attribute == 'mime_type' && !$record[$attribute])
2786                                        {
2787                                                $db2 = $GLOBALS['phpgw']->db;
2788                                                $record[$attribute] = $this->get_ext_mime_type (array(
2789                                                                'string'        => $p->fake_name_clean
2790                                                        )
2791                                                );
2792
2793                                                if($record[$attribute])
2794                                                {
2795                                                        $db2->query ("UPDATE phpgw_vfs SET mime_type='".$record[$attribute]."' WHERE directory='".
2796                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2797                                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" . $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2798                                                }
2799                                        }
2800
2801                                        $rarray[$i][$attribute] = $record[$attribute];
2802                                }
2803                        }
2804
2805                        return $rarray;
2806                }
2807
2808                /*
2809                 * See vfs_shared
2810                 */
2811                function update_real ($data,$recursive = False)
2812                {
2813                        if (!is_array ($data))
2814                        {
2815                                $data = array ();
2816                        }
2817
2818                        $default_values = array
2819                                (
2820                                        'relatives'     => array (RELATIVE_CURRENT)
2821                                );
2822
2823                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2824
2825                        $p = $this->path_parts (array(
2826                                        'string'        => $data['string'],
2827                                        'relatives'     => array ($data['relatives'][0])
2828                                )
2829                        );
2830
2831                        if (file_exists ($p->real_full_path))
2832                        {
2833                                if (is_dir ($p->real_full_path))
2834                                {
2835                                        $dir_handle = opendir ($p->real_full_path);
2836                                        while ($filename = readdir ($dir_handle))
2837                                        {
2838                                                if ($filename == '.' || $filename == '..')
2839                                                {
2840                                                        continue;
2841                                                }
2842
2843                                                $rarray[] = $this->get_real_info (array(
2844                                                                'string'        => $p->fake_full_path . '/' . $filename,
2845                                                                'relatives'     => array (RELATIVE_NONE)
2846                                                        )
2847                                                );
2848                                        }
2849                                }
2850                                else
2851                                {
2852                                        $rarray[] = $this->get_real_info (array(
2853                                                        'string'        => $p->fake_full_path,
2854                                                        'relatives'     => array (RELATIVE_NONE)
2855                                                )
2856                                        );
2857                                }
2858
2859                                if (!is_array ($rarray))
2860                                {
2861                                        $rarray = array ();
2862                                }
2863
2864                                foreach($rarray as $num => $file_array)
2865                                {
2866                                        $p2 = $this->path_parts (array(
2867                                                        'string'        => $file_array['directory'] . '/' . $file_array['name'],
2868                                                        'relatives'     => array (RELATIVE_NONE)
2869                                                )
2870                                        );
2871
2872                                        /* Note the mime_type.  This can be "Directory", which is how we create directories */
2873                                        $set_attributes_array = Array(
2874                                                'size' => $file_array['size'],
2875                                                'mime_type' => $file_array['mime_type']
2876                                        );
2877
2878                                        if (!$this->file_exists (array(
2879                                                        'string'        => $p2->fake_full_path,
2880                                                        'relatives'     => array (RELATIVE_NONE)
2881                                                ))
2882                                        )
2883                                        {
2884                                                $this->touch (array(
2885                                                                'string'        => $p2->fake_full_path,
2886                                                                'relatives'     => array (RELATIVE_NONE)
2887                                                        )
2888                                                );
2889                                        }
2890                                        $this->set_attributes (array(
2891                                                        'string'        => $p2->fake_full_path,
2892                                                        'relatives'     => array (RELATIVE_NONE),
2893                                                        'attributes'    => $set_attributes_array
2894                                                )
2895                                        );
2896                                        if ($recursive && $file_array['mime_type'] == 'Directory')
2897                                        {
2898                                                $dir_data = $data;
2899                                                $dir_data['string'] = $file_array['directory'] . '/' . $file_array['name'];
2900                                                $this->update_real($dir_data,$recursive);
2901                                        }
2902                                }
2903                        }
2904                }
2905
2906                /* Helper functions */
2907
2908                /* This fetchs all available file system information for string (not using the database) */
2909                function get_real_info ($data)
2910                {
2911                        if (!is_array ($data))
2912                        {
2913                                $data = array ();
2914                        }
2915
2916                        $default_values = array
2917                                (
2918                                        'relatives'     => array (RELATIVE_CURRENT)
2919                                );
2920
2921                        $data = array_merge ($this->default_values ($data, $default_values), $data);
2922
2923                        $p = $this->path_parts (array(
2924                                        'string'        => $data['string'],
2925                                        'relatives'     => array ($data['relatives'][0])
2926                                )
2927                        );
2928
2929                        if (is_dir ($p->real_full_path))
2930                        {
2931                                $mime_type = 'Directory';
2932                        }
2933                        else
2934                        {
2935                                $mime_type = $this->get_ext_mime_type (array(
2936                                                'string'        => $p->fake_name
2937                                        )
2938                                );
2939
2940                                if($mime_type)
2941                                {
2942                                        $GLOBALS['phpgw']->db->query ("UPDATE phpgw_vfs SET mime_type='".$mime_type."' WHERE directory='".
2943                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_leading_dirs_clean)."' AND name='".
2944                                                $GLOBALS['phpgw']->db->db_addslashes($p->fake_name_clean)."'" .
2945                                                $this->extra_sql (array ('query_type' => VFS_SQL_SELECT)), __LINE__, __FILE__);
2946                                }
2947                        }
2948
2949                        $size = filesize ($p->real_full_path);
2950                        $rarray = array(
2951                                'directory' => $p->fake_leading_dirs,
2952                                'name' => $p->fake_name,
2953                                'size' => $size,
2954                                'mime_type' => $mime_type
2955                        );
2956
2957                        return ($rarray);
2958                }
2959        }
2960?>
Note: See TracBrowser for help on using the repository browser.