File: platform/classes/Q/File.php
<?php
/**
* @module Q
*/
/**
* Q File class
* @class Q_File
*/
class Q_File
{
/**
* Saves a file, usually sent by the client
* @method save
* @static
* @param {array} $params
* @param {string} [$params.data] the file data
* @param {string} [$params.path="Q/uploads"] parent path under web dir (see subpath)
* @param {string} [$params.subpath=""] subpath that should follow the path, to save the image under
* @param {string} [$params.name] override the name of the file, after the subpath
* @param {string} [$params.skipAccess=false] if true, skips the check for authorization to write files there
* @param {boolean} [$params.audio] set this to true if the file is an audio file
* @return {array} Returns array containing ($name => $tailUrl) pair
*/
static function save($params)
{
if (empty($params['data'])) {
throw new Q_Exception(array('field' => 'file'), 'data');
}
// check whether we can write to this path, and create dirs if needed
$data = $params['data'];
$path = isset($params['path'])
? Q_Uri::interpolateUrl($params['path'])
: 'Q/uploads';
$subpath = isset($params['subpath']) ? $params['subpath'] : '';
$realPath = Q::realPath(APP_WEB_DIR.DS.$path);
if ($realPath === false) {
throw new Q_Exception_MissingFile(array(
'filename' => APP_WEB_DIR.DS.$path
));
}
$name = isset($params['name']) ? $params['name'] : 'file';
if (!preg_match('/^[\w.-]+$/', $name)) {
$info = pathinfo($name);
$name = Q_Utils::normalize($info['filename']) . '.' . $info['extension'];
}
// TODO: recognize some extensions maybe
$writePath = $realPath.($subpath ? DS.$subpath : '');
$lastChar = substr($writePath, -1);
if ($lastChar !== DS and $lastChar !== '/') {
$writePath .= DS;
}
$skipAccess = !empty($params['skipAccess']);
Q_Utils::canWriteToPath($writePath, $skipAccess ? null : true, true);
file_put_contents($writePath.$name, $data);
$size = filesize($writePath.$name);
$tailUrl = $subpath ? "$path/$subpath/$name" : "$path/$name";
// need to send to Q/file/save after event
$audio = !empty($params['audio']);
/**
* @event Q/file/save {after}
* @param {string} user the user
* @param {string} path the path in the url
* @param {string} subpath the subpath in the url
* @param {string} name the actual name of the file
* @param {string} writePath the actual folder where the path is written
* @param {string} data the data written to the file
* @param {string} tailUrl consists of $path/[$subpath/]$name
* @param {integer} size the size of the file that was written
* @param {boolean} skipAccess whether we are skipping access checks
* @param {boolean} audio whether the file is audio
*/
Q::event(
'Q/file/save',
compact('path', 'subpath', 'name', 'writePath', 'data', 'tailUrl', 'size', 'skipAccess', 'audio'),
'after'
);
return array($name => $tailUrl);
}
}