aboutsummaryrefslogtreecommitdiffstats
path: root/Zotlabs
diff options
context:
space:
mode:
Diffstat (limited to 'Zotlabs')
-rw-r--r--Zotlabs/Daemon/Expire.php2
-rw-r--r--Zotlabs/Lib/ThreadItem.php2
-rw-r--r--Zotlabs/Module/Cloud.php12
-rw-r--r--Zotlabs/Module/Dav.php2
-rw-r--r--Zotlabs/Module/Dreport.php1
-rw-r--r--Zotlabs/Module/Item.php22
-rw-r--r--Zotlabs/Module/New_channel.php4
-rw-r--r--Zotlabs/Module/Profile_photo.php2
-rw-r--r--Zotlabs/Module/Tagger.php11
-rw-r--r--Zotlabs/Storage/Directory.php286
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;
+ }
+
}