Commit 27daea35 authored by Mario's avatar Mario
Browse files

files_ng: some work on file categories

parent 5a45743b
Pipeline #368903 passed with stage
in 2 minutes and 51 seconds
......@@ -28,6 +28,7 @@ class Attach_edit extends Controller {
$recurse = ((x($_POST, 'recurse_' . $attach_id)) ? intval($_POST['recurse_' . $attach_id]) : 0);
$notify = ((x($_POST, 'notify_edit_' . $attach_id)) ? intval($_POST['notify_edit_' . $attach_id]) : 0);
$copy = ((x($_POST, 'copy_' . $attach_id)) ? intval($_POST['copy_' . $attach_id]) : 0);
$categories = ((x($_POST, 'categories_' . $attach_id)) ? notags($_POST['categories_' . $attach_id]) : '');
$channel = App::get_channel();
......@@ -38,7 +39,7 @@ class Attach_edit extends Controller {
$x = attach_move($channel['channel_id'], $resource, $newfolder, $newfilename);
}
if($x['success'])
if ($x['success'])
$resource = $x['resource_id'];
$acl = new AccessList($channel);
......@@ -49,6 +50,22 @@ class Attach_edit extends Controller {
attach_change_permissions($channel['channel_id'], $resource, $x['allow_cid'], $x['allow_gid'], $x['deny_cid'], $x['deny_gid'], $recurse, true);
if ($categories) {
$cat = explode(',', $categories);
hz_syslog(print_r($cat,true));
if ($cat) {
foreach($cat as $term) {
$term = trim(escape_tags($term));
if ($term) {
$term_link = z_root() . '/cloud/' . $channel['channel_address'] . '/?cat=' . $term;
store_item_tag($channel['channel_id'], $attach_id, TERM_OBJ_FILE, TERM_CATEGORY, $term, $term_link);
}
}
}
}
$sync = attach_export_data($channel, $resource, false);
if ($sync) {
......
......@@ -109,13 +109,13 @@ class Cloud extends Controller {
if($browser->build_page)
construct_page();
killme();
}
function DAVException($err) {
if($err instanceof \Sabre\DAV\Exception\NotFound) {
notice( t('Not found') . EOL);
}
......@@ -130,7 +130,7 @@ class Cloud extends Controller {
}
construct_page();
killme();
}
......
......@@ -76,8 +76,11 @@ class Browser extends DAV\Browser\Plugin {
* @param string $path which should be displayed
*/
public function generateDirectoryIndex($path) {
// (owner_id = channel_id) is visitor owner of this directory?
$is_owner = ((local_channel() && $this->auth->owner_id == local_channel()) ? true : false);
$cat = $_REQUEST['cat'];
if ($this->auth->getTimezone())
date_default_timezone_set($this->auth->getTimezone());
......@@ -88,13 +91,14 @@ class Browser extends DAV\Browser\Plugin {
$html = '';
}
$files = $this->server->getPropertiesForPath($path, array(
$files = $this->server->getPropertiesForPath($path, [
'{DAV:}displayname',
'{DAV:}resourcetype',
'{DAV:}getcontenttype',
'{DAV:}getcontentlength',
'{DAV:}getlastmodified',
), 1);
'{DAV:}getetag'
], 1);
$parent = $this->server->tree->getNodeForPath($path);
......@@ -193,15 +197,26 @@ class Browser extends DAV\Browser\Plugin {
$parentHash = '';
$owner = $this->auth->owner_id;
$splitPath = explode('/', $relPath);
if (count($splitPath) > 3) {
for ($i = 3; $i < count($splitPath); $i++) {
$attachName = urldecode($splitPath[$i]);
$attachHash = $this->findAttachHash($owner, $parentHash, $attachName);
$parentHash = $attachHash;
}
if (isset($file[200]['{DAV:}getetag'])) {
$attachHash = trim($file[200]['{DAV:}getetag'], '"');
$parentHash = $parent->folder_hash;
}
else {
// folders don't have an etag - can we get the folder hash in an other way?
$splitPath = explode('/', $relPath);
if (count($splitPath) > 3) {
for ($i = 3; $i < count($splitPath); $i++) {
$attachName = urldecode($splitPath[$i]);
if($cat)
$attachHash = $this->findAttachHashFlat($owner, $attachName);
else
$attachHash = $this->findAttachHash($owner, $parentHash, $attachName);
$parentHash = $attachHash;
}
}
}
// generate preview icons for tile view.
// Currently we only handle images, but this could potentially be extended with plugins
......@@ -214,11 +229,10 @@ class Browser extends DAV\Browser\Plugin {
$photo_icon = '';
$preview_style = intval(get_config('system','thumbnail_security',0));
$r = q("SELECT content, creator, hash, revision, folder, is_dir, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE hash = '%s' AND uid = %d",
$r = q("SELECT id, content, creator, hash, revision, folder, display_path, is_dir, allow_cid, allow_gid, deny_cid, deny_gid FROM attach WHERE hash = '%s' AND uid = %d",
dbesc($attachHash),
intval($owner)
);
if($r) {
$is_creator = (($r[0]['creator'] === get_observer_hash()) ? true : false);
if(file_exists(dbunescbin($r[0]['content']) . '.thumb')) {
......@@ -248,8 +262,26 @@ class Browser extends DAV\Browser\Plugin {
$attachIcon = ""; // "<a href=\"attach/".$attachHash."\" title=\"".$displayName."\"><i class=\"fa fa-arrow-circle-o-down\"></i></a>";
$lockstate = (($r[0]['allow_cid'] || $r[0]['allow_gid'] || $r[0]['deny_cid'] || $r[0]['deny_gid']) ? 'lock' : 'unlock');
$id = $this->findAttachIdByHash($attachHash);
$id = $r[0]['id'];
$terms = q("select * from term where oid = %d AND otype = %d",
intval($id),
intval(TERM_OBJ_FILE)
);
if($terms) {
foreach($terms as $t) {
$term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ;
if(! trim($term))
continue;
$categories[] = array('term' => $term, 'url' => $t['url']);
}
$ft['terms'] = replace_macros(get_markup_template('item_categories.tpl'),array(
'$categories' => $categories
));
unset($categories);
}
// put the array for this file together
$ft['attachId'] = $id;
$ft['fileStorageUrl'] = substr($relPath, 0, strpos($relPath, "cloud/")) . "filestorage/" . $this->auth->owner_nick;
......@@ -259,8 +291,8 @@ class Browser extends DAV\Browser\Plugin {
// @todo Should this be an item value, not a global one?
$ft['is_owner'] = $is_owner;
$ft['is_creator'] = $is_creator;
$ft['relPath'] = $relPath;
$ft['fullPath'] = z_root() . $relPath;
$ft['relPath'] = '/cloud/' . $this->auth->getCurrentUser() .'/' . $r[0]['display_path'];
$ft['fullPath'] = z_root() . '/cloud/' . $this->auth->getCurrentUser() .'/' . $r[0]['display_path'];
$ft['displayName'] = $displayName;
$ft['type'] = $type;
$ft['size'] = $size;
......@@ -284,6 +316,8 @@ class Browser extends DAV\Browser\Plugin {
$ft['folder'] = $r[0]['folder'];
$ft['revision'] = $r[0]['revision'];
$ft['newfilename'] = ['newfilename_' . $id, t('Change filename to'), $displayName];
$ft['categories'] = ['categories_' . $id, t('Add categories'), ''];
// create a copy of the list which we can alter for the current resource
$folders = $folder_list;
if($r[0]['is_dir']) {
......@@ -313,8 +347,10 @@ class Browser extends DAV\Browser\Plugin {
$parentpath = [];
}
$header = (($cat) ? t('File categories') . ": " . $this->escapeHTML($path) . "/" : t('Files') . ": " . $this->escapeHTML($path) . "/");
$html .= replace_macros(get_markup_template('cloud.tpl'), array(
'$header' => t('Files') . ": " . $this->escapeHTML($path) . "/",
'$header' => $header,
'$total' => t('Total'),
'$actionspanel' => $output,
'$shared' => t('Shared'),
......@@ -496,6 +532,21 @@ class Browser extends DAV\Browser\Plugin {
return $hash;
}
protected function findAttachHashFlat($owner, $attachName) {
$r = q("SELECT hash FROM attach WHERE uid = %d AND filename = '%s' ORDER BY edited DESC LIMIT 1",
intval($owner),
dbesc($attachName)
);
$hash = '';
if ($r) {
foreach ($r as $rr) {
$hash = $rr['hash'];
}
}
return $hash;
}
/**
* @brief Returns an attachment's id for a given hash.
*
......
......@@ -25,7 +25,8 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
* @var string $red_path
*/
private $red_path;
private $folder_hash;
public $folder_hash;
/**
* @brief The full path as seen in the browser.
* /cloud + $red_path
......@@ -269,8 +270,8 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
dbesc($f),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
'',
'',
'',
'',
dbesc($allow_cid),
dbesc($allow_gid),
dbesc($deny_cid),
......@@ -293,7 +294,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
else {
$size = file_put_contents($f, $data);
}
// delete attach entry if file_put_contents() failed
if ($size === false) {
logger('file_put_contents() failed to ' . $f);
......@@ -374,7 +375,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
$args = array( 'resource_id' => $hash, 'album' => $album, 'os_syspath' => $f, 'os_path' => $xpath['os_path'], 'display_path' => $xpath['path'], 'filename' => $name, 'getimagesize' => $gis, 'directory' => $direct);
$p = photo_upload($c[0], \App::get_observer(), $args);
}
\Zotlabs\Daemon\Master::Summon([ 'Thumbnail' , $hash ]);
$sync = attach_export_data($c[0], $hash);
......@@ -402,13 +403,14 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
if ($r) {
// When initiated from DAV, set the 'force' flag on attach_mkdir(). This will cause the operation to report success even if the
// folder already exists.
// When initiated from DAV, set the 'force' flag on attach_mkdir(). This will cause the operation to report success even if the
// folder already exists.
require_once('include/attach.php');
$result = attach_mkdir($r[0], $this->auth->observer, array('filename' => $name, 'folder' => $this->folder_hash, 'force' => true));
if($result['success']) {
$sync = attach_export_data($r[0],$result['data']['hash']);
logger('createDirectory: attach_export_data returns $sync:' . print_r($sync, true), LOGGER_DEBUG);
......@@ -610,6 +612,9 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
$file = trim($file, '/');
$path_arr = explode('/', $file);
$cat = $_REQUEST['cat'];
if (! $path_arr)
return null;
......@@ -680,7 +685,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
$_SESSION['cloud_sort'] = 'name';
switch($_SESSION['cloud_sort']) {
case 'size':
case 'size':
$suffix = ' order by is_dir desc, filesize asc ';
break;
// The following provides inconsistent results for directories because we re-calculate the date for directories based on the most recent change
......@@ -693,17 +698,27 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
break;
}
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
dbesc($folder),
intval($channel_id)
);
if ($cat) {
$r = q("select $prefix attach.id, attach.uid, attach.hash, attach.filename, attach.filetype, attach.filesize, attach.revision, attach.folder, attach.flags, attach.is_dir, attach.created, attach.edited from attach
left join term on attach.id = term.oid
where term.term = '%s' and attach.uid = %d $perms $suffix",
dbesc($cat),
intval($channel_id)
);
}
else {
$r = q("select $prefix id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, created, edited from attach where folder = '%s' and uid = %d $perms $suffix",
dbesc($folder),
intval($channel_id)
);
}
foreach ($r as $rr) {
if(\App::$module === 'cloud' && (strpos($rr['filename'],'.') === 0) && (! get_pconfig($channel_id,'system','show_dot_files')) )
continue;
// @FIXME I don't think we use revisions currently in attach structures.
// In case we see any in the wild provide a unique filename. This
// In case we see any in the wild provide a unique filename. This
// name may or may not be accessible
if($rr['revision'])
......@@ -717,7 +732,6 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
$ret[] = new File($path . '/' . $rr['filename'], $rr, $auth);
}
}
return $ret;
}
......@@ -889,7 +903,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
$used = 0;
$limit = 0;
$free = 0;
if ($this->auth->owner_id) {
$channel = channelx_by_n($this->auth->owner_id);
if($channel) {
......@@ -920,5 +934,4 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota, DAV\IMo
return [ (int) $used, (int) $free ];
}
}
......@@ -433,7 +433,7 @@ define ( 'TERM_FORUM', 11 );
define ( 'TERM_EMOJI', 12 );
define ( 'TERM_OBJ_POST', 1 );
define ( 'TERM_OBJ_PHOTO', 2 );
define ( 'TERM_OBJ_FILE', 2 );
define ( 'TERM_OBJ_PROFILE', 3 );
define ( 'TERM_OBJ_CHANNEL', 4 );
define ( 'TERM_OBJ_OBJECT', 5 );
......
#files-mkdir-tools,
#files-upload-tools,
.link-code,
.cloud-tool {
display: none;
}
......@@ -22,27 +21,35 @@
width: 100%;
}
#cloud-index td a {
#cloud-index td:nth-child(2) a {
display: block;
}
#cloud-index td:nth-child(1){
#cloud-index td:nth-child(1) {
padding: 7px 3px 7px 10px;
}
#cloud-index td:nth-child(2){
#cloud-index td:nth-child(4) {
padding: 7px 10px 7px 3px;
}
#cloud-index td:nth-child(2) {
word-break: break-all;
}
#cloud-index th:nth-child(5),
#cloud-index td:nth-child(5){
padding: 7px 0px;
#cloud-index td:nth-child(3) {
white-space: nowrap;
}
#cloud-index th:nth-child(6),
#cloud-index td:nth-child(6){
padding: 7px 0px;
#cloud-index td:nth-child(6) {
padding: 7px 3px;
white-space: nowrap;
}
#cloud-index th:nth-child(7),
#cloud-index td:nth-child(7) {
padding: 7px 10px;
white-space: nowrap;
}
......
......@@ -46,7 +46,8 @@
<table id="cloud-index">
<tr>
<th width="1%">{{* icon *}}</th>
<th width="95%">{{$name}}</th>
<th width="94%">{{$name}}</th>
<th width="1%">{{* categories *}}</th>
<th width="1%">{{* lock icon *}}</th>
<th width="1%">{{* tools icon *}}</th>
<th width="1%" class="d-none d-md-table-cell">{{$size}}</th>
......@@ -55,7 +56,7 @@
{{if $parentpath}}
<tr id="cloud-index-0">
<td><i class="fa fa-level-up"></i>{{*$parentpath.icon*}}</td>
<td colspan="5"><a href="{{$parentpath.path}}" title="{{$parent}}">..</a></td>
<td colspan="7"><a href="{{$parentpath.path}}" title="{{$parent}}">..</a></td>
</tr>
{{/if}}
<tr id="new-upload-progress-bar-1"></tr> {{* this is needed to append the upload files in the right order *}}
......@@ -63,6 +64,7 @@
<tr id="cloud-index-{{$item.attachId}}" class="cloud-index">
<td><i class="fa {{$item.iconFromType}}" title="{{$item.type}}"></i></td>
<td><a href="{{$item.relPath}}" class="p-2">{{$item.displayName}}</a></td>
<td>{{$item.terms}}</td>
<td class="cloud-index-tool p-2">{{if $item.lockstate == 'lock'}}<i class="fa fa-fw fa-{{$item.lockstate}}"></i>{{/if}}</td>
{{if $item.is_owner}}
<td class="cloud-index-tool">
......@@ -105,7 +107,7 @@
<td class="d-none d-md-table-cell p-2">{{$item.lastmodified}}</td>
</tr>
<tr id="cloud-tools-{{$item.attachId}}" class="cloud-tools">
<td id="attach-edit-panel-{{$item.attachId}}" colspan="6">
<td id="attach-edit-panel-{{$item.attachId}}" colspan="7">
<form id="attach_edit_form_{{$item.attachId}}" action="attach_edit/{{$nick}}/{{$item.attachId}}" method="post" class="acl-form" data-form_id="attach_edit_form_{{$item.attachId}}" data-allow_cid='{{$item.allow_cid}}' data-allow_gid='{{$item.allow_gid}}' data-deny_cid='{{$item.deny_cid}}' data-deny_gid='{{$item.deny_gid}}'>
<input type="hidden" name="attach_id" value="{{$item.attachId}}" />
<input type="hidden" name="resource" value="{{$item.resource}}" />
......@@ -121,6 +123,7 @@
<div id="cloud-tool-submit-{{$item.attachId}}" class="cloud-tool">
{{if !$item.collection}}{{include file="field_checkbox.tpl" field=$item.notify}}{{/if}}
{{if $item.collection}}{{include file="field_checkbox.tpl" field=$item.recurse}}{{/if}}
{{include file="field_input.tpl" field=$item.categories}}
<div id="attach-submit-{{$item.attachId}}" class="form-group">
<button id="cloud-tool-cancel-btn-{{$item.attachId}}" class="btn btn-outline-secondary btn-sm cloud-tool-cancel-btn" type="button" data-id="{{$item.attachId}}">
Cancel
......@@ -134,6 +137,9 @@
</button>
</div>
</div>
</div>
<div id="cloud-tool-categories-{{$item.attachId}}" class="">
</div>
<!--div id="cloud-tool-share-{{$item.attachId}}" class="">
<div id="attach-edit-tools-share-{{$item.attachId}}" class="btn-group form-group">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment