aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authormrjive <mrjive@mrjive.it>2015-11-11 16:51:48 +0100
committermrjive <mrjive@mrjive.it>2015-11-11 16:51:48 +0100
commit53a796afcc0cff6f9e3f51457df4506a43db1945 (patch)
treea2366c48e0dae047b052283cc44284224369c8cd /include
parenta4c3058f845a1c38d06b2201a10700c5f878366d (diff)
parentbc7c0ed844711e81c4bc642e3024849195a48421 (diff)
downloadvolse-hubzilla-53a796afcc0cff6f9e3f51457df4506a43db1945.tar.gz
volse-hubzilla-53a796afcc0cff6f9e3f51457df4506a43db1945.tar.bz2
volse-hubzilla-53a796afcc0cff6f9e3f51457df4506a43db1945.zip
Merge pull request #8 from redmatrix/master
get fresh code from HZ base
Diffstat (limited to 'include')
-rw-r--r--include/Contact.php5
-rw-r--r--include/ItemObject.php1
-rw-r--r--include/RedDAV/RedDirectory.php23
-rw-r--r--include/RedDAV/RedFile.php12
-rw-r--r--include/acl_selectors.php2
-rw-r--r--include/api.php159
-rw-r--r--include/api_auth.php95
-rw-r--r--include/attach.php27
-rw-r--r--include/auth.php1
-rw-r--r--include/bb2diaspora.php16
-rw-r--r--include/bbcode.php12
-rw-r--r--include/conversation.php11
-rw-r--r--include/dir_fns.php18
-rw-r--r--include/identity.php13
-rwxr-xr-xinclude/items.php16
-rw-r--r--include/network.php22
-rw-r--r--include/notifier.php2
-rw-r--r--include/photo/photo_driver.php22
-rw-r--r--include/photo/photo_gd.php2
-rw-r--r--include/photos.php25
-rw-r--r--include/text.php23
-rw-r--r--include/widgets.php2
-rw-r--r--include/zot.php56
23 files changed, 379 insertions, 186 deletions
diff --git a/include/Contact.php b/include/Contact.php
index 8e22c608e..3bd5f9936 100644
--- a/include/Contact.php
+++ b/include/Contact.php
@@ -292,7 +292,8 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
intval($channel_id)
);
-
+ logger('deleting hublocs',LOGGER_DEBUG);
+
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s'",
dbesc($channel['channel_hash'])
);
@@ -349,6 +350,8 @@ function channel_remove($channel_id, $local = true, $unset_session=true) {
}
+ logger('deleting hublocs',LOGGER_DEBUG);
+
$r = q("update hubloc set hubloc_deleted = 1 where hubloc_hash = '%s' and hubloc_url = '%s' ",
dbesc($channel['channel_hash']),
dbesc(z_root())
diff --git a/include/ItemObject.php b/include/ItemObject.php
index c5c2cb2e6..34500efb9 100644
--- a/include/ItemObject.php
+++ b/include/ItemObject.php
@@ -263,6 +263,7 @@ class Item extends BaseObject {
localize_item($item);
+
$body = prepare_body($item,true);
// $viewthread (below) is only valid in list mode. If this is a channel page, build the thread viewing link
diff --git a/include/RedDAV/RedDirectory.php b/include/RedDAV/RedDirectory.php
index 507fde46f..8d8af5bd3 100644
--- a/include/RedDAV/RedDirectory.php
+++ b/include/RedDAV/RedDirectory.php
@@ -251,7 +251,7 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
intval($filesize),
intval(0),
intval($is_photo),
- dbesc($this->os_path . '/' . $hash),
+ dbesc($f),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($allow_cid),
@@ -363,6 +363,27 @@ class RedDirectory extends DAV\Node implements DAV\ICollection, DAV\IQuota {
}
/**
+ * @brief delete directory
+ */
+
+ public function delete() {
+ logger('delete file ' . basename($this->red_path), LOGGER_DEBUG);
+
+ if ((! $this->auth->owner_id) || (! perm_is_allowed($this->auth->owner_id, $this->auth->observer, 'write_storage'))) {
+ throw new DAV\Exception\Forbidden('Permission denied.');
+ }
+
+ if ($this->auth->owner_id !== $this->auth->channel_id) {
+ if (($this->auth->observer !== $this->data['creator']) || intval($this->data['is_dir'])) {
+ throw new DAV\Exception\Forbidden('Permission denied.');
+ }
+ }
+
+ attach_delete($this->auth->owner_id, $this->folder_hash);
+ }
+
+
+ /**
* @brief Checks if a child exists.
*
* @param string $name
diff --git a/include/RedDAV/RedFile.php b/include/RedDAV/RedFile.php
index ec6871a69..3283a6e88 100644
--- a/include/RedDAV/RedFile.php
+++ b/include/RedDAV/RedFile.php
@@ -126,7 +126,11 @@ class RedFile extends DAV\Node implements DAV\IFile {
}
}
$fname = dbunescbin($d[0]['data']);
- $f = 'store/' . $this->auth->owner_nick . '/' . (($fname) ? $fname : '');
+ if(strpos($fname,'store') === false)
+ $f = 'store/' . $this->auth->owner_nick . '/' . $fname ;
+ else
+ $f = $fname;
+
// @todo check return value and set $size directly
@file_put_contents($f, $data);
$size = @filesize($f);
@@ -226,7 +230,11 @@ class RedFile extends DAV\Node implements DAV\IFile {
}
if (intval($r[0]['os_storage'])) {
- $f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . dbunescbin($r[0]['data']);
+ $x = dbunescbin($r[0]['data']);
+ if(strpos($x,'store') === false)
+ $f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . $x;
+ else
+ $f = $x;
return fopen($f, 'rb');
}
return dbunescbin($r[0]['data']);
diff --git a/include/acl_selectors.php b/include/acl_selectors.php
index cb2266473..4d44ec12e 100644
--- a/include/acl_selectors.php
+++ b/include/acl_selectors.php
@@ -231,6 +231,7 @@ function populate_acl($defaults = null,$show_jotnets = true) {
$jotnets = '';
if($show_jotnets) {
+logger('jot_networks');
call_hooks('jot_networks', $jotnets);
}
@@ -243,6 +244,7 @@ function populate_acl($defaults = null,$show_jotnets = true) {
'$allowgid' => json_encode($allow_gid),
'$denycid' => json_encode($deny_cid),
'$denygid' => json_encode($deny_gid),
+ '$jnetModalTitle' => t('Other networks and post services'),
'$jotnets' => $jotnets,
'$aclModalTitle' => t('Permissions'),
'$aclModalDismiss' => t('Close')
diff --git a/include/api.php b/include/api.php
index 16dbb569b..24176884c 100644
--- a/include/api.php
+++ b/include/api.php
@@ -66,95 +66,6 @@ require_once('include/attach.php');
'auth'=>$auth);
}
- /**
- * Simple HTTP Login
- */
-
- function api_login(&$a){
- // login with oauth
- try {
- $oauth = new FKOAuth1();
- $req = OAuthRequest::from_request();
- list($consumer,$token) = $oauth->verify_request($req);
-// list($consumer,$token) = $oauth->verify_request(OAuthRequest::from_request());
- if (!is_null($token)){
- $oauth->loginUser($token->uid);
-
- $a->set_oauth_key($consumer->key);
-
- call_hooks('logged_in', $a->user);
- return;
- }
- echo __file__.__line__.__function__."<pre>";
-// var_dump($consumer, $token);
- die();
- }
- catch(Exception $e) {
- logger(__file__.__line__.__function__."\n".$e);
- }
-
-
- // workaround for HTTP-auth in CGI mode
- if(x($_SERVER,'REDIRECT_REMOTE_USER')) {
- $userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"],6)) ;
- if(strlen($userpass)) {
- list($name, $password) = explode(':', $userpass);
- $_SERVER['PHP_AUTH_USER'] = $name;
- $_SERVER['PHP_AUTH_PW'] = $password;
- }
- }
-
- if(x($_SERVER,'HTTP_AUTHORIZATION')) {
- $userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"],6)) ;
- if(strlen($userpass)) {
- list($name, $password) = explode(':', $userpass);
- $_SERVER['PHP_AUTH_USER'] = $name;
- $_SERVER['PHP_AUTH_PW'] = $password;
- }
- }
-
-
- if (!isset($_SERVER['PHP_AUTH_USER'])) {
- logger('API_login: ' . print_r($_SERVER,true), LOGGER_DEBUG);
- header('WWW-Authenticate: Basic realm="Red"');
- header('HTTP/1.0 401 Unauthorized');
- die('This api requires login');
- }
-
- // process normal login request
- require_once('include/auth.php');
- $channel_login = 0;
- $record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
- if(! $record) {
- $r = q("select * from channel where channel_address = '%s' limit 1",
- dbesc($_SERVER['PHP_AUTH_USER'])
- );
- if ($r) {
- $x = q("select * from account where account_id = %d limit 1",
- intval($r[0]['channel_account_id'])
- );
- if ($x) {
- $record = account_verify_password($x[0]['account_email'],$_SERVER['PHP_AUTH_PW']);
- if($record)
- $channel_login = $r[0]['channel_id'];
- }
- }
- if(! $record) {
- logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
- header('WWW-Authenticate: Basic realm="Red"');
- header('HTTP/1.0 401 Unauthorized');
- die('This api requires login');
- }
- }
-
- require_once('include/security.php');
- authenticate_success($record);
-
- if($channel_login)
- change_channel($channel_login);
-
- $_SESSION['allow_api'] = true;
- }
/**************************
* MAIN API ENTRY POINT *
@@ -627,6 +538,71 @@ require_once('include/attach.php');
api_register_func('api/red/files','api_attach_list', true);
+
+
+
+ function api_file_meta(&$a,$type) {
+ if (api_user()===false) return false;
+ if(! $_REQUEST['file_id']) return false;
+ $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['file_id'])
+ );
+ if($r) {
+ unset($r[0]['data']);
+ $ret = array('attach' => $r[0]);
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+ api_register_func('api/red/filemeta', 'api_file_meta', true);
+
+
+ function api_file_data(&$a,$type) {
+ if (api_user()===false) return false;
+ if(! $_REQUEST['file_id']) return false;
+ $start = (($_REQUEST['start']) ? intval($_REQUEST['start']) : 0);
+ $length = (($_REQUEST['length']) ? intval($_REQUEST['length']) : 0);
+
+ $r = q("select * from attach where uid = %d and hash = '%s' limit 1",
+ intval(api_user()),
+ dbesc($_REQUEST['file_id'])
+ );
+ if($r) {
+ $ptr = $r[0];
+ if($length === 0)
+ $length = intval($ptr['filesize']);
+
+ if($ptr['is_dir'])
+ $ptr['data'] = '';
+ elseif(! intval($r[0]['os_storage'])) {
+ $ptr['start'] = $start;
+ $x = substr(dbunescbin($ptr['data'],$start,$length));
+ $ptr['length'] = strlen($x);
+ $ptr['data'] = base64_encode($x);
+ }
+ else {
+ $fp = fopen(dbunescbin($ptr['data']),'r');
+ if($fp) {
+ $seek = fseek($fp,$start,SEEK_SET);
+ $x = fread($fp,$length);
+ $ptr['start'] = $start;
+ $ptr['length'] = strlen($x);
+ $ptr['data'] = base64_encode($x);
+ }
+ }
+
+ $ret = array('attach' => $ptr);
+ json_return_and_die($ret);
+ }
+ killme();
+ }
+
+ api_register_func('api/red/filedata', 'api_file_data', true);
+
+
+
function api_file_detail(&$a,$type) {
if (api_user()===false) return false;
if(! $_REQUEST['file_id']) return false;
@@ -826,6 +802,7 @@ require_once('include/attach.php');
require_once('include/html2bbcode.php');
$txt = requestdata('htmlstatus');
+
if((strpos($txt,'<') !== false) || (strpos($txt,'>') !== false)) {
$txt = html2bb_video($txt);
@@ -837,9 +814,10 @@ require_once('include/attach.php');
$purifier = new HTMLPurifier($config);
$txt = $purifier->purify($txt);
- $_REQUEST['body'] = html2bbcode($txt);
}
+ $_REQUEST['body'] = html2bbcode($txt);
+
}
else
$_REQUEST['body'] = requestdata('status');
@@ -2348,6 +2326,7 @@ logger('Req: ' . var_export($req,true));
api_register_func('api/oauth/request_token', 'api_oauth_request_token', false);
api_register_func('api/oauth/access_token', 'api_oauth_access_token', false);
+
/*
Not implemented by now:
statuses/retweets_of_me
diff --git a/include/api_auth.php b/include/api_auth.php
new file mode 100644
index 000000000..ee9db3f55
--- /dev/null
+++ b/include/api_auth.php
@@ -0,0 +1,95 @@
+<?php /** @file */
+
+require_once("oauth.php");
+
+
+/**
+ * Simple HTTP Login
+ */
+
+function api_login(&$a){
+ // login with oauth
+ try {
+ $oauth = new FKOAuth1();
+ $req = OAuthRequest::from_request();
+
+ list($consumer,$token) = $oauth->verify_request($req);
+
+ if (!is_null($token)){
+ $oauth->loginUser($token->uid);
+
+ $a->set_oauth_key($consumer->key);
+
+ call_hooks('logged_in', $a->user);
+ return;
+ }
+ echo __file__.__line__.__function__."<pre>";
+// var_dump($consumer, $token);
+ die();
+ }
+ catch(Exception $e) {
+ logger(__file__.__line__.__function__."\n".$e);
+ }
+
+
+ // workaround for HTTP-auth in CGI mode
+ if(x($_SERVER,'REDIRECT_REMOTE_USER')) {
+ $userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"],6)) ;
+ if(strlen($userpass)) {
+ list($name, $password) = explode(':', $userpass);
+ $_SERVER['PHP_AUTH_USER'] = $name;
+ $_SERVER['PHP_AUTH_PW'] = $password;
+ }
+ }
+
+ if(x($_SERVER,'HTTP_AUTHORIZATION')) {
+ $userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"],6)) ;
+ if(strlen($userpass)) {
+ list($name, $password) = explode(':', $userpass);
+ $_SERVER['PHP_AUTH_USER'] = $name;
+ $_SERVER['PHP_AUTH_PW'] = $password;
+ }
+ }
+
+
+ if (!isset($_SERVER['PHP_AUTH_USER'])) {
+ logger('API_login: ' . print_r($_SERVER,true), LOGGER_DEBUG);
+ header('WWW-Authenticate: Basic realm="Red"');
+ header('HTTP/1.0 401 Unauthorized');
+ die('This api requires login');
+ }
+
+ // process normal login request
+ require_once('include/auth.php');
+ $channel_login = 0;
+ $record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
+ if(! $record) {
+ $r = q("select * from channel where channel_address = '%s' limit 1",
+ dbesc($_SERVER['PHP_AUTH_USER'])
+ );
+ if ($r) {
+ $x = q("select * from account where account_id = %d limit 1",
+ intval($r[0]['channel_account_id'])
+ );
+ if ($x) {
+ $record = account_verify_password($x[0]['account_email'],$_SERVER['PHP_AUTH_PW']);
+ if($record)
+ $channel_login = $r[0]['channel_id'];
+ }
+ }
+ if(! $record) {
+ logger('API_login failure: ' . print_r($_SERVER,true), LOGGER_DEBUG);
+ header('WWW-Authenticate: Basic realm="Red"');
+ header('HTTP/1.0 401 Unauthorized');
+ die('This api requires login');
+ }
+ }
+
+ require_once('include/security.php');
+ authenticate_success($record);
+
+ if($channel_login)
+ change_channel($channel_login);
+
+ $_SESSION['allow_api'] = true;
+}
diff --git a/include/attach.php b/include/attach.php
index f5d2c69b6..36b971712 100644
--- a/include/attach.php
+++ b/include/attach.php
@@ -64,7 +64,10 @@ function z_mime_content_type($filename) {
'wav' => 'audio/wav',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
- 'ogg' => 'application/ogg',
+ 'ogg' => 'audio/ogg',
+ 'ogv' => 'video/ogg',
+ 'ogx' => 'application/ogg',
+ 'flac' => 'audio/flac',
'opus' => 'audio/ogg',
'webm' => 'video/webm',
// 'webm' => 'audio/webm',
@@ -105,9 +108,9 @@ function z_mime_content_type($filename) {
'oth' => 'application/vnd.oasis.opendocument.text-web'
);
- $dot = strpos($filename, '.');
- if ($dot !== false) {
- $ext = strtolower(substr($filename, $dot + 1));
+ $last_dot = strrpos($filename, '.');
+ if ($last_dot !== false) {
+ $ext = strtolower(substr($filename, $last_dot + 1));
if (array_key_exists($ext, $mime_types)) {
return $mime_types[$ext];
}
@@ -719,7 +722,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
intval($filesize),
intval(1),
intval($is_photo),
- dbesc($os_relpath),
+ dbesc($os_basepath . $os_relpath),
dbesc($created),
intval($existing_id),
intval($channel_id)
@@ -739,7 +742,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
intval($x[0]['revision'] + 1),
intval(1),
intval($is_photo),
- dbesc($os_relpath),
+ dbesc($os_basepath . $os_relpath),
dbesc($created),
dbesc($created),
dbesc($x[0]['allow_cid']),
@@ -780,7 +783,7 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
intval(0),
intval(1),
intval($is_photo),
- dbesc($os_relpath),
+ dbesc($os_basepath . $os_relpath),
dbesc($created),
dbesc($created),
dbesc(($arr && array_key_exists('allow_cid',$arr)) ? $arr['allow_cid'] : $str_contact_allow),
@@ -1267,9 +1270,13 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
);
if($y) {
- $f = 'store/' . $channel_address . '/' . $y[0]['data'];
- if(is_dir($y[0]['data']))
- @rmdir($y[0]['data']);
+ if(strpos($y[0]['data'],'store') === false)
+ $f = 'store/' . $channel_address . '/' . $y[0]['data'];
+ else
+ $f = $y[0]['data'];
+
+ if(is_dir($f))
+ @rmdir($f);
elseif(file_exists($f))
unlink($f);
}
diff --git a/include/auth.php b/include/auth.php
index 643894e32..4f0c4c928 100644
--- a/include/auth.php
+++ b/include/auth.php
@@ -9,6 +9,7 @@
* Also provides a function for OpenID identiy matching.
*/
+require_once('include/api_auth.php');
require_once('include/security.php');
/**
diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
index d10ed57eb..1be7caa19 100644
--- a/include/bb2diaspora.php
+++ b/include/bb2diaspora.php
@@ -162,10 +162,10 @@ function diaspora2bb($s, $use_zrl = false) {
}
//$s = preg_replace("/([^\]\=]|^)(https?\:\/\/)(vimeo|youtu|www\.youtube|soundcloud)([a-zA-Z0-9\:\/\-\?\&\;\.\=\_\~\#\%\$\!\+\,]+)/ism", '$1[url=$2$3$4]$2$3$4[/url]',$s);
- $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/url\]/ism",'[youtube]$2[/youtube]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=https?:\/\/www.youtube.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism",'[youtube]$1[/youtube]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/ \/vimeo.com\/([0-9]+)(.*?)\[\/url\]/ism",'[vimeo]$2[/vimeo]','url',$s);
- $s = bb_tag_preg_replace("/\[url\=https?:\/\/vimeo.com\/([0-9]+)\](.*?)\[\/url\]/ism",'[vimeo]$1[/vimeo]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/\/www.youtube.com\/watch\?v\=(.*?)\[\/url\]/ism",'[embed]https://www.youtube.com/watch?v=$2[/embed]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=https?:\/\/www.youtube.com\/watch\?v\=(.*?)\].*?\[\/url\]/ism",'[embed]https://www.youtube.com/watch?v=$1[/embed]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=?(.*?)\]https?:\/ \/vimeo.com\/([0-9]+)(.*?)\[\/url\]/ism",'[embed]https://vimeo.com/$2[/embed]','url',$s);
+ $s = bb_tag_preg_replace("/\[url\=https?:\/\/vimeo.com\/([0-9]+)\](.*?)\[\/url\]/ism",'[embed]https://vimeo.com/$1[/embed]','url',$s);
// remove duplicate adjacent code tags
$s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s);
@@ -309,9 +309,8 @@ function bb2diaspora_itembody($item, $force_update = false) {
$is_photo = (($item['obj_type'] == ACTIVITY_OBJ_PHOTO) ? true : false);
if($is_photo) {
$object = json_decode($item['object'],true);
- if($object['link'][2]) {
- $photo_bb = '[zrl=' . rawurldecode($object['id']) . ']' . '[zmg=' . $object['link'][2]['width'] . 'x' . $object['link'][2]['height'] . ']' . rawurldecode($object['link'][2]['href']) . '[/zmg]' . '[/zrl]';
- $item['body'] = (($item['body']) ? $photo_bb . $item['body'] : $photo_bb);
+ if($object['bbcode']) {
+ $item['body'] = (($item['body']) ? $object['bbcode'] . "\r\n" . $item['body'] : $object['bbcode']);
}
}
@@ -441,6 +440,9 @@ function bb2diaspora($Text,$preserve_nl = false, $fordiaspora = true) {
// So take off the angle brackets of any such URL
$Text = preg_replace("/<http(.*?)>/is", "http$1", $Text);
+ // Remove empty zrl links
+ $Text = preg_replace("/\[zrl\=\].*?\[\/zrl\]/is", "", $Text);
+
// Remove all unconverted tags
$Text = strip_tags($Text);
diff --git a/include/bbcode.php b/include/bbcode.php
index 1092c08a3..05802aa57 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -28,7 +28,7 @@ function tryzrlaudio($match) {
if($zrl)
$link = zid($link);
- return '<audio src="' . str_replace(' ','%20',$link) . '" controls="controls"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></audio>';
+ return '<audio src="' . str_replace(' ','%20',$link) . '" controls="controls" preload="none"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></audio>';
}
function tryzrlvideo($match) {
@@ -37,7 +37,7 @@ function tryzrlvideo($match) {
if($zrl)
$link = zid($link);
- return '<video controls="controls" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . get_app()->videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
+ return '<video controls="controls" preload="none" src="' . str_replace(' ','%20',$link) . '" style="width:100%; max-width:' . get_app()->videowidth . 'px"><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></video>';
}
// [noparse][i]italic[/i][/noparse] turns into
@@ -599,6 +599,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1" target="_newwin" >$2</a>', $Text);
}
+
// leave open the posibility of [map=something]
// this is replaced in prepare_body() which has knowledge of the item location
@@ -983,7 +984,12 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/', '&$1;', $Text);
// fix any escaped ampersands that may have been converted into links
- $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text);
+
+ if(strpos($Text,'&amp;') !== false)
+ $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text);
+
+ // This is subtle - it's an XSS filter. It only accepts links with a protocol scheme and where
+ // the scheme begins with z (zhttp), h (http(s)), f (ftp), m (mailto), and named anchors.
$Text = preg_replace("/\<(.*?)(src|href)=\"[^zhfm#](.*?)\>/ism", '<$1$2="">', $Text);
diff --git a/include/conversation.php b/include/conversation.php
index c2d9641ba..c278dcf12 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -681,7 +681,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
$body = prepare_body($item,true);
- $is_photo = ((($item['resource_type'] == 'photo') && (feature_enabled($profile_owner,'large_photos'))) ? true : false);
$has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
$tmp_item = array(
@@ -698,6 +697,7 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'thumb' => $profile_avatar,
'title' => $item['title'],
'body' => $body['html'],
+ 'photo' => $body['photo'],
'tags' => $body['tags'],
'categories' => $body['categories'],
'mentions' => $body['mentions'],
@@ -738,7 +738,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $
'previewing' => $previewing,
'wait' => t('Please wait'),
'thread_level' => 1,
- 'is_photo' => $is_photo,
'has_tags' => $has_tags,
);
@@ -918,6 +917,9 @@ function item_photo_menu($item){
if($item['parent'] == $item['id'] && $channel && ($channel_hash != $item['author_xchan'])) {
$sub_link = 'javascript:dosubthread(' . $item['id'] . '); return false;';
}
+ if($channel) {
+ $unsub_link = 'javascript:dounsubthread(' . $item['id'] . '); return false;';
+ }
}
$profile_link = chanlink_hash($item['author_xchan']);
@@ -942,6 +944,7 @@ function item_photo_menu($item){
$menu = Array(
t("View Source") => $vsrc_link,
t("Follow Thread") => $sub_link,
+ t("Stop Following") => $unsub_link,
t("View Status") => $status_link,
t("View Profile") => $profile_link,
t("View Photos") => $photos_link,
@@ -1021,8 +1024,8 @@ function builtin_activity_puller($item, &$conv_responses) {
if((activity_match($item['verb'], $verb)) && ($item['id'] != $item['parent'])) {
$name = (($item['author']['xchan_name']) ? $item['author']['xchan_name'] : t('Unknown'));
- $url = (($item['author']['xchan_url'])
- ? '<a href="' . chanlink_url($item['author']['xchan_url']) . '">' . $name . '</a>'
+ $url = (($item['author']['xchan_url'] && $item['author']['xchan_photo_s'])
+ ? '<a href="' . chanlink_url($item['author']['xchan_url']) . '">' . '<img class="response-photo" src="' . zid($item['author']['xchan_photo_s']) . ' alt="' . urlencode($name) . '" /> ' . $name . '</a>'
: '<a href="#" class="disabled">' . $name . '</a>'
);
diff --git a/include/dir_fns.php b/include/dir_fns.php
index ecc5f6d96..398f43d00 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -15,6 +15,19 @@ function find_upstream_directory($dirmode) {
global $DIRECTORY_FALLBACK_SERVERS;
$preferred = get_config('system','directory_server');
+
+ // Thwart attempts to use a private directory
+
+ if(($preferred) && ($prefered != z_root())) {
+ $r = q("select * from site where site_url = '%s' limit 1",
+ dbesc($preferred)
+ );
+ if(($r) && ($r[0]['site_flags'] & DIRECTORY_MODE_STADALONE)) {
+ $preferred = '';
+ }
+ }
+
+
if (! $preferred) {
/*
@@ -190,8 +203,9 @@ function sync_directories($dirmode) {
intval($r[0]['site_valid'])
);
- $r = q("select * from site where (site_flags & %d) > 0 and site_url != '%s' and site_type = %d ",
- intval(DIRECTORY_MODE_PRIMARY|DIRECTORY_MODE_SECONDARY),
+ $r = q("select * from site where site_flags in (%d, %d) and site_url != '%s' and site_type = %d ",
+ intval(DIRECTORY_MODE_PRIMARY),
+ intval(DIRECTORY_MODE_SECONDARY),
dbesc(z_root()),
intval(SITE_TYPE_ZOT)
);
diff --git a/include/identity.php b/include/identity.php
index 0c4a9df45..21d919508 100644
--- a/include/identity.php
+++ b/include/identity.php
@@ -904,19 +904,6 @@ function profile_load(&$a, $nickname, $profile = '') {
}
/**
- * @brief
- *
- * @param App &$a
- * @param boolean $connect
- */
-function profile_create_sidebar(&$a, $connect = true) {
-
- $block = (((get_config('system', 'block_public')) && (! local_channel()) && (! remote_channel())) ? true : false);
-
- $a->set_widget('profile', profile_sidebar($a->profile, $block, $connect));
-}
-
-/**
* @brief Formats a profile for display in the sidebar.
*
* It is very difficult to templatise the HTML completely
diff --git a/include/items.php b/include/items.php
index 08be981e7..3e4805212 100755
--- a/include/items.php
+++ b/include/items.php
@@ -2837,6 +2837,8 @@ function store_diaspora_comment_sig($datarray, $channel, $parent_item, $post_id,
function send_status_notifications($post_id,$item) {
$notify = false;
+ $unfollowed = false;
+
$parent = 0;
$r = q("select channel_hash from channel where channel_id = %d limit 1",
@@ -2864,6 +2866,14 @@ function send_status_notifications($post_id,$item) {
foreach($x as $xx) {
if($xx['author_xchan'] === $r[0]['channel_hash']) {
$notify = true;
+
+ // check for an unfollow thread activity - we should probably decode the obj and check the id
+ // but it will be extremely rare for this to be wrong.
+
+ if(($xx['verb'] === ACTIVITY_UNFOLLOW)
+ && ($xx['obj_type'] === ACTIVITY_OBJ_NOTE || $xx['obj_type'] === ACTIVITY_OBJ_PHOTO)
+ && ($xx['parent'] != $xx['id']))
+ $unfollowed = true;
}
if($xx['id'] == $xx['parent']) {
$parent = $xx['parent'];
@@ -2871,6 +2881,9 @@ function send_status_notifications($post_id,$item) {
}
}
+ if($unfollowed)
+ return;
+
$link = get_app()->get_baseurl() . '/display/' . $item['mid'];
$y = q("select id from notify where link = '%s' and uid = %d limit 1",
@@ -3455,6 +3468,7 @@ function post_is_importable($item,$abook) {
$text = prepare_text($item['body'],$item['mimetype']);
$text = html2plain($text);
+
$lang = null;
if((strpos($abook['abook_incl'],'lang=') !== false) || (strpos($abook['abook_excl'],'lang=') !== false)) {
@@ -4792,7 +4806,7 @@ function items_fetch($arr,$channel = null,$observer_hash = null,$client_mode = C
if($arr['mid'])
$sql_options .= " and parent_mid = '" . dbesc($arr['mid']) . "' ";
- $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options ) ";
+ $sql_extra = " AND item.parent IN ( SELECT parent FROM item WHERE item_thread_top = 1 $sql_options $item_normal ) ";
if($arr['since_id'])
$sql_extra .= " and item.id > " . $since_id . " ";
diff --git a/include/network.php b/include/network.php
index c67c019ef..65599bd05 100644
--- a/include/network.php
+++ b/include/network.php
@@ -526,28 +526,6 @@ function allowed_email($email) {
-function avatar_img($email) {
-
- $avatar = array();
- $a = get_app();
-
- $avatar['size'] = 300;
- $avatar['email'] = $email;
- $avatar['url'] = '';
- $avatar['success'] = false;
-
- call_hooks('avatar_lookup', $avatar);
-
- if (! $avatar['success'])
- $avatar['url'] = $a->get_baseurl() . '/' . get_default_profile_photo();
-
- logger('Avatar: ' . $avatar['email'] . ' ' . $avatar['url'], LOGGER_DEBUG);
-
- return $avatar['url'];
-}
-
-
-
function parse_xml_string($s,$strict = true) {
if($strict) {
if(! strstr($s,'<?xml'))
diff --git a/include/notifier.php b/include/notifier.php
index 0b29146c1..34a527e15 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -675,7 +675,7 @@ function notifier_run($argv, $argc){
dbesc(json_encode($encoded_item))
);
// only create delivery reports for normal undeleted items
- if(array_key_exists('postopts',$target_item) && (! $target_item['item_deleted'])) {
+ if(is_array($target_item) && array_key_exists('postopts',$target_item) && (! $target_item['item_deleted'])) {
q("insert into dreport ( dreport_mid, dreport_site, dreport_recip, dreport_result, dreport_time, dreport_xchan, dreport_queue ) values ( '%s','%s','%s','%s','%s','%s','%s' ) ",
dbesc($target_item['mid']),
dbesc($hub['hubloc_host']),
diff --git a/include/photo/photo_driver.php b/include/photo/photo_driver.php
index 32b9bd302..285cbc8fb 100644
--- a/include/photo/photo_driver.php
+++ b/include/photo/photo_driver.php
@@ -546,11 +546,18 @@ function guess_image_type($filename, $headers = '') {
$ext = pathinfo($filename, PATHINFO_EXTENSION);
$ph = photo_factory('');
$types = $ph->supportedTypes();
- $type = "image/jpeg";
foreach ($types as $m=>$e){
if ($ext==$e) $type = $m;
}
}
+
+ if(is_null($type)) {
+ $size = getimagesize($filename);
+ $ph = photo_factory('');
+ $types = $ph->supportedTypes();
+ $type = ((array_key_exists($size['mime'], $types)) ? $size['mime'] : 'image/jpeg');
+ }
+
}
logger('Photo: guess_image_type: type='.$type, LOGGER_DEBUG);
return $type;
@@ -586,16 +593,12 @@ function import_xchan_photo($photo,$xchan,$thing = false) {
if($photo) {
$filename = basename($photo);
- $type = guess_image_type($photo);
-
- if(! $type)
- $type = 'image/jpeg';
-
$result = z_fetch_url($photo,true);
if($result['success']) {
$img_str = $result['body'];
+ $type = guess_image_type($photo, $result['header']);
$h = explode("\n",$result['header']);
if($h) {
@@ -731,6 +734,11 @@ function import_channel_photo($photo,$type,$aid,$uid) {
$photo_failure = true;
}
- return(($photo_failure)? false : true);
+ //return(($photo_failure)? false : true);
+
+ if($photo_failure)
+ return false;
+ else
+ return $hash;
}
diff --git a/include/photo/photo_gd.php b/include/photo/photo_gd.php
index fa1f700e9..2ac7287e4 100644
--- a/include/photo/photo_gd.php
+++ b/include/photo/photo_gd.php
@@ -137,4 +137,4 @@ class photo_gd extends photo_driver {
return $string;
}
-} \ No newline at end of file
+}
diff --git a/include/photos.php b/include/photos.php
index a8619c372..c7360a956 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -292,18 +292,19 @@ function photo_upload($channel, $observer, $args) {
$tag = (($r2) ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]');
}
+ $body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
+ . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]'
+ . '[/zrl]';
+
// Create item object
$object = array(
'type' => ACTIVITY_OBJ_PHOTO,
'title' => $title,
'id' => rawurlencode(z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash),
- 'link' => $link
+ 'link' => $link,
+ 'bbcode' => $body
);
- $body = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
- . $tag . z_root() . "/photo/{$photo_hash}-{$scale}." . $ph->getExt() . '[/zmg]'
- . '[/zrl]';
-
// Create item container
if($args['item']) {
foreach($args['item'] as $i) {
@@ -378,6 +379,20 @@ function photo_upload($channel, $observer, $args) {
$arr['plink'] = z_root() . '/channel/' . $channel['channel_address'] . '/?f=&mid=' . $arr['mid'];
$arr['body'] = (($object) ? $args['body'] : $body . "\r\n" . $args['body']);
+
+ // this one is tricky because the item and the photo have the same permissions, those of the photo.
+ // Use the channel read_stream permissions to get the correct public_policy for the item and recalculate the
+ // private flag accordingly. This may cause subtle bugs due to custom permissions roles. We want to use
+ // public policy when federating items to other sites, but should probably ignore them when accessing the item
+ // in the photos pages - using the photos permissions instead. We need the public policy to keep the photo
+ // linked item from leaking into the feed when somebody has a channel with read_stream restrictions.
+
+ $arr['public_policy'] = map_scope($channel['channel_r_stream'],true);
+ if($arr['public_policy'])
+ $arr['item_private'] = 1;
+
+
+
$result = item_store($arr);
$item_id = $result['item_id'];
diff --git a/include/text.php b/include/text.php
index c30be77b8..edaa8dcd3 100644
--- a/include/text.php
+++ b/include/text.php
@@ -872,15 +872,17 @@ function searchbox($s,$id='search-box',$url='/search',$save = false) {
));
}
+function valid_email_regex($x){
+ if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x))
+ return true;
+ return false;
+}
function valid_email($x){
if(get_config('system','disable_email_validation'))
return true;
- if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x))
- return true;
-
- return false;
+ return valid_email_regex($x);
}
/**
@@ -912,8 +914,17 @@ function sslify($s) {
if (strpos(z_root(),'https:') === false)
return $s;
+ // By default we'll only sslify img tags because media files will probably choke.
+ // You can set sslify_everything if you want - but it will likely white-screen if it hits your php memory limit.
+ // The downside is that http: media files will likely be blocked by your browser
+ // Complain to your browser maker
+
+ $allow = get_config('system','sslify_everything');
+
+ $pattern = (($allow) ? "/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/" : "/\<img(.*?)src=\"(http\:.*?)\"(.*?)\>/" );
+
$matches = null;
- $cnt = preg_match_all("/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/",$s,$matches,PREG_SET_ORDER);
+ $cnt = preg_match_all($pattern,$s,$matches,PREG_SET_ORDER);
if ($cnt) {
foreach ($matches as $match) {
$filename = basename( parse_url($match[2], PHP_URL_PATH) );
@@ -1224,7 +1235,7 @@ function theme_attachments(&$item) {
if($label == ' ')
$label = t('Unknown Attachment');
- $title = t('Attachment') . ' - ' . (($r['length']) ? userReadableSize($r['length']) : t('Size Unknown'));
+ $title = t('Size') . ' ' . (($r['length']) ? userReadableSize($r['length']) : t('unknown'));
require_once('include/identity.php');
if(is_foreigner($item['author_xchan']))
diff --git a/include/widgets.php b/include/widgets.php
index 3e6fdb04c..0f61a04a0 100644
--- a/include/widgets.php
+++ b/include/widgets.php
@@ -642,7 +642,7 @@ function widget_conversations($arr) {
'subject' => (($rr['seen']) ? $rr['title'] : '<strong>' . $rr['title'] . '</strong>'),
'delete' => t('Delete conversation'),
'body' => $rr['body'],
- 'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], t('D, d M Y - g:i A')),
+ 'date' => datetime_convert('UTC',date_default_timezone_get(),$rr['created'], 'c'),
'seen' => $rr['seen'],
'selected' => ((argv(2)) ? (argv(2) == $rr['id']) : ($r[0]['id'] == $rr['id']))
);
diff --git a/include/zot.php b/include/zot.php
index 793eb6b39..d5d68f72c 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -117,7 +117,8 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
'guid' => $channel['channel_guid'],
'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'])),
'url' => z_root(),
- 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']))
+ 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
+ 'sitekey' => get_config('system','pubkey')
),
'callback' => '/post',
'version' => ZOT_REVISION
@@ -569,11 +570,12 @@ function zot_gethub($arr,$multiple = false) {
}
$limit = (($multiple) ? '' : ' limit 1 ');
-
+ $sitekey = ((array_key_exists('sitekey',$arr) && $arr['sitekey']) ? " and hubloc_sitekey = '" . protect_sprintf($arr['sitekey']) . "' " : '');
+
$r = q("select * from hubloc
where hubloc_guid = '%s' and hubloc_guid_sig = '%s'
and hubloc_url = '%s' and hubloc_url_sig = '%s'
- $limit",
+ $sitekey $limit",
dbesc($arr['guid']),
dbesc($arr['guid_sig']),
dbesc($arr['url']),
@@ -814,7 +816,34 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
if ($local) {
$ph = z_fetch_url($arr['photo'], true);
if ($ph['success']) {
- import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'],$local[0]['channel_id']);
+
+ $hash = import_channel_photo($ph['body'], $arr['photo_mimetype'], $local[0]['channel_account_id'], $local[0]['channel_id']);
+
+ if($hash) {
+ // unless proven otherwise
+ $is_default_profile = 1;
+
+ $profile = q("select is_default from profile where aid = %d and uid = %d limit 1",
+ intval($local[0]['channel_account_id']),
+ intval($local[0]['channel_id'])
+ );
+ if($profile) {
+ if(! intval($profile[0]['is_default']))
+ $is_default_profile = 0;
+ }
+
+ // If setting for the default profile, unset the profile photo flag from any other photos I own
+ if($is_default_profile) {
+ q("UPDATE photo SET photo_usage = %d WHERE photo_usage = %d AND resource_id != '%s' AND aid = %d AND uid = %d",
+ intval(PHOTO_NORMAL),
+ intval(PHOTO_PROFILE),
+ dbesc($hash),
+ intval($local[0]['channel_account_id']),
+ intval($local[0]['channel_id'])
+ );
+ }
+ }
+
// reset the names in case they got messed up when we had a bug in this function
$photos = array(
z_root() . '/photo/profile/l/' . $local[0]['channel_id'],
@@ -2337,16 +2366,16 @@ function sync_locations($sender, $arr, $absolute = false) {
$changed = true;
}
}
- if((intval($r[0]['hubloc_deleted']) && (! $location['deleted']))
- || ((! (intval($r[0]['hubloc_deleted']))) && ($location['deleted']))) {
+ if(intval($r[0]['hubloc_deleted']) && (! intval($location['deleted']))) {
$n = q("update hubloc set hubloc_deleted = 0, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
);
- $what .= 'delete_hub ';
+ $what .= 'undelete_hub ';
$changed = true;
}
- elseif((! intval($r[0]['hubloc_deleted'])) && ($location['deleted'])) {
+ elseif((! intval($r[0]['hubloc_deleted'])) && (intval($location['deleted']))) {
+ logger('deleting hubloc: ' . $r[0]['hubloc_addr']);
$n = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($r[0]['hubloc_id'])
@@ -2401,7 +2430,7 @@ function sync_locations($sender, $arr, $absolute = false) {
if($absolute && $xisting) {
foreach($xisting as $x) {
if(! array_key_exists('updated',$x)) {
- logger('sync_locations: deleting unreferenced hub location ' . $x['hubloc_url']);
+ logger('sync_locations: deleting unreferenced hub location ' . $x['hubloc_addr']);
$r = q("update hubloc set hubloc_deleted = 1, hubloc_updated = '%s' where hubloc_id = %d",
dbesc(datetime_convert()),
intval($x['hubloc_id'])
@@ -2437,6 +2466,13 @@ function zot_encode_locations($channel) {
if($x && count($x)) {
foreach($x as $hub) {
+
+ // if this is a local channel that has been deleted, the hubloc is no good - make sure it is marked deleted
+ // so that nobody tries to use it.
+
+ if(intval($channel['channel_removed']) && $hub['hubloc_url'] === z_root())
+ $hub['hubloc_deleted'] = 1;
+
$ret[] = array(
'host' => $hub['hubloc_host'],
'address' => $hub['hubloc_addr'],
@@ -3709,6 +3745,8 @@ function zotinfo($arr) {
$ret['public_forum'] = $public_forum;
if($deleted)
$ret['deleted'] = $deleted;
+ if(intval($e['channel_removed']))
+ $ret['deleted_locally'] = true;
// premium or other channel desiring some contact with potential followers before connecting.
// This is a template - %s will be replaced with the follow_url we discover for the return channel.