diff options
Diffstat (limited to 'Zotlabs')
-rw-r--r-- | Zotlabs/Daemon/Expire.php | 2 | ||||
-rw-r--r-- | Zotlabs/Lib/ThreadItem.php | 2 | ||||
-rw-r--r-- | Zotlabs/Module/Cloud.php | 12 | ||||
-rw-r--r-- | Zotlabs/Module/Dav.php | 2 | ||||
-rw-r--r-- | Zotlabs/Module/Dreport.php | 1 | ||||
-rw-r--r-- | Zotlabs/Module/Item.php | 22 | ||||
-rw-r--r-- | Zotlabs/Module/New_channel.php | 4 | ||||
-rw-r--r-- | Zotlabs/Module/Profile_photo.php | 2 | ||||
-rw-r--r-- | Zotlabs/Module/Tagger.php | 11 | ||||
-rw-r--r-- | Zotlabs/Storage/Directory.php | 286 |
10 files changed, 309 insertions, 35 deletions
diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php index 0ba83b240..215513e87 100644 --- a/Zotlabs/Daemon/Expire.php +++ b/Zotlabs/Daemon/Expire.php @@ -38,7 +38,7 @@ class Expire { logger('site_expire: ' . $site_expire); - $r = q("SELECT channel_id, channel_address, channel_pageflags, channel_expire_days from channel where true"); + $r = q("SELECT channel_id, channel_system, channel_address, channel_expire_days from channel where true"); if ($r) { foreach ($r as $rr) { diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index 6625b7b52..638afeb6b 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -248,7 +248,7 @@ class ThreadItem { $has_bookmarks = false; if(is_array($item['term'])) { foreach($item['term'] as $t) { - if(!UNO && $t['type'] == TERM_BOOKMARK) + if(!UNO && $t['ttype'] == TERM_BOOKMARK) $has_bookmarks = true; } } diff --git a/Zotlabs/Module/Cloud.php b/Zotlabs/Module/Cloud.php index 833b1b493..9845c5658 100644 --- a/Zotlabs/Module/Cloud.php +++ b/Zotlabs/Module/Cloud.php @@ -23,7 +23,6 @@ require_once('vendor/autoload.php'); class Cloud extends \Zotlabs\Web\Controller { function init() { - require_once('include/reddav.php'); if (! is_dir('store')) os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false); @@ -79,17 +78,6 @@ class Cloud extends \Zotlabs\Web\Controller { $is_readable = false; - if($_SERVER['REQUEST_METHOD'] === 'GET') { - try { - $x = RedFileData('/' . \App::$cmd, $auth); - } - catch(\Exception $e) { - if($e instanceof Sabre\DAV\Exception\Forbidden) { - http_status_exit(401, 'Permission denied.'); - } - } - } - // provide a directory view for the cloud in Hubzilla $browser = new \Zotlabs\Storage\Browser($auth); $auth->setBrowserPlugin($browser); diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 6528e0271..9b4b576c8 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -44,8 +44,6 @@ class Dav extends \Zotlabs\Web\Controller { } } - require_once('include/reddav.php'); - if (! is_dir('store')) os_mkdir('store', STORAGE_DEFAULT_PERMISSIONS, false); diff --git a/Zotlabs/Module/Dreport.php b/Zotlabs/Module/Dreport.php index 17ed6515e..d2933b464 100644 --- a/Zotlabs/Module/Dreport.php +++ b/Zotlabs/Module/Dreport.php @@ -146,6 +146,7 @@ class Dreport extends \Zotlabs\Web\Controller { '$title' => sprintf( t('Delivery report for %1$s'),substr($mid,0,32)) . '...', '$table' => $table, '$mid' => urlencode($mid), + '$options' => t('Options'), '$push' => t('Redeliver'), '$entries' => $entries )); diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index 369dd3948..58d39da83 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -93,7 +93,7 @@ class Item extends \Zotlabs\Web\Controller { $origin = (($api_source && array_key_exists('origin',$_REQUEST)) ? intval($_REQUEST['origin']) : 1); - // To represent message-ids on other networks - this will create an item_id record + // To represent message-ids on other networks - this will create an iconfig record $namespace = (($api_source && array_key_exists('namespace',$_REQUEST)) ? strip_tags($_REQUEST['namespace']) : ''); $remote_id = (($api_source && array_key_exists('remote_id',$_REQUEST)) ? strip_tags($_REQUEST['remote_id']) : ''); @@ -535,7 +535,7 @@ class Item extends \Zotlabs\Web\Controller { } /** - * fix naked links by passing through a callback to see if this is a red site + * fix naked links by passing through a callback to see if this is a hubzilla site * (already known to us) which will get a zrl, otherwise link with url, add bookmark tag to both. * First protect any url inside certain bbcode tags so we don't double link it. */ @@ -834,21 +834,23 @@ class Item extends \Zotlabs\Web\Controller { if($orig_post) $datarray['edit'] = true; + // suppress duplicates, *unless* you're editing an existing post. This could get picked up + // as a duplicate if you're editing it very soon after posting it initially and you edited + // some attribute besides the content, such as title or categories. + if(feature_enabled($profile_uid,'suppress_duplicates') && (! $orig_post)) { - $z = q("select created from item where uid = %d and body = '%s'", + $z = q("select created from item where uid = %d and created > %s - INTERVAL %s and body = '%s' limit 1", intval($profile_uid), + db_utcnow(), + db_quoteinterval('2 MINUTE'), dbesc($body) ); if($z) { - foreach($z as $zz) { - if($zz['created'] > datetime_convert('UTC','UTC', 'now - 2 minutes')) { - $datarray['cancel'] = 1; - notice( t('Duplicate post suppressed.') . EOL); - logger('Duplicate post. Faking plugin cancel.'); - } - } + $datarray['cancel'] = 1; + notice( t('Duplicate post suppressed.') . EOL); + logger('Duplicate post. Faking plugin cancel.'); } } diff --git a/Zotlabs/Module/New_channel.php b/Zotlabs/Module/New_channel.php index 1dcf84fb0..26883b6e2 100644 --- a/Zotlabs/Module/New_channel.php +++ b/Zotlabs/Module/New_channel.php @@ -125,9 +125,9 @@ class New_channel extends \Zotlabs\Web\Controller { } } - $name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"')); + $name = array('name', t('Name or caption'), ((x($_REQUEST,'name')) ? $_REQUEST['name'] : ''), t('Examples: "Bob Jameson", "Lisa and her Horses", "Soccer", "Aviation Group"'), "*"); $nickhub = '@' . \App::get_hostname(); - $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub)); + $nickname = array('nickname', t('Choose a short nickname'), ((x($_REQUEST,'nickname')) ? $_REQUEST['nickname'] : ''), sprintf( t('Your nickname will be used to create an easy to remember channel address e.g. nickname%s'), $nickhub), "*"); $privacy_role = ((x($_REQUEST,'permissions_role')) ? $_REQUEST['permissions_role'] : "" ); $role = array('permissions_role' , t('Channel role and privacy'), ($privacy_role) ? $privacy_role : 'social', t('Select a channel role with your privacy requirements.') . ' <a href="help/roles" target="_blank">' . t('Read more about roles') . '</a>',get_roles()); diff --git a/Zotlabs/Module/Profile_photo.php b/Zotlabs/Module/Profile_photo.php index 9359b80f8..f459f7deb 100644 --- a/Zotlabs/Module/Profile_photo.php +++ b/Zotlabs/Module/Profile_photo.php @@ -180,6 +180,8 @@ class Profile_photo extends \Zotlabs\Web\Controller { dbesc(datetime_convert()), dbesc($channel['xchan_hash']) ); + // Similarly, tell the nav bar to bypass the cache and update the avater image. + $_SESSION['reload_avatar'] = true; info( t('Shift-reload the page or clear browser cache if the new photo does not display immediately.') . EOL); diff --git a/Zotlabs/Module/Tagger.php b/Zotlabs/Module/Tagger.php index 0a46cf56d..25f518d53 100644 --- a/Zotlabs/Module/Tagger.php +++ b/Zotlabs/Module/Tagger.php @@ -129,9 +129,14 @@ class Tagger extends \Zotlabs\Web\Controller { store_item_tag($item['uid'],$item['id'],TERM_OBJ_POST,TERM_COMMUNITYTAG,$term,$tagid); $ret = post_activity_item($arr); - - if($ret['success']) - \Zotlabs\Daemon\Master::Summon(array('Notifier','tag',$ret['activity']['id'])); + + if($ret['success']) { + build_sync_packet(local_channel(), + [ + 'item' => [ encode_item($ret['activity'],true) ] + ] + ); + } killme(); diff --git a/Zotlabs/Storage/Directory.php b/Zotlabs/Storage/Directory.php index 06ae90a5f..b524b3cab 100644 --- a/Zotlabs/Storage/Directory.php +++ b/Zotlabs/Storage/Directory.php @@ -91,7 +91,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota { throw new DAV\Exception\Forbidden('Permission denied.'); } - $contents = RedCollectionData($this->red_path, $this->auth); + $contents = $this->CollectionData($this->red_path, $this->auth); return $contents; } @@ -119,7 +119,7 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota { return new Directory('/' . $modulename, $this->auth); } - $x = RedFileData($this->ext_path . '/' . $name, $this->auth); + $x = $this->FileData($this->ext_path . '/' . $name, $this->auth); if ($x) { return $x; } @@ -206,6 +206,8 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota { throw new DAV\Exception\Forbidden('Permission denied.'); } + require_once('include/attach.php'); + $mimetype = z_mime_content_type($name); $c = q("SELECT * FROM channel WHERE channel_id = %d AND channel_removed = 0 LIMIT 1", @@ -431,8 +433,8 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota { return true; } - $x = RedFileData($this->ext_path . '/' . $name, $this->auth, true); - //logger('RedFileData returns: ' . print_r($x, true), LOGGER_DATA); + $x = $this->FileData($this->ext_path . '/' . $name, $this->auth, true); + //logger('FileData returns: ' . print_r($x, true), LOGGER_DATA); if ($x) return true; @@ -565,4 +567,280 @@ class Directory extends DAV\Node implements DAV\ICollection, DAV\IQuota { $free ); } + + + /** + * @brief Array with all Directory and File DAV\Node items for the given path. + * + * + * @param string $file path to a directory + * @param \Zotlabs\Storage\BasicAuth &$auth + * @returns null|array \Sabre\DAV\INode[] + * @throw \Sabre\DAV\Exception\Forbidden + * @throw \Sabre\DAV\Exception\NotFound + */ + + function CollectionData($file, &$auth) { + $ret = array(); + + $x = strpos($file, '/cloud'); + if ($x === 0) { + $file = substr($file, 6); + } + + // return a list of channel if we are not inside a channel + if ((! $file) || ($file === '/')) { + return $this->ChannelList($auth); + } + + $file = trim($file, '/'); + $path_arr = explode('/', $file); + + if (! $path_arr) + return null; + + $channel_name = $path_arr[0]; + + $r = q("SELECT channel_id FROM channel WHERE channel_address = '%s' LIMIT 1", + dbesc($channel_name) + ); + + if (! $r) + return null; + + $channel_id = $r[0]['channel_id']; + $perms = permissions_sql($channel_id); + + $auth->owner_id = $channel_id; + + $path = '/' . $channel_name; + + $folder = ''; + $errors = false; + $permission_error = false; + + for ($x = 1; $x < count($path_arr); $x++) { + $r = q("SELECT id, hash, filename, flags, is_dir FROM attach WHERE folder = '%s' AND filename = '%s' AND uid = %d AND is_dir != 0 $perms LIMIT 1", + dbesc($folder), + dbesc($path_arr[$x]), + intval($channel_id) + ); + if (! $r) { + // path wasn't found. Try without permissions to see if it was the result of permissions. + $errors = true; + $r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 limit 1", + dbesc($folder), + basename($path_arr[$x]), + intval($channel_id) + ); + if ($r) { + $permission_error = true; + } + break; + } + + if ($r && intval($r[0]['is_dir'])) { + $folder = $r[0]['hash']; + $path = $path . '/' . $r[0]['filename']; + } + } + + if ($errors) { + if ($permission_error) { + throw new DAV\Exception\Forbidden('Permission denied.'); + } + else { + throw new DAV\Exception\NotFound('A component of the request file path could not be found.'); + } + } + + // This should no longer be needed since we just returned errors for paths not found + if ($path !== '/' . $file) { + logger("Path mismatch: $path !== /$file"); + return NULL; + } + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $prefix = 'DISTINCT ON (filename)'; + $suffix = 'ORDER BY filename'; + } + else { + $prefix = ''; + $suffix = 'GROUP BY filename'; + } + $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) { + //logger('filename: ' . $rr['filename'], LOGGER_DEBUG); + if (intval($rr['is_dir'])) { + $ret[] = new Directory($path . '/' . $rr['filename'], $auth); + } + else { + $ret[] = new File($path . '/' . $rr['filename'], $rr, $auth); + } + } + + return $ret; + } + + + /** + * @brief Returns an array with viewable channels. + * + * Get a list of Directory objects with all the channels where the visitor + * has <b>view_storage</b> perms. + * + * + * @param BasicAuth &$auth + * @return array Directory[] + */ + + function ChannelList(&$auth) { + $ret = array(); + + $r = q("SELECT channel_id, channel_address FROM channel WHERE channel_removed = 0 + AND channel_system = 0 AND NOT (channel_pageflags & %d)>0", + intval(PAGE_HIDDEN) + ); + + if ($r) { + foreach ($r as $rr) { + if (perm_is_allowed($rr['channel_id'], $auth->observer, 'view_storage')) { + logger('found channel: /cloud/' . $rr['channel_address'], LOGGER_DATA); + // @todo can't we drop '/cloud'? It gets stripped off anyway in RedDirectory + $ret[] = new Directory('/cloud/' . $rr['channel_address'], $auth); + } + } + } + return $ret; + } + + + /** + * @brief + * + * + * @param string $file + * path to file or directory + * @param BasicAuth &$auth + * @param boolean $test (optional) enable test mode + * @return File|Directory|boolean|null + * @throw \Sabre\DAV\Exception\Forbidden + */ + + function FileData($file, &$auth, $test = false) { + logger($file . (($test) ? ' (test mode) ' : ''), LOGGER_DATA); + + $x = strpos($file, '/cloud'); + if ($x === 0) { + $file = substr($file, 6); + } + else { + $x = strpos($file,'/dav'); + if($x === 0) + $file = substr($file,4); + } + + + if ((! $file) || ($file === '/')) { + return new Directory('/', $auth); + } + + $file = trim($file, '/'); + + $path_arr = explode('/', $file); + + if (! $path_arr) + return null; + + $channel_name = $path_arr[0]; + + $r = q("select channel_id from channel where channel_address = '%s' limit 1", + dbesc($channel_name) + ); + + if (! $r) + return null; + + $channel_id = $r[0]['channel_id']; + + $path = '/' . $channel_name; + + $auth->owner_id = $channel_id; + + $permission_error = false; + + $folder = ''; + + require_once('include/security.php'); + $perms = permissions_sql($channel_id); + + $errors = false; + + for ($x = 1; $x < count($path_arr); $x++) { + $r = q("select id, hash, filename, flags, is_dir from attach where folder = '%s' and filename = '%s' and uid = %d and is_dir != 0 $perms", + dbesc($folder), + dbesc($path_arr[$x]), + intval($channel_id) + ); + + if ($r && intval($r[0]['is_dir'])) { + $folder = $r[0]['hash']; + $path = $path . '/' . $r[0]['filename']; + } + if (! $r) { + $r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach + where folder = '%s' and filename = '%s' and uid = %d $perms order by filename limit 1", + dbesc($folder), + dbesc(basename($file)), + intval($channel_id) + ); + } + if (! $r) { + $errors = true; + $r = q("select id, uid, hash, filename, filetype, filesize, revision, folder, flags, is_dir, os_storage, created, edited from attach + where folder = '%s' and filename = '%s' and uid = %d order by filename limit 1", + dbesc($folder), + dbesc(basename($file)), + intval($channel_id) + ); + if ($r) + $permission_error = true; + } + } + + if ($path === '/' . $file) { + if ($test) + return true; + // final component was a directory. + return new Directory($file, $auth); + } + + if ($errors) { + logger('not found ' . $file); + if ($test) + return false; + if ($permission_error) { + logger('permission error ' . $file); + throw new DAV\Exception\Forbidden('Permission denied.'); + } + return; + } + + if ($r) { + if ($test) + return true; + + if (intval($r[0]['is_dir'])) { + return new Directory($path . '/' . $r[0]['filename'], $auth); + } + else { + return new File($path . '/' . $r[0]['filename'], $r[0], $auth); + } + } + return false; + } + } |