From 4ef33ac6ebbf7418742a9ee7a4a549808754eb1f Mon Sep 17 00:00:00 2001 From: Zach Prezkuta Date: Sat, 23 Jun 2012 19:57:59 -0600 Subject: [PATCH 01/12] fix BB-to-Diaspora list formatting --- include/bb2diaspora.php | 46 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index 96cc735bd..d509a2e31 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -68,9 +68,14 @@ function stripdcode_br_cb($s) { function diaspora_ul($s) { - // Replace "[\\*]" followed by any number (including zero) of + // Replace "[*]" followed by any number (including zero) of // spaces by "* " to match Diaspora's list format - return preg_replace("/\[\\\\\*\]( *)/", "* ", $s[1]); + if( strpos($s[0], "[list]") === 0 ) + return ''; + elseif( strpos($s[0], "[ul]") === 0 ) + return ''; + else + return $s[0]; } @@ -80,12 +85,47 @@ function diaspora_ol($s) { // 1. First element // 1. Second element // 1. Third element - return preg_replace("/\[\\\\\*\]( *)/", "1. ", $s[1]); + if( strpos($s[0], "[list=1]") === 0 ) + return ''; + elseif( strpos($s[0], "[list=i]") === 0 ) + return ''; + elseif( strpos($s[0], "[list=I]") === 0 ) + return ''; + elseif( strpos($s[0], "[list=a]") === 0 ) + return ''; + elseif( strpos($s[0], "[list=A]") === 0 ) + return ''; + elseif( strpos($s[0], "[ol]") === 0 ) + return ''; + else + return $s[0]; } function bb2diaspora($Text,$preserve_nl = false) { + // bbcode() will convert "[*]" into "
  • " with no closing "
  • " + // Markdownify() is unable to handle these, as it makes each new + // "
  • " into a deeper nested element until it crashes. So pre-format + // the lists as Diaspora lists before sending the $Text to bbcode() + // + // Note that regular expressions are really not suitable for parsing + // text with opening and closing tags, so nested lists may make things + // wonky + $endlessloop = 0; + while ((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false) && + (strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false) && + (strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false) && (++$endlessloop < 20)) { + $Text = preg_replace_callback("/\[list\](.*?)\[\/list\]/is", 'diaspora_ul', $Text); + $Text = preg_replace_callback("/\[ul\](.*?)\[\/ul\]/is", 'diaspora_ul', $Text); + $Text = preg_replace_callback("/\[list=1\](.*?)\[\/list\]/is", 'diaspora_ol', $Text); + $Text = preg_replace_callback("/\[list=i\](.*?)\[\/list\]/s",'diaspora_ol', $Text); + $Text = preg_replace_callback("/\[list=I\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); + $Text = preg_replace_callback("/\[list=a\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); + $Text = preg_replace_callback("/\[list=A\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); + $Text = preg_replace_callback("/\[ol\](.*?)\[\/ol\]/is", 'diaspora_ol', $Text); + } + // Convert it to HTML - don't try oembed $Text = bbcode($Text, $preserve_nl, false); From 1f968396749f8cac31aaeee770ae7fc5aff48f38 Mon Sep 17 00:00:00 2001 From: Zach Prezkuta Date: Sat, 23 Jun 2012 20:01:29 -0600 Subject: [PATCH 02/12] small optimization --- include/bb2diaspora.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index d509a2e31..75ba57dff 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -113,18 +113,16 @@ function bb2diaspora($Text,$preserve_nl = false) { // text with opening and closing tags, so nested lists may make things // wonky $endlessloop = 0; - while ((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false) && - (strpos($Text, "[/ul]") !== false) && (strpos($Text, "[ul]") !== false) && - (strpos($Text, "[/ol]") !== false) && (strpos($Text, "[ol]") !== false) && (++$endlessloop < 20)) { + while ((strpos($Text, "[/list]") !== false) && (strpos($Text, "[list") !== false) && (++$endlessloop < 20)) { $Text = preg_replace_callback("/\[list\](.*?)\[\/list\]/is", 'diaspora_ul', $Text); - $Text = preg_replace_callback("/\[ul\](.*?)\[\/ul\]/is", 'diaspora_ul', $Text); $Text = preg_replace_callback("/\[list=1\](.*?)\[\/list\]/is", 'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=i\](.*?)\[\/list\]/s",'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=I\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=a\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); $Text = preg_replace_callback("/\[list=A\](.*?)\[\/list\]/s", 'diaspora_ol', $Text); - $Text = preg_replace_callback("/\[ol\](.*?)\[\/ol\]/is", 'diaspora_ol', $Text); } + $Text = preg_replace_callback("/\[ul\](.*?)\[\/ul\]/is", 'diaspora_ul', $Text); + $Text = preg_replace_callback("/\[ol\](.*?)\[\/ol\]/is", 'diaspora_ol', $Text); // Convert it to HTML - don't try oembed $Text = bbcode($Text, $preserve_nl, false); From 5d2eed35177da3debacc6db6db2f7a74bc4b64c7 Mon Sep 17 00:00:00 2001 From: Zach Prezkuta Date: Sat, 23 Jun 2012 22:02:08 -0600 Subject: [PATCH 03/12] allow bare URLS to make it through to Diaspora --- include/bb2diaspora.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/bb2diaspora.php b/include/bb2diaspora.php index 75ba57dff..ac693127b 100644 --- a/include/bb2diaspora.php +++ b/include/bb2diaspora.php @@ -131,6 +131,12 @@ function bb2diaspora($Text,$preserve_nl = false) { $md = new Markdownify(false, false, false); $Text = $md->parseString($Text); + // If the text going into bbcode() has a plain URL in it, i.e. + // with no [url] tags around it, it will come out of parseString() + // looking like: , which gets removed by strip_tags(). + // So take off the angle brackets of any such URL + $Text = preg_replace("//is", "http$1", $Text); + // Remove all unconverted tags $Text = strip_tags($Text); From 0877c5b687e208955dfe31830815f408d50ccbb4 Mon Sep 17 00:00:00 2001 From: Zach Prezkuta Date: Sat, 23 Jun 2012 22:04:20 -0600 Subject: [PATCH 04/12] use author handle instead of sender handle --- include/diaspora.php | 108 +++++++++++++++++++++++++++++++++---------- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index fdb85f15f..ab43b4608 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -5,6 +5,7 @@ require_once('include/items.php'); require_once('include/bb2diaspora.php'); require_once('include/contact_selectors.php'); require_once('include/queue_fn.php'); +require_once('include/lock.php'); function diaspora_dispatch_public($msg) { @@ -113,27 +114,83 @@ function diaspora_get_contact_by_handle($uid,$handle) { } function find_diaspora_person_by_handle($handle) { + + $person = false; $update = false; - $r = q("select * from fcontact where network = '%s' and addr = '%s' limit 1", - dbesc(NETWORK_DIASPORA), - dbesc($handle) - ); - if(count($r)) { - logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DEBUG); - // update record occasionally so it doesn't get stale - $d = strtotime($r[0]['updated'] . ' +00:00'); - if($d > strtotime('now - 14 days')) - return $r[0]; - $update = true; - } - logger('find_diaspora_person_by_handle: refresh',LOGGER_DEBUG); - require_once('include/Scrape.php'); - $r = probe_url($handle, PROBE_DIASPORA); - if((count($r)) && ($r['network'] === NETWORK_DIASPORA)) { - add_fcontact($r,$update); - return ($r); - } - return false; + $got_lock = false; + + do { + $r = q("select * from fcontact where network = '%s' and addr = '%s' limit 1", + dbesc(NETWORK_DIASPORA), + dbesc($handle) + ); + if(count($r)) { + $person = $r[0]; + logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DEBUG); + + // update record occasionally so it doesn't get stale + $d = strtotime($person['updated'] . ' +00:00'); + if($d < strtotime('now - 14 days')) + $update = true; + } + + + // FETCHING PERSON INFORMATION FROM REMOTE SERVER + // + // If the person isn't in our 'fcontact' table, or if he/she is but + // his/her information hasn't been updated for more than 14 days, then + // we want to fetch the person's information from the remote server. + // + // Note that $person isn't changed by this block of code unless the + // person's information has been successfully fetched from the remote + // server. So if $person was 'false' to begin with (because he/she wasn't + // in the local cache), it'll stay false, and if $person held the local + // cache information to begin with, it'll keep that information. That way + // if there's a problem with the remote fetch, we can at least use our + // cached information--it's better than nothing. + + if((! $person) || ($update)) { + // Lock the function to prevent race conditions if multiple items + // come in at the same time from a person who doesn't exist in + // fcontact + $got_lock = lock_function('find_diaspora_person_by_handle', false); + + if($got_lock) { + logger('find_diaspora_person_by_handle: create or refresh', LOGGER_DEBUG); + require_once('include/Scrape.php'); + $r = probe_url($handle, PROBE_DIASPORA); + + // Note that Friendica contacts can return a "Diaspora person" + // if Diaspora connectivity is enabled on their server + if((count($r)) && ($r['network'] === NETWORK_DIASPORA)) { + add_fcontact($r,$update); + $person = ($r); + } + + unlock_function('find_diaspora_person_by_handle'); + } + else { + logger('find_diaspora_person_by_handle: couldn\'t lock function', LOGGER_DEBUG); + if(! $person) + block_on_function_lock('find_diaspora_person_by_handle'); + } + } + } while((! $person) && (! $got_lock)); + // We need to try again if the person wasn't in 'fcontact' but the function was locked. + // The fact that the function was locked may mean that another process was creating the + // person's record. It could also mean another process was creating or updating an unrelated + // person. + // + // At any rate, we need to keep trying until we've either got the person or had a chance to + // try to fetch his/her remote information. But we don't want to block on locking the + // function, because if the other process is creating the record, then when we acquire the lock + // we'll dive right into creating another, duplicate record. We DO want to at least wait + // until the lock is released, so we don't flood the database with requests. + // + // If the person was in the 'fcontact' table, don't try again. It's not worth the time, since + // we do have some information for the person + + return $person; } @@ -2252,7 +2309,6 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $relay_retract = true; $target_type = ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment'); - $sender_signed_text = $item['guid'] . ';' . $target_type ; $sql_sign_id = 'retract_iid'; $tpl = get_markup_template('diaspora_relayable_retraction.tpl'); @@ -2263,13 +2319,10 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { $target_type = 'Post'; // $positive = (($item['deleted']) ? 'false' : 'true'); $positive = 'true'; - $sender_signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $myaddr; $tpl = get_markup_template('diaspora_like_relay.tpl'); } else { // item is a comment - $sender_signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $myaddr; - $tpl = get_markup_template('diaspora_comment_relay.tpl'); } @@ -2295,6 +2348,13 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) { return; } + if($relay_retract) + $sender_signed_text = $item['guid'] . ';' . $target_type; + elseif($like) + $sender_signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $handle; + else + $sender_signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $handle; + // Sign the relayable with the top-level owner's signature // // We'll use the $sender_signed_text that we just created, instead of the $signed_text From 1574396d04ead2e410aa992b049fe63422080bab Mon Sep 17 00:00:00 2001 From: friendica Date: Sat, 23 Jun 2012 21:11:18 -0700 Subject: [PATCH 05/12] sort out some "like" issues --- boot.php | 2 +- include/conversation.php | 8 +-- include/items.php | 14 +++-- util/messages.po | 127 ++++++++++++++++++--------------------- 4 files changed, 73 insertions(+), 78 deletions(-) diff --git a/boot.php b/boot.php index be47184aa..971762634 100644 --- a/boot.php +++ b/boot.php @@ -10,7 +10,7 @@ require_once('include/nav.php'); require_once('include/cache.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); -define ( 'FRIENDICA_VERSION', '3.0.1382' ); +define ( 'FRIENDICA_VERSION', '3.0.1383' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DB_UPDATE_VERSION', 1149 ); diff --git a/include/conversation.php b/include/conversation.php index d830c8daa..c2113dead 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -427,8 +427,8 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { // We've already parsed out like/dislike for special treatment. We can ignore them now if(((activity_match($item['verb'],ACTIVITY_LIKE)) - || (activity_match($item['verb'],ACTIVITY_DISLIKE))) - && ($item['id'] != $item['parent'])) + || (activity_match($item['verb'],ACTIVITY_DISLIKE)))) +// && ($item['id'] != $item['parent'])) continue; $toplevelpost = (($item['id'] == $item['parent']) ? true : false); @@ -549,13 +549,13 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $shareable = ((($profile_owner == local_user()) && ((! $item['private']) || $item['network'] === NETWORK_FEED)) ? true : false); if($page_writeable) { - if($toplevelpost) { +/* if($toplevelpost) { */ $likebuttons = array( 'like' => array( t("I like this \x28toggle\x29"), t("like")), 'dislike' => array( t("I don't like this \x28toggle\x29"), t("dislike")), ); if ($shareable) $likebuttons['share'] = array( t('Share this'), t('share')); - } +/* } */ $qc = $qcomment = null; diff --git a/include/items.php b/include/items.php index 91ed6762c..e495393fa 100755 --- a/include/items.php +++ b/include/items.php @@ -1726,10 +1726,12 @@ function consume_feed($xml,$importer,&$contact, &$hub, $datedir = 0, $pass = 0) $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; // only one like or dislike per person - $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", + $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 and (`parent-uri` = '%s' OR `thr_parent` = '%s') limit 1", intval($datarray['uid']), intval($datarray['contact-id']), - dbesc($datarray['verb']) + dbesc($datarray['verb']), + dbesc($parent_uri), + dbesc($parent_uri) ); if($r && count($r)) continue; @@ -2363,7 +2365,7 @@ function local_delivery($importer,$data) { $datarray['gravity'] = GRAVITY_LIKE; $datarray['last-child'] = 0; // only one like or dislike per person - $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and (`thr-parent` = '%s' or `parent-uri` = '%s') and deleted = 0 limit 1", + $r = q("select id from item where uid = %d and `contact-id` = %d and verb = '%s' and (`thr-parent` = '%s' or `parent-uri` = '%s') and deleted = 0 limit 1", intval($datarray['uid']), intval($datarray['contact-id']), dbesc($datarray['verb']), @@ -2537,10 +2539,12 @@ function local_delivery($importer,$data) { $datarray['type'] = 'activity'; $datarray['gravity'] = GRAVITY_LIKE; // only one like or dislike per person - $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 limit 1", + $r = q("select id from item where uid = %d and `contact-id` = %d and verb ='%s' and deleted = 0 and (`parent-uri` = '%s' OR `thr-parent` = '%s') limit 1", intval($datarray['uid']), intval($datarray['contact-id']), - dbesc($datarray['verb']) + dbesc($datarray['verb']), + dbesc($parent_uri), + dbesc($parent_uri) ); if($r && count($r)) continue; diff --git a/util/messages.po b/util/messages.po index 416e30ef8..0bde2488c 100644 --- a/util/messages.po +++ b/util/messages.po @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: 3.0.1382\n" +"Project-Id-Version: 3.0.1383\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-06-22 10:00-0700\n" +"POT-Creation-Date: 2012-06-23 10:00-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -55,7 +55,7 @@ msgstr "" #: ../../mod/profiles.php:385 ../../mod/delegate.php:6 #: ../../mod/suggest.php:28 ../../mod/invite.php:13 ../../mod/invite.php:81 #: ../../mod/dfrn_confirm.php:53 ../../addon/facebook/facebook.php:507 -#: ../../addon/dav/layout.fnk.php:353 ../../include/items.php:3401 +#: ../../addon/dav/layout.fnk.php:353 ../../include/items.php:3407 #: ../../index.php:309 msgid "Permission denied." msgstr "" @@ -278,7 +278,7 @@ msgid "Description:" msgstr "" #: ../../mod/events.php:423 ../../include/event.php:37 -#: ../../include/bb2diaspora.php:265 ../../boot.php:1126 +#: ../../include/bb2diaspora.php:311 ../../boot.php:1126 msgid "Location:" msgstr "" @@ -546,14 +546,14 @@ msgstr "" msgid "I don't like this (toggle)" msgstr "" -#: ../../mod/photos.php:1290 ../../include/conversation.php:989 +#: ../../mod/photos.php:1290 ../../include/conversation.php:993 msgid "Share" msgstr "" #: ../../mod/photos.php:1291 ../../mod/editpost.php:104 #: ../../mod/wallmessage.php:145 ../../mod/message.php:215 #: ../../mod/message.php:411 ../../include/conversation.php:371 -#: ../../include/conversation.php:731 ../../include/conversation.php:1008 +#: ../../include/conversation.php:731 ../../include/conversation.php:1012 msgid "Please wait" msgstr "" @@ -569,7 +569,7 @@ msgid "Comment" msgstr "" #: ../../mod/photos.php:1311 ../../mod/editpost.php:125 -#: ../../include/conversation.php:589 ../../include/conversation.php:1026 +#: ../../include/conversation.php:589 ../../include/conversation.php:1030 msgid "Preview" msgstr "" @@ -640,7 +640,7 @@ msgstr "" msgid "Edit post" msgstr "" -#: ../../mod/editpost.php:80 ../../include/conversation.php:975 +#: ../../mod/editpost.php:80 ../../include/conversation.php:979 msgid "Post to Email" msgstr "" @@ -651,17 +651,17 @@ msgstr "" #: ../../mod/editpost.php:96 ../../mod/wallmessage.php:143 #: ../../mod/message.php:213 ../../mod/message.php:408 -#: ../../include/conversation.php:990 +#: ../../include/conversation.php:994 msgid "Upload photo" msgstr "" -#: ../../mod/editpost.php:97 ../../include/conversation.php:992 +#: ../../mod/editpost.php:97 ../../include/conversation.php:996 msgid "Attach file" msgstr "" #: ../../mod/editpost.php:98 ../../mod/wallmessage.php:144 #: ../../mod/message.php:214 ../../mod/message.php:409 -#: ../../include/conversation.php:994 +#: ../../include/conversation.php:998 msgid "Insert web link" msgstr "" @@ -677,35 +677,35 @@ msgstr "" msgid "Insert Vorbis [.ogg] audio" msgstr "" -#: ../../mod/editpost.php:102 ../../include/conversation.php:1000 +#: ../../mod/editpost.php:102 ../../include/conversation.php:1004 msgid "Set your location" msgstr "" -#: ../../mod/editpost.php:103 ../../include/conversation.php:1002 +#: ../../mod/editpost.php:103 ../../include/conversation.php:1006 msgid "Clear browser location" msgstr "" -#: ../../mod/editpost.php:105 ../../include/conversation.php:1009 +#: ../../mod/editpost.php:105 ../../include/conversation.php:1013 msgid "Permission settings" msgstr "" -#: ../../mod/editpost.php:113 ../../include/conversation.php:1018 +#: ../../mod/editpost.php:113 ../../include/conversation.php:1022 msgid "CC: email addresses" msgstr "" -#: ../../mod/editpost.php:114 ../../include/conversation.php:1019 +#: ../../mod/editpost.php:114 ../../include/conversation.php:1023 msgid "Public post" msgstr "" -#: ../../mod/editpost.php:117 ../../include/conversation.php:1005 +#: ../../mod/editpost.php:117 ../../include/conversation.php:1009 msgid "Set title" msgstr "" -#: ../../mod/editpost.php:119 ../../include/conversation.php:1007 +#: ../../mod/editpost.php:119 ../../include/conversation.php:1011 msgid "Categories (comma-separated list)" msgstr "" -#: ../../mod/editpost.php:120 ../../include/conversation.php:1021 +#: ../../mod/editpost.php:120 ../../include/conversation.php:1025 msgid "Example: bob@example.com, mary@example.com" msgstr "" @@ -826,7 +826,7 @@ msgstr "" msgid "Confirm" msgstr "" -#: ../../mod/dfrn_request.php:715 ../../include/items.php:2797 +#: ../../mod/dfrn_request.php:715 ../../include/items.php:2801 msgid "[Name Withheld]" msgstr "" @@ -1152,7 +1152,7 @@ msgid "" msgstr "" #: ../../mod/localtime.php:12 ../../include/event.php:11 -#: ../../include/bb2diaspora.php:243 +#: ../../include/bb2diaspora.php:289 msgid "l F d, Y \\@ g:i A" msgstr "" @@ -1728,7 +1728,7 @@ msgstr "" #: ../../addon/facebook/facebook.php:692 #: ../../addon/facebook/facebook.php:1182 #: ../../addon/public_server/public_server.php:62 -#: ../../addon/testdrive/testdrive.php:67 ../../include/items.php:2806 +#: ../../addon/testdrive/testdrive.php:67 ../../include/items.php:2810 #: ../../boot.php:720 msgid "Administrator" msgstr "" @@ -2455,7 +2455,7 @@ msgid "No recipient." msgstr "" #: ../../mod/wallmessage.php:124 ../../mod/message.php:172 -#: ../../include/conversation.php:943 +#: ../../include/conversation.php:947 msgid "Please enter a link URL:" msgstr "" @@ -2777,7 +2777,7 @@ msgstr "" msgid "People Search" msgstr "" -#: ../../mod/like.php:185 ../../mod/like.php:259 ../../mod/tagger.php:70 +#: ../../mod/like.php:185 ../../mod/like.php:260 ../../mod/tagger.php:70 #: ../../addon/facebook/facebook.php:1576 #: ../../addon/communityhome/communityhome.php:158 #: ../../addon/communityhome/communityhome.php:167 @@ -2803,7 +2803,7 @@ msgstr "" #: ../../mod/notice.php:15 ../../mod/viewsrc.php:15 ../../mod/admin.php:159 #: ../../mod/admin.php:700 ../../mod/admin.php:899 ../../mod/display.php:37 -#: ../../mod/display.php:142 ../../include/items.php:3248 +#: ../../mod/display.php:142 ../../include/items.php:3254 msgid "Item not found." msgstr "" @@ -4010,7 +4010,7 @@ msgstr "" msgid "Edit visibility" msgstr "" -#: ../../mod/filer.php:29 ../../include/conversation.php:947 +#: ../../mod/filer.php:29 ../../include/conversation.php:951 msgid "Save to Folder:" msgstr "" @@ -6458,11 +6458,11 @@ msgstr "" msgid "Ask me" msgstr "" -#: ../../include/event.php:17 ../../include/bb2diaspora.php:249 +#: ../../include/event.php:17 ../../include/bb2diaspora.php:295 msgid "Starts:" msgstr "" -#: ../../include/event.php:27 ../../include/bb2diaspora.php:257 +#: ../../include/event.php:27 ../../include/bb2diaspora.php:303 msgid "Finishes:" msgstr "" @@ -6634,7 +6634,7 @@ msgstr "" msgid "Sharing notification from Diaspora network" msgstr "" -#: ../../include/diaspora.php:2074 +#: ../../include/diaspora.php:2084 msgid "Attachments:" msgstr "" @@ -6642,11 +6642,11 @@ msgstr "" msgid "view full size" msgstr "" -#: ../../include/oembed.php:134 +#: ../../include/oembed.php:135 msgid "Embedded content" msgstr "" -#: ../../include/oembed.php:143 +#: ../../include/oembed.php:144 msgid "Embedding disabled" msgstr "" @@ -6943,11 +6943,11 @@ msgstr "" msgid "From: " msgstr "" -#: ../../include/bbcode.php:210 ../../include/bbcode.php:230 +#: ../../include/bbcode.php:214 ../../include/bbcode.php:234 msgid "$1 wrote:" msgstr "" -#: ../../include/bbcode.php:245 ../../include/bbcode.php:314 +#: ../../include/bbcode.php:249 ../../include/bbcode.php:322 msgid "Image/photo" msgstr "" @@ -7188,27 +7188,18 @@ msgstr "" msgid "following" msgstr "" -#: ../../include/items.php:2804 +#: ../../include/items.php:2808 msgid "A new person is sharing with you at " msgstr "" -#: ../../include/items.php:2804 +#: ../../include/items.php:2808 msgid "You have a new follower at " msgstr "" -#: ../../include/items.php:3466 +#: ../../include/items.php:3472 msgid "Archives" msgstr "" -#: ../../include/bb2diaspora.php:102 ../../include/bb2diaspora.php:112 -#: ../../include/bb2diaspora.php:113 -msgid "image/photo" -msgstr "" - -#: ../../include/bb2diaspora.php:102 -msgid "link" -msgstr "" - #: ../../include/user.php:38 msgid "An invitation is required." msgstr "" @@ -7449,102 +7440,102 @@ msgstr "" msgid "Delete Selected Items" msgstr "" -#: ../../include/conversation.php:901 +#: ../../include/conversation.php:905 #, php-format msgid "%s likes this." msgstr "" -#: ../../include/conversation.php:901 +#: ../../include/conversation.php:905 #, php-format msgid "%s doesn't like this." msgstr "" -#: ../../include/conversation.php:905 +#: ../../include/conversation.php:909 #, php-format msgid "%2$d people like this." msgstr "" -#: ../../include/conversation.php:907 +#: ../../include/conversation.php:911 #, php-format msgid "%2$d people don't like this." msgstr "" -#: ../../include/conversation.php:913 +#: ../../include/conversation.php:917 msgid "and" msgstr "" -#: ../../include/conversation.php:916 +#: ../../include/conversation.php:920 #, php-format msgid ", and %d other people" msgstr "" -#: ../../include/conversation.php:917 +#: ../../include/conversation.php:921 #, php-format msgid "%s like this." msgstr "" -#: ../../include/conversation.php:917 +#: ../../include/conversation.php:921 #, php-format msgid "%s don't like this." msgstr "" -#: ../../include/conversation.php:942 +#: ../../include/conversation.php:946 msgid "Visible to everybody" msgstr "" -#: ../../include/conversation.php:944 +#: ../../include/conversation.php:948 msgid "Please enter a video link/URL:" msgstr "" -#: ../../include/conversation.php:945 +#: ../../include/conversation.php:949 msgid "Please enter an audio link/URL:" msgstr "" -#: ../../include/conversation.php:946 +#: ../../include/conversation.php:950 msgid "Tag term:" msgstr "" -#: ../../include/conversation.php:948 +#: ../../include/conversation.php:952 msgid "Where are you right now?" msgstr "" -#: ../../include/conversation.php:991 +#: ../../include/conversation.php:995 msgid "upload photo" msgstr "" -#: ../../include/conversation.php:993 +#: ../../include/conversation.php:997 msgid "attach file" msgstr "" -#: ../../include/conversation.php:995 +#: ../../include/conversation.php:999 msgid "web link" msgstr "" -#: ../../include/conversation.php:996 +#: ../../include/conversation.php:1000 msgid "Insert video link" msgstr "" -#: ../../include/conversation.php:997 +#: ../../include/conversation.php:1001 msgid "video link" msgstr "" -#: ../../include/conversation.php:998 +#: ../../include/conversation.php:1002 msgid "Insert audio link" msgstr "" -#: ../../include/conversation.php:999 +#: ../../include/conversation.php:1003 msgid "audio link" msgstr "" -#: ../../include/conversation.php:1001 +#: ../../include/conversation.php:1005 msgid "set location" msgstr "" -#: ../../include/conversation.php:1003 +#: ../../include/conversation.php:1007 msgid "clear location" msgstr "" -#: ../../include/conversation.php:1010 +#: ../../include/conversation.php:1014 msgid "permissions" msgstr "" From 59ebe6f111865d0528ac34a237dc3f6a34782252 Mon Sep 17 00:00:00 2001 From: Zach Prezkuta Date: Sat, 23 Jun 2012 22:28:28 -0600 Subject: [PATCH 06/12] ok now I'm just making silly mistakes--take out premature function locking code --- include/diaspora.php | 97 +++++++++----------------------------------- 1 file changed, 20 insertions(+), 77 deletions(-) diff --git a/include/diaspora.php b/include/diaspora.php index ab43b4608..a398007e1 100755 --- a/include/diaspora.php +++ b/include/diaspora.php @@ -5,7 +5,6 @@ require_once('include/items.php'); require_once('include/bb2diaspora.php'); require_once('include/contact_selectors.php'); require_once('include/queue_fn.php'); -require_once('include/lock.php'); function diaspora_dispatch_public($msg) { @@ -114,83 +113,27 @@ function diaspora_get_contact_by_handle($uid,$handle) { } function find_diaspora_person_by_handle($handle) { - - $person = false; $update = false; - $got_lock = false; - - do { - $r = q("select * from fcontact where network = '%s' and addr = '%s' limit 1", - dbesc(NETWORK_DIASPORA), - dbesc($handle) - ); - if(count($r)) { - $person = $r[0]; - logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DEBUG); - - // update record occasionally so it doesn't get stale - $d = strtotime($person['updated'] . ' +00:00'); - if($d < strtotime('now - 14 days')) - $update = true; - } - - - // FETCHING PERSON INFORMATION FROM REMOTE SERVER - // - // If the person isn't in our 'fcontact' table, or if he/she is but - // his/her information hasn't been updated for more than 14 days, then - // we want to fetch the person's information from the remote server. - // - // Note that $person isn't changed by this block of code unless the - // person's information has been successfully fetched from the remote - // server. So if $person was 'false' to begin with (because he/she wasn't - // in the local cache), it'll stay false, and if $person held the local - // cache information to begin with, it'll keep that information. That way - // if there's a problem with the remote fetch, we can at least use our - // cached information--it's better than nothing. - - if((! $person) || ($update)) { - // Lock the function to prevent race conditions if multiple items - // come in at the same time from a person who doesn't exist in - // fcontact - $got_lock = lock_function('find_diaspora_person_by_handle', false); - - if($got_lock) { - logger('find_diaspora_person_by_handle: create or refresh', LOGGER_DEBUG); - require_once('include/Scrape.php'); - $r = probe_url($handle, PROBE_DIASPORA); - - // Note that Friendica contacts can return a "Diaspora person" - // if Diaspora connectivity is enabled on their server - if((count($r)) && ($r['network'] === NETWORK_DIASPORA)) { - add_fcontact($r,$update); - $person = ($r); - } - - unlock_function('find_diaspora_person_by_handle'); - } - else { - logger('find_diaspora_person_by_handle: couldn\'t lock function', LOGGER_DEBUG); - if(! $person) - block_on_function_lock('find_diaspora_person_by_handle'); - } - } - } while((! $person) && (! $got_lock)); - // We need to try again if the person wasn't in 'fcontact' but the function was locked. - // The fact that the function was locked may mean that another process was creating the - // person's record. It could also mean another process was creating or updating an unrelated - // person. - // - // At any rate, we need to keep trying until we've either got the person or had a chance to - // try to fetch his/her remote information. But we don't want to block on locking the - // function, because if the other process is creating the record, then when we acquire the lock - // we'll dive right into creating another, duplicate record. We DO want to at least wait - // until the lock is released, so we don't flood the database with requests. - // - // If the person was in the 'fcontact' table, don't try again. It's not worth the time, since - // we do have some information for the person - - return $person; + $r = q("select * from fcontact where network = '%s' and addr = '%s' limit 1", + dbesc(NETWORK_DIASPORA), + dbesc($handle) + ); + if(count($r)) { + logger('find_diaspora_person_by handle: in cache ' . print_r($r,true), LOGGER_DEBUG); + // update record occasionally so it doesn't get stale + $d = strtotime($r[0]['updated'] . ' +00:00'); + if($d > strtotime('now - 14 days')) + return $r[0]; + $update = true; + } + logger('find_diaspora_person_by_handle: refresh',LOGGER_DEBUG); + require_once('include/Scrape.php'); + $r = probe_url($handle, PROBE_DIASPORA); + if((count($r)) && ($r['network'] === NETWORK_DIASPORA)) { + add_fcontact($r,$update); + return ($r); + } + return false; } From 7f3813e9b066ab7290963e378dafd010de5416fe Mon Sep 17 00:00:00 2001 From: friendica Date: Sun, 24 Jun 2012 00:56:27 -0700 Subject: [PATCH 07/12] service class basics --- boot.php | 6 +++--- include/plugin.php | 38 ++++++++++++++++++++++++++++++++++++++ include/user.php | 14 ++++++++++---- mod/dfrn_confirm.php | 2 +- 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/boot.php b/boot.php index 971762634..ac561edf6 100644 --- a/boot.php +++ b/boot.php @@ -1374,9 +1374,9 @@ if(! function_exists('proc_run')) { if(count($args) && $args[0] === 'php') $args[0] = ((x($a->config,'php_path')) && (strlen($a->config['php_path'])) ? $a->config['php_path'] : 'php'); - foreach ($args as $arg){ - $arg = escapeshellarg($arg); - } + for($x = 0; $x < count($args); $x ++) + $args[$x] = escapeshellarg($args[$x]); + $cmdline = implode($args," "); proc_close(proc_open($cmdline." &",array(),$foo)); } diff --git a/include/plugin.php b/include/plugin.php index c6b61ae6e..3b6faa072 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -316,3 +316,41 @@ function get_theme_screenshot($theme) { } return($a->get_baseurl() . '/images/blank.png'); } + + +// check service_class restrictions. If there are no service_classes defined, everything is allowed. +// if $usage is supplied, we check against a maximum count and return true if the current usage is +// less than the subscriber plan allows. Otherwise we return boolean true or false if the property +// is allowed (or not) in this subscriber plan. An unset property for this service plan means +// the property is allowed, so it is only necessary to provide negative properties for each plan, +// or what the subscriber is not allowed to do. + + +function service_class_allows($uid,$property,$usage = false) { + + if($uid == local_user()) { + $service_class = $a->user['service_class']; + } + else { + $r = q("select service_class from user where uid = %d limit 1", + intval($uid) + ); + if($r !== false and count($r)) { + $service_class = $r[0]['service_class']; + } + } + if(! x($service_class)) + return true; // everything is allowed + + $arr = get_config('service_class',$service_class); + if(! is_array($arr) || (! count($arr))) + return true; + + if($usage === false) + return ((x($arr[$property])) ? (bool) $arr['property'] : true); + else { + if(! array_key_exists($property,$arr)) + return true; + return (((intval($usage)) < intval($arr[$property])) ? true : false); + } +} \ No newline at end of file diff --git a/include/user.php b/include/user.php index 2477438bf..383a3b3e1 100644 --- a/include/user.php +++ b/include/user.php @@ -147,13 +147,18 @@ function create_user($arr) { require_once('include/crypto.php'); - $keys = new_keypair(1024); + $keys = new_keypair(4096); if($keys === false) { $result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL; return $result; } + $default_service_class = get_config('system','default_service_class'); + if(! $default_service_class) + $default_service_class = ''; + + $prvkey = $keys['prvkey']; $pubkey = $keys['pubkey']; @@ -173,8 +178,8 @@ function create_user($arr) { $spubkey = $sres['pubkey']; $r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`, - `pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone` ) - VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC' )", + `pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone`, `service_class` ) + VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC', '%s' )", dbesc(generate_user_guid()), dbesc($username), dbesc($new_password_encoded), @@ -187,7 +192,8 @@ function create_user($arr) { dbesc($sprvkey), dbesc(datetime_convert()), intval($verified), - intval($blocked) + intval($blocked), + dbesc($default_service_class) ); if($r) { diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php index 76b99cbca..8e39f5fd0 100644 --- a/mod/dfrn_confirm.php +++ b/mod/dfrn_confirm.php @@ -146,7 +146,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) { */ require_once('include/crypto.php'); - $res = new_keypair(1024); + $res = new_keypair(4096); $private_key = $res['prvkey']; $public_key = $res['pubkey']; From 9528beac34389f8d8f20de1816bca8d516a556cc Mon Sep 17 00:00:00 2001 From: friendica Date: Sun, 24 Jun 2012 16:51:39 -0700 Subject: [PATCH 08/12] sidebar photo album list not visible to anybody if user['hidewall'] set --- boot.php | 2 +- mod/photos.php | 6 +- util/messages.po | 203 +++++++++++++++++++++++++---------------------- 3 files changed, 115 insertions(+), 96 deletions(-) diff --git a/boot.php b/boot.php index ac561edf6..8aa36f18a 100644 --- a/boot.php +++ b/boot.php @@ -10,7 +10,7 @@ require_once('include/nav.php'); require_once('include/cache.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); -define ( 'FRIENDICA_VERSION', '3.0.1383' ); +define ( 'FRIENDICA_VERSION', '3.0.1384' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DB_UPDATE_VERSION', 1149 ); diff --git a/mod/photos.php b/mod/photos.php index d96bc135e..31046565d 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -38,8 +38,10 @@ function photos_init(&$a) { $o .= '
    ' . $a->data['user']['username'] . '
    '; $o .= '
    ' . $a->data['user']['username'] . '
    '; $o .= ''; - - if(! intval($a->data['user']['hidewall'])) { + + $albums_visible = ((intval($a->data['user']['hidewall']) && (! local_user()) && (! remote_user())) ? false : true); + + if($albums_visible) { $o .= ' +
    +

    +$lbl_likes +

    + + + +
    +
    + + + +
    +

    +$lbl_dislikes +

    + + + +
    +
    + + +

    $lbl_social From ad6c82bdea11e4c35284e18608f78ad4c355405d Mon Sep 17 00:00:00 2001 From: friendica Date: Sun, 24 Jun 2012 22:23:17 -0700 Subject: [PATCH 10/12] implement "follow" service limits --- include/follow.php | 36 ++++++++++++++++++++++++++++++++++++ include/plugin.php | 15 ++++++++++++++- view/en/update_fail_eml.tpl | 2 +- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/follow.php b/include/follow.php index 22288a0da..b4d1732b8 100644 --- a/include/follow.php +++ b/include/follow.php @@ -62,6 +62,11 @@ function new_contact($uid,$url,$interactive = false) { } } + + + + + // This extra param just confuses things, remove it if($ret['network'] === NETWORK_DIASPORA) $ret['url'] = str_replace('?absolute=true','',$ret['url']); @@ -89,6 +94,11 @@ function new_contact($uid,$url,$interactive = false) { $ret['notify'] = ''; } + + + + + if(! $ret['notify']) { $result['message'] .= t('Limited profile. This person will be unable to receive direct/personal notifications from you.') . EOL; } @@ -129,6 +139,32 @@ function new_contact($uid,$url,$interactive = false) { } else { + + // check service class limits + + $r = q("select count(*) as total from contact where uid = %d and pending = 0 and self = 0", + intval($uid) + ); + if(count($r)) + $total_contacts = $r[0]['total']; + + if(! service_class_allows($uid,'total_contacts',$total_contacts)) { + $result['message'] .= upgrade_message(); + return $result; + } + + $r = q("select count(network) as total from contact where uid = %d and network = '%s' and pending = 0 and self = 0", + intval($uid), + dbesc($network) + ); + if(count($r)) + $total_network = $r[0]['total']; + + if(! service_class_allows($uid,'total_contacts_' . $network,$total_network)) { + $result['message'] .= upgrade_message(); + return $result; + } + $new_relation = (($ret['network'] === NETWORK_MAIL) ? CONTACT_IS_FRIEND : CONTACT_IS_SHARING); if($ret['network'] === NETWORK_DIASPORA) $new_relation = CONTACT_IS_FOLLOWER; diff --git a/include/plugin.php b/include/plugin.php index 3b6faa072..89715485e 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -353,4 +353,17 @@ function service_class_allows($uid,$property,$usage = false) { return true; return (((intval($usage)) < intval($arr[$property])) ? true : false); } -} \ No newline at end of file +} + +function upgrade_link() { + $l = get_config('service_class','upgrade_link'); + $t = sprintf('' . t('Click here to upgrade.') . '

    ', $l); + if($l) + return $t; + return ''; +} + +function upgrade_message() { + $x = upgrade_link(); + return t('This action exceeds the limits set by your subscription plan.') . (($x) ? ' ' . $x : '') ; +} diff --git a/view/en/update_fail_eml.tpl b/view/en/update_fail_eml.tpl index f68a3dece..548e1a0df 100644 --- a/view/en/update_fail_eml.tpl +++ b/view/en/update_fail_eml.tpl @@ -1,5 +1,5 @@ Hey, -I'm $sitename. +I'm $sitename; The friendica developers released update $update recently, but when I tried to install it, something went terribly wrong. This needs to be fixed soon and I can't do it alone. Please contact a From 35a098e0dc7940974132d8d65bbc4418d92fb204 Mon Sep 17 00:00:00 2001 From: friendica Date: Mon, 25 Jun 2012 01:37:44 -0700 Subject: [PATCH 11/12] service limits for photo uploads --- include/plugin.php | 25 +++++++++++++++++++++++ mod/photos.php | 33 ++++++++++++++++++++++++++++++- view/photos_upload.tpl | 3 +++ view/theme/duepuntozero/style.css | 3 +++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/include/plugin.php b/include/plugin.php index 89715485e..e8fec4cbe 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -355,6 +355,31 @@ function service_class_allows($uid,$property,$usage = false) { } } + +function service_class_fetch($uid,$property) { + + if($uid == local_user()) { + $service_class = $a->user['service_class']; + } + else { + $r = q("select service_class from user where uid = %d limit 1", + intval($uid) + ); + if($r !== false and count($r)) { + $service_class = $r[0]['service_class']; + } + } + if(! x($service_class)) + return false; // everything is allowed + + $arr = get_config('service_class',$service_class); + if(! is_array($arr) || (! count($arr))) + return false; + + return((array_key_exists($property,$arr)) ? $arr[$property] : false); + +} + function upgrade_link() { $l = get_config('service_class','upgrade_link'); $t = sprintf('' . t('Click here to upgrade.') . '', $l); diff --git a/mod/photos.php b/mod/photos.php index 31046565d..ea4d7f81f 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -711,6 +711,24 @@ function photos_post(&$a) { logger('mod/photos.php: photos_post(): loading the contents of ' . $src , LOGGER_DEBUG); $imagedata = @file_get_contents($src); + + + + $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", + intval($a->data['user']['uid']) + ); + + $limit = service_class_fetch($a->data['user']['uid'],'photo_upload_limit'); + + if(($limit !== false) && (($r[0]['total'] + strlen($imagedata)) > $limit)) { + notice( upgrade_message() . EOL ); + @unlink($src); + $foo = 0; + call_hooks('photo_post_end',$foo); + killme(); + } + + $ph = new Photo($imagedata, $type); if(! $ph->is_valid()) { @@ -968,12 +986,25 @@ function photos_content(&$a) { '; - + $r = q("select sum(octet_length(data)) as total from photo where uid = %d and scale = 0 and album != 'Contact Photos' ", + intval($a->data['user']['uid']) + ); + + + $limit = service_class_fetch($a->data['user']['uid'],'photo_upload_limit'); + if($limit !== false) { + $usage_message = sprintf( t("You have used %1$.2f Mbytes of %2$.2f Mbytes photo storage."), $r[0]['total'] / 1024000, $limit / 1024000 ); + } + else { + $usage_message = sprintf( t('You have used %1$.2f Mbytes of photo storage.'), $r[0]['total'] / 1024000 ); + } + $tpl = get_markup_template('photos_upload.tpl'); $o .= replace_macros($tpl,array( '$pagename' => t('Upload Photos'), '$sessid' => session_id(), + '$usage' => $usage_message, '$nickname' => $a->data['user']['nickname'], '$newalbum' => t('New album name: '), '$existalbumtext' => t('or existing album name: '), diff --git a/view/photos_upload.tpl b/view/photos_upload.tpl index 318a92427..706b3398d 100644 --- a/view/photos_upload.tpl +++ b/view/photos_upload.tpl @@ -1,4 +1,7 @@

    $pagename

    + +
    $usage
    +
    diff --git a/view/theme/duepuntozero/style.css b/view/theme/duepuntozero/style.css index de366210b..ea3a2da9c 100644 --- a/view/theme/duepuntozero/style.css +++ b/view/theme/duepuntozero/style.css @@ -1644,6 +1644,9 @@ input#dfrn-url { display:block!important; } +#photos-usage-message { + margin-bottom: 15px; +} #acl-wrapper { From 7ea5917bf794c431fe304fa25380f19a6927cf63 Mon Sep 17 00:00:00 2001 From: friendica Date: Mon, 25 Jun 2012 03:25:06 -0700 Subject: [PATCH 12/12] more service class functionality --- include/plugin.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/plugin.php b/include/plugin.php index e8fec4cbe..d762e8717 100644 --- a/include/plugin.php +++ b/include/plugin.php @@ -392,3 +392,8 @@ function upgrade_message() { $x = upgrade_link(); return t('This action exceeds the limits set by your subscription plan.') . (($x) ? ' ' . $x : '') ; } + +function upgrade_bool_message() { + $x = upgrade_link(); + return t('This action is not available under your subscription plan.') . (($x) ? ' ' . $x : '') ; +}