Files
In a CodKep based site you can store files managed and unmanaged way.
All kind of uploaded files should located under /date
directory.
While unmanaged files does not have any additional info stored in the database,
the managed files have a database record generated by CodKep file module. The file module registers every managed
file, gives an unique identifier of each file, stores the mime type, the original upload filename,
the upload time and user and other useful data.
This document is describe the using of managed files in CodKep:
All managed files has an UFI (The Unique File Identifier) number which obviously identifies the file.
Database sample with two files:
mysql> select * from file;
+-----+--------+-------------+-----+--------------+------------+----------+---------------------+
| ufi | type | name | sub | fsname | mime | uploader | uploaded |
+-----+--------+-------------+-----+--------------+------------+----------+---------------------+
| 1 | public | monkey.jpg | | monkey_1.jpg | image/jpeg | admin | 2017-02-05 13:49:24 |
| 2 | secure | meerkat.jpg | | meerkat.jpg | image/jpeg | admin | 2017-02-05 13:49:24 |
+-----+--------+-------------+-----+--------------+------------+----------+---------------------+
2 rows in set (0.00 sec)
Storing type
The managed files can stored in two available type:
public
- The file is uploaded/stored under
/data
directory and available through the web server with a simple url. - In case you ask an url of a public file, you will get a simple url which points to the desired file. The will served directly by the web server. (It means that anyone can read this file who knows the url)
- The file is uploaded/stored under
secure
- The file is uploaded/stored under
/data/secure
directory which is not available by the web server. (Should configured this way) - In case you ask an url of a secure file, you will get an url which points to a special file module callback which check the permissions and serve the file content if allowed. (It means that only one can read this file who has the appropriate permissions) Read the file access section for details.
- The file is uploaded/stored under
File class
The File class of the CodKep can used to create File objects which represents a managed file in CodKep.
The File class can represents both public
and secure
typed files.
function create_img_tag_from_ufi($image_ufi)
{
$img = file_load($image_ufi,true);
/* Equivalent to call:
* $img = new File('');
* $img->load($image_ufi,true);
*/
if($img == NULL)
return '<img src="'.url('/site/no_image.jpg').'" />';
return '<img src="'.$img->url.'" />';
}
Fixed properties of the File object
Every File object has same built-in properties which are available in any kind of file.
Built-in properties of file object:
(The $file
is only a sample object variable here))
- url - (Use:
$file->url
)- The url of the file to put a link to the html code.
- path - (Use:
$file->path
)- The path in the filesystem, to reach the file from code.
- ufi - (Use:
$file->ufi
)- The ufi of the file.
- type - (Use:
$file->type
)- The store type of the file. (
public
orsecure
)
- The store type of the file. (
- subdir - (Use:
$file->subdir
)- The storing subdirectory of the file in the local filesystem.
- mime - (Use:
$file->mime
)- The mime type of the file.
- uploaded - (Use:
$file->uploaded
)- The upload time of the file.
- uploader - (Use:
$file->uploader
)- The uploader user of the file.
Methods of File object
- File($type) - The constructor (
__construct
) of File- The
$type
parameter specifies the store type of the file. (public
orsecure
)
- The
- urlResized($sizeclass)
- The url of the file to put a link to the html code. In case this file is an image file with an available size class according to the
register_image_sizeclass
function andHOOK_file_image_sizeclass
hook this url will automatically referenced a scaled version of the image. See the size class chapter for details. - The function checks for the required permissions. (HOOK_file_access)
- The url of the file to put a link to the html code. In case this file is an image file with an available size class according to the
- addFromTemp($name, $from, $subdir = '', array $context = [])
- This function can create a new (managed) File object from an uploaded or a temporary file.
- The parameter
$name
tells the original filename. This can differs from the filesystem filename. A secure typed file will be available through file url with this name. This parameter is the php$_FILES[ITEM_NAME]["name"]
in case of simple form based upload. - The parameter
$from
is the temporary file name and path of the uploaded/temporary file. This parameter is the php$_FILES[ITEM_NAME]["tmp_name"]
in case of simple form based upload. - The parameter
$subdir
is the desired subdirectory in the filesystem where the file will stored. - The
$context
parameter is an array can used for define the file upload/add context.- If the
$context
array has'noupload' => true
value, theaddFromTemp
method will use a simple file moving instead ofmove_uploaded_file()
. (You have to specify if the file is not received by standard php upload)
- If the
- The parameter
- The function checks for the required permissions. (HOOK_file_access)
- This function can create a new (managed) File object from an uploaded or a temporary file.
- load($ufi,$disable_show_error = false)
- Loads the file object according to the
$ufi
parameter.- If the
$disable_show_error
parameter istrue
the load() method won't do an automatic redirection to the error page when the ufi is not loadable.
- If the
- Loads the file object according to the
- load_from_array($file_data_array)
- Loads the file object from a previously read array which contains all columns from the file table. (See sql scheme editor) This function exists for that purpose to avoiding an unnecessary database read if the required data already loaded somewhere.
- remove()
- Removes the file object from the system, which means the removing both of the database record and the referenced file from the filesystem.
- The function checks for the required permissions. (HOOK_file_access)
- getContent()
- Returns the content of the referenced file.
- The function checks for the required permissions. (HOOK_file_access)
Helper functions of File class
file_load($ufi,$disable_show_error = false)
Loads a file object by UFI.
This function is create an empty File object and call load($ufi,$disable_show_error)
method on it.
file_load_from_array($file_data_array)
Loads the file object from a previously read array which contains all columns from the file table.
This function is create an empty File object and call load_from_array($file_data_array)
method on it.
file_remove($ufi,$disable_show_error = false)
Loads a file object by UFI and delete both the database record and the referenced file.
This function is create an empty File object and call load($ufi,$disable_show_error)
method
then call the remove()
on it.
file_create_upload($name,$opts = [])
Manages after the form submitted part of a file upload procedure.
The $name
parameter is the form item name of the input type="file"
tag.
- The function returns
NULL
if the upload is failed or a file UFI if success. - The
$opts
array can contains some options:"container" => secure or public
- Determines if the file is public or secure
"filetypes" => MIMETYPES_SEPARATED_BY_COMMA
- Restrict the upload for the specified mime types
"subdir" => SUBDIRECTORY
- Specifies the upload subdirectory
A simple file upload page callback:
function upload_page()
{
par_def('upl','text2ns');
if(par_is('upl','Upload'))
{
form_source_check(); //Recommended to do this
$n_ufi = file_create_upload('myfile',
['container' => 'secure','filetypes' => 'image/jpeg;image/png']);
if($n_ufi == NULL)
return 'The file upload is failed.';
$f = file_load($n_ufi);
return "The file is uploaded (With ufi:$n_ufi): <img src=\"".$f->url."\"/>";
}
$f = new HtmlForm('fupl');
$f->action_post(current_loc());
$f->upload('myfile','');
$f->input('submit','upl','Upload');
ob_start();
print "Please browse the file to upload";
print $f->get();
return ob_get_clean();
}
register_image_sizeclass($name, $w, $h)
See the size class chapter for details.
File access control
You can control the access of the files by implementing the HOOK_file_access
hook.
The hook receives the following three parameters:
$file
The examined file object. The system queries the permissions for this file.$op
The system queries the permission for this operation. Possible values are:"create"
"delete"
"view"
$account
Determine the permission of this account (user node)
The hook have to return one value of these defines:
FILE_ACCESS_IGNORE
- Ignore the answerFILE_ACCESS_ALLOW
- Allow the operation specified by parametersFILE_ACCESS_DENY
- Deny the operation specified by parameters
In case there is no HOOK_file_access
in the system or received FILE_ACCESS_IGNORE value the system
will deny every request except the following default allowed:
- Allows everything for admin users.
- Allows new file creation for authenticated users.
- Allows to view public files. (Pointless to disable it.)
- Allows delete/view to the file owner/uploader.
Note: The FILE_ACCESS_DENY is always stronger than FILE_ACCESS_ALLOW, if both received the result will FILE_ACCESS_DENY
Samples:
// Allow add/edit/delete for editors but allows view for everyone
function hook_mymodule_file_access($file,$op,$account)
{
if($op == 'view')
return FILE_ACCESS_ALLOW;
if($acc->auth && $acc->role >= ROLE_EDITOR)
return FILE_ACCESS_ALLOW;
return FILE_ACCESS_IGNORE;
}
The file_access function
file_access(File $file,$op,$account)
Calculate the permission of the operation on the secure file of the parameter passed account.
(It's call the HOOK_file_access
in background.)
$file
Determine the permission on this file$op
Determine the permission for this operation. Possible values are:"create"
"delete"
"update"
"view"
$account
Determine the permission of this account (user node)
The return value of this function can be:
FILE_ACCESS_IGNORE
FILE_ACCESS_ALLOW
FILE_ACCESS_DENY
Tricks with file hooks
This code changes both the display filename and the storing filename of the uploaded jpeg
files with the HOOK_upload_filename_alter
hook:
function hook_mymodule_upload_filename_alter($p)
{
if($p->file_ref->type == 'secure' &&
$p->file_ref->type == 'image/jpeg')
{
$nn = rand(1000, 9999);
$p->file_ref->name = 'image' . $nn . '.jpg';
$p->pp_ref['filename'] = time() . '_' . $nn;
}
}
The following code re-sample all uploaded jpeg images to fit 350x350 size (while keep aspect ratio)
with the HOOK_file_uploaded
hook:
function hook_mymodule_file_uploaded($f)
{
if($f->file_ref->mime == 'image/jpeg')
image_resample($f->file_ref->path, $f->file_ref->path, 350, 350);
}
Image size classes
CodKep also can store images as file object. Often this images should be available in different size than the uploaded size. For example if you do an image gallery the pictures should have an index image variant which has smaller size than the original. The CodKep has a helper mechanism to easy handle this for png,jpeg and gif images. The system achieve this function as lazy which means that the scaled versions is generated when they needed to show not in upload phase. This behaviour enable to create/change size classes on the fly without affecting existing files.
register_image_sizeclass($name, $w, $h)
Registers an image size class in CodKep. By calling this function you will register one (more) image size class
with name specified by $name
parameter in size $w
and $h
which are the desired width and the height
of the class.
(The images always scaled as keeping aspect ratio, so the final sizes may differs from the values specified here. -
It means that the scaled image will fit in the specified size but may differs.)
After you define your size classes in the system, the you can tell the CodKep which file should have the size classes
to generate. The mechanism similar to file access.
You can use the HOOK_file_image_sizeclass($fileobject,$sizeclass)
hook to tell which file
has the specified size class available.
The HOOK_file_image_sizeclass
should one of this value:
FILE_ACCESS_IGNORE
FILE_ACCESS_ALLOW
FILE_ACCESS_DENY
In case a size class is defined (by register_image_sizeclass
) and the HOOK_file_image_sizeclass
hook will
return FILE_ACCESS_ALLOW
the codkep will generate a scaled version of the file:
- In "secure" type:
- The scaled images are stored in a size class named subdirectory under the directory of the original files.
- The scaled images are generated in time when they accessed. The image serving function will check if a scaled version is available. If not the system will generate a scaled image and serve that.
- In "public" type:
- The scaled images are stored in a size class named subdirectory under the directory of the original files.
- The scaled images are generated when a scaled link is generated by
urlResized($sizeclass)
function. (Because all public files is referenced directly without the CodKep, this is the only way to generated this files as lazy)
You can use the scaled version of the image files by the file class method urlResized($sizeclass)
.
Using example of size classes:
function hook_mymodule_before_start()
{
...
//We will register two size class here
register_image_sizeclass('40x40',40,40);
register_image_sizeclass('100x100',100,100);
}
function hook_mymodule_file_image_sizeclass($fileobject,$sizeclass)
{
//We will allow the scaling only for image files stored in 'customerportraits' directory
if($fileobject->subdir == 'customerportraits')
return FILE_ACCESS_ALLOW;
return FILE_ACCESS_DENY;
}
//We will use the scaled images in this page callback function
function show_user_list()
{
...
foreach($customers as $customer)
{
...
$cifile = file_load($customer->portrait);
print l('<img src="' . $cifile->urlResized("100x100") . '"/>',$cifile->url());
...
}
...
}
Note 1: If the urlResized($sizeclass)
method is called on a file which has size classes disabled
(One HOOK_file_image_sizeclass
returns FILE_ACCESS_DENY
on it) the original file url will returned.
It means that the CodKep won't do error handling if non available size class requested instead serve the original (unscaled) file.
Node 2: In case a file is removed by the remove()
method the system will check every available size class of the file
(according to the HOOK_file_image_sizeclass
hook) and remove all scaled version of the file if exists.
Note 3: The size classes are only works on files which are jpeg,png or gif files according to their mime type.
Other file types are ignored. (The urlResized()
returns same as url
property)
Settings of the file module
The file settings which can set in site settings.
name | default | description |
---|---|---|
$site_config->public_file_path | "data" | The location of public files in the filesystem on server. (The files can stored in subdirectories here.) |
$site_config->public_file_url | "/data" | The browser URL prefix of public files. (url location) |
$site_config->secure_file_path | "data/secure" | The location of secure files in the filesystem on server. (The files can stored in subdirectories here.) |
$site_config->secure_file_url | "/data/secure" | The browser URL prefix of secure files. This is a callback function by default. |
$site_config->file_ufi_lastInsertId_name | '' | You can specify your own sequence name which used to generate the keys of file table. The empty means autodetect. |
Hooks
The following hooks can be implement to interact with file module.
Note: Many of this hooks has an $obj
parameter which is a container object holding references
to the object and other data structures which are modifiable by the hook.
Hook | Description |
---|---|
HOOK_file_access($file,$op,$account) | Controls the access to a secured file. Read the file access section for details. The value of $op can be view,create,delete |
HOOK_file_denied($f,$user) | Runs before the user will redirect to access denied page. Possible to change the standard "not found" message. |
HOOK_file_uploaded($obj) | Runs when a file is uploaded, stored in sql. You can see an example here. |
HOOK_upload_filename_alter($obj) | Runs when a file is uploaded and the local fs name is determined. You can see an example here. |
HOOK_file_upload_in($obj) | Runs when a file is uploaded but not yet stored in sql. |
HOOK_file_loaded($obj) | Runs when a file is loaded. |
HOOK_file_will_delete($obj) | Runs before a file is removed. |
HOOK_file_image_sizeclass($fileobject,$sizeclass) | Controls the available size classes of the specified file. See size classes above. |