Merge remote-tracking branch 'upstream/develop' into 1610-priority-dbclean

This commit is contained in:
Michael 2016-11-05 05:25:22 +00:00
commit 4b33573c20
23 changed files with 1581 additions and 1007 deletions

View file

@ -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 (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 ($ssl) {
$scheme = 'https';
else
} else {
$scheme = 'http';
}
}
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;
}
if (get_config('config', 'hostname') != '') {
$this->hostname = get_config('config', 'hostname');
}
$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'))
}
if (x($parsed, 'path')) {
$this->path = trim($parsed['path'], '\\/');
if (file_exists(".htpreconfig.php"))
@include(".htpreconfig.php");
if (get_config('config','hostname') != "")
$this->hostname = get_config('config','hostname');
if (!isset($this->hostname) OR ($this->hostname == ""))
$this->hostname = $hostname;
}
if (file_exists(".htpreconfig.php")) {
@include(".htpreconfig.php");
}
if (get_config('config', 'hostname') != '') {
$this->hostname = get_config('config', 'hostname');
}
if (!isset($this->hostname) OR ($this->hostname == '')) {
$this->hostname = $hostname;
}
}
}
function get_hostname() {

View file

@ -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;

View file

@ -1,187 +1,551 @@
Friendica BBCode tags reference
========================
* [Home](help)
* [Creating posts](help/Text_editor)
Inline
-----
## Inline
<style>
table.bbcodes {
margin: 1em 0;
background-color: #f9f9f9;
border: 1px solid #aaa;
border-collapse: collapse;
color: #000;
width: 100%;
}
<pre>[b]bold[/b]</pre> : <strong>bold</strong>
table.bbcodes > tr > th,
table.bbcodes > tr > td,
table.bbcodes > * > tr > th,
table.bbcodes > * > tr > td {
border: 1px solid #aaa;
padding: 0.2em 0.4em
}
<pre>[i]italic[/i]</pre> : <em>italic</em>
table.bbcodes > tr > th,
table.bbcodes > * > tr > th {
background-color: #f2f2f2;
text-align: center
}
</style>
<pre>[u]underlined[/u]</pre> : <u>underlined</u>
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[b]bold[/b]</td>
<td><strong>bold</strong></td>
</tr>
<tr>
<td>[i]italic[/i]</td>
<td><em>italic</em></td>
</tr>
<tr>
<td>[u]underlined[/u]</td>
<td><u>underlined</u></td>
</tr>
<tr>
<td>[s]strike[/s]</td>
<td><strike>strike</strike></td>
</tr>
<tr>
<td>[o]overline[/o]</td>
<td><span class="overline">overline</span></td>
</tr>
<tr>
<td>[color=red]red[/color]</td>
<td><span style="color: red;">red</span></td>
</tr>
<tr>
<td>[url=http://www.friendica.com]Friendica[/url]</td>
<td><a href="http://www.friendica.com" target="external-link">Friendica</a></td>
</tr>
<tr>
<td>[img]http://friendica.com/sites/default/files/friendika-32.png[/img]</td>
<td><img src="http://friendica.com/sites/default/files/friendika-32.png" alt="Immagine/foto"></td>
</tr>
<tr>
<td>[img=64x32]http://friendica.com/sites/default/files/friendika-32.png[/img]<br>
<br>Note: provided height is simply discarded.</td>
<td><img src="http://friendica.com/sites/default/files/friendika-32.png" style="width: 64px;"></td>
</tr>
<tr>
<td>[size=xx-small]small text[/size]</td>
<td><span style="font-size: xx-small;">small text</span></td>
</tr>
<tr>
<td>[size=xx-large]big text[/size]</td>
<td><span style="font-size: xx-large;">big text</span></td>
</tr>
<tr>
<td>[size=20]exact size[/size] (size can be any number, in pixel)</td>
<td><span style="font-size: 20px;">exact size</span></td>
</tr>
<tr>
<td>[font=serif]Serif font[/font]</td>
<td><span style="font-family: serif;">Serif font</span></td>
</tr>
</table>
<pre>[s]strike[/s]</pre> : <strike>strike</strike>
### Links
<pre>[color=red]red[/color]</pre> : <span style="color: red;">red</span>
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[url]http://friendica.com[/url]</td>
<td><a href="http://friendica.com">http://friendica.com</a></td>
</tr>
<tr>
<td>[url=http://friendica.com]Friendica[/url]</td>
<td><a href="http://friendica.com">Friendica</a></td>
</tr>
<tr>
<td>[bookmark]http://friendica.com[/bookmark]<br><br>
#^[url]http://friendica.com[/url]</td>
<td><span class="oembed link"><h4>Friendica: <a href="http://friendica.com" rel="oembed"></a><a href="http://friendica.com" target="_blank">http://friendica.com</a></h4></span></td>
</tr>
<tr>
<td>[bookmark=http://friendica.com]Bookmark[/bookmark]<br><br>
#^[url=http://friendica.com]Bookmark[/url]<br><br>
#[url=http://friendica.com]^[/url][url=http://friendica.com]Bookmark[/url]</td>
<td><span class="oembed link"><h4>Friendica: <a href="http://friendica.com" rel="oembed"></a><a href="http://friendica.com" target="_blank">Bookmark</a></h4></span></td>
</tr>
<tr>
<td>[url=/posts/f16d77b0630f0134740c0cc47a0ea02a]Diaspora post with GUID[/url]</td>
<td><a href="/display/f16d77b0630f0134740c0cc47a0ea02a" target="_blank">Diaspora post with GUID</a></td>
</tr>
<tr>
<td>#Friendica</td>
<td>#<a href="/search?tag=Friendica">Friendica</a></td>
</tr>
<tr>
<td>@Mention</td>
<td>@<a href="javascript:void(0)">Mention</a></td>
</tr>
<tr>
<td>acct:account@friendica.host.com (WebFinger)</td>
<td><a href="/acctlink?addr=account@friendica.host.com" target="extlink">acct:account@friendica.host.com</a></td>
</tr>
<tr>
<td>[mail]user@mail.example.com[/mail]</td>
<td><a href="mailto:user@mail.example.com">user@mail.example.com</a></td>
</tr>
<tr>
<td>[mail=user@mail.example.com]Send an email to User[/mail]</td>
<td><a href="mailto:user@mail.example.com">Send an email to User</a></td>
</tr>
</table>
<pre>[url=http://www.friendica.com]Friendica[/url]</pre> : <a href="http://www.friendica.com" target="external-link">Friendica</a>
## Blocks
<pre>[img]http://friendica.com/sites/default/files/friendika-32.png[/img]</pre> : <img src="http://friendica.com/sites/default/files/friendika-32.png" alt="Immagine/foto">
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[p]A paragraph of text[/p]</td>
<td><p>A paragraph of text</p></td>
</tr>
<tr>
<td>Inline [code]code[/code] in a paragraph</td>
<td>Inline <key>code</key> in a paragraph</td>
</tr>
<tr>
<td>[code]Multi<br>line<br>code[/code]</td>
<td><code>Multi
line
code</code></td>
</tr>
<tr>
<td>[code=php]function text_highlight($s,$lang)[/code]</td>
<td><code><div class="hl-main"><ol class="hl-main"><li><span class="hl-code">&nbsp;</span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">text_highlight</span><span class="hl-brackets">(</span><span class="hl-var">$s</span><span class="hl-code">,</span><span class="hl-var">$lang</span><span class="hl-brackets">)</span></li></ol></div></code></td>
</tr>
<tr>
<td>[quote]quote[/quote]</td>
<td><blockquote>quote</blockquote></td>
</tr>
<tr>
<td>[quote=Author]Author? Me? No, no, no...[/quote]</td>
<td><strong class="author">Author wrote:</strong><blockquote>Author? Me? No, no, no...</blockquote></td>
</tr>
<tr>
<td>[center]Centered text[/center]</td>
<td><div style="text-align:center;">Centered text</div></td>
</tr>
<tr>
<td>You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler]</td>
<td>
<div class="wall-item-container">
You should not read any further if you want to be surprised.<br>
<span id="spoiler-wrap-0716e642" class="spoiler-wrap fakelink" onclick="openClose('spoiler-0716e642');">Click to open/close</span>
<blockquote class="spoiler" id="spoiler-0716e642" style="display: none;">There is a happy end.</blockquote>
<div class="body-attach"><div class="clear"></div></div>
</div>
</td>
</tr>
<tr>
<td>[spoiler=Author]Spoiler quote[/spoiler]</td>
<td>
<div class="wall-item-container">
<strong class="spoiler">Author wrote:</strong><br>
<span id="spoiler-wrap-a893765a" class="spoiler-wrap fakelink" onclick="openClose('spoiler-a893765a');">Click to open/close</span>
<blockquote class="spoiler" id="spoiler-a893765a" style="display: none;">Spoiler quote</blockquote>
<div class="body-attach"><div class="clear"></div></div>
</div>
</td>
</tr>
<tr>
<td>[hr] (horizontal line)</td>
<td><hr></td>
</tr>
</table>
<pre>[size=xx-small]small text[/size]</pre> : <span style="font-size: xx-small;">small text</span>
### Titles
<pre>[size=xx-large]big text[/size]</pre> : <span style="font-size: xx-large;">big text</span>
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[h1]Title 1[/h1]</td>
<td><h1>Title 1</h1></td>
</tr>
<tr>
<td>[h2]Title 2[/h2]</td>
<td><h2>Title 2</h2></td>
</tr>
<tr>
<td>[h3]Title 3[/h3]</td>
<td><h3>Title 3</h3></td>
</tr>
<tr>
<td>[h4]Title 4[/h4]</td>
<td><h4>Title 4</h4></td>
</tr>
<tr>
<td>[h5]Title 5[/h5]</td>
<td><h5>Title 5</h5></td>
</tr>
<tr>
<td>[h6]Title 6[/h6]</td>
<td><h6>Title 6</h6></td>
</tr>
</table>
<pre>[size=20]exact size[/size] (size can be any number, in pixel)</pre> : <span style="font-size: 20px;">exact size</span>
### Tables
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[table]<br>
&nbsp;&nbsp;[tr]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[th]Header 1[/th]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[th]Header 2[/th]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[th]Header 2[/th]<br>
&nbsp;&nbsp;[/tr]<br>
&nbsp;&nbsp;[tr]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 1[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 2[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 3[/td]<br>
&nbsp;&nbsp;[/tr]<br>
&nbsp;&nbsp;[tr]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 4[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 5[/td]<br>
&nbsp;&nbsp;&nbsp;&nbsp;[td]Cell 6[/td]<br>
&nbsp;&nbsp;[/tr]<br>
[/table]</td>
<td>
<table>
<tbody>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</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>
</tbody>
</table>
</td>
</tr>
<tr>
<td>[table border=0]</td>
<td>
<table border="0">
<tbody>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</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>
</tbody>
</table>
</td>
</tr>
<tr>
<td>[table border=1]</td>
<td>
<table border="1">
<tbody>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</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>
</tbody>
</table>
</td>
</tr>
</table>
### Lists
Block
-----
<pre>[code]code[/code]</pre>
<code>code</code>
<p style="clear:both;">&nbsp;</p>
<pre>[code=php]function text_highlight($s,$lang)[/code]</pre>
<code><div class="hl-main"><ol class="hl-main"><li><span class="hl-code">&nbsp;</span><span class="hl-reserved">function</span><span class="hl-code"> </span><span class="hl-identifier">text_highlight</span><span class="hl-brackets">(</span><span class="hl-var">$s</span><span class="hl-code">,</span><span class="hl-var">$lang</span><span class="hl-brackets">)</span></li></ol></div></code>
<p style="clear:both;">&nbsp;</p>
<pre>[quote]quote[/quote]</pre>
<blockquote>quote</blockquote>
<p style="clear:both;">&nbsp;</p>
<pre>[quote=Author]Author? Me? No, no, no...[/quote]</pre>
<strong class="author">Author wrote:</strong><blockquote>Author? Me? No, no, no...</blockquote>
<p style="clear:both;">&nbsp;</p>
<pre>[center]centered text[/center]</pre>
<div style="text-align:center;">centered text</div>
<p style="clear:both;">&nbsp;</p>
<pre>You should not read any further if you want to be surprised.[spoiler]There is a happy end.[/spoiler]</pre>
You should not read any further if you want to be surprised.<br />*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.)
<p style="clear:both;">&nbsp;</p>
**Table**
<pre>[table border=1]
[tr]
[th]Tables now[/th]
[/tr]
[tr]
[td]Have headers[/td]
[/tr]
[/table]</pre>
<table border="1"><tbody><tr><th>Tables now</th></tr><tr><td>Have headers</td></tr></tbody></table>
<p style="clear:both;">&nbsp;</p>
**List**
<pre>[list]
[*] First list element
[*] Second list element
[/list]</pre>
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[ul]<br>
&nbsp;&nbsp;[li] First list element<br>
&nbsp;&nbsp;[li] Second list element<br>
[/ul]<br>
[list]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/list]</td>
<td>
<ul class="listbullet" style="list-style-type: circle;">
<li> First list element<br>
</li>
<li>First list element</li>
<li>Second list element</li>
</ul>
</td>
</tr>
<tr>
<td>[ol]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/ol]<br>
[list=1]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/list]</td>
<td>
<ul class="listdecimal" style="list-style-type: decimal;">
<li> First list element</li>
<li> Second list element</li>
</ul>
</td>
</tr>
<tr>
<td>[list=]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/list]</td>
<td>
<ul class="listnone" style="list-style-type: none;">
<li> First list element</li>
<li> Second list element</li>
</ul>
</td>
</tr>
<tr>
<td>[list=i]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/list]</td>
<td>
<ul class="listlowerroman" style="list-style-type: lower-roman;">
<li> First list element</li>
<li> Second list element</li>
</ul>
</td>
</tr>
<tr>
<td>[list=I]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/list]</td>
<td>
<ul class="listupperroman" style="list-style-type: upper-roman;">
<li> First list element</li>
<li> Second list element</li>
</ul>
</td>
</tr>
<tr>
<td>[list=a]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/list]</td>
<td>
<ul class="listloweralpha" style="list-style-type: lower-alpha;">
<li> First list element</li>
<li> Second list element</li>
</ul>
</td>
</tr>
<tr>
<td>[list=A]<br>
&nbsp;&nbsp;[*] First list element<br>
&nbsp;&nbsp;[*] Second list element<br>
[/list]</td>
<td>
<ul class="listupperalpha" style="list-style-type: upper-alpha;">
<li> First list element</li>
<li> Second list element</li>
</ul>
</td>
</tr>
</table>
[list] is equivalent to [ul] (unordered list).
[ol] can be used instead of [list] to show an ordered list:
<pre>[ol]
[*] First list element
[*] Second list element
[/ol]</pre>
<ul class="listdecimal" style="list-style-type: decimal;"><li> First list element<br></li><li> Second list element</li></ul>
For more options on ordered lists, you can define the style of numeration on [list] argument:
<pre>[list=1]</pre> : decimal
<pre>[list=i]</pre> : lover case roman
<pre>[list=I]</pre> : upper case roman
<pre>[list=a]</pre> : lover case alphabetic
<pre>[list=A] </pre> : upper case alphabetic
Embed
------
## Embed
You can embed video, audio and more in a message.
<pre>[video]url[/video]</pre>
<pre>[audio]url[/audio]</pre>
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[video]url[/video]</td>
<td>Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications.</td>
</tr>
<tr>
<td>[video]Video file url[/video]
[audio]Audio file url[/audio]</td>
<td>Full URL to an ogg/ogv/oga/ogm/webm/mp4/mp3 file. An HTML5 player will be used to show it.</td>
</tr>
<tr>
<td>[youtube]Youtube URL[/youtube]</td>
<td>Youtube video OEmbed display. May not embed an actual player.</td>
</tr>
<tr>
<td>[youtube]Youtube video ID[/youtube]</td>
<td>Youtube player iframe embed.</td>
</tr>
<tr>
<td>[vimeo]Vimeo URL[/vimeo]</td>
<td>Vimeo video OEmbed display. May not embed an actual player.</td>
</tr>
<tr>
<td>[vimeo]Vimeo video ID[/vimeo]</td>
<td>Vimeo player iframe embed.</td>
</tr>
<tr>
<td>[iframe]URL[/iframe]</td>
<td>General embed, iframe size is limited by the theme size for video players.</td>
</tr>
<tr>
<td>[url]*url*[/url]</td>
<td>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.</td>
</tr>
</table>
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
<pre>[url]*url*[/url]</pre>
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.
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[map]address[/map]</td>
<td>Embeds a map centered on this address.</td>
</tr>
<tr>
<td>[map=lat,long]</td>
<td>Embeds a map centered on those coordinates.</td>
</tr>
<tr>
<td>[map]</td>
<td>Embeds a map centered on the post's location.</td>
</tr>
</table>
Map
---
## Abstract for longer posts
<pre>[map]address[/map]</pre>
<pre>[map=lat,long]</pre>
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)
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.
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.
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.
Example:
<pre>[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.</pre>
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 ..."
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>[abstract]Totally interesting! A must-see! Please click the link![/abstract]<br>
I want to tell you a really boring story that you really never wanted to hear.</td>
<td>Twitter would display the text <blockquote>Totally interesting! A must-see! Please click the link!</blockquote>
On Friendica you would only see the text after <blockquote>I want to tell you a really ...</blockquote></td>
</tr>
</table>
It is even possible to define abstracts for separate networks:
<pre>
[abstract]Hi friends Here are my newest pictures![abstract]
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>
[abstract]Hi friends Here are my newest pictures![/abstract]<br>
[abstract=twit]Hi my dear Twitter followers. Do you want to see my new
pictures?[abstract]
pictures?[/abstract]<br>
[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 ...
</pre>
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.
that I wanted to share with you.[/abstract]<br>
Today I was in the woods and took some real cool pictures ...</td>
<td>For Twitter and App.net the system will use the defined abstracts.<br>
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.</td>
</tr>
</table>
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.
@ -189,20 +553,58 @@ 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:
<pre>
[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 ... </pre>
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>
[abstract]These days I had a strange encounter...[/abstract]<br>
[abstract=goog]Helly my dear Google+ followers. You have to read my newest blog post![/abstract]<br>
[abstract=face]Hello my Facebook friends. These days happened something really cool.[/abstract]<br>
While taking pictures in the woods I had a really strange encounter...</td>
<td>Google and Facebook will show the respective abstracts while the other networks will show the default one.<br>
<br>Meanwhile, Friendica won't show any of the abstracts.</td>
</tr>
</table>
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:
<pre>[noparse][b]bold[/b][/noparse]</pre> : [b]bold[/b]
<table class="bbcodes">
<tr>
<th>BBCode</th>
<th>Result</th>
</tr>
<tr>
<td>If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode:
<ul>
<li>[noparse][b]bold[/b][/noparse]</li>
<li>[nobb][b]bold[/b][/nobb]</li>
<li>[pre][b]bold[/b][/pre]</li>
</ul>
</td>
<td>[b]bold[/b]</td>
</tr>
<tr>
<td>[nosmile] is used to disable smilies on a post by post basis<br>
<br>
[nosmile] ;-) :-O
</td>
<td>;-) :-O</td>
</tr>
<tr>
<td>Custom inline styles<br>
<br>
[style=text-shadow: 0 0 4px #CC0000;]You can change all the CSS properties of this block.[/style]</td>
<td><span style="text-shadow: 0 0 4px #cc0000;;">You can change all the CSS properties of this block.</span></td>
</tr>
<tr>
<td>Custom class block<br>
<br>
[class=custom]If the class exists, this block will have the custom class style applied.[/class]</td>
<td><pre>&lt;span class="custom"&gt;If the class exists,<br> this block will have the custom class<br> style applied.&lt;/span&gt;</pre></td>
</tr>
</table>

View file

@ -2,7 +2,7 @@ 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 | |
@ -10,13 +10,15 @@ Table notify
| url | | varchar(255) | NO | | | |
| photo | | varchar(255) | NO | | | |
| date | | datetime | NO | | 0000-00-00 00:00:00 | |
| msg | | mediumtext | NO | | NULL | |
| 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 | | | |
| iid | item.id | int(11) | NO | | 0 | |
| 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)

View file

@ -1,11 +1,16 @@
<?php
/**
* @file include/Photo.php
* @brief This file contains the Photo class for image processing
*/
require_once("include/photos.php");
if(! class_exists("Photo")) {
class Photo {
private $image;
/**
/*
* Put back gd stuff, not everybody have Imagick
*/
private $imagick;
@ -16,14 +21,13 @@ class Photo {
private $types;
/**
* supported mimetypes and corresponding file extensions
* @brief supported mimetypes and corresponding file extensions
*/
static function supportedTypes() {
if (class_exists('Imagick')) {
/**
* Imagick::queryFormats won't help us a lot there...
* At least, not yet, other parts of friendica uses this array
*/
// Imagick::queryFormats won't help us a lot there...
// At least, not yet, other parts of friendica uses this array
$t = array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
@ -32,7 +36,9 @@ class Photo {
} else {
$t = array();
$t['image/jpeg'] ='jpg';
if (imagetypes() & IMG_PNG) $t['image/png'] = 'png';
if (imagetypes() & IMG_PNG) {
$t['image/png'] = 'png';
}
}
return $t;
@ -71,7 +77,8 @@ class Photo {
}
/**
* Maps Mime types to Imagick formats
* @brief Maps Mime types to Imagick formats
* @return arr With with image formats (mime type as key)
*/
public function get_FormatsMap() {
$m = array(
@ -87,13 +94,12 @@ class Photo {
$this->image = new Imagick();
try {
$this->image->readImageBlob($data);
}
catch (Exception $e) {
} catch (Exception $e) {
// Imagick couldn't use the data
return false;
}
/**
/*
* Setup the image to the format it will be saved to
*/
$map = $this->get_FormatsMap();
@ -103,15 +109,16 @@ class Photo {
// Always coalesce, if it is not a multi-frame image it won't hurt anyway
$this->image = $this->image->coalesceImages();
/**
/*
* setup the compression here, so we'll do it only once
*/
switch($this->getType()){
case "image/png":
$quality = get_config('system', 'png_quality');
if((! $quality) || ($quality > 9))
if ((! $quality) || ($quality > 9)) {
$quality = PNG_QUALITY;
/**
}
/*
* From http://www.imagemagick.org/script/command-line-options.php#quality:
*
* 'For the MNG and PNG image formats, the quality value sets
@ -124,8 +131,9 @@ class Photo {
break;
case "image/jpeg":
$quality = get_config('system', 'jpeg_quality');
if((! $quality) || ($quality > 100))
if ((! $quality) || ($quality > 100)) {
$quality = JPEG_QUALITY;
}
$this->image->setCompressionQuality($quality);
}
@ -139,7 +147,7 @@ class Photo {
$this->valid = false;
$this->image = @imagecreatefromstring($data);
if($this->image !== FALSE) {
if ($this->image !== false) {
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
$this->valid = true;
@ -153,32 +161,38 @@ class Photo {
}
public function is_valid() {
if($this->is_imagick())
return ($this->image !== FALSE);
if ($this->is_imagick()) {
return ($this->image !== false);
}
return $this->valid;
}
public function getWidth() {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if($this->is_imagick())
if ($this->is_imagick()) {
return $this->image->getImageWidth();
}
return $this->width;
}
public function getHeight() {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if($this->is_imagick())
if ($this->is_imagick()) {
return $this->image->getImageHeight();
}
return $this->height;
}
public function getImage() {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if ($this->is_imagick()) {
/* Clean it */
@ -189,30 +203,34 @@ class Photo {
}
public function getType() {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
return $this->type;
}
public function getExt() {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
return $this->types[$this->getType()];
}
public function scaleImage($max) {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
$width = $this->getWidth();
$height = $this->getHeight();
$dest_width = $dest_height = 0;
if((! $width)|| (! $height))
return FALSE;
if ((! $width)|| (! $height)) {
return false;
}
if ($width > $max && $height > $max) {
@ -222,25 +240,19 @@ class Photo {
if ((($height * 9) / 16) > $width) {
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
}
} elseif ($width > $height) {
// else constrain both dimensions
elseif($width > $height) {
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
}
else {
} else {
$dest_width = intval(($width * $max) / $height);
$dest_height = $max;
}
}
else {
} else {
if ($width > $max) {
$dest_width = $max;
$dest_height = intval(($height * $max) / $width);
}
else {
} else {
if ($height > $max) {
// very tall image (greater than 16:9)
@ -249,13 +261,11 @@ class Photo {
if ((($height * 9) / 16) > $width) {
$dest_width = $width;
$dest_height = $height;
}
else {
} else {
$dest_width = intval(($width * $max) / $height);
$dest_height = $max;
}
}
else {
} else {
$dest_width = $width;
$dest_height = $height;
}
@ -264,7 +274,7 @@ class Photo {
if ($this->is_imagick()) {
/**
/*
* If it is not animated, there will be only one iteration here,
* so don't bother checking
*/
@ -289,18 +299,22 @@ class Photo {
$dest = imagecreatetruecolor($dest_width, $dest_height);
imagealphablending($dest, false);
imagesavealpha($dest, true);
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
if ($this->type=='image/png') {
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
}
imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
if($this->image)
if ($this->image) {
imagedestroy($this->image);
}
$this->image = $dest;
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
}
public function rotate($degrees) {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if ($this->is_imagick()) {
$this->image->setFirstIterator();
@ -316,14 +330,19 @@ class Photo {
}
public function flip($horiz = true, $vert = false) {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if ($this->is_imagick()) {
$this->image->setFirstIterator();
do {
if($horiz) $this->image->flipImage();
if($vert) $this->image->flopImage();
if ($horiz) {
$this->image->flipImage();
}
if ($vert) {
$this->image->flopImage();
}
} while ($this->image->nextImage());
return;
}
@ -361,19 +380,22 @@ class Photo {
}
$this->image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
return TRUE;
return true;
}
// based off comment on http://php.net/manual/en/function.imagerotate.php
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if( (! function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg') )
if ((!function_exists('exif_read_data')) || ($this->getType() !== 'image/jpeg')) {
return;
}
$exif = @exif_read_data($filename,null,true);
if(! $exif)
if (!$exif) {
return;
}
$ort = $exif['IFD0']['Orientation'];
@ -421,8 +443,9 @@ class Photo {
public function scaleImageUp($min) {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
$width = $this->getWidth();
@ -430,46 +453,47 @@ class Photo {
$dest_width = $dest_height = 0;
if((! $width)|| (! $height))
return FALSE;
if ((!$width)|| (!$height)) {
return false;
}
if ($width < $min && $height < $min) {
if ($width > $height) {
$dest_width = $min;
$dest_height = intval(($height * $min) / $width);
}
else {
} else {
$dest_width = intval(($width * $min) / $height);
$dest_height = $min;
}
}
else {
} else {
if ($width < $min) {
$dest_width = $min;
$dest_height = intval(($height * $min) / $width);
}
else {
} else {
if ($height < $min) {
$dest_width = intval(($width * $min) / $height);
$dest_height = $min;
}
else {
} else {
$dest_width = $width;
$dest_height = $height;
}
}
}
if($this->is_imagick())
if ($this->is_imagick()) {
return $this->scaleImage($dest_width, $dest_height);
}
$dest = imagecreatetruecolor($dest_width, $dest_height);
imagealphablending($dest, false);
imagesavealpha($dest, true);
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
if ($this->type=='image/png') {
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
}
imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dest_width, $dest_height, $width, $height);
if($this->image)
if ($this->image) {
imagedestroy($this->image);
}
$this->image = $dest;
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
@ -478,8 +502,9 @@ class Photo {
public function scaleImageSquare($dim) {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if ($this->is_imagick()) {
$this->image->setFirstIterator();
@ -492,10 +517,13 @@ class Photo {
$dest = imagecreatetruecolor($dim, $dim);
imagealphablending($dest, false);
imagesavealpha($dest, true);
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
if ($this->type=='image/png') {
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
}
imagecopyresampled($dest, $this->image, 0, 0, 0, 0, $dim, $dim, $this->width, $this->height);
if($this->image)
if ($this->image) {
imagedestroy($this->image);
}
$this->image = $dest;
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
@ -503,14 +531,15 @@ class Photo {
public function cropImage($max, $x, $y, $w, $h) {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if ($this->is_imagick()) {
$this->image->setFirstIterator();
do {
$this->image->cropImage($w, $h, $x, $y);
/**
/*
* We need to remove the canva,
* or the image is not resized to the crop:
* http://php.net/manual/en/imagick.cropimage.php#97232
@ -523,18 +552,22 @@ class Photo {
$dest = imagecreatetruecolor($max, $max);
imagealphablending($dest, false);
imagesavealpha($dest, true);
if ($this->type=='image/png') imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
if ($this->type=='image/png') {
imagefill($dest, 0, 0, imagecolorallocatealpha($dest, 0, 0, 0, 127)); // fill with alpha
}
imagecopyresampled($dest, $this->image, 0, 0, $x, $y, $max, $max, $w, $h);
if($this->image)
if ($this->image) {
imagedestroy($this->image);
}
$this->image = $dest;
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
}
public function saveImage($path) {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
$string = $this->imageString();
@ -546,8 +579,9 @@ class Photo {
}
public function imageString() {
if(!$this->is_valid())
return FALSE;
if (!$this->is_valid()) {
return false;
}
if ($this->is_imagick()) {
/* Clean it */
@ -556,7 +590,7 @@ class Photo {
return $string;
}
$quality = FALSE;
$quality = false;
ob_start();
@ -566,15 +600,17 @@ class Photo {
switch($this->getType()){
case "image/png":
$quality = get_config('system', 'png_quality');
if((! $quality) || ($quality > 9))
if ((!$quality) || ($quality > 9)) {
$quality = PNG_QUALITY;
imagepng($this->image,NULL, $quality);
}
imagepng($this->image, null, $quality);
break;
case "image/jpeg":
$quality = get_config('system', 'jpeg_quality');
if((! $quality) || ($quality > 100))
if ((!$quality) || ($quality > 100)) {
$quality = JPEG_QUALITY;
imagejpeg($this->image,NULL,$quality);
}
imagejpeg($this->image, null, $quality);
}
$string = ob_get_contents();
ob_end_clean();
@ -586,23 +622,24 @@ class Photo {
public function store($uid, $cid, $rid, $filename, $album, $scale, $profile = 0, $allow_cid = '', $allow_gid = '', $deny_cid = '', $deny_gid = '') {
$r = q("select `guid` from photo where `resource-id` = '%s' and `guid` != '' limit 1",
$r = q("SELECT `guid` FROM `photo` WHERE `resource-id` = '%s' AND `guid` != '' LIMIT 1",
dbesc($rid)
);
if(count($r))
if (dbm::is_result($r)) {
$guid = $r[0]['guid'];
else
} else {
$guid = get_guid();
}
$x = q("select id from photo where `resource-id` = '%s' and uid = %d and `contact-id` = %d and `scale` = %d limit 1",
$x = q("SELECT `id` FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d AND `contact-id` = %d AND `scale` = %d LIMIT 1",
dbesc($rid),
intval($uid),
intval($cid),
intval($scale)
);
if(count($x)) {
if (dbm::is_result($x)) {
$r = q("UPDATE `photo`
set `uid` = %d,
SET `uid` = %d,
`contact-id` = %d,
`guid` = '%s',
`resource-id` = '%s',
@ -621,7 +658,7 @@ class Photo {
`allow_gid` = '%s',
`deny_cid` = '%s',
`deny_gid` = '%s'
where id = %d",
WHERE `id` = %d",
intval($uid),
intval($cid),
@ -644,8 +681,7 @@ class Photo {
dbesc($deny_gid),
intval($x[0]['id'])
);
}
else {
} else {
$r = q("INSERT INTO `photo`
(`uid`, `contact-id`, `guid`, `resource-id`, `created`, `edited`, `filename`, type, `album`, `height`, `width`, `datasize`, `data`, `scale`, `profile`, `allow_cid`, `allow_gid`, `deny_cid`, `deny_gid`)
VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, '%s', %d, %d, '%s', '%s', '%s', '%s')",
@ -678,7 +714,7 @@ class Photo {
return $r;
}
}}
}
/**
@ -717,7 +753,9 @@ function guess_image_type($filename, $fromcurl=false) {
$types = Photo::supportedTypes();
$type = "image/jpeg";
foreach ($types as $m => $e){
if ($ext==$e) $type = $m;
if ($ext == $e) {
$type = $m;
}
}
}
}
@ -739,10 +777,11 @@ function guess_image_type($filename, $fromcurl=false) {
function update_contact_avatar($avatar, $uid, $cid, $force = false) {
$r = q("SELECT `avatar`, `photo`, `thumb`, `micro` FROM `contact` WHERE `id` = %d LIMIT 1", intval($cid));
if (!$r)
if (!dbm::is_result($r)) {
return false;
else
} else {
$data = array($r[0]["photo"], $r[0]["thumb"], $r[0]["micro"]);
}
if (($r[0]["avatar"] != $avatar) OR $force) {
$photos = import_profile_photo($avatar, $uid, $cid, true);
@ -762,11 +801,11 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) {
$a = get_app();
$r = q("select `resource-id` from photo where `uid` = %d and `contact-id` = %d and `scale` = 4 and `album` = 'Contact Photos' limit 1",
$r = q("SELECT `resource-id` FROM `photo` WHERE `uid` = %d AND `contact-id` = %d AND `scale` = 4 AND `album` = 'Contact Photos' LIMIT 1",
intval($uid),
intval($cid)
);
if(count($r) && strlen($r[0]['resource-id'])) {
if (dbm::is_result($r) && strlen($r[0]['resource-id'])) {
$hash = $r[0]['resource-id'];
} else {
$hash = photo_new_resource();
@ -777,8 +816,9 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) {
$filename = basename($photo);
$img_str = fetch_url($photo, true);
if ($quit_on_error AND ($img_str == ""))
if ($quit_on_error AND ($img_str == "")) {
return false;
}
$type = guess_image_type($photo, true);
$img = new Photo($img_str, $type);
@ -802,17 +842,20 @@ function import_profile_photo($photo,$uid,$cid, $quit_on_error = false) {
$r = $img->store($uid, $cid, $hash, $filename, 'Contact Photos', 6);
if($r === false)
if ($r === false) {
$photo_failure = true;
}
$photo = $a->get_baseurl() . '/photo/' . $hash . '-4.' . $img->getExt();
$thumb = $a->get_baseurl() . '/photo/' . $hash . '-5.' . $img->getExt();
$micro = $a->get_baseurl() . '/photo/' . $hash . '-6.' . $img->getExt();
} else
} else {
$photo_failure = true;
}
if($photo_failure AND $quit_on_error)
if ($photo_failure AND $quit_on_error) {
return false;
}
if ($photo_failure) {
$photo = $a->get_baseurl() . '/images/person-175.jpg';
@ -829,17 +872,13 @@ function get_photo_info($url) {
$data = Cache::get($url);
// Unserialise to be able to check in the next step if the cached data is alright.
if (!is_null($data))
$data = unserialize($data);
if (is_null($data) OR !$data) {
$img_str = fetch_url($url, true, $redirects, 4);
$filesize = strlen($img_str);
if (function_exists("getimagesizefromstring"))
if (function_exists("getimagesizefromstring")) {
$data = getimagesizefromstring($img_str);
else {
} else {
$tempfile = tempnam(get_temppath(), "cache");
$a = get_app();
@ -851,10 +890,11 @@ function get_photo_info($url) {
unlink($tempfile);
}
if ($data)
if ($data) {
$data["size"] = $filesize;
}
Cache::set($url, serialize($data));
Cache::set($url, $data);
}
return $data;
@ -864,8 +904,9 @@ function scale_image($width, $height, $max) {
$dest_width = $dest_height = 0;
if((!$width) || (!$height))
return FALSE;
if ((!$width) || (!$height)) {
return false;
}
if ($width > $max && $height > $max) {
@ -911,10 +952,10 @@ function scale_image($width, $height, $max) {
function store_photo($a, $uid, $imagedata = "", $url = "") {
$r = q("SELECT `user`.`nickname`, `user`.`page-flags`, `contact`.`id` FROM `user` INNER JOIN `contact` on `user`.`uid` = `contact`.`uid`
WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1",
WHERE `user`.`uid` = %d AND `user`.`blocked` = 0 AND `contact`.`self` = 1 LIMIT 1",
intval($uid));
if(!count($r)) {
if (!dbm::is_result($r)) {
logger("Can't detect user data for uid ".$uid, LOGGER_DEBUG);
return(array());
}
@ -982,10 +1023,12 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
unlink($tempfile);
$max_length = get_config('system', 'max_image_length');
if(! $max_length)
if (! $max_length) {
$max_length = MAX_IMAGE_LENGTH;
if($max_length > 0)
}
if ($max_length > 0) {
$ph->scaleImage($max_length);
}
$width = $ph->getWidth();
$height = $ph->getHeight();
@ -1009,44 +1052,50 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
$image = array("page" => $a->get_baseurl().'/photos/'.$page_owner_nick.'/image/'.$hash,
"full" => $a->get_baseurl()."/photo/{$hash}-0.".$ph->getExt());
if($width > 800 || $height > 800)
if ($width > 800 || $height > 800) {
$image["large"] = $a->get_baseurl()."/photo/{$hash}-0.".$ph->getExt();
}
if ($width > 640 || $height > 640) {
$ph->scaleImage(640);
$r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 1, 0, $defperm);
if($r)
if ($r) {
$image["medium"] = $a->get_baseurl()."/photo/{$hash}-1.".$ph->getExt();
}
}
if ($width > 320 || $height > 320) {
$ph->scaleImage(320);
$r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 2, 0, $defperm);
if($r)
if ($r) {
$image["small"] = $a->get_baseurl()."/photo/{$hash}-2.".$ph->getExt();
}
}
if ($width > 160 AND $height > 160) {
$x = 0;
$y = 0;
$min = $ph->getWidth();
if ($min > 160)
if ($min > 160) {
$x = ($min - 160) / 2;
}
if ($ph->getHeight() < $min) {
$min = $ph->getHeight();
if ($min > 160)
if ($min > 160) {
$y = ($min - 160) / 2;
}
}
$min = 160;
$ph->cropImage(160, $x, $y, $min, $min);
$r = $ph->store($uid, $visitor, $hash, $tempfile, t('Wall Photos'), 3, 0, $defperm);
if($r)
if ($r) {
$image["thumb"] = $a->get_baseurl()."/photo/{$hash}-3.".$ph->getExt();
}
}
// Set the full image as preview image. This will be overwritten, if the picture is larger than 640.
$image["preview"] = $image["full"];
@ -1059,39 +1108,9 @@ function store_photo($a, $uid, $imagedata = "", $url = "") {
//if (isset($image["small"]))
// $image["preview"] = $image["small"];
if (isset($image["medium"]))
if (isset($image["medium"])) {
$image["preview"] = $image["medium"];
}
return($image);
}
/**
* @brief Fetch the photo albums that are available for a viewer
*
* The query in this function is cost intensive, so it is cached.
*
* @param int $uid User id of the photos
* @param bool $update Update the cache
*
* @return array Returns array of the photo albums
*/
function photo_albums($uid, $update = false) {
$sql_extra = permissions_sql($uid);
$key = "photo_albums:".$uid.":".local_user().":".remote_user();
$albums = Cache::get($key);
if (is_null($albums) OR $update) {
/// @todo This query needs to be renewed. It is really slow
// At this time we just store the data in the cache
$albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`
FROM `photo` USE INDEX (`uid_album_created`)
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra
GROUP BY `album` ORDER BY `created` DESC",
intval($uid),
dbesc('Contact Photos'),
dbesc(t('Contact Photos'))
);
Cache::set($key, $albums, CACHE_DAY);
}
return $albums;
}

View file

@ -217,7 +217,6 @@ class Probe {
if ($cache) {
$result = Cache::get("probe_url:".$network.":".$uri);
if (!is_null($result)) {
$result = unserialize($result);
return $result;
}
}
@ -257,7 +256,7 @@ class Probe {
// Only store into the cache if the value seems to be valid
if (!in_array($data['network'], array(NETWORK_PHANTOM, NETWORK_MAIL))) {
Cache::set("probe_url:".$network.":".$uri,serialize($data), CACHE_DAY);
Cache::set("probe_url:".$network.":".$uri, $data, CACHE_DAY);
/// @todo temporary fix - we need a real contact update function that updates only changing fields
/// The biggest problem is the avatar picture that could have a reduced image size.

View file

@ -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:(.*?)@(.*?)([ ,])/', '<a href="' . $a->get_baseurl() . '/acctlink?addr=' . "$1@$2"
. '" target="extlink" >acct:' . "$1@$2$3" . '</a>',$Text);
$Text = preg_replace('/acct:([^@]+)@((?!\-)(?:[a-zA-Z\d\-]{0,62}[a-zA-Z\d]\.){1,126}(?!\d+)[a-zA-Z\d]{1,63})/', '<a href="' . $a->get_baseurl() . '/acctlink?addr=$1@$2" target="extlink">acct:$1@$2</a>',$Text);
// Perform MAIL Search
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);

View file

@ -99,8 +99,8 @@ class Cache {
dbesc($key)
);
if (count($r)) {
return $r[0]['v'];
if (dbm::is_result($r)) {
return unserialize($r[0]['v']);
}
return null;
@ -109,6 +109,8 @@ class Cache {
/**
* @brief Put data in the cache according to the key
*
* The input $value can have multiple formats.
*
* @param string $key The key to the cached data
* @param mixed $valie The value that is about to be stored
* @param integer $duration The cache lifespan
@ -126,7 +128,7 @@ class Cache {
/// @todo store the cache data in the same way like the config data
q("REPLACE INTO `cache` (`k`,`v`,`expire_mode`,`updated`) VALUES ('%s','%s',%d,'%s')",
dbesc($key),
dbesc($value),
dbesc(serialize($value)),
intval($duration),
dbesc(datetime_convert()));
}

View file

@ -11,6 +11,7 @@ if (!file_exists("boot.php") AND (sizeof($_SERVER["argv"]) != 0)) {
}
require_once("boot.php");
require_once("include/photos.php");
function cron_run(&$argv, &$argc){
@ -155,8 +156,9 @@ function cron_run(&$argv, &$argc){
*/
function cron_update_photo_albums() {
$r = q("SELECT `uid` FROM `user` WHERE NOT `account_expired` AND NOT `account_removed`");
if (!dbm::is_result($r))
if (!dbm::is_result($r)) {
return;
}
foreach ($r AS $user) {
photo_albums($user['uid'], true);

View file

@ -325,7 +325,7 @@ 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()
* <tt>%1$d %2$s ago</tt>, e.g. 22 hours ago, 1 minute ago
*
@ -333,7 +333,7 @@ function datetimesel($format, $min, $max, $default, $label, $id = 'datetimepicke
*/
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,8 +361,9 @@ 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]));
}

View file

@ -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"),

View file

@ -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;
}

View file

@ -39,14 +39,13 @@ function gprobe_run(&$argv, &$argc){
logger("gprobe start for ".normalise_link($url), LOGGER_DEBUG);
if (!count($r)) {
if (!dbm::is_result($r)) {
// Is it a DDoS attempt?
$urlparts = parse_url($url);
$result = Cache::get("gprobe:".$urlparts["host"]);
if (!is_null($result)) {
$result = unserialize($result);
if (in_array($result["network"], array(NETWORK_FEED, NETWORK_PHANTOM))) {
logger("DDoS attempt detected for ".$urlparts["host"]." by ".$_SERVER["REMOTE_ADDR"].". server data: ".print_r($_SERVER, true), LOGGER_DEBUG);
return;
@ -56,7 +55,7 @@ function gprobe_run(&$argv, &$argc){
$arr = probe_url($url);
if (is_null($result))
Cache::set("gprobe:".$urlparts["host"],serialize($arr));
Cache::set("gprobe:".$urlparts["host"], $arr);
if (!in_array($arr["network"], array(NETWORK_FEED, NETWORK_PHANTOM)))
update_gcontact($arr);
@ -65,7 +64,7 @@ function gprobe_run(&$argv, &$argc){
dbesc(normalise_link($url))
);
}
if(count($r)) {
if(dbm::is_result($r)) {
// Check for accessibility and do a poco discovery
if (poco_last_updated($r[0]['url'], true) AND ($r[0]["network"] == NETWORK_DFRN))
poco_load(0,0,$r[0]['id'], str_replace('/profile/','/poco/',$r[0]['url']));

View file

@ -6,7 +6,15 @@ function oembed_replacecb($matches){
return $s;
}
/**
* @brief Get data from an URL to embed its content.
*
* @param string $embedurl The URL from which the data should be fetched.
* @param bool $no_rich_type If set to true rich type content won't be fetched.
*
* @return bool|object Returns object with embed content or false if no embedable
* content exists
*/
function oembed_fetch_url($embedurl, $no_rich_type = false){
$embedurl = trim($embedurl, "'");
$embedurl = trim($embedurl, '"');
@ -16,11 +24,11 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
$r = q("SELECT * FROM `oembed` WHERE `url` = '%s'",
dbesc(normalise_link($embedurl)));
if ($r)
if (dbm::is_result($r)) {
$txt = $r[0]["content"];
else
} else {
$txt = Cache::get($a->videowidth . $embedurl);
}
// These media files should now be caught in bbcode.php
// left here as a fallback in case this is called from another source
@ -34,7 +42,7 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
if (!in_array($ext, $noexts)){
// try oembed autodiscovery
$redirects = 0;
$html_text = fetch_url($embedurl, false, $redirects, 15, "text/*"); /**/
$html_text = fetch_url($embedurl, false, $redirects, 15, "text/*");
if ($html_text) {
$dom = @DOMDocument::loadHTML($html_text);
if ($dom) {
@ -70,16 +78,17 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
$txt=trim($txt);
if ($txt[0]!="{")
if ($txt[0]!="{") {
$txt='{"type":"error"}';
else { //save in cache
} else { //save in cache
$j = json_decode($txt);
if ($j->type != "error")
if ($j->type != "error") {
q("INSERT INTO `oembed` (`url`, `content`, `created`) VALUES ('%s', '%s', '%s')
ON DUPLICATE KEY UPDATE `content` = '%s', `created` = '%s'",
dbesc(normalise_link($embedurl)),
dbesc($txt), dbesc(datetime_convert()),
dbesc($txt), dbesc(datetime_convert()));
}
Cache::set($a->videowidth.$embedurl, $txt, CACHE_DAY);
}
@ -87,13 +96,15 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
$j = json_decode($txt);
if (!is_object($j))
if (!is_object($j)) {
return false;
}
// Always embed the SSL version
if (isset($j->html))
if (isset($j->html)) {
$j->html = str_replace(array("http://www.youtube.com/", "http://player.vimeo.com/"),
array("https://www.youtube.com/", "https://player.vimeo.com/"), $j->html);
}
$j->embedurl = $embedurl;
@ -109,11 +120,13 @@ function oembed_fetch_url($embedurl, $no_rich_type = false){
//$j->height = $data["images"][0]["height"];
}
if (isset($data["title"]))
if (isset($data["title"])) {
$j->title = $data["title"];
}
if (isset($data["text"]))
if (isset($data["text"])) {
$j->description = $data["text"];
}
if (is_array($data["images"])) {
$j->thumbnail_url = $data["images"][0]["src"];

View file

@ -25,3 +25,34 @@ function gps2Num($coordPart) {
return floatval($parts[0]) / floatval($parts[1]);
}
/**
* @brief Fetch the photo albums that are available for a viewer
*
* The query in this function is cost intensive, so it is cached.
*
* @param int $uid User id of the photos
* @param bool $update Update the cache
*
* @return array Returns array of the photo albums
*/
function photo_albums($uid, $update = false) {
$sql_extra = permissions_sql($uid);
$key = "photo_albums:".$uid.":".local_user().":".remote_user();
$albums = Cache::get($key);
if (is_null($albums) OR $update) {
/// @todo This query needs to be renewed. It is really slow
// At this time we just store the data in the cache
$albums = qu("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`
FROM `photo` USE INDEX (`uid_album_created`)
WHERE `uid` = %d AND `album` != '%s' AND `album` != '%s' $sql_extra
GROUP BY `album` ORDER BY `created` DESC",
intval($uid),
dbesc('Contact Photos'),
dbesc(t('Contact Photos'))
);
Cache::set($key, $albums, CACHE_DAY);
}
return $albums;
}

View file

@ -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;
}

View file

@ -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;
}}
}
//

View file

@ -21,8 +21,6 @@ function photos_init(&$a) {
nav_set_selected('home');
$o = '';
if ($a->argc > 1) {
$nick = $a->argv[1];
$user = qu("SELECT * FROM `user` WHERE `nickname` = '%s' AND `blocked` = 0 LIMIT 1",

View file

@ -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"]));
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);
}

View file

@ -1,6 +1,6 @@
<?php
define('UPDATE_VERSION' , 1207);
define('UPDATE_VERSION' , 1208);
/**
*

View file

@ -27,6 +27,10 @@ a.btn, a.btn:hover {
background-color: #2d2d2d;
}
.overline {
text-decoration: overline;
}
/* List of social Networks */
img.connector, img.connector-disabled {
height: 40px;

View file

@ -38,6 +38,18 @@ body a {
color: $link_color;
text-decoration: none;
}
/* Anchors incorrectly display with a fixed top menu. This global rule offsets all
* anchors so that accessing them with a # link will actually scroll the associated
* content in the visible part of the page.
*
* anchor.top should be the opposite of body.padding-top
*/
body a[name]:not([href]) {
display: block;
position: relative;
top: -110px;
visibility: hidden;
}
body a:hover, body a:focus, body a:active, body a.active, body .btn-link:hover{
/*color: #59d6e4;*/

View file

@ -57,7 +57,9 @@ as the value of $top_child_total (this is done at the end of this file)
<!-- TODO => Unknow block -->
<div class="wall-item-decor" style="display:none;">
{{if $item.star}}
<span class="icon s22 star {{$item.isstarred}}" id="starred-{{$item.id}}" title="{{$item.star.starred}}">{{$item.star.starred}}</span>
{{/if}}
{{if $item.lock}}<span class="navicon lock fakelink" onclick="lockview(event,{{$item.id}});" title="{{$item.lock}}"></span><span class="fa fa-lock"></span>{{/if}}
<img id="like-rotator-{{$item.id}}" class="like-rotator" src="images/rotator.gif" alt="{{$item.wait}}" title="{{$item.wait}}" style="display: none;" />
</div>