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

Revision 5141, 75.1 KB checked in by wmerlotto, 12 years ago (diff)

Ticket #2305 - Enviando alteracoes, desenvolvidas internamente na Prognus, modulo phpgwapi.

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