Merge remote-tracking branch 'friendika/master' into newacl
This commit is contained in:
commit
020deefba6
61
LICENSE
61
LICENSE
|
@ -1,42 +1,25 @@
|
||||||
* Friendika
|
The Friendika project is distributed under the following license terms:
|
||||||
* Copyright (c) 2010, 2011 Mike Macgirvin
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* * Neither the name of Friendika nor the
|
|
||||||
* names of its contributors may be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY Mike Macgirvin ``AS IS'' AND ANY
|
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
* DISCLAIMED. IN NO EVENT SHALL Mike Macgirvin BE LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
Friendika incorporates other software which may be licensed under different
|
* This software is provided for any use with no license terms or restrictions.
|
||||||
terms and conditions. Some system libraries which are supplied with and
|
|
||||||
incorporated into Friendika were provided by their respective authors under
|
No guarantee is provided. Use at your own risk.
|
||||||
the LGPL (Lesser GNU Public License) and may result in legal encumberance if
|
|
||||||
you make any code changes to these libraries.
|
Components packaged with this software may fall under different license terms.
|
||||||
|
|
||||||
|
cropper - BSD
|
||||||
|
TwitterOAuth - BSD
|
||||||
|
markdown - BSD
|
||||||
|
slinky - BSD
|
||||||
|
ajax-upload - MIT
|
||||||
|
simplepie - MIT
|
||||||
|
LightOpenID - MIT
|
||||||
|
HTML5 - MIT
|
||||||
|
jQuery - MIT
|
||||||
|
TinyMCE - LGPL
|
||||||
|
phpsec - LGPL
|
||||||
|
HTMLPurifer - LGPL
|
||||||
|
Facebook SDK - Apache
|
||||||
|
|
||||||
|
Addons, plugins, and themes may also be provided under their own license terms.
|
||||||
|
|
||||||
Addon or "plugin" modules (projects by other authors and fully contained within
|
|
||||||
the 'addon' and 'theme' directories) are licensed under terms provided by the
|
|
||||||
respective software author or authors of those works, and MAY include copyleft
|
|
||||||
licenses such as GPLv3, AGPL, and/or commercial licenses. For the purposes of
|
|
||||||
licensing, addon modules and themes are considered separate standalone works,
|
|
||||||
where the "work as a whole" is defined as the embodiment of the theme or
|
|
||||||
addon module.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
|
|
||||||
Friendika addons/plugins license terms are under the control of the project
|
Friendika addons/plugins license terms are under the control of the project
|
||||||
author or authors.
|
author or authors.
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@ Installing the Friendika/Facebook connector
|
||||||
$a->config['facebook']['appid'] = 'xxxxxxxxxxx';
|
$a->config['facebook']['appid'] = 'xxxxxxxxxxx';
|
||||||
$a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
|
$a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
|
||||||
Replace with the settings Facebook gives you.
|
Replace with the settings Facebook gives you.
|
||||||
|
d. Navigate to Set Web->Site URL & Domain -> Website Settings. Set Site URL
|
||||||
|
to yoursubdomain.yourdomain.com. Set Site Domain to your yourdomain.com.
|
||||||
2. Enable the facebook plugin by including it in .htconfig.php - e.g.
|
2. Enable the facebook plugin by including it in .htconfig.php - e.g.
|
||||||
$a->config['system']['addon'] = 'plugin1,plugin2,facebook';
|
$a->config['system']['addon'] = 'plugin1,plugin2,facebook';
|
||||||
3. Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
|
3. Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
* $a->config['facebook']['appid'] = 'xxxxxxxxxxx';
|
* $a->config['facebook']['appid'] = 'xxxxxxxxxxx';
|
||||||
* $a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
|
* $a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
|
||||||
* Replace with the settings Facebook gives you.
|
* Replace with the settings Facebook gives you.
|
||||||
|
* d. Navigate to Set Web->Site URL & Domain -> Website Settings. Set
|
||||||
|
* Site URL to yoursubdomain.yourdomain.com. Set Site Domain to your
|
||||||
|
* yourdomain.com.
|
||||||
* 2. Enable the facebook plugin by including it in .htconfig.php - e.g.
|
* 2. Enable the facebook plugin by including it in .htconfig.php - e.g.
|
||||||
* $a->config['system']['addon'] = 'plugin1,plugin2,facebook';
|
* $a->config['system']['addon'] = 'plugin1,plugin2,facebook';
|
||||||
* 3. Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
|
* 3. Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
|
||||||
|
|
|
@ -260,7 +260,7 @@ function statusnet_settings(&$a,&$s) {
|
||||||
$s .= '<input id="statusnet-token" type="hidden" name="statusnet-token" value="'.$token.'" />';
|
$s .= '<input id="statusnet-token" type="hidden" name="statusnet-token" value="'.$token.'" />';
|
||||||
$s .= '<input id="statusnet-token2" type="hidden" name="statusnet-token2" value="'.$request_token['oauth_token_secret'].'" />';
|
$s .= '<input id="statusnet-token2" type="hidden" name="statusnet-token2" value="'.$request_token['oauth_token_secret'].'" />';
|
||||||
$s .= '</div><div class="clear"></div>';
|
$s .= '</div><div class="clear"></div>';
|
||||||
$s .= '<div class="settings-submit-wrapper" ><input type="submit" name="submit" class="settings-submit" value="' . t('Submit') . '" /></div>';
|
$s .= '<div class="settings-submit-wrapper" ><input type="submit" name="statusnet-submit" class="settings-submit" value="' . t('Submit') . '" /></div>';
|
||||||
$s .= '<h4>'.t('Cancel Connection Process').'</h4>';
|
$s .= '<h4>'.t('Cancel Connection Process').'</h4>';
|
||||||
$s .= '<div id="statusnet-cancel-wrapper">';
|
$s .= '<div id="statusnet-cancel-wrapper">';
|
||||||
$s .= '<p>'.t('Current StatusNet API is').': '.$api.'</p>';
|
$s .= '<p>'.t('Current StatusNet API is').': '.$api.'</p>';
|
||||||
|
|
|
@ -243,8 +243,11 @@ function twitter_post_hook(&$a,&$b) {
|
||||||
$msg .= '... ' . $shortlink;
|
$msg .= '... ' . $shortlink;
|
||||||
}
|
}
|
||||||
// and now tweet it :-)
|
// and now tweet it :-)
|
||||||
if(strlen($msg))
|
if(strlen($msg)) {
|
||||||
$tweet->post('statuses/update', array('status' => $msg));
|
$result = $tweet->post('statuses/update', array('status' => $msg));
|
||||||
|
logger('twitter_post returns: ' . $result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
86
boot.php
86
boot.php
|
@ -1,12 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
set_time_limit(0);
|
define ( 'FRIENDIKA_VERSION', '2.2.1046' );
|
||||||
ini_set('pcre.backtrack_limit', 250000);
|
|
||||||
|
|
||||||
|
|
||||||
define ( 'FRIENDIKA_VERSION', '2.2.1034' );
|
|
||||||
define ( 'DFRN_PROTOCOL_VERSION', '2.21' );
|
define ( 'DFRN_PROTOCOL_VERSION', '2.21' );
|
||||||
define ( 'DB_UPDATE_VERSION', 1075 );
|
define ( 'DB_UPDATE_VERSION', 1076 );
|
||||||
|
|
||||||
define ( 'EOL', "<br />\r\n" );
|
define ( 'EOL', "<br />\r\n" );
|
||||||
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
|
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
|
||||||
|
@ -89,6 +85,7 @@ define ( 'PAGE_FREELOVE', 3 );
|
||||||
* Network and protocol family types
|
* Network and protocol family types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
define ( 'NETWORK_ZOT', 'zot!'); // Zot!
|
||||||
define ( 'NETWORK_DFRN', 'dfrn'); // Friendika, Mistpark, other DFRN implementations
|
define ( 'NETWORK_DFRN', 'dfrn'); // Friendika, Mistpark, other DFRN implementations
|
||||||
define ( 'NETWORK_OSTATUS', 'stat'); // status.net, identi.ca, GNU-social, other OStatus implementations
|
define ( 'NETWORK_OSTATUS', 'stat'); // status.net, identi.ca, GNU-social, other OStatus implementations
|
||||||
define ( 'NETWORK_FEED', 'feed'); // RSS/Atom feeds with no known "post/notify" protocol
|
define ( 'NETWORK_FEED', 'feed'); // RSS/Atom feeds with no known "post/notify" protocol
|
||||||
|
@ -103,6 +100,13 @@ define ( 'NETWORK_FACEBOOK', 'face'); // Facebook API
|
||||||
|
|
||||||
define ( 'MAX_LIKERS', 75);
|
define ( 'MAX_LIKERS', 75);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Communication timeout
|
||||||
|
*/
|
||||||
|
|
||||||
|
define ( 'ZCURL_TIMEOUT' , (-1));
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* email notification options
|
* email notification options
|
||||||
*/
|
*/
|
||||||
|
@ -117,6 +121,7 @@ define ( 'NOTIFY_MAIL', 0x0010 );
|
||||||
* various namespaces we may need to parse
|
* various namespaces we may need to parse
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
define ( 'NAMESPACE_ZOT', 'http://purl.org/macgirvin/zot' );
|
||||||
define ( 'NAMESPACE_DFRN' , 'http://purl.org/macgirvin/dfrn/1.0' );
|
define ( 'NAMESPACE_DFRN' , 'http://purl.org/macgirvin/dfrn/1.0' );
|
||||||
define ( 'NAMESPACE_THREAD' , 'http://purl.org/syndication/thread/1.0' );
|
define ( 'NAMESPACE_THREAD' , 'http://purl.org/syndication/thread/1.0' );
|
||||||
define ( 'NAMESPACE_TOMB' , 'http://purl.org/atompub/tombstones/1.0' );
|
define ( 'NAMESPACE_TOMB' , 'http://purl.org/atompub/tombstones/1.0' );
|
||||||
|
@ -170,20 +175,28 @@ define ( 'GRAVITY_COMMENT', 6);
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (get_magic_quotes_gpc()) {
|
function startup() {
|
||||||
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
|
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
||||||
while (list($key, $val) = each($process)) {
|
set_time_limit(0);
|
||||||
foreach ($val as $k => $v) {
|
ini_set('pcre.backtrack_limit', 250000);
|
||||||
unset($process[$key][$k]);
|
|
||||||
if (is_array($v)) {
|
|
||||||
$process[$key][stripslashes($k)] = $v;
|
if (get_magic_quotes_gpc()) {
|
||||||
$process[] = &$process[$key][stripslashes($k)];
|
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
|
||||||
} else {
|
while (list($key, $val) = each($process)) {
|
||||||
$process[$key][stripslashes($k)] = stripslashes($v);
|
foreach ($val as $k => $v) {
|
||||||
}
|
unset($process[$key][$k]);
|
||||||
}
|
if (is_array($v)) {
|
||||||
}
|
$process[$key][stripslashes($k)] = $v;
|
||||||
unset($process);
|
$process[] = &$process[$key][stripslashes($k)];
|
||||||
|
} else {
|
||||||
|
$process[$key][stripslashes($k)] = stripslashes($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($process);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -251,6 +264,8 @@ class App {
|
||||||
|
|
||||||
$this->query_string = '';
|
$this->query_string = '';
|
||||||
|
|
||||||
|
startup();
|
||||||
|
|
||||||
$this->scheme = ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'])) ? 'https' : 'http' );
|
$this->scheme = ((isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'])) ? 'https' : 'http' );
|
||||||
|
|
||||||
if(x($_SERVER,'SERVER_NAME')) {
|
if(x($_SERVER,'SERVER_NAME')) {
|
||||||
|
@ -756,15 +771,17 @@ function post_url($url,$params, $headers = null, &$redirects = 0) {
|
||||||
$curl_time = intval(get_config('system','curl_timeout'));
|
$curl_time = intval(get_config('system','curl_timeout'));
|
||||||
curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60));
|
curl_setopt($ch, CURLOPT_TIMEOUT, (($curl_time !== false) ? $curl_time : 60));
|
||||||
|
|
||||||
if(!is_array($headers)) {
|
if(defined('LIGHTTPD')) {
|
||||||
$headers = array('Expect:');
|
if(!is_array($headers)) {
|
||||||
} else {
|
$headers = array('Expect:');
|
||||||
if(!in_array('Expect:', $headers)) {
|
} else {
|
||||||
array_push($headers, 'Expect:');
|
if(!in_array('Expect:', $headers)) {
|
||||||
|
array_push($headers, 'Expect:');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($headers)
|
||||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
|
||||||
$check_cert = get_config('system','verifyssl');
|
$check_cert = get_config('system','verifyssl');
|
||||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
|
||||||
|
@ -2056,6 +2073,9 @@ function get_tags($s) {
|
||||||
// we might be inside a bbcode color tag - leave it alone
|
// we might be inside a bbcode color tag - leave it alone
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// ignore strictly numeric tags like #1
|
||||||
|
if((strpos($mtch,'#') === 0) && ctype_digit(substr($mtch,1)))
|
||||||
|
continue;
|
||||||
if(substr($mtch,-1,1) === '.')
|
if(substr($mtch,-1,1) === '.')
|
||||||
$ret[] = substr($mtch,0,-1);
|
$ret[] = substr($mtch,0,-1);
|
||||||
else
|
else
|
||||||
|
@ -2937,3 +2957,15 @@ function return_bytes ($size_str) {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
function generate_guid() {
|
||||||
|
$found = true;
|
||||||
|
do {
|
||||||
|
$guid = substr(random_string(),0,16);
|
||||||
|
$x = q("SELECT `uid` FROM `user` WHERE `guid` = '%s' LIMIT 1",
|
||||||
|
dbesc($guid)
|
||||||
|
);
|
||||||
|
if(! count($x))
|
||||||
|
$found = false;
|
||||||
|
} while ($found == true );
|
||||||
|
return $guid;
|
||||||
|
}
|
|
@ -379,6 +379,7 @@ CREATE TABLE IF NOT EXISTS `session` (
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `user` (
|
CREATE TABLE IF NOT EXISTS `user` (
|
||||||
`uid` int(11) NOT NULL AUTO_INCREMENT,
|
`uid` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`guid` char(16) NOT NULL,
|
||||||
`username` char(255) NOT NULL,
|
`username` char(255) NOT NULL,
|
||||||
`password` char(255) NOT NULL,
|
`password` char(255) NOT NULL,
|
||||||
`nickname` char(255) NOT NULL,
|
`nickname` char(255) NOT NULL,
|
||||||
|
|
|
@ -129,6 +129,10 @@ $a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
|
||||||
|
|
||||||
Replace with the settings Facebook gives you.
|
Replace with the settings Facebook gives you.
|
||||||
|
|
||||||
|
d. Navigate to Set Web->Site URL & Domain -> Website Settings. Set Site URL
|
||||||
|
to yoursubdomain.yourdomain.com. Set Site Domain to your yourdomain.com.
|
||||||
|
|
||||||
|
|
||||||
Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
|
Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
|
||||||
and click 'Install Facebook Connector'.
|
and click 'Install Facebook Connector'.
|
||||||
|
|
||||||
|
|
|
@ -300,6 +300,8 @@ function probe_url($url) {
|
||||||
if(count($links)) {
|
if(count($links)) {
|
||||||
logger('probe_url: found lrdd links: ' . print_r($links,true), LOGGER_DATA);
|
logger('probe_url: found lrdd links: ' . print_r($links,true), LOGGER_DATA);
|
||||||
foreach($links as $link) {
|
foreach($links as $link) {
|
||||||
|
if($link['@attributes']['rel'] === NAMESPACE_ZOT)
|
||||||
|
$zot = unamp($link['@attributes']['href']);
|
||||||
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
|
if($link['@attributes']['rel'] === NAMESPACE_DFRN)
|
||||||
$dfrn = unamp($link['@attributes']['href']);
|
$dfrn = unamp($link['@attributes']['href']);
|
||||||
if($link['@attributes']['rel'] === 'salmon')
|
if($link['@attributes']['rel'] === 'salmon')
|
||||||
|
@ -379,6 +381,25 @@ function probe_url($url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strlen($zot)) {
|
||||||
|
$s = fetch_url($zot);
|
||||||
|
if($s) {
|
||||||
|
$j = json_decode($s);
|
||||||
|
if($j) {
|
||||||
|
$network = NETWORK_ZOT;
|
||||||
|
$vcard = array(
|
||||||
|
'fn' => $j->fullname,
|
||||||
|
'nick' => $j->nickname,
|
||||||
|
'photo' => $j->photo
|
||||||
|
);
|
||||||
|
$profile = $j->url;
|
||||||
|
$notify = $j->post;
|
||||||
|
$pubkey = $j->pubkey;
|
||||||
|
$poll = 'N/A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(strlen($dfrn)) {
|
if(strlen($dfrn)) {
|
||||||
$ret = scrape_dfrn($dfrn);
|
$ret = scrape_dfrn($dfrn);
|
||||||
if(is_array($ret) && x($ret,'dfrn-request')) {
|
if(is_array($ret) && x($ret,'dfrn-request')) {
|
||||||
|
@ -390,7 +411,7 @@ function probe_url($url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
|
if($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) {
|
||||||
$network = NETWORK_OSTATUS;
|
$network = NETWORK_OSTATUS;
|
||||||
$priority = 0;
|
$priority = 0;
|
||||||
|
|
||||||
|
@ -549,6 +570,7 @@ function probe_url($url) {
|
||||||
$result['priority'] = $priority;
|
$result['priority'] = $priority;
|
||||||
$result['network'] = $network;
|
$result['network'] = $network;
|
||||||
$result['alias'] = $alias;
|
$result['alias'] = $alias;
|
||||||
|
$result['pubkey'] = $pubkey;
|
||||||
|
|
||||||
logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG);
|
logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,13 @@
|
||||||
require_once("include/oembed.php");
|
require_once("include/oembed.php");
|
||||||
require_once('include/event.php');
|
require_once('include/event.php');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function stripcode_br_cb($s) {
|
||||||
|
return '[code]' . str_replace('<br />', '', $s[1]) . '[/code]';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// BBcode 2 HTML was written by WAY2WEB.net
|
// BBcode 2 HTML was written by WAY2WEB.net
|
||||||
// extended to work with Mistpark/Friendika - Mike Macgirvin
|
// extended to work with Mistpark/Friendika - Mike Macgirvin
|
||||||
|
|
||||||
|
@ -89,9 +96,16 @@ function bbcode($Text,$preserve_nl = false) {
|
||||||
$Text = preg_replace("(\[font=(.*?)\](.*?)\[\/font\])","<span style=\"font-family: $1;\">$2</span>",$Text);
|
$Text = preg_replace("(\[font=(.*?)\](.*?)\[\/font\])","<span style=\"font-family: $1;\">$2</span>",$Text);
|
||||||
|
|
||||||
// Declare the format for [code] layout
|
// Declare the format for [code] layout
|
||||||
|
|
||||||
|
$Text = preg_replace_callback("/\[code\](.*?)\[\/code\]/is",'stripcode_br_cb',$Text);
|
||||||
|
|
||||||
$CodeLayout = '<code>$1</code>';
|
$CodeLayout = '<code>$1</code>';
|
||||||
// Check for [code] text
|
// Check for [code] text
|
||||||
$Text = preg_replace("/\[code\](.*?)\[\/code\]/is","$CodeLayout", $Text);
|
$Text = preg_replace("/\[code\](.*?)\[\/code\]/is","$CodeLayout", $Text);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Declare the format for [quote] layout
|
// Declare the format for [quote] layout
|
||||||
$QuoteLayout = '<blockquote>$1</blockquote>';
|
$QuoteLayout = '<blockquote>$1</blockquote>';
|
||||||
// Check for [quote] text
|
// Check for [quote] text
|
||||||
|
|
|
@ -30,7 +30,7 @@ function nav(&$a) {
|
||||||
$sitelocation = $myident . substr($a->get_baseurl(),strpos($a->get_baseurl(),'//') + 2 );
|
$sitelocation = $myident . substr($a->get_baseurl(),strpos($a->get_baseurl(),'//') + 2 );
|
||||||
|
|
||||||
|
|
||||||
// nav links: array of array('href', 'text', 'extra css classes')
|
// nav links: array of array('href', 'text', 'extra css classes', 'title')
|
||||||
$nav = Array();
|
$nav = Array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,10 +38,10 @@ function nav(&$a) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(local_user()) {
|
if(local_user()) {
|
||||||
$nav['logout'] = Array('logout',t('Logout'), "");
|
$nav['logout'] = Array('logout',t('Logout'), "", t('End this session'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$nav['login'] = Array('login',t('Login'), ($a->module == 'login'?'nav-selected':''));
|
$nav['login'] = Array('login',t('Login'), ($a->module == 'login'?'nav-selected':''), t('Sign in'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,21 +52,21 @@ function nav(&$a) {
|
||||||
$homelink = ((x($_SESSION,'visitor_home')) ? $_SESSION['visitor_home'] : '');
|
$homelink = ((x($_SESSION,'visitor_home')) ? $_SESSION['visitor_home'] : '');
|
||||||
|
|
||||||
if(($a->module != 'home') && (! (local_user())))
|
if(($a->module != 'home') && (! (local_user())))
|
||||||
$nav['home'] = array($homelink, t('Home'), "");
|
$nav['home'] = array($homelink, t('Home'), "", t('Home Page'));
|
||||||
|
|
||||||
|
|
||||||
if(($a->config['register_policy'] == REGISTER_OPEN) && (! local_user()) && (! remote_user()))
|
if(($a->config['register_policy'] == REGISTER_OPEN) && (! local_user()) && (! remote_user()))
|
||||||
$nav['register'] = array('register',t('Register'), "");
|
$nav['register'] = array('register',t('Register'), "", t('Create an account'));
|
||||||
|
|
||||||
$help_url = $a->get_baseurl() . '/help';
|
$help_url = $a->get_baseurl() . '/help';
|
||||||
|
|
||||||
if(! get_config('system','hide_help'))
|
if(! get_config('system','hide_help'))
|
||||||
$nav['help'] = array($help_url, t('Help'), "");
|
$nav['help'] = array($help_url, t('Help'), "", t('Help and documentation'));
|
||||||
|
|
||||||
if($a->apps)
|
if($a->apps)
|
||||||
$nav['apps'] = array('apps', t('Apps'), "");
|
$nav['apps'] = array('apps', t('Apps'), "", t('Addon applications, utilities, games'));
|
||||||
|
|
||||||
$nav['search'] = array('search', t('Search'), "");
|
$nav['search'] = array('search', t('Search'), "", t('Search site content'));
|
||||||
|
|
||||||
$gdirpath = 'directory';
|
$gdirpath = 'directory';
|
||||||
|
|
||||||
|
@ -76,9 +76,9 @@ function nav(&$a) {
|
||||||
$gdirpath = $gdir;
|
$gdirpath = $gdir;
|
||||||
}
|
}
|
||||||
elseif(! get_config('system','no_community_page'))
|
elseif(! get_config('system','no_community_page'))
|
||||||
$nav['community'] = array('community', t('Community'), "");
|
$nav['community'] = array('community', t('Community'), "", t('Conversations on this site'));
|
||||||
|
|
||||||
$nav['directory'] = array($gdirpath, t('Directory'), "");
|
$nav['directory'] = array($gdirpath, t('Directory'), "", t('People directory'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -88,33 +88,33 @@ function nav(&$a) {
|
||||||
|
|
||||||
if(local_user()) {
|
if(local_user()) {
|
||||||
|
|
||||||
$nav['network'] = array('network', t('Network'), "");
|
$nav['network'] = array('network', t('Network'), "", t('Conversations from your friends'));
|
||||||
|
|
||||||
$nav['home'] = array('profile/' . $a->user['nickname'], t('Home'), "");
|
$nav['home'] = array('profile/' . $a->user['nickname'], t('Home'), "", t('Your posts and conversations'));
|
||||||
|
|
||||||
|
|
||||||
/* only show friend requests for normal pages. Other page types have automatic friendship. */
|
/* only show friend requests for normal pages. Other page types have automatic friendship. */
|
||||||
|
|
||||||
if($_SESSION['page_flags'] == PAGE_NORMAL) {
|
if($_SESSION['page_flags'] == PAGE_NORMAL) {
|
||||||
$nav['notifications'] = array('notifications', t('Notifications'), "");
|
$nav['notifications'] = array('notifications', t('Notifications'), "", t('Friend requests'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav['messages'] = array('message', t('Messages'), "");
|
$nav['messages'] = array('message', t('Messages'), "", t('Private mail'));
|
||||||
|
|
||||||
if(is_array($a->identities) && count($a->identities) > 1) {
|
if(is_array($a->identities) && count($a->identities) > 1) {
|
||||||
$nav['manage'] = array('manage', t('Manage'), "");
|
$nav['manage'] = array('manage', t('Manage'), "", t('Manage other pages'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav['settings'] = array('settings', t('Settings'),"");
|
$nav['settings'] = array('settings', t('Settings'),"", t('Account settings'));
|
||||||
$nav['profiles'] = array('profiles', t('Profiles'),"");
|
$nav['profiles'] = array('profiles', t('Profiles'),"", t('Manage/edit profiles'));
|
||||||
$nav['contacts'] = array('contacts', t('Contacts'),"");
|
$nav['contacts'] = array('contacts', t('Contacts'),"", t('Manage/edit friends and contacts'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin page
|
* Admin page
|
||||||
*/
|
*/
|
||||||
if (is_site_admin()){
|
if (is_site_admin()){
|
||||||
$nav['admin'] = array('admin/', t('Admin'), "");
|
$nav['admin'] = array('admin/', t('Admin'), "", t('Site setup and configuration'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,193 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
|
||||||
|
require_once('include/salmon.php');
|
||||||
|
|
||||||
|
function zot_get($url,$args) {
|
||||||
|
$argstr = '';
|
||||||
|
foreach($args as $k => $v) {
|
||||||
|
if($argstr)
|
||||||
|
$argstr .= '&';
|
||||||
|
$argstr .= $k . '=' . $v;
|
||||||
|
}
|
||||||
|
$s = fetch_url($url . '?' . $argstr);
|
||||||
|
if($s) {
|
||||||
|
$j = json_decode($s);
|
||||||
|
if($j)
|
||||||
|
return($j);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function zot_post($url,$args) {
|
||||||
|
$s = post_url($url,$args);
|
||||||
|
if($s) {
|
||||||
|
$j = json_decode($s);
|
||||||
|
if($j)
|
||||||
|
return($j);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function zot_prv_encode($s,$prvkey) {
|
||||||
|
$x = '';
|
||||||
|
$res = openssl_private_encrypt($s,$x,$prvkey);
|
||||||
|
return base64url_encode($y);
|
||||||
|
}
|
||||||
|
function zot_pub_encode($s,$pubkey) {
|
||||||
|
$x = '';
|
||||||
|
$res = openssl_public_encrypt($s,$x,$pubkey);
|
||||||
|
return base64url_encode($x);
|
||||||
|
}
|
||||||
|
|
||||||
|
function zot_prv_decode($s,$prvkey) {
|
||||||
|
$s = base64url_decode($s);
|
||||||
|
$x = '';
|
||||||
|
openssl_private_decrypt($s,$x,$prvkey);
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function zot_pub_decode($s,$pubkey) {
|
||||||
|
$s = base64url_decode($s);
|
||||||
|
$x = '';
|
||||||
|
openssl_public_decrypt($s,$x,$pubkey);
|
||||||
|
return $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function zot_getzid($url,$myaddress,$myprvkey) {
|
||||||
|
$ret = array();
|
||||||
|
$j = zot_get($url,array('sender' => $myaddress));
|
||||||
|
if($j->zid_encoded)
|
||||||
|
$ret['zid'] = zot_prv_decode($j->zid_encoded,$myprvkey);
|
||||||
|
if($j->zkey_encoded)
|
||||||
|
$ret['zkey'] = zot_prv_decode($j->zkey_encoded,$myprvkey);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function zot_post_init($url,$zid,$myprvkey,$theirpubkey) {
|
||||||
|
$ret = array();
|
||||||
|
|
||||||
|
$zinit = random_string(32);
|
||||||
|
|
||||||
|
$j = zot_get($url,array('zid' => $zid,'zinit' => $zinit));
|
||||||
|
|
||||||
|
$a = get_app();
|
||||||
|
if(! $a->get_curl_code())
|
||||||
|
return ZCURL_TIMEOUT;
|
||||||
|
if(! $j->zinit) {
|
||||||
|
logger('zot_post_init: no zinit returned.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(zot_pub_decode($j->zinit,$thierpubkey) !== $zinit) {
|
||||||
|
logger('zot_post_init: incorrect zinit returned.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if($j->challenge) {
|
||||||
|
$s = zot_prv_decode($j->challenge,$myprvkey);
|
||||||
|
$s1 = substr($s,0,strpos($s,'.'));
|
||||||
|
if($s1 != $zid) {
|
||||||
|
logger("zot_post_init: incorrect zid returned");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$ret['result'] = substr($s,strpos($s,'.') + 1);
|
||||||
|
$ret['perms'] = $j->perms;
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function zot_encrypt_data($data,&$key) {
|
||||||
|
$key = random_string();
|
||||||
|
return aes_encrypt($data,$key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// encrypt the data prior to calling this function so it only need be done once per message
|
||||||
|
// regardless of the number of recipients.
|
||||||
|
|
||||||
|
function zot_post_data($url,$zid,$myprvkey,$theirpubkey,$encrypted_data,$key, $intro = false) {
|
||||||
|
$i = zot_post_init($url,$zid,$myprvkey,$theirpubkey);
|
||||||
|
if($i === ZCURL_TIMEOUT)
|
||||||
|
return ZCURL_TIMEOUT;
|
||||||
|
|
||||||
|
if((! $i) || (! array_key_exists('perms',$i)) || (! array_key_exists('result',$i)))
|
||||||
|
return false;
|
||||||
|
if((! stristr($i['perms'],'post')) && ($intro === false)) {
|
||||||
|
logger("zot_post_data: no permission to post: url=$url zid=$zid");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$p = array();
|
||||||
|
$p['zid'] = $zid;
|
||||||
|
$p['result'] = zot_pub_encode($i['result'],$theirpubkey);
|
||||||
|
$p['aes_key'] = zot_prv_encode($key,$myprvkey);
|
||||||
|
$p['data'] = $encrypted_data;
|
||||||
|
$s = zot_post($url,$p);
|
||||||
|
$a = get_app();
|
||||||
|
if(! $a->get_curl_code())
|
||||||
|
return ZCURL_TIMEOUT;
|
||||||
|
|
||||||
|
if($s) {
|
||||||
|
$j = json_decode($s);
|
||||||
|
return $j;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function zot_deliver($recipients,$myprvkey,$data) {
|
||||||
|
|
||||||
|
if(is_array($recipients) && count($recipients)) {
|
||||||
|
|
||||||
|
$key = '';
|
||||||
|
$encrypted = zot_encrypt_data($data,$key);
|
||||||
|
|
||||||
|
|
||||||
|
foreach($recipients as $r) {
|
||||||
|
$result = zot_post_data(
|
||||||
|
$r['post'],
|
||||||
|
$r['zid'],
|
||||||
|
$myprvkey,
|
||||||
|
$r['pubkey'],
|
||||||
|
$encrypted,
|
||||||
|
$key
|
||||||
|
);
|
||||||
|
if($result === false) {
|
||||||
|
// post failed
|
||||||
|
logger('zot_deliver: failed: ' . print_r($r,true));
|
||||||
|
}
|
||||||
|
elseif($result === ZCURL_TIMEOUT) {
|
||||||
|
// queue for redelivery
|
||||||
|
}
|
||||||
|
elseif($result->error) {
|
||||||
|
// failed at other end
|
||||||
|
logger('zot_deliver: remote failure: ' . $result->error . ' ' . print_r($r,true));
|
||||||
|
}
|
||||||
|
elseif($result->success) {
|
||||||
|
logger('zot_deliver: success ' . print_r($r,true, LOGGER_DEBUG));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
logger('zot_deliver: unknown failure.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function zot_new_contact($user,$cc) {
|
||||||
|
|
||||||
|
$zid = random_string(32);
|
||||||
|
$zkey = random_string(32);
|
||||||
|
|
||||||
|
logger("zot_new_contact: zid=$zid zkey=$zkey uid={$user['uid']} " . print_r($cc,true));
|
||||||
|
|
||||||
|
$ret = array();
|
||||||
|
$ret['zid_encoded'] = zot_pub_encode($zid,$cc['pubkey']);
|
||||||
|
$ret['zkey_encoded'] = zot_pub_encode($zkey,$cc['pubkey']);
|
||||||
|
return $ret;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
error_reporting(E_ERROR | E_WARNING | E_PARSE);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Friendika
|
* Friendika
|
||||||
|
|
|
@ -3,13 +3,26 @@
|
||||||
require_once('include/Contact.php');
|
require_once('include/Contact.php');
|
||||||
|
|
||||||
function contacts_init(&$a) {
|
function contacts_init(&$a) {
|
||||||
|
if(! local_user())
|
||||||
|
return;
|
||||||
|
|
||||||
require_once('include/group.php');
|
require_once('include/group.php');
|
||||||
if(! x($a->page,'aside'))
|
if(! x($a->page,'aside'))
|
||||||
$a->page['aside'] = '';
|
$a->page['aside'] = '';
|
||||||
$a->page['aside'] .= group_side();
|
$a->page['aside'] .= group_side();
|
||||||
|
|
||||||
if($a->config['register_policy'] != REGISTER_CLOSED)
|
$inv = '<div class="side-link" id="side-invite-link" ><a href="invite" >' . t("Invite Friends") . '</a></div>';
|
||||||
$a->page['aside'] .= '<div class="side-link" id="side-invite-link" ><a href="invite" >' . t("Invite Friends") . '</a></div>';
|
|
||||||
|
if(get_config('system','invitation_only')) {
|
||||||
|
$x = get_pconfig(local_user(),'system','invites_remaining');
|
||||||
|
if($x || is_site_admin()) {
|
||||||
|
$a->page['aside'] .= '<div class="side-link" id="side-invite-remain">'
|
||||||
|
. sprintf( tt('%d invitation available','%d invitations available',$x), $x)
|
||||||
|
. '</div>' . $inv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif($a->config['register_policy'] != REGISTER_CLOSED)
|
||||||
|
$a->page['aside'] .= $inv;
|
||||||
|
|
||||||
|
|
||||||
$a->page['aside'] .= '<div class="side-link" id="side-match-link"><a href="match" >'
|
$a->page['aside'] .= '<div class="side-link" id="side-match-link"><a href="match" >'
|
||||||
|
|
|
@ -39,7 +39,6 @@ function friendika_content(&$a) {
|
||||||
|
|
||||||
$o .= '<p></p><p>';
|
$o .= '<p></p><p>';
|
||||||
|
|
||||||
$o .= 'View <a href="LICENSE">License</a>' . '<br /><br />';
|
|
||||||
$o .= t('This is Friendika version') . ' ' . FRIENDIKA_VERSION . ' ';
|
$o .= t('This is Friendika version') . ' ' . FRIENDIKA_VERSION . ' ';
|
||||||
$o .= t('running at web location') . ' ' . $a->get_baseurl() . '</p><p>';
|
$o .= t('running at web location') . ' ' . $a->get_baseurl() . '</p><p>';
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ function install_content(&$a) {
|
||||||
'$dbpass' => notags(trim($_POST['dbpass'])),
|
'$dbpass' => notags(trim($_POST['dbpass'])),
|
||||||
'$dbdata' => notags(trim($_POST['dbdata'])),
|
'$dbdata' => notags(trim($_POST['dbdata'])),
|
||||||
'$phpath' => $phpath,
|
'$phpath' => $phpath,
|
||||||
'$adminemail' => notags(trim($_POST['adminemail']))
|
'$adminmail' => notags(trim($_POST['adminmail']))
|
||||||
));
|
));
|
||||||
|
|
||||||
return $o;
|
return $o;
|
||||||
|
|
|
@ -20,6 +20,13 @@ function invite_post(&$a) {
|
||||||
|
|
||||||
$total = 0;
|
$total = 0;
|
||||||
|
|
||||||
|
if(get_config('system','invitation_only')) {
|
||||||
|
$invonly = true;
|
||||||
|
$x = get_pconfig(local_user(),'system','invites_remaining');
|
||||||
|
if((! $x) && (! is_site_admin()))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach($recips as $recip) {
|
foreach($recips as $recip) {
|
||||||
|
|
||||||
$recip = trim($recip);
|
$recip = trim($recip);
|
||||||
|
@ -28,9 +35,29 @@ function invite_post(&$a) {
|
||||||
notice( sprintf( t('%s : Not a valid email address.'), $recip) . EOL);
|
notice( sprintf( t('%s : Not a valid email address.'), $recip) . EOL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($invonly && ($x || is_site_admin())) {
|
||||||
|
$code = autoname(8) . srand(1000,9999);
|
||||||
|
$nmessage = str_replace('$invite_code',$code,$message);
|
||||||
|
|
||||||
|
$r = q("INSERT INTO `register` (`hash`,`created`) VALUES ('%s', '%s') ",
|
||||||
|
dbesc($code),
|
||||||
|
dbesc(datetime_convert())
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! is_site_admin()) {
|
||||||
|
$x --;
|
||||||
|
if($x >= 0)
|
||||||
|
set_pconfig(local_user(),'system','invites_remaining',$x);
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$nmessage = $message;
|
||||||
|
|
||||||
$res = mail($recip, sprintf( t('Please join my network on %s'), $a->config['sitename']),
|
$res = mail($recip, sprintf( t('Please join my network on %s'), $a->config['sitename']),
|
||||||
$message,
|
$nmessage,
|
||||||
"From: " . $a->user['email'] . "\n"
|
"From: " . $a->user['email'] . "\n"
|
||||||
. 'Content-type: text/plain; charset=UTF-8' . "\n"
|
. 'Content-type: text/plain; charset=UTF-8' . "\n"
|
||||||
. 'Content-transfer-encoding: 8bit' );
|
. 'Content-transfer-encoding: 8bit' );
|
||||||
|
@ -56,14 +83,25 @@ function invite_content(&$a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$tpl = get_markup_template('invite.tpl');
|
$tpl = get_markup_template('invite.tpl');
|
||||||
|
$invonly = false;
|
||||||
|
|
||||||
|
if(get_config('system','invitation_only')) {
|
||||||
|
$invonly = true;
|
||||||
|
$x = get_pconfig(local_user(),'system','invites_remaining');
|
||||||
|
if((! $x) && (! is_site_admin())) {
|
||||||
|
notice( t('You have no more invitations available') . EOL);
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$o = replace_macros($tpl, array(
|
$o = replace_macros($tpl, array(
|
||||||
'$invite' => t('Send invitations'),
|
'$invite' => t('Send invitations'),
|
||||||
'$addr_text' => t('Enter email addresses, one per line:'),
|
'$addr_text' => t('Enter email addresses, one per line:'),
|
||||||
'$msg_text' => t('Your message:'),
|
'$msg_text' => t('Your message:'),
|
||||||
'$default_message' => sprintf(t('Please join my social network on %s'), $a->config['sitename']) . "\r\n" . "\r\n"
|
'$default_message' => sprintf(t('Please join my social network on %s'), $a->config['sitename']) . "\r\n" . "\r\n"
|
||||||
. t('To accept this invitation, please visit:') . "\r\n" . "\r\n" . $a->get_baseurl()
|
. t('To accept this invitation, please visit:') . "\r\n" . "\r\n" . $a->get_baseurl()
|
||||||
. "\r\n" . "\r\n" . t('Once you have registered, please connect with me via my profile page at:')
|
. "\r\n" . "\r\n" . (($invonly) ? t('You will need to supply this invitation code: $invite_code') . "\r\n" . "\r\n" : '') .t('Once you have registered, please connect with me via my profile page at:')
|
||||||
. "\r\n" . "\r\n" . $a->get_baseurl() . '/profile/' . $a->user['nickname'] ,
|
. "\r\n" . "\r\n" . $a->get_baseurl() . '/profile/' . $a->user['nickname'] ,
|
||||||
'$submit' => t('Submit')
|
'$submit' => t('Submit')
|
||||||
));
|
));
|
||||||
|
|
|
@ -184,12 +184,10 @@ function item_post(&$a) {
|
||||||
|
|
||||||
if($post_type === 'net-comment') {
|
if($post_type === 'net-comment') {
|
||||||
if($parent_item !== null) {
|
if($parent_item !== null) {
|
||||||
if($parent_item['type'] === 'remote') {
|
if($parent_item['wall'] == 1)
|
||||||
$post_type = 'remote-comment';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$post_type = 'wall-comment';
|
$post_type = 'wall-comment';
|
||||||
}
|
else
|
||||||
|
$post_type = 'remote-comment';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ function parse_url_content(&$a) {
|
||||||
|
|
||||||
$text = null;
|
$text = null;
|
||||||
|
|
||||||
$template = "<a href=\"%s\" >%s</a>\n%s";
|
$template = "<br /><a href=\"%s\" >%s</a>%s<br />";
|
||||||
|
|
||||||
|
|
||||||
$arr = array('url' => $url, 'text' => '');
|
$arr = array('url' => $url, 'text' => '');
|
||||||
|
@ -39,12 +39,20 @@ function parse_url_content(&$a) {
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(strpos($s,'<title>')) {
|
||||||
|
$title = substr($s,strpos($s,'<title>')+7,64);
|
||||||
|
if(strpos($title,'<') !== false)
|
||||||
|
$title = strip_tags(substr($title,0,strpos($title,'<')));
|
||||||
|
}
|
||||||
|
|
||||||
$config = HTMLPurifier_Config::createDefault();
|
$config = HTMLPurifier_Config::createDefault();
|
||||||
$config->set('Cache.DefinitionImpl', null);
|
$config->set('Cache.DefinitionImpl', null);
|
||||||
|
|
||||||
$purifier = new HTMLPurifier($config);
|
$purifier = new HTMLPurifier($config);
|
||||||
$s = $purifier->purify($s);
|
$s = $purifier->purify($s);
|
||||||
|
|
||||||
|
// logger('parse_url: purified: ' . $s, LOGGER_DATA);
|
||||||
|
|
||||||
$dom = @HTML5_Parser::parse($s);
|
$dom = @HTML5_Parser::parse($s);
|
||||||
|
|
||||||
if(! $dom) {
|
if(! $dom) {
|
||||||
|
@ -65,21 +73,27 @@ function parse_url_content(&$a) {
|
||||||
if($divs) {
|
if($divs) {
|
||||||
foreach($divs as $div) {
|
foreach($divs as $div) {
|
||||||
$class = $div->getAttribute('class');
|
$class = $div->getAttribute('class');
|
||||||
if($class && stristr($class,'article')) {
|
if($class && (stristr($class,'article') || stristr($class,'content'))) {
|
||||||
$items = $div->getElementsByTagName('p');
|
$items = $div->getElementsByTagName('p');
|
||||||
if($items) {
|
if($items) {
|
||||||
foreach($items as $item) {
|
foreach($items as $item) {
|
||||||
if($item->getElementsByTagName('script'))
|
|
||||||
continue;
|
|
||||||
$text = $item->textContent;
|
$text = $item->textContent;
|
||||||
$text = strip_tags($text);
|
if(stristr($text,'<script')) {
|
||||||
if(strlen($text) < 100)
|
$text = '';
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
$text = strip_tags($text);
|
||||||
|
if(strlen($text) < 100) {
|
||||||
|
$text = '';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$text = substr($text,0,250) . '...' ;
|
$text = substr($text,0,250) . '...' ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if($text)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,12 +101,14 @@ function parse_url_content(&$a) {
|
||||||
$items = $dom->getElementsByTagName('p');
|
$items = $dom->getElementsByTagName('p');
|
||||||
if($items) {
|
if($items) {
|
||||||
foreach($items as $item) {
|
foreach($items as $item) {
|
||||||
if($item->getElementsByTagName('script'))
|
|
||||||
continue;
|
|
||||||
$text = $item->textContent;
|
$text = $item->textContent;
|
||||||
$text = strip_tags($text);
|
if(stristr($text,'<script'))
|
||||||
if(strlen($text) < 100)
|
|
||||||
continue;
|
continue;
|
||||||
|
$text = strip_tags($text);
|
||||||
|
if(strlen($text) < 100) {
|
||||||
|
$text = '';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$text = substr($text,0,250) . '...' ;
|
$text = substr($text,0,250) . '...' ;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +116,7 @@ function parse_url_content(&$a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strlen($text)) {
|
if(strlen($text)) {
|
||||||
$text = '<br />' . $text;
|
$text = '<br /><br />' . $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
echo sprintf($template,$url,($title) ? $title : $url,$text);
|
echo sprintf($template,$url,($title) ? $title : $url,$text);
|
||||||
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Diaspora endpoint
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
require_once('include/salmon.php');
|
||||||
|
require_once('library/simplepie/simplepie.inc');
|
||||||
|
|
||||||
|
function receive_return($val) {
|
||||||
|
|
||||||
|
if($val >= 400)
|
||||||
|
$err = 'Error';
|
||||||
|
if($val >= 200 && $val < 300)
|
||||||
|
$err = 'OK';
|
||||||
|
|
||||||
|
logger('mod-diaspora returns ' . $val);
|
||||||
|
header($_SERVER["SERVER_PROTOCOL"] . ' ' . $val . ' ' . $err);
|
||||||
|
killme();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function receive_post(&$a) {
|
||||||
|
|
||||||
|
if($a->argc != 3 || $a->argv[1] !== 'users')
|
||||||
|
receive_return(500);
|
||||||
|
|
||||||
|
$guid = $a->argv[2];
|
||||||
|
|
||||||
|
$r = q("SELECT * FROM `user` WHERE `guid` = '%s' LIMIT 1",
|
||||||
|
dbesc($guid)
|
||||||
|
);
|
||||||
|
if(! count($r))
|
||||||
|
salmon_return(500);
|
||||||
|
|
||||||
|
$importer = $r[0];
|
||||||
|
|
||||||
|
$xml = $_POST['xml'];
|
||||||
|
|
||||||
|
logger('mod-diaspora: new salmon ' . $xml, LOGGER_DATA);
|
||||||
|
|
||||||
|
if(! $xml)
|
||||||
|
receive_return(500);
|
||||||
|
|
||||||
|
// parse the xml
|
||||||
|
|
||||||
|
$dom = simplexml_load_string($xml,'SimpleXMLElement',0,NAMESPACE_SALMON_ME);
|
||||||
|
|
||||||
|
// figure out where in the DOM tree our data is hiding
|
||||||
|
|
||||||
|
if($dom->provenance->data)
|
||||||
|
$base = $dom->provenance;
|
||||||
|
elseif($dom->env->data)
|
||||||
|
$base = $dom->env;
|
||||||
|
elseif($dom->data)
|
||||||
|
$base = $dom;
|
||||||
|
|
||||||
|
if(! $base) {
|
||||||
|
logger('mod-diaspora: unable to locate salmon data in xml ');
|
||||||
|
receive_return(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stash the signature away for now. We have to find their key or it won't be good for anything.
|
||||||
|
$signature = base64url_decode($base->sig);
|
||||||
|
|
||||||
|
// unpack the data
|
||||||
|
|
||||||
|
// strip whitespace so our data element will return to one big base64 blob
|
||||||
|
$data = str_replace(array(" ","\t","\r","\n"),array("","","",""),$base->data);
|
||||||
|
|
||||||
|
// stash away some other stuff for later
|
||||||
|
|
||||||
|
$type = $base->data[0]->attributes()->type[0];
|
||||||
|
$keyhash = $base->sig[0]->attributes()->keyhash[0];
|
||||||
|
$encoding = $base->encoding;
|
||||||
|
$alg = $base->alg;
|
||||||
|
|
||||||
|
$signed_data = $data . '.' . base64url_encode($type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($alg);
|
||||||
|
|
||||||
|
// decode the data
|
||||||
|
$data = base64url_decode($data);
|
||||||
|
|
||||||
|
// Remove the xml declaration
|
||||||
|
$data = preg_replace('/\<\?xml[^\?].*\?\>/','',$data);
|
||||||
|
|
||||||
|
// Create a fake feed wrapper so simplepie doesn't choke
|
||||||
|
|
||||||
|
$tpl = get_markup_template('fake_feed.tpl');
|
||||||
|
|
||||||
|
$base = substr($data,strpos($data,'<entry'));
|
||||||
|
|
||||||
|
$feedxml = $tpl . $base . '</feed>';
|
||||||
|
|
||||||
|
logger('mod-diaspora: Processed feed: ' . $feedxml);
|
||||||
|
|
||||||
|
// Now parse it like a normal atom feed to scrape out the author URI
|
||||||
|
|
||||||
|
$feed = new SimplePie();
|
||||||
|
$feed->set_raw_data($feedxml);
|
||||||
|
$feed->enable_order_by_date(false);
|
||||||
|
$feed->init();
|
||||||
|
|
||||||
|
logger('mod-diaspora: Feed parsed.');
|
||||||
|
|
||||||
|
if($feed->get_item_quantity()) {
|
||||||
|
foreach($feed->get_items() as $item) {
|
||||||
|
$author = $item->get_author();
|
||||||
|
$author_link = unxmlify($author->get_link());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(! $author_link) {
|
||||||
|
logger('mod-diaspora: Could not retrieve author URI.');
|
||||||
|
receive_return(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once we have the author URI, go to the web and try to find their public key
|
||||||
|
|
||||||
|
logger('mod-salmon: Fetching key for ' . $author_link );
|
||||||
|
|
||||||
|
|
||||||
|
$key = get_salmon_key($author_link,$keyhash);
|
||||||
|
|
||||||
|
if(! $key) {
|
||||||
|
logger('mod-salmon: Could not retrieve author key.');
|
||||||
|
receive_return(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup RSA stuff to verify the signature
|
||||||
|
|
||||||
|
set_include_path(get_include_path() . PATH_SEPARATOR . 'library' . PATH_SEPARATOR . 'phpsec');
|
||||||
|
|
||||||
|
require_once('library/phpsec/Crypt/RSA.php');
|
||||||
|
|
||||||
|
$key_info = explode('.',$key);
|
||||||
|
|
||||||
|
$m = base64url_decode($key_info[1]);
|
||||||
|
$e = base64url_decode($key_info[2]);
|
||||||
|
|
||||||
|
logger('mod-salmon: key details: ' . print_r($key_info,true));
|
||||||
|
|
||||||
|
$rsa = new CRYPT_RSA();
|
||||||
|
$rsa->signatureMode = CRYPT_RSA_SIGNATURE_PKCS1;
|
||||||
|
$rsa->setHash('sha256');
|
||||||
|
|
||||||
|
$rsa->modulus = new Math_BigInteger($m, 256);
|
||||||
|
$rsa->k = strlen($rsa->modulus->toBytes());
|
||||||
|
$rsa->exponent = new Math_BigInteger($e, 256);
|
||||||
|
|
||||||
|
$verify = $rsa->verify($signed_data,$signature);
|
||||||
|
|
||||||
|
if(! $verify) {
|
||||||
|
logger('mod-diaspora: Message did not verify. Discarding.');
|
||||||
|
receive_return(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
logger('mod-diaspora: Message verified.');
|
||||||
|
|
||||||
|
/* decrypt the sucker */
|
||||||
|
/*
|
||||||
|
// TODO
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* If we reached this point, the message is good. Now let's figure out if the author is allowed to send us stuff.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$r = q("SELECT * FROM `contact` WHERE `network` = 'dspr' AND ( `url` = '%s' OR `alias` = '%s')
|
||||||
|
AND `uid` = %d LIMIT 1",
|
||||||
|
dbesc($author_link),
|
||||||
|
dbesc($author_link),
|
||||||
|
intval($importer['uid'])
|
||||||
|
);
|
||||||
|
if(! count($r)) {
|
||||||
|
logger('mod-diaspora: Author unknown to us.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// is this a follower? Or have we ignored the person?
|
||||||
|
// If so we can not accept this post.
|
||||||
|
|
||||||
|
if((count($r)) && (($r[0]['readonly']) || ($r[0]['rel'] == REL_VIP) || ($r[0]['blocked']))) {
|
||||||
|
logger('mod-diaspora: Ignoring this author.');
|
||||||
|
receive_return(202);
|
||||||
|
// NOTREACHED
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once('include/items.php');
|
||||||
|
|
||||||
|
// Placeholder for hub discovery. We shouldn't find any hubs
|
||||||
|
// since we supplied the fake feed header - and it doesn't have any.
|
||||||
|
|
||||||
|
$hub = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* anti-spam measure: consume_feed will accept a follow activity from
|
||||||
|
* this person (and nothing else) if there is no existing contact record.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
$contact_rec = ((count($r)) ? $r[0] : null);
|
||||||
|
|
||||||
|
consume_feed($feedxml,$importer,$contact_rec,$hub);
|
||||||
|
|
||||||
|
receive_return(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,11 @@ function register_post(&$a) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$using_invites = get_config('system','invitation_only');
|
||||||
|
$num_invites = get_config('system','number_invites');
|
||||||
|
|
||||||
|
|
||||||
|
$invite_id = ((x($_POST,'invite_id')) ? notags(trim($_POST['invite_id'])) : '');
|
||||||
$username = ((x($_POST,'username')) ? notags(trim($_POST['username'])) : '');
|
$username = ((x($_POST,'username')) ? notags(trim($_POST['username'])) : '');
|
||||||
$nickname = ((x($_POST,'nickname')) ? notags(trim($_POST['nickname'])) : '');
|
$nickname = ((x($_POST,'nickname')) ? notags(trim($_POST['nickname'])) : '');
|
||||||
$email = ((x($_POST,'email')) ? notags(trim($_POST['email'])) : '');
|
$email = ((x($_POST,'email')) ? notags(trim($_POST['email'])) : '');
|
||||||
|
@ -43,6 +47,19 @@ function register_post(&$a) {
|
||||||
$netpublish = ((strlen(get_config('system','directory_submit_url'))) ? $publish : 0);
|
$netpublish = ((strlen(get_config('system','directory_submit_url'))) ? $publish : 0);
|
||||||
|
|
||||||
$tmp_str = $openid_url;
|
$tmp_str = $openid_url;
|
||||||
|
|
||||||
|
if($using_invites) {
|
||||||
|
if(! $invite_id) {
|
||||||
|
notice( t('An invitation is required.') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id));
|
||||||
|
if(! results($r)) {
|
||||||
|
notice( t('Invitation could not be verified.') . EOL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if((! x($username)) || (! x($email)) || (! x($nickname))) {
|
if((! x($username)) || (! x($email)) || (! x($nickname))) {
|
||||||
if($openid_url) {
|
if($openid_url) {
|
||||||
if(! validate_url($tmp_str)) {
|
if(! validate_url($tmp_str)) {
|
||||||
|
@ -181,9 +198,10 @@ function register_post(&$a) {
|
||||||
$spkey = openssl_pkey_get_details($sres);
|
$spkey = openssl_pkey_get_details($sres);
|
||||||
$spubkey = $spkey["key"];
|
$spubkey = $spkey["key"];
|
||||||
|
|
||||||
$r = q("INSERT INTO `user` ( `username`, `password`, `email`, `openid`, `nickname`,
|
$r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,
|
||||||
`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked` )
|
`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked` )
|
||||||
VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
|
VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d )",
|
||||||
|
dbesc(generate_guid()),
|
||||||
dbesc($username),
|
dbesc($username),
|
||||||
dbesc($new_password_encoded),
|
dbesc($new_password_encoded),
|
||||||
dbesc($email),
|
dbesc($email),
|
||||||
|
@ -328,7 +346,15 @@ function register_post(&$a) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
call_hooks('register_account', $newuid);
|
||||||
|
|
||||||
if( $a->config['register_policy'] == REGISTER_OPEN ) {
|
if( $a->config['register_policy'] == REGISTER_OPEN ) {
|
||||||
|
|
||||||
|
if($using_invites && $invite_id) {
|
||||||
|
q("delete * from register where hash = '%s' limit 1", dbesc($invite_id));
|
||||||
|
set_pconfig($newuid,'system','invites_remaining',$num_invites);
|
||||||
|
}
|
||||||
|
|
||||||
$email_tpl = get_intltext_template("register_open_eml.tpl");
|
$email_tpl = get_intltext_template("register_open_eml.tpl");
|
||||||
$email_tpl = replace_macros($email_tpl, array(
|
$email_tpl = replace_macros($email_tpl, array(
|
||||||
'$sitename' => $a->config['sitename'],
|
'$sitename' => $a->config['sitename'],
|
||||||
|
@ -376,6 +402,10 @@ function register_post(&$a) {
|
||||||
else
|
else
|
||||||
push_lang('en');
|
push_lang('en');
|
||||||
|
|
||||||
|
if($using_invites && $invite_id) {
|
||||||
|
q("delete * from register where hash = '%s' limit 1", dbesc($invite_id));
|
||||||
|
set_pconfig($newuid,'system','invites_remaining',$num_invites);
|
||||||
|
}
|
||||||
|
|
||||||
$email_tpl = get_intltext_template("register_verify_eml.tpl");
|
$email_tpl = get_intltext_template("register_verify_eml.tpl");
|
||||||
$email_tpl = replace_macros($email_tpl, array(
|
$email_tpl = replace_macros($email_tpl, array(
|
||||||
|
@ -434,6 +464,7 @@ function register_content(&$a) {
|
||||||
$openid_url = ((x($_POST,'openid_url')) ? $_POST['openid_url'] : ((x($_GET,'openid_url')) ? $_GET['openid_url'] : ''));
|
$openid_url = ((x($_POST,'openid_url')) ? $_POST['openid_url'] : ((x($_GET,'openid_url')) ? $_GET['openid_url'] : ''));
|
||||||
$nickname = ((x($_POST,'nickname')) ? $_POST['nickname'] : ((x($_GET,'nickname')) ? $_GET['nickname'] : ''));
|
$nickname = ((x($_POST,'nickname')) ? $_POST['nickname'] : ((x($_GET,'nickname')) ? $_GET['nickname'] : ''));
|
||||||
$photo = ((x($_POST,'photo')) ? $_POST['photo'] : ((x($_GET,'photo')) ? hex2bin($_GET['photo']) : ''));
|
$photo = ((x($_POST,'photo')) ? $_POST['photo'] : ((x($_GET,'photo')) ? hex2bin($_GET['photo']) : ''));
|
||||||
|
$invite_id = ((x($_POST,'invite_id')) ? $_POST['invite_id'] : ((x($_GET,'invite_id')) ? $_GET['invite_id'] : ''));
|
||||||
|
|
||||||
$noid = get_config('system','no_openid');
|
$noid = get_config('system','no_openid');
|
||||||
|
|
||||||
|
@ -476,6 +507,10 @@ function register_content(&$a) {
|
||||||
$o = get_markup_template("register.tpl");
|
$o = get_markup_template("register.tpl");
|
||||||
$o = replace_macros($o, array(
|
$o = replace_macros($o, array(
|
||||||
'$oidhtml' => $oidhtml,
|
'$oidhtml' => $oidhtml,
|
||||||
|
'$invitations' => get_config('system','invitation_only'),
|
||||||
|
'$invite_desc' => t('Membership on this site is by invitation only.'),
|
||||||
|
'$invite_label' => t('Your invitation ID: '),
|
||||||
|
'$invite_id' => $invite_id,
|
||||||
'$realpeople' => $realpeople,
|
'$realpeople' => $realpeople,
|
||||||
'$regtitle' => t('Registration'),
|
'$regtitle' => t('Registration'),
|
||||||
'$registertext' =>((x($a->config,'register_text'))
|
'$registertext' =>((x($a->config,'register_text'))
|
||||||
|
|
|
@ -435,11 +435,6 @@ function settings_content(&$a) {
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$invisible = (((! $profile['publish']) && (! $profile['net-publish']))
|
$invisible = (((! $profile['publish']) && (! $profile['net-publish']))
|
||||||
? true : false);
|
? true : false);
|
||||||
|
|
||||||
|
@ -495,6 +490,7 @@ function settings_content(&$a) {
|
||||||
'$h_pass' => t('Password Settings'),
|
'$h_pass' => t('Password Settings'),
|
||||||
'$password1'=> array('npassword', t('New Password:'), '', ''),
|
'$password1'=> array('npassword', t('New Password:'), '', ''),
|
||||||
'$password2'=> array('confirm', t('Confirm:'), '', t('Leave password fields blank unless changing')),
|
'$password2'=> array('confirm', t('Confirm:'), '', t('Leave password fields blank unless changing')),
|
||||||
|
'$oid_enable' => (! get_config('system','no_openid')),
|
||||||
'$openid' => $openid_field,
|
'$openid' => $openid_field,
|
||||||
|
|
||||||
'$h_basic' => t('Basic Settings'),
|
'$h_basic' => t('Basic Settings'),
|
||||||
|
@ -527,11 +523,11 @@ function settings_content(&$a) {
|
||||||
|
|
||||||
'$h_not' => t('Notification Settings'),
|
'$h_not' => t('Notification Settings'),
|
||||||
'$lbl_not' => t('Send a notification email when:'),
|
'$lbl_not' => t('Send a notification email when:'),
|
||||||
'$notify1' => array('notify1', t('You receive an introduction'), ($notify & NOTIFY_INTRO), ''),
|
'$notify1' => array('notify1', t('You receive an introduction'), ($notify & NOTIFY_INTRO), NOTIFY_INTRO, ''),
|
||||||
'$notify2' => array('notify1', t('Your introductions are confirmed'), ($notify & NOTIFY_CONFIRM), ''),
|
'$notify2' => array('notify2', t('Your introductions are confirmed'), ($notify & NOTIFY_CONFIRM), NOTIFY_CONFIRM, ''),
|
||||||
'$notify3' => array('notify1', t('Someone writes on your profile wall'), ($notify & NOTIFY_WALL), ''),
|
'$notify3' => array('notify3', t('Someone writes on your profile wall'), ($notify & NOTIFY_WALL), NOTIFY_WALL, ''),
|
||||||
'$notify4' => array('notify1', t('Someone writes a followup comment'), ($notify & NOTIFY_COMMENT), ''),
|
'$notify4' => array('notify4', t('Someone writes a followup comment'), ($notify & NOTIFY_COMMENT), NOTIFY_COMMENT, ''),
|
||||||
'$notify5' => array('notify1', t('You receive a private message'), ($notify & NOTIFY_MAIL), ''),
|
'$notify5' => array('notify5', t('You receive a private message'), ($notify & NOTIFY_MAIL), NOTIFY_MAIL, ''),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
15
mod/xrd.php
15
mod/xrd.php
|
@ -27,6 +27,20 @@ function xrd_content(&$a) {
|
||||||
header('Access-Control-Allow-Origin: *');
|
header('Access-Control-Allow-Origin: *');
|
||||||
header("Content-type: text/xml");
|
header("Content-type: text/xml");
|
||||||
|
|
||||||
|
$dspr_enabled = get_config('system','diaspora_enabled');
|
||||||
|
|
||||||
|
if($dspr_enabled) {
|
||||||
|
$tpl = file_get_contents('view/xrd_diaspora.tpl');
|
||||||
|
$dspr = replace_macros($tpl,array(
|
||||||
|
'$baseurl' => $a->get_baseurl(),
|
||||||
|
'$dspr_guid' => $r[0]['guid'],
|
||||||
|
'$dspr_key' => base64_encode($r[0]['pubkey'])
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
$dspr = '';
|
||||||
|
|
||||||
|
|
||||||
$tpl = file_get_contents('view/xrd_person.tpl');
|
$tpl = file_get_contents('view/xrd_person.tpl');
|
||||||
|
|
||||||
$o = replace_macros($tpl, array(
|
$o = replace_macros($tpl, array(
|
||||||
|
@ -34,6 +48,7 @@ function xrd_content(&$a) {
|
||||||
'$profile_url' => $a->get_baseurl() . '/profile/' . $r[0]['nickname'],
|
'$profile_url' => $a->get_baseurl() . '/profile/' . $r[0]['nickname'],
|
||||||
'$atom' => $a->get_baseurl() . '/dfrn_poll/' . $r[0]['nickname'],
|
'$atom' => $a->get_baseurl() . '/dfrn_poll/' . $r[0]['nickname'],
|
||||||
'$photo' => $a->get_baseurl() . '/photo/profile/' . $r[0]['uid'] . '.jpg',
|
'$photo' => $a->get_baseurl() . '/photo/profile/' . $r[0]['uid'] . '.jpg',
|
||||||
|
'$dspr' => $dspr,
|
||||||
'$salmon' => $a->get_baseurl() . '/salmon/' . $r[0]['nickname'],
|
'$salmon' => $a->get_baseurl() . '/salmon/' . $r[0]['nickname'],
|
||||||
'$salmen' => $a->get_baseurl() . '/salmon/' . $r[0]['nickname'] . '/mention',
|
'$salmen' => $a->get_baseurl() . '/salmon/' . $r[0]['nickname'] . '/mention',
|
||||||
'$modexp' => 'data:application/magic-public-key,' . $salmon_key
|
'$modexp' => 'data:application/magic-public-key,' . $salmon_key
|
||||||
|
|
25
update.php
25
update.php
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
define( 'UPDATE_VERSION' , 1075 );
|
define( 'UPDATE_VERSION' , 1076 );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -601,3 +601,26 @@ function update_1074() {
|
||||||
}
|
}
|
||||||
q("ALTER TABLE `profile` DROP `hidewall`");
|
q("ALTER TABLE `profile` DROP `hidewall`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function update_1075() {
|
||||||
|
q("ALTER TABLE `user` ADD `guid` CHAR( 16 ) NOT NULL AFTER `uid` ");
|
||||||
|
$r = q("SELECT `uid` FROM `user` WHERE 1");
|
||||||
|
if(count($r)) {
|
||||||
|
foreach($r as $rr) {
|
||||||
|
$found = true;
|
||||||
|
do {
|
||||||
|
$guid = substr(random_string(),0,16);
|
||||||
|
$x = q("SELECT `uid` FROM `user` WHERE `guid` = '%s' LIMIT 1",
|
||||||
|
dbesc($guid)
|
||||||
|
);
|
||||||
|
if(! count($x))
|
||||||
|
$found = false;
|
||||||
|
} while ($found == true );
|
||||||
|
|
||||||
|
q("UPDATE `user` SET `guid` = '%s' WHERE `uid` = %d LIMIT 1",
|
||||||
|
dbesc($guid),
|
||||||
|
intval($rr['uid'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<config>
|
||||||
|
<site>
|
||||||
|
<name>$sitedesc</name>
|
||||||
|
<server>$sitename</server>
|
||||||
|
<theme>default</theme>
|
||||||
|
<path></path>
|
||||||
|
<logo>$sitelogo</logo>
|
||||||
|
|
||||||
|
<fancy>true</fancy>
|
||||||
|
<language>en</language>
|
||||||
|
<email>$adminemail</email>
|
||||||
|
<broughtby></broughtby>
|
||||||
|
<broughtbyurl></broughtbyurl>
|
||||||
|
<timezone>UTC</timezone>
|
||||||
|
<closed>$siteclosed</closed>
|
||||||
|
|
||||||
|
<inviteonly>false</inviteonly>
|
||||||
|
<private>$siteprivate</private>
|
||||||
|
<textlimit>$textlimit</textlimit>
|
||||||
|
<ssl>$has_ssl</ssl>
|
||||||
|
<sslserver>$ssl_server</sslserver>
|
||||||
|
<shorturllength>30</shorturllength>
|
||||||
|
|
||||||
|
</site>
|
||||||
|
<license>
|
||||||
|
<type>cc</type>
|
||||||
|
<owner></owner>
|
||||||
|
<url>http://creativecommons.org/licenses/by/3.0/</url>
|
||||||
|
<title>Creative Commons Attribution 3.0</title>
|
||||||
|
<image>http://i.creativecommons.org/l/by/3.0/80x15.png</image>
|
||||||
|
|
||||||
|
</license>
|
||||||
|
<nickname>
|
||||||
|
<featured></featured>
|
||||||
|
</nickname>
|
||||||
|
<profile>
|
||||||
|
<biolimit></biolimit>
|
||||||
|
</profile>
|
||||||
|
<group>
|
||||||
|
<desclimit></desclimit>
|
||||||
|
</group>
|
||||||
|
<notice>
|
||||||
|
|
||||||
|
<contentlimit></contentlimit>
|
||||||
|
</notice>
|
||||||
|
<throttle>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
<count>20</count>
|
||||||
|
<timespan>600</timespan>
|
||||||
|
</throttle>
|
||||||
|
<xmpp>
|
||||||
|
|
||||||
|
<enabled>false</enabled>
|
||||||
|
<server>INVALID SERVER</server>
|
||||||
|
<port>5222</port>
|
||||||
|
<user>update</user>
|
||||||
|
</xmpp>
|
||||||
|
<integration>
|
||||||
|
<source>StatusNet</source>
|
||||||
|
|
||||||
|
</integration>
|
||||||
|
<attachments>
|
||||||
|
<uploads>false</uploads>
|
||||||
|
<file_quota>0</file_quota>
|
||||||
|
</attachments>
|
||||||
|
</config>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<decrypted_hdeader>
|
||||||
|
<iv>$inner_iv</iv>
|
||||||
|
<aes_key>$inner_key</aes_key>
|
||||||
|
<author>
|
||||||
|
<name>$author_name</name>
|
||||||
|
<uri>$author_uri</uri>
|
||||||
|
</author>
|
||||||
|
</decrypted_header>
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
<div class='field checkbox'>
|
||||||
|
<label for='id_$field.0'>$field.1</label>
|
||||||
|
<input type="checkbox" name='$field.0' id='id_$field.0' value="$field.3" {{ if $field.2 }}checked="true"{{ endif }}>
|
||||||
|
<span class='field_help'>$field.4</span>
|
||||||
|
</div>
|
|
@ -27,7 +27,7 @@ $lbl_03 $lbl_04 $lbl_05
|
||||||
<div id="install-dbdata-end"></div>
|
<div id="install-dbdata-end"></div>
|
||||||
|
|
||||||
<label for="install-admin" id="install-admin-label">$lbl_11</label>
|
<label for="install-admin" id="install-admin-label">$lbl_11</label>
|
||||||
<input type="text" name="adminemail" id="install-admin" value="$adminemail" />
|
<input type="text" name="adminmail" id="install-admin" value="$adminmail" />
|
||||||
<div id="install-admin-end"></div>
|
<div id="install-admin-end"></div>
|
||||||
|
|
||||||
<div id="install-tz-desc">
|
<div id="install-tz-desc">
|
||||||
|
|
|
@ -9,7 +9,7 @@ tinyMCE.init({
|
||||||
theme : "advanced",
|
theme : "advanced",
|
||||||
mode : "specific_textareas",
|
mode : "specific_textareas",
|
||||||
editor_selector: /(profile-jot-text|prvmail-text)/,
|
editor_selector: /(profile-jot-text|prvmail-text)/,
|
||||||
plugins : "bbcode,paste",
|
plugins : "bbcode,paste,autoresize",
|
||||||
theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
|
theme_advanced_buttons1 : "bold,italic,underline,undo,redo,link,unlink,image,forecolor,formatselect,code",
|
||||||
theme_advanced_buttons2 : "",
|
theme_advanced_buttons2 : "",
|
||||||
theme_advanced_buttons3 : "",
|
theme_advanced_buttons3 : "",
|
||||||
|
|
34
view/nav.tpl
34
view/nav.tpl
|
@ -2,48 +2,48 @@ $langselector
|
||||||
|
|
||||||
<div id="site-location">$sitelocation</div>
|
<div id="site-location">$sitelocation</div>
|
||||||
|
|
||||||
{{ if $nav.logout }}<a id="nav-logout-link" class="nav-link $nav.logout.2" href="$nav.logout.0">$nav.logout.1</a> {{ endif }}
|
{{ if $nav.logout }}<a id="nav-logout-link" class="nav-link $nav.logout.2" href="$nav.logout.0" title="$nav.logout.3" >$nav.logout.1</a> {{ endif }}
|
||||||
{{ if $nav.login }}<a id="nav-login-link" class="nav-login-link $nav.login.2" href="$nav.login.0">$nav.login.1</a> {{ endif }}
|
{{ if $nav.login }}<a id="nav-login-link" class="nav-login-link $nav.login.2" href="$nav.login.0" title="$nav.login.3" >$nav.login.1</a> {{ endif }}
|
||||||
|
|
||||||
<span id="nav-link-wrapper" >
|
<span id="nav-link-wrapper" >
|
||||||
|
|
||||||
{{ if $nav.register }}<a id="nav-register-link" class="nav-commlink $nav.register.2" href="$nav.register.0">$nav.register.1</a>{{ endif }}
|
{{ if $nav.register }}<a id="nav-register-link" class="nav-commlink $nav.register.2" href="$nav.register.0" title="$nav.register.3" >$nav.register.1</a>{{ endif }}
|
||||||
|
|
||||||
<a id="nav-help-link" class="nav-link $nav.help.2" target="friendika-help" href="$nav.help.0">$nav.help.1</a>
|
<a id="nav-help-link" class="nav-link $nav.help.2" target="friendika-help" href="$nav.help.0" title="$nav.help.3" >$nav.help.1</a>
|
||||||
|
|
||||||
{{ if $nav.apps }}<a id="nav-apps-link" class="nav-link $nav.apps.2" href="$nav.apps.0">$nav.apps.1</a>{{ endif }}
|
{{ if $nav.apps }}<a id="nav-apps-link" class="nav-link $nav.apps.2" href="$nav.apps.0" title="$nav.apps.3" >$nav.apps.1</a>{{ endif }}
|
||||||
|
|
||||||
<a id="nav-search-link" class="nav-link $nav.search.2" href="$nav.search.0">$nav.search.1</a>
|
<a id="nav-search-link" class="nav-link $nav.search.2" href="$nav.search.0" title="$nav.search.3" >$nav.search.1</a>
|
||||||
<a id="nav-directory-link" class="nav-link $nav.directory.2" href="$nav.directory.0">$nav.directory.1</a>
|
<a id="nav-directory-link" class="nav-link $nav.directory.2" href="$nav.directory.0" title="$nav.directory.3" >$nav.directory.1</a>
|
||||||
|
|
||||||
{{ if $nav.admin }}<a id="nav-admin-link" class="nav-link $nav.admin.2" href="$nav.admin.0">$nav.admin.1</a>{{ endif }}
|
{{ if $nav.admin }}<a id="nav-admin-link" class="nav-link $nav.admin.2" href="$nav.admin.0" title="$nav.admin.3" >$nav.admin.1</a>{{ endif }}
|
||||||
|
|
||||||
{{ if $nav.network }}
|
{{ if $nav.network }}
|
||||||
<a id="nav-network-link" class="nav-commlink $nav.network.2" href="$nav.network.0">$nav.network.1</a>
|
<a id="nav-network-link" class="nav-commlink $nav.network.2" href="$nav.network.0" title="$nav.network.3" >$nav.network.1</a>
|
||||||
<span id="net-update" class="nav-ajax-left"></span>
|
<span id="net-update" class="nav-ajax-left"></span>
|
||||||
{{ endif }}
|
{{ endif }}
|
||||||
{{ if $nav.home }}
|
{{ if $nav.home }}
|
||||||
<a id="nav-home-link" class="nav-commlink $nav.home.2" href="$nav.home.0">$nav.home.1</a>
|
<a id="nav-home-link" class="nav-commlink $nav.home.2" href="$nav.home.0" title="$nav.home.3" >$nav.home.1</a>
|
||||||
<span id="home-update" class="nav-ajax-left"></span>
|
<span id="home-update" class="nav-ajax-left"></span>
|
||||||
{{ endif }}
|
{{ endif }}
|
||||||
{{ if $nav.community }}
|
{{ if $nav.community }}
|
||||||
<a id="nav-community-link" class="nav-commlink $nav.community.2" href="$nav.community.0">$nav.community.1</a>
|
<a id="nav-community-link" class="nav-commlink $nav.community.2" href="$nav.community.0" title="$nav.community.3" >$nav.community.1</a>
|
||||||
{{ endif }}
|
{{ endif }}
|
||||||
{{ if $nav.notifications }}
|
{{ if $nav.notifications }}
|
||||||
<a id="nav-notify-link" class="nav-commlink $nav.notifications.2" href="$nav.notifications.0">$nav.notifications.1</a>
|
<a id="nav-notify-link" class="nav-commlink $nav.notifications.2" href="$nav.notifications.0" title="$nav.notifications.3" >$nav.notifications.1</a>
|
||||||
<span id="notify-update" class="nav-ajax-left"></span>
|
<span id="notify-update" class="nav-ajax-left"></span>
|
||||||
{{ endif }}
|
{{ endif }}
|
||||||
{{ if $nav.messages }}
|
{{ if $nav.messages }}
|
||||||
<a id="nav-messages-link" class="nav-commlink $nav.messages.2" href="$nav.messages.0">$nav.messages.1</a>
|
<a id="nav-messages-link" class="nav-commlink $nav.messages.2" href="$nav.messages.0" title="$nav.messages.3" >$nav.messages.1</a>
|
||||||
<span id="mail-update" class="nav-ajax-left"></span>
|
<span id="mail-update" class="nav-ajax-left"></span>
|
||||||
{{ endif }}
|
{{ endif }}
|
||||||
|
|
||||||
{{ if $nav.manage }}<a id="nav-manage-link" class="nav-commlink $nav.manage.2" href="$nav.manage.0">$nav.manage.1</a>{{ endif }}
|
{{ if $nav.manage }}<a id="nav-manage-link" class="nav-commlink $nav.manage.2" href="$nav.manage.0" title="$nav.manage.3">$nav.manage.1</a>{{ endif }}
|
||||||
|
|
||||||
{{ if $nav.settings }}<a id="nav-settings-link" class="nav-link $nav.settings.2" href="$nav.settings.0">$nav.settings.1</a>{{ endif }}
|
{{ if $nav.settings }}<a id="nav-settings-link" class="nav-link $nav.settings.2" href="$nav.settings.0" title="$nav.settings.3">$nav.settings.1</a>{{ endif }}
|
||||||
{{ if $nav.profiles }}<a id="nav-profiles-link" class="nav-link $nav.profiles.2" href="$nav.profiles.0">$nav.profiles.1</a>{{ endif }}
|
{{ if $nav.profiles }}<a id="nav-profiles-link" class="nav-link $nav.profiles.2" href="$nav.profiles.0" title="$nav.profiles.3" >$nav.profiles.1</a>{{ endif }}
|
||||||
|
|
||||||
{{ if $nav.contacts }}<a id="nav-contacts-link" class="nav-link $nav.contacts.2" href="$nav.contacts.0">$nav.contacts.1</a>{{ endif }}
|
{{ if $nav.contacts }}<a id="nav-contacts-link" class="nav-link $nav.contacts.2" href="$nav.contacts.0" title="$nav.contacts.3" >$nav.contacts.1</a>{{ endif }}
|
||||||
</span>
|
</span>
|
||||||
<span id="nav-end"></span>
|
<span id="nav-end"></span>
|
||||||
<span id="banner">$banner</span>
|
<span id="banner">$banner</span>
|
||||||
|
|
|
@ -16,6 +16,17 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="register-openid-end" ></div>
|
<div id="register-openid-end" ></div>
|
||||||
|
|
||||||
|
{{ if $invitations }}
|
||||||
|
|
||||||
|
<p id="register-invite-desc">$invite_desc</p>
|
||||||
|
<div id="register-invite-wrapper" >
|
||||||
|
<label for="register-invite" id="label-register-invite" >$invite_label</label>
|
||||||
|
<input type="text" maxlength="60" size="32" name="invite_id" id="register-invite" value="$invite_id" >
|
||||||
|
</div>
|
||||||
|
<div id="register-name-end" ></div>
|
||||||
|
|
||||||
|
{{ endif }}
|
||||||
|
|
||||||
|
|
||||||
<div id="register-name-wrapper" >
|
<div id="register-name-wrapper" >
|
||||||
<label for="register-name" id="label-register-name" >$namelabel</label>
|
<label for="register-name" id="label-register-name" >$namelabel</label>
|
||||||
|
|
|
@ -15,8 +15,9 @@ $nickname_block
|
||||||
{{inc field_password.tpl with $field=$password1 }}{{endinc}}
|
{{inc field_password.tpl with $field=$password1 }}{{endinc}}
|
||||||
{{inc field_password.tpl with $field=$password2 }}{{endinc}}
|
{{inc field_password.tpl with $field=$password2 }}{{endinc}}
|
||||||
|
|
||||||
|
{{ if $oid_enable }}
|
||||||
{{inc field_input.tpl with $field=$openid }}{{endinc}}
|
{{inc field_input.tpl with $field=$openid }}{{endinc}}
|
||||||
|
{{ endif }}
|
||||||
|
|
||||||
<div class="settings-submit-wrapper" >
|
<div class="settings-submit-wrapper" >
|
||||||
<input type="submit" name="submit" class="settings-submit" value="$submit" />
|
<input type="submit" name="submit" class="settings-submit" value="$submit" />
|
||||||
|
@ -82,11 +83,11 @@ $hide_wall
|
||||||
<div id="settings-notify-desc">$lbl_not </div>
|
<div id="settings-notify-desc">$lbl_not </div>
|
||||||
|
|
||||||
<div class="group">
|
<div class="group">
|
||||||
{{inc field_checkbox.tpl with $field=$notify1 }}{{endinc}}
|
{{inc field_intcheckbox.tpl with $field=$notify1 }}{{endinc}}
|
||||||
{{inc field_checkbox.tpl with $field=$notify2 }}{{endinc}}
|
{{inc field_intcheckbox.tpl with $field=$notify2 }}{{endinc}}
|
||||||
{{inc field_checkbox.tpl with $field=$notify3 }}{{endinc}}
|
{{inc field_intcheckbox.tpl with $field=$notify3 }}{{endinc}}
|
||||||
{{inc field_checkbox.tpl with $field=$notify4 }}{{endinc}}
|
{{inc field_intcheckbox.tpl with $field=$notify4 }}{{endinc}}
|
||||||
{{inc field_checkbox.tpl with $field=$notify5 }}{{endinc}}
|
{{inc field_intcheckbox.tpl with $field=$notify5 }}{{endinc}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,8 @@ code {
|
||||||
border: 1px solid #444;
|
border: 1px solid #444;
|
||||||
background: #EEE;
|
background: #EEE;
|
||||||
color: #444;
|
color: #444;
|
||||||
padding: 10px;
|
padding: 0px 10px 10px 10px;
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
/*blockquote:before {
|
/*blockquote:before {
|
||||||
content: '>> ';
|
content: '>> ';
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -12,6 +12,13 @@ a:hover {text-decoration: underline; }
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: block; width: 16px; height: 16px;
|
||||||
|
background-image: url('greenicons.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body { background-image: url(head.jpg); }
|
body { background-image: url(head.jpg); }
|
||||||
aside( background-image: url(border.jpg); }
|
aside( background-image: url(border.jpg); }
|
||||||
section { background-image: url(border.jpg); }
|
section { background-image: url(border.jpg); }
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<Link rel="http://joindiaspora.com/seed_location" type="text/html" href="$baseurl/" />
|
||||||
|
<Link rel="http://joindiaspora.com/guid" type="text/html" href="$dspr_guid" />
|
||||||
|
<Link rel="diaspora-public-key" type="RSA" href="$dspr_key" />
|
|
@ -19,6 +19,7 @@
|
||||||
<Link rel="http://webfinger.net/rel/avatar"
|
<Link rel="http://webfinger.net/rel/avatar"
|
||||||
type="image/jpeg"
|
type="image/jpeg"
|
||||||
href="$photo" />
|
href="$photo" />
|
||||||
|
$dspr
|
||||||
<Link rel="salmon"
|
<Link rel="salmon"
|
||||||
href="$salmon" />
|
href="$salmon" />
|
||||||
<Link rel="http://salmon-protocol.org/ns/salmon-replies"
|
<Link rel="http://salmon-protocol.org/ns/salmon-replies"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user