diff --git a/api/src/Storage.php b/api/src/Storage.php index b1df9cfdd2..28f4538f68 100644 --- a/api/src/Storage.php +++ b/api/src/Storage.php @@ -218,6 +218,10 @@ class Storage extends Storage\Base */ function save_customfields($data, array $extra_cols=array()) { + $id = isset($data[$this->autoinc_id]) ? $data[$this->autoinc_id] : $data[$this->db_key_cols[$this->autoinc_id]]; + + \EGroupware\Api\Storage\Customfields::handle_files($this->app, $id, $data, $this->customfields); + foreach (array_keys((array)$this->customfields) as $name) { if (!isset($data[$field = $this->get_cf_field($name)])) continue; diff --git a/api/src/Storage/Customfields.php b/api/src/Storage/Customfields.php index 1f83b27a17..4690833b0e 100755 --- a/api/src/Storage/Customfields.php +++ b/api/src/Storage/Customfields.php @@ -544,6 +544,59 @@ class Customfields implements \IteratorAggregate self::$db = $GLOBALS['egw_setup']->db; } } + + /** + * Handle any uploaded files that weren't dealt with immediately when uploaded. + * This usually happens for new entries, where we don't have the entry's ID + * to properly file it in the VFS. Files are stored temporarily until we + * have the ID, then here we move the files to their proper location. + * + * @staticvar array $_customfields List of custom field data, kept to avoid + * loading it multiple times if called again. + * + * @param string $app Current application + * @param string $entry_id Application ID of the new entry + * @param Array $values Array of entry data, including custom fields. + * File information from the VFS widget (via self::validate()) will be found & + * dealt with. Successful or not, the value is cleared to avoid trying to insert it into + * the database, which would generate errors. + * @param Array $customfields Pass the custom field list if you have it to avoid loading it again + */ + public static function handle_files($app, $entry_id, &$values, &$customfields = array()) + { + if(!is_array($values) || !$entry_id) return; + + if(!$customfields) + { + static $_customfields = array(); + if(!$_customfields[$app]) + { + $_customfields[$app] = Api\Storage\Customfields::get($app); + } + $customfields = $_customfields[$app]; + } + foreach ($customfields as $field_name => $field) + { + if($field['type'] == 'filemanager' && $value =& $values[Api\Storage::CF_PREFIX.$field_name]) + { + static::handle_file($entry_id, $field, $value); + unset($values[Api\Storage::CF_PREFIX.$field_name]); + } + } + } + + protected static function handle_file($entry_id, $field, $value) + { + $path = Api\Etemplate\Widget\Vfs::get_vfs_path($field['app'].":$entry_id:".$field['label']); + if($path) + { + foreach($value as $file) + { + $file['tmp_name'] = Api\Vfs::PREFIX.$file['path']; + Api\Etemplate\Widget\Vfs::store_file($path, $file); + } + } + } } Customfields::init_static(); diff --git a/calendar/inc/class.calendar_so.inc.php b/calendar/inc/class.calendar_so.inc.php index fc9343db45..1430c7f8c0 100644 --- a/calendar/inc/class.calendar_so.inc.php +++ b/calendar/inc/class.calendar_so.inc.php @@ -1628,6 +1628,8 @@ ORDER BY cal_user_type, cal_usre_id $this->participants($cal_id,$event['cal_participants'],!$cal_id ? false : $change_since); } // Custom fields + Api\Storage\Customfields::handle_files('calendar', $cal_id, $event); + foreach($event as $name => $value) { if ($name[0] == '#') diff --git a/infolog/inc/class.infolog_so.inc.php b/infolog/inc/class.infolog_so.inc.php index 6dc5f37336..a14ac57bd1 100644 --- a/infolog/inc/class.infolog_so.inc.php +++ b/infolog/inc/class.infolog_so.inc.php @@ -594,6 +594,10 @@ class infolog_so $this->db->delete($this->extra_table,$where,__LINE__,__FILE__); } $to_delete = array(); + + // Deal with files in new entries + Api\Storage\Customfields::handle_files('infolog',$info_id,$values); + foreach($values as $key => $val) { if ($key[0] != '#')