diff options
author | Wave <wave72@users.noreply.github.com> | 2015-11-06 09:09:58 +0100 |
---|---|---|
committer | Wave <wave72@users.noreply.github.com> | 2015-11-06 09:09:58 +0100 |
commit | 30d083ac3cbdf36171cfee7b892271b9b587325c (patch) | |
tree | f2f63728f86f8336330d31ee8edf2fcd742dc71e /include | |
parent | 50cf095c000813d0b1408d929c1fa7422b131a3d (diff) | |
parent | 4ca0c2cfd14df5e2b6e9c7f59a10628f7653d6a4 (diff) | |
download | volse-hubzilla-30d083ac3cbdf36171cfee7b892271b9b587325c.tar.gz volse-hubzilla-30d083ac3cbdf36171cfee7b892271b9b587325c.tar.bz2 volse-hubzilla-30d083ac3cbdf36171cfee7b892271b9b587325c.zip |
Merge pull request #2 from redmatrix/master
Update to latest hubzilla
Diffstat (limited to 'include')
-rw-r--r-- | include/Contact.php | 5 | ||||
-rw-r--r-- | include/ItemObject.php | 5 | ||||
-rw-r--r-- | include/RedDAV/RedBrowser.php | 55 | ||||
-rw-r--r-- | include/RedDAV/RedDirectory.php | 2 | ||||
-rw-r--r-- | include/RedDAV/RedFile.php | 12 | ||||
-rw-r--r-- | include/api.php | 72 | ||||
-rw-r--r-- | include/apps.php | 11 | ||||
-rw-r--r-- | include/attach.php | 42 | ||||
-rw-r--r-- | include/bb2diaspora.php | 20 | ||||
-rw-r--r-- | include/bbcode.php | 44 | ||||
-rw-r--r-- | include/conversation.php | 14 | ||||
-rw-r--r-- | include/dir_fns.php | 8 | ||||
-rw-r--r-- | include/features.php | 5 | ||||
-rwxr-xr-x | include/items.php | 18 | ||||
-rw-r--r-- | include/notifier.php | 6 | ||||
-rw-r--r-- | include/photo/photo_driver.php | 22 | ||||
-rw-r--r-- | include/photo/photo_gd.php | 2 | ||||
-rw-r--r-- | include/photos.php | 101 | ||||
-rwxr-xr-x | include/plugin.php | 17 | ||||
-rw-r--r-- | include/text.php | 67 | ||||
-rw-r--r-- | include/widgets.php | 2 | ||||
-rw-r--r-- | include/zot.php | 71 |
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('/\[\&\;([#a-z0-9]+)\;\]/', '&$1;', $Text); // fix any escaped ampersands that may have been converted into links - $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism", '<$1$2=$3&$4>', $Text); + + if(strpos($Text,'&') !== false) + $Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/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; } |