aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorMario <mario@mariovavti.com>2021-01-13 09:50:53 +0000
committerMario <mario@mariovavti.com>2021-01-13 09:50:53 +0000
commit5eefdc6485b2f6082f6fe5dfd6f1731fae7e3a2a (patch)
tree7521f4800e393538d19c393c6f495ea2d41cbf5a /include
parent0bc4c7d1a0e4348018e533be600ad1c648fd97fb (diff)
parent4d2bcbc5837a7d99dc541595ca8087c335242af0 (diff)
downloadvolse-hubzilla-5eefdc6485b2f6082f6fe5dfd6f1731fae7e3a2a.tar.gz
volse-hubzilla-5eefdc6485b2f6082f6fe5dfd6f1731fae7e3a2a.tar.bz2
volse-hubzilla-5eefdc6485b2f6082f6fe5dfd6f1731fae7e3a2a.zip
Merge branch '5.2RC'5.2
Diffstat (limited to 'include')
-rw-r--r--include/acl_selectors.php17
-rw-r--r--include/attach.php388
-rw-r--r--include/cdav.php4
-rw-r--r--include/channel.php2
-rw-r--r--include/connections.php43
-rw-r--r--include/contact_widgets.php36
-rw-r--r--include/dir_fns.php31
-rw-r--r--include/feedutils.php11
-rw-r--r--include/help.php2
-rw-r--r--include/html2plain.php4
-rw-r--r--include/import.php27
-rwxr-xr-xinclude/items.php55
-rw-r--r--include/js_strings.php9
-rw-r--r--include/network.php12
-rw-r--r--include/text.php67
15 files changed, 563 insertions, 145 deletions
diff --git a/include/acl_selectors.php b/include/acl_selectors.php
index a3476439a..8da46649c 100644
--- a/include/acl_selectors.php
+++ b/include/acl_selectors.php
@@ -82,7 +82,6 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
$r = q("SELECT id, hash, gname FROM pgrp WHERE deleted = 0 AND uid = %d ORDER BY gname ASC",
intval(local_channel())
);
-
if($r) {
$groups .= '<optgroup label = "' . t('Privacy Groups').'">';
foreach($r as $rr) {
@@ -110,13 +109,23 @@ function populate_acl($defaults = null,$show_jotnets = true, $emptyACL_descripti
if($dialog_description) {
$forums = get_forum_channels(local_channel(),1);
if($forums) {
- $groups .= '<optgroup label = "' . t('Forums').'">';
+ $forums_count = 0;
+ $forum_otions = '';
foreach($forums as $f) {
+ if($f['no_post_perms'])
+ continue;
+
$private = (($f['private_forum']) ? ' (' . t('Private Forum') . ')' : '');
$selected = (($single_group && $f['hash'] === $allow_cid[0]) ? ' selected = "selected" ' : '');
- $groups .= '<option id="^' . $f['abook_id'] . '" value="^' . $f['xchan_hash'] . '"' . $selected . '>' . $f['xchan_name'] . $private . '</option>' . "\r\n";
+ $forum_otions .= '<option id="^' . $f['abook_id'] . '" value="^' . $f['xchan_hash'] . '"' . $selected . '>' . $f['xchan_name'] . $private . '</option>' . "\r\n";
+ $forums_count++;
}
- $groups .= '</optgroup>';
+ if($forums_count) {
+ $groups .= '<optgroup label = "' . t('Forums').'">';
+ $groups .= $forum_otions;
+ $groups .= '</optgroup>';
+ }
+
}
}
diff --git a/include/attach.php b/include/attach.php
index c9649a4ce..f65f41477 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -300,6 +300,44 @@ function attach_by_hash($hash, $observer_hash, $rev = 0) {
}
+/**
+ * @brief Find an attachment by id.
+ *
+ * Returns the entire attach structure including data.
+ *
+ * This could exhaust memory so most useful only when immediately sending the data.
+ *
+ * @param string $hash
+ * @param string $observer_hash
+ * @return array
+ */
+function attach_by_id($id, $observer_hash) {
+
+ $ret = array('success' => false);
+
+ // Check for existence, which will also provide us the owner uid
+
+ $r = q("SELECT * FROM attach WHERE id = %d",
+ intval($id)
+ );
+ if(! $r) {
+ $ret['message'] = t('Item was not found.');
+ return $ret;
+ }
+
+ if(! attach_can_view($r[0]['uid'], $observer_hash, $r[0]['hash'])) {
+ $ret['message'] = t('Permission denied.');
+ return $ret;
+ }
+
+ $r[0]['content'] = dbunescbin($r[0]['content']);
+
+ $ret['success'] = true;
+ $ret['data'] = $r[0];
+
+ return $ret;
+}
+
function attach_can_view($uid,$ob_hash,$resource) {
$sql_extra = permissions_sql($uid,$ob_hash);
@@ -647,17 +685,15 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$pathname = filepath_macro($newalbum);
}
elseif(array_key_exists('folder',$arr)) {
- $x = q("select filename from attach where hash = '%s' and uid = %d limit 1",
- dbesc($arr['folder']),
- intval($channel['channel_id'])
- );
- if($x)
- $pathname = $x[0]['filename'];
+ $pathname = find_path_by_hash($channel['channel_id'], $arr['folder']);
}
else {
$pathname = filepath_macro($album);
}
}
+ elseif(array_key_exists('folder',$arr)) {
+ $pathname = find_path_by_hash($channel['channel_id'], $arr['folder']);
+ }
if(! $pathname) {
$pathname = filepath_macro($upload_path);
}
@@ -807,6 +843,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
$os_relpath = ltrim($os_relpath,'/');
$os_path = $os_relpath;
+
$display_path = ltrim($pathname . '/' . $filename,'/');
if($src) {
@@ -890,7 +927,6 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
);
}
else {
-
$r = q("INSERT INTO attach ( aid, uid, hash, creator, filename, filetype, folder, filesize, revision, os_storage, is_photo, content, created, edited, os_path, display_path, 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', '%s', '%s' ) ",
intval($channel['channel_account_id']),
@@ -1122,7 +1158,6 @@ function attach_mkdir($channel, $observer_hash, $arr = null) {
if(! is_dir($os_basepath))
os_mkdir($os_basepath,STORAGE_DEFAULT_PERMISSIONS, true);
-
$os_basepath .= '/';
if(! perm_is_allowed($channel_id, $observer_hash, 'write_storage')) {
@@ -1432,7 +1467,7 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
$channel_address = (($c) ? $c[0]['channel_address'] : 'notfound');
$photo_sql = (($is_photo) ? " and is_photo = 1 " : '');
- $r = q("SELECT hash, os_storage, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
+ $r = q("SELECT id, hash, os_storage, flags, is_dir, is_photo, folder FROM attach WHERE hash = '%s' AND uid = %d $photo_sql limit 1",
dbesc($resource),
intval($channel_id)
);
@@ -1453,6 +1488,12 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
return;
}
+ q("DELETE FROM term WHERE uid = %d AND oid = %d AND otype = %d",
+ intval($channel_id),
+ intval($r[0]['id']),
+ intval(TERM_OBJ_FILE)
+ );
+
// 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",
@@ -1534,7 +1575,7 @@ function attach_drop_photo($channel_id,$resource) {
$interactive = (($x[0]['item_hidden']) ? false : true);
drop_item($x[0]['id'], $interactive, $stage);
}
-
+
$r = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1",
dbesc($resource),
intval($channel_id)
@@ -1544,7 +1585,7 @@ function attach_drop_photo($channel_id,$resource) {
@unlink(dbunescbin($i['content']));
}
}
-
+
q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
intval($channel_id),
dbesc($resource)
@@ -1741,6 +1782,29 @@ function find_filename_by_hash($channel_id, $attachHash) {
}
/**
+ * @brief Returns the display_path of an attachment in a given channel.
+ *
+ * @param int $channel_id
+ * The id of the channel
+ * @param string $attachHash
+ * The hash of the attachment
+ * @return string
+ * The filename of the attachment
+ */
+function find_path_by_hash($channel_id, $attachHash) {
+ $r = q("SELECT display_path FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1",
+ intval($channel_id),
+ dbesc($attachHash)
+ );
+ $display_path = '';
+ if ($r) {
+ $display_path = $r[0]['display_path'];
+ }
+
+ return $display_path;
+}
+
+/**
* @brief Pipes $in to $out in 16KB chunks.
*
* @param resource $in File pointer of input
@@ -2306,6 +2370,18 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
$r[0]['content'] = dbunescbin($r[0]['content']);
$hash_ptr = $r[0]['folder'];
+
+ $r[0]['term'] = [];
+
+ $term = q("SELECT * FROM term WHERE uid = %d AND oid = %d AND otype = %d",
+ intval($channel['channel_id']),
+ intval($r[0]['id']),
+ intval(TERM_OBJ_FILE)
+ );
+
+ if ($term)
+ $r[0]['term'] = array_reverse($term);
+
$paths[] = $r[0];
} while($hash_ptr);
@@ -2314,7 +2390,6 @@ function attach_export_data($channel, $resource_id, $deleted = false) {
$ret['attach'] = $paths;
-
if($attach_ptr['is_photo']) {
// This query could potentially result in a few megabytes of data use.
@@ -2495,7 +2570,7 @@ function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpat
return true;
}
/**
- * This function performs an in place directory-to-directory move of a stored attachment or photo.
+ * This function performs an in place directory-to-directory move of a stored resource.
* The data is physically moved in the store/nickname storage location and the paths adjusted
* in the attach structure (and if applicable the photo table). The new 'album name' is recorded
* for photos and will show up immediately there.
@@ -2507,60 +2582,64 @@ function copy_folder_to_cloudfiles($channel, $observer_hash, $srcpath, $cloudpat
* @param int $channel_id
* @param int $resource_id
* @param string $new_folder_hash
- * @return void|boolean
+ * @param (optional) string $newname
+ * @param (optional) boolean $recurse
+ * @return array Associative array with:
+ * * \e boolean \b success
+ * * \e string \b resource_id
*/
-function attach_move($channel_id, $resource_id, $new_folder_hash) {
+function attach_move($channel_id, $resource_id, $new_folder_hash, $newname = '', $recurse = true) {
+
+ $ret = [
+ 'success' => false,
+ 'resource_id' => $resource_id
+ ];
$c = channelx_by_n($channel_id);
if(! ($c && $resource_id))
- return false;
-
+ return $ret;
// find the resource to be moved
-
$r = q("select * from attach where hash = '%s' and uid = %d limit 1",
dbesc($resource_id),
intval($channel_id)
);
if(! $r) {
logger('resource_id not found');
- return false;
+ return $ret;
}
$oldstorepath = dbunescbin($r[0]['content']);
-
// find the resource we are moving to
-
if($new_folder_hash) {
$n = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1",
dbesc($new_folder_hash),
intval($channel_id)
);
if(! $n)
- return false;
+ return $ret;
+ $newdirname = $n[0]['filename'];
$newalbumname = $n[0]['display_path'];
$newstorepath = dbunescbin($n[0]['content']) . '/' . $resource_id;
}
else {
-
// root directory
-
+ $newdirname = EMPTY_STR;
$newalbumname = EMPTY_STR;
$newstorepath = 'store/' . $c['channel_address'] . '/' . $resource_id;
}
- rename($oldstorepath,$newstorepath);
-
- // duplicate detection. If 'overwrite' is specified, return false because we can't yet do that.
-
- $filename = $r[0]['filename'];
-
- // don't do duplicate check unless our parent folder has changed.
+ if ($recurse) {
+ rename($oldstorepath,$newstorepath);
+ }
- if($r[0]['folder'] !== $new_folder_hash) {
+ $oldfilename = $r[0]['filename'];
+ $filename = (($newname) ? basename($newname) : $oldfilename);
+ // duplicate detection.
+ if($recurse) {
$s = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
dbesc($filename),
dbesc($new_folder_hash)
@@ -2568,9 +2647,10 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
if($s) {
$overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
+ // If 'overwrite' is specified, return false because we can't yet do that.
if($overwrite) {
/// @fixme
- return;
+ return $ret;
}
else {
if(strpos($filename,'.') !== false) {
@@ -2586,7 +2666,8 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
if(preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches))
$basename = $matches[1];
- $v = q("select filename from attach where ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
+ $v = q("select filename from attach where uid = %d and ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
+ intval($channel_id),
dbesc($basename . $ext),
dbesc($basename . '(%)' . $ext),
dbesc($new_folder_hash)
@@ -2609,12 +2690,14 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
while($found);
$filename = $basename . '(' . $x . ')' . $ext;
}
- else
+ else {
$filename = $basename . $ext;
+ }
}
}
}
+
q("update attach set content = '%s', folder = '%s', filename = '%s' where id = %d",
dbescbin($newstorepath),
dbesc($new_folder_hash),
@@ -2631,7 +2714,6 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
intval($r[0]['id'])
);
-
if($r[0]['is_photo']) {
q("update photo set album = '%s', filename = '%s', os_path = '%s', display_path = '%s'
where resource_id = '%s' and uid = %d",
@@ -2643,11 +2725,24 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
intval($channel_id)
);
- q("update photo set content = '%s' where resource_id = '%s' and uid = %d and imgscale = 0",
+ q("update photo set content = CASE imgscale WHEN 0 THEN '%s' ELSE CONCAT('%s', '-', imgscale) END where resource_id = '%s' and uid = %d and os_storage = 1",
+ dbescbin($newstorepath),
dbescbin($newstorepath),
dbesc($resource_id),
intval($channel_id)
);
+
+ // now rename the thumbnails in os_storage - the original should have been copied before already
+ $ps = q("SELECT content, imgscale FROM photo WHERE uid = %d AND resource_id = '%s' and imgscale > 0 and os_storage = 1",
+ intval($channel_id),
+ dbesc($resource_id)
+ );
+
+ if ($recurse) {
+ foreach($ps as $p) {
+ rename($oldstorepath . '-' . $p['imgscale'], $p['content']);
+ }
+ }
}
if($r[0]['is_dir']) {
@@ -2658,19 +2753,223 @@ function attach_move($channel_id, $resource_id, $new_folder_hash) {
);
if($x) {
foreach($x as $xv) {
- $rs = attach_move($channel_id,$xv['hash'],$r[0]['hash']);
- if(! $rs) {
+ $rs = attach_move($channel_id, $xv['hash'], $r[0]['hash'], '', false);
+ if(! $rs['success']) {
$move_success = false;
break;
}
}
}
- return $move_success;
+
+ $ret['success'] = $move_success;
+ return $ret;
}
- return true;
+ $ret['success'] = true;
+ return $ret;
}
+/**
+ * This function performs an in place directory-to-directory copy of a stored resource.
+ * The data is physically copyed in the store/nickname storage location and the paths adjusted
+ * in the attach structure (and if applicable the photo table). The new 'album name' is recorded
+ * for photos and will show up immediately there.
+ * This takes a channel_id, attach.hash of the file to copy (this is the same as a photo resource_id), and
+ * the attach.hash of the new parent folder, which must already exist. If $new_folder_hash is blank or empty,
+ * the new file is copyed to the root of the channel's storage area.
+ *
+ *
+ * @param int $channel_id
+ * @param int $resource_id
+ * @param string $new_folder_hash
+ * @param (optional) string $newname
+ * @param (optional) boolean $recurse
+ * @return array Associative array with:
+ * * \e boolean \b success
+ * * \e string \b resource_id of the new resource
+ */
+function attach_copy($channel_id, $resource_id, $new_folder_hash, $newname = '', $recurse = true) {
+
+ $ret = [
+ 'success' => false,
+ 'resource_id' => ''
+ ];
+
+ $c = channelx_by_n($channel_id);
+ if(! ($c && $resource_id))
+ return $ret;
+
+ // find the resource to be copied
+ $r = q("select * from attach where hash = '%s' and uid = %d limit 1",
+ dbesc($resource_id),
+ intval($channel_id)
+ );
+ if(! $r) {
+ logger('resource_id not found');
+ return $ret;
+ }
+
+ $a = $r[0];
+ $new_resource_id = new_uuid();
+
+ $ret['resource_id'] = $new_resource_id;
+
+ $oldstorepath = dbunescbin($r[0]['content']);
+
+ // find the resource we are copying to
+ if($new_folder_hash) {
+ $n = q("select * from attach where hash = '%s' and uid = %d and is_dir = 1 limit 1",
+ dbesc($new_folder_hash),
+ intval($channel_id)
+ );
+ if(! $n) {
+ logger('new_folder_hash not found');
+ return $ret;
+ }
+
+ $newdirname = $n[0]['filename'];
+ $newalbumname = $n[0]['display_path'];
+ $newstorepath = dbunescbin($n[0]['content']) . '/' . $new_resource_id;
+ }
+ else {
+ // root directory
+ $newdirname = EMPTY_STR;
+ $newalbumname = EMPTY_STR;
+ $newstorepath = 'store/' . $c['channel_address'] . '/' . $new_resource_id;
+ }
+
+ if(is_dir($oldstorepath)) {
+ os_mkdir($newstorepath,STORAGE_DEFAULT_PERMISSIONS,true);
+ }
+ else {
+ copy($oldstorepath,$newstorepath);
+ }
+
+ $oldfilename = $r[0]['filename'];
+ $filename = (($newname) ? basename($newname) : $oldfilename);
+
+ // duplicate detection. If 'overwrite' is specified, return false because we can't yet do that.
+ if($recurse) {
+ $s = q("select filename, id, hash, filesize from attach where filename = '%s' and folder = '%s' ",
+ dbesc($filename),
+ dbesc($new_folder_hash)
+ );
+
+ if($s) {
+ $overwrite = get_pconfig($channel_id,'system','overwrite_dup_files');
+ if($overwrite) {
+ /// @fixme
+ return $ret;
+ }
+ else {
+ if(strpos($filename,'.') !== false) {
+ $basename = substr($filename,0,strrpos($filename,'.'));
+ $ext = substr($filename,strrpos($filename,'.'));
+ }
+ else {
+ $basename = $filename;
+ $ext = '';
+ }
+
+ $matches = false;
+ if(preg_match('/(.*?)\([0-9]{1,}\)$/',$basename,$matches))
+ $basename = $matches[1];
+
+ $v = q("select filename from attach where uid = %d and ( filename = '%s' OR filename like '%s' ) and folder = '%s' ",
+ intval($channel_id),
+ dbesc($basename . $ext),
+ dbesc($basename . '(%)' . $ext),
+ dbesc($new_folder_hash)
+ );
+
+ if($v) {
+ $x = 1;
+
+ do {
+ $found = false;
+ foreach($v as $vv) {
+ if($vv['filename'] === $basename . '(' . $x . ')' . $ext) {
+ $found = true;
+ break;
+ }
+ }
+ if($found)
+ $x++;
+ }
+ while($found);
+ $filename = $basename . '(' . $x . ')' . $ext;
+ }
+ else {
+ $filename = $basename . $ext;
+ }
+ }
+ }
+ }
+
+ unset($a['id']);
+ $a['hash'] = $new_resource_id;
+ $a['content'] = $newstorepath;
+ $a['folder'] = $new_folder_hash;
+ $a['filename'] = $filename;
+
+ create_table_from_array('attach', $a, ['content']);
+
+ $x = attach_syspaths($channel_id, $new_resource_id);
+
+ q("update attach set os_path = '%s', display_path = '%s' where hash = '%s'",
+ dbesc($x['os_path']),
+ dbesc($x['path']),
+ dbesc($new_resource_id)
+ );
+
+ if($a['is_photo']) {
+
+ $ps = q("SELECT * FROM photo WHERE uid = %d AND resource_id = '%s'",
+ intval($channel_id),
+ dbesc($resource_id)
+ );
+
+ foreach($ps as $p) {
+ unset($p['id']);
+ $p['resource_id'] = $new_resource_id;
+ $p['album'] = $newalbumname;
+ $p['filename'] = $filename;
+ $p['os_path'] = $x['os_path'];
+ $p['display_path'] = $x['path'];
+ if($p['os_storage']) {
+ $p['content'] = (($p['imgscale'] == 0) ? $newstorepath : $newstorepath . '-' . $p['imgscale']);
+
+ //the original should have been copied before already
+ if($p['imgscale'] > 0)
+ copy($oldstorepath, $p['content']);
+ }
+ create_table_from_array('photo', $p, ['content']);
+ }
+ }
+
+ if($r[0]['is_dir']) {
+ $copy_success = true;
+ $x = q("select hash from attach where folder = '%s' and uid = %d",
+ dbesc($r[0]['hash']),
+ intval($channel_id)
+ );
+ if($x) {
+ foreach($x as $xv) {
+ $rs = attach_copy($channel_id,$xv['hash'],$new_resource_id, '', false);
+ if(! $rs['success']) {
+ $copy_success = false;
+ break;
+ }
+ }
+ }
+
+ $ret['success'] = $copy_success;
+ return $ret;
+ }
+
+ $ret['success'] = true;
+ return $ret;
+}
/**
* Used to generate a select input box of all your folders
@@ -2688,10 +2987,7 @@ function attach_folder_select_list($channel_id) {
if($r) {
foreach($r as $rv) {
- $x = attach_folder_rpaths($r,$rv);
- if($x) {
- $out[$x[0]] = $x[1];
- }
+ $out[$rv['hash']] = $rv['display_path'];
}
}
@@ -2721,7 +3017,7 @@ function attach_folder_rpaths($all_folders,$that_folder) {
if(! $found)
$error = true;
}
- while((! $found) && (! $error) && ($parent_hash != ''));
+ while((! $error) && ($parent_hash != ''));
}
return (($error) ? false : [ $current_hash , $path ]);
diff --git a/include/cdav.php b/include/cdav.php
index ef248a9fe..fcce0ec4a 100644
--- a/include/cdav.php
+++ b/include/cdav.php
@@ -111,7 +111,7 @@ function process_cdav_card($f, &$vcard, $edit = false) {
function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backend, &$ids, $notice = false) {
$i = 0;
- $newid = (count($ids) ? false : true);
+ $newid = (count($ids) ? false : true);
while ($object = $objects->getNext()) {
@@ -161,7 +161,7 @@ function import_cdav_card($id, $ext, $table, $column, $objects, $profile, $backe
);
}
- if($notice && $exp == 'vcf') {
+ if($notice && $ext == 'vcf') {
notice(
'<strong>' . t('INVALID CARD DISMISSED!') . '</strong>' . EOL .
'<strong>' . t('Name: ') . '</strong>' . (($object->FN) ? $object->FN : t('Unknown')) . EOL .
diff --git a/include/channel.php b/include/channel.php
index d610a0b9a..2d79cd074 100644
--- a/include/channel.php
+++ b/include/channel.php
@@ -651,7 +651,7 @@ function change_channel_keys($channel) {
foreach($h as $hv) {
$hv['hubloc_guid_sig'] = $sig;
$hv['hubloc_hash'] = $hash;
- $hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$modifed['channel_prvkey']));
+ $hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$modified['channel_prvkey']));
hubloc_store_lowlevel($hv);
}
}
diff --git a/include/connections.php b/include/connections.php
index a5a3fc3ce..99a4cc71e 100644
--- a/include/connections.php
+++ b/include/connections.php
@@ -71,7 +71,7 @@ function abook_connections($channel_id, $sql_conditions = '') {
intval($channel_id)
);
return(($r) ? $r : array());
-}
+}
function abook_self($channel_id) {
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d
@@ -79,7 +79,7 @@ function abook_self($channel_id) {
intval($channel_id)
);
return(($r) ? $r[0] : array());
-}
+}
function vcard_from_xchan($xchan, $observer = null, $mode = '') {
@@ -119,14 +119,15 @@ function vcard_from_xchan($xchan, $observer = null, $mode = '') {
if(array_key_exists('channel_id',$xchan))
App::$profile_uid = $xchan['channel_id'];
- $url = (($observer)
- ? z_root() . '/magic?f=&owa=1&bdest=' . bin2hex($xchan['xchan_url']) . '&addr=' . $xchan['xchan_addr']
+ $url = (($observer)
+ ? z_root() . '/magic?f=&owa=1&bdest=' . bin2hex($xchan['xchan_url']) . '&addr=' . $xchan['xchan_addr']
: $xchan['xchan_url']
);
-
+
return replace_macros(get_markup_template('xchan_vcard.tpl'),array(
'$name' => $xchan['xchan_name'],
- '$photo' => ((is_array(App::$profile) && array_key_exists('photo',App::$profile)) ? App::$profile['photo'] : $xchan['xchan_photo_l']),
+ '$addr' => (($xchan['xchan_addr']) ? $xchan['xchan_addr'] : $xchan['xchan_url']),
+ '$photo' => $xchan['xchan_photo_m'],
'$follow' => (($xchan['xchan_addr']) ? $xchan['xchan_addr'] : $xchan['xchan_url']),
'$link' => zid($xchan['xchan_url']),
'$connect' => $connect,
@@ -177,10 +178,10 @@ function abook_toggle_flag($abook,$flag) {
);
- // if unsetting the archive bit, update the timestamps so we'll try to connect for an additional 30 days.
+ // if unsetting the archive bit, update the timestamps so we'll try to connect for an additional 30 days.
if(($flag === ABOOK_FLAG_ARCHIVED) && (intval($abook['abook_archived']))) {
- $r = q("update abook set abook_connected = '%s', abook_updated = '%s'
+ $r = q("update abook set abook_connected = '%s', abook_updated = '%s'
where abook_id = %d and abook_channel = %d",
dbesc(datetime_convert()),
dbesc(datetime_convert()),
@@ -210,7 +211,7 @@ function mark_orphan_hubsxchans() {
if($dirmode == DIRECTORY_MODE_NORMAL)
return;
- $r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0
+ $r = q("update hubloc set hubloc_error = 1 where hubloc_error = 0
and hubloc_network = 'zot' and hubloc_connected < %s - interval %s",
db_utcnow(), db_quoteinterval('36 day')
);
@@ -301,9 +302,9 @@ function remove_all_xchan_resources($xchan, $channel_id = 0) {
);
// Cannot delete just one side of the conversation since we do not allow
- // you to block private mail replies. This would leave open a gateway for abuse.
+ // you to block private mail replies. This would leave open a gateway for abuse.
// Both participants are owners of the conversation and both can remove it.
-
+
$r = q("delete from mail where ( from_xchan = '%s' or to_xchan = '%s' )",
dbesc($xchan),
dbesc($xchan)
@@ -356,7 +357,7 @@ function contact_remove($channel_id, $abook_id) {
call_hooks('connection_remove',$x);
- $archive = get_pconfig($channel_id, 'system','archive_removed_contacts');
+ $archive = get_pconfig($channel_id, 'system', 'archive_removed_contacts');
if($archive) {
q("update abook set abook_archived = 1 where abook_id = %d and abook_channel = %d",
intval($abook_id),
@@ -387,7 +388,7 @@ function contact_remove($channel_id, $abook_id) {
$already_saved = [];
foreach($r as $rr) {
$w = $x = $y = null;
-
+
// optimise so we only process newly seen parent items
if (in_array($rr['parent'],$already_saved)) {
continue;
@@ -423,7 +424,7 @@ function contact_remove($channel_id, $abook_id) {
drop_item($rr['id'],false);
}
}
-
+
q("delete from abook where abook_id = %d and abook_channel = %d",
intval($abook['abook_id']),
intval($channel_id)
@@ -501,17 +502,17 @@ function update_vcard($arr,$vcard = null) {
$fn = $arr['fn'];
-
+
// This isn't strictly correct and could be a cause for concern.
// 'N' => array_reverse(explode(' ', $fn))
- // What we really want is
+ // What we really want is
// 'N' => Adams;John;Quincy;Reverend,Dr.;III
// which is a very difficult parsing problem especially if you allow
// the surname to contain spaces. The only way to be sure to get it
- // right is to provide a form to input all the various fields and not
- // try to extract it from the FN.
+ // right is to provide a form to input all the various fields and not
+ // try to extract it from the FN.
if(! $vcard) {
$vcard = new \Sabre\VObject\Component\VCard([
@@ -689,12 +690,12 @@ function get_vcard_array($vc,$id) {
if(is_array($entry['address'])) {
array_walk($entry['address'],'array_escape_tags');
}
- else {
+ else {
$entry['address'] = (string) escape_tags($entry['address']);
}
$adrs[] = $entry;
-
+
}
}
@@ -768,7 +769,7 @@ function vcard_query(&$r) {
if($a) {
foreach($a as $av) {
for($x = 0; $x < count($r); $x ++) {
- if($r[$x]['abook_xchan'] == $av['xchan']) {
+ if($r[$x]['abook_xchan'] == $av['xchan']) {
$vctmp = \Sabre\VObject\Reader::read($av['v']);
$r[$x]['vcard'] = (($vctmp) ? get_vcard_array($vctmp,$r[$x]['abook_id']) : [] );
}
diff --git a/include/contact_widgets.php b/include/contact_widgets.php
index 626a825b2..3b22a3c6d 100644
--- a/include/contact_widgets.php
+++ b/include/contact_widgets.php
@@ -93,7 +93,7 @@ function categories_widget($baseurl,$selected = '') {
dbesc(ACTIVITY_UPDATE)
);
}
- else
+ else
$r = unserialize($content);
$terms = array();
@@ -206,6 +206,40 @@ function articlecategories_widget($baseurl,$selected = '') {
return '';
}
+function filecategories_widget($baseurl,$selected = '') {
+
+ $perms = permissions_sql(App::$profile['profile_uid']);
+
+ $terms = array();
+ $r = q("select distinct(term.term)
+ from term join attach on term.oid = attach.id
+ where attach.uid = %d
+ and term.uid = attach.uid
+ and term.ttype = %d
+ and term.otype = %d
+ $perms
+ order by term.term asc",
+ intval(App::$profile['profile_uid']),
+ intval(TERM_CATEGORY),
+ intval(TERM_OBJ_FILE)
+ );
+
+ if($r && count($r)) {
+ foreach($r as $rr)
+ $terms[] = array('name' => $rr['term'], 'selected' => (($selected == $rr['term']) ? 'selected' : ''));
+
+ return replace_macros(get_markup_template('categories_widget.tpl'),array(
+ '$title' => t('Categories'),
+ '$desc' => '',
+ '$sel_all' => (($selected == '') ? 'selected' : ''),
+ '$all' => t('Everything'),
+ '$terms' => $terms,
+ '$base' => $baseurl,
+ ));
+ }
+
+ return '';
+}
function common_friends_visitor_widget($profile_uid,$cnt = 25) {
diff --git a/include/dir_fns.php b/include/dir_fns.php
index f477b35dd..88a1bb74f 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -16,7 +16,6 @@ require_once('include/permissions.php');
* @return array
*/
function find_upstream_directory($dirmode) {
- global $DIRECTORY_FALLBACK_SERVERS;
$preferred = get_config('system','directory_server');
@@ -28,7 +27,7 @@ function find_upstream_directory($dirmode) {
);
if(($r) && ($r[0]['site_flags'] & DIRECTORY_MODE_STANDALONE)) {
$preferred = '';
- }
+ }
}
@@ -39,14 +38,16 @@ function find_upstream_directory($dirmode) {
* from our list of directory servers. However, if we're a directory
* server ourself, point at the local instance
* We will then set this value so this should only ever happen once.
- * Ideally there will be an admin setting to change to a different
+ * Ideally there will be an admin setting to change to a different
* directory server if you don't like our choice or if circumstances change.
*/
+ $directory_fallback_servers = get_directory_fallback_servers();
+
$dirmode = intval(get_config('system','directory_mode'));
if ($dirmode == DIRECTORY_MODE_NORMAL) {
- $toss = mt_rand(0,count($DIRECTORY_FALLBACK_SERVERS));
- $preferred = $DIRECTORY_FALLBACK_SERVERS[$toss];
+ $toss = mt_rand(0,count($directory_fallback_servers));
+ $preferred = $directory_fallback_servers[$toss];
set_config('system','directory_server',$preferred);
} else{
set_config('system','directory_server',z_root());
@@ -94,7 +95,7 @@ function get_directory_setting($observer, $setting) {
$ret = get_config('directory', $setting);
- // 'safemode' is the default if there is no observer or no established preference.
+ // 'safemode' is the default if there is no observer or no established preference.
if($setting == 'safemode' && $ret === false)
$ret = 1;
@@ -152,8 +153,8 @@ function dir_sort_links() {
*
* Checks the directory mode of this hub to see if it is some form of directory server. If it is,
* get the directory realm of this hub. Fetch a list of all other directory servers in this realm and request
- * a directory sync packet. This will contain both directory updates and new ratings. Store these all in the DB.
- * In the case of updates, we will query each of them asynchronously from a poller task. Ratings are stored
+ * a directory sync packet. This will contain both directory updates and new ratings. Store these all in the DB.
+ * In the case of updates, we will query each of them asynchronously from a poller task. Ratings are stored
* directly if the rater's signature matches.
*
* @param int $dirmode;
@@ -189,7 +190,7 @@ function sync_directories($dirmode) {
[
'site_url' => DIRECTORY_FALLBACK_MASTER,
'site_flags' => DIRECTORY_MODE_PRIMARY,
- 'site_update' => NULL_DATE,
+ 'site_update' => NULL_DATE,
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
'site_realm' => DIRECTORY_REALM,
'site_valid' => 1,
@@ -335,11 +336,11 @@ function update_directory_entry($ud) {
// modify the directory search to only return zot6 entries, and also modify this function
// to *only* fetch the zot6 entries.
// Otherwise we'll be showing duplicates or have a mostly empty directory for a good chunk of
- // the transition period. Directory server load will likely increase "moderately" during this transition.
- // The one month counter begins when the primary directory has upgraded to a release which uses this code.
+ // the transition period. Directory server load will likely increase "moderately" during this transition.
+ // The one month counter begins when the primary directory has upgraded to a release which uses this code.
// Hubzilla channels running traditional zot which have not upgraded can or will be dropped from the directory or
// "not found" at the end of the transition period as the directory will only serve zot6 entries at that time.
-
+
$uri = Webfinger::zot_url($ud['ud_addr']);
if($uri) {
$record = Zotfinger::exec($uri);
@@ -347,8 +348,8 @@ function update_directory_entry($ud) {
// Check the HTTP signature
$hsig = $record['signature'];
- if($hsig && $hsig['signer'] === $url && $hsig['header_valid'] === true && $hsig['content_valid'] === true) {
- $x = \Zotlabs\Lib\Libzot::import_xchan($record['data'], 0, $ud);
+ if($hsig && $hsig['signer'] === $uri && $hsig['header_valid'] === true && $hsig['content_valid'] === true) {
+ $x = Libzot::import_xchan($record['data'], 0, $ud);
if($x['success']) {
$success = true;
}
@@ -394,7 +395,7 @@ function local_dir_update($uid, $force) {
$profile['description'] = $p[0]['pdesc'];
$profile['birthday'] = $p[0]['dob'];
- if ($age = age($p[0]['dob'],$p[0]['channel_timezone'],''))
+ if ($age = age($p[0]['dob'],$p[0]['channel_timezone'],''))
$profile['age'] = $age;
$profile['gender'] = $p[0]['gender'];
diff --git a/include/feedutils.php b/include/feedutils.php
index 5f5f563f8..352b8f038 100644
--- a/include/feedutils.php
+++ b/include/feedutils.php
@@ -14,9 +14,6 @@
* @return string with an atom feed
*/
-use Ramsey\Uuid\Uuid;
-use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
-
function get_public_feed($channel, $params) {
if(! $params)
@@ -435,13 +432,7 @@ function get_atom_elements($feed, $item) {
$res['plink'] = unxmlify($item->get_link(0));
$res['item_rss'] = 1;
- try {
- $uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, $res['plink'])->toString();
- } catch (UnsatisfiedDependencyException $e) {
- $uuid = md5($res['plink']);
- }
-
- $res['uuid'] = $uuid;
+ $res['uuid'] = uuid_from_url($res['plink']);
$summary = unxmlify($item->get_description(true));
diff --git a/include/help.php b/include/help.php
index affe64495..ebf1ccc08 100644
--- a/include/help.php
+++ b/include/help.php
@@ -299,7 +299,7 @@ function load_context_help() {
break;
array_pop($args);
- $path = implode($args,'/');
+ $path = implode('/', $args);
}
return $context_help;
diff --git a/include/html2plain.php b/include/html2plain.php
index 979354079..fde70bd01 100644
--- a/include/html2plain.php
+++ b/include/html2plain.php
@@ -40,7 +40,7 @@ function breaklines($line, $level, $wraplength = 75)
$newlines[] = $line;
- return(implode($newlines, "\n"));
+ return(implode("\n", $newlines));
}
function quotelevel($message, $wraplength = 75)
@@ -73,7 +73,7 @@ function quotelevel($message, $wraplength = 75)
if (!$startquote or ($line != ''))
$newlines[] = breaklines($line, $currlevel, $wraplength);
}
- return(implode($newlines, "\n"));
+ return(implode("\n", $newlines));
}
function collecturls($message) {
diff --git a/include/import.php b/include/import.php
index 831a0f257..b512e1f11 100644
--- a/include/import.php
+++ b/include/import.php
@@ -1208,6 +1208,9 @@ function sync_files($channel, $files) {
continue;
}
+ $term = $att['term'];
+ unset($att['term']);
+
$attach_exists = false;
$x = attach_by_hash($att['hash'],$channel['channel_hash']);
logger('sync_files duplicate check: attach_exists=' . $attach_exists, LOGGER_DEBUG);
@@ -1352,17 +1355,35 @@ function sync_files($channel, $files) {
}
$redirects = 0;
-
$headers = [];
$headers['Accept'] = 'application/x-zot+json' ;
$headers['Sigtoken'] = random_string();
- $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], 'acct:' . channel_reddress($channel),true,'sha512');
+ $headers = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), true, 'sha512');
$x = z_post_url($fetch_url,$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]);
fclose($fp);
if($x['success']) {
$attachment_stored = true;
+
+ $a = q("SELECT id FROM attach WHERE hash = '%s' AND uid = %d LIMIT 1",
+ dbesc($att['hash']),
+ intval($channel['channel_id'])
+ );
+ if($a) {
+ q("DELETE FROM term WHERE uid = %d AND oid = %d AND otype = %d",
+ intval($channel['channel_id']),
+ intval($a[0]['id']),
+ intval(TERM_OBJ_FILE)
+ );
+ if($term) {
+ foreach($term as $t) {
+ if(array_key_exists('type',$t))
+ $t['ttype'] = $t['type'];
+ store_item_tag($channel['channel_id'], $a[0]['id'], TERM_OBJ_FILE, $t['ttype'], escape_tags($t['term']), escape_tags($t['url']));
+ }
+ }
+ }
}
continue;
}
@@ -1442,7 +1463,7 @@ function sync_files($channel, $files) {
$headers = [];
$headers['Accept'] = 'application/x-zot+json' ;
$headers['Sigtoken'] = random_string();
- $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'],'acct:' . channel_reddress($channel),true,'sha512');
+ $headers = HTTPSig::create_sig($headers, $channel['channel_prvkey'], channel_url($channel), true, 'sha512');
$x = z_post_url($fetch_url,$parr,$redirects,[ 'filep' => $fp, 'headers' => $headers]);
fclose($fp);
diff --git a/include/items.php b/include/items.php
index cf2491319..317a84730 100755
--- a/include/items.php
+++ b/include/items.php
@@ -1551,7 +1551,7 @@ function get_mail_elements($x) {
$arr['expires'] = datetime_convert('UTC','UTC',$x['expires']);
$arr['mail_flags'] = 0;
-
+
if(array_key_exists('sig',$x))
$arr['sig'] = $x['sig'];
@@ -2206,6 +2206,7 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) {
return $ret;
}
+
// override the unseen flag with the original
$arr['item_unseen'] = $orig[0]['item_unseen'];
@@ -2672,6 +2673,11 @@ function tag_deliver($uid, $item_id) {
}
if ($is_group && intval($item['item_private']) === 2 && intval($item['item_thread_top'])) {
+
+ // do not turn the groups own direkt messages into group items
+ if($item['item_wall'] && $item['author_xchan'] === $u[0]['channel_hash'])
+ return;
+
// group delivery via DM
if(perm_is_allowed($uid,$item['owner_xchan'],'post_wall') || perm_is_allowed($uid,$item['owner_xchan'],'tag_deliver')) {
logger('group DM delivery for ' . $u[0]['channel_address']);
@@ -2682,6 +2688,12 @@ function tag_deliver($uid, $item_id) {
if ($is_group && intval($item['item_thread_top']) && intval($item['item_wall']) && $item['author_xchan'] !== $item['owner_xchan']) {
+
+ if($item['resource_type'] === 'group_item') {
+ logger('resource_type group_item: already shared');
+ return;
+ }
+
if (strpos($item['body'],'[/share]')) {
logger('W2W post already shared');
return;
@@ -2813,7 +2825,7 @@ function tag_deliver($uid, $item_id) {
// standard forum tagging sequence !forumname
-
+/*
$forumpattern = '/\!\!?\[[uz]rl\=([^\]]*?)\]((?:.(?!\[[uz]rl\=))*?)\[\/[uz]rl\]/';
$forumpattern2 = '/\[[uz]rl\=([^\]]*?)\]\!((?:.(?!\[[uz]rl\=))*?)\[\/[uz]rl\]/';
@@ -2847,6 +2859,8 @@ function tag_deliver($uid, $item_id) {
}
}
+*/
+
if(! ($tagged || $plustagged)) {
logger('Mention was in a reshare or exceeded max_tagged_forums - ignoring');
continue;
@@ -3022,7 +3036,7 @@ function tgroup_check($uid, $item) {
}
// post to group via DM
-
+
if ($is_group) {
if (intval($item['item_private']) === 2 && $item['mid'] === $item['parent_mid']) {
return true;
@@ -3076,7 +3090,7 @@ function tgroup_check($uid, $item) {
$body = preg_replace('/\[share(.*?)\[\/share\]/','',$item['body']);
-
+/*
$forumpattern = '/\!\!?\[zrl\=([^\]]*?)\]((?:.(?!\[zrl\=))*?)\[\/zrl\]/';
$forumpattern2 = '/\[zrl\=([^\]]*?)\]\!((?:.(?!\[zrl\=))*?)\[\/zrl\]/';
@@ -3116,6 +3130,7 @@ function tgroup_check($uid, $item) {
logger('tgroup_check: mention was in a reshare or exceeded max_tagged_forums - ignoring');
continue;
}
+*/
return true;
}
@@ -3199,18 +3214,20 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false
if ($group && (! $parent)) {
$arr = [];
-
+
if ($edit) {
+
// process edit or delete action
- $r = q("select * from item where source_xchan = '%s' and body like '%s' and uid = %d limit 1",
- dbesc($item['owner_xchan']),
- dbesc("%message_id='" . $item['mid'] . "'%"),
- intval($channel['channel_id'])
+ $r = q("select * from item where uid = %d and resource_id = '%s' and source_xchan = '%s' and resource_type = 'group_item' limit 1",
+ intval($channel['channel_id']),
+ dbesc($item['mid']),
+ dbesc($item['author_xchan'])
);
+
if ($r) {
if (intval($item['item_deleted'])) {
- drop_item($r[0]['id'],false,DROPITEM_PHASE1);
- Master::Summon([ 'Notifier','drop',$r[0]['id'] ]);
+ drop_item($r[0]['id'], false, DROPITEM_PHASE1);
+ Master::Summon([ 'Notifier', 'drop', $r[0]['id'] ]);
return;
}
$arr['id'] = intval($r[0]['id']);
@@ -3231,29 +3248,32 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false
$arr['mid'] = z_root() . '/activity/' . $arr['uuid'];
$arr['parent_mid'] = $arr['mid'];
}
-
+
$arr['aid'] = $channel['channel_account_id'];
$arr['uid'] = $channel['channel_id'];
// WARNING: the presence of both source_xchan and non-zero item_uplink here will cause a delivery loop
-
+
$arr['item_uplink'] = 0;
$arr['source_xchan'] = $item['owner_xchan'];
+ $arr['resource_id'] = $item['mid'];
+ $arr['resource_type'] = 'group_item';
+
$arr['item_private'] = (($channel['channel_allow_cid'] || $channel['channel_allow_gid']
|| $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0);
$arr['item_origin'] = 1;
$arr['item_wall'] = 1;
$arr['item_thread_top'] = 1;
-
+
if (strpos($item['body'], "[/share]") !== false) {
$pos = strpos($item['body'], "[share");
$bb = substr($item['body'], $pos);
} else {
$bb = "[share author='" . urlencode($item['author']['xchan_name']).
"' profile='" . $item['author']['xchan_url'] .
- "' portable_id='" . $item['author']['xchan_hash'] .
+ "' portable_id='" . $item['author']['xchan_hash'] .
"' avatar='" . $item['author']['xchan_photo_s'] .
"' link='" . $item['plink'] .
"' auth='" . ((in_array($item['author']['xchan_network'], ['zot6','zot'])) ? 'true' : 'false') .
@@ -3261,12 +3281,13 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false
"' message_id='" . $item['mid'] .
"']";
if($item['title'])
- $bb .= '[b]'.$item['title'].'[/b]'."\r\n";
+ $bb .= '[h3][b]'.$item['title'].'[/b][/h3]'."\r\n";
$bb .= $item['body'];
$bb .= "[/share]";
}
$arr['body'] = $bb;
+ $arr['term'] = $item['term'];
$arr['author_xchan'] = $channel['channel_hash'];
$arr['owner_xchan'] = $channel['channel_hash'];
@@ -4800,7 +4821,7 @@ function set_linkified_perms($linkified, &$str_contact_allow, &$str_group_allow,
elseif(strpos($access_tag,'gid:') === 0) {
$str_group_allow .= '<' . substr($access_tag,4) . '>';
$access_tag = '';
- $private = 2;
+ $private = 1;
}
}
}
diff --git a/include/js_strings.php b/include/js_strings.php
index 6f559f4c4..e06e105fd 100644
--- a/include/js_strings.php
+++ b/include/js_strings.php
@@ -47,10 +47,10 @@ function js_strings() {
'days' => tt('%d days', '%d days', '%d'),
'months' => tt('%d months', '%d months', '%d'),
'years' => tt('%d years', '%d years', '%d'),
-
+
// get plural function code
'plural_func' => tf(),
-
+
'$t01' => ((t('timeago.prefixAgo') == 'timeago.prefixAgo') ? '' : ((t('timeago.prefixAgo') == 'NONE') ? '' : t('timeago.prefixAgo'))),
'$t02' => ((t('timeago.prefixFromNow') == 'timeago.prefixFromNow') ? '' : ((t('timeago.prefixFromNow') == 'NONE') ? '' : t('timeago.prefixFromNow'))),
'$t03' => ((t('timeago.suffixAgo') == 'timeago.suffixAgo') ? 'ago' : ((t('timeago.suffixAgo') == 'NONE') ? '' : t('timeago.suffixAgo'))),
@@ -113,6 +113,9 @@ function js_strings() {
'$month' => t('month','calendar'),
'$week' => t('week','calendar'),
'$day' => t('day','calendar'),
- '$allday' => t('All day','calendar')
+ '$allday' => t('All day','calendar'),
+
+ // mod cloud
+ '$download_info' => t('Please stand by while your download is being prepared.')
));
}
diff --git a/include/network.php b/include/network.php
index bcd66cf85..324a99eba 100644
--- a/include/network.php
+++ b/include/network.php
@@ -714,7 +714,7 @@ function sxml2array ( $xmlObject, $out = array () )
* @brief xml2array() will convert the given XML text to an array in the XML structure.
*
* Link: http://www.bin-co.com/php/scripts/xml2array/
- * Portions significantly re-written by mike@macgirvin.com
+ * Portions significantly re-written by mike@macgirvin.com
* (namespaces, lowercase tags, get_attribute default changed, more...)
*
* Examples: $array = xml2array(file_get_contents('feed.xml'));
@@ -1113,8 +1113,8 @@ function discover_by_webbie($webbie, $protocol = '') {
// Check the HTTP signature
$hsig = $record['signature'];
- if($hsig && ($hsig['signer'] === $url || $hsig['signer'] === $link['href']) && $hsig['header_valid'] === true && $hsig['content_valid'] === true)
- $hsig_valid = true;
+ if($hsig && $hsig['signer'] === $link['href'] && $hsig['header_valid'] === true && $hsig['content_valid'] === true)
+ $hsig_valid = true;
if(! $hsig_valid) {
logger('http signature not valid: ' . print_r($hsig,true));
@@ -1431,7 +1431,7 @@ function scrape_feed($url) {
function do_delivery($deliveries, $force = false) {
// $force is set if a site that wasn't responding suddenly returns to life.
- // Try and shove through everything going to that site while it's responding.
+ // Try and shove through everything going to that site while it's responding.
if(! (is_array($deliveries) && count($deliveries)))
return;
@@ -2069,7 +2069,7 @@ function get_request_string($url) {
* Takes the output of parse_url and builds a URL from it
*
*/
-
+
function unparse_url($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
@@ -2081,4 +2081,4 @@ function unparse_url($parsed_url) {
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
-}
+}
diff --git a/include/text.php b/include/text.php
index c2a45814c..d6b196f1e 100644
--- a/include/text.php
+++ b/include/text.php
@@ -1801,7 +1801,7 @@ function prepare_body(&$item,$attach = false,$opts = false) {
$tags = format_hashtags($item);
- if($item['resource_type'])
+ if($item['resource_type'] == 'photo')
$mentions = format_mentions($item);
$categories = format_categories($item,$writeable);
@@ -2795,7 +2795,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
$termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN);
$termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype);
- $termtype = ((strpos($tag,'!') === 0) ? TERM_FORUM : $termtype);
+// $termtype = ((strpos($tag,'!') === 0) ? TERM_FORUM : $termtype);
$termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype);
// Is it a hashtag of some kind?
@@ -2864,7 +2864,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
if ( in_array($termtype, [ TERM_MENTION, TERM_FORUM ] )) {
- // The @! tag and !! tag will alter permissions
+ // The @! tag will alter permissions
// $in_network is set to false to avoid false positives on posts originating
// on a network which does not implement privacy tags or implements them differently.
@@ -2966,12 +2966,13 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
//create profile link
$profile = str_replace(',','%2c',$profile);
$url = $profile;
+/*
if($termtype === TERM_FORUM) {
$newtag = '!' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
$body = str_replace('!' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
}
- else {
- // ( $termtype === TERM_MENTION )
+*/
+ if ($termtype === TERM_MENTION) {
$newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
$body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
}
@@ -2983,7 +2984,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
$str_tags .= $newtag;
}
}
-
+
$fn_results[] = [
'replaced' => $replaced,
@@ -3032,12 +3033,13 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
//create profile link
$profile = str_replace(',','%2c',$profile);
$url = $profile;
+/*
if($termtype === TERM_FORUM) {
$newtag = '!' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
$body = str_replace('!' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
}
- else {
- // ( $termtype === TERM_MENTION )
+*/
+ if ($termtype === TERM_MENTION) {
$newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . '[/zrl]';
$body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body);
}
@@ -3060,7 +3062,7 @@ function handle_tag(&$body, &$str_tags, $profile_uid, $tag, $in_network = true)
];
}
}
-
+
return $fn_results;
}
@@ -3098,7 +3100,7 @@ function linkify_tags(&$body, $uid, $in_network = true) {
function getIconFromType($type) {
$iconMap = array(
//Folder
- t('Collection') => 'fa-folder-o',
+ 'Collection' => 'fa-folder-o',
'multipart/mixed' => 'fa-folder-o', //dirs in attach use this mime type
//Common file
'application/octet-stream' => 'fa-file-o',
@@ -3242,7 +3244,7 @@ function item_url_replace($channel,&$item,$old,$new,$oldnick = '') {
if($oldnick)
json_url_replace('/' . $oldnick . '/' ,'/' . $channel['channel_address'] . '/' ,$item['target']);
}
-
+
$item['body'] = preg_replace("/(\[zrl=".preg_quote($old,'/')."\/(photo|photos|gallery)\/".$channel['channel_address'].".+\]\[zmg=\d+x\d+\])".preg_quote($old,'/')."\/(.+\[\/zmg\])/", '${1}'.$new.'/${3}', $item['body']);
$item['body'] = preg_replace("/".preg_quote($old,'/')."\/(search|\w+\/".$channel['channel_address'].")/", $new.'/${1}', $item['body']);
@@ -3575,7 +3577,7 @@ function cleanup_bbcode($body) {
$body = preg_replace_callback('/\[\$b64url(.*?)\[\/(url)\]/ism','\red_unescape_codeblock',$body);
$body = preg_replace_callback('/\[\$b64code(.*?)\[\/(code)\]/ism','\red_unescape_codeblock',$body);
$body = preg_replace_callback('/\[\$b64svg(.*?)\[\/(svg)\]/ism','\red_unescape_codeblock',$body);
-
+
// fix any img tags that should be zmg
$body = preg_replace_callback('/\[img(.*?)\](.*?)\[\/img\]/ism','\red_zrlify_img_callback',$body);
@@ -3690,6 +3692,11 @@ function get_forum_channels($uid) {
);
if($x1) {
+
+ $x2 = [];
+ $x3 = [];
+ $x4 = [];
+
$xc = ids_to_querystr($x1,'xchan',true);
$x2 = q("select xchan from abconfig where chan = %d and cat = 'their_perms' and k = 'tag_deliver' and v = '1' and xchan in (" . $xc . ") ",
@@ -3706,6 +3713,15 @@ function get_forum_channels($uid) {
if($x3) {
$xf = ids_to_querystr(array_merge($x2,$x3),'xchan',true);
}
+
+ // public forums with no permission to post
+ $x4 = q("select xchan from abconfig left join xchan on xchan = xchan_hash where chan = %d and cat = 'their_perms' and k in ('post_wall', 'tag_deliver') and v = '0' and xchan in (" . $xc . ") and xchan_pubforum = 1 $sql_extra ",
+ intval(local_channel())
+ );
+ if($x4) {
+ $xf = ids_to_querystr(array_merge($x2,$x3,$x4),'xchan',true);
+ }
+
}
$sql_extra_1 = (($xf) ? " and ( xchan_hash in (" . $xf . ") or xchan_pubforum = 1 ) " : " and xchan_pubforum = 1 ");
@@ -3722,6 +3738,15 @@ function get_forum_channels($uid) {
}
}
}
+
+ if($x4) {
+ foreach($x4 as $xx) {
+ if($r[$x]['xchan_hash'] == $xx['xchan']) {
+ $r[$x]['no_post_perms'] = 1;
+ }
+ }
+ }
+
}
App::$data['forum_channels'] = $r;
@@ -3791,7 +3816,7 @@ function array_path_exists($str,$arr) {
/**
- * @brief Generate a unique ID.
+ * @brief Generate a random v4 UUID.
*
* @return string
*/
@@ -3807,6 +3832,22 @@ function new_uuid() {
}
+/**
+ * @brief Generate a name-based v5 UUID in the URL namespace
+ *
+ * @param string $url
+ * @return string
+ */
+function uuid_from_url($url) {
+
+ try {
+ $hash = Uuid::uuid5(Uuid::NAMESPACE_URL, $url)->toString();
+ } catch (UnsatisfiedDependencyException $e) {
+ $hash = md5($url);
+ }
+ return $hash;
+}
+
function svg2bb($s) {
$s = preg_replace("/\<text (.*?)\>(.*?)\<(.*?)\<\/text\>/", '<text $1>$2&lt;$3</text>', $s);