diff --git a/boot.php b/boot.php
index b169efd7ee..eb91b26baf 100644
--- a/boot.php
+++ b/boot.php
@@ -38,7 +38,7 @@ define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_CODENAME', 'Asparagus');
define ( 'FRIENDICA_VERSION', '3.5.1-dev' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
-define ( 'DB_UPDATE_VERSION', 1207 );
+define ( 'DB_UPDATE_VERSION', 1208 );
/**
* @brief Constant with a HTML line break.
@@ -785,60 +785,100 @@ class App {
return($this->scheme);
}
+ /**
+ * @brief Retrieves the Friendica instance base URL
+ *
+ * This function assembles the base URL from multiple parts:
+ * - Protocol is determined either by the request or a combination of
+ * system.ssl_policy and the $ssl parameter.
+ * - Host name is determined either by system.hostname or inferred from request
+ * - Path is inferred from SCRIPT_NAME
+ *
+ * Caches the result (depending on $ssl value) for performance.
+ *
+ * Note: $ssl parameter value doesn't directly correlate with the resulting protocol
+ *
+ * @param bool $ssl Whether to append http or https under SSL_POLICY_SELFSIGN
+ * @return string Friendica server base URL
+ */
function get_baseurl($ssl = false) {
// Is the function called statically?
- if (!is_object($this))
- return(self::$a->get_baseurl($ssl));
+ if (!is_object($this)) {
+ return self::$a->get_baseurl($ssl);
+ }
+
+ // Arbitrary values, the resulting url protocol can be different
+ $cache_index = $ssl ? 'https' : 'http';
+
+ // Cached value found, nothing to process
+ if (isset($this->baseurl[$cache_index])) {
+ return $this->baseurl[$cache_index];
+ }
$scheme = $this->scheme;
- if((x($this->config,'system')) && (x($this->config['system'],'ssl_policy'))) {
- if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL))
+ if ((x($this->config, 'system')) && (x($this->config['system'], 'ssl_policy'))) {
+ if (intval($this->config['system']['ssl_policy']) === SSL_POLICY_FULL) {
$scheme = 'https';
+ }
// Basically, we have $ssl = true on any links which can only be seen by a logged in user
// (and also the login link). Anything seen by an outsider will have it turned off.
- if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) {
- if($ssl)
+ if ($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) {
+ if ($ssl) {
$scheme = 'https';
- else
+ } else {
$scheme = 'http';
+ }
}
}
- if (get_config('config','hostname') != "")
- $this->hostname = get_config('config','hostname');
+ if (get_config('config', 'hostname') != '') {
+ $this->hostname = get_config('config', 'hostname');
+ }
- $this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
- return $this->baseurl;
+ $this->baseurl[$cache_index] = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
+
+ return $this->baseurl[$cache_index];
}
+ /**
+ * @brief Initializes the baseurl components
+ *
+ * Clears the baseurl cache to prevent inconstistencies
+ *
+ * @param string $url
+ */
function set_baseurl($url) {
$parsed = @parse_url($url);
- $this->baseurl = $url;
+ $this->baseurl = [];
if($parsed) {
$this->scheme = $parsed['scheme'];
$hostname = $parsed['host'];
- if(x($parsed,'port'))
+ if (x($parsed, 'port')) {
$hostname .= ':' . $parsed['port'];
- if(x($parsed,'path'))
- $this->path = trim($parsed['path'],'\\/');
+ }
+ if (x($parsed, 'path')) {
+ $this->path = trim($parsed['path'], '\\/');
+ }
- if (file_exists(".htpreconfig.php"))
+ if (file_exists(".htpreconfig.php")) {
@include(".htpreconfig.php");
+ }
- if (get_config('config','hostname') != "")
- $this->hostname = get_config('config','hostname');
+ if (get_config('config', 'hostname') != '') {
+ $this->hostname = get_config('config', 'hostname');
+ }
- if (!isset($this->hostname) OR ($this->hostname == ""))
+ if (!isset($this->hostname) OR ($this->hostname == '')) {
$this->hostname = $hostname;
+ }
}
-
}
function get_hostname() {
diff --git a/database.sql b/database.sql
index f12746e7e5..c5fd49ba01 100644
--- a/database.sql
+++ b/database.sql
@@ -655,6 +655,8 @@ CREATE TABLE IF NOT EXISTS `notify` (
`seen` tinyint(1) NOT NULL DEFAULT 0,
`verb` varchar(255) NOT NULL DEFAULT '',
`otype` varchar(16) NOT NULL DEFAULT '',
+ `name_cache` tinytext,
+ `msg_name` mediumtext,
PRIMARY KEY(`id`),
INDEX `uid` (`uid`)
) DEFAULT CHARSET=utf8mb4;
diff --git a/doc/BBCode.md b/doc/BBCode.md
index d22f7afa58..595c2da860 100644
--- a/doc/BBCode.md
+++ b/doc/BBCode.md
@@ -1,208 +1,610 @@
Friendica BBCode tags reference
========================
-* [Home](help)
+* [Creating posts](help/Text_editor)
-Inline
------
+## Inline
+
-
[u]underlined[/u]
: underlined
+
+
+ BBCode |
+ Result |
+
+
+ [b]bold[/b] |
+ bold |
+
+
+ [i]italic[/i] |
+ italic |
+
+
+ [u]underlined[/u] |
+ underlined |
+
+
+ [s]strike[/s] |
+ strike |
+
+
+ [o]overline[/o] |
+ overline |
+
+
+ [color=red]red[/color] |
+ red |
+
+
+ [url=http://www.friendica.com]Friendica[/url] |
+ Friendica |
+
+
+ [img]http://friendica.com/sites/default/files/friendika-32.png[/img] |
+  |
+
+
+ [img=64x32]http://friendica.com/sites/default/files/friendika-32.png[/img]
+ Note: provided height is simply discarded. |
+  |
+
+
+ [size=xx-small]small text[/size] |
+ small text |
+
+
+ [size=xx-large]big text[/size] |
+ big text |
+
+
+ [size=20]exact size[/size] (size can be any number, in pixel) |
+ exact size |
+
+
+ [font=serif]Serif font[/font] |
+ Serif font |
+
+
-[s]strike[/s]
: strike
+### Links
-[color=red]red[/color]
: red
+
+
+ BBCode |
+ Result |
+
+
+ [url]http://friendica.com[/url] |
+ http://friendica.com |
+
+
+ [url=http://friendica.com]Friendica[/url] |
+ Friendica |
+
+
+ [bookmark]http://friendica.com[/bookmark]
+#^[url]http://friendica.com[/url] |
+ |
+
+
+ [bookmark=http://friendica.com]Bookmark[/bookmark]
+#^[url=http://friendica.com]Bookmark[/url]
+#[url=http://friendica.com]^[/url][url=http://friendica.com]Bookmark[/url] |
+ |
+
+
+ [url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora post with GUID[/url] |
+ Diaspora post with GUID |
+
+
+ #Friendica |
+ #Friendica |
+
+
+ @Mention |
+ @Mention |
+
+
+ acct:account@friendica.host.com (WebFinger) |
+ acct:account@friendica.host.com |
+
+
+ [mail]user@mail.example.com[/mail] |
+ user@mail.example.com |
+
+
+ [mail=user@mail.example.com]Send an email to User[/mail] |
+ Send an email to User |
+
+
-[url=http://www.friendica.com]Friendica[/url]
: Friendica
+## Blocks
-[img]http://friendica.com/sites/default/files/friendika-32.png[/img]
:
+
+
+ BBCode |
+ Result |
+
+
+ [p]A paragraph of text[/p] |
+ A paragraph of text |
+
+
+ Inline [code]code[/code] in a paragraph |
+ Inline code in a paragraph |
+
+
+ [code]Multi line code[/code] |
+ Multi
+line
+code |
+
+
+ [code=php]function text_highlight($s,$lang)[/code] |
+ - function text_highlight($s,$lang)
|
+
+
+ [quote]quote[/quote] |
+ quote |
+
+
+ [quote=Author]Author? Me? No, no, no...[/quote] |
+ Author wrote:Author? Me? No, no, no... |
+
+
+ [center]Centered text[/center] |
+ Centered text |
+
+
+ You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler] |
+
+
+ You should not read any further if you want to be surprised.
+ Click to open/close
+ There is a happy end.
+
+
+ |
+
+
+ [spoiler=Author]Spoiler quote[/spoiler] |
+
+
+ Author wrote:
+ Click to open/close
+ Spoiler quote
+
+
+ |
+
+
+ [hr] (horizontal line) |
+
|
+
+
-[size=xx-small]small text[/size]
: small text
+### Titles
-[size=xx-large]big text[/size]
: big text
+
+
+ BBCode |
+ Result |
+
+
+ [h1]Title 1[/h1] |
+ Title 1 |
+
+
+ [h2]Title 2[/h2] |
+ Title 2 |
+
+
+ [h3]Title 3[/h3] |
+ Title 3 |
+
+
+ [h4]Title 4[/h4] |
+ Title 4 |
+
+
+ [h5]Title 5[/h5] |
+ Title 5 |
+
+
+ [h6]Title 6[/h6] |
+ Title 6 |
+
+
-[size=20]exact size[/size] (size can be any number, in pixel)
: exact size
+### Tables
+
+
+ BBCode |
+ Result |
+
+
+ [table]
+ [tr]
+ [th]Header 1[/th]
+ [th]Header 2[/th]
+ [th]Header 2[/th]
+ [/tr]
+ [tr]
+ [td]Cell 1[/td]
+ [td]Cell 2[/td]
+ [td]Cell 3[/td]
+ [/tr]
+ [tr]
+ [td]Cell 4[/td]
+ [td]Cell 5[/td]
+ [td]Cell 6[/td]
+ [/tr]
+[/table] |
+
+
+
+
+ Header 1 |
+ Header 2 |
+ Header 3 |
+
+
+ Cell 1 |
+ Cell 2 |
+ Cell 3 |
+
+
+ Cell 4 |
+ Cell 5 |
+ Cell 6 |
+
+
+
+ |
+
+
+ [table border=0] |
+
+
+
+
+ Header 1 |
+ Header 2 |
+ Header 3 |
+
+
+ Cell 1 |
+ Cell 2 |
+ Cell 3 |
+
+
+ Cell 4 |
+ Cell 5 |
+ Cell 6 |
+
+
+
+ |
+
+
+ [table border=1] |
+
+
+
+
+ Header 1 |
+ Header 2 |
+ Header 3 |
+
+
+ Cell 1 |
+ Cell 2 |
+ Cell 3 |
+
+
+ Cell 4 |
+ Cell 5 |
+ Cell 6 |
+
+
+
+ |
+
+
+### Lists
+
+
+ BBCode |
+ Result |
+
+
+ [ul]
+ [li] First list element
+ [li] Second list element
+[/ul]
+[list]
+ [*] First list element
+ [*] Second list element
+[/list] |
+
+
+ - First list element
+ - Second list element
+
+ |
+
+
+ [ol]
+ [*] First list element
+ [*] Second list element
+[/ol]
+[list=1]
+ [*] First list element
+ [*] Second list element
+[/list] |
+
+
+ - First list element
+ - Second list element
+
+ |
+
+
+ [list=]
+ [*] First list element
+ [*] Second list element
+[/list] |
+
+
+ - First list element
+ - Second list element
+
+ |
+
+
+ [list=i]
+ [*] First list element
+ [*] Second list element
+[/list] |
+
+
+ - First list element
+ - Second list element
+
+ |
+
+
+ [list=I]
+ [*] First list element
+ [*] Second list element
+[/list] |
+
+
+ - First list element
+ - Second list element
+
+ |
+
+
+ [list=a]
+ [*] First list element
+ [*] Second list element
+[/list] |
+
+
+ - First list element
+ - Second list element
+
+ |
+
+
+ [list=A]
+ [*] First list element
+ [*] Second list element
+[/list] |
+
+
+ - First list element
+ - Second list element
+
+ |
+
+
-
-
-
-Block
------
-
-[code]code[/code]
-
-code
-
-
-
-[code=php]function text_highlight($s,$lang)[/code]
-
-- function text_highlight($s,$lang)
-
-
-
-[quote]quote[/quote]
-
-quote
-
-
-
-[quote=Author]Author? Me? No, no, no...[/quote]
-
-Author wrote:Author? Me? No, no, no...
-
-
-
-[center]centered text[/center]
-
-centered text
-
-
-
-You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler]
-
-You should not read any further if you want to be surprised.
*click to open/close*
-
-(The text between thhe opening and the closing of the spoiler tag will be visible once the link is clicked. So *"There is a happy end."* wont be visible until the spoiler is uncovered.)
-
-
-
-**Table**
-[table border=1]
- [tr]
- [th]Tables now[/th]
- [/tr]
- [tr]
- [td]Have headers[/td]
- [/tr]
-[/table]
-
-
-
-
-
-**List**
-
-[list]
- [*] First list element
- [*] Second list element
-[/list]
-
-- First list element
-
-- Second list element
-
-
-[list] is equivalent to [ul] (unordered list).
-
-[ol] can be used instead of [list] to show an ordered list:
-
-[ol]
- [*] First list element
- [*] Second list element
-[/ol]
-- First list element
- Second list element
-
-For more options on ordered lists, you can define the style of numeration on [list] argument:
-[list=1]
: decimal
-
-[list=i]
: lover case roman
-
-[list=I]
: upper case roman
-
-[list=a]
: lover case alphabetic
-
-[list=A]
: upper case alphabetic
-
-
-
-
-Embed
-------
+## Embed
You can embed video, audio and more in a message.
-[video]url[/video]
-[audio]url[/audio]
+
+
+ BBCode |
+ Result |
+
+
+ [video]url[/video] |
+ Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications. |
+
+
+ [video]Video file url[/video]
+[audio]Audio file url[/audio] |
+ Full URL to an ogg/ogv/oga/ogm/webm/mp4/mp3 file. An HTML5 player will be used to show it. |
+
+
+ [youtube]Youtube URL[/youtube] |
+ Youtube video OEmbed display. May not embed an actual player. |
+
+
+ [youtube]Youtube video ID[/youtube] |
+ Youtube player iframe embed. |
+
+
+ [vimeo]Vimeo URL[/vimeo] |
+ Vimeo video OEmbed display. May not embed an actual player. |
+
+
+ [vimeo]Vimeo video ID[/vimeo] |
+ Vimeo player iframe embed. |
+
+
+ [iframe]URL[/iframe] |
+ General embed, iframe size is limited by the theme size for video players. |
+
+
+ [url]*url*[/url] |
+ If *url* supports oembed or opengraph specifications the embedded object will be shown (eg, documents from scribd).
+Page title with a link to *url* will be shown. |
+
+
-Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications.
-*url* can be also full url to an ogg file. HTML5 tag will be used to show it.
+## Map
-[url]*url*[/url]
+This require "openstreetmap" addon version 1.3 or newer. If the addon isn't activated,
+the raw coordinates are shown instead.
-If *url* supports oembed or opengraph specifications the embedded object will be shown (eg, documents from scribd).
-Page title with a link to *url* will be shown.
+
+
+ BBCode |
+ Result |
+
+
+ [map]address[/map] |
+ Embeds a map centered on this address. |
+
+
+ [map=lat,long] |
+ Embeds a map centered on those coordinates. |
+
+
+ [map] |
+ Embeds a map centered on the post's location. |
+
+
-Map
----
+## Abstract for longer posts
-[map]address[/map]
-[map=lat,long]
+If you want to spread your post to several third party networks you can have the problem that these networks have a length limitation like on Twitter.
-You can embed maps from coordinates or addresses.
-This require "openstreetmap" addon version 1.3 or newer.
-
------------------------------------------------------------
-
-Abstract for longer posts
--------------------------
-
-If you want to spread your post to several third party networks you can have the problem that these networks have (for example) a length limitation.
-(Like on Twitter)
-
-Friendica is using a semi intelligent mechanism to generate a fitting abstract.
-But it can be interesting to define an own abstract that will only be displayed on the external network.
-This is done with the [abstract]-element.
-Example:
-
-[abstract]Totally interesting! A must-see! Please click the link![/abstract]
-I want to tell you a really boring story that you really never wanted
-to hear.
-
-Twitter would display the text "Totally interesting! A must-see! Please click the link!".
-On Friendica you would only see the text after "I want to tell you a really ..."
+Friendica is using a semi intelligent mechanism to generate a fitting abstract.
+But it can be interesting to define a custom abstract that will only be displayed on the external network.
+This is done with the [abstract]-element.
+
+
+ BBCode |
+ Result |
+
+
+ [abstract]Totally interesting! A must-see! Please click the link![/abstract]
+I want to tell you a really boring story that you really never wanted to hear. |
+ Twitter would display the text Totally interesting! A must-see! Please click the link!
+On Friendica you would only see the text after I want to tell you a really ... |
+
+
It is even possible to define abstracts for separate networks:
-
-[abstract]Hi friends Here are my newest pictures![abstract]
-[abstract=twit]Hi my dear Twitter followers. Do you want to see my new
-pictures?[abstract]
-[abstract=apdn]Helly my dear followers on ADN. I made sone new pictures
-that I wanted to share with you.[abstract]
-Today I was in the woods and took some real cool pictures ...
-
-
-For Twitter and App.net the system will use the defined abstracts.
-For other networks (e.g. when you are using the "statusnet" connector that is used to post to GNU Social) the general abstract element will be used.
+
+
+ BBCode |
+ Result |
+
+
+
+[abstract]Hi friends Here are my newest pictures![/abstract]
+[abstract=twit]Hi my dear Twitter followers. Do you want to see my new
+pictures?[/abstract]
+[abstract=apdn]Helly my dear followers on ADN. I made sone new pictures
+that I wanted to share with you.[/abstract]
+Today I was in the woods and took some real cool pictures ... |
+ For Twitter and App.net the system will use the defined abstracts.
+For other networks (e.g. when you are using the "statusnet" connector that is used to post to GNU Social) the general abstract element will be used. |
+
+
If you use (for example) the "buffer" connector to post to Facebook or Google+ you can use this element to define an abstract for a longer blogpost that you don't want to post completely to these networks.
-Networks like Facebook or Google+ aren't length limited.
-For this reason the [abstract] element isn't used.
+Networks like Facebook or Google+ aren't length limited.
+For this reason the [abstract] element isn't used.
Instead you have to name the explicit network:
-
-[abstract]These days I had a strange encounter ...[abstract]
-[abstract=goog]Helly my dear Google+ followers. You have to read my
-newest blog post![abstract]
-[abstract=face]Hello my Facebook friends. These days happened something
-really cool.[abstract]
-While taking pictures in the woods I had a really strange encounter ...
+
+
+ BBCode |
+ Result |
+
+
+
+[abstract]These days I had a strange encounter...[/abstract]
+[abstract=goog]Helly my dear Google+ followers. You have to read my newest blog post![/abstract]
+[abstract=face]Hello my Facebook friends. These days happened something really cool.[/abstract]
+While taking pictures in the woods I had a really strange encounter... |
+ Google and Facebook will show the respective abstracts while the other networks will show the default one.
+ Meanwhile, Friendica won't show any of the abstracts. |
+
+
-The [abstract] element isn't working with the native OStatus connection or with connectors where we post the HTML.
-(Like Tumblr, Wordpress or Pump.io)
+The [abstract] element isn't working with the native OStatus connection or with connectors where we post the HTML like Tumblr, Wordpress or Pump.io.
-Special
--------
+## Special
-If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
-
-[noparse][b]bold[/b][/noparse]
: [b]bold[/b]
+
+
+ BBCode |
+ Result |
+
+
+ If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
+
+ - [noparse][b]bold[/b][/noparse]
+ - [nobb][b]bold[/b][/nobb]
+ - [pre][b]bold[/b][/pre]
+
+ |
+ [b]bold[/b] |
+
+
+ [nosmile] is used to disable smilies on a post by post basis
+
+ [nosmile] ;-) :-O
+ |
+ ;-) :-O |
+
+
+ Custom inline styles
+
+[style=text-shadow: 0 0 4px #CC0000;]You can change all the CSS properties of this block.[/style] |
+ You can change all the CSS properties of this block. |
+
+
+ Custom class block
+
+[class=custom]If the class exists, this block will have the custom class style applied.[/class] |
+ <span class="custom">If the class exists, this block will have the custom class style applied.</span> |
+
+
diff --git a/doc/database/db_notify.md b/doc/database/db_notify.md
index 5ef2aa7ebc..b2bae64717 100644
--- a/doc/database/db_notify.md
+++ b/doc/database/db_notify.md
@@ -1,22 +1,24 @@
Table notify
============
-| Field | Description | Type | Null | Key | Default | Extra |
-| ------ | --------------------------------- | ------------ | ---- | --- | ------------------- | --------------- |
-| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
-| hash | | varchar(64) | NO | | | |
-| type | | int(11) | NO | | 0 | |
-| name | | varchar(255) | NO | | | |
-| url | | varchar(255) | NO | | | |
-| photo | | varchar(255) | NO | | | |
-| date | | datetime | NO | | 0000-00-00 00:00:00 | |
-| msg | | mediumtext | NO | | NULL | |
-| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | |
-| link | | varchar(255) | NO | | | |
-| parent | | int(11) | NO | | 0 | |
-| seen | | tinyint(1) | NO | | 0 | |
-| verb | | varchar(255) | NO | | | |
-| otype | | varchar(16) | NO | | | |
-| iid | item.id | int(11) | NO | | 0 | |
+| Field | Description | Type | Null | Key | Default | Extra |
+| ---------- | --------------------------------- | ------------ | ---- | --- | ------------------- | --------------- |
+| id | sequential ID | int(11) | NO | PRI | NULL | auto_increment |
+| hash | | varchar(64) | NO | | | |
+| type | | int(11) | NO | | 0 | |
+| name | | varchar(255) | NO | | | |
+| url | | varchar(255) | NO | | | |
+| photo | | varchar(255) | NO | | | |
+| date | | datetime | NO | | 0000-00-00 00:00:00 | |
+| msg | | mediumtext | YES | | NULL | |
+| uid | user.id of the owner of this data | int(11) | NO | MUL | 0 | |
+| link | | varchar(255) | NO | | | |
+| iid | item.id | int(11) | NO | | 0 | |
+| parent | | int(11) | NO | | 0 | |
+| seen | | tinyint(1) | NO | | 0 | |
+| verb | | varchar(255) | NO | | | |
+| otype | | varchar(16) | NO | | | |
+| name_cache | Cached bbcode parsing of name | tinytext | YES | | NULL | |
+| msg_cache | Cached bbcode parsing of msg | mediumtext | YES | | NULL | |
Return to [database documentation](help/database)
diff --git a/include/bbcode.php b/include/bbcode.php
index ed23253648..ebafc353a4 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -146,7 +146,7 @@ function cleancss($input) {
if (($char >= "a") and ($char <= "z"))
$cleaned .= $char;
- if (!(strpos(" #;:0123456789-_", $char) === false))
+ if (!(strpos(" #;:0123456789-_.%", $char) === false))
$cleaned .= $char;
}
@@ -892,8 +892,7 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal
// we may need to restrict this further if it picks up too many strays
// link acct:user@host to a webfinger profile redirector
- $Text = preg_replace('/acct:(.*?)@(.*?)([ ,])/', 'acct:' . "$1@$2$3" . '',$Text);
+ $Text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', 'acct:$1@$2',$Text);
// Perform MAIL Search
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '$1', $Text);
diff --git a/include/datetime.php b/include/datetime.php
index ea98f01fe0..16b134e90b 100644
--- a/include/datetime.php
+++ b/include/datetime.php
@@ -325,15 +325,15 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
* Results relative to current timezone.
* Limited to range of timestamps.
*
- * @param string $posted_date
+ * @param string $posted_date MySQL-formatted date string (YYYY-MM-DD HH:MM:SS)
* @param string $format (optional) Parsed with sprintf()
* %1$d %2$s ago, e.g. 22 hours ago, 1 minute ago
- *
+ *
* @return string with relative date
*/
-function relative_date($posted_date,$format = null) {
+function relative_date($posted_date, $format = null) {
- $localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date);
+ $localtime = $posted_date . ' UTC';
$abs = strtotime($localtime);
@@ -347,13 +347,6 @@ function relative_date($posted_date,$format = null) {
return t('less than a second ago');
}
- /*
- $time_append = '';
- if ($etime >= 86400) {
- $time_append = ' ('.$localtime.')';
- }
- */
-
$a = array( 12 * 30 * 24 * 60 * 60 => array( t('year'), t('years')),
30 * 24 * 60 * 60 => array( t('month'), t('months')),
7 * 24 * 60 * 60 => array( t('week'), t('weeks')),
@@ -368,10 +361,11 @@ function relative_date($posted_date,$format = null) {
if ($d >= 1) {
$r = round($d);
// translators - e.g. 22 hours ago, 1 minute ago
- if(! $format)
+ if (!$format) {
$format = t('%1$d %2$s ago');
+ }
- return sprintf( $format,$r, (($r == 1) ? $str[0] : $str[1]));
+ return sprintf($format, $r, (($r == 1) ? $str[0] : $str[1]));
}
}
}
diff --git a/include/dbstructure.php b/include/dbstructure.php
index 1347891778..bd4a07eb56 100644
--- a/include/dbstructure.php
+++ b/include/dbstructure.php
@@ -1039,6 +1039,8 @@ function db_definition($charset) {
"seen" => array("type" => "tinyint(1)", "not null" => "1", "default" => "0"),
"verb" => array("type" => "varchar(255)", "not null" => "1", "default" => ""),
"otype" => array("type" => "varchar(16)", "not null" => "1", "default" => ""),
+ "name_cache" => array("type" => "tinytext"),
+ "msg_cache" => array("type" => "mediumtext")
),
"indexes" => array(
"PRIMARY" => array("id"),
diff --git a/include/enotify.php b/include/enotify.php
index 4973bedc24..5b2bea2977 100644
--- a/include/enotify.php
+++ b/include/enotify.php
@@ -418,6 +418,7 @@ function notification($params) {
$datarray = array();
$datarray['hash'] = $hash;
$datarray['name'] = $params['source_name'];
+ $datarray['name_cache'] = strip_tags(bbcode($params['source_name']));
$datarray['url'] = $params['source_link'];
$datarray['photo'] = $params['source_photo'];
$datarray['date'] = datetime_convert();
@@ -439,8 +440,8 @@ function notification($params) {
// create notification entry in DB
- $r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`)
- values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s')",
+ $r = q("INSERT INTO `notify` (`hash`, `name`, `url`, `photo`, `date`, `uid`, `link`, `iid`, `parent`, `type`, `verb`, `otype`, `name_cache`)
+ values('%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s')",
dbesc($datarray['hash']),
dbesc($datarray['name']),
dbesc($datarray['url']),
@@ -452,7 +453,8 @@ function notification($params) {
intval($datarray['parent']),
intval($datarray['type']),
dbesc($datarray['verb']),
- dbesc($datarray['otype'])
+ dbesc($datarray['otype']),
+ dbesc($datarray["name_cache"])
);
$r = q("SELECT `id` FROM `notify` WHERE `hash` = '%s' AND `uid` = %d LIMIT 1",
@@ -494,8 +496,10 @@ function notification($params) {
$itemlink = $a->get_baseurl().'/notify/view/'.$notify_id;
$msg = replace_macros($epreamble, array('$itemlink' => $itemlink));
- $r = q("UPDATE `notify` SET `msg` = '%s' WHERE `id` = %d AND `uid` = %d",
+ $msg_cache = format_notification_message($datarray['name_cache'], strip_tags(bbcode($msg)));
+ $r = q("UPDATE `notify` SET `msg` = '%s', `msg_cache` = '%s' WHERE `id` = %d AND `uid` = %d",
dbesc($msg),
+ dbesc($msg_cache),
intval($notify_id),
intval($params['uid'])
);
@@ -778,4 +782,27 @@ function check_item_notification($itemid, $uid, $defaulttype = "") {
if (isset($params["type"]))
notification($params);
}
-?>
+
+/**
+ * @brief Formats a notification message with the notification author
+ *
+ * Replace the name with {0} but ensure to make that only once. The {0} is used
+ * later and prints the name in bold.
+ *
+ * @param string $name
+ * @param string $message
+ * @return string Formatted message
+ */
+function format_notification_message($name, $message) {
+ if ($name != '') {
+ $pos = strpos($message, $name);
+ } else {
+ $pos = false;
+ }
+
+ if ($pos !== false) {
+ $message = substr_replace($message, '{0}', $pos, strlen($name));
+ }
+
+ return $message;
+}
diff --git a/include/session.php b/include/session.php
index c69a402317..763b05f481 100644
--- a/include/session.php
+++ b/include/session.php
@@ -40,6 +40,19 @@ function ref_session_read($id) {
return '';
}
+/**
+ * @brief Standard PHP session write callback
+ *
+ * This callback updates the DB-stored session data and/or the expiration depending
+ * on the case. Uses the $session_expire global for existing session, 5 minutes
+ * for newly created session.
+ *
+ * @global bool $session_exists Whether a session with the given id already exists
+ * @global int $session_expire Session expiration delay in seconds
+ * @param string $id Session ID with format: [a-z0-9]{26}
+ * @param string $data Serialized session data
+ * @return boolean Returns false if parameters are missing, true otherwise
+ */
function ref_session_write($id, $data) {
global $session_exists, $session_expire;
@@ -66,10 +79,11 @@ function ref_session_write($id, $data) {
SET `expire` = '%s'
WHERE `expire` != '%s' AND `sid` = '%s'",
dbesc($expire), dbesc($expire), dbesc($id));
- } else
+ } else {
$r = q("INSERT INTO `session`
SET `sid` = '%s', `expire` = '%s', `data` = '%s'",
dbesc($id), dbesc($default_expire), dbesc($data));
+ }
return true;
}
diff --git a/include/text.php b/include/text.php
index 5c9202c580..83eab19270 100644
--- a/include/text.php
+++ b/include/text.php
@@ -769,71 +769,75 @@ function activity_match($haystack,$needle) {
}}
-if(! function_exists('get_tags')) {
/**
- * Pull out all #hashtags and @person tags from $s;
+ * @brief Pull out all #hashtags and @person tags from $string.
+ *
* We also get @person@domain.com - which would make
* the regex quite complicated as tags can also
* end a sentence. So we'll run through our results
* and strip the period from any tags which end with one.
* Returns array of tags found, or empty array.
*
- * @param string $s
- * @return array
+ * @param string $string Post content
+ * @return array List of tag and person names
*/
-function get_tags($s) {
+function get_tags($string) {
$ret = array();
// Convert hashtag links to hashtags
- $s = preg_replace("/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism", "#$2", $s);
+ $string = preg_replace('/#\[url\=([^\[\]]*)\](.*?)\[\/url\]/ism', '#$2', $string);
// ignore anything in a code block
- $s = preg_replace('/\[code\](.*?)\[\/code\]/sm','',$s);
+ $string = preg_replace('/\[code\](.*?)\[\/code\]/sm', '', $string);
// Force line feeds at bbtags
- $s = str_replace(array("[", "]"), array("\n[", "]\n"), $s);
+ $string = str_replace(array('[', ']'), array("\n[", "]\n"), $string);
// ignore anything in a bbtag
- $s = preg_replace('/\[(.*?)\]/sm','',$s);
+ $string = preg_replace('/\[(.*?)\]/sm', '', $string);
// 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,"]")) {
+ if (preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/', $string, $matches)) {
+ foreach ($matches[1] as $match) {
+ if (strstr($match, ']')) {
// we might be inside a bbcode color tag - leave it alone
continue;
}
- if(substr($mtch,-1,1) === '.')
- $ret[] = substr($mtch,0,-1);
- else
- $ret[] = $mtch;
+ if (substr($match, -1, 1) === '.') {
+ $ret[] = substr($match, 0, -1);
+ } else {
+ $ret[] = $match;
+ }
}
}
// Otherwise pull out single word tags. These can be @nickname, @first_last
// and #hash tags.
- if(preg_match_all('/([!#@][^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/',$s,$match)) {
- foreach($match[1] as $mtch) {
- if(strstr($mtch,"]")) {
+ if (preg_match_all('/([!#@][^\^ \x0D\x0A,;:?]+)([ \x0D\x0A,;:?]|$)/', $string, $matches)) {
+ foreach($matches[1] as $match) {
+ if (strstr($match, ']')) {
// we might be inside a bbcode color tag - leave it alone
continue;
}
- if(substr($mtch,-1,1) === '.')
- $mtch = substr($mtch,0,-1);
+ if (substr($match, -1, 1) === '.') {
+ $match = substr($match,0,-1);
+ }
// ignore strictly numeric tags like #1
- if((strpos($mtch,'#') === 0) && ctype_digit(substr($mtch,1)))
+ if ((strpos($match, '#') === 0) && ctype_digit(substr($match, 1))) {
continue;
+ }
// try not to catch url fragments
- if(strpos($s,$mtch) && preg_match('/[a-zA-z0-9\/]/',substr($s,strpos($s,$mtch)-1,1)))
+ if (strpos($string, $match) && preg_match('/[a-zA-z0-9\/]/', substr($string, strpos($string, $match) - 1, 1))) {
continue;
- $ret[] = $mtch;
+ }
+ $ret[] = $match;
}
}
return $ret;
-}}
+}
//
diff --git a/mod/ping.php b/mod/ping.php
index 8c28e74744..0ed7eb3fed 100644
--- a/mod/ping.php
+++ b/mod/ping.php
@@ -344,6 +344,12 @@ function ping_init(&$a) {
killme();
}
+/**
+ * @brief Retrieves the notifications array for the given user ID
+ *
+ * @param int $uid User id
+ * @return array Associative array of notifications
+ */
function ping_get_notifications($uid) {
$result = array();
@@ -372,46 +378,47 @@ function ping_get_notifications($uid) {
$seensql = "";
$order = "DESC";
$offset = 0;
- } elseif (!$r)
+ } elseif (!$r) {
$quit = true;
- else
+ } else {
$offset += 50;
-
+ }
foreach ($r AS $notification) {
- if (is_null($notification["visible"]))
+ if (is_null($notification["visible"])) {
$notification["visible"] = true;
+ }
- if (is_null($notification["spam"]))
+ if (is_null($notification["spam"])) {
$notification["spam"] = 0;
+ }
- if (is_null($notification["deleted"]))
+ if (is_null($notification["deleted"])) {
$notification["deleted"] = 0;
+ }
- $notification["message"] = strip_tags(bbcode($notification["msg"]));
- $notification["name"] = strip_tags(bbcode($notification["name"]));
+ if ($notification["msg_cache"]) {
+ $notification["name"] = $notification["name_cache"];
+ $notification["message"] = $notification["msg_cache"];
+ } else {
+ $notification["name"] = strip_tags(bbcode($notification["name"]));
+ $notification["message"] = format_notification_message($notification["name"], strip_tags(bbcode($notification["msg"])));
- // Replace the name with {0} but ensure to make that only once
- // The {0} is used later and prints the name in bold.
+ q("UPDATE `notify` SET `name_cache` = '%s', `msg_cache` = '%s' WHERE `id` = %d",
+ dbesc($notification["name"]),
+ dbesc($notification["message"]),
+ intval($notification["id"])
+ );
+ }
- if ($notification['name'] != "")
- $pos = strpos($notification["message"],$notification['name']);
- else
- $pos = false;
-
- if ($pos !== false)
- $notification["message"] = substr_replace($notification["message"],"{0}",$pos,strlen($notification["name"]));
-
- $notification['href'] = $a->get_baseurl() . '/notify/view/' . $notification['id'];
+ $notification["href"] = $a->get_baseurl() . "/notify/view/" . $notification["id"];
if ($notification["visible"] AND !$notification["spam"] AND
!$notification["deleted"] AND !is_array($result[$notification["parent"]])) {
$result[$notification["parent"]] = $notification;
}
}
-
} while ((count($result) < 50) AND !$quit);
-
return($result);
}
diff --git a/update.php b/update.php
index 5eab9c2207..fa03ddd1ac 100644
--- a/update.php
+++ b/update.php
@@ -1,6 +1,6 @@