The structure of the filestore is tied to file ownership by Elgg entities. Whenever
the first file owned by an entity is written to the filestore, a directory corresponding
to the entity GUID will be created within a parent bucket directory (buckets are bound to 5000 guids).
E.g. files owned by user with guid 7777 will be located in 5000/7777/.

When files are created, filenames can contain subdirectory names (often referred to as
$prefix throughout the code). For instance, avatars of the above user, can be found
under 5000/7777/profile/.

To write a file to the filestore, you would use an instance of ElggFile. Even though
ElggFile extends ElggObject and can be stored as an actual Elgg entity, that is not
always necessary (e.g. when writing thumbs of an image).

$file=newElggFile();$file->owner_guid=7777;$file->setFilename('portfolio/files/sample.txt');$file->open('write');$file->write('Contents of the file');$file->close();// to uprade this file to an entity$file->subtype='file';$file->save();

You can serve files from filestore using elgg_get_inline_url() and elgg_get_download_url().
Both functions accept 3 arguments:

``file`` An instance of ElggFile to be served

``use_cookie`` If set to true, validity of the URL will be limited to current session

``expires`` Expiration time of the URL

You can use use_cookie and expires arguments as means of access control. For example,
users avatars in most cases have a long expiration time and do not need to be restricted by
current session - this will allows browsers to cache the images and file service will
send appropriate NotModified headers on consecutive requests.

For entities that are under Elgg’s access control, you may want to use cookies to ensure
that access settings are respected and users do not share download URLs with somebody else.

You can also invalidated all previously generated URLs by updating file’s modified time, e.g.
by using touch().

Please note that due to their nature inline and download URLs are not suitable for embedding.
Embed URLs must be permanent, whereas inline and download URLs are volatile (bound to user session
and file modification time).

In order to implement an action that saves a single file uploaded by a user, you can use the following approach:

// in your formechoelgg_view('input/file',['name'=>'upload','label'=>'Select an image to upload','help'=>'Only jpeg, gif and png images are supported',]);

// in your action$uploaded_files=elgg_get_uploaded_files('upload');if(!$uploaded_files){register_error("No file was uploaded");forward(REFERER);}$uploaded_file=array_shift($uploaded_files);if(!$uploaded_file->isValid()){$error=elgg_get_friendly_upload_error($uploaded_file->getError());register_error($error);forward(REFERER);}$supported_mimes=['image/jpeg','image/png','image/gif',];$mime_type=ElggFile::detectMimeType($uploaded_file->getPathname(),$uploaded_file->getClientMimeType());if(!in_array($mime_type,$supported_mimes)){register_error("$mime_type is not supported");forward(REFERER);}$file=newElggFile();$file->owner_guid=elgg_get_logged_in_user_guid();if($file->acceptUploadedFile($uploaded_file)){$file->save();}

If your file input supports multiple files, you can iterate through them in your action: