aboutsummaryrefslogtreecommitdiffstats
path: root/include/attach.php
diff options
context:
space:
mode:
Diffstat (limited to 'include/attach.php')
-rw-r--r--include/attach.php610
1 files changed, 525 insertions, 85 deletions
diff --git a/include/attach.php b/include/attach.php
index c16944601..a556ff775 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -150,10 +150,11 @@ function attach_count_files($channel_id, $observer, $hash = '', $filename = '',
if($filetype)
$sql_extra .= protect_sprintf(" and filetype like '@" . dbesc($filetype) . "@' ");
- $r = q("select id from attach where uid = %d $sql_extra",
+ $r = q("select id, uid, folder from attach where uid = %d $sql_extra",
intval($channel_id)
);
+
$ret['success'] = ((is_array($r)) ? true : false);
$ret['results'] = ((is_array($r)) ? count($r) : false);
@@ -202,7 +203,7 @@ function attach_list_files($channel_id, $observer, $hash = '', $filename = '', $
// Retrieve all columns except 'data'
- $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit",
+ $r = q("select id, aid, uid, hash, filename, filetype, filesize, revision, folder, os_storage, is_dir, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d $sql_extra ORDER BY $orderby $limit",
intval($channel_id)
);
@@ -262,12 +263,40 @@ function attach_by_hash($hash, $rev = 0) {
return $ret;
}
+ if($r[0]['folder']) {
+ $x = attach_can_view_folder($r[0]['uid'],get_observer_hash(),$r[0]['folder']);
+ if(! $x) {
+ $ret['message'] = t('Permission denied.');
+ return $ret;
+ }
+ }
+
$ret['success'] = true;
$ret['data'] = $r[0];
return $ret;
}
+function attach_can_view_folder($uid,$ob_hash,$folder_hash) {
+
+ $sql_extra = permissions_sql($uid,$ob_hash);
+ $hash = $folder_hash;
+ $result = false;
+
+ do {
+ $r = q("select folder from attach where hash = '%s' and uid = %d $sql_extra",
+ dbesc($hash),
+ intval($uid)
+ );
+ if(! $r)
+ return false;
+ $hash = $r[0]['folder'];
+ }
+ while($hash);
+ return true;
+}
+
+
/**
* @brief Find an attachment by hash and revision.
*
@@ -310,7 +339,7 @@ function attach_by_hash_nodata($hash, $rev = 0) {
// Now we'll see if we can access the attachment
- $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1",
+ $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_extra limit 1",
intval($r[0]['uid']),
dbesc($hash)
);
@@ -320,6 +349,15 @@ function attach_by_hash_nodata($hash, $rev = 0) {
return $ret;
}
+ if($r[0]['folder']) {
+ $x = attach_can_view_folder($r[0]['uid'],get_observer_hash(),$r[0]['folder']);
+ if(! $x) {
+ $ret['message'] = t('Permission denied.');
+ return $ret;
+ }
+ }
+
+
$ret['success'] = true;
$ret['data'] = $r[0];
@@ -340,17 +378,68 @@ function attach_by_hash_nodata($hash, $rev = 0) {
* @param string $options (optional) one of update, replace, revision
* @param array $arr (optional) associative array
*/
+
+/**
+ * A lot going on in this function, and some of it is old cruft and some is new cruft
+ * and the entire thing probably needs to be refactored. It started out just storing
+ * files, before we had DAV. It was made extensible to do extra stuff like edit an
+ * existing file or optionally store a separate revision using $options to choose between different
+ * storage models. Along the way we moved from
+ * DB data storage to file system storage.
+ * Then DAV came along and used different upload methods depending on whether the
+ * file was stored as a DAV directory object or updated as a file object. One of these
+ * is essentially an update and the other is basically an upload, but doesn't use the traditional PHP
+ * upload workflow.
+ * Then came hubzilla and we tried to merge photo functionality with the file storage. Most of
+ * that integration occurs within this function.
+ * This required overlap with the old photo_upload stuff and photo albums were
+ * completely different concepts from directories which needed to be reconciled somehow.
+ * The old revision stuff is kind of orphaned currently. There's new revision stuff for photos
+ * which attaches (2) etc. onto the name, but doesn't integrate with the attach table revisioning.
+ * That's where it sits currently. I repeat it needs to be refactored, and this note is here
+ * for future explorers and those who may be doing that work to understand where it came
+ * from and got to be the monstrosity of tangled unrelated code that it currently is.
+ */
+
function attach_store($channel, $observer_hash, $options = '', $arr = null) {
+ require_once('include/photos.php');
+
+
+ call_hooks('photo_upload_begin',$arr);
+
$ret = array('success' => false);
$channel_id = $channel['channel_id'];
$sql_options = '';
+ $source = (($arr) ? $arr['source'] : '');
+ $album = (($arr) ? $arr['album'] : '');
+ $newalbum = (($arr) ? $arr['newalbum'] : '');
+ $hash = (($arr && $arr['hash']) ? $arr['hash'] : null);
+ $upload_path = (($arr && $arr['directory']) ? $arr['directory'] : '');
- if(! perm_is_allowed($channel_id,get_observer_hash(), 'write_storage')) {
+ $observer = array();
+
+ if($observer_hash) {
+ $x = q("select * from xchan where xchan_hash = '%s' limit 1",
+ dbesc($observer_hash)
+ );
+ if($x)
+ $observer = $x[0];
+ }
+
+ logger('arr: ' . print_r($arr,true));
+
+ if(! perm_is_allowed($channel_id,$observer_hash, 'write_storage')) {
$ret['message'] = t('Permission denied.');
return $ret;
}
+ $str_group_allow = perms2str($arr['group_allow']);
+ $str_contact_allow = perms2str($arr['contact_allow']);
+ $str_group_deny = perms2str($arr['group_deny']);
+ $str_contact_deny = perms2str($arr['contact_deny']);
+
+
// The 'update' option sets db values without uploading a new attachment
// 'replace' replaces the existing uploaded data
// 'revision' creates a new revision with new upload data
@@ -358,23 +447,48 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
// revise or update must provide $arr['hash'] of the thing to revise/update
- if($options !== 'update') {
- if(! x($_FILES,'userfile')) {
- $ret['message'] = t('No source file.');
- return $ret;
- }
+ // By default remove $src when finished
+
+ $remove_when processed = true;
+
+ if($options === 'import') {
+ $src = $arr['src'];
+ $filename = $arr['filename'];
+ $filesize = @filesize($src);
+ $hash = $arr['resource_id'];
+ if($arr['preserve_original'])
+ $remove_when_processed = false;
+ }
+ elseif($options !== 'update') {
+ $f = array('src' => '', 'filename' => '', 'filesize' => 0, 'type' => '');
+
+ call_hooks('photo_upload_file',$f);
+ call_hooks('attach_upload_file',$f);
+
+ if (x($f,'src') && x($f,'filesize')) {
+ $src = $f['src'];
+ $filename = $f['filename'];
+ $filesize = $f['filesize'];
+ $type = $f['type'];
+
+ } else {
+
+ if(! x($_FILES,'userfile')) {
+ $ret['message'] = t('No source file.');
+ return $ret;
+ }
- $src = $_FILES['userfile']['tmp_name'];
- $filename = basename($_FILES['userfile']['name']);
- $filesize = intval($_FILES['userfile']['size']);
+ $src = $_FILES['userfile']['tmp_name'];
+ $filename = basename($_FILES['userfile']['name']);
+ $filesize = intval($_FILES['userfile']['size']);
+ }
}
$existing_size = 0;
if($options === 'replace') {
- /** @BUG $replace is undefined here */
$x = q("select id, hash, filesize from attach where id = %d and uid = %d limit 1",
- intval($replace),
+ intval($arr['id']),
intval($channel_id)
);
if(! $x) {
@@ -391,7 +505,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($options === 'update' && $arr && array_key_exists('revision',$arr))
$sql_options = " and revision = " . intval($arr['revision']) . " ";
- $x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1",
+ $x = q("select id, aid, uid, filename, filetype, filesize, hash, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where hash = '%s' and uid = %d $sql_options limit 1",
dbesc($arr['hash']),
intval($channel_id)
);
@@ -402,13 +516,129 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$hash = $x[0]['hash'];
}
+
+
+ $def_extension = '';
+ $is_photo = 0;
+ $gis = @getimagesize($src);
+ logger('getimagesize: ' . print_r($gis,true), LOGGER_DATA);
+ if(($gis) && ($gis[2] === IMAGETYPE_GIF || $gis[2] === IMAGETYPE_JPEG || $gis[2] === IMAGETYPE_PNG)) {
+ $is_photo = 1;
+ if($gis[2] === IMAGETYPE_GIF)
+ $def_extension = '.gif';
+ if($gis[2] === IMAGETYPE_JPEG)
+ $def_extension = '.jpg';
+ if($gis[2] === IMAGETYPE_PNG)
+ $def_extension = '.png';
+
+ }
+
+ $pathname = '';
+
+ if($is_photo) {
+ if($newalbum)
+ $pathname = filepath_macro($newalbum);
+ else
+ $pathname = filepath_macro($album);
+ }
+ else {
+ $pathname = filepath_macro($upload_path);
+ }
+
+ $darr = array('pathname' => $pathname);
+
+ // if we need to create a directory, use the channel default permissions.
+
+ $darr['allow_cid'] = $channel['allow_cid'];
+ $darr['allow_gid'] = $channel['allow_gid'];
+ $darr['deny_cid'] = $channel['deny_cid'];
+ $darr['deny_gid'] = $channel['deny_gid'];
+
+
+ $direct = null;
+
+ if($pathname) {
+ $x = attach_mkdirp($channel, $observer_hash, $darr);
+ $folder_hash = (($x['success']) ? $x['data']['hash'] : '');
+ $direct = (($x['success']) ? $x['data'] : null);
+ if((! $str_contact_allow) && (! $str_group_allow) && (! $str_contact_deny) && (! $str_group_deny)) {
+ $str_contact_allow = $x['data']['allow_cid'];
+ $str_group_allow = $x['data']['allow_gid'];
+ $str_contact_deny = $x['data']['deny_cid'];
+ $str_group_deny = $x['data']['deny_gid'];
+ }
+ }
+ else {
+ $folder_hash = '';
+ }
+
+ if((! $options) || ($options === 'import')) {
+
+ // A freshly uploaded file. Check for duplicate and resolve with the channel's overwrite settings.
+
+ $r = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
+ dbesc($filename),
+ dbesc($folder_hash)
+ );
+ if($r) {
+ $overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
+ if($overwrite) {
+ $options = 'replace';
+ $existing_id = $x[0]['id'];
+ $existing_size = intval($x[0]['filesize']);
+ $hash = $x[0]['hash'];
+ }
+ else {
+ if(strpos($filename,'.') !== false) {
+ $basename = substr($filename,0,strrpos($filename,'.'));
+ $ext = substr($filename,strrpos($filename,'.'));
+ }
+ else {
+ $basename = $filename;
+ $ext = $def_extension;
+ }
+
+ $r = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
+ dbesc($basename . $ext),
+ dbesc($basename . '(%)' . $ext),
+ dbesc($folder_hash)
+ );
+
+ if($r) {
+ $x = 1;
+
+ do {
+ $found = false;
+ foreach($r as $rr) {
+ if($rr['filename'] === $basename . '(' . $x . ')' . $ext) {
+ $found = true;
+ break;
+ }
+ }
+ if($found)
+ $x++;
+ }
+ while($found);
+ $filename = $basename . '(' . $x . ')' . $ext;
+ }
+ else
+ $filename = $basename . $ext;
+ }
+ }
+ }
+
+ if(! $hash)
+ $hash = random_string();
+
// Check storage limits
if($options !== 'update') {
$maxfilesize = get_config('system','maxfilesize');
if(($maxfilesize) && ($filesize > $maxfilesize)) {
$ret['message'] = sprintf( t('File exceeds size limit of %d'), $maxfilesize);
- @unlink($src);
+ if($remove_when_processed)
+ @unlink($src);
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
@@ -420,41 +650,70 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
if(($r) && (($r[0]['total'] + $filesize) > ($limit - $existing_size))) {
$ret['message'] = upgrade_message(true) . sprintf(t("You have reached your limit of %1$.0f Mbytes attachment storage."), $limit / 1024000);
- @unlink($src);
+ if($remove_when_processed)
+ @unlink($src);
+
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
}
- $mimetype = z_mime_content_type($filename);
+ $mimetype = ((isset($type) && $type) ? $type : z_mime_content_type($filename));
}
- if(! isset($hash))
- $hash = random_string();
+ $os_basepath = 'store/' . $channel['channel_address'] . '/' ;
+ $os_relpath = '';
- $created = datetime_convert();
+ if($folder_hash) {
+ $curr = find_folder_hash_by_attach_hash($channel_id,$folder_hash,true);
+ if($curr)
+ $os_relpath .= $curr . '/';
+ $os_relpath .= $folder_hash . '/';
+ }
+
+ $os_relpath .= $hash;
+
+ if($src)
+ @file_put_contents($os_basepath . $os_relpath,@file_get_contents($src));
+
+ if(array_key_exists('created', $arr))
+ $created = $arr['created'];
+ else
+ $created = datetime_convert();
+
+ if(array_key_exists('edited', $arr))
+ $edited = $arr['edited'];
+ else
+ $edited = $created;
if($options === 'replace') {
- $r = q("update attach set filename = '%s', filetype = '%s', filesize = %d, data = '%s', edited = '%s' where id = %d and uid = %d",
+ $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', filesize = %d, os_storage = %d, is_photo = %d, data = '%s', edited = '%s' where id = %d and uid = %d",
dbesc($filename),
dbesc($mimetype),
+ dbesc($folder_hash),
intval($filesize),
- dbescbin(@file_get_contents($src)),
+ intval(1),
+ intval($is_photo),
+ dbesc($os_relpath),
dbesc($created),
intval($existing_id),
intval($channel_id)
);
}
elseif($options === 'revise') {
- $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $r = q("insert into attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($x[0]['aid']),
intval($channel_id),
dbesc($x[0]['hash']),
- dbesc(get_observer_hash()),
+ dbesc($observer_hash),
dbesc($filename),
dbesc($mimetype),
+ dbesc($folder_hash),
intval($filesize),
intval($x[0]['revision'] + 1),
- dbescbin(@file_get_contents($src)),
+ intval(1),
+ intval($is_photo),
+ dbesc($os_relpath),
dbesc($created),
dbesc($created),
dbesc($x[0]['allow_cid']),
@@ -464,11 +723,14 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
}
elseif($options === 'update') {
- $r = q("update attach set filename = '%s', filetype = '%s', edited = '%s',
+ $r = q("update attach set filename = '%s', filetype = '%s', folder = '%s', edited = '%s', os_storage = %d, is_photo = %d,
allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where id = %d and uid = %d",
dbesc((array_key_exists('filename',$arr)) ? $arr['filename'] : $x[0]['filename']),
dbesc((array_key_exists('filetype',$arr)) ? $arr['filetype'] : $x[0]['filetype']),
+ dbesc(($folder_hash) ? $folder_hash : $x[0]['folder']),
dbesc($created),
+ dbesc((array_key_exists('os_storage',$arr)) ? $arr['os_storage'] : $x[0]['os_storage']),
+ dbesc((array_key_exists('is_photo',$arr)) ? $arr['is_photo'] : $x[0]['is_photo']),
dbesc((array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $x[0]['allow_cid']),
dbesc((array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $x[0]['allow_gid']),
dbesc((array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $x[0]['deny_cid']),
@@ -478,49 +740,90 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
}
else {
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, data, created, edited, allow_cid, allow_gid,deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel_id),
dbesc($hash),
dbesc(get_observer_hash()),
dbesc($filename),
dbesc($mimetype),
+ dbesc($folder_hash),
intval($filesize),
intval(0),
- dbescbin(@file_get_contents($src)),
+ intval(1),
+ intval($is_photo),
+ dbesc($os_relpath),
dbesc($created),
dbesc($created),
- dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : '<' . $channel['channel_hash'] . '>'),
- dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : ''),
- dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : ''),
- dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : '')
+ dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $str_contact_allow),
+ dbesc(($arr && array_key_exists('allow_gid',$arr)) ? $arr['allow_gid'] : $str_group_allow),
+ dbesc(($arr && array_key_exists('deny_cid',$arr)) ? $arr['deny_cid'] : $str_contact_deny),
+ dbesc(($arr && array_key_exists('deny_gid',$arr)) ? $arr['deny_gid'] : $str_group_deny)
);
}
- if($options !== 'update')
+ if($is_photo) {
+
+ $args = array( 'source' => $source, 'visible' => 0, 'resource_id' => $hash, 'album' => basename($pathname), 'os_path' => $os_basepath . $os_relpath, 'filename' => $filename, 'getimagesize' => $gis, 'directory' => $direct);
+ if($arr['contact_allow'])
+ $args['contact_allow'] = $arr['contact_allow'];
+ if($arr['group_allow'])
+ $args['group_allow'] = $arr['group_allow'];
+ if($arr['contact_deny'])
+ $args['contact_deny'] = $arr['contact_deny'];
+ if($arr['group_deny'])
+ $args['group_deny'] = $arr['group_deny'];
+ if(array_key_exists('allow_cid',$arr))
+ $args['allow_cid'] = $arr['allow_cid'];
+ if(array_key_exists('allow_gid',$arr))
+ $args['allow_gid'] = $arr['allow_gid'];
+ if(array_key_exists('deny_cid',$arr))
+ $args['deny_cid'] = $arr['deny_cid'];
+ if(array_key_exists('deny_gid',$arr))
+ $args['deny_gid'] = $arr['deny_gid'];
+
+ $args['created'] = $created;
+ $args['edited'] = $edited;
+ if($arr['item'])
+ $args['item'] = $arr['item'];
+
+ $p = photo_upload($channel,$observer,$args);
+ if($p['success']) {
+ $ret['body'] = $p['body'];
+ }
+ }
+
+ if(($options !== 'update') && ($remove_when_processed))
@unlink($src);
if(! $r) {
$ret['message'] = t('File upload failed. Possible system limit or action terminated.');
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
// Caution: This re-uses $sql_options set further above
- $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_options limit 1",
+ $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where uid = %d and hash = '%s' $sql_options limit 1",
intval($channel_id),
dbesc($hash)
);
if(! $r) {
$ret['message'] = t('Stored file could not be verified. Upload failed.');
+ call_hooks('photo_upload_end',$ret);
return $ret;
}
+
$ret['success'] = true;
$ret['data'] = $r[0];
-
+ if(! $is_photo) {
+ // This would've been called already with a success result in photos_upload() if it was a photo.
+ call_hooks('photo_upload_end',$ret);
+ }
return $ret;
}
@@ -552,10 +855,9 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
if(count($paths) > 1) {
$curpath = array_shift($paths);
- $r = q("select hash, id from attach where uid = %d and filename = '%s' and (flags & %d )>0 " . permissions_sql($channel_id) . " limit 1",
+ $r = q("select hash, id, is_dir from attach where uid = %d and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id) . " limit 1",
intval($channel_id),
- dbesc($curpath),
- intval(ATTACH_FLAG_DIR)
+ dbesc($curpath)
);
if(! $r) {
$ret['message'] = t('Path not available.');
@@ -568,11 +870,10 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
else
$paths = array($pathname);
- $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and (flags & %d )>0 " . permissions_sql($channel_id),
+ $r = q("select id, aid, uid, hash, creator, filename, filetype, filesize, revision, folder, is_photo, is_dir, os_storage, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and folder = '%s' and filename = '%s' and is_dir != 0 " . permissions_sql($channel_id),
intval($channel_id),
dbesc($parent_hash),
- dbesc($paths[0]),
- intval(ATTACH_FLAG_DIR)
+ dbesc($paths[0])
);
if(! $r) {
$ret['message'] = t('Path not available.');
@@ -594,7 +895,7 @@ function z_readdir($channel_id, $observer_hash, $pathname, $parent_hash = '') {
* * \e string \b filename
* * \e string \b folder hash of parent directory, empty string for root directory
* - Optional:
- * * \e string \b hash precumputed hash for this node
+ * * \e string \b hash precomputed hash for this node
* * \e tring \b allow_cid
* * \e string \b allow_gid
* * \e string \b deny_cid
@@ -605,6 +906,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$ret = array('success' => false);
$channel_id = $channel['channel_id'];
+
$sql_options = '';
$basepath = 'store/' . $channel['channel_address'];
@@ -629,13 +931,23 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
// Check for duplicate name.
// Check both the filename and the hash as we will be making use of both.
- $r = q("select hash from attach where ( filename = '%s' or hash = '%s' ) and folder = '%s' and uid = %d limit 1",
+ $r = q("select id, hash, is_dir, flags from attach where ( filename = '%s' or hash = '%s' ) and folder = '%s' and uid = %d limit 1",
dbesc($arr['filename']),
dbesc($arr['hash']),
dbesc($arr['folder']),
intval($channel['channel_id'])
);
if($r) {
+ if(array_key_exists('force',$arr) && intval($arr['force'])
+ && (intval($r[0]['is_dir']))) {
+ $ret['success'] = true;
+ $r = q("select * from attach where id = %d limit 1",
+ intval($r[0]['id'])
+ );
+ if($r)
+ $ret['data'] = $r[0];
+ return $ret;
+ }
$ret['message'] = t('duplicate filename or path');
return $ret;
}
@@ -651,11 +963,10 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$sql_options = permissions_sql($channel['channel_id']);
do {
- $r = q("select filename, hash, flags, folder from attach where uid = %d and hash = '%s' and ( flags & %d )>0
+ $r = q("select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0
$sql_options limit 1",
intval($channel['channel_id']),
- dbesc($lfile),
- intval(ATTACH_FLAG_DIR)
+ dbesc($lfile)
);
if(! $r) {
@@ -666,7 +977,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
if($lfile)
$lpath = $r[0]['hash'] . '/' . $lpath;
$lfile = $r[0]['folder'];
- } while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR)) ;
+ } while ( ($r[0]['folder']) && intval($r[0]['is_dir'])) ;
$path = $basepath . '/' . $lpath;
}
else
@@ -676,8 +987,8 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
$created = datetime_convert();
- $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, flags, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
- VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
+ $r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, filesize, revision, folder, os_storage, is_dir, data, created, edited, allow_cid, allow_gid, deny_cid, deny_gid )
+ VALUES ( %d, %d, '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s' ) ",
intval($channel['channel_account_id']),
intval($channel_id),
dbesc($arr['hash']),
@@ -687,7 +998,8 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
intval(0),
intval(0),
dbesc($arr['folder']),
- intval(ATTACH_FLAG_DIR|ATTACH_FLAG_OS),
+ intval(1),
+ intval(1),
dbesc($path),
dbesc($created),
dbesc($created),
@@ -700,7 +1012,6 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
if($r) {
if(os_mkdir($path, STORAGE_DEFAULT_PERMISSIONS, true)) {
$ret['success'] = true;
- $ret['data'] = $arr;
// update the parent folder's lastmodified timestamp
$e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d",
@@ -708,6 +1019,13 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
dbesc($arr['folder']),
intval($channel_id)
);
+
+ $z = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1",
+ dbesc($arr['hash']),
+ intval($channel_id)
+ );
+ if($z)
+ $ret['data'] = $z[0];
}
else {
logger('attach_mkdir: ' . mkdir . ' ' . $path . ' failed.');
@@ -722,6 +1040,95 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
}
/**
+ * @brief Create directory (recursive).
+ *
+ * @param array $channel channel array of owner
+ * @param string $observer_hash hash of current observer
+ * @param array $arr parameter array to fulfil request
+ * - Required:
+ * * \e string \b pathname
+ * * \e string \b folder hash of parent directory, empty string for root directory
+ * - Optional:
+ * * \e string \b allow_cid
+ * * \e string \b allow_gid
+ * * \e string \b deny_cid
+ * * \e string \b deny_gid
+ * @return array
+ */
+function attach_mkdirp($channel, $observer_hash, $arr = null) {
+
+ $ret = array('success' => false);
+ $channel_id = $channel['channel_id'];
+
+ $sql_options = '';
+
+ $basepath = 'store/' . $channel['channel_address'];
+
+ logger('attach_mkdirp: basepath: ' . $basepath);
+
+ if(! is_dir($basepath))
+ os_mkdir($basepath,STORAGE_DEFAULT_PERMISSIONS, true);
+
+ if(! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) {
+ $ret['message'] = t('Permission denied.');
+ return $ret;
+ }
+
+ if(! $arr['pathname']) {
+ $ret['message'] = t('Empty pathname');
+ return $ret;
+ }
+
+ $paths = explode('/',$arr['pathname']);
+ if(! $paths) {
+ $ret['message'] = t('Empty path');
+ return $ret;
+ }
+
+ $current_parent = '';
+
+ foreach($paths as $p) {
+ if(! $p)
+ continue;
+ $arx = array(
+ 'filename' => $p,
+ 'folder' => $current_parent,
+ 'force' => 1
+ );
+ if(array_key_exists('allow_cid',$arr))
+ $arx['allow_cid'] = $arr['allow_cid'];
+ if(array_key_exists('deny_cid',$arr))
+ $arx['deny_cid'] = $arr['deny_cid'];
+ if(array_key_exists('allow_gid',$arr))
+ $arx['allow_gid'] = $arr['allow_gid'];
+ if(array_key_exists('deny_gid',$arr))
+ $arx['deny_gid'] = $arr['deny_gid'];
+
+ $x = attach_mkdir($channel, $observer_hash, $arx);
+ if($x['success']) {
+ $current_parent = $x['data']['hash'];
+ }
+ else {
+ $ret['message'] = $x['message'];
+ return $ret;
+ }
+ }
+ if(isset($x)) {
+ $ret['success'] = true;
+ $ret['data'] = $x['data'];
+ }
+
+ return $ret;
+
+}
+
+
+
+
+
+
+
+/**
* @brief Changes permissions of a file.
*
* @param int $channel_id
@@ -734,7 +1141,7 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
*/
function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse = false) {
- $r = q("select hash, flags from attach where hash = '%s' and uid = %d limit 1",
+ $r = q("select hash, flags, is_dir, is_photo from attach where hash = '%s' and uid = %d limit 1",
dbesc($resource),
intval($channel_id)
);
@@ -742,9 +1149,9 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
if(! $r)
return;
- if($r[0]['flags'] & ATTACH_FLAG_DIR) {
+ if(intval($r[0]['is_dir'])) {
if($recurse) {
- $r = q("select hash, flags from attach where folder = '%s' and uid = %d",
+ $r = q("select hash, flags, is_dir from attach where folder = '%s' and uid = %d",
dbesc($resource),
intval($channel_id)
);
@@ -764,6 +1171,16 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
dbesc($resource),
intval($channel_id)
);
+ if($r[0]['is_photo']) {
+ $x = q("update photo set allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s' where resource_id = '%s' and uid = %d",
+ dbesc($allow_cid),
+ dbesc($allow_gid),
+ dbesc($deny_cid),
+ dbesc($deny_gid),
+ dbesc($resource),
+ intval($channel_id)
+ );
+ }
}
/**
@@ -778,15 +1195,16 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi
* The hash to delete
* @return void
*/
-function attach_delete($channel_id, $resource) {
+function attach_delete($channel_id, $resource, $is_photo = 0) {
$c = q("SELECT channel_address FROM channel WHERE channel_id = %d LIMIT 1",
intval($channel_id)
);
$channel_address = (($c) ? $c[0]['channel_address'] : 'notfound');
+ $photo_sql = (($is_photo) ? " and is_photo = 1 " : '');
- $r = q("SELECT hash, flags, folder FROM attach WHERE hash = '%s' AND uid = %d limit 1",
+ $r = q("SELECT hash, flags, is_dir, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
dbesc($resource),
intval($channel_id)
);
@@ -798,8 +1216,8 @@ function attach_delete($channel_id, $resource) {
$object = get_file_activity_object($channel_id, $resource, $cloudpath);
// If resource is a directory delete everything in the directory recursive
- if($r[0]['flags'] & ATTACH_FLAG_DIR) {
- $x = q("SELECT hash, flags FROM attach WHERE folder = '%s' AND uid = %d",
+ if(intval($r[0]['is_dir'])) {
+ $x = q("SELECT hash, os_storage, is_dir, flags FROM attach WHERE folder = '%s' AND uid = %d",
dbesc($resource),
intval($channel_id)
);
@@ -811,7 +1229,7 @@ function attach_delete($channel_id, $resource) {
}
// delete a file from filesystem
- if($r[0]['flags'] & ATTACH_FLAG_OS) {
+ if(intval($r[0]['os_storage'])) {
$y = q("SELECT data FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
dbesc($resource),
intval($channel_id)
@@ -873,11 +1291,10 @@ function get_cloudpath($arr) {
$lfile = $arr['folder'];
do {
- $r = q("select filename, hash, flags, folder from attach where uid = %d and hash = '%s' and ( flags & %d )>0
+ $r = q("select filename, hash, flags, is_dir, folder from attach where uid = %d and hash = '%s' and is_dir != 0
limit 1",
intval($arr['uid']),
- dbesc($lfile),
- intval(ATTACH_FLAG_DIR)
+ dbesc($lfile)
);
if(! $r)
@@ -887,7 +1304,7 @@ function get_cloudpath($arr) {
$lpath = $r[0]['filename'] . '/' . $lpath;
$lfile = $r[0]['folder'];
- } while ( ($r[0]['folder']) && ($r[0]['flags'] & ATTACH_FLAG_DIR));
+ } while ( ($r[0]['folder']) && intval($r[0]['is_dir']));
$path .= $lpath;
}
@@ -932,14 +1349,19 @@ function get_parent_cloudpath($channel_id, $channel_name, $attachHash) {
* The hash of the attachment
* @return string
*/
-function find_folder_hash_by_attach_hash($channel_id, $attachHash) {
+function find_folder_hash_by_attach_hash($channel_id, $attachHash, $recurse = false) {
+
+logger('attach_hash: ' . $attachHash);
$r = q("SELECT folder FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id),
dbesc($attachHash)
);
$hash = '';
- if ($r) {
- $hash = $r[0]['folder'];
+ if($r && $r[0]['folder']) {
+ if($recurse)
+ $hash = find_folder_hash_by_attach_hash($channel_id,$r[0]['folder'],true) . '/' . $r[0]['folder'];
+ else
+ $hash = $r[0]['folder'];
}
return $hash;
}
@@ -1011,7 +1433,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
//filter out receivers which do not have permission to view filestorage
$arr_allow_cid = check_list_permissions($channel_id, $arr_allow_cid, 'view_storage');
- $is_dir = (($object['flags'] & ATTACH_FLAG_DIR) ? true : false);
+ $is_dir = (intval($object['is_dir']) ? true : false);
//do not send activity for folders for now
if($is_dir)
@@ -1036,9 +1458,13 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$mid = item_message_id();
- $objtype = ACTIVITY_OBJ_FILE;
+ $arr = array();
+
+ $arr['item_wall'] = 1;
+ $arr['item_origin'] = 1;
+ $arr['item_unseen'] = 1;
- $item_flags = ITEM_WALL|ITEM_ORIGIN;
+ $objtype = ACTIVITY_OBJ_FILE;
$private = (($arr_allow_cid[0] || $arr_allow_gid[0] || $arr_deny_cid[0] || $arr_deny_gid[0]) ? 1 : 0);
@@ -1077,23 +1503,20 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$u_mid = item_message_id();
- $arr = array();
-
$arr['aid'] = get_account_id();
$arr['uid'] = $channel_id;
$arr['mid'] = $u_mid;
$arr['parent_mid'] = $u_mid;
- $arr['item_flags'] = $item_flags;
- $arr['item_unseen'] = 1;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
$arr['title'] = '';
- $arr['allow_cid'] = perms2str($u_arr_allow_cid);
- $arr['allow_gid'] = perms2str($u_arr_allow_gid);
- $arr['deny_cid'] = perms2str($u_arr_deny_cid);
- $arr['deny_gid'] = perms2str($u_arr_deny_gid);
- $arr['item_restrict'] = ITEM_HIDDEN;
- $arr['item_private'] = $private;
+ //updates should be visible to everybody -> perms may have changed
+ $arr['allow_cid'] = '';
+ $arr['allow_gid'] = '';
+ $arr['deny_cid'] = '';
+ $arr['deny_gid'] = '';
+ $arr['item_hidden'] = 1;
+ $arr['item_private'] = 0;
$arr['verb'] = ACTIVITY_UPDATE;
$arr['obj_type'] = $objtype;
$arr['object'] = $u_jsonobject;
@@ -1124,7 +1547,8 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$arr['uid'] = $channel_id;
$arr['mid'] = $mid;
$arr['parent_mid'] = $mid;
- $arr['item_flags'] = $item_flags;
+ $arr['item_wall'] = 1;
+ $arr['item_origin'] = 1;
$arr['item_unseen'] = 1;
$arr['author_xchan'] = $poster['xchan_hash'];
$arr['owner_xchan'] = $poster['xchan_hash'];
@@ -1133,7 +1557,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
$arr['allow_gid'] = perms2str($arr_allow_gid);
$arr['deny_cid'] = perms2str($arr_deny_cid);
$arr['deny_gid'] = perms2str($arr_deny_gid);
- $arr['item_restrict'] = ITEM_HIDDEN;
+ $arr['item_hidden'] = 1;
$arr['item_private'] = $private;
$arr['verb'] = (($update) ? ACTIVITY_UPDATE : ACTIVITY_POST);
$arr['obj_type'] = $objtype;
@@ -1165,7 +1589,7 @@ function file_activity($channel_id, $object, $allow_cid, $allow_gid, $deny_cid,
*/
function get_file_activity_object($channel_id, $hash, $cloudpath) {
- $x = q("SELECT creator, filename, filetype, filesize, revision, folder, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
+ $x = q("SELECT creator, filename, filetype, filesize, revision, folder, os_storage, is_photo, is_dir, flags, created, edited, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
intval($channel_id),
dbesc($hash)
);
@@ -1193,6 +1617,9 @@ function get_file_activity_object($channel_id, $hash, $cloudpath) {
'revision' => $x[0]['revision'],
'folder' => $x[0]['folder'],
'flags' => $x[0]['flags'],
+ 'os_storage' => $x[0]['os_storage'],
+ 'is_photo' => $x[0]['is_photo'],
+ 'is_dir' => $x[0]['is_dir'],
'created' => $x[0]['created'],
'edited' => $x[0]['edited'],
'allow_cid' => $x[0]['allow_cid'],
@@ -1348,3 +1775,16 @@ function in_group($group_id) {
return $group_members;
}
+
+
+function filepath_macro($s) {
+
+ return str_replace(
+ array( '%Y', '%m', '%d' ),
+ array( datetime_convert('UTC',date_default_timezone_get(),'now', 'Y'),
+ datetime_convert('UTC',date_default_timezone_get(),'now', 'm'),
+ datetime_convert('UTC',date_default_timezone_get(),'now', 'd')
+ ), $s);
+
+}
+