aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/Contact.php5
-rw-r--r--include/ItemObject.php5
-rw-r--r--include/RedDAV/RedBrowser.php55
-rw-r--r--include/RedDAV/RedDirectory.php2
-rw-r--r--include/RedDAV/RedFile.php12
-rw-r--r--include/api.php72
-rw-r--r--include/apps.php11
-rw-r--r--include/attach.php42
-rw-r--r--include/bb2diaspora.php20
-rw-r--r--include/bbcode.php44
-rw-r--r--include/conversation.php14
-rw-r--r--include/dir_fns.php8
-rw-r--r--include/features.php5
-rwxr-xr-xinclude/items.php18
-rw-r--r--include/notifier.php6
-rw-r--r--include/photo/photo_driver.php22
-rw-r--r--include/photo/photo_gd.php2
-rw-r--r--include/photos.php101
-rwxr-xr-xinclude/plugin.php17
-rw-r--r--include/text.php67
-rw-r--r--include/widgets.php2
-rw-r--r--include/zot.php71
22 files changed, 449 insertions, 152 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 ee431dccb..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
@@ -278,8 +279,6 @@ class Item extends BaseObject {
$children = $this->get_children();
- $is_photo = ((($item['resource_type'] == 'photo') && (feature_enabled($conv->get_profile_owner(),'large_photos'))) ? true : false);
-
$has_tags = (($body['tags'] || $body['categories'] || $body['mentions'] || $body['attachments'] || $body['folders']) ? true : false);
$tmp_item = array(
@@ -333,7 +332,7 @@ class Item extends BaseObject {
'owner_url' => $this->get_owner_url(),
'owner_photo' => $this->get_owner_photo(),
'owner_name' => $this->get_owner_name(),
- 'is_photo' => $is_photo,
+ 'photo' => $body['photo'],
'has_tags' => $has_tags,
// Item toolbar buttons
diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php
index d74bba220..efea5d92f 100644
--- a/include/RedDAV/RedBrowser.php
+++ b/include/RedDAV/RedBrowser.php
@@ -217,31 +217,6 @@ class RedBrowser extends DAV\Browser\Plugin {
$f[] = $ft;
}
- // Storage and quota for the account (all channels of the owner of this directory)!
- $limit = service_class_fetch($owner, 'attach_upload_limit');
- $r = q("SELECT SUM(filesize) AS total FROM attach WHERE aid = %d",
- intval($this->auth->channel_account_id)
- );
- $used = $r[0]['total'];
- if ($used) {
- $quotaDesc = t('%1$s used');
- $quotaDesc = sprintf($quotaDesc,
- userReadableSize($used));
- }
- if ($limit && $used) {
- $quotaDesc = t('%1$s used of %2$s (%3$s%)');
- $quotaDesc = sprintf($quotaDesc,
- userReadableSize($used),
- userReadableSize($limit),
- round($used / $limit, 1));
- }
-
- // prepare quota for template
- $quota = array();
- $quota['used'] = $used;
- $quota['limit'] = $limit;
- $quota['desc'] = $quotaDesc;
-
$output = '';
if ($this->enablePost) {
$this->server->broadcastEvent('onHTMLActionsPanel', array($parent, &$output));
@@ -249,7 +224,6 @@ class RedBrowser extends DAV\Browser\Plugin {
$html .= replace_macros(get_markup_template('cloud.tpl'), array(
'$header' => t('Files') . ": " . $this->escapeHTML($path) . "/",
- '$quota' => $quota,
'$total' => t('Total'),
'$actionspanel' => $output,
'$shared' => t('Shared'),
@@ -298,11 +272,38 @@ class RedBrowser extends DAV\Browser\Plugin {
if (get_class($node) === 'Sabre\\DAV\\SimpleCollection')
return;
+ // Storage and quota for the account (all channels of the owner of this directory)!
+ $limit = service_class_fetch($owner, 'attach_upload_limit');
+ $r = q("SELECT SUM(filesize) AS total FROM attach WHERE aid = %d",
+ intval($this->auth->channel_account_id)
+ );
+ $used = $r[0]['total'];
+ if ($used) {
+ $quotaDesc = t('You are using %1$s of your available file storage.');
+ $quotaDesc = sprintf($quotaDesc,
+ userReadableSize($used));
+ }
+ if ($limit && $used) {
+ $quotaDesc = t('You are using %1$s of %2$s available file storage. (%3$s%)');
+ $quotaDesc = sprintf($quotaDesc,
+ userReadableSize($used),
+ userReadableSize($limit),
+ round($used / $limit, 1) * 100);
+ }
+
+ // prepare quota for template
+ $quota = array();
+ $quota['used'] = $used;
+ $quota['limit'] = $limit;
+ $quota['desc'] = $quotaDesc;
+ $quota['warning'] = ((($limit) && ((round($used / $limit, 1) * 100) >= 90)) ? t('WARNING:') : ''); // 10485760 bytes = 100MB
+
$output .= replace_macros(get_markup_template('cloud_actionspanel.tpl'), array(
'$folder_header' => t('Create new folder'),
'$folder_submit' => t('Create'),
'$upload_header' => t('Upload file'),
- '$upload_submit' => t('Upload')
+ '$upload_submit' => t('Upload'),
+ '$quota' => $quota
));
}
diff --git a/include/RedDAV/RedDirectory.php b/include/RedDAV/RedDirectory.php
index 507fde46f..87bdf8f13 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),
diff --git a/include/RedDAV/RedFile.php b/include/RedDAV/RedFile.php
index ec6871a69..2bc3f40e5 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) ? $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/api.php b/include/api.php
index 16dbb569b..b51bcc5f0 100644
--- a/include/api.php
+++ b/include/api.php
@@ -75,8 +75,9 @@ require_once('include/attach.php');
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);
@@ -627,6 +628,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 +892,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 +904,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');
diff --git a/include/apps.php b/include/apps.php
index c036867b1..0a62dc5a8 100644
--- a/include/apps.php
+++ b/include/apps.php
@@ -176,14 +176,19 @@ function app_render($papp,$mode = 'view') {
$installed = false;
- if(! $papp['photo'])
- $papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
-
if(! $papp)
return;
+ if(! $papp['photo'])
+ $papp['photo'] = z_root() . '/' . get_default_profile_photo(80);
+
+
+
$papp['papp'] = papp_encode($papp);
+ if(! strstr($papp['url'],'://'))
+ $papp['url'] = z_root() . ((strpos($papp['url'],'/') === 0) ? '' : '/') . $papp['url'];
+
foreach($papp as $k => $v) {
if(strpos($v,'http') === 0 && $k != 'papp')
$papp[$k] = zid($v);
diff --git a/include/attach.php b/include/attach.php
index f95feed2d..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),
@@ -815,6 +818,12 @@ function attach_store($channel, $observer_hash, $options = '', $arr = null) {
if($arr['item'])
$args['item'] = $arr['item'];
+ if($arr['body'])
+ $args['body'] = $arr['body'];
+
+ if($arr['description'])
+ $args['description'] = $arr['description'];
+
$p = photo_upload($channel,$observer,$args);
if($p['success']) {
$ret['body'] = $p['body'];
@@ -1261,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);
}
@@ -1282,12 +1295,11 @@ function attach_delete($channel_id, $resource, $is_photo = 0) {
);
if($x) {
drop_item($x[0]['id'],false,(($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1),true);
-
- q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
- intval($channel_id),
- dbesc($resource)
- );
}
+ q("DELETE FROM photo WHERE uid = %d AND resource_id = '%s'",
+ intval($channel_id),
+ dbesc($resource)
+ );
}
// update the parent folder's lastmodified timestamp
diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php
index 692128087..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);
@@ -305,6 +305,15 @@ function bb2diaspora_itembody($item, $force_update = false) {
$matches = array();
+ //if we have a photo item just prepend the photo bbcode to item['body']
+ $is_photo = (($item['obj_type'] == ACTIVITY_OBJ_PHOTO) ? true : false);
+ if($is_photo) {
+ $object = json_decode($item['object'],true);
+ if($object['bbcode']) {
+ $item['body'] = (($item['body']) ? $object['bbcode'] . "\r\n" . $item['body'] : $object['bbcode']);
+ }
+ }
+
if(($item['diaspora_meta']) && (! $force_update)) {
$diaspora_meta = json_decode($item['diaspora_meta'],true);
if($diaspora_meta) {
@@ -431,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 db5824237..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
@@ -570,7 +570,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$urlchars = '[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,\@]';
if (strpos($Text,'http') !== false) {
- $Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ism", '$1<a href="$2" >$2</a>', $Text);
+ $Text = preg_replace("/([^\]\='".'"'."\/]|^|\#\^)(https?\:\/\/$urlchars+)/ism", '$1<a href="$2" target="_newwin" >$2</a>', $Text);
}
if (strpos($Text,'[/share]') !== false) {
@@ -582,23 +582,24 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
}
}
if (strpos($Text,'[/url]') !== false) {
- $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" >$2</a>', $Text);
- $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" >$2</a>', $Text);
+ $Text = preg_replace("/\#\^\[url\]([$URLSearchString]*)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\#\^\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<span class="bookmark-identifier">#^</span><a class="bookmark" href="$1" target="_newwin" >$2</a>', $Text);
+ $Text = preg_replace("/\[url\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="_newwin" >$2</a>', $Text);
}
if (strpos($Text,'[/zrl]') !== false) {
- $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" >$2</a>', $Text);
- $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" >$1</a>', $Text);
- $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" >$2</a>', $Text);
+ $Text = preg_replace("/\#\^\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\#\^\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<span class="bookmark-identifier">#^</span><a class="zrl bookmark" href="$1" target="_newwin" >$2</a>', $Text);
+ $Text = preg_replace("/\[zrl\]([$URLSearchString]*)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_newwin" >$1</a>', $Text);
+ $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '<a class="zrl" href="$1" target="_newwin" >$2</a>', $Text);
}
// Perform MAIL Search
if (strpos($Text,'[/mail]') !== false) {
- $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
- $Text = preg_replace("/\[mail\=([$MAILSearchString]*)\](.*?)\[\/mail\]/", '<a href="mailto:$1">$2</a>', $Text);
+ $Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1" target="_newwin" >$1</a>', $Text);
+ $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
@@ -885,17 +886,17 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
// if video couldn't be embedded, link to it instead.
if (strpos($Text,'[/video]') !== false) {
- $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[video\](.*?)\[\/video\]/", '<a href="$1" target="_newwin" >$1</a>', $Text);
}
if (strpos($Text,'[/audio]') !== false) {
- $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[audio\](.*?)\[\/audio\]/", '<a href="$1" target="_newwin" >$1</a>', $Text);
}
if (strpos($Text,'[/zvideo]') !== false) {
- $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[zvideo\](.*?)\[\/zvideo\]/", '<a class="zid" href="$1" target="_newwin" >$1</a>', $Text);
}
if (strpos($Text,'[/zaudio]') !== false) {
- $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[zaudio\](.*?)\[\/zaudio\]/", '<a class="zid" href="$1" target="_newwin" >$1</a>', $Text);
}
if ($tryoembed){
@@ -904,7 +905,7 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
}
} else {
if (strpos($Text,'[/iframe]') !== false) {
- $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1">$1</a>', $Text);
+ $Text = preg_replace("/\[iframe\](.*?)\[\/iframe\]/ism", '<a href="$1" target="_newwin" >$1</a>', $Text);
}
}
@@ -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 ebbc6684c..a5fe573cd 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,
@@ -1166,6 +1169,10 @@ function status_editor($a, $x, $popup = false) {
if($defexpire)
$defexpire = datetime_convert('UTC',date_default_timezone_get(),$defexpire,'Y-m-d H:i');
+ $defpublish = ((($z = get_pconfig($x['profile_uid'], 'system', 'default_post_publish')) && (! $webpage)) ? $z : '');
+ if($defpublish)
+ $defpublish = datetime_convert('UTC',date_default_timezone_get(),$defpublish,'Y-m-d H:i');
+
$cipher = get_pconfig($x['profile_uid'], 'system', 'default_cipher');
if(! $cipher)
$cipher = 'aes256';
@@ -1237,6 +1244,9 @@ function status_editor($a, $x, $popup = false) {
'$defexpire' => $defexpire,
'$feature_expire' => ((feature_enabled($x['profile_uid'], 'content_expire') && (! $webpage)) ? true : false),
'$expires' => t('Set expiration date'),
+ '$defpublish' => $defpublish,
+ '$feature_future' => ((feature_enabled($x['profile_uid'], 'delayed_posting') && (! $webpage)) ? true : false),
+ '$future_txt' => t('Set publish date'),
'$feature_encrypt' => ((feature_enabled($x['profile_uid'], 'content_encrypt') && (! $webpage)) ? true : false),
'$encrypt' => t('Encrypt text'),
'$cipher' => $cipher,
diff --git a/include/dir_fns.php b/include/dir_fns.php
index e466b7404..e5f0e1e2b 100644
--- a/include/dir_fns.php
+++ b/include/dir_fns.php
@@ -178,9 +178,10 @@ function sync_directories($dirmode) {
'site_directory' => DIRECTORY_FALLBACK_MASTER . '/dirsearch',
'site_realm' => DIRECTORY_REALM,
'site_valid' => 1
+
);
$x = q("insert into site ( site_url, site_flags, site_update, site_directory, site_realm, site_valid )
- values ( '%s', %d', '%s', '%s', '%s' ) ",
+ values ( '%s', %d, '%s', '%s', '%s', %d ) ",
dbesc($r[0]['site_url']),
intval($r[0]['site_flags']),
dbesc($r[0]['site_update']),
@@ -189,8 +190,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/features.php b/include/features.php
index a6c4757cd..74ae7b3d7 100644
--- a/include/features.php
+++ b/include/features.php
@@ -55,10 +55,11 @@ function get_features() {
t('Post Composition Features'),
// array('richtext', t('Richtext Editor'), t('Enable richtext editor'),false),
array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts'),false),
- array('large_photos', t('Large Photos'), t('Include large (640px) photo thumbnails in posts. If not enabled, use small (320px) photo thumbnails'),false),
+ array('large_photos', t('Large Photos'), t('Include large (1024px) photo thumbnails in posts. If not enabled, use small (640px) photo thumbnails'),false),
array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds'),false),
array('content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key'),false),
- array('consensus_tools', t('Enable voting tools'), t('Provide a class of post which others can vote on'),false),
+ array('consensus_tools', t('Enable Voting Tools'), t('Provide a class of post which others can vote on'),false),
+ array('delayed_posting', t('Delayed Posting'), t('Allow posts to be published at a later date'),false),
),
diff --git a/include/items.php b/include/items.php
index 9159f6da3..3e4805212 100755
--- a/include/items.php
+++ b/include/items.php
@@ -889,7 +889,6 @@ function get_item_elements($x,$allow_code = false) {
$arr['mimetype'] = (($x['mimetype']) ? htmlspecialchars($x['mimetype'], ENT_COMPAT,'UTF-8',false) : '');
$arr['obj_type'] = (($x['object_type']) ? htmlspecialchars($x['object_type'], ENT_COMPAT,'UTF-8',false) : '');
$arr['tgt_type'] = (($x['target_type']) ? htmlspecialchars($x['target_type'], ENT_COMPAT,'UTF-8',false) : '');
- $arr['resource_type'] = (($x['resource_type']) ? htmlspecialchars($x['resource_type'], ENT_COMPAT,'UTF-8',false) : '');
$arr['public_policy'] = (($x['public_scope']) ? htmlspecialchars($x['public_scope'], ENT_COMPAT,'UTF-8',false) : '');
if($arr['public_policy'] === 'public')
@@ -1286,7 +1285,6 @@ function encode_item($item,$mirror = false) {
$x['verb'] = $item['verb'];
$x['object_type'] = $item['obj_type'];
$x['target_type'] = $item['tgt_type'];
- $x['resource_type'] = $item['resource_type'];
$x['permalink'] = $item['plink'];
$x['location'] = $item['location'];
$x['longlat'] = $item['coord'];
@@ -2839,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",
@@ -2866,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'];
@@ -2873,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",
@@ -3457,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)) {
@@ -4794,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/notifier.php b/include/notifier.php
index b7cea629d..34a527e15 100644
--- a/include/notifier.php
+++ b/include/notifier.php
@@ -127,7 +127,7 @@ function notifier_run($argv, $argc){
if($s) {
$perm_update = array('sender' => $s[0], 'recipient' => $r[0], 'success' => false, 'deliveries' => '');
- if($cmd == 'permission_create'])
+ if($cmd == 'permission_create')
call_hooks('permissions_create',$perm_update);
else
call_hooks('permissions_update',$perm_update);
@@ -366,7 +366,7 @@ function notifier_run($argv, $argc){
logger('notifier: target item not forwardable: type ' . $target_item['item_type'], LOGGER_DEBUG);
return;
}
- if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed_publish'])) {
+ if(intval($target_item['item_unpublished']) || intval($target_item['item_delayed'])) {
logger('notifier: target item not published, so not forwardable', LOGGER_DEBUG);
return;
}
@@ -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 e78b899e0..c7360a956 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -7,6 +7,7 @@
require_once('include/permissions.php');
require_once('include/items.php');
require_once('include/photo/photo_driver.php');
+require_once('include/text.php');
/**
* @brief
@@ -18,6 +19,8 @@ require_once('include/photo/photo_driver.php');
*/
function photo_upload($channel, $observer, $args) {
+ $a = get_app();
+
$ret = array('success' => false);
$channel_id = $channel['channel_id'];
$account_id = $channel['channel_account_id'];
@@ -185,8 +188,16 @@ function photo_upload($channel, $observer, $args) {
if($args['description'])
$p['description'] = $args['description'];
+ $link = array();
+
$r0 = $ph->save($p);
- $r0wxh = $ph->getWidth() . 'x' . $ph->getHeight();
+ $link[0] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-0.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
if(! $r0)
$errors = true;
@@ -198,7 +209,13 @@ function photo_upload($channel, $observer, $args) {
$p['scale'] = 1;
$r1 = $ph->save($p);
- $r1wxh = $ph->getWidth() . 'x' . $ph->getHeight();
+ $link[1] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-1.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
if(! $r1)
$errors = true;
@@ -207,7 +224,13 @@ function photo_upload($channel, $observer, $args) {
$p['scale'] = 2;
$r2 = $ph->save($p);
- $r2wxh = $ph->getWidth() . 'x' . $ph->getHeight();
+ $link[2] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-2.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
if(! $r2)
$errors = true;
@@ -216,7 +239,13 @@ function photo_upload($channel, $observer, $args) {
$p['scale'] = 3;
$r3 = $ph->save($p);
- $r3wxh = $ph->getWidth() . 'x' . $ph->getHeight();
+ $link[3] = array(
+ 'rel' => 'alternate',
+ 'type' => 'text/html',
+ 'href' => $url = rawurlencode(z_root() . '/photo/' . $photo_hash . '-3.' . $ph->getExt()),
+ 'width' => $ph->getWidth(),
+ 'height' => $ph->getHeight()
+ );
if(! $r3)
$errors = true;
@@ -242,19 +271,41 @@ function photo_upload($channel, $observer, $args) {
}
}
- $larger = feature_enabled($channel['channel_id'], 'large_photos');
+ $title = (($args['description']) ? $args['description'] : $args['filename']);
+
+ $large_photos = feature_enabled($channel['channel_id'], 'large_photos');
+
+ linkify_tags($a, $args['body'], $channel_id);
- if($larger) {
- $tag = (($r1wxh) ? '[zmg=' . $r1wxh . ']' : '[zmg]');
+ if($large_photos) {
$scale = 1;
+ $width = $link[1]['width'];
+ $height = $link[1]['height'];
+ $tag = (($r1) ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]');
+
+
}
else {
- $tag = (($r2wxh) ? '[zmg=' . $r2wxh . ']' : '[zmg]');
$scale = 2;
+ $width = $link[2]['width'];
+ $height = $link[2]['height'];
+ $tag = (($r2) ? '[zmg=' . $width . 'x' . $height . ']' : '[zmg]');
}
- // Create item container
+ $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,
+ 'bbcode' => $body
+ );
+
+ // Create item container
if($args['item']) {
foreach($args['item'] as $i) {
@@ -263,13 +314,13 @@ function photo_upload($channel, $observer, $args) {
if($item['mid'] === $item['parent_mid']) {
- $item['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
- . $tag . z_root() . "/photo/{$photo_hash}-{$scale}.".$ph->getExt() . '[/zmg]'
- . '[/zrl]';
+ $item['body'] = (($object) ? $args['body'] : $body . "\r\n" . $args['body']);
+ $item['obj_type'] = (($object) ? ACTIVITY_OBJ_PHOTO : '');
+ $item['object'] = (($object) ? json_encode($object) : '');
if($item['author_xchan'] === $channel['channel_hash']) {
- $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
- $item['item_verified'] = 1;
+ $item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
+ $item['item_verified'] = 1;
}
else {
$item['sig'] = '';
@@ -297,7 +348,6 @@ function photo_upload($channel, $observer, $args) {
}
}
else {
- $title = $args['filename'] ? $args['filename'] : '';
$mid = item_message_id();
$arr = array();
@@ -320,15 +370,28 @@ function photo_upload($channel, $observer, $args) {
$arr['deny_cid'] = $ac['deny_cid'];
$arr['deny_gid'] = $ac['deny_gid'];
$arr['verb'] = ACTIVITY_POST;
+ $arr['obj_type'] = (($object) ? ACTIVITY_OBJ_PHOTO : '');
+ $arr['object'] = (($object) ? json_encode($object) : '');
$arr['item_wall'] = 1;
$arr['item_origin'] = 1;
$arr['item_thread_top'] = 1;
$arr['item_private'] = intval($acl->is_private());
$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;
+
- $arr['body'] = '[zrl=' . z_root() . '/photos/' . $channel['channel_address'] . '/image/' . $photo_hash . ']'
- . $tag . z_root() . "/photo/{$photo_hash}-{$scale}.".$ph->getExt() . '[/zmg]'
- . '[/zrl]';
$result = item_store($arr);
$item_id = $result['item_id'];
@@ -339,7 +402,7 @@ function photo_upload($channel, $observer, $args) {
$ret['success'] = true;
$ret['item'] = $arr;
- $ret['body'] = $arr['body'];
+ $ret['body'] = $body;
$ret['resource_id'] = $photo_hash;
$ret['photoitem_id'] = $item_id;
diff --git a/include/plugin.php b/include/plugin.php
index 4d8405b62..8749f3fbf 100755
--- a/include/plugin.php
+++ b/include/plugin.php
@@ -504,18 +504,21 @@ function script_path() {
$scheme = 'https';
else
$scheme = 'http';
+
+ // Some proxy setups may require using http_host
- if(x($_SERVER,'SERVER_NAME')) {
- $hostname = $_SERVER['SERVER_NAME'];
+ if(intval(get_app()->config['system']['script_path_use_http_host']))
+ $server_var = 'HTTP_HOST';
+ else
+ $server_var = 'SERVER_NAME';
+
+
+ if(x($_SERVER,$server_var)) {
+ $hostname = $_SERVER[$server_var];
}
else {
return z_root();
}
-
- if(x($_SERVER,'SERVER_PORT') && $_SERVER['SERVER_PORT'] != 80 && $_SERVER['SERVER_PORT'] != 443) {
- $hostname .= ':' . $_SERVER['SERVER_PORT'];
- }
-
return $scheme . '://' . $hostname;
}
diff --git a/include/text.php b/include/text.php
index 25743e872..c2573da0c 100644
--- a/include/text.php
+++ b/include/text.php
@@ -912,8 +912,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 +1233,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']))
@@ -1363,6 +1372,7 @@ function generate_named_map($location) {
function prepare_body(&$item,$attach = false) {
+ require_once('include/identity.php');
// if($item['html']) {
// $s = bb_observer($item['html']);
@@ -1373,9 +1383,35 @@ function prepare_body(&$item,$attach = false) {
$s = prepare_text($item['body'],$item['mimetype'], false);
// }
- $prep_arr = array('item' => $item, 'html' => $s);
+
+ $photo = '';
+ $is_photo = (($item['obj_type'] === ACTIVITY_OBJ_PHOTO) ? true : false);
+
+ if($is_photo) {
+ $object = json_decode($item['object'],true);
+
+ // if original photo width is <= 640px prepend it to item body
+ if($object['link'][0]['width'] && $object['link'][0]['width'] <= 640) {
+ $s = '<div class="inline-photo-item-wrapper"><a href="' . zid(rawurldecode($object['id'])) . '" target="_newwin"><img class="inline-photo-item" style="max-width:' . $object['link'][0]['width'] . 'px; width:100%; height:auto;" src="' . zid(rawurldecode($object['link'][0]['href'])) . '"></a></div>' . $s;
+ }
+
+ // if original photo width is > 640px make it a cover photo
+ if($object['link'][0]['width'] && $object['link'][0]['width'] > 640) {
+ $scale = ((($object['link'][1]['width'] == 1024) || ($object['link'][1]['height'] == 1024)) ? 1 : 0);
+ $photo = '<a href="' . zid(rawurldecode($object['id'])) . '" target="_newwin"><img style="max-width:' . $object['link'][$scale]['width'] . 'px; width:100%; height:auto;" src="' . zid(rawurldecode($object['link'][$scale]['href'])) . '"></a>';
+ }
+ }
+
+ $prep_arr = array(
+ 'item' => $item,
+ 'html' => $s,
+ 'photo' => $photo
+ );
+
call_hooks('prepare_body', $prep_arr);
+
$s = $prep_arr['html'];
+ $photo = $prep_arr['photo'];
// q("update item set html = '%s' where id = %d",
// dbesc($s),
@@ -1391,7 +1427,7 @@ function prepare_body(&$item,$attach = false) {
if($x) {
$s = preg_replace('/\<div class\=\"map\"\>/','$0' . $x,$s);
}
- }
+ }
$attachments = theme_attachments($item);
@@ -1439,17 +1475,20 @@ function prepare_body(&$item,$attach = false) {
}
$prep_arr = array(
- //'item' => $item,
- 'html' => $s,
- 'categories' => $categories,
- 'folders' => $filer,
- 'tags' => $tags,
- 'mentions' => $mentions,
- 'attachments' => $attachments
- );
+ 'item' => $item,
+ 'photo' => $photo,
+ 'html' => $s,
+ 'categories' => $categories,
+ 'folders' => $filer,
+ 'tags' => $tags,
+ 'mentions' => $mentions,
+ 'attachments' => $attachments
+ );
call_hooks('prepare_body_final', $prep_arr);
+ unset($prep_arr['item']);
+
return $prep_arr;
}
@@ -1967,13 +2006,13 @@ function xchan_query(&$items,$abook = true,$effective_uid = 0) {
if(count($arr)) {
if($abook) {
$chans = q("select * from xchan left join hubloc on hubloc_hash = xchan_hash left join abook on abook_xchan = xchan_hash and abook_channel = %d
- where xchan_hash in (" . implode(',', $arr) . ") and hubloc_primary = 1",
+ where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and hubloc_primary = 1",
intval($item['uid'])
);
}
else {
$chans = q("select xchan.*,hubloc.* from xchan left join hubloc on hubloc_hash = xchan_hash
- where xchan_hash in (" . implode(',', $arr) . ") and hubloc_primary = 1");
+ where xchan_hash in (" . protect_sprintf(implode(',', $arr)) . ") and hubloc_primary = 1");
}
$xchans = q("select * from xchan where xchan_hash in (" . protect_sprintf(implode(',',$arr)) . ") and xchan_network in ('rss','unknown')");
if(! $chans)
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 02dab3617..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'],
@@ -2739,6 +2775,7 @@ function import_site($arr, $pubkey) {
$sellpage = htmlspecialchars($arr['sellpage'],ENT_COMPAT,'UTF-8',false);
$site_location = htmlspecialchars($arr['location'],ENT_COMPAT,'UTF-8',false);
$site_realm = htmlspecialchars($arr['realm'],ENT_COMPAT,'UTF-8',false);
+ $site_project = htmlspecialchars($arr['project'],ENT_COMPAT,'UTF-8',false);
// You can have one and only one primary directory per realm.
// Downgrade any others claiming to be primary. As they have
@@ -2757,13 +2794,15 @@ function import_site($arr, $pubkey) {
|| ($siterecord['site_sellpage'] != $sellpage)
|| ($siterecord['site_location'] != $site_location)
|| ($siterecord['site_register'] != $register_policy)
+ || ($siterecord['site_project'] != $site_project)
|| ($siterecord['site_realm'] != $site_realm)) {
$update = true;
// logger('import_site: input: ' . print_r($arr,true));
// logger('import_site: stored: ' . print_r($siterecord,true));
- $r = q("update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d
+
+ $r = q("update site set site_dead = 0, site_location = '%s', site_flags = %d, site_access = %d, site_directory = '%s', site_register = %d, site_update = '%s', site_sellpage = '%s', site_realm = '%s', site_type = %d, site_project = '%s'
where site_url = '%s'",
dbesc($site_location),
intval($site_directory),
@@ -2774,6 +2813,7 @@ function import_site($arr, $pubkey) {
dbesc($sellpage),
dbesc($site_realm),
intval(SITE_TYPE_ZOT),
+ dbesc($site_project),
dbesc($url)
);
if(! $r) {
@@ -2790,8 +2830,9 @@ function import_site($arr, $pubkey) {
}
else {
$update = true;
- $r = q("insert into site ( site_location, site_url, site_access, site_flags, site_update, site_directory, site_register, site_sellpage, site_realm, site_type )
- values ( '%s', '%s', %d, %d, '%s', '%s', %d, '%s', '%s', %d )",
+
+ $r = q("insert into site ( site_location, site_url, site_access, site_flags, site_update, site_directory, site_register, site_sellpage, site_realm, site_type, site_project )
+ values ( '%s', '%s', %d, %d, '%s', '%s', %d, '%s', '%s', %d, '%s' )",
dbesc($site_location),
dbesc($url),
intval($access_policy),
@@ -2801,7 +2842,8 @@ function import_site($arr, $pubkey) {
intval($register_policy),
dbesc($sellpage),
dbesc($site_realm),
- intval(SITE_TYPE_ZOT)
+ intval(SITE_TYPE_ZOT),
+ dbesc($site_project)
);
if(! $r) {
logger('import_site: record create failed. ' . print_r($arr,true));
@@ -3703,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.
@@ -3810,6 +3854,7 @@ function zotinfo($arr) {
$ret['site']['sellpage'] = get_config('system','sellpage');
$ret['site']['location'] = get_config('system','site_location');
$ret['site']['realm'] = get_directory_realm();
+ $ret['site']['project'] = PLATFORM_NAME;
}