diff options
author | anaqreon <tamanning@zoho.com> | 2014-12-30 16:06:35 -0600 |
---|---|---|
committer | anaqreon <tamanning@zoho.com> | 2014-12-30 16:06:35 -0600 |
commit | b78a545a1056e6db9f4b6b4f262182b0a5c56e67 (patch) | |
tree | 515c2f742a5a39e18b00debf1849ee9703fa4a42 /include | |
parent | d67c5a6ffd134602084a6dcb37b316bf768bf715 (diff) | |
parent | 43671a0a323afa758df56c06822ce3c46da026df (diff) | |
download | volse-hubzilla-b78a545a1056e6db9f4b6b4f262182b0a5c56e67.tar.gz volse-hubzilla-b78a545a1056e6db9f4b6b4f262182b0a5c56e67.tar.bz2 volse-hubzilla-b78a545a1056e6db9f4b6b4f262182b0a5c56e67.zip |
Merge pull request #1 from friendica/master
Pull from upstream
Diffstat (limited to 'include')
-rw-r--r-- | include/Contact.php | 66 | ||||
-rw-r--r-- | include/Import/Importer.php | 38 | ||||
-rw-r--r-- | include/Import/refimport.php | 2 | ||||
-rw-r--r-- | include/ItemObject.php | 14 | ||||
-rw-r--r-- | include/RedDAV/RedBasicAuth.php | 7 | ||||
-rw-r--r-- | include/RedDAV/RedBrowser.php | 89 | ||||
-rw-r--r-- | include/activities.php | 6 | ||||
-rw-r--r-- | include/api.php | 26 | ||||
-rw-r--r-- | include/apps.php | 113 | ||||
-rw-r--r-- | include/attach.php | 2 | ||||
-rw-r--r-- | include/auth.php | 24 | ||||
-rw-r--r-- | include/bb2diaspora.php | 24 | ||||
-rw-r--r-- | include/bbcode.php | 36 | ||||
-rw-r--r-- | include/conversation.php | 24 | ||||
-rw-r--r-- | include/dir_fns.php | 21 | ||||
-rw-r--r-- | include/features.php | 4 | ||||
-rw-r--r-- | include/fixd.php | 33 | ||||
-rw-r--r-- | include/hubloc.php | 2 | ||||
-rw-r--r-- | include/identity.php | 17 | ||||
-rw-r--r-- | include/nav.php | 55 | ||||
-rw-r--r-- | include/network.php | 30 | ||||
-rw-r--r-- | include/notifier.php | 53 | ||||
-rw-r--r-- | include/permissions.php | 270 | ||||
-rw-r--r-- | include/poller.php | 2 | ||||
-rw-r--r-- | include/security.php | 121 | ||||
-rw-r--r-- | include/taxonomy.php | 20 | ||||
-rw-r--r-- | include/text.php | 735 | ||||
-rw-r--r-- | include/widgets.php | 172 | ||||
-rw-r--r-- | include/zot.php | 21 |
29 files changed, 1301 insertions, 726 deletions
diff --git a/include/Contact.php b/include/Contact.php index 64779d45f..233798181 100644 --- a/include/Contact.php +++ b/include/Contact.php @@ -207,6 +207,7 @@ function account_remove($account_id,$local = true,$unset_session=true) { intval($account_id) ); + if ($unset_session) { unset($_SESSION['authenticated']); unset($_SESSION['uid']); @@ -216,6 +217,28 @@ function account_remove($account_id,$local = true,$unset_session=true) { return $r; } +// recursively delete a directory +function rrmdir($path) +{ + if (is_dir($path) === true) + { + $files = array_diff(scandir($path), array('.', '..')); + + foreach ($files as $file) + { + rrmdir(realpath($path) . '/' . $file); + } + + return rmdir($path); + } + + else if (is_file($path) === true) + { + return unlink($path); + } + + return false; +} function channel_remove($channel_id, $local = true, $unset_session=true) { @@ -311,6 +334,19 @@ function channel_remove($channel_id, $local = true, $unset_session=true) { dbesc($channel['channel_hash']) ); } + + //remove from file system + $r = q("select channel_address from channel where channel_id = %d limit 1", + intval($channel_id) + ); + if($r) + $channel_address = $r[0]['channel_address'] ; + if ($channel_address !== '') { + $f = 'store/' . $channel_address.'/'; + logger ('delete '. $f); + if(is_dir($f)) + @rrmdir($f); + } proc_run('php','include/directory.php',$channel_id); @@ -545,12 +581,30 @@ function contact_remove($channel_id, $abook_id) { function random_profile() { $randfunc = db_getfunc('rand'); - $r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_connected > %s - interval %s order by $randfunc limit 1", - db_utcnow(), db_quoteinterval('30 day') - ); - if($r) - return $r[0]['xchan_url']; + + $checkrandom = get_config('randprofile','check'); // False by default + $retryrandom = intval(get_config('randprofile','retry')); + if($retryrandom === false) $retryrandom = 5; + + for($i = 0; $i < $retryrandom; $i++) { + $r = q("select xchan_url from xchan left join hubloc on hubloc_hash = xchan_hash where hubloc_connected > %s - interval %s order by $randfunc limit 1", + db_utcnow(), db_quoteinterval('30 day') + ); + + if(!$r) return ''; // Couldn't get a random channel + + if($checkrandom) { + $x = z_fetch_url($r[0]['xchan_url']); + if($x['success']) + return $r[0]['xchan_url']; + else + logger('Random channel turned out to be bad.'); + } + else { + return $r[0]['xchan_url']; + } + + } return ''; } - diff --git a/include/Import/Importer.php b/include/Import/Importer.php index c42344236..5e684cd8e 100644 --- a/include/Import/Importer.php +++ b/include/Import/Importer.php @@ -1,26 +1,28 @@ <?php /** @file */ -namespace Redmatrix\Import; - +namespace RedMatrix\Import; +/** + * @brief Class Import + * + * @package RedMatrix\Import + */ class Import { - $credentials = null; - $itemlist = null; - $src_items = null; + private $credentials = null; - $items = null; + protected $itemlist = null; + protected $src_items = null; + protected $items = null; function get_credentials() { - + return $this->credentials; } function get_itemlist() { - - + return $this->itemlist; } - function get_item_ident($item) { } @@ -43,19 +45,17 @@ class Import { function convert_taxonomy($item_ident) { - } function convert_child($child) { } - function store($item,$update = false) { + function store($item, $update = false) { } function run() { - $this->credentials = $this->get_credentials(); $this->itemlist = $this->get_itemlist(); if($this->itemlist) { @@ -77,18 +77,6 @@ class Import { } $cnt ++; } - - - - } - - - - - - } - - }
\ No newline at end of file diff --git a/include/Import/refimport.php b/include/Import/refimport.php index 4f2572660..181b2b398 100644 --- a/include/Import/refimport.php +++ b/include/Import/refimport.php @@ -13,8 +13,6 @@ require_once('include/hubloc.php'); // with a browser until all the posts had been imported. - - define('REDMATRIX_IMPORTCHANNEL','mike'); define('REFLECT_EXPORTUSERNAME','mike'); define('REFLECT_BLOGNAME','Diary and Other Rantings'); diff --git a/include/ItemObject.php b/include/ItemObject.php index 6037daa7a..ec8116297 100644 --- a/include/ItemObject.php +++ b/include/ItemObject.php @@ -231,7 +231,14 @@ 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 + // since we can't depend on llink or plink pointing to the right local location. + + $owner_address = substr($item['owner']['xchan_addr'],0,strpos($item['owner']['xchan_addr'],'@')); + $viewthread = $item['llink']; + if($conv->get_mode() === 'channel') + $viewthread = z_root() . '/channel/' . $owner_address . '?f=&mid=' . $item['mid']; $comment_count_txt = sprintf( tt('%d comment','%d comments',$total_children),$total_children ); $list_unseen_txt = (($unseen_comments) ? sprintf('%d unseen',$unseen_comments) : ''); @@ -249,6 +256,7 @@ class Item extends BaseObject { 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, $item['author']['xchan_addr']), 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $this->get_owner_name(), $item['owner']['xchan_addr']), 'llink' => $item['llink'], + 'viewthread' => $viewthread, 'to' => t('to'), 'via' => t('via'), 'wall' => t('Wall-to-Wall'), @@ -284,7 +292,7 @@ class Item extends BaseObject { 'share' => $share, 'rawmid' => $item['mid'], 'plink' => get_plink($item), - 'edpost' => ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''), + 'edpost' => $edpost, // ((feature_enabled($conv->get_profile_owner(),'edit_posts')) ? $edpost : ''), 'star' => ((feature_enabled($conv->get_profile_owner(),'star_posts')) ? $star : ''), 'tagger' => ((feature_enabled($conv->get_profile_owner(),'commtag')) ? $tagger : ''), 'filer' => ((feature_enabled($conv->get_profile_owner(),'filing')) ? $filer : ''), @@ -627,7 +635,7 @@ class Item extends BaseObject { '$edimg' => t('Image'), '$edurl' => t('Link'), '$edvideo' => t('Video'), - '$preview' => ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''), + '$preview' => t('Preview'), // ((feature_enabled($conv->get_profile_owner(),'preview')) ? t('Preview') : ''), '$indent' => $indent, '$feature_encrypt' => ((feature_enabled($conv->get_profile_owner(),'content_encrypt')) ? true : false), '$encrypt' => t('Encrypt text'), diff --git a/include/RedDAV/RedBasicAuth.php b/include/RedDAV/RedBasicAuth.php index 2f86d4f82..19dd9a5f0 100644 --- a/include/RedDAV/RedBasicAuth.php +++ b/include/RedDAV/RedBasicAuth.php @@ -118,8 +118,11 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic { } } } - logger('password failed for ' . $username); - // @TODO add security logger + + $error = 'password failed for ' . $username; + logger($error); + log_failed_login($error); + return false; } diff --git a/include/RedDAV/RedBrowser.php b/include/RedDAV/RedBrowser.php index 21ea76aed..709f6339b 100644 --- a/include/RedDAV/RedBrowser.php +++ b/include/RedDAV/RedBrowser.php @@ -173,6 +173,7 @@ class RedBrowser extends DAV\Browser\Plugin { $type = $this->escapeHTML($type); $icon = ''; + if ($this->enableAssets) { $node = $this->server->tree->getNodeForPath(($path ? $path . '/' : '') . $name); foreach (array_reverse($this->iconMap) as $class=>$iconName) { @@ -182,10 +183,10 @@ class RedBrowser extends DAV\Browser\Plugin { } } } - - $parentHash = ""; + + $parentHash = ''; $owner = $this->auth->owner_id; - $splitPath = split("/", $fullPath); + $splitPath = split('/', $fullPath); if (count($splitPath) > 3) { for ($i = 3; $i < count($splitPath); $i++) { $attachName = urldecode($splitPath[$i]); @@ -209,6 +210,7 @@ class RedBrowser extends DAV\Browser\Plugin { $ft['size'] = $size; $ft['sizeFormatted'] = $this->userReadableSize($size); $ft['lastmodified'] = (($lastmodified) ? datetime_convert('UTC', date_default_timezone_get(), $lastmodified) : ''); + $ft['iconFromType'] = $this->getIconFromType($type); $f[] = $ft; } @@ -233,15 +235,26 @@ class RedBrowser extends DAV\Browser\Plugin { } // prepare quota for template + $quota = array(); $quota['used'] = $used; $quota['limit'] = $limit; $quota['desc'] = $quotaDesc; - $html .= replace_macros(get_markup_template('cloud_directory.tpl'), array( + $output = ''; + if ($this->enablePost) { + $this->server->broadcastEvent('onHTMLActionsPanel', array($parent, &$output)); + } + + $html .= replace_macros(get_markup_template('cloud_header.tpl'), array( '$header' => t('Files') . ": " . $this->escapeHTML($path) . "/", + '$quota' => $quota, + '$total' => t('Total'), + '$actionspanel' => $output + )); + + $html .= replace_macros(get_markup_template('cloud_directory.tpl'), array( '$parentpath' => $parentpath, '$entries' => $f, - '$quota' => $quota, '$name' => t('Name'), '$type' => t('Type'), '$size' => t('Size'), @@ -249,15 +262,9 @@ class RedBrowser extends DAV\Browser\Plugin { '$parent' => t('parent'), '$edit' => t('Edit'), '$delete' => t('Delete'), - '$total' => t('Total') + '$nick' => $this->auth->getCurrentUser() )); - $output = ''; - if ($this->enablePost) { - $this->server->broadcastEvent('onHTMLActionsPanel', array($parent, &$output)); - } - $html .= $output; - get_app()->page['content'] = $html; load_pdl(get_app()); construct_page(get_app()); @@ -321,6 +328,62 @@ class RedBrowser extends DAV\Browser\Plugin { } /** + * @brief returns icon name for use with e.g. font-awesome based on mime-type + * + * @param string $type + * @return string + */ + protected function getIconFromType($type) { + $iconMap = array( + //Folder + t('Collection') => 'icon-folder-close', + + //Common file + 'application/octet-stream' => 'icon-file-alt', + + //Text + 'text/plain' => 'icon-file-text-alt', + 'application/msword' => 'icon-file-text-alt', + 'application/pdf' => 'icon-file-text-alt', + 'application/vnd.oasis.opendocument.text' => 'icon-file-text-alt', + 'application/epub+zip' => 'icon-book', + + //Spreadsheet + 'application/vnd.oasis.opendocument.spreadsheet' => 'icon-table', + 'application/vnd.ms-excel' => 'icon-table', + + //Image + 'image/jpeg' => 'icon-picture', + 'image/png' => 'icon-picture', + 'image/gif' => 'icon-picture', + 'image/svg+xml' => 'icon-picture', + + //Archive + 'application/zip' => 'icon-archive', + 'application/x-rar-compressed' => 'icon-archive', + + //Audio + 'audio/mpeg' => 'icon-music', + 'audio/wav' => 'icon-music', + 'application/ogg' => 'icon-music', + + //Video + 'video/quicktime' => 'icon-film', + + + ); + + $iconFromType = 'icon-file-alt'; + + if (array_key_exists($type, $iconMap)) + { + $iconFromType = $iconMap[$type]; + } + + return $iconFromType; + } + + /** * @brief Return the hash of an attachment. * * Given the owner, the parent folder and and attach name get the attachment @@ -370,4 +433,4 @@ class RedBrowser extends DAV\Browser\Plugin { } return $id; } -}
\ No newline at end of file +} diff --git a/include/activities.php b/include/activities.php index d978ebcd6..d770ccb23 100644 --- a/include/activities.php +++ b/include/activities.php @@ -48,7 +48,11 @@ function profile_activity($changed, $value) { if($t == 1 && strlen($value)) { // if it's a url, the HTML quotes will mess it up, so link it and don't try and zidify it because we don't know what it points to. - $value = linkify($value); + $value = preg_replace_callback("/([^\]\='".'"'."]|^|\#\^)(https?\:\/\/[a-zA-Z0-9\:\/\-\?\&\;\.\=\@\_\~\#\%\$\!\+\,]+)/ism", 'red_zrl_callback', $value); + // take out the bookmark indicator + if(substr($value,0,2) === '#^') + $value = str_replace('#^','',$value); + $message = sprintf( t('%1$s changed %2$s to “%3$s”'), $A, $changes, $value); $message .= "\n\n" . sprintf( t('Visit %1$s\'s %2$s'), $A, $prof); } diff --git a/include/api.php b/include/api.php index aeee95d3b..51de412cf 100644 --- a/include/api.php +++ b/include/api.php @@ -1868,11 +1868,14 @@ require_once('include/items.php'); require_once("include/message.php"); - $r = q("SELECT `id` FROM `contact` WHERE `uid`=%d AND `nick`='%s'", + // in a decentralised world the screen name is ambiguous + + $r = q("SELECT `abook_id` FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel`=%d and xchan_addr like '%s'", intval(api_user()), - dbesc($_POST['screen_name'])); + dbesc($_POST['screen_name'] . '@%') + ); - $recipient = api_get_user($a, $r[0]['id']); + $recipient = api_get_user($a, $r[0]['abook_id']); $replyto = ''; $sub = ''; if (x($_REQUEST,'replyto')) { @@ -1925,10 +1928,11 @@ require_once('include/items.php'); if ($page<0) $page=0; $start = $page*$count; - - $profile_url = $a->get_baseurl() . '/channel/' . $a->user['nickname']; + $channel = $a->get_channel(); + + $profile_url = $a->get_baseurl() . '/channel/' . $channel['channel_address']; if ($box=="sentbox") { - $sql_extra = "`from-url`='".dbesc( $profile_url )."'"; + $sql_extra = "`from_xchan`='".dbesc( $channel['channel_hash'] )."'"; } elseif ($box=="conversation") { $sql_extra = "`parent_mid`='".dbesc( $_GET["uri"] ) ."'"; @@ -1937,10 +1941,10 @@ require_once('include/items.php'); $sql_extra = "true"; } elseif ($box=="inbox") { - $sql_extra = "`from-url`!='".dbesc( $profile_url )."'"; + $sql_extra = "`from_xchan`!='".dbesc( $channel['channel_hash'] )."'"; } - $r = q("SELECT * FROM `mail` WHERE uid=%d AND $sql_extra ORDER BY created DESC LIMIT %d OFFSET %d", + $r = q("SELECT * FROM `mail` WHERE channel_id = %d AND $sql_extra ORDER BY created DESC LIMIT %d OFFSET %d", intval(api_user()), intval($count), intval($start) ); @@ -1950,10 +1954,12 @@ require_once('include/items.php'); foreach($r as $item) { if ($box == "inbox" || $item['from-url'] != $profile_url){ $recipient = $user_info; - $sender = api_get_user($a,$item['contact-id']); + // fixme to lookup recipient + $sender = api_get_user($a); } elseif ($box == "sentbox" || $item['from-url'] != $profile_url){ - $recipient = api_get_user($a,$item['contact-id']); + // fixme to lookup recipient + $recipient = api_get_user($a); $sender = $user_info; } diff --git a/include/apps.php b/include/apps.php index 9c4fe826a..e08e6a6f5 100644 --- a/include/apps.php +++ b/include/apps.php @@ -83,35 +83,37 @@ function parse_app_description($f) { $ret['target'] = str_replace(array('\'','"'),array(''','&dquot;'),$ret['target']); if(array_key_exists('requires',$ret)) { - $require = trim(strtolower($ret['requires'])); - switch($require) { - case 'nologin': - if(local_user()) - unset($ret); - break; - case 'admin': - if(! is_site_admin()) - unset($ret); - break; - case 'local_user': - if(! local_user()) - unset($ret); - break; - case 'public_profile': - if(! is_public_profile()) - unset($ret); - break; - case 'observer': - if(! $observer) - unset($ret); - break; - default: - if(! local_user() && feature_enabled(local_user(),$require)) - unset($ret); - break; + $requires = explode(',',$ret['requires']); + foreach($requires as $require) { + $require = trim(strtolower($require)); + switch($require) { + case 'nologin': + if(local_user()) + unset($ret); + break; + case 'admin': + if(! is_site_admin()) + unset($ret); + break; + case 'local_user': + if(! local_user()) + unset($ret); + break; + case 'public_profile': + if(! is_public_profile()) + unset($ret); + break; + case 'observer': + if(! $observer) + unset($ret); + break; + default: + if(! (local_user() && feature_enabled(local_user(),$require))) + unset($ret); + break; + } } -// logger('require: ' . print_r($ret,true)); } if($ret) { translate_system_apps($ret); @@ -189,34 +191,37 @@ function app_render($papp,$mode = 'view') { $papp['desc'] = str_replace(array('\'','"'),array(''','&dquot;'),$papp['desc']); if($k === 'requires') { - $require = trim(strtolower($v)); - switch($require) { - case 'nologin': - if(local_user()) - return ''; - break; - case 'admin': - if(! is_site_admin()) - return ''; - break; - case 'local_user': - if(! local_user()) - return ''; - break; - case 'public_profile': - if(! is_public_profile()) - return ''; - break; - case 'observer': - $observer = get_app()->get_observer(); - if(! $observer) - return ''; - break; - default: - if(! local_user() && feature_enabled(local_user(),$require)) - return ''; - break; + $requires = explode(',',$v); + foreach($requires as $require) { + $require = trim(strtolower($require)); + switch($require) { + case 'nologin': + if(local_user()) + return ''; + break; + case 'admin': + if(! is_site_admin()) + return ''; + break; + case 'local_user': + if(! local_user()) + return ''; + break; + case 'public_profile': + if(! is_public_profile()) + return ''; + break; + case 'observer': + $observer = get_app()->get_observer(); + if(! $observer) + return ''; + break; + default: + if(! (local_user() && feature_enabled(local_user(),$require))) + return ''; + break; + } } } diff --git a/include/attach.php b/include/attach.php index ad6ca1b21..a76dd4b28 100644 --- a/include/attach.php +++ b/include/attach.php @@ -717,7 +717,7 @@ function attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gi ); if($r) { foreach($r as $rr) { - attach_change_permissions($channel_id, $resource, $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse); + attach_change_permissions($channel_id, $rr['hash'], $allow_cid, $allow_gid, $deny_cid, $deny_gid, $recurse); } } } diff --git a/include/auth.php b/include/auth.php index 94c64e58d..c4bbaf546 100644 --- a/include/auth.php +++ b/include/auth.php @@ -41,6 +41,9 @@ function nuke_session() { /** * @brief Verify login credentials. * + * If system <i>authlog</i> is set a log entry will be added for failed login + * attempts. + * * @param string $email * The email address to verify. * @param string $pass @@ -88,14 +91,25 @@ function account_verify_password($email, $pass) { if($record['account_flags'] & ACCOUNT_PENDING) logger('Account is pending. account_flags = ' . $record['account_flags']); - // Also log failed logins to a separate auth log to reduce overhead for server side intrusion prevention - $authlog = get_config('system', 'authlog'); - if ($authlog) - @file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $error . "\n", FILE_APPEND); + log_failed_login($error); return null; } +/** + * @brief Log failed logins to a separate auth log. + * + * Can be used to reduce overhead for server side intrusion prevention, like + * parse the authlog file with something like fail2ban, OSSEC, etc. + * + * @param string $errormsg + * Error message to display for failed login. + */ +function log_failed_login($errormsg) { + $authlog = get_config('system', 'authlog'); + if ($authlog) + @file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $errormsg . PHP_EOL, FILE_APPEND); +} /** * Inline - not a function @@ -269,7 +283,7 @@ else { @file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $error . "\n", FILE_APPEND); notice( t('Login failed.') . EOL ); - goaway(z_root()); + goaway(z_root() . '/login'); } // If the user specified to remember the authentication, then change the cookie diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index 3c4f07568..5c93ac3aa 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -116,22 +116,11 @@ function diaspora_mention_callback($matches) { function diaspora2bb($s,$use_zrl = false) { + $s = str_replace("
","\r",$s); $s = str_replace("
\n>","",$s); $s = html_entity_decode($s,ENT_COMPAT,'UTF-8'); - // Too many new lines. So deactivated the following line - // $s = str_replace("\r","\n",$s); - // Simply remove cr. - $s = str_replace("\r","",$s); - - // <br/> is invalid. Replace it with the valid expression - $s = str_replace("<br/>","<br />",$s); - $s = str_replace("\n","<br />",$s); - - -// $s = preg_replace('/\@\{(.+?)\; (.+?)\@(.+?)\}/','@[url=https://$3/u/$2]$1[/url]',$s); - // first try plustags $s = preg_replace_callback('/\@\{(.+?)\; (.+?)\@(.+?)\}\+/','diaspora_mention_callback',$s); @@ -143,16 +132,13 @@ function diaspora2bb($s,$use_zrl = false) { // This seems to work $s = preg_replace('/\#([^\s\#])/','#$1',$s); - $s = preg_replace_callback('/\[share(.*?)\]/ism','share_shield',$s); - $s = Markdown($s); + $s = str_replace("\r","",$s); + $s = str_replace('#','#',$s); -// we seem to have double linebreaks -// $s = str_replace("\n",'<br />',$s); $s = html2bbcode($s); -// $s = str_replace('*','*',$s); // protect the recycle symbol from turning into a tag, but without unescaping angles and naked ampersands $s = str_replace('♲',html_entity_decode('♲',ENT_QUOTES,'UTF-8'),$s); @@ -175,10 +161,6 @@ function diaspora2bb($s,$use_zrl = false) { // remove duplicate adjacent code tags $s = preg_replace("/(\[code\])+(.*?)(\[\/code\])+/ism","[code]$2[/code]", $s); - - $s = preg_replace_callback('/\[share(.*?)\]/ism','share_unshield',$s); - - // Don't show link to full picture (until it is fixed) $s = scale_external_images($s, false); diff --git a/include/bbcode.php b/include/bbcode.php index 5b7451a6b..ab56bda61 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -22,7 +22,7 @@ function tryzrlaudio($match) { $zrl = is_matrix_url($link); if($zrl) $link = zid($link); - return '<audio src="' . $link . '" controls="controls" ><a href="' . $link . '">' . $link . '</a></audio>'; + return '<audio src="' . str_replace(' ','%20',$link) . '" controls="controls" ><a href="' . str_replace(' ','%20',$link) . '">' . $link . '</a></audio>'; } function tryzrlvideo($match) { @@ -30,7 +30,7 @@ function tryzrlvideo($match) { $zrl = is_matrix_url($link); if($zrl) $link = zid($link); - return '<video controls="controls" src="' . $link . '" style="width:100%; max-width:' . get_app()->videowidth . 'px"><a href="' . $link . '">' . $link . '</a></video>'; + 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>'; } @@ -278,6 +278,17 @@ function rpost_callback($match) { } } +function bb_map_coords($match) { + // the extra space in the following line is intentional + return str_replace($match[0],'<div class="map" >' . generate_map(str_replace('/',' ',$match[1])) . '</div>', $match[0]); +} + +function bb_map_location($match) { + // the extra space in the following line is intentional + return str_replace($match[0],'<div class="map" >' . generate_named_map($match[1]) . '</div>', $match[0]); +} + + function bb_sanitize_style($input) { //whitelist property limits (0 = no limitation) $w = array( // color properties @@ -357,11 +368,6 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) { $Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_spacefy',$Text); } -// Not yet implemented - thinking this should display a map or perhaps be a map directive -// if (strpos($Text,'[location]') !== false) { -// $Text = preg_replace_callback("/\[location\](.*?)\[\/location\]/ism", 'bb_location',$Text); -// } - // If we find any event code, turn it into an event. @@ -492,6 +498,22 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true) { $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); } + + // leave open the posibility of [map=something] + // this is replaced in prepare_body() which has knowledge of the item location + + if (strpos($Text,'[/map]') !== false) { + $Text = preg_replace_callback("/\[map\](.*?)\[\/map\]/ism",'bb_map_location',$Text); + } + + if (strpos($Text,'[map=') !== false) { + $Text = preg_replace_callback("/\[map=(.*?)\]/ism",'bb_map_coords',$Text); + } + + if (strpos($Text,'[map]') !== false) { + $Text = preg_replace("/\[map\]/", '<div class="map"></div>', $Text); + } + // Check for bold text if (strpos($Text,'[b]') !== false) { $Text = preg_replace("(\[b\](.*?)\[\/b\])ism",'<strong>$1</strong>',$Text); diff --git a/include/conversation.php b/include/conversation.php index 6b3e278f0..a2fb3d162 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -431,13 +431,18 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $arr_blocked = null; - if(local_user()) { + if(local_user()) $str_blocked = get_pconfig(local_user(),'system','blocked'); - if($str_blocked) { + if(! local_user() && ($mode == 'network')) { + $sys = get_sys_channel(); + $id = $sys['channel_id']; + $str_blocked = get_pconfig($id,'system','blocked'); + } + + if($str_blocked) { $arr_blocked = explode(',',$str_blocked); for($x = 0; $x < count($arr_blocked); $x ++) - $arr_blocked[$x] = trim($arr_blocked[$x]); - } + $arr_blocked[$x] = trim($arr_blocked[$x]); } @@ -661,7 +666,6 @@ function conversation(&$a, $items, $mode, $update, $page_mode = 'traditional', $ $body = prepare_body($item,true); - //$tmp_item = replace_macros($tpl,array( $tmp_item = array( 'template' => $tpl, 'toplevel' => 'toplevel_item', @@ -1095,8 +1099,8 @@ function status_editor($a,$x,$popup=false) { $jotplugins = ''; $jotnets = ''; - - $preview = ((feature_enabled($x['profile_uid'],'preview')) ? t('Preview') : ''); + $preview = t('Preview'); +// $preview = ((feature_enabled($x['profile_uid'],'preview')) ? t('Preview') : ''); if(x($x,'nopreview')) $preview = ''; @@ -1128,13 +1132,13 @@ function status_editor($a,$x,$popup=false) { '$shortaudio' => t('audio link'), '$setloc' => t('Set your location'), '$shortsetloc' => t('set location'), - '$noloc' => t('Clear browser location'), + '$noloc' => ((get_pconfig($x['profile_uid'],'system','use_browser_location')) ? t('Clear browser location') : ''), '$shortnoloc' => t('clear location'), '$title' => ((x($x,'title')) ? htmlspecialchars($x['title'], ENT_COMPAT,'UTF-8') : ''), - '$placeholdertitle' => t('Set title'), + '$placeholdertitle' => t('Title (optional)'), '$catsenabled' => ((feature_enabled($x['profile_uid'],'categories') && (! $webpage)) ? 'categories' : ''), '$category' => "", - '$placeholdercategory' => t('Categories (comma-separated list)'), + '$placeholdercategory' => t('Categories (optional, comma-separated list)'), '$wait' => t('Please wait'), '$permset' => t('Permission settings'), '$shortpermset' => t('permissions'), diff --git a/include/dir_fns.php b/include/dir_fns.php index 909005bbb..af6f78c01 100644 --- a/include/dir_fns.php +++ b/include/dir_fns.php @@ -51,13 +51,32 @@ function check_upstream_directory() { } function dir_sort_links() { + // Build urls without order and pubforums so it's easy to tack on the changed value + // Probably there's an easier way to do this + + $current_order = (($_REQUEST['order']) ? $_REQUEST['order'] : 'normal'); + $url = 'directory?'; + $tmp = $_REQUEST; + unset($tmp['order']); + $sorturl = $url . http_build_query($tmp); + $tmp = $_REQUEST; + + unset($tmp['pubforums']); + $forumsurl = $url . http_build_query($tmp); $o = replace_macros(get_markup_template('dir_sort_links.tpl'), array( '$header' => t('Directory Options'), '$normal' => t('Alphabetic'), '$reverse' => t('Reverse Alphabetic'), '$date' => t('Newest to Oldest'), + '$reversedate' => t('Oldest to Newest'), '$pubforums' => t('Public Forums Only'), + '$pubforumsonly' => x($_REQUEST,'pubforums') ? $_REQUEST['pubforums'] : '', + '$sort' => t('Sort'), + '$selected_sort' => $current_order, + '$sorturl' => $sorturl, + '$forumsurl' => $forumsurl, + )); return $o; } @@ -213,7 +232,7 @@ function update_directory_entry($ud) { function local_dir_update($uid,$force) { - logger('local_dir_update', LOGGER_DEBUG); + logger('local_dir_update: uid: ' . $uid, LOGGER_DEBUG); $p = q("select channel.channel_hash, channel_address, channel_timezone, profile.* from profile left join channel on channel_id = uid where uid = %d and is_default = 1", intval($uid) diff --git a/include/features.php b/include/features.php index 92d8598a5..7009b1d6b 100644 --- a/include/features.php +++ b/include/features.php @@ -45,7 +45,7 @@ function get_features() { t('Post Composition Features'), // array('richtext', t('Richtext Editor'), t('Enable richtext editor')), array('markdown', t('Use Markdown'), t('Allow use of "Markdown" to format posts')), - array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them')), +// array('preview', t('Post Preview'), t('Allow previewing posts and comments before publishing them')), array('channel_sources', t('Channel Sources'), t('Automatically import channel content from other channels or feeds')), array('content_encrypt', t('Even More Encryption'), t('Allow optional encryption of content end-to-end with a shared secret key')), array('adult_photo_flagging', t('Flag Adult Photos'), t('Provide photo edit option to hide adult photos from default album view')), @@ -67,7 +67,7 @@ function get_features() { 'tools' => array( t('Post/Comment Tools'), // array('multi_delete', t('Multiple Deletion'), t('Select and delete multiple posts/comments at once')), - array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending')), +// array('edit_posts', t('Edit Sent Posts'), t('Edit and correct posts and comments after sending')), array('commtag', t('Tagging'), t('Ability to tag existing posts')), array('categories', t('Post Categories'), t('Add categories to your posts')), array('filing', t('Saved Folders'), t('Ability to file posts under folders')), diff --git a/include/fixd.php b/include/fixd.php new file mode 100644 index 000000000..bce5eb348 --- /dev/null +++ b/include/fixd.php @@ -0,0 +1,33 @@ +<?php + + require_once('include/cli_startup.php'); + + cli_startup(); + + $rand = db_getfunc('RAND'); + $r = q("select xchan_addr, hubloc_url from xchan left join hubloc on hubloc_hash = xchan_hash where xchan_network like '%%diaspora%%' order by $rand"); + + if(! $r) + killme(); + + require_once('include/network.php'); + $total = 0; + foreach ($r as $rr) { + if($rr['hubloc_url']) { + continue; + } + $total ++; + } + + print $total . "\n"; + + foreach ($r as $rr) { + if($rr['hubloc_url']) { + continue; + } + + $webbie = $rr['xchan_addr']; + print $webbie . ' '; + + discover_by_webbie($webbie); + } diff --git a/include/hubloc.php b/include/hubloc.php index 43187fcee..b5a3d47c5 100644 --- a/include/hubloc.php +++ b/include/hubloc.php @@ -33,7 +33,7 @@ function prune_hub_reinstalls() { // allow some slop period, say 3 days - just in case this is a glitch or transient occurrence // Then remove any hublocs pointing to the oldest entry. - if($d1 < $d2) { + if(($d1 < $d2) && ($x[0]['hubloc_sitekey'])) { logger('prune_hub_reinstalls: removing dead hublocs at ' . $rr['site_url']); $y = q("delete from hubloc where hubloc_sitekey = '%s'", dbesc($x[0]['hubloc_sitekey']) diff --git a/include/identity.php b/include/identity.php index 11da745da..7ae8e48f6 100644 --- a/include/identity.php +++ b/include/identity.php @@ -1113,7 +1113,7 @@ logger('online: ' . $profile['online']); function advanced_profile(&$a) { - + require_once('include/text.php'); if(! perm_is_allowed($a->profile['profile_uid'],get_observer_hash(),'view_profile')) return ''; @@ -1205,7 +1205,18 @@ function advanced_profile(&$a) { if($txt = prepare_text($a->profile['contact'])) $profile['contact'] = array( t('Contact information and Social Networks:'), $txt); - if($txt = prepare_text($a->profile['channels'])) $profile['channels'] = array( t('My other channels:'), $txt); + // Support tags in the other channels field (probably want to restrict it to channels only?) + $txt = $a->profile['channels']; + $matches = get_tags($txt); + $access_tag = ''; + $str_tags = ''; + foreach($matches as $m) { + $success = handle_tag($a, $txt, $access_tag, $str_tags, $a->profile_uid, $m); // Use uid of the profile maker + } + + if($txt = prepare_text($txt)) { + $profile['channels'] = array( t('My other channels:'), $txt); + } if($txt = prepare_text($a->profile['music'])) $profile['music'] = array( t('Musical interests:'), $txt); @@ -1580,4 +1591,4 @@ function get_channel_default_perms($uid) { if($r) return $r[0]['abook_my_perms']; return 0; -}
\ No newline at end of file +} diff --git a/include/nav.php b/include/nav.php index b4aa0f14a..a9bff4b29 100644 --- a/include/nav.php +++ b/include/nav.php @@ -92,40 +92,40 @@ EOT; if($chans && count($chans) > 1 && feature_enabled(local_user(),'nav_channel_select')) $nav['channels'] = $chans; - $nav['logout'] = Array('logout',t('Logout'), "", t('End this session')); + $nav['logout'] = Array('logout',t('Logout'), "", t('End this session'),'logout_nav_btn'); // user menu - $nav['usermenu'][] = Array('channel/' . $channel['channel_address'], t('Home'), "", t('Your posts and conversations')); - $nav['usermenu'][] = Array('profile/' . $channel['channel_address'], t('View Profile'), "", t('Your profile page')); + $nav['usermenu'][] = Array('channel/' . $channel['channel_address'], t('Home'), "", t('Your posts and conversations'),'channel_nav_btn'); + $nav['usermenu'][] = Array('profile/' . $channel['channel_address'], t('View Profile'), "", t('Your profile page'),'profile_nav_btn'); if(feature_enabled(local_user(),'multi_profiles')) - $nav['usermenu'][] = Array('profiles', t('Edit Profiles'),"", t('Manage/Edit profiles')); + $nav['usermenu'][] = Array('profiles', t('Edit Profiles'),"", t('Manage/Edit profiles'),'profiles_nav_btn'); else - $nav['usermenu'][] = Array('profiles/' . $prof[0]['id'], t('Edit Profile'),"", t('Edit your profile')); + $nav['usermenu'][] = Array('profiles/' . $prof[0]['id'], t('Edit Profile'),"", t('Edit your profile'),'profiles_nav_btn'); - $nav['usermenu'][] = Array('photos/' . $channel['channel_address'], t('Photos'), "", t('Your photos')); - $nav['usermenu'][] = Array('cloud/' . $channel['channel_address'],t('Files'),"",t('Your files')); + $nav['usermenu'][] = Array('photos/' . $channel['channel_address'], t('Photos'), "", t('Your photos'),'photos_nav_btn'); + $nav['usermenu'][] = Array('cloud/' . $channel['channel_address'],t('Files'),"",t('Your files'),'cloud_nav_btn'); require_once('include/chat.php'); $has_chats = chatroom_list_count(local_user()); if($has_chats) { - $nav['usermenu'][] = Array('chat/' . $channel['channel_address'],t('Chat'),"",t('Your chatrooms')); + $nav['usermenu'][] = Array('chat/' . $channel['channel_address'],t('Chat'),"",t('Your chatrooms'),'chat_nav_btn'); } require_once('include/menu.php'); $has_bookmarks = menu_list_count(local_user(),'',MENU_BOOKMARK) + menu_list_count(local_user(),'',MENU_SYSTEM|MENU_BOOKMARK); if($has_bookmarks) { - $nav['usermenu'][] = Array('bookmarks', t('Bookmarks'), "", t('Your bookmarks')); + $nav['usermenu'][] = Array('bookmarks', t('Bookmarks'), "", t('Your bookmarks'),'bookmarks_nav_btn'); } if(feature_enabled($channel['channel_id'],'webpages')) - $nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages')); + $nav['usermenu'][] = Array('webpages/' . $channel['channel_address'],t('Webpages'),"",t('Your webpages'),'webpages_nav_btn'); } else { if(! get_account_id()) { - $nav['loginmenu'][] = Array('login',t('Login'),'',t('Sign in')); + $nav['loginmenu'][] = Array('login',t('Login'),'',t('Sign in'),'login_nav_btn'); } else - $nav['alogout'] = Array('logout',t('Logout'), "", t('End this session')); + $nav['alogout'] = Array('logout',t('Logout'), "", t('End this session'),'logout_nav_btn'); } @@ -142,7 +142,7 @@ EOT; sprintf( t('%s - click to logout'), $observer['xchan_addr'])); } else { - $nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub')); + $nav['loginmenu'][] = Array('rmagic',t('Remote authentication'),'',t('Click to authenticate to your home hub'),'rmagic_nav_btn'); } /** @@ -156,24 +156,24 @@ EOT; } if(($a->module != 'home') && (! (local_user()))) - $nav['home'] = array($homelink, t('Home'), "", t('Home Page')); + $nav['home'] = array($homelink, t('Home'), "", t('Home Page'),'home_nav_btn'); if(($a->config['system']['register_policy'] == REGISTER_OPEN) && (! local_user()) && (! remote_user())) - $nav['register'] = array('register',t('Register'), "", t('Create an account')); + $nav['register'] = array('register',t('Register'), "", t('Create an account'),'register_nav_btn'); $help_url = z_root() . '/help?f=&cmd=' . $a->cmd; if(! get_config('system','hide_help')) - $nav['help'] = array($help_url, t('Help'), "", t('Help and documentation')); + $nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'),'help_nav_btn'); - $nav['apps'] = array('apps', t('Apps'), "", t('Applications, utilities, links, games')); + $nav['apps'] = array('apps', t('Apps'), "", t('Applications, utilities, links, games'),'apps_nav_btn'); $nav['search'] = array('search', t('Search'), "", t('Search site content')); - $nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory')); + $nav['directory'] = array('directory', t('Directory'), "", t('Channel Directory'),'directory_nav_btn'); /** @@ -187,21 +187,21 @@ EOT; $network_options = get_pconfig(local_user(),'system','network_page_default'); $nav['network'] = array('network' . (($network_options) ? '?f=&' . $network_options : ''), - t('Matrix'), "", t('Your matrix')); + t('Matrix'), "", t('Your matrix'),'network_nav_btn'); $nav['network']['mark'] = array('', t('Mark all matrix notifications seen'), '',''); - $nav['home'] = array('channel/' . $channel['channel_address'], t('Channel Home'), "", t('Channel home')); + $nav['home'] = array('channel/' . $channel['channel_address'], t('Channel Home'), "", t('Channel home'),'home_nav_btn'); $nav['home']['mark'] = array('', t('Mark all channel notifications seen'), '',''); - $nav['intros'] = array('connections/ifpending', t('Connections'), "", t('Connections')); + $nav['intros'] = array('connections/ifpending', t('Connections'), "", t('Connections'),'connections_nav_btn'); - $nav['notifications'] = array('notifications/system', t('Notices'), "", t('Notifications')); + $nav['notifications'] = array('notifications/system', t('Notices'), "", t('Notifications'),'notifications_nav_btn'); $nav['notifications']['all']=array('notifications/system', t('See all notifications'), "", ""); $nav['notifications']['mark'] = array('', t('Mark all system notifications seen'), '',''); - $nav['messages'] = array('message', t('Mail'), "", t('Private mail')); + $nav['messages'] = array('message', t('Mail'), "", t('Private mail'),'mail_nav_btn'); $nav['messages']['all']=array('message', t('See all private messages'), "", ""); $nav['messages']['mark'] = array('', t('Mark all private messages seen'), '',''); $nav['messages']['inbox'] = array('message', t('Inbox'), "", t('Inbox')); @@ -209,13 +209,13 @@ EOT; $nav['messages']['new'] = array('mail/new', t('New Message'), "", t('New Message')); - $nav['all_events'] = array('events', t('Events'), "", t('Event Calendar')); + $nav['all_events'] = array('events', t('Events'), "", t('Event Calendar'),'events_nav_btn'); $nav['all_events']['all']=array('events', t('See all events'), "", ""); $nav['all_events']['mark'] = array('', t('Mark all events seen'), '',''); - $nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage Your Channels')); + $nav['manage'] = array('manage', t('Channel Manager'), "", t('Manage Your Channels'),'manage_nav_btn'); - $nav['settings'] = array('settings', t('Settings'),"", t('Account/Channel Settings')); + $nav['settings'] = array('settings', t('Settings'),"", t('Account/Channel Settings'),'settings_nav_btn'); } @@ -223,7 +223,7 @@ EOT; * Admin page */ if (is_site_admin()){ - $nav['admin'] = array('admin/', t('Admin'), "", t('Site Setup and Configuration')); + $nav['admin'] = array('admin/', t('Admin'), "", t('Site Setup and Configuration'),'admin_nav_btn'); } @@ -259,6 +259,7 @@ $powered_by = ''; '$localuser' => local_user(), '$sel' => $a->nav_sel, '$powered_by' => $powered_by, + '$help' => t('@name, #tag, content'), '$pleasewait' => t('Please wait...') )); diff --git a/include/network.php b/include/network.php index ee2a6a59b..98c411cd8 100644 --- a/include/network.php +++ b/include/network.php @@ -1092,25 +1092,27 @@ function discover_by_webbie($webbie) { $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($webbie) ); - if($r) - return true; - - $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_instance_url, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", - dbesc($addr), - dbesc($guid), - dbesc($pubkey), - dbesc($addr), - dbesc($profile), - dbesc($vcard['fn']), - dbesc($network), - dbesc(z_root()), - dbescdate(datetime_convert()) - ); + if(! $r) { + + $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_instance_url, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", + dbesc($addr), + dbesc($guid), + dbesc($pubkey), + dbesc($addr), + dbesc($profile), + dbesc($vcard['fn']), + dbesc($network), + dbesc(z_root()), + dbescdate(datetime_convert()) + ); + } $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($webbie) ); + if(! $r) { + $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_flags ) values ('%s','%s','%s','%s','%s','%s','%s','%s', %d)", dbesc($guid), dbesc($addr), diff --git a/include/notifier.php b/include/notifier.php index cb97fcdf8..e1eb0c554 100644 --- a/include/notifier.php +++ b/include/notifier.php @@ -493,40 +493,51 @@ function notifier_run($argv, $argc){ $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc - where hubloc_hash in (" . implode(',',$recipients) . ") group by hubloc_sitekey order by hubloc_connected desc limit 1"); + where hubloc_hash in (" . implode(',',$recipients) . ") order by hubloc_connected desc limit 1"); } else { - if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { - $r = q("select distinct on (hubloc_sitekey) hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc - where hubloc_hash in (" . implode(',',$recipients) . ") and not (hubloc_flags & %d)>0 and not (hubloc_status & %d)>0", - intval(HUBLOC_FLAGS_DELETED), - intval(HUBLOC_OFFLINE) - ); - } else { $r = q("select hubloc_guid, hubloc_url, hubloc_sitekey, hubloc_network, hubloc_flags, hubloc_callback, hubloc_host from hubloc - where hubloc_hash in (" . implode(',',$recipients) . ") and not (hubloc_flags & %d)>0 and not (hubloc_status & %d)>0 group by hubloc_sitekey", + where hubloc_hash in (" . implode(',',$recipients) . ") and not (hubloc_flags & %d) > 0 and not (hubloc_status & %d) > 0", intval(HUBLOC_FLAGS_DELETED), intval(HUBLOC_OFFLINE) - ); - } - } + ); + } if(! $r) { logger('notifier: no hubs'); return; } + $hubs = $r; - $hublist = array(); - $keys = array(); + + /** + * Reduce the hubs to those that are unique. For zot hubs, we need to verify uniqueness by the sitekey, since it may have been + * a re-install which has not yet been detected and pruned. + * For other networks which don't have or require sitekeys, we'll have to use the URL + */ + + + $hublist = array(); // this provides an easily printable list for the logs + $dhubs = array(); // delivery hubs where we store our resulting unique array + $keys = array(); // array of keys to check uniquness for zot hubs + $urls = array(); // array of urls to check uniqueness of hubs from other networks + foreach($hubs as $hub) { - // don't try to deliver to deleted hublocs - and inexplicably SQL "distinct" and "group by" - // both return records with duplicate keys in rare circumstances -// FIXME this is probably redundant now. - if((! ($hub['hubloc_flags'] & HUBLOC_FLAGS_DELETED)) && (! in_array($hub['hubloc_sitekey'],$keys))) { - $hublist[] = $hub['hubloc_host']; - $keys[] = $hub['hubloc_sitekey']; + if($hub['hubloc_network'] == 'zot') { + if(! in_array($hub['hubloc_sitekey'],$keys)) { + $hublist[] = $hub['hubloc_host']; + $dhubs[] = $hub; + $keys[] = $hub['hubloc_sitekey']; + } + } + else { + if(! in_array($hub['hubloc_url'],$urls)) { + $hublist[] = $hub['hubloc_host']; + $dhubs[] = $hub; + $urls[] = $hub['hubloc_url']; + } } } @@ -542,7 +553,7 @@ function notifier_run($argv, $argc){ $deliver = array(); - foreach($hubs as $hub) { + foreach($dhubs as $hub) { if(defined('DIASPORA_RELIABILITY_EMULATION')) { $cointoss = mt_rand(0,2); diff --git a/include/permissions.php b/include/permissions.php index b078de4d5..9e60223fb 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -1,6 +1,19 @@ -<?php /** @file */ - +<?php +/** + * @file incldue/permissions.php + * + * This file conntains functions to check and work with permissions. + */ +/** + * @brief Return an array with all available permissions. + * + * These are channel specific permissions. + * The list of available permissions can get manipulated by the <i>hook</i> + * <b>global_permissions</b>. + * + * @return array associative array containing all permissions + */ function get_perms() { // thinking about making element[2] a bitmask instead of boolean so that we can provide a list of applicable selections @@ -14,8 +27,8 @@ function get_perms() { 'view_profile' => array('channel_r_profile', intval(PERMS_R_PROFILE), true, t('Can view my default channel profile'), ''), 'view_photos' => array('channel_r_photos', intval(PERMS_R_PHOTOS), true, t('Can view my photo albums'), ''), 'view_contacts' => array('channel_r_abook', intval(PERMS_R_ABOOK), true, t('Can view my connections'), ''), - 'view_storage' => array('channel_r_storage', intval(PERMS_R_STORAGE), true, t('Can view my file storage'), ''), - 'view_pages' => array('channel_r_pages', intval(PERMS_R_PAGES), true, t('Can view my webpages'), ''), + 'view_storage' => array('channel_r_storage', intval(PERMS_R_STORAGE), true, t('Can view my file storage'), ''), + 'view_pages' => array('channel_r_pages', intval(PERMS_R_PAGES), true, t('Can view my webpages'), ''), // Write permissions 'send_stream' => array('channel_w_stream', intval(PERMS_W_STREAM), false, t('Can send me their channel stream and posts'), ''), @@ -23,19 +36,20 @@ function get_perms() { 'post_comments' => array('channel_w_comment', intval(PERMS_W_COMMENT), false, t('Can comment on or like my posts'), ''), 'post_mail' => array('channel_w_mail', intval(PERMS_W_MAIL), false, t('Can send me private mail messages'), ''), 'post_photos' => array('channel_w_photos', intval(PERMS_W_PHOTOS), false, t('Can post photos to my photo albums'), ''), - 'post_like' => array('channel_w_like', intval(PERMS_W_LIKE), false, t('Can like/dislike stuff'), t('Profiles and things other than posts/comments')), + 'post_like' => array('channel_w_like', intval(PERMS_W_LIKE), false, t('Can like/dislike stuff'), t('Profiles and things other than posts/comments')), 'tag_deliver' => array('channel_w_tagwall', intval(PERMS_W_TAGWALL), false, t('Can forward to all my channel contacts via post @mentions'), t('Advanced - useful for creating group forum channels')), 'chat' => array('channel_w_chat', intval(PERMS_W_CHAT), false, t('Can chat with me (when available)'), t('')), - 'write_storage' => array('channel_w_storage', intval(PERMS_W_STORAGE), false, t('Can write to my file storage'), ''), - 'write_pages' => array('channel_w_pages', intval(PERMS_W_PAGES), false, t('Can edit my webpages'), ''), + 'write_storage' => array('channel_w_storage', intval(PERMS_W_STORAGE), false, t('Can write to my file storage'), ''), + 'write_pages' => array('channel_w_pages', intval(PERMS_W_PAGES), false, t('Can edit my webpages'), ''), - 'republish' => array('channel_a_republish', intval(PERMS_A_REPUBLISH), false, t('Can source my public posts in derived channels'), t('Somewhat advanced - very useful in open communities')), + 'republish' => array('channel_a_republish', intval(PERMS_A_REPUBLISH), false, t('Can source my public posts in derived channels'), t('Somewhat advanced - very useful in open communities')), - 'delegate' => array('channel_a_delegate', intval(PERMS_A_DELEGATE), false, t('Can administer my channel resources'), t('Extremely advanced. Leave this alone unless you know what you are doing')), + 'delegate' => array('channel_a_delegate', intval(PERMS_A_DELEGATE), false, t('Can administer my channel resources'), t('Extremely advanced. Leave this alone unless you know what you are doing')), ); $ret = array('global_permissions' => $global_perms); - call_hooks('global_permissions',$ret); + call_hooks('global_permissions', $ret); + return $ret['global_permissions']; } @@ -43,13 +57,13 @@ function get_perms() { /** * get_all_perms($uid,$observer_xchan) * - * @param $uid : The channel_id associated with the resource owner - * @param $observer_xchan: The xchan_hash representing the observer + * @param int $uid The channel_id associated with the resource owner + * @param string $observer_xchan The xchan_hash representing the observer + * @param bool $internal_use (default true) * - * @returns: array of all permissions, key is permission name, value is true or false + * @returns array of all permissions, key is permission name, value is true or false */ - -function get_all_perms($uid,$observer_xchan,$internal_use = true) { +function get_all_perms($uid, $observer_xchan, $internal_use = true) { $global_perms = get_perms(); @@ -85,7 +99,6 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { continue; } - // Next we're going to check for blocked or ignored contacts. // These take priority over all other settings. @@ -94,7 +107,7 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { $ret[$perm_name] = true; continue; } - + if(! $abook_checked) { $x = q("select abook_my_perms, abook_flags, xchan_network from abook left join xchan on abook_xchan = xchan_hash where abook_channel = %d and abook_xchan = '%s' and not ( abook_flags & %d )>0 limit 1", @@ -105,7 +118,7 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { if(! $x) { // not in address book, see if they've got an xchan $y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1", - dbesc($observer_xchan) + dbesc($observer_xchan) ); } @@ -113,7 +126,7 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { } // If they're blocked - they can't read or write - + if(($x) && ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED)) { $ret[$perm_name] = false; continue; @@ -130,7 +143,7 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { // system is blocked to anybody who is not authenticated - if((! $observer_xchan) && intval(get_config('system','block_public'))) { + if((! $observer_xchan) && intval(get_config('system', 'block_public'))) { $ret[$perm_name] = false; continue; } @@ -177,14 +190,14 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { $onsite_checked = true; } - + if($c) $ret[$perm_name] = true; else $ret[$perm_name] = false; continue; - } + } // From here on we require that the observer be a connection and // handle whether we're allowing any, approved or specific ones @@ -226,7 +239,6 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { $ret[$perm_name] = false; continue; - } $arr = array( @@ -235,11 +247,23 @@ function get_all_perms($uid,$observer_xchan,$internal_use = true) { 'permissions' => $ret); call_hooks('get_all_perms',$arr); + return $arr['permissions']; } - -function perm_is_allowed($uid,$observer_xchan,$permission) { +/** + * @brief Checks if given permission is allowed for given observer on a channel. + * + * Checks if the given observer with the hash $observer_xchan has permission + * $permission on channel_id $uid. + * $permission is one defined in get_perms(); + * + * @param int $uid The channel_id associated with the resource owner + * @param string $observer_xchan The xchan_hash representing the observer + * @param string $permission + * @return bool true if permission is allowed for observer on channel + */ +function perm_is_allowed($uid, $observer_xchan, $permission) { $arr = array( 'channel_id' => $uid, @@ -247,7 +271,7 @@ function perm_is_allowed($uid,$observer_xchan,$permission) { 'permission' => $permission, 'result' => false); - call_hooks('perm_is_allowed',$arr); + call_hooks('perm_is_allowed', $arr); if($arr['result']) return true; @@ -279,21 +303,21 @@ function perm_is_allowed($uid,$observer_xchan,$permission) { if(($x) && ($x[0]['abook_flags'] & ABOOK_FLAG_BLOCKED)) return false; - + if(($x) && (! $global_perms[$permission][2]) && ($x[0]['abook_flags'] & ABOOK_FLAG_IGNORED)) return false; if(! $x) { // not in address book, see if they've got an xchan $y = q("select xchan_network from xchan where xchan_hash = '%s' limit 1", - dbesc($observer_xchan) + dbesc($observer_xchan) ); } } // system is blocked to anybody who is not authenticated - if((! $observer_xchan) && intval(get_config('system','block_public'))) + if((! $observer_xchan) && intval(get_config('system', 'block_public'))) return false; // Check if this $uid is actually the $observer_xchan @@ -301,7 +325,6 @@ function perm_is_allowed($uid,$observer_xchan,$permission) { if($r[0]['channel_hash'] === $observer_xchan) return true; - if($r[0][$channel_perm] & PERMS_PUBLIC) return true; @@ -326,6 +349,7 @@ function perm_is_allowed($uid,$observer_xchan,$permission) { ); if($c) return true; + return false; } @@ -361,25 +385,32 @@ function perm_is_allowed($uid,$observer_xchan,$permission) { // No permissions allowed. - return false; + return false; } // Check a simple array of observers against a permissions // return a simple array of those with permission -function check_list_permissions($uid,$arr,$perm) { +function check_list_permissions($uid, $arr, $perm) { $result = array(); if($arr) foreach($arr as $x) - if(perm_is_allowed($uid,$x,$perm)) + if(perm_is_allowed($uid, $x, $perm)) $result[] = $x; + return($result); } - +/** + * @brief Sets site wide default permissions. + * + * @return array + */ function site_default_perms() { + $ret = array(); + $typical = array( 'view_stream' => PERMS_PUBLIC, 'view_profile' => PERMS_PUBLIC, @@ -401,14 +432,14 @@ function site_default_perms() { ); $global_perms = get_perms(); - $ret = array(); foreach($global_perms as $perm => $v) { - $x = get_config('default_perms',$perm); + $x = get_config('default_perms', $perm); if($x === false) $x = $typical[$perm]; $ret[$perm] = $x; } + return $ret; } @@ -449,15 +480,15 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; - $ret['channel_w_stream'] = PERMS_CONTACTS; - $ret['channel_w_wall'] = PERMS_CONTACTS; + $ret['channel_w_stream'] = PERMS_SPECIFIC; + $ret['channel_w_wall'] = PERMS_SPECIFIC; $ret['channel_w_tagwall'] = PERMS_SPECIFIC; - $ret['channel_w_comment'] = PERMS_CONTACTS; - $ret['channel_w_mail'] = PERMS_CONTACTS; + $ret['channel_w_comment'] = PERMS_SPECIFIC; + $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; - $ret['channel_w_chat'] = PERMS_CONTACTS; + $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; $ret['channel_r_storage'] = PERMS_PUBLIC; $ret['channel_w_storage'] = 0; @@ -465,9 +496,8 @@ function get_role_perms($role) { $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; $ret['channel_w_like'] = PERMS_NETWORK; - - break; + break; case 'social_restricted': $ret['perms_auto'] = false; @@ -482,25 +512,24 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; - $ret['channel_w_stream'] = PERMS_CONTACTS; - $ret['channel_w_wall'] = PERMS_CONTACTS; + $ret['channel_w_stream'] = PERMS_SPECIFIC; + $ret['channel_w_wall'] = PERMS_SPECIFIC; $ret['channel_w_tagwall'] = PERMS_SPECIFIC; - $ret['channel_w_comment'] = PERMS_CONTACTS; - $ret['channel_w_mail'] = PERMS_CONTACTS; + $ret['channel_w_comment'] = PERMS_SPECIFIC; + $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; - $ret['channel_w_chat'] = PERMS_CONTACTS; + $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; $ret['channel_r_storage'] = PERMS_PUBLIC; $ret['channel_w_storage'] = 0; $ret['channel_r_pages'] = PERMS_PUBLIC; $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; - $ret['channel_w_like'] = PERMS_CONTACTS; - - break; + $ret['channel_w_like'] = PERMS_SPECIFIC; + break; case 'social_private': $ret['perms_auto'] = false; @@ -515,12 +544,12 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; - $ret['channel_r_abook'] = PERMS_CONTACTS; - $ret['channel_w_stream'] = PERMS_CONTACTS; - $ret['channel_w_wall'] = PERMS_CONTACTS; + $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_abook'] = PERMS_SPECIFIC; + $ret['channel_w_stream'] = PERMS_SPECIFIC; + $ret['channel_w_wall'] = PERMS_SPECIFIC; $ret['channel_w_tagwall'] = PERMS_SPECIFIC; - $ret['channel_w_comment'] = PERMS_CONTACTS; + $ret['channel_w_comment'] = PERMS_SPECIFIC; $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; $ret['channel_w_chat'] = PERMS_SPECIFIC; @@ -530,8 +559,8 @@ function get_role_perms($role) { $ret['channel_r_pages'] = PERMS_PUBLIC; $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; - $ret['channel_w_like'] = PERMS_CONTACTS; - + $ret['channel_w_like'] = PERMS_SPECIFIC; + break; case 'forum': @@ -547,15 +576,15 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE|PERMS_W_TAGWALL; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; $ret['channel_w_stream'] = 0; - $ret['channel_w_wall'] = PERMS_CONTACTS; - $ret['channel_w_tagwall'] = PERMS_CONTACTS; - $ret['channel_w_comment'] = PERMS_CONTACTS; - $ret['channel_w_mail'] = PERMS_CONTACTS; + $ret['channel_w_wall'] = PERMS_SPECIFIC; + $ret['channel_w_tagwall'] = PERMS_SPECIFIC; + $ret['channel_w_comment'] = PERMS_SPECIFIC; + $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; - $ret['channel_w_chat'] = PERMS_CONTACTS; + $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; $ret['channel_r_storage'] = PERMS_PUBLIC; $ret['channel_w_storage'] = 0; @@ -563,7 +592,7 @@ function get_role_perms($role) { $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; $ret['channel_w_like'] = PERMS_NETWORK; - + break; case 'forum_restricted': @@ -579,25 +608,24 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE|PERMS_W_TAGWALL; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; $ret['channel_w_stream'] = 0; - $ret['channel_w_wall'] = PERMS_CONTACTS; + $ret['channel_w_wall'] = PERMS_SPECIFIC; $ret['channel_w_tagwall'] = PERMS_SPECIFIC; - $ret['channel_w_comment'] = PERMS_CONTACTS; - $ret['channel_w_mail'] = PERMS_CONTACTS; + $ret['channel_w_comment'] = PERMS_SPECIFIC; + $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; - $ret['channel_w_chat'] = PERMS_CONTACTS; + $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; $ret['channel_r_storage'] = PERMS_PUBLIC; $ret['channel_w_storage'] = 0; $ret['channel_r_pages'] = PERMS_PUBLIC; $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; - $ret['channel_w_like'] = PERMS_CONTACTS; - - break; + $ret['channel_w_like'] = PERMS_SPECIFIC; + break; case 'forum_private': $ret['perms_auto'] = false; @@ -611,24 +639,24 @@ function get_role_perms($role) { |PERMS_W_STREAM|PERMS_W_WALL|PERMS_W_COMMENT|PERMS_W_MAIL|PERMS_W_CHAT |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE; $ret['channel_r_stream'] = PERMS_PUBLIC; - $ret['channel_r_profile'] = PERMS_CONTACTS; - $ret['channel_r_photos'] = PERMS_CONTACTS; - $ret['channel_r_abook'] = PERMS_CONTACTS; + $ret['channel_r_profile'] = PERMS_SPECIFIC; + $ret['channel_r_photos'] = PERMS_SPECIFIC; + $ret['channel_r_abook'] = PERMS_SPECIFIC; $ret['channel_w_stream'] = 0; - $ret['channel_w_wall'] = PERMS_CONTACTS; + $ret['channel_w_wall'] = PERMS_SPECIFIC; $ret['channel_w_tagwall'] = 0; - $ret['channel_w_comment'] = PERMS_CONTACTS; + $ret['channel_w_comment'] = PERMS_SPECIFIC; $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; - $ret['channel_r_storage'] = PERMS_CONTACTS; + $ret['channel_r_storage'] = PERMS_SPECIFIC; $ret['channel_w_storage'] = 0; - $ret['channel_r_pages'] = PERMS_CONTACTS; + $ret['channel_r_pages'] = PERMS_SPECIFIC; $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; - $ret['channel_w_like'] = PERMS_CONTACTS; - + $ret['channel_w_like'] = PERMS_SPECIFIC; + break; case 'feed': @@ -644,15 +672,15 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; - $ret['channel_w_stream'] = PERMS_CONTACTS; - $ret['channel_w_wall'] = PERMS_CONTACTS; + $ret['channel_w_stream'] = PERMS_SPECIFIC; + $ret['channel_w_wall'] = PERMS_SPECIFIC; $ret['channel_w_tagwall'] = PERMS_SPECIFIC; - $ret['channel_w_comment'] = PERMS_CONTACTS; - $ret['channel_w_mail'] = PERMS_CONTACTS; + $ret['channel_w_comment'] = PERMS_SPECIFIC; + $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; - $ret['channel_w_chat'] = PERMS_CONTACTS; + $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; $ret['channel_r_storage'] = PERMS_PUBLIC; $ret['channel_w_storage'] = 0; @@ -660,11 +688,10 @@ function get_role_perms($role) { $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_NETWORK; $ret['channel_w_like'] = PERMS_NETWORK; - + break; case 'feed_restricted': - $ret['perms_auto'] = false; $ret['default_collection'] = true; $ret['directory_publish'] = false; @@ -677,15 +704,15 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_W_LIKE; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; - $ret['channel_w_stream'] = PERMS_CONTACTS; - $ret['channel_w_wall'] = PERMS_CONTACTS; + $ret['channel_w_stream'] = PERMS_SPECIFIC; + $ret['channel_w_wall'] = PERMS_SPECIFIC; $ret['channel_w_tagwall'] = PERMS_SPECIFIC; - $ret['channel_w_comment'] = PERMS_CONTACTS; - $ret['channel_w_mail'] = PERMS_CONTACTS; + $ret['channel_w_comment'] = PERMS_SPECIFIC; + $ret['channel_w_mail'] = PERMS_SPECIFIC; $ret['channel_w_photos'] = 0; - $ret['channel_w_chat'] = PERMS_CONTACTS; + $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; $ret['channel_r_storage'] = PERMS_PUBLIC; $ret['channel_w_storage'] = 0; @@ -693,7 +720,7 @@ function get_role_perms($role) { $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; $ret['channel_w_like'] = PERMS_NETWORK; - + break; case 'soapbox': @@ -707,7 +734,7 @@ function get_role_perms($role) { |PERMS_R_STORAGE|PERMS_R_PAGES|PERMS_A_REPUBLISH|PERMS_W_LIKE; $ret['channel_r_stream'] = PERMS_PUBLIC; $ret['channel_r_profile'] = PERMS_PUBLIC; - $ret['channel_r_photos'] = PERMS_PUBLIC; + $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; $ret['channel_w_stream'] = 0; $ret['channel_w_wall'] = 0; @@ -723,7 +750,7 @@ function get_role_perms($role) { $ret['channel_w_pages'] = 0; $ret['channel_a_republish'] = PERMS_SPECIFIC; $ret['channel_w_like'] = PERMS_NETWORK; - + break; case 'repository': @@ -741,28 +768,25 @@ function get_role_perms($role) { $ret['channel_r_profile'] = PERMS_PUBLIC; $ret['channel_r_photos'] = PERMS_PUBLIC; $ret['channel_r_abook'] = PERMS_PUBLIC; - $ret['channel_w_stream'] = PERMS_CONTACTS; - $ret['channel_w_wall'] = PERMS_CONTACTS; - $ret['channel_w_tagwall'] = PERMS_CONTACTS; - $ret['channel_w_comment'] = PERMS_CONTACTS; - $ret['channel_w_mail'] = PERMS_CONTACTS; - $ret['channel_w_photos'] = PERMS_CONTACTS; - $ret['channel_w_chat'] = PERMS_CONTACTS; + $ret['channel_w_stream'] = PERMS_SPECIFIC; + $ret['channel_w_wall'] = PERMS_SPECIFIC; + $ret['channel_w_tagwall'] = PERMS_SPECIFIC; + $ret['channel_w_comment'] = PERMS_SPECIFIC; + $ret['channel_w_mail'] = PERMS_SPECIFIC; + $ret['channel_w_photos'] = PERMS_SPECIFIC; + $ret['channel_w_chat'] = PERMS_SPECIFIC; $ret['channel_a_delegate'] = 0; $ret['channel_r_storage'] = PERMS_PUBLIC; - $ret['channel_w_storage'] = PERMS_CONTACTS; + $ret['channel_w_storage'] = PERMS_SPECIFIC; $ret['channel_r_pages'] = PERMS_PUBLIC; - $ret['channel_w_pages'] = PERMS_CONTACTS; + $ret['channel_w_pages'] = PERMS_SPECIFIC; $ret['channel_a_republish'] = PERMS_SPECIFIC; $ret['channel_w_like'] = PERMS_NETWORK; - - break; - + break; default: break; - } $x = get_config('system','role_perms'); @@ -775,7 +799,12 @@ function get_role_perms($role) { return $ret; } - +/** + * @brief Creates a HTML select field with all available roles. + * + * @param string $current The current role + * @return string Returns the complete HTML code for this privacy-role-select field. + */ function role_selector($current) { if(! $current) @@ -792,16 +821,17 @@ function role_selector($current) { array('soapbox' => t('Celebrity/Soapbox'), 'repository' => t('Group Repository'))), 'other' => array( t('Other'), array('custom' => t('Custom/Expert Mode')))); + $o = '<select name="permissions_role" id="privacy-role-select">'; foreach($roles as $k => $v) { - $o .= '<optgroup label="'. htmlspecialchars($v[0]) . '" >'; + $o .= '<optgroup label="'. htmlspecialchars($v[0]) . '">'; foreach($v[1] as $kk => $vv) { - $selected = (($kk === $current) ? ' selected="selected" ' : ''); - $o .= '<option value="' . $kk . '" ' . $selected . '>' . htmlspecialchars($vv) . '</option>'; + $selected = (($kk === $current) ? ' selected="selected"' : ''); + $o .= '<option value="' . $kk . '"' . $selected . '>' . htmlspecialchars($vv) . '</option>'; } $o .= '</optgroup>'; } $o .= '</select>'; - return $o; -} + return $o; +} diff --git a/include/poller.php b/include/poller.php index e13c6829d..bd3f81a2e 100644 --- a/include/poller.php +++ b/include/poller.php @@ -403,6 +403,8 @@ function poller_run($argv, $argc){ } } + set_config('system','lastpoll',datetime_convert()); + //All done - clear the lockfile @unlink($lockfile); diff --git a/include/security.php b/include/security.php index 8066a76f6..07b6a96aa 100644 --- a/include/security.php +++ b/include/security.php @@ -1,12 +1,24 @@ -<?php /** @file */ - -function authenticate_success($user_record, $login_initial = false, $interactive = false,$return = false,$update_lastlog = false) { +<?php +/** + * @file include/security.php + * + * Some security related functions. + */ + +/** + * @param int $user_record The account_id + * @param bool $login_initial default false + * @param bool $interactive default false + * @param bool $return + * @param bool $update_lastlog + */ +function authenticate_success($user_record, $login_initial = false, $interactive = false, $return = false, $update_lastlog = false) { $a = get_app(); $_SESSION['addr'] = $_SERVER['REMOTE_ADDR']; - if(x($user_record,'account_id')) { + if(x($user_record, 'account_id')) { $a->account = $user_record; $_SESSION['account_id'] = $user_record['account_id']; $_SESSION['authenticated'] = 1; @@ -39,7 +51,7 @@ function authenticate_success($user_record, $login_initial = false, $interactive // might want to log success here } - if($return || x($_SESSION,'workflow')) { + if($return || x($_SESSION, 'workflow')) { unset($_SESSION['workflow']); return; } @@ -70,7 +82,13 @@ function authenticate_success($user_record, $login_initial = false, $interactive /* else just return */ } - +/** + * @brief Change to another channel with current logged-in account. + * + * @param int $change_channel The channel_id of the channel you want to change to + * + * @return bool|array false or channel record of the new channel + */ function change_channel($change_channel) { $ret = false; @@ -83,17 +101,17 @@ function change_channel($change_channel) { ); // It's not there. Is this an administrator, and is this the sys channel? - if (is_developer()) { - if (! $r) { - if (is_site_admin()) { - $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and ( channel_pageflags & %d) and not (channel_pageflags & %d )>0 limit 1", - intval($change_channel), - intval(PAGE_SYSTEM), - intval(PAGE_REMOVED) - ); + if (is_developer()) { + if (! $r) { + if (is_site_admin()) { + $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and ( channel_pageflags & %d) and not (channel_pageflags & %d )>0 limit 1", + intval($change_channel), + intval(PAGE_SYSTEM), + intval(PAGE_REMOVED) + ); + } } } - } if($r) { $hash = $r[0]['channel_hash']; @@ -109,23 +127,28 @@ function change_channel($change_channel) { ); if($x) { $_SESSION['my_url'] = $x[0]['xchan_url']; - $_SESSION['my_address'] = $r[0]['channel_address'] . '@' . substr(get_app()->get_baseurl(),strpos(get_app()->get_baseurl(),'://')+3); + $_SESSION['my_address'] = $r[0]['channel_address'] . '@' . substr(get_app()->get_baseurl(), strpos(get_app()->get_baseurl(), '://') + 3); get_app()->set_observer($x[0]); - get_app()->set_perms(get_all_perms(local_user(),$hash)); + get_app()->set_perms(get_all_perms(local_user(), $hash)); } if(! is_dir('store/' . $r[0]['channel_address'])) @os_mkdir('store/' . $r[0]['channel_address'], STORAGE_DEFAULT_PERMISSIONS,true); - } return $ret; - } - - -function permissions_sql($owner_id,$remote_verified = false,$groups = null) { +/** + * @brief Creates an addiontal SQL where statement to check permissions. + * + * @param int $owner_id + * @param bool $remote_verified default false, not used at all + * @param string $groups this param is not used at all + * + * @return string additional SQL where statement + */ +function permissions_sql($owner_id, $remote_verified = false, $groups = null) { if(defined('STATUSNET_PRIVACY_COMPATIBILITY')) return ''; @@ -142,8 +165,7 @@ function permissions_sql($owner_id,$remote_verified = false,$groups = null) { $sql = " AND allow_cid = '' AND allow_gid = '' AND deny_cid = '' - AND deny_gid = '' - + AND deny_gid = '' "; /** @@ -162,7 +184,6 @@ function permissions_sql($owner_id,$remote_verified = false,$groups = null) { * done this and passed the groups into this function. */ - else { $observer = get_observer_hash(); if($observer) { @@ -191,7 +212,16 @@ function permissions_sql($owner_id,$remote_verified = false,$groups = null) { return $sql; } -function item_permissions_sql($owner_id,$remote_verified = false,$groups = null) { +/** + * @brief Creates an addiontal SQL where statement to check permissions for an item. + * + * @param int $owner_id + * @param bool $remote_verified default false, not used at all + * @param string $groups this param is not used at all + * + * @return string additional SQL where statement + */ +function item_permissions_sql($owner_id, $remote_verified = false, $groups = null) { if(defined('STATUSNET_PRIVACY_COMPATIBILITY')) return ''; @@ -206,7 +236,6 @@ function item_permissions_sql($owner_id,$remote_verified = false,$groups = null) */ $sql = " AND item_private=0 "; - /** * Profile owner - everything is visible @@ -224,7 +253,6 @@ function item_permissions_sql($owner_id,$remote_verified = false,$groups = null) * done this and passed the groups into this function. */ - else { $observer = get_observer_hash(); @@ -250,12 +278,18 @@ function item_permissions_sql($owner_id,$remote_verified = false,$groups = null) ); } } + return $sql; } +/** + * @param string $observer_hash + * + * @return string additional SQL where statement + */ function public_permissions_sql($observer_hash) { - $observer = get_app()->get_observer(); + //$observer = get_app()->get_observer(); $groups = init_groups_visitor($observer_hash); $gs = '<<>>'; // should be impossible to match @@ -263,7 +297,7 @@ function public_permissions_sql($observer_hash) { if(is_array($groups) && count($groups)) { foreach($groups as $g) $gs .= '|<' . $g . '>'; - } + } $sql = ''; if($observer_hash) { $regexop = db_getfunc('REGEXP'); @@ -341,11 +375,11 @@ function check_form_security_token_ForbiddenOnErr($typename = '', $formname = 'f } } + // Returns an array of group id's this contact is a member of. // This array will only contain group id's related to the uid of this // DFRN contact. They are *not* neccessarily unique across the entire site. - if(! function_exists('init_groups_visitor')) { function init_groups_visitor($contact_id) { $groups = array(); @@ -361,8 +395,6 @@ function init_groups_visitor($contact_id) { - - // This is used to determine which uid have posts which are visible to the logged in user (from the API) for the // public_timeline, and we can use this in a community page by making // $perms = (PERMS_NETWORK|PERMS_PUBLIC) unless logged in. @@ -380,21 +412,24 @@ function stream_perms_api_uids($perms = NULL ) { $ret[] = local_user(); $r = q("select channel_id from channel where channel_r_stream > 0 and (channel_r_stream & %d)>0 and not (channel_pageflags & %d)>0", intval($perms), - intval(PAGE_CENSORED|PAGE_SYSTEM|PAGE_REMOVED) + intval(PAGE_ADULT|PAGE_CENSORED|PAGE_SYSTEM|PAGE_REMOVED) ); - if($r) + if($r) { foreach($r as $rr) - if(! in_array($rr['channel_id'],$ret)) + if(! in_array($rr['channel_id'], $ret)) $ret[] = $rr['channel_id']; + } $str = ''; - if($ret) + if($ret) { foreach($ret as $rr) { if($str) $str .= ','; $str .= intval($rr); } + } logger('stream_perms_api_uids: ' . $str, LOGGER_DEBUG); + return $str; } @@ -407,21 +442,23 @@ function stream_perms_xchans($perms = NULL ) { $r = q("select channel_hash from channel where channel_r_stream > 0 and (channel_r_stream & %d)>0 and not (channel_pageflags & %d)>0", intval($perms), - intval(PAGE_CENSORED|PAGE_SYETEM|PAGE_REMOVED) + intval(PAGE_ADULT|PAGE_CENSORED|PAGE_SYSTEM|PAGE_REMOVED) ); - if($r) + if($r) { foreach($r as $rr) - if(! in_array($rr['channel_hash'],$ret)) + if(! in_array($rr['channel_hash'], $ret)) $ret[] = $rr['channel_hash']; + } $str = ''; - if($ret) + if($ret) { foreach($ret as $rr) { if($str) $str .= ','; $str .= "'" . dbesc($rr) . "'"; } + } logger('stream_perms_xchans: ' . $str, LOGGER_DEBUG); + return $str; } - diff --git a/include/taxonomy.php b/include/taxonomy.php index fab31c73d..be80008df 100644 --- a/include/taxonomy.php +++ b/include/taxonomy.php @@ -216,6 +216,26 @@ function tagblock($link,$uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$ return $o; } +function wtagblock($uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$type = TERM_HASHTAG) { + $o = ''; + $tab = 0; + $r = tagadelic($uid,$count,$authors,$flags,$restrict,$type); + + if($r) { + $c = q("select channel_address from channel where channel_id = %d limit 1", + intval($uid) + ); + + $o = '<div class="tagblock widget"><h3>' . t('Tags') . '</h3><div class="tags" align="center">'; + foreach($r as $rr) { + $o .= '<span class="tag' . $rr[2] . '">#</span><a href="channel/' . $c[0]['channel_address'] . '?f=&tag=' . urlencode($rr[0]).'" class="tag'.$rr[2].'">'.$rr[0].'</a> ' . "\r\n"; + } + $o .= '</div></div>'; + } + return $o; +} + + function catblock($uid,$count = 0,$authors = '',$flags = 0,$restrict = 0,$type = TERM_CATEGORY) { $o = ''; $tab = 0; diff --git a/include/text.php b/include/text.php index ce729ac1b..cd34fd88d 100644 --- a/include/text.php +++ b/include/text.php @@ -181,34 +181,34 @@ function autoname($len) { 'kh', 'kl','kr','mn','pl','pr','rh','tr','qu','wh'); $start = mt_rand(0,2); - if($start == 0) - $table = $vowels; - else - $table = $cons; + if($start == 0) + $table = $vowels; + else + $table = $cons; $word = ''; for ($x = 0; $x < $len; $x ++) { - $r = mt_rand(0,count($table) - 1); - $word .= $table[$r]; - - if($table == $vowels) - $table = array_merge($cons,$midcons); - else - $table = $vowels; + $r = mt_rand(0,count($table) - 1); + $word .= $table[$r]; + + if($table == $vowels) + $table = array_merge($cons,$midcons); + else + $table = $vowels; } $word = substr($word,0,$len); foreach($noend as $noe) { - if((strlen($word) > 2) && (substr($word,-2) == $noe)) { - $word = substr($word,0,-1); - break; - } + if((strlen($word) > 2) && (substr($word,-2) == $noe)) { + $word = substr($word,0,-1); + break; + } } if(substr($word,-1) == 'q') - $word = substr($word,0,-1); + $word = substr($word,0,-1); return $word; } @@ -224,11 +224,11 @@ function autoname($len) { */ function xmlify($str) { $buffer = ''; - + $len = mb_strlen($str); for($x = 0; $x < $len; $x ++) { $char = mb_substr($str,$x,1); - + switch( $char ) { case "\r" : @@ -267,7 +267,7 @@ function xmlify($str) { function unxmlify($s) { $ret = str_replace('&','&', $s); $ret = str_replace(array('<','>','"','''),array('<','>','"',"'"),$ret); - return $ret; + return $ret; } // convenience wrapper, reverse the operation "bin2hex" @@ -314,8 +314,7 @@ function paginate(&$a) { $pagenum = $a->pager['page']; $url = $a->get_baseurl() . '/' . $stripped; - - if($a->pager['total'] > $a->pager['itemspage']) { + if($a->pager['total'] > $a->pager['itemspage']) { $o .= '<div class="pager">'; if($a->pager['page'] != 1) $o .= '<span class="pager_prev">'."<a href=\"$url".'&page='.($a->pager['page'] - 1).'">' . t('prev') . '</a></span> '; @@ -331,7 +330,7 @@ function paginate(&$a) { $numstart = (($pagenum > 7) ? ($pagenum - 7) : 1); $numstop = (($pagenum > ($numpages - 7)) ? $numpages : ($numstart + 14)); } - + for($i = $numstart; $i <= $numstop; $i++){ if($i == $a->pager['page']) $o .= '<span class="pager_current">'.(($i < 10) ? ' '.$i : $i); @@ -405,7 +404,7 @@ function expand_acl($s) { } } return $ret; -} +} // Used to wrap ACL elements in angle brackets for storage @@ -420,7 +419,6 @@ function sanitise_acl(&$item) { // Convert an ACL array to a storable string - function perms2str($p) { $ret = ''; @@ -436,16 +434,17 @@ function perms2str($p) { return $ret; } -// generate a guaranteed unique (for this domain) item ID for ATOM -// safe from birthday paradox - - +/** + * @brief Generate a guaranteed unique (for this domain) item ID for ATOM. + * + * Safe from birthday paradox. + * + * @return string a unique id + */ function item_message_id() { - do { $dups = false; $hash = random_string(); - $mid = $hash . '@' . get_app()->get_hostname(); $r = q("SELECT id FROM item WHERE mid = '%s' LIMIT 1", @@ -453,31 +452,33 @@ function item_message_id() { if(count($r)) $dups = true; } while($dups == true); + return $mid; } -// Generate a guaranteed unique photo ID. -// safe from birthday paradox - - +/** + * @brief Generate a guaranteed unique photo ID. + * + * Safe from birthday paradox. + * + * @return string a uniqe hash + */ function photo_new_resource() { - do { $found = false; - $resource = hash('md5',uniqid(mt_rand(),true)); + $resource = hash('md5', uniqid(mt_rand(), true)); + $r = q("SELECT id FROM photo WHERE resource_id = '%s' LIMIT 1", - dbesc($resource) - ); + dbesc($resource)); if(count($r)) $found = true; - } while($found == true); + } while($found === true); + return $resource; } - - // for html,xml parsing - let's say you've got // an attribute foobar="class1 class2 class3" // and you want to find out if it contains 'class3'. @@ -487,52 +488,76 @@ function photo_new_resource() { // pass the attribute string as $attr and the attribute you // are looking for as $s - returns true if found, otherwise false -function attribute_contains($attr,$s) { +function attribute_contains($attr, $s) { $a = explode(' ', $attr); - if(count($a) && in_array($s,$a)) + if(count($a) && in_array($s, $a)) return true; + return false; } - -function logger($msg,$level = 0) { +/** + * @brief Logging function for RedMatrix. + * + * Logging output is configured through RedMatrix's system config. The log file + * is set in system logfile, log level in system loglevel and to enable logging + * set system debugging. + * + * Available constants for log level are LOGGER_NORMAL, LOGGER_TRACE, LOGGER_DEBUG, + * LOGGER_DATA and LOGGER_ALL. + * + * Since PHP5.4 we get the file, function and line automatically where the logger + * was caleld, so no need to add it to the message anymore. + * + * @param string $msg Message to log + * @param int $level A log level. + */ +function logger($msg, $level = 0) { // turn off logger in install mode global $a; global $db; - if(($a->module == 'install') || (! ($db && $db->connected))) return; + if(($a->module == 'install') || (! ($db && $db->connected))) + return; - $debugging = get_config('system','debugging'); - $loglevel = intval(get_config('system','loglevel')); - $logfile = get_config('system','logfile'); + $debugging = get_config('system', 'debugging'); + $loglevel = intval(get_config('system', 'loglevel')); + $logfile = get_config('system', 'logfile'); if((! $debugging) || (! $logfile) || ($level > $loglevel)) return; $where = ''; - if(version_compare(PHP_VERSION,'5.4.0') >= 0) { - $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2); + if(version_compare(PHP_VERSION, '5.4.0') >= 0) { + $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; } - @file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . "\n", FILE_APPEND); - return; + @file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND); } - -// This is a special logging facility for developers. It allows one to target specific things to trace/debug -// and is identical to logger() with the exception of the log filename. This allows one to isolate specific -// calls while allowing logger() to paint a bigger picture of overall activity and capture more detail. -// If you find dlogger() calls in checked in code, you are free to remove them - so as to provide a noise-free -// development environment which responds to events you are targetting personally. - - -function dlogger($msg,$level = 0) { +/** + * @brief This is a special logging facility for developers. + * + * It allows one to target specific things to trace/debug and is identical to + * logger() with the exception of the log filename. This allows one to isolate + * specific calls while allowing logger() to paint a bigger picture of overall + * activity and capture more detail. + * + * If you find dlogger() calls in checked in code, you are free to remove them - + * so as to provide a noise-free development environment which responds to events + * you are targetting personally. + * + * @param string $msg Message to log + * @param int $level A log level. + */ +function dlogger($msg, $level = 0) { // turn off logger in install mode global $a; global $db; - if(($a->module == 'install') || (! ($db && $db->connected))) return; + if(($a->module == 'install') || (! ($db && $db->connected))) + return; $debugging = get_config('system','debugging'); $loglevel = intval(get_config('system','loglevel')); @@ -540,19 +565,23 @@ function dlogger($msg,$level = 0) { if((! $debugging) || (! $logfile) || ($level > $loglevel)) return; - - @file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $msg . "\n", FILE_APPEND); - return; + + $where = ''; + if(version_compare(PHP_VERSION, '5.4.0') >= 0) { + $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; + } + + @file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND); } function profiler($t1,$t2,$label) { if(file_exists('profiler.out') && $t1 && t2) - @file_put_contents('profiler.out', sprintf('%01.4f %s',$t2 - $t1,$label) . "\n", FILE_APPEND); + @file_put_contents('profiler.out', sprintf('%01.4f %s',$t2 - $t1,$label) . PHP_EOL, FILE_APPEND); } - function activity_match($haystack,$needle) { if(($haystack === $needle) || ((basename($needle) === $haystack) && strstr($needle,NAMESPACE_ACTIVITY_SCHEMA))) return true; @@ -569,7 +598,6 @@ function activity_match($haystack,$needle) { // Returns array of tags found, or empty array. - function get_tags($s) { $ret = array(); @@ -592,9 +620,6 @@ function get_tags($s) { // Match full names against @tags including the space between first and last // We will look these up afterward to see if they are full names or not recognisable. - - - if(preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/',$s,$match)) { foreach($match[1] as $mtch) { if(strstr($mtch,"]")) { @@ -648,7 +673,6 @@ function get_tags($s) { usort($ret,'tag_sort_length'); - // logger('get_tags: ' . print_r($ret,true)); return $ret; @@ -657,13 +681,12 @@ function get_tags($s) { function tag_sort_length($a,$b) { if(mb_strlen($a) == mb_strlen($b)) return 0; + return((mb_strlen($b) < mb_strlen($a)) ? (-1) : 1); } - - function strip_zids($s) { return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s); } @@ -673,12 +696,10 @@ function strip_zids($s) { function qp($s) { -return str_replace ("%","=",rawurlencode($s)); + return str_replace ("%","=",rawurlencode($s)); } - - function get_mentions($item,$tags) { $o = ''; @@ -712,7 +733,6 @@ function contact_block() { if($shown == 0) return; - $is_owner = ((local_user() && local_user() == $a->profile['uid']) ? true : false); $abook_flags = ABOOK_FLAG_PENDING|ABOOK_FLAG_SELF; @@ -734,8 +754,7 @@ function contact_block() { } if(! $total) { $contacts = t('No connections'); - $micropro = Null; - + $micropro = null; } else { if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { $randfunc = 'RANDOM()'; @@ -758,7 +777,7 @@ function contact_block() { } } } - + $tpl = get_markup_template('contact_block.tpl'); $o = replace_macros($tpl, array( '$contacts' => $contacts, @@ -771,7 +790,6 @@ function contact_block() { call_hooks('contact_block_end', $arr); return $o; - } @@ -815,8 +833,6 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) { } - - function search($s,$id='search-box',$url='/search',$save = false) { $a = get_app(); return replace_macros(get_markup_template('searchbox.tpl'),array( @@ -843,12 +859,12 @@ function searchbox($s,$id='search-box',$url='/search',$save = false) { function valid_email($x){ - if(get_config('system','disable_email_validation')) return true; if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x)) return true; + return false; } @@ -868,6 +884,7 @@ function linkify($s) { return($s); } + /** * @function sslify($s) * Replace media element using http url with https to a local redirector if using https locally @@ -879,11 +896,10 @@ function linkify($s) { * * @returns string */ - - function sslify($s) { if(strpos(z_root(),'https:') === false) return $s; + $matches = null; $cnt = preg_match_all("/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/",$s,$matches,PREG_SET_ORDER); if($cnt) { @@ -897,7 +913,6 @@ function sslify($s) { function get_poke_verbs() { - // index is present tense verb // value is array containing past tense verb, translation of present, translation of past @@ -909,12 +924,13 @@ function get_poke_verbs() { 'finger' => array( 'fingered', t('finger'), t('fingered')), 'rebuff' => array( 'rebuffed', t('rebuff'), t('rebuffed')), ); + call_hooks('poke_verbs', $arr); return $arr; } function get_mood_verbs() { - + $arr = array( 'happy' => t('happy'), 'sad' => t('sad'), @@ -943,41 +959,10 @@ function get_mood_verbs() { return $arr; } - -/** - * - * Function: smilies - * - * Description: - * Replaces text emoticons with graphical images - * - * @Parameter: string $s - * - * Returns string - * - * It is expected that this function will be called using HTML text. - * We will escape text between HTML pre and code blocks, and HTML attributes - * (such as urls) from being processed. - * - * At a higher level, the bbcode [nosmile] tag can be used to prevent this - * function from being executed by the prepare_text() routine when preparing - * bbcode source for HTML display - * - */ - - -function smilies($s, $sample = false) { - +// Function to list all smilies, both internal and from addons +// Returns array with keys 'texts' and 'icons' +function list_smilies() { $a = get_app(); - - if(intval(get_config('system','no_smilies')) - || (local_user() && intval(get_pconfig(local_user(),'system','no_smilies')))) - return $s; - - - $s = preg_replace_callback('{<(pre|code)>.*?</\1>}ism','smile_shield',$s); - $s = preg_replace_callback('/<[a-z]+ .*?>/ism','smile_shield',$s); - $texts = array( '<3', '</3', @@ -1055,8 +1040,42 @@ function smilies($s, $sample = false) { ); - $params = array('texts' => $texts, 'icons' => $icons, 'string' => $s); + $params = array('texts' => $texts, 'icons' => $icons); call_hooks('smilie', $params); + return $params; +} +/** + * + * Function: smilies + * + * Description: + * Replaces text emoticons with graphical images + * + * @Parameter: string $s + * + * Returns string + * + * It is expected that this function will be called using HTML text. + * We will escape text between HTML pre and code blocks, and HTML attributes + * (such as urls) from being processed. + * + * At a higher level, the bbcode [nosmile] tag can be used to prevent this + * function from being executed by the prepare_text() routine when preparing + * bbcode source for HTML display + * + */ +function smilies($s, $sample = false) { + $a = get_app(); + + if(intval(get_config('system','no_smilies')) + || (local_user() && intval(get_pconfig(local_user(),'system','no_smilies')))) + return $s; + + $s = preg_replace_callback('{<(pre|code)>.*?</\1>}ism','smile_shield',$s); + $s = preg_replace_callback('/<[a-z]+ .*?>/ism','smile_shield',$s); + + $params = list_smilies(); + $params['string'] = $s; if($sample) { $s = '<div class="smiley-sample">'; @@ -1072,7 +1091,6 @@ function smilies($s, $sample = false) { $s = preg_replace_callback('/<!--base64:(.*?)-->/ism', 'smile_unshield', $s); return $s; - } function smile_shield($m) { @@ -1132,6 +1150,7 @@ function normalise_link($url) { function link_compare($a,$b) { if(strcasecmp(normalise_link($a),normalise_link($b)) === 0) return true; + return false; } @@ -1147,7 +1166,6 @@ function unobscure(&$item) { if($item['body']) $item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key); } - } function theme_attachments(&$item) { @@ -1190,12 +1208,10 @@ function theme_attachments(&$item) { $url = $r['href']; else $url = z_root() . '/magic?f=&hash=' . $item['author_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision']; + $s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>'; $attaches[] = array('title' => $title, 'url' => $url, 'icon' => $icon ); - } - - } $s = replace_macros(get_markup_template('item_attach.tpl'), array( @@ -1203,13 +1219,12 @@ function theme_attachments(&$item) { )); return $s; - } function format_categories(&$item,$writeable) { - $s = ''; + $terms = get_terms_oftype($item['term'],TERM_CATEGORY); if($terms) { $categories = array(); @@ -1225,6 +1240,7 @@ function format_categories(&$item,$writeable) { '$remove' => t('remove category'), '$categories' => $categories )); + return $s; } @@ -1235,7 +1251,6 @@ function format_hashtags(&$item) { $s = ''; $terms = get_terms_oftype($item['term'],TERM_HASHTAG); if($terms) { - $categories = array(); foreach($terms as $t) { $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; if(! trim($term)) @@ -1255,11 +1270,10 @@ function format_hashtags(&$item) { function format_mentions(&$item) { - $s = ''; + $terms = get_terms_oftype($item['term'],TERM_MENTION); if($terms) { - $categories = array(); foreach($terms as $t) { $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; if(! trim($term)) @@ -1278,8 +1292,8 @@ function format_mentions(&$item) { function format_filer(&$item) { - $s = ''; + $terms = get_terms_oftype($item['term'],TERM_FILE); if($terms) { $categories = array(); @@ -1295,18 +1309,28 @@ function format_filer(&$item) { '$remove' => t('remove from file'), '$categories' => $categories )); + return $s; } +function generate_map($coord) { + $coord = trim($coord); + $coord = str_replace(array(',','/',' '),array(' ',' ',' '),$coord); + $arr = array('lat' => trim(substr($coord,0,strpos($coord,' '))), 'lon' => trim(substr($coord,strpos($coord,' ')+1)), 'html' => ''); + call_hooks('generate_map',$arr); + return $arr['html']; +} +function generate_named_map($location) { + $arr = array('location' => $location, 'html' => ''); + call_hooks('generate_named_map',$arr); + return $arr['html']; +} -function prepare_body(&$item,$attach = false) { - - $a = get_app(); - +function prepare_body(&$item,$attach = false) { call_hooks('prepare_body_init', $item); @@ -1322,28 +1346,29 @@ function prepare_body(&$item,$attach = false) { return $s; } + if(strpos($s,'<div class="map">') !== false && $item['coord']) { + $x = generate_map(trim($item['coord'])); + if($x) { + $s = preg_replace('/\<div class\=\"map\"\>/','$0' . $x,$s); + } + } $s .= theme_attachments($item); - - $writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false); - + $writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false); $s .= format_hashtags($item); if($item['resource_type']) $s .= format_mentions($item); - $s .= format_categories($item,$writeable); if(local_user() == $item['uid']) $s .= format_filer($item); - $s = sslify($s); - // Look for spoiler $spoilersearch = '<blockquote class="spoiler">'; @@ -1358,7 +1383,7 @@ function prepare_body(&$item,$attach = false) { $pos = strpos($s, $spoilersearch); $rnd = random_string(8); $spoilerreplace = '<br /> <span id="spoiler-wrap-'.$rnd.'" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'spoiler-'.$rnd.'\');">'.sprintf(t('Click to open/close')).'</span>'. - '<blockquote class="spoiler" id="spoiler-'.$rnd.'" style="display: none;">'; + '<blockquote class="spoiler" id="spoiler-'.$rnd.'" style="display: none;">'; $s = substr($s, 0, $pos).$spoilerreplace.substr($s, $pos+strlen($spoilersearch)); } @@ -1366,11 +1391,10 @@ function prepare_body(&$item,$attach = false) { $authorsearch = '<blockquote class="author">'; while ((strpos($s, $authorsearch) !== false)) { - $pos = strpos($s, $authorsearch); $rnd = random_string(8); $authorreplace = '<br /> <span id="author-wrap-'.$rnd.'" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'author-'.$rnd.'\');">'.sprintf(t('Click to open/close')).'</span>'. - '<blockquote class="author" id="author-'.$rnd.'" style="display: block;">'; + '<blockquote class="author" id="author-'.$rnd.'" style="display: block;">'; $s = substr($s, 0, $pos).$authorreplace.substr($s, $pos+strlen($authorsearch)); } @@ -1386,10 +1410,7 @@ function prepare_body(&$item,$attach = false) { function prepare_text($text,$content_type = 'text/bbcode') { - - switch($content_type) { - case 'text/plain': $s = escape_tags($text); break; @@ -1459,7 +1480,7 @@ function zidify_callback($match) { function zidify_img_callback($match) { $is_zid = ((feature_enabled(local_user(),'sendzid')) || (strpos($match[1],'zrl')) ? true : false); $replace = '<img' . $match[1] . ' src="' . (($is_zid) ? zid($match[2]) : $match[2]) . '"'; - + $x = str_replace($match[0],$replace,$match[0]); return $x; } @@ -1472,14 +1493,11 @@ function zidify_links($s) { } - /** * return atom link elements for all of our hubs */ - function feed_hublinks() { - $hub = get_config('system','huburl'); $hubxml = ''; @@ -1494,14 +1512,13 @@ function feed_hublinks() { } } } + return $hubxml; } /* return atom link elements for salmon endpoints */ - function feed_salmonlinks($nick) { - $a = get_app(); $salmon = '<link rel="salmon" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; @@ -1510,23 +1527,23 @@ function feed_salmonlinks($nick) { $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; + return $salmon; } function get_plink($item,$conversation_mode = true) { - $a = get_app(); if($conversation_mode) $key = 'plink'; else $key = 'llink'; - + if(x($item,$key)) { return array( 'href' => zid($item[$key]), 'title' => t('Link to Source'), ); - } + } else { return false; } @@ -1558,9 +1575,6 @@ function layout_select($channel_id, $current = '') { } - - - function mimetype_select($channel_id, $current = 'text/bbcode') { $x = array( @@ -1591,19 +1605,17 @@ function mimetype_select($channel_id, $current = 'text/bbcode') { $o .= '</select>'; return $o; - } - function lang_selector() { global $a; - + $langs = glob('view/*/strings.php'); - + $lang_options = array(); $selected = ""; - + if(is_array($langs) && count($langs)) { $langs[] = ''; if(! in_array('view/en/strings.php',$langs)) @@ -1621,25 +1633,24 @@ function lang_selector() { } } - $tpl = get_markup_template("lang_selector.tpl"); + $tpl = get_markup_template("lang_selector.tpl"); $o = replace_macros($tpl, array( '$title' => t('Select an alternate language'), '$langs' => array($lang_options, $selected), )); + return $o; } - function return_bytes ($size_str) { - switch (substr ($size_str, -1)) - { - case 'M': case 'm': return (int)$size_str * 1048576; - case 'K': case 'k': return (int)$size_str * 1024; - case 'G': case 'g': return (int)$size_str * 1073741824; - default: return $size_str; - } + switch (substr ($size_str, -1)) { + case 'M': case 'm': return (int)$size_str * 1048576; + case 'K': case 'k': return (int)$size_str * 1024; + case 'G': case 'g': return (int)$size_str * 1073741824; + default: return $size_str; + } } @@ -1654,7 +1665,6 @@ function base64url_encode($s, $strip_padding = true) { } function base64url_decode($s) { - if(is_array($s)) { logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true)); return $s; @@ -1662,7 +1672,11 @@ function base64url_decode($s) { return base64_decode(strtr($s,'-_','+/')); } - +/** + * @ Return a div to clear floats. + * + * @return string + */ function cleardiv() { return '<div class="clear"></div>'; } @@ -1680,7 +1694,7 @@ function bb_translate_video($s) { $s = str_replace($mtch[0],'[vimeo]' . $mtch[1] . '[/vimeo]',$s); } } - return $s; + return $s; } function html2bb_video($s) { @@ -1700,61 +1714,57 @@ function html2bb_video($s) { /** * apply xmlify() to all values of array $val, recursively */ -function array_xmlify($val){ +function array_xmlify($val) { if (is_bool($val)) return $val?"true":"false"; if (is_array($val)) return array_map('array_xmlify', $val); return xmlify((string) $val); } -function reltoabs($text, $base) -{ - if (empty($base)) - return $text; +function reltoabs($text, $base) { + if (empty($base)) + return $text; - $base = rtrim($base,'/'); + $base = rtrim($base,'/'); - $base2 = $base . "/"; - - // Replace links - $pattern = "/<a([^>]*) href=\"(?!http|https|\/)([^\"]*)\"/"; - $replace = "<a\${1} href=\"" . $base2 . "\${2}\""; - $text = preg_replace($pattern, $replace, $text); + $base2 = $base . "/"; - $pattern = "/<a([^>]*) href=\"(?!http|https)([^\"]*)\"/"; - $replace = "<a\${1} href=\"" . $base . "\${2}\""; - $text = preg_replace($pattern, $replace, $text); + // Replace links + $pattern = "/<a([^>]*) href=\"(?!http|https|\/)([^\"]*)\"/"; + $replace = "<a\${1} href=\"" . $base2 . "\${2}\""; + $text = preg_replace($pattern, $replace, $text); - // Replace images - $pattern = "/<img([^>]*) src=\"(?!http|https|\/)([^\"]*)\"/"; - $replace = "<img\${1} src=\"" . $base2 . "\${2}\""; - $text = preg_replace($pattern, $replace, $text); + $pattern = "/<a([^>]*) href=\"(?!http|https)([^\"]*)\"/"; + $replace = "<a\${1} href=\"" . $base . "\${2}\""; + $text = preg_replace($pattern, $replace, $text); - $pattern = "/<img([^>]*) src=\"(?!http|https)([^\"]*)\"/"; - $replace = "<img\${1} src=\"" . $base . "\${2}\""; - $text = preg_replace($pattern, $replace, $text); + // Replace images + $pattern = "/<img([^>]*) src=\"(?!http|https|\/)([^\"]*)\"/"; + $replace = "<img\${1} src=\"" . $base2 . "\${2}\""; + $text = preg_replace($pattern, $replace, $text); + $pattern = "/<img([^>]*) src=\"(?!http|https)([^\"]*)\"/"; + $replace = "<img\${1} src=\"" . $base . "\${2}\""; + $text = preg_replace($pattern, $replace, $text); - // Done - return $text; + // Done + return $text; } function item_post_type($item) { - - - switch($item['resource_type']) { - case 'photo': - $post_type = t('photo'); - break; - case 'event': - $post_type = t('event'); - break; - default: - $post_type = t('status'); - if($item['mid'] != $item['parent_mid']) - $post_type = t('comment'); - break; - } + switch($item['resource_type']) { + case 'photo': + $post_type = t('photo'); + break; + case 'event': + $post_type = t('event'); + break; + default: + $post_type = t('status'); + if($item['mid'] != $item['parent_mid']) + $post_type = t('comment'); + break; + } if(strlen($item['verb']) && (! activity_match($item['verb'],ACTIVITY_POST))) $post_type = t('activity'); @@ -1796,6 +1806,7 @@ function is_a_date_arg($s) { return true; } } + return false; } @@ -1820,7 +1831,7 @@ function check_webbie($arr) { $taken = explode(',', $reservechan); else $taken = array(); - + $str = ''; if(count($arr)) { foreach($arr as $x) { @@ -1847,14 +1858,16 @@ function check_webbie($arr) { } } } + return ''; } - + function ids_to_querystr($arr,$idx = 'id') { $t = array(); foreach($arr as $x) $t[] = $x[$idx]; + return(implode(',', $t)); } @@ -1903,7 +1916,6 @@ function xchan_query(&$items,$abook = true,$effective_uid = 0) { $items[$x]['author'] = find_xchan_in_array($items[$x]['author_xchan'],$chans); } } - } function xchan_mail_query(&$item) { @@ -1943,6 +1955,7 @@ function get_rel_link($j,$rel) { foreach($j as $l) if($l['rel'] === $rel) return $l['href']; + return ''; } @@ -1952,7 +1965,7 @@ function get_rel_link($j,$rel) { function magic_link($s) { return $s; } - + // if $escape is true, dbesc() each element before adding quotes function stringify_array_elms(&$arr,$escape = false) { @@ -1969,23 +1982,22 @@ function stringify_array_elms(&$arr,$escape = false) { */ function jindent($json) { - $result = ''; - $pos = 0; - $strLen = strlen($json); - $indentStr = ' '; - $newLine = "\n"; - $prevChar = ''; + $result = ''; + $pos = 0; + $strLen = strlen($json); + $indentStr = ' '; + $newLine = "\n"; + $prevChar = ''; $outOfQuotes = true; for ($i=0; $i<=$strLen; $i++) { - // Grab the next character in the string. $char = substr($json, $i, 1); // Are we inside a quoted string? if ($char == '"' && $prevChar != '\\') { $outOfQuotes = !$outOfQuotes; - + // If this character is the end of an element, // output a new line and indent the next line. } else if(($char == '}' || $char == ']') && $outOfQuotes) { @@ -1995,7 +2007,7 @@ function jindent($json) { $result .= $indentStr; } } - + // Add the character to the result string. $result .= $char; @@ -2006,7 +2018,7 @@ function jindent($json) { if ($char == '{' || $char == '[') { $pos ++; } - + for ($j = 0; $j < $pos; $j++) { $result .= $indentStr; } @@ -2020,12 +2032,11 @@ function jindent($json) { function json_decode_plus($s) { - $x = json_decode($s,true); if(! $x) $x = json_decode(str_replace(array('\\"','\\\\'),array('"','\\'),$s),true); - return $x; + return $x; } @@ -2087,3 +2098,255 @@ function extra_query_args() { } return $s; } + +/** + * This function removes the tag $tag from the text $body and replaces it with + * the appropiate link. + * + * @param unknown_type $body the text to replace the tag in + * @param unknown_type $access_tag - used to return tag ACL exclusions e.g. @!foo + * @param unknown_type $str_tags string to add the tag to + * @param unknown_type $profile_uid + * @param unknown_type $tag the tag to replace + * + * @return boolean true if replaced, false if not replaced + */ +function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) { + + $replaced = false; + $r = null; + + $termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN); + $termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype); + $termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype); + + //is it a hash tag? + if(strpos($tag,'#') === 0) { + if(strpos($tag,'#^[') === 0) { + if(preg_match('/#\^\[(url|zrl)(.*?)\](.*?)\[\/(url|zrl)\]/',$tag,$match)) { + $basetag = $match[3]; + $url = ((substr($match[2],0,1) === '=') ? substr($match[2],1) : $match[3]); + $replaced = true; + } + } + // if the tag is already replaced... + elseif((strpos($tag,'[zrl=')) || (strpos($tag,'[url='))) { + //...do nothing + return $replaced; + } + if($tag == '#getzot') { + $basetag = 'getzot'; + $url = 'https://redmatrix.me'; + $newtag = '#[zrl=' . $url . ']' . $basetag . '[/zrl]'; + $body = str_replace($tag,$newtag,$body); + $replaced = true; + } + if(! $replaced) { + + //base tag has the tags name only + + if((substr($tag,0,7) === '#"') && (substr($tag,-6,6) === '"')) { + $basetag = substr($tag,7); + $basetag = substr($basetag,0,-6); + } + else + $basetag = str_replace('_',' ',substr($tag,1)); + + //create text for link + $url = $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag); + $newtag = '#[zrl=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/zrl]'; + //replace tag by the link + $body = str_replace($tag, $newtag, $body); + $replaced = true; + } + //is the link already in str_tags? + if(! stristr($str_tags,$newtag)) { + //append or set str_tags + if(strlen($str_tags)) + $str_tags .= ','; + + $str_tags .= $newtag; + } + return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $basetag, 'url' => $url, 'contact' => $r[0]); + } + + //is it a person tag? + + if(strpos($tag,'@') === 0) { + + // The @! tag will alter permissions + $exclusive = ((strpos($tag,'!') === 1) ? true : false); + + //is it already replaced? + if(strpos($tag,'[zrl=')) + return $replaced; + + //get the person's name + + $name = substr($tag,(($exclusive) ? 2 : 1)); // The name or name fragment we are going to replace + $newname = $name; // a copy that we can mess with + $tagcid = 0; + + $r = null; + + // is it some generated name? + + $forum = false; + $trailing_plus_name = false; + + // @channel+ is a forum or network delivery tag + + if(substr($newname,-1,1) === '+') { + $forum = true; + $newname = substr($newname,0,-1); + } + + // Here we're looking for an address book entry as provided by the auto-completer + // of the form something+nnn where nnn is an abook_id or the first chars of xchan_hash + + if(strrpos($newname,'+')) { + //get the id + + if(strrpos($tagcid,' ')) + $tagcid = substr($tagcid,0,strrpos($tagcid,' ')); + + $tagcid = substr($newname,strrpos($newname,'+') + 1); + + if(strlen($tagcid) < 16) + $abook_id = intval($tagcid); + //remove the next word from tag's name + if(strpos($name,' ')) { + $name = substr($name,0,strpos($name,' ')); + } + + if($abook_id) { // if there was an id + // select channel with that id from the logged in user's address book + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + WHERE abook_id = %d AND abook_channel = %d LIMIT 1", + intval($abook_id), + intval($profile_uid) + ); + } + else { + $r = q("SELECT * FROM xchan + WHERE xchan_hash like '%s%%' LIMIT 1", + dbesc($tagcid) + ); + } + } + + if(! $r) { + + // look for matching names in the address book + + // Two ways to deal with spaces - double quote the name or use underscores + // we see this after input filtering so quotes have been html entity encoded + + if((substr($name,0,6) === '"') && (substr($name,-6,6) === '"')) { + $newname = substr($name,6); + $newname = substr($newname,0,-6); + } + else + $newname = str_replace('_',' ',$name); + + // do this bit over since we started over with $name + + if(substr($newname,-1,1) === '+') { + $forum = true; + $newname = substr($newname,0,-1); + } + + //select someone from this user's contacts by name + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", + dbesc($newname), + intval($profile_uid) + ); + + if(! $r) { + //select someone by attag or nick and the name passed in + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + WHERE xchan_addr like ('%s') AND abook_channel = %d LIMIT 1", + dbesc(((strpos($newname,'@')) ? $newname : $newname . '@%')), + intval($profile_uid) + ); + } + + if(! $r) { + // it's possible somebody has a name ending with '+', which we stripped off as a forum indicator + // This is very rare but we want to get it right. + + $r = q("SELECT * FROM abook left join xchan on abook_xchan = xchan_hash + WHERE xchan_name = '%s' AND abook_channel = %d LIMIT 1", + dbesc($newname . '+'), + intval($profile_uid) + ); + if($r) + $trailing_plus_name = true; + } + } + + // $r is set if we found something + + $channel = get_app()->get_channel(); + + if($r) { + $profile = $r[0]['xchan_url']; + $newname = $r[0]['xchan_name']; + // add the channel's xchan_hash to $access_tag if exclusive + if($exclusive) { + $access_tag .= 'cid:' . $r[0]['xchan_hash']; + } + } + else { + // check for a group/collection exclusion tag + + // note that we aren't setting $replaced even though we're replacing text. + // This tag isn't going to get a term attached to it. It's only used for + // access control. The link points to out own channel just so it doesn't look + // weird - as all the other tags are linked to something. + + if(local_user() && local_user() == $profile_uid) { + require_once('include/group.php'); + $grp = group_byname($profile_uid,$name); + + if($grp) { + $g = q("select hash from groups where id = %d and visible = 1 limit 1", + intval($grp) + ); + if($g && $exclusive) { + $access_tag .= 'gid:' . $g[0]['hash']; + } + $channel = get_app()->get_channel(); + if($channel) { + $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . z_root() . '/channel/' . $channel['channel_address'] . ']' . $newname . '[/zrl]'; + $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); + } + } + } + } + + if(($exclusive) && (! $access_tag)) { + $access_tag .= 'cid:' . $channel['channel_hash']; + } + + // if there is an url for this channel + + if(isset($profile)) { + $replaced = true; + //create profile link + $profile = str_replace(',','%2c',$profile); + $url = $profile; + $newtag = '@' . (($exclusive) ? '!' : '') . '[zrl=' . $profile . ']' . $newname . (($forum && ! $trailing_plus_name) ? '+' : '') . '[/zrl]'; + $body = str_replace('@' . (($exclusive) ? '!' : '') . $name, $newtag, $body); + //append tag to str_tags + if(! stristr($str_tags,$newtag)) { + if(strlen($str_tags)) + $str_tags .= ','; + $str_tags .= $newtag; + } + } + } + + return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $newname, 'url' => $url, 'contact' => $r[0]); +} diff --git a/include/widgets.php b/include/widgets.php index f7b8a20bd..bb9890add 100644 --- a/include/widgets.php +++ b/include/widgets.php @@ -1,4 +1,9 @@ -<?php /** @file */ +<?php +/** + * @file include/widgets.php + * + * @brief This file contains the widgets. + */ require_once('include/dir_fns.php'); require_once('include/contact_widgets.php'); @@ -6,7 +11,7 @@ require_once('include/contact_widgets.php'); function widget_profile($args) { $a = get_app(); - $block = (((get_config('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false); + $block = (((get_config('system', 'block_public')) && (! local_user()) && (! remote_user())) ? true : false); return profile_sidebar($a->profile, $block, true); } @@ -16,14 +21,15 @@ function widget_profile($args) { function widget_tagcloud($args) { $o = ''; - $tab = 0; + //$tab = 0; $a = get_app(); $uid = $a->profile_uid; $count = ((x($args,'count')) ? intval($args['count']) : 24); $flags = 0; $type = TERM_CATEGORY; - $r = tagadelic($uid,$count,$authors,$flags,ITEM_WEBPAGE,$type); + // FIXME there exists no $authors variable + $r = tagadelic($uid, $count, $authors, $flags, ITEM_WEBPAGE, $type); if($r) { $o = '<div class="tagblock widget"><h3>' . t('Categories') . '</h3><div class="tags" align="center">'; @@ -75,9 +81,8 @@ function widget_collections($args) { return ''; break; } - - return group_side($every, $each, $edit, $current, $abook_id, $wmode); + return group_side($every, $each, $edit, $current, $abook_id, $wmode); } @@ -93,7 +98,6 @@ function widget_appselect($arr) { } - function widget_suggestions($arr) { if((! local_user()) || (! feature_enabled(local_user(),'suggest'))) @@ -114,16 +118,13 @@ function widget_suggestions($arr) { // This will throw some entropy intot he situation so you won't // be looking at the same two mug shots every time the widget runs - $index = ((count($r) > 2) ? mt_rand(0,count($r) - 2) : 0); - for($x = $index; $x <= ($index+1); $x ++) { - $rr = $r[$x]; if(! $rr['xchan_url']) break; - + $connlnk = z_root() . '/follow/?url=' . $rr['xchan_addr']; $arr[] = array( @@ -138,7 +139,6 @@ function widget_suggestions($arr) { ); } - $o = replace_macros(get_markup_template('suggest_widget.tpl'),array( '$title' => t('Suggestions'), '$more' => t('See more...'), @@ -146,13 +146,13 @@ function widget_suggestions($arr) { )); return $o; - } function widget_follow($args) { if(! local_user()) return ''; + $a = get_app(); $uid =$a->channel['channel_id']; $r = q("select count(*) as total from abook where abook_channel = %d and not (abook_flags & %d)>0 ", @@ -163,10 +163,10 @@ function widget_follow($args) { $total_channels = $r[0]['total']; $limit = service_class_fetch($uid,'total_channels'); if($limit !== false) { - $abook_usage_message = sprintf( t("You have %1$.0f of %2$.0f allowed connections."), $total_channels, $limit); + $abook_usage_message = sprintf( t("You have %1$.0f of %2$.0f allowed connections."), $total_channels, $limit); } else { - $abook_usage_message = ''; + $abook_usage_message = ''; } return replace_macros(get_markup_template('follow.tpl'),array( '$connect' => t('Add New Connection'), @@ -175,7 +175,6 @@ function widget_follow($args) { '$follow' => t('Connect'), '$abook_usage_message' => $abook_usage_message )); - } @@ -192,6 +191,7 @@ function widget_notes($arr) { '$text' => $text, '$save' => t('Save'), )); + return $o; } @@ -228,8 +228,6 @@ function widget_savedsearch($arr) { $search = ''; } - - $srchurl = $a->query_string; $srchurl = rtrim(preg_replace('/searchsave\=[^\&].*?(\&|$)/is','',$srchurl),'&'); @@ -238,9 +236,13 @@ function widget_savedsearch($arr) { $hasq = ((strpos($srchurl,'?') !== false) ? true : false); $srchurl = rtrim(preg_replace('/search\=[^\&].*?(\&|$)/is','',$srchurl),'&'); + $srchurl = rtrim(preg_replace('/submit\=[^\&].*?(\&|$)/is','',$srchurl),'&'); $srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl); + + $hasq = ((strpos($srchurl,'?') !== false) ? true : false); - + + $o = ''; $r = q("select `tid`,`term` from `term` WHERE `uid` = %d and `type` = %d ", @@ -252,31 +254,28 @@ function widget_savedsearch($arr) { if(count($r)) { foreach($r as $rr) { - $saved[] = array( 'id' => $rr['tid'], - 'term' => $rr['term'], + 'term' => $rr['term'], 'dellink' => z_root() . '/' . $srchurl . (($hasq) ? '' : '?f=') . '&searchremove=1&search=' . urlencode($rr['term']), 'srchlink' => z_root() . '/' . $srchurl . (($hasq) ? '' : '?f=') . '&search=' . urlencode($rr['term']), 'displayterm' => htmlspecialchars($rr['term'], ENT_COMPAT,'UTF-8'), - 'encodedterm' => urlencode($rr['term']), - 'delete' => t('Remove term'), - 'selected' => ($search==$rr['term']), + 'encodedterm' => urlencode($rr['term']), + 'delete' => t('Remove term'), + 'selected' => ($search==$rr['term']), ); } - } + } - $tpl = get_markup_template("saved_searches.tpl"); $o = replace_macros($tpl, array( '$title' => t('Saved Searches'), '$add' => t('add'), - '$searchbox' => searchbox($search,'netsearch-box',$srchurl . (($hasq) ? '' : '?f='),true), + '$searchbox' => searchbox($search, 'netsearch-box', $srchurl . (($hasq) ? '' : '?f='), true), '$saved' => $saved, )); return $o; - } @@ -306,7 +305,6 @@ function widget_filer($arr) { '$all' => t('Everything'), '$terms' => $terms, '$base' => z_root() . '/' . $a->cmd - )); } @@ -327,7 +325,6 @@ function widget_archive($arr) { if(! perm_is_allowed($uid,get_observer_hash(),'view_stream')) return ''; - $wall = ((array_key_exists('wall', $arr)) ? intval($arr['wall']) : 0); $style = ((array_key_exists('style', $arr)) ? $arr['style'] : 'select'); $showend = ((get_pconfig($uid,'system','archive_show_end_date')) ? true : false); @@ -336,10 +333,8 @@ function widget_archive($arr) { if(! $visible_years) $visible_years = 5; - $url = z_root() . '/' . $a->cmd; - $ret = list_post_dates($uid,$wall,$mindate); if(! count($ret)) @@ -367,7 +362,7 @@ function widget_fullprofile($arr) { if(! $a->profile['profile_uid']) return; - $block = (((get_config('system','block_public')) && (! local_user()) && (! remote_user())) ? true : false); + $block = (((get_config('system', 'block_public')) && (! local_user()) && (! remote_user())) ? true : false); return profile_sidebar($a->profile, $block); } @@ -375,41 +370,43 @@ function widget_fullprofile($arr) { function widget_categories($arr) { $a = get_app(); - if($a->profile['profile_uid'] && (! perm_is_allowed($a->profile['profile_uid'],get_observer_hash(),'view_stream'))) return ''; - $cat = ((x($_REQUEST,'cat')) ? htmlspecialchars($_REQUEST['cat'],ENT_COMPAT,'UTF-8') : ''); $srchurl = $a->query_string; $srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is','',$srchurl),'&'); $srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl); - return categories_widget($srchurl,$cat); + return categories_widget($srchurl, $cat); } function widget_tagcloud_wall($arr) { $a = get_app(); + if((! $a->profile['profile_uid']) || (! $a->profile['channel_hash'])) return ''; - if(! perm_is_allowed($a->profile['profile_uid'],get_observer_hash(),'view_stream')) + if(! perm_is_allowed($a->profile['profile_uid'], get_observer_hash(), 'view_stream')) return ''; - $limit = ((array_key_exists('limit',$arr)) ? intval($arr['limit']) : 50); - if(feature_enabled($a->profile['profile_uid'],'tagadelic')) - return tagblock('search',$a->profile['profile_uid'],$limit,$a->profile['channel_hash'],ITEM_WALL); + $limit = ((array_key_exists('limit', $arr)) ? intval($arr['limit']) : 50); + if(feature_enabled($a->profile['profile_uid'], 'tagadelic')) + return wtagblock($a->profile['profile_uid'], $limit, $a->profile['channel_hash'], ITEM_WALL); + return ''; } + function widget_catcloud_wall($arr) { $a = get_app(); + if((! $a->profile['profile_uid']) || (! $a->profile['channel_hash'])) return ''; - if(! perm_is_allowed($a->profile['profile_uid'],get_observer_hash(),'view_stream')) + if(! perm_is_allowed($a->profile['profile_uid'], get_observer_hash(), 'view_stream')) return ''; $limit = ((array_key_exists('limit',$arr)) ? intval($arr['limit']) : 50); - return catblock($a->profile['profile_uid'],$limit,$a->profile['channel_hash'],ITEM_WALL); - return ''; + + return catblock($a->profile['profile_uid'], $limit, $a->profile['channel_hash'], ITEM_WALL); } @@ -438,6 +435,7 @@ function widget_affinity($arr) { call_hooks('main_slider',$arr); return $arr['html']; } + return ''; } @@ -463,20 +461,19 @@ function widget_settings_menu($arr) { if($abk) $abook_self_id = $abk[0]['abook_id']; - $tabs = array( array( 'label' => t('Account settings'), 'url' => $a->get_baseurl(true).'/settings/account', 'selected' => ((argv(1) === 'account') ? 'active' : ''), ), - + array( 'label' => t('Channel settings'), 'url' => $a->get_baseurl(true).'/settings/channel', 'selected' => ((argv(1) === 'channel') ? 'active' : ''), ), - + array( 'label' => t('Additional features'), 'url' => $a->get_baseurl(true).'/settings/features', @@ -494,7 +491,7 @@ function widget_settings_menu($arr) { 'url' => $a->get_baseurl(true).'/settings/display', 'selected' => ((argv(1) === 'display') ? 'active' : ''), ), - + array( 'label' => t('Connected apps'), 'url' => $a->get_baseurl(true) . '/settings/oauth', @@ -503,13 +500,7 @@ function widget_settings_menu($arr) { array( 'label' => t('Export channel'), - 'url' => $a->get_baseurl(true) . '/uexport/basic', - 'selected' => '' - ), - - array( - 'label' => t('Export content'), - 'url' => $a->get_baseurl(true) . '/uexport/complete', + 'url' => $a->get_baseurl(true) . '/uexport', 'selected' => '' ), @@ -529,7 +520,6 @@ function widget_settings_menu($arr) { 'url' => $a->get_baseurl(true) . '/connect/' . $channel['channel_address'], 'selected' => '' ); - } if(feature_enabled(local_user(),'channel_sources')) { @@ -538,18 +528,14 @@ function widget_settings_menu($arr) { 'url' => $a->get_baseurl(true) . '/sources', 'selected' => '' ); - } - - $tabtpl = get_markup_template("generic_links_widget.tpl"); return replace_macros($tabtpl, array( '$title' => t('Settings'), '$class' => 'settings-widget', '$items' => $tabs, )); - } @@ -560,9 +546,7 @@ function widget_mailmenu($arr) { $a = get_app(); return replace_macros(get_markup_template('message_side.tpl'), array( '$title' => t('Messages'), - '$tabs'=> array(), - '$check'=>array( 'label' => t('Check Mail'), 'url' => $a->get_baseurl(true) . '/message', @@ -573,9 +557,7 @@ function widget_mailmenu($arr) { 'url' => $a->get_baseurl(true) . '/mail/new', 'sel'=> (argv(1) == 'new'), ) - )); - } function widget_design_tools($arr) { @@ -586,7 +568,7 @@ function widget_design_tools($arr) { if($a->profile['profile_uid']) if(($a->profile['profile_uid'] != local_user()) && (! $a->is_sys)) - return ''; + return ''; if(! local_user()) return ''; @@ -601,23 +583,25 @@ function widget_findpeople($arr) { function widget_photo_albums($arr) { $a = get_app(); + if(! $a->profile['profile_uid']) return ''; $channelx = channelx_by_n($a->profile['profile_uid']); - if((! $channelx) || (! perm_is_allowed($a->profile['profile_uid'],get_observer_hash(),'view_photos'))) + if((! $channelx) || (! perm_is_allowed($a->profile['profile_uid'], get_observer_hash(), 'view_photos'))) return ''; - return photos_album_widget($channelx,$a->get_observer()); + require_once('include/photos.php'); + return photos_album_widget($channelx, $a->get_observer()); } function widget_vcard($arr) { require_once ('include/Contact.php'); - return vcard_from_xchan('',get_app()->get_observer()); + return vcard_from_xchan('', get_app()->get_observer()); } -/** +/* * The following directory widgets are only useful on the directory page */ @@ -630,21 +614,23 @@ function widget_dirsort($arr) { } function widget_dirtags($arr) { - return dir_tagblock(z_root() . '/directory',null); + return dir_tagblock(z_root() . '/directory', null); } function widget_menu_preview($arr) { if(! get_app()->data['menu_item']) return; require_once('include/menu.php'); + return menu_render(get_app()->data['menu_item']); } function widget_chatroom_list($arr) { $a = get_app(); + require_once("include/chat.php"); $r = chatroom_list($a->profile['profile_uid']); - return replace_macros(get_markup_template('chatroomlist.tpl'),array( + return replace_macros(get_markup_template('chatroomlist.tpl'), array( '$header' => t('Chat Rooms'), '$baseurl' => z_root(), '$nickname' => $a->profile['channel_address'], @@ -657,7 +643,7 @@ function widget_bookmarkedchats($arr) { if(! $h) return; $r = q("select * from xchat where xchat_xchan = '%s' group by xchat_url order by xchat_desc", - dbesc($h) + dbesc($h) ); if($r) { for($x = 0; $x < count($r); $x ++) { @@ -691,17 +677,17 @@ function widget_suggestedchats($arr) { } function widget_item($arr) { + // FIXME there is no $a here $uid = $a->profile['profile_uid']; if((! $uid) || (! $arr['mid'])) return ''; - if(! perm_is_allowed($uid,get_observer_hash(),'view_pages')) + if(! perm_is_allowed($uid, get_observer_hash(), 'view_pages')) return ''; require_once('include/security.php'); $sql_extra = item_permissions_sql($uid); - $r = q("select * from item where mid = '%s' and uid = %d and item_restrict = " . intval(ITEM_WEBPAGE) . " $sql_extra limit 1", dbesc($arr['mid']), intval($uid) @@ -711,11 +697,10 @@ function widget_item($arr) { return ''; xchan_query($r); - $r = fetch_post_tags($r,true); + $r = fetch_post_tags($r, true); - $o .= prepare_page($r[0]); + $o = prepare_page($r[0]); return $o; - } function widget_clock($arr) { @@ -785,18 +770,17 @@ return $o; * URL must be an http or https URL */ - function widget_photo($arr) { $style = $zrl = false; - $params = ''; - if(array_key_exists('src',$arr) && isset($arr['src'])) + + if(array_key_exists('src', $arr) && isset($arr['src'])) $url = $arr['src']; if(strpos($url,'http') !== 0) return ''; - if(array_key_exists('style',$arr) && isset($arr['style'])) + if(array_key_exists('style', $arr) && isset($arr['style'])) $style = $arr['style']; // ensure they can't sneak in an eval(js) function @@ -804,7 +788,7 @@ function widget_photo($arr) { if(strpos($style,'(') !== false) return ''; - if(array_key_exists('zrl',$arr) && isset($arr['zrl'])) + if(array_key_exists('zrl', $arr) && isset($arr['zrl'])) $zrl = (($arr['zrl']) ? true : false); if($zrl) @@ -814,7 +798,7 @@ function widget_photo($arr) { $o .= '<img ' . (($zrl) ? ' class="zrl" ' : '') . (($style) ? ' style="' . $style . '"' : '') - . ' src="' . $url . '" alt="' . t('photo/image') . '" />'; + . ' src="' . $url . '" alt="' . t('photo/image') . '">'; $o .= '</div>'; @@ -825,15 +809,15 @@ function widget_photo($arr) { function widget_photo_rand($arr) { require_once('include/photos.php'); - $style = $zrl = false; - $params = ''; - if(array_key_exists('album',$arr) && isset($arr['album'])) + $style = false; + + if(array_key_exists('album', $arr) && isset($arr['album'])) $album = $arr['album']; else $album = ''; $channel_id = 0; - if(array_key_exists('channel_id',$arr) && intval($arr['channel_id'])) + if(array_key_exists('channel_id', $arr) && intval($arr['channel_id'])) $channel_id = intval($arr['channel_id']); if(! $channel_id) $channel_id = get_app()->profile_uid; @@ -843,7 +827,7 @@ function widget_photo_rand($arr) { $scale = ((array_key_exists('scale',$arr)) ? intval($arr['scale']) : 0); $ret = photos_list_photos(array('channel_id' => $channel_id),get_app()->get_observer(),$album); - + $filtered = array(); if($ret['success'] && $ret['photos']) foreach($ret['photos'] as $p) @@ -851,14 +835,14 @@ function widget_photo_rand($arr) { $filtered[] = $p['src']; if($filtered) { - $e = mt_rand(0,count($filtered)-1); + $e = mt_rand(0, count($filtered) - 1); $url = $filtered[$e]; } - if(strpos($url,'http') !== 0) + if(strpos($url, 'http') !== 0) return ''; - if(array_key_exists('style',$arr) && isset($arr['style'])) + if(array_key_exists('style', $arr) && isset($arr['style'])) $style = $arr['style']; // ensure they can't sneak in an eval(js) function @@ -872,7 +856,7 @@ function widget_photo_rand($arr) { $o .= '<img class="zrl" ' . (($style) ? ' style="' . $style . '"' : '') - . ' src="' . $url . '" alt="' . t('photo/image') . '" />'; + . ' src="' . $url . '" alt="' . t('photo/image') . '">'; $o .= '</div>'; @@ -912,10 +896,10 @@ function widget_random_block($arr) { $o = '<div class="widget bblock">'; if($r[0]['title']) $o .= '<h3>' . $r[0]['title'] . '</h3>'; + $o .= prepare_text($r[0]['body'],$r[0]['mimetype']); $o .= '</div>'; - } - return $o; -}
\ No newline at end of file + return $o; +} diff --git a/include/zot.php b/include/zot.php index 3b8584509..c88b2a369 100644 --- a/include/zot.php +++ b/include/zot.php @@ -1417,8 +1417,9 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque return; } } - + foreach($deliveries as $d) { + $local_public = $public; $r = q("select * from channel where channel_hash = '%s' limit 1", dbesc($d['hash']) ); @@ -1432,8 +1433,18 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque $channel = $r[0]; // allow public postings to the sys channel regardless of permissions - if(($channel['channel_pageflags'] & PAGE_SYSTEM) && (! $arr['item_private'])) - $public = true; + if(($channel['channel_pageflags'] & PAGE_SYSTEM) && (! $arr['item_private'])) { + $local_public = true; + + $r = q("select xchan_flags from xchan where xchan_hash = '%s' limit 1", + dbesc($sender['hash']) + ); + // don't import sys channel posts from selfcensored authors + if($r && ($r[0]['xchan_flags'] & XCHAN_FLAGS_SELFCENSORED)) { + $local_public = false; + continue; + } + } $tag_delivery = tgroup_check($channel['channel_id'],$arr); @@ -1452,7 +1463,7 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque } } - if((! perm_is_allowed($channel['channel_id'],$sender['hash'],$perm)) && (! $tag_delivery) && (! $public)) { + if((! perm_is_allowed($channel['channel_id'],$sender['hash'],$perm)) && (! $tag_delivery) && (! $local_public)) { logger("permission denied for delivery to channel {$channel['channel_id']} {$channel['channel_address']}"); $result[] = array($d['hash'],'permission denied',$channel['channel_name'] . ' <' . $channel['channel_address'] . '@' . get_app()->get_hostname() . '>',$arr['mid']); continue; @@ -1487,7 +1498,7 @@ function process_delivery($sender,$arr,$deliveries,$relay,$public = false,$reque // the top level post is unlikely to be imported and // this is just an exercise in futility. - if((! $relay) && (! $request) && (! $public) + if((! $relay) && (! $request) && (! $local_public) && perm_is_allowed($channel['channel_id'],$sender['hash'],'send_stream')) { proc_run('php', 'include/notifier.php', 'request', $channel['channel_id'], $sender['hash'], $arr['parent_mid']); } |