/** * @brief Delete a file/directory from a channel. * * If the provided resource hash is from a directory it will delete everything * recursively under this directory. * * @param int $channel_id * The id of the channel * @param string $resource * The hash to delete * @return void */ 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, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d {$photo_sql} limit 1", dbesc($resource), intval($channel_id)); if (!$r) { return; } $cloudpath = get_parent_cloudpath($channel_id, $channel_address, $resource); $object = get_file_activity_object($channel_id, $resource, $cloudpath); // If resource is a directory delete everything in the directory recursive 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)); if ($x) { foreach ($x as $xx) { attach_delete($channel_id, $xx['hash']); } } } // delete a file from filesystem 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)); if ($y) { $f = 'store/' . $channel_address . '/' . $y[0]['data']; if (is_dir($y[0]['data'])) { @rmdir($y[0]['data']); } elseif (file_exists($f)) { unlink($f); } } } // delete from database $z = q("DELETE FROM attach WHERE hash = '%s' AND uid = %d", dbesc($resource), intval($channel_id)); if ($r[0]['is_photo']) { $x = q("select id, item_hidden from item where resource_id = '%s' and resource_type = 'photo' and uid = %d", dbesc($resource), intval($channel_id)); if ($x) { drop_item($x[0]['id'], false, $x[0]['item_hidden'] ? DROPITEM_NORMAL : DROPITEM_PHASE1, true); q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'", intval($channel_id), dbesc($resource)); } } // update the parent folder's lastmodified timestamp $e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d", dbesc(datetime_convert()), dbesc($r[0]['folder']), intval($channel_id)); file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', $notify = 0); }
function filestorage_content(&$a) { if (argc() > 1) { $which = argv(1); } else { notice(t('Requested profile is not available.') . EOL); $a->error = 404; return; } $r = q("select * from channel where channel_address = '%s'", dbesc($which)); if ($r) { $channel = $r[0]; $owner = intval($r[0]['channel_id']); } $observer = $a->get_observer(); $ob_hash = $observer ? $observer['xchan_hash'] : ''; $perms = get_all_perms($owner, $ob_hash); if (!$perms['view_storage']) { notice(t('Permission denied.') . EOL); return; } // Since we have ACL'd files in the wild, but don't have ACL here yet, we // need to return for anyone other than the owner, despite the perms check for now. $is_owner = local_channel() && $owner == local_channel() ? true : false; if (!$is_owner) { info(t('Permission Denied.') . EOL); return; } if (argc() > 3 && argv(3) === 'delete') { if (!$perms['write_storage']) { notice(t('Permission denied.') . EOL); return; } $file = intval(argv(2)); $r = q("SELECT hash FROM attach WHERE id = %d AND uid = %d LIMIT 1", dbesc($file), intval($owner)); if (!$r) { notice(t('File not found.') . EOL); goaway(z_root() . '/cloud/' . $which); } $f = $r[0]; $channel = $a->get_channel(); $parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']); attach_delete($owner, $f['hash']); goaway($parentpath); } if (argc() > 3 && argv(3) === 'edit') { require_once 'include/acl_selectors.php'; if (!$perms['write_storage']) { notice(t('Permission denied.') . EOL); return; } $file = intval(argv(2)); $r = q("select id, uid, folder, filename, revision, flags, hash, allow_cid, allow_gid, deny_cid, deny_gid from attach where id = %d and uid = %d limit 1", intval($file), intval($owner)); $f = $r[0]; $channel = $a->get_channel(); $cloudpath = get_cloudpath($f) . ($f['flags'] & ATTACH_FLAG_DIR ? '?f=&davguest=1' : ''); $parentpath = get_parent_cloudpath($channel['channel_id'], $channel['channel_address'], $f['hash']); $aclselect_e = populate_acl($f, false); $is_a_dir = $f['flags'] & ATTACH_FLAG_DIR ? true : false; $lockstate = $f['allow_cid'] || $f['allow_gid'] || $f['deny_cid'] || $f['deny_gid'] ? 'lock' : 'unlock'; // Encode path that is used for link so it's a valid URL // Keep slashes as slashes, otherwise mod_rewrite doesn't work correctly $encoded_path = str_replace('%2F', '/', rawurlencode($cloudpath)); $o = replace_macros(get_markup_template('attach_edit.tpl'), array('$header' => t('Edit file permissions'), '$file' => $f, '$cloudpath' => z_root() . '/' . $encoded_path, '$parentpath' => $parentpath, '$uid' => $channel['channel_id'], '$channelnick' => $channel['channel_address'], '$permissions' => t('Permissions'), '$aclselect' => $aclselect_e, '$lockstate' => $lockstate, '$permset' => t('Set/edit permissions'), '$recurse' => array('recurse', t('Include all files and sub folders'), 0, '', array(t('No'), t('Yes'))), '$backlink' => t('Return to file list'), '$isadir' => $is_a_dir, '$cpdesc' => t('Copy/paste this code to attach file to a post'), '$cpldesc' => t('Copy/paste this URL to link file from a web page'), '$submit' => t('Submit'), '$attach_btn_title' => t('Share this file'), '$link_btn_title' => t('Show URL to this file'), '$notify' => array('notify', t('Notify your contacts about this file'), 0, '', array(t('No'), t('Yes'))))); echo $o; killme(); } goaway(z_root() . '/cloud/' . $which); }
/** * @brief Delete a file/directory from a channel. * * If the provided resource hash is from a directory it will delete everything * recursively under this directory. * * @param int $channel_id * The id of the channel * @param string $resource * The hash to delete * @return void */ function attach_delete($channel_id, $resource) { $c = q("SELECT channel_address FROM channel WHERE channel_id = %d LIMIT 1", intval($channel_id)); $channel_address = $c ? $c[0]['channel_address'] : 'notfound'; $r = q("SELECT hash, flags, folder FROM attach WHERE hash = '%s' AND uid = %d limit 1", dbesc($resource), intval($channel_id)); if (!$r) { return; } $cloudpath = get_parent_cloudpath($channel_id, $channel_address, $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", dbesc($resource), intval($channel_id)); if ($x) { foreach ($x as $xx) { attach_delete($channel_id, $xx['hash']); } } } // delete a file from filesystem if ($r[0]['flags'] & ATTACH_FLAG_OS) { $y = q("SELECT data FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1", dbesc($resource), intval($channel_id)); if ($y) { $f = 'store/' . $channel_address . '/' . $y[0]['data']; if (is_dir($f)) { @rmdir($f); } elseif (file_exists($f)) { unlink($f); } } } // delete from database $z = q("DELETE FROM attach WHERE hash = '%s' AND uid = %d", dbesc($resource), intval($channel_id)); // update the parent folder's lastmodified timestamp $e = q("UPDATE attach SET edited = '%s' WHERE hash = '%s' AND uid = %d", dbesc(datetime_convert()), dbesc($r[0]['folder']), intval($channel_id)); file_activity($channel_id, $object, $object['allow_cid'], $object['allow_gid'], $object['deny_cid'], $object['deny_gid'], 'update', $no_activity = false); }