Merge branch 'master' of git://github.com/friendica/friendica
This commit is contained in:
commit
12474e3c2e
47
INSTALL.txt
47
INSTALL.txt
|
@ -222,3 +222,50 @@ Retry the installation. As soon as the database has been created,
|
|||
|
||||
% chmod 755 .htconfig.php
|
||||
|
||||
#####################################################################
|
||||
- Some configurations with "suhosin" security are configured without
|
||||
an ability to run external processes. Friendica requires this ability.
|
||||
Following are some notes provided by one of our members.
|
||||
#####################################################################
|
||||
|
||||
On my server I use the php protection system Suhosin
|
||||
[http://www.hardened-php.net/suhosin/]. One of the things it does is to block
|
||||
certain functions like proc_open, as configured in /etc/php5/conf.d/suhosin.ini:
|
||||
|
||||
suhosin.executor.func.blacklist = proc_open, ...
|
||||
|
||||
For those sites like Friendica that really need these functions they can be
|
||||
enabled, e.g. in /etc/apache2/sites-available/friendica:
|
||||
|
||||
<Directory /var/www/friendica/>
|
||||
php_admin_value suhosin.executor.func.blacklist none
|
||||
php_admin_value suhosin.executor.eval.blacklist none
|
||||
</Directory>
|
||||
|
||||
This enables every function for Friendica if accessed via browser, but not for
|
||||
the cronjob that is called via php command line. I attempted to enable it for
|
||||
cron by using something like
|
||||
|
||||
*/10 * * * * cd /var/www/friendica/friendica/ && sudo -u www-data /usr/bin/php
|
||||
-d suhosin.executor.func.blacklist=none -d suhosin.executor.eval.blacklist=none
|
||||
-f include/poller.php
|
||||
|
||||
This worked well for simple test cases, but the friendica-cron still failed with
|
||||
a fatal error:
|
||||
suhosin[22962]: ALERT - function within blacklist called: proc_open() (attacker
|
||||
'REMOTE_ADDR not set', file '/var/www/friendica/friendica/boot.php', line 1341)
|
||||
|
||||
After a while I noticed, that include/poller.php calls further php script via
|
||||
proc_open. These scripts themselves also use proc_open and fail, because they
|
||||
are NOT called with -d suhosin.executor.func.blacklist=none.
|
||||
|
||||
So the simple solution is to put the correct parameters into .htconfig.php:
|
||||
// Location of PHP command line processor
|
||||
$a->config['php_path'] = '/usr/bin/php -d suhosin.executor.func.blacklist=none
|
||||
-d suhosin.executor.eval.blacklist=none';
|
||||
|
||||
|
||||
This is obvious as soon as you notice that the friendica-cron uses proc_open to
|
||||
execute php-scripts that also use proc_open, but it took me quite some time to
|
||||
find that out. I hope this saves some time for other people using suhosin with
|
||||
function blacklists.
|
||||
|
|
41
boot.php
41
boot.php
|
@ -9,9 +9,9 @@ require_once('include/nav.php');
|
|||
require_once('include/cache.php');
|
||||
|
||||
define ( 'FRIENDICA_PLATFORM', 'Friendica');
|
||||
define ( 'FRIENDICA_VERSION', '3.0.1338' );
|
||||
define ( 'FRIENDICA_VERSION', '3.0.1363' );
|
||||
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
|
||||
define ( 'DB_UPDATE_VERSION', 1143 );
|
||||
define ( 'DB_UPDATE_VERSION', 1148 );
|
||||
|
||||
define ( 'EOL', "<br />\r\n" );
|
||||
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
|
||||
|
@ -441,18 +441,15 @@ if(! class_exists('App')) {
|
|||
if(intval($this->config['system']['ssl_policy']) === intval(SSL_POLICY_FULL))
|
||||
$scheme = 'https';
|
||||
|
||||
// We need to populate the $ssl flag across the entire program before turning this on.
|
||||
// Basically, we'll have $ssl = true on any links which can only be seen by a logged in user
|
||||
// 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.
|
||||
// At present, setting SSL_POLICY_SELFSIGN will only force remote contacts to update their
|
||||
// contact links to this site with "http:" if they are currently using "https:"
|
||||
|
||||
// if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) {
|
||||
// if($ssl)
|
||||
// $scheme = 'https';
|
||||
// else
|
||||
// $scheme = 'http';
|
||||
// }
|
||||
if($this->config['system']['ssl_policy'] == SSL_POLICY_SELFSIGN) {
|
||||
if($ssl)
|
||||
$scheme = 'https';
|
||||
else
|
||||
$scheme = 'http';
|
||||
}
|
||||
}
|
||||
|
||||
$this->baseurl = $scheme . "://" . $this->hostname . ((isset($this->path) && strlen($this->path)) ? '/' . $this->path : '' );
|
||||
|
@ -511,6 +508,7 @@ if(! class_exists('App')) {
|
|||
$tpl = file_get_contents('view/head.tpl');
|
||||
$this->page['htmlhead'] = replace_macros($tpl,array(
|
||||
'$baseurl' => $this->get_baseurl(), // FIXME for z_path!!!!
|
||||
'$local_user' => local_user(),
|
||||
'$generator' => 'Friendica' . ' ' . FRIENDICA_VERSION,
|
||||
'$delitem' => t('Delete this item?'),
|
||||
'$comment' => t('Comment'),
|
||||
|
@ -1323,6 +1321,25 @@ if(! function_exists('proc_run')) {
|
|||
$a = get_app();
|
||||
|
||||
$args = func_get_args();
|
||||
|
||||
$newargs = array();
|
||||
if(! count($args))
|
||||
return;
|
||||
|
||||
// expand any arrays
|
||||
|
||||
foreach($args as $arg) {
|
||||
if(is_array($arg)) {
|
||||
foreach($arg as $n) {
|
||||
$newargs[] = $n;
|
||||
}
|
||||
}
|
||||
else
|
||||
$newargs[] = $arg;
|
||||
}
|
||||
|
||||
$args = $newargs;
|
||||
|
||||
$arr = array('args' => $args, 'run_cmd' => true);
|
||||
|
||||
call_hooks("proc_run", $arr);
|
||||
|
|
19
convert_innodb.sql
Normal file
19
convert_innodb.sql
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
ALTER TABLE `profile` DROP INDEX `pub_keywords` ;
|
||||
ALTER TABLE `profile` DROP INDEX `prv_keywords` ;
|
||||
|
||||
ALTER TABLE `item` DROP INDEX `title` ;
|
||||
ALTER TABLE `item` DROP INDEX `body` ;
|
||||
ALTER TABLE `item` DROP INDEX `allow_cid` ;
|
||||
ALTER TABLE `item` DROP INDEX `allow_gid` ;
|
||||
ALTER TABLE `item` DROP INDEX `deny_cid` ;
|
||||
ALTER TABLE `item` DROP INDEX `deny_gid` ;
|
||||
ALTER TABLE `item` DROP INDEX `tag` ;
|
||||
ALTER TABLE `item` DROP INDEX `file` ;
|
||||
|
||||
|
||||
SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' engine=InnoDB;')
|
||||
FROM information_schema.tables
|
||||
WHERE engine = 'MyISAM';
|
||||
|
10
database.sql
10
database.sql
|
@ -173,6 +173,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
|
|||
`readonly` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`writable` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`forum` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`prv` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`hidden` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`archive` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`pending` tinyint(1) NOT NULL DEFAULT '1',
|
||||
|
@ -819,9 +820,11 @@ CREATE TABLE IF NOT EXISTS `profile` (
|
|||
`region` char(255) NOT NULL,
|
||||
`postal-code` char(32) NOT NULL,
|
||||
`country-name` char(255) NOT NULL,
|
||||
`hometown` char(255) NOT NULL,
|
||||
`gender` char(32) NOT NULL,
|
||||
`marital` char(255) NOT NULL,
|
||||
`with` text NOT NULL,
|
||||
`howlong` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
`sexual` char(255) NOT NULL,
|
||||
`politic` char(255) NOT NULL,
|
||||
`religion` char(255) NOT NULL,
|
||||
|
@ -941,12 +944,14 @@ CREATE TABLE IF NOT EXISTS `session` (
|
|||
|
||||
CREATE TABLE IF NOT EXISTS `sign` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`iid` int(10) unsigned NOT NULL,
|
||||
`iid` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`retract_iid` int(10) unsigned NOT NULL DEFAULT '0',
|
||||
`signed_text` mediumtext NOT NULL,
|
||||
`signature` text NOT NULL,
|
||||
`signer` char(255) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `iid` (`iid`)
|
||||
KEY `iid` (`iid`),
|
||||
KEY `retract_iid` (`retract_iid`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
@ -1028,6 +1033,7 @@ CREATE TABLE IF NOT EXISTS `user` (
|
|||
`account_expires_on` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`expire_notification_sent` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`service_class` char(32) NOT NULL,
|
||||
`def_gid` int(11) NOT NULL DEFAULT '0',
|
||||
`allow_cid` mediumtext NOT NULL,
|
||||
`allow_gid` mediumtext NOT NULL,
|
||||
`deny_cid` mediumtext NOT NULL,
|
||||
|
|
|
@ -88,3 +88,6 @@ $a->config['system']['itemcache'] = "";
|
|||
|
||||
// If enabled, the lockpath is used for a lockfile to check if the poller is running
|
||||
$a->config['system']['lockpath'] = "";
|
||||
|
||||
// If enabled, the MyBB fulltext engine is used
|
||||
// $a->config['system']['use_fulltext_engine'] = true;
|
||||
|
|
BIN
images/icons.png
BIN
images/icons.png
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -209,7 +209,7 @@ function contact_photo_menu($contact) {
|
|||
);
|
||||
|
||||
|
||||
$args = array('contact' => $contact, 'menu' => $menu);
|
||||
$args = array('contact' => $contact, 'menu' => &$menu);
|
||||
|
||||
call_hooks('contact_photo_menu', $args);
|
||||
|
||||
|
|
|
@ -87,6 +87,12 @@ class Photo {
|
|||
|
||||
}
|
||||
|
||||
public function rotate($degrees) {
|
||||
$this->image = imagerotate($this->image,$degrees,0);
|
||||
$this->width = imagesx($this->image);
|
||||
$this->height = imagesy($this->image);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function scaleImageUp($min) {
|
||||
|
|
|
@ -985,10 +985,18 @@
|
|||
$myurl = substr($myurl,strpos($myurl,'://')+3);
|
||||
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
|
||||
$diasp_url = str_replace('/profile/','/u/',$myurl);
|
||||
$sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` regexp '%s' or `tag` regexp '%s' or tag regexp '%s' )) ",
|
||||
dbesc($myurl . '$'),
|
||||
dbesc($myurl . '\\]'),
|
||||
dbesc($diasp_url . '\\]')
|
||||
|
||||
if (get_config('system','use_fulltext_engine'))
|
||||
$sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where (MATCH(`author-link`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(`tag`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode))) ",
|
||||
dbesc(protect_sprintf($myurl)),
|
||||
dbesc(protect_sprintf($myurl)),
|
||||
dbesc(protect_sprintf($diasp_url))
|
||||
);
|
||||
else
|
||||
$sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` like '%s' or `tag` like '%s' or tag like '%s' )) ",
|
||||
dbesc(protect_sprintf('%' . $myurl)),
|
||||
dbesc(protect_sprintf('%' . $myurl . ']%')),
|
||||
dbesc(protect_sprintf('%' . $diasp_url . ']%'))
|
||||
);
|
||||
|
||||
if ($max_id > 0)
|
||||
|
@ -1251,6 +1259,9 @@
|
|||
else
|
||||
$statustext = trim($statustitle."\n\n".$statusbody);
|
||||
|
||||
if (($item["network"] == NETWORK_FEED) and (strlen($statustext)> 1000))
|
||||
$statustext = substr($statustext, 0, 1000)."... \n".$item["plink"];
|
||||
|
||||
$status = array(
|
||||
'text' => $statustext,
|
||||
'truncated' => False,
|
||||
|
|
|
@ -11,6 +11,13 @@ function nuke_session() {
|
|||
unset($_SESSION['cid']);
|
||||
unset($_SESSION['theme']);
|
||||
unset($_SESSION['page_flags']);
|
||||
unset($_SESSION['submanage']);
|
||||
unset($_SESSION['my_url']);
|
||||
unset($_SESSION['my_address']);
|
||||
unset($_SESSION['addr']);
|
||||
unset($_SESSION['return_url']);
|
||||
unset($_SESSION['theme']);
|
||||
unset($_SESSION['page_flags']);
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,6 +53,8 @@ if((isset($_SESSION)) && (x($_SESSION,'authenticated')) && ((! (x($_POST,'auth-p
|
|||
$check = get_config('system','paranoia');
|
||||
// extra paranoia - if the IP changed, log them out
|
||||
if($check && ($_SESSION['addr'] != $_SERVER['REMOTE_ADDR'])) {
|
||||
logger('Session address changed. Paranoid setting in effect, blocking session. '
|
||||
. $_SESSION['addr'] . ' != ' . $_SERVER['REMOTE_ADDR']);
|
||||
nuke_session();
|
||||
goaway(z_root());
|
||||
}
|
||||
|
|
|
@ -221,13 +221,18 @@ function bb2diaspora($Text,$preserve_nl = false) {
|
|||
|
||||
$Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text);
|
||||
|
||||
$Text = preg_replace('/\[(.*?)\]\((.*?)\\\\_(.*?)\)/ism','[$1]($2_$3)',$Text);
|
||||
$Text = preg_replace_callback('/\[(.*?)\]\((.*?)\)/ism','unescape_underscores_in_links',$Text);
|
||||
|
||||
call_hooks('bb2diaspora',$Text);
|
||||
|
||||
return $Text;
|
||||
}
|
||||
|
||||
function unescape_underscores_in_links($m) {
|
||||
$y = str_replace('\\_','_', $m[2]);
|
||||
return('[' . $m[1] . '](' . $y . ')');
|
||||
}
|
||||
|
||||
function format_event_diaspora($ev) {
|
||||
|
||||
$a = get_app();
|
||||
|
|
|
@ -52,6 +52,8 @@ function bb_unspacefy_and_trim($st) {
|
|||
|
||||
function bbcode($Text,$preserve_nl = false) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
// Hide all [noparse] contained bbtags spacefying them
|
||||
|
||||
$Text = preg_replace_callback("/\[noparse\](.*?)\[\/noparse\]/ism", 'bb_spacefy',$Text);
|
||||
|
@ -114,6 +116,11 @@ function bbcode($Text,$preserve_nl = false) {
|
|||
$Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '<a href="$1" target="external-link">$2</a>', $Text);
|
||||
//$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", '<a href="$1" target="_blank">$2</a>', $Text);
|
||||
|
||||
// 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);
|
||||
|
||||
// Perform MAIL Search
|
||||
$Text = preg_replace("/\[mail\]([$MAILSearchString]*)\[\/mail\]/", '<a href="mailto:$1">$1</a>', $Text);
|
||||
|
@ -226,7 +233,7 @@ function bbcode($Text,$preserve_nl = false) {
|
|||
$endlessloop = 0;
|
||||
while ((strpos($Text, "[/quote]")!== false) and (strpos($Text, "[quote=") !== false) and (++$endlessloop < 20))
|
||||
$Text = preg_replace("/\[quote=[\"\']*(.*?)[\"\']*\](.*?)\[\/quote\]/ism",
|
||||
"<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote class=".'"author"'.">$2</blockquote>",
|
||||
"<br /><strong class=".'"author"'.">" . $t_wrote . "</strong><blockquote>$2</blockquote>",
|
||||
$Text);
|
||||
|
||||
// [img=widthxheight]image source[/img]
|
||||
|
|
|
@ -30,6 +30,9 @@ function load_config($family) {
|
|||
$a->config[$family][$k] = $rr['v'];
|
||||
}
|
||||
}
|
||||
} else if ($rr['cat'] != 'config') {
|
||||
// Negative caching
|
||||
$a->config[$family] = "!<unset>!";
|
||||
}
|
||||
}}
|
||||
|
||||
|
@ -47,6 +50,13 @@ function get_config($family, $key, $instore = false) {
|
|||
global $a;
|
||||
|
||||
if(! $instore) {
|
||||
// Looking if the whole family isn't set
|
||||
if(isset($a->config[$family])) {
|
||||
if($a->config[$family] === '!<unset>!') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($a->config[$family][$key])) {
|
||||
if($a->config[$family][$key] === '!<unset>!') {
|
||||
return false;
|
||||
|
@ -77,11 +87,9 @@ function get_config($family, $key, $instore = false) {
|
|||
if(! function_exists('set_config')) {
|
||||
function set_config($family,$key,$value) {
|
||||
global $a;
|
||||
|
||||
// manage array value
|
||||
$dbvalue = (is_array($value)?serialize($value):$value);
|
||||
$dbvalue = (is_bool($value) ? intval($value) : $value);
|
||||
|
||||
$dbvalue = (is_bool($dbvalue) ? intval($dbvalue) : $dbvalue);
|
||||
if(get_config($family,$key,true) === false) {
|
||||
$a->config[$family][$key] = $value;
|
||||
$ret = q("INSERT INTO `config` ( `cat`, `k`, `v` ) VALUES ( '%s', '%s', '%s' ) ",
|
||||
|
@ -120,6 +128,9 @@ function load_pconfig($uid,$family) {
|
|||
$k = $rr['k'];
|
||||
$a->config[$uid][$family][$k] = $rr['v'];
|
||||
}
|
||||
} else if ($rr['cat'] != 'config') {
|
||||
// Negative caching
|
||||
$a->config[$uid][$family] = "!<unset>!";
|
||||
}
|
||||
}}
|
||||
|
||||
|
@ -131,6 +142,13 @@ function get_pconfig($uid,$family, $key, $instore = false) {
|
|||
global $a;
|
||||
|
||||
if(! $instore) {
|
||||
// Looking if the whole family isn't set
|
||||
if(isset($a->config[$uid][$family])) {
|
||||
if($a->config[$uid][$family] === '!<unset>!') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($a->config[$uid][$family][$key])) {
|
||||
if($a->config[$uid][$family][$key] === '!<unset>!') {
|
||||
return false;
|
||||
|
|
|
@ -173,6 +173,13 @@ function localize_item(&$item){
|
|||
$item['body'] = str_replace($mtch[0],'@[url=' . zrl($mtch[1]). ']',$item['body']);
|
||||
}
|
||||
}
|
||||
if(preg_match_all('/\[url=(.*?)\/photos\/(.*?)\/image\/(.*?)\]\[img(.*?)\]h(.*?)\[\/img\]\[\/url\]/is',$item['body'],$matches,PREG_SET_ORDER)) {
|
||||
logger('matched');
|
||||
foreach($matches as $mtch) {
|
||||
$item['body'] = str_replace($mtch[0],'[url=' . zrl($mtch[1] . '/photos/' . $mtch[2] . '/image/' . $mtch[3] ,true) . '][img' . $mtch[4] . ']h' . $mtch[5] . '[/img][/url]',$item['body']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -495,7 +502,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
|
||||
// On the network page, I am the owner. On the display page it will be the profile owner.
|
||||
// This will have been stored in $a->page_contact by our calling page.
|
||||
// Put this person on the left of the wall-to-wall notice.
|
||||
// Put this person as the wall owner of the wall-to-wall notice.
|
||||
|
||||
$owner_url = zrl($a->page_contact['url']);
|
||||
$owner_photo = $a->page_contact['thumb'];
|
||||
|
@ -503,9 +510,23 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
$template = $wallwall;
|
||||
$commentww = 'ww';
|
||||
}
|
||||
if((! $item['wall']) && (strlen($item['owner-link'])) && (! link_compare($item['owner-link'],$item['author-link']))) {
|
||||
|
||||
// Could be anybody.
|
||||
if((! $item['wall']) && $item['owner-link']) {
|
||||
|
||||
$owner_linkmatch = (($item['owner-link']) && link_compare($item['owner-link'],$item['author-link']));
|
||||
$alias_linkmatch = (($item['alias']) && link_compare($item['alias'],$item['author-link']));
|
||||
$owner_namematch = (($item['owner-name']) && $item['owner-name'] == $item['author-name']);
|
||||
if((! $owner_linkmatch) && (! $alias_linkmatch) && (! $owner_namematch)) {
|
||||
|
||||
// The author url doesn't match the owner (typically the contact)
|
||||
// and also doesn't match the contact alias.
|
||||
// The name match is a hack to catch several weird cases where URLs are
|
||||
// all over the park. It can be tricked, but this prevents you from
|
||||
// seeing "Bob Smith to Bob Smith via Wall-to-wall" and you know darn
|
||||
// well that it's the same Bob Smith.
|
||||
|
||||
// But it could be somebody else with the same name. It just isn't highly likely.
|
||||
|
||||
|
||||
$owner_url = $item['owner-link'];
|
||||
$owner_photo = $item['owner-avatar'];
|
||||
|
@ -522,6 +543,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
$owner_url = zrl($owner_url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$likebuttons = '';
|
||||
$shareable = ((($profile_owner == local_user()) && (! $item['private'])) ? true : false); //($mode != 'display') &&
|
||||
|
|
|
@ -293,3 +293,37 @@ function zot_unencapsulate($data,$prvkey) {
|
|||
$ret['data'] = aes_unencapsulate($x,$prvkey);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function new_keypair($bits) {
|
||||
|
||||
$openssl_options = array(
|
||||
'digest_alg' => 'sha1',
|
||||
'private_key_bits' => $bits,
|
||||
'encrypt_key' => false
|
||||
);
|
||||
|
||||
$conf = get_config('system','openssl_conf_file');
|
||||
if($conf)
|
||||
$openssl_options['config'] = $conf;
|
||||
|
||||
$result = openssl_pkey_new($openssl_options);
|
||||
|
||||
if(empty($result)) {
|
||||
logger('new_keypair: failed');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get private key
|
||||
|
||||
$response = array('prvkey' => '', 'pubkey' => '');
|
||||
|
||||
openssl_pkey_export($result, $response['prvkey']);
|
||||
|
||||
// Get public key
|
||||
$pkey = openssl_pkey_get_details($result);
|
||||
$response['pubkey'] = $pkey["key"];
|
||||
|
||||
return $response;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -244,7 +244,7 @@ function timesel($pre,$h,$m) {
|
|||
// Limited to range of timestamps
|
||||
|
||||
if(! function_exists('relative_date')) {
|
||||
function relative_date($posted_date) {
|
||||
function relative_date($posted_date,$format = null) {
|
||||
|
||||
$localtime = datetime_convert('UTC',date_default_timezone_get(),$posted_date);
|
||||
|
||||
|
@ -274,7 +274,9 @@ function relative_date($posted_date) {
|
|||
if ($d >= 1) {
|
||||
$r = round($d);
|
||||
// translators - e.g. 22 hours ago, 1 minute ago
|
||||
return sprintf( t('%1$d %2$s ago'),$r, (($r == 1) ? $str[0] : $str[1]));
|
||||
if(! $format)
|
||||
$format = t('%1$d %2$s ago');
|
||||
return sprintf( $format,$r, (($r == 1) ? $str[0] : $str[1]));
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
|
|
@ -77,11 +77,17 @@ class dba {
|
|||
|
||||
$this->error = '';
|
||||
|
||||
//if (get_config("system", "db_log") != "")
|
||||
// @file_put_contents(get_config("system", "db_log"), datetime_convert().':'.session_id(). ' Start '.$sql."\n", FILE_APPEND);
|
||||
|
||||
if($this->mysqli)
|
||||
$result = @$this->db->query($sql);
|
||||
else
|
||||
$result = @mysql_query($sql,$this->db);
|
||||
|
||||
//if (get_config("system", "db_log") != "")
|
||||
// @file_put_contents(get_config("system", "db_log"), datetime_convert().':'.session_id(). ' Stop '."\n", FILE_APPEND);
|
||||
|
||||
if($this->mysqli) {
|
||||
if($this->db->errno)
|
||||
$this->error = $this->db->error;
|
||||
|
|
|
@ -38,7 +38,10 @@ function delivery_run($argv, $argc){
|
|||
|
||||
$cmd = $argv[1];
|
||||
$item_id = intval($argv[2]);
|
||||
$contact_id = intval($argv[3]);
|
||||
|
||||
for($x = 3; $x < $argc; $x ++) {
|
||||
|
||||
$contact_id = intval($argv[$x]);
|
||||
|
||||
// Some other process may have delivered this item already.
|
||||
|
||||
|
@ -48,7 +51,7 @@ function delivery_run($argv, $argc){
|
|||
dbesc($contact_id)
|
||||
);
|
||||
if(! count($r)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
$maxsysload = intval(get_config('system','maxloadavg'));
|
||||
|
@ -71,7 +74,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if((! $item_id) || (! $contact_id))
|
||||
return;
|
||||
continue;
|
||||
|
||||
$expire = false;
|
||||
$top_level = false;
|
||||
|
@ -92,7 +95,7 @@ function delivery_run($argv, $argc){
|
|||
$uid = $item_id;
|
||||
$item_id = 0;
|
||||
if(! count($items))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -102,7 +105,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if((! count($r)) || (! intval($r[0]['parent']))) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
$target_item = $r[0];
|
||||
|
@ -110,8 +113,9 @@ function delivery_run($argv, $argc){
|
|||
$uid = $r[0]['uid'];
|
||||
$updated = $r[0]['edited'];
|
||||
|
||||
// The following seems superfluous. We've already checked for "if (! intval($r[0]['parent']))" a few lines up
|
||||
if(! $parent_id)
|
||||
return;
|
||||
continue;
|
||||
|
||||
|
||||
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
|
||||
|
@ -120,7 +124,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if(! count($items)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
$icontacts = null;
|
||||
|
@ -135,7 +139,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
}
|
||||
if( ! ($icontacts && count($icontacts)))
|
||||
return;
|
||||
continue;
|
||||
|
||||
// avoid race condition with deleting entries
|
||||
|
||||
|
@ -159,7 +163,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if(! count($r))
|
||||
return;
|
||||
continue;
|
||||
|
||||
$owner = $r[0];
|
||||
|
||||
|
@ -209,7 +213,7 @@ function delivery_run($argv, $argc){
|
|||
logger('relay denied for delivery agent.');
|
||||
|
||||
/* no relay allowed for direct contact delivery */
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((strlen($parent['allow_cid']))
|
||||
|
@ -233,7 +237,7 @@ function delivery_run($argv, $argc){
|
|||
require_once('include/salmon.php');
|
||||
|
||||
if($contact['self'])
|
||||
return;
|
||||
continue;
|
||||
|
||||
$deliver_status = 0;
|
||||
|
||||
|
@ -285,7 +289,7 @@ function delivery_run($argv, $argc){
|
|||
|
||||
if($normal_mode) {
|
||||
if($item_id == $item['id'] || $item['id'] == $item['parent'])
|
||||
$atom .= atom_entry($item,'text',null,$owner,true);
|
||||
$atom .= atom_entry($item,'text',null,$owner,true,(($top_level) ? $contact['id'] : 0));
|
||||
}
|
||||
else
|
||||
$atom .= atom_entry($item,'text',null,$owner,true);
|
||||
|
@ -505,17 +509,17 @@ function delivery_run($argv, $argc){
|
|||
// unsupported
|
||||
break;
|
||||
}
|
||||
elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
|
||||
elseif(($target_item['deleted']) && ($target_item['uri'] === $target_item['parent-uri'])) {
|
||||
// top-level retraction
|
||||
logger('delivery: diaspora retract: ' . $loc);
|
||||
// diaspora delete,
|
||||
|
||||
diaspora_send_retraction($target_item,$owner,$contact,$public_message);
|
||||
break;
|
||||
}
|
||||
elseif($target_item['parent'] != $target_item['id']) {
|
||||
|
||||
elseif($target_item['uri'] !== $target_item['parent-uri']) {
|
||||
// we are the relay - send comments, likes and relayable_retractions to our conversants
|
||||
logger('delivery: diaspora relay: ' . $loc);
|
||||
|
||||
// we are the relay - send comments, likes and unlikes to our conversants
|
||||
diaspora_send_relay($target_item,$owner,$contact,$public_message);
|
||||
break;
|
||||
}
|
||||
|
@ -537,6 +541,7 @@ function delivery_run($argv, $argc){
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
205
include/diaspora.php
Normal file → Executable file
205
include/diaspora.php
Normal file → Executable file
|
@ -83,6 +83,9 @@ function diaspora_dispatch($importer,$msg) {
|
|||
elseif($xmlbase->signed_retraction) {
|
||||
$ret = diaspora_signed_retraction($importer,$xmlbase->signed_retraction,$msg);
|
||||
}
|
||||
elseif($xmlbase->relayable_retraction) {
|
||||
$ret = diaspora_signed_retraction($importer,$xmlbase->relayable_retraction,$msg);
|
||||
}
|
||||
elseif($xmlbase->photo) {
|
||||
$ret = diaspora_photo($importer,$xmlbase->photo,$msg);
|
||||
}
|
||||
|
@ -569,6 +572,14 @@ function diaspora_request($importer,$xml) {
|
|||
return;
|
||||
}
|
||||
|
||||
$g = q("select def_gid from user where uid = %d limit 1",
|
||||
intval($importer['uid'])
|
||||
);
|
||||
if($g && intval($g[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member($importer['uid'],'',$contact_record['id'],$g[0]['def_gid']);
|
||||
}
|
||||
|
||||
if($importer['page-flags'] == PAGE_NORMAL) {
|
||||
|
||||
$hash = random_string() . (string) time(); // Generate a confirm_key
|
||||
|
@ -1594,22 +1605,28 @@ function diaspora_like($importer,$xml,$msg) {
|
|||
logger('diaspora_like: duplicate like: ' . $guid);
|
||||
return;
|
||||
}
|
||||
// Note: I don't think "Like" objects with positive = "false" are ever actually used
|
||||
// It looks like "RelayableRetractions" are used for "unlike" instead
|
||||
if($positive === 'false') {
|
||||
q("UPDATE `item` SET `deleted` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
logger('diaspora_like: received a like with positive set to "false"...ignoring');
|
||||
/* q("UPDATE `item` SET `deleted` = 1 WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval($r[0]['id']),
|
||||
intval($importer['uid'])
|
||||
);
|
||||
);*/
|
||||
// FIXME
|
||||
// send notification via proc_run()
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Note: I don't think "Like" objects with positive = "false" are ever actually used
|
||||
// It looks like "RelayableRetractions" are used for "unlike" instead
|
||||
if($positive === 'false') {
|
||||
logger('diaspora_like: unlike received with no corresponding like');
|
||||
logger('diaspora_like: received a like with positive set to "false"');
|
||||
logger('diaspora_like: unlike received with no corresponding like...ignoring');
|
||||
return;
|
||||
}
|
||||
|
||||
$author_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
|
||||
$signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
|
||||
|
||||
$author_signature = base64_decode($author_signature);
|
||||
|
||||
|
@ -1627,20 +1644,20 @@ function diaspora_like($importer,$xml,$msg) {
|
|||
}
|
||||
}
|
||||
|
||||
if(! rsa_verify($author_signed_data,$author_signature,$key,'sha256')) {
|
||||
if(! rsa_verify($signed_data,$author_signature,$key,'sha256')) {
|
||||
logger('diaspora_like: verification failed.');
|
||||
return;
|
||||
}
|
||||
|
||||
if($parent_author_signature) {
|
||||
|
||||
$owner_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
|
||||
//$owner_signed_data = $guid . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $diaspora_handle;
|
||||
|
||||
$parent_author_signature = base64_decode($parent_author_signature);
|
||||
|
||||
$key = $msg['key'];
|
||||
|
||||
if(! rsa_verify($owner_signed_data,$parent_author_signature,$key,'sha256')) {
|
||||
if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
|
||||
logger('diaspora_like: owner verification failed.');
|
||||
return;
|
||||
}
|
||||
|
@ -1775,38 +1792,89 @@ function diaspora_signed_retraction($importer,$xml,$msg) {
|
|||
$type = notags(unxmlify($xml->target_type));
|
||||
$sig = notags(unxmlify($xml->target_author_signature));
|
||||
|
||||
$parent_author_signature = (($xml->parent_author_signature) ? notags(unxmlify($xml->parent_author_signature)) : '');
|
||||
|
||||
$contact = diaspora_get_contact_by_handle($importer['uid'],$diaspora_handle);
|
||||
if(! $contact) {
|
||||
logger('diaspora_signed_retraction: no contact');
|
||||
return;
|
||||
}
|
||||
|
||||
// this may not yet work for comments. Need to see how the relaying works
|
||||
// and figure out who signs it.
|
||||
|
||||
|
||||
$signed_data = $guid . ';' . $type ;
|
||||
|
||||
$sig = base64_decode($sig);
|
||||
$sig_decode = base64_decode($sig);
|
||||
|
||||
if(strcasecmp($diaspora_handle,$msg['author']) == 0) {
|
||||
$person = $contact;
|
||||
$key = $msg['key'];
|
||||
}
|
||||
else {
|
||||
$person = find_diaspora_person_by_handle($diaspora_handle);
|
||||
|
||||
if(! rsa_verify($signed_data,$sig,$key,'sha256')) {
|
||||
logger('diaspora_signed_retraction: owner verification failed.' . print_r($msg,true));
|
||||
if(is_array($person) && x($person,'pubkey'))
|
||||
$key = $person['pubkey'];
|
||||
else {
|
||||
logger('diaspora_signed_retraction: unable to find author details');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(! rsa_verify($signed_data,$sig_decode,$key,'sha256')) {
|
||||
logger('diaspora_signed_retraction: retraction-owner verification failed.' . print_r($msg,true));
|
||||
return;
|
||||
}
|
||||
|
||||
if($type === 'StatusMessage') {
|
||||
if($parent_author_signature) {
|
||||
$parent_author_signature = base64_decode($parent_author_signature);
|
||||
|
||||
$key = $msg['key'];
|
||||
|
||||
if(! rsa_verify($signed_data,$parent_author_signature,$key,'sha256')) {
|
||||
logger('diaspora_signed_retraction: failed to verify person relaying the retraction (e.g. owner of a post relaying a retracted comment');
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($type === 'StatusMessage' || $type === 'Comment' || $type === 'Like') {
|
||||
$r = q("select * from item where guid = '%s' and uid = %d and not file like '%%[%%' limit 1",
|
||||
dbesc($guid),
|
||||
intval($importer['uid'])
|
||||
);
|
||||
if(count($r)) {
|
||||
if(link_compare($r[0]['author-link'],$contact['url'])) {
|
||||
q("update item set `deleted` = 1, `changed` = '%s' where `id` = %d limit 1",
|
||||
q("update item set `deleted` = 1, `edited` = '%s', `changed` = '%s', `body` = '' , `title` = '' where `id` = %d limit 1",
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['id'])
|
||||
);
|
||||
|
||||
// Now check if the retraction needs to be relayed by us
|
||||
//
|
||||
// The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always
|
||||
// return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent.
|
||||
// The only item with `parent` and `id` as the parent id is the parent item.
|
||||
$p = q("select origin from item where parent = %d and id = %d limit 1",
|
||||
$r[0]['parent'],
|
||||
$r[0]['parent']
|
||||
);
|
||||
if(count($p)) {
|
||||
if(($p[0]['origin']) && (! $parent_author_signature)) {
|
||||
q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
|
||||
$r[0]['id'],
|
||||
dbesc($signed_data),
|
||||
dbesc($sig),
|
||||
dbesc($diaspora_handle)
|
||||
);
|
||||
|
||||
// the existence of parent_author_signature would have meant the parent_author or owner
|
||||
// is already relaying.
|
||||
logger('diaspora_signed_retraction: relaying relayable_retraction');
|
||||
|
||||
proc_run('php','include/notifier.php','relayable_retraction',$r[0]['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2047,8 +2115,12 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) {
|
|||
$myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
|
||||
$theiraddr = $contact['addr'];
|
||||
|
||||
$p = q("select guid from item where parent = %d limit 1",
|
||||
$item['parent']
|
||||
// The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always
|
||||
// return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent.
|
||||
// The only item with `parent` and `id` as the parent id is the parent item.
|
||||
$p = q("select guid from item where parent = %d and id = %d limit 1",
|
||||
intval($item['parent']),
|
||||
intval($item['parent'])
|
||||
);
|
||||
if(count($p))
|
||||
$parent_guid = $p[0]['guid'];
|
||||
|
@ -2059,7 +2131,11 @@ function diaspora_send_followup($item,$owner,$contact,$public_batch = false) {
|
|||
$tpl = get_markup_template('diaspora_like.tpl');
|
||||
$like = true;
|
||||
$target_type = 'Post';
|
||||
$positive = (($item['deleted']) ? 'false' : 'true');
|
||||
// $positive = (($item['deleted']) ? 'false' : 'true');
|
||||
$positive = 'true';
|
||||
|
||||
if(($item['deleted']))
|
||||
logger('diaspora_send_followup: received deleted "like". Those should go to diaspora_send_retraction');
|
||||
}
|
||||
else {
|
||||
$tpl = get_markup_template('diaspora_comment.tpl');
|
||||
|
@ -2103,37 +2179,47 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) {
|
|||
$theiraddr = $contact['addr'];
|
||||
|
||||
|
||||
$p = q("select guid from item where parent = %d limit 1",
|
||||
$item['parent']
|
||||
// The first item in the `item` table with the parent id is the parent. However, MySQL doesn't always
|
||||
// return the items ordered by `item`.`id`, in which case the wrong item is chosen as the parent.
|
||||
// The only item with `parent` and `id` as the parent id is the parent item.
|
||||
$p = q("select guid from item where parent = %d and id = %d limit 1",
|
||||
intval($item['parent']),
|
||||
intval($item['parent'])
|
||||
);
|
||||
if(count($p))
|
||||
$parent_guid = $p[0]['guid'];
|
||||
else
|
||||
return;
|
||||
|
||||
if($item['verb'] === ACTIVITY_LIKE) {
|
||||
$like = false;
|
||||
$relay_retract = false;
|
||||
$sql_sign_id = 'iid';
|
||||
if( $item['deleted']) {
|
||||
$tpl = get_markup_template('diaspora_relayable_retraction.tpl');
|
||||
$relay_retract = true;
|
||||
$sql_sign_id = 'retract_iid';
|
||||
$target_type = ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment');
|
||||
}
|
||||
elseif($item['verb'] === ACTIVITY_LIKE) {
|
||||
$tpl = get_markup_template('diaspora_like_relay.tpl');
|
||||
$like = true;
|
||||
$target_type = 'Post';
|
||||
$positive = (($item['deleted']) ? 'false' : 'true');
|
||||
// $positive = (($item['deleted']) ? 'false' : 'true');
|
||||
$positive = 'true';
|
||||
}
|
||||
else {
|
||||
$tpl = get_markup_template('diaspora_comment_relay.tpl');
|
||||
$like = false;
|
||||
}
|
||||
|
||||
$body = $item['body'];
|
||||
|
||||
$text = html_entity_decode(bb2diaspora($body));
|
||||
|
||||
// fetch the original signature if somebody sent the post to us to relay
|
||||
// If we are relaying for a reply originating on our own account, there wasn't a 'send to relay'
|
||||
// action. It wasn't needed. In that case create the original signature and the
|
||||
// owner (parent author) signature
|
||||
// comments from other networks will be relayed under our name, with a brief
|
||||
// preamble to describe what's happening and noting the real author
|
||||
|
||||
$r = q("select * from sign where iid = %d limit 1",
|
||||
// fetch the original signature if the relayable was created by a Diaspora
|
||||
// or DFRN user. Relayables for other networks are not supported.
|
||||
|
||||
$r = q("select * from sign where " . $sql_sign_id . " = %d limit 1",
|
||||
intval($item['id'])
|
||||
);
|
||||
if(count($r)) {
|
||||
|
@ -2144,6 +2230,12 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) {
|
|||
}
|
||||
else {
|
||||
|
||||
// Author signature information (for likes, comments, and retractions of likes or comments,
|
||||
// whether from Diaspora or Friendica) must be placed in the `sign` table before this
|
||||
// function is called
|
||||
logger('diaspora_send_relay: original author signature not found, cannot send relayable');
|
||||
return;
|
||||
/*
|
||||
$itemcontact = q("select * from contact where `id` = %d limit 1",
|
||||
intval($item['contact-id'])
|
||||
);
|
||||
|
@ -2152,29 +2244,40 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) {
|
|||
$prefix = sprintf( t('[Relayed] Comment authored by %s from network %s'),
|
||||
'['. $item['author-name'] . ']' . '(' . $item['author-link'] . ')',
|
||||
network_to_name($itemcontact['network'])) . "\n";
|
||||
// "$body" was assigned to "$text" above. It isn't used after that, so I don't think
|
||||
// the following change will do anything
|
||||
$body = $prefix . $body;
|
||||
|
||||
// I think this comment will fail upon reaching Diaspora, because "$signed_text" is not defined
|
||||
}
|
||||
}
|
||||
else {
|
||||
// I'm confused about this "else." Since it sets "$handle = $myaddr," it seems like it should be for the case
|
||||
// where the top-level post owner commented on his own post, i.e. "$itemcontact[0]['self']" is true. But it's
|
||||
// positioned to be for the case where "count($itemcontact)" is 0.
|
||||
|
||||
$handle = $myaddr;
|
||||
|
||||
if($like)
|
||||
$signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $myaddr;
|
||||
$signed_text = $item['guid'] . ';' . $target_type . ';' . $parent_guid . ';' . $positive . ';' . $handle;
|
||||
elseif($relay_retract)
|
||||
$signed_text = $item['guid'] . ';' . $target_type;
|
||||
else
|
||||
$signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $myaddr;
|
||||
$signed_text = $item['guid'] . ';' . $parent_guid . ';' . $text . ';' . $handle;
|
||||
|
||||
$authorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256'));
|
||||
|
||||
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
|
||||
q("insert into sign (`" . $sql_sign_id . "`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
|
||||
intval($item['id']),
|
||||
dbesc($signed_text),
|
||||
dbesc(base64_encode($authorsig)),
|
||||
dbesc($myaddr)
|
||||
dbesc($authorsig),
|
||||
dbesc($handle)
|
||||
);
|
||||
$handle = $myaddr;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// sign it
|
||||
// sign it with the top-level owner's signature
|
||||
|
||||
$parentauthorsig = base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256'));
|
||||
|
||||
|
@ -2182,14 +2285,15 @@ function diaspora_send_relay($item,$owner,$contact,$public_batch = false) {
|
|||
'$guid' => xmlify($item['guid']),
|
||||
'$parent_guid' => xmlify($parent_guid),
|
||||
'$target_type' =>xmlify($target_type),
|
||||
'$authorsig' => xmlify($orig_sign['signature']),
|
||||
'$authorsig' => xmlify($authorsig),
|
||||
'$parentsig' => xmlify($parentauthorsig),
|
||||
'$body' => xmlify($text),
|
||||
'$positive' => xmlify($positive),
|
||||
'$handle' => xmlify($handle)
|
||||
));
|
||||
|
||||
logger('diaspora_relay_comment: base message: ' . $msg, LOGGER_DATA);
|
||||
logger('diaspora_send_relay: base message: ' . $msg, LOGGER_DATA);
|
||||
|
||||
|
||||
$slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch)));
|
||||
|
||||
|
@ -2204,14 +2308,25 @@ function diaspora_send_retraction($item,$owner,$contact,$public_batch = false) {
|
|||
$a = get_app();
|
||||
$myaddr = $owner['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
|
||||
|
||||
$signed_text = $item['guid'] . ';' . 'StatusMessage';
|
||||
// Check whether the retraction is for a top-level post or whether it's a relayable
|
||||
if( $item['uri'] !== $item['parent-uri'] ) {
|
||||
|
||||
$tpl = get_markup_template('diaspora_relay_retraction.tpl');
|
||||
$target_type = (($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment');
|
||||
}
|
||||
else {
|
||||
|
||||
$tpl = get_markup_template('diaspora_signed_retract.tpl');
|
||||
$target_type = 'StatusMessage';
|
||||
}
|
||||
|
||||
$signed_text = $item['guid'] . ';' . $target_type;
|
||||
|
||||
$msg = replace_macros($tpl, array(
|
||||
'$guid' => $item['guid'],
|
||||
'$type' => 'StatusMessage',
|
||||
'$handle' => $myaddr,
|
||||
'$signature' => base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256'))
|
||||
'$guid' => xmlify($item['guid']),
|
||||
'$type' => xmlify($target_type),
|
||||
'$handle' => xmlify($myaddr),
|
||||
'$signature' => xmlify(base64_encode(rsa_sign($signed_text,$owner['uprvkey'],'sha256')))
|
||||
));
|
||||
|
||||
$slap = 'xml=' . urlencode(urlencode(diaspora_msg_build($msg,$owner,$contact,$owner['uprvkey'],$contact['pubkey'],$public_batch)));
|
||||
|
@ -2335,3 +2450,5 @@ function diaspora_transmit($owner,$contact,$slap,$public_batch) {
|
|||
|
||||
return(($return_code) ? $return_code : (-1));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ function directory_run($argv, $argc){
|
|||
|
||||
load_config('system');
|
||||
|
||||
load_hooks();
|
||||
|
||||
|
||||
$a->set_baseurl(get_config('system','url'));
|
||||
|
||||
$dir = get_config('system','directory_submit_url');
|
||||
|
@ -31,7 +34,12 @@ function directory_run($argv, $argc){
|
|||
if(! strlen($dir))
|
||||
return;
|
||||
|
||||
fetch_url($dir . '?url=' . bin2hex($argv[1]));
|
||||
$arr = array('url' => $argv[1]);
|
||||
|
||||
call_hooks('globaldir_update', $arr);
|
||||
|
||||
if(strlen($arr['url']))
|
||||
fetch_url($dir . '?url=' . bin2hex($arr['url']));
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,13 +13,16 @@ function notification($params) {
|
|||
|
||||
$banner = t('Friendica Notification');
|
||||
$product = FRIENDICA_PLATFORM;
|
||||
$siteurl = z_path();
|
||||
$siteurl = $a->get_baseurl(true);
|
||||
$thanks = t('Thank You,');
|
||||
$sitename = get_config('config','sitename');
|
||||
$site_admin = sprintf( t('%s Administrator'), $sitename);
|
||||
|
||||
$sender_name = $product;
|
||||
$hostname = $a->get_hostname();
|
||||
if(strpos($hostname,':'))
|
||||
$hostname = substr($hostname,0,strpos($hostname,':'));
|
||||
|
||||
$sender_email = t('noreply') . '@' . $hostname;
|
||||
$additional_mail_header = "";
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ function format_event_html($ev) {
|
|||
return $o;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
function parse_event($h) {
|
||||
|
||||
require_once('include/Scrape.php');
|
||||
|
@ -108,7 +108,7 @@ function parse_event($h) {
|
|||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
function format_event_bbcode($ev) {
|
||||
|
||||
|
@ -162,7 +162,6 @@ function bbtoevent($s) {
|
|||
$match = '';
|
||||
if(preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is",$s,$match))
|
||||
$ev['adjust'] = $match[1];
|
||||
$match = '';
|
||||
$ev['nofinish'] = (((x($ev, 'start') && $ev['start']) && (!x($ev, 'finish') || !$ev['finish'])) ? 1 : 0);
|
||||
return $ev;
|
||||
|
||||
|
@ -294,10 +293,14 @@ function event_store($arr) {
|
|||
intval($arr['uid'])
|
||||
);
|
||||
|
||||
return $r[0]['id'];
|
||||
$item_id = $r[0]['id'];
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
$item_id = 0;
|
||||
|
||||
call_hooks("event_updated", $arr['id']);
|
||||
|
||||
return $item_id;
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -361,7 +364,7 @@ function event_store($arr) {
|
|||
$item_arr['body'] = format_event_bbcode($event);
|
||||
|
||||
|
||||
$item_arr['object'] = '<object><type>' . xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . xmlify($uri) . '</id>';
|
||||
$item_arr['object'] = '<object><type>' . xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . xmlify($arr['uri']) . '</id>';
|
||||
$item_arr['object'] .= '<content>' . xmlify(format_event_bbcode($event)) . '</content>';
|
||||
$item_arr['object'] .= '</object>' . "\n";
|
||||
|
||||
|
@ -383,6 +386,8 @@ function event_store($arr) {
|
|||
);
|
||||
}
|
||||
|
||||
call_hooks("event_created", $event['id']);
|
||||
|
||||
return $item_id;
|
||||
}
|
||||
}
|
||||
|
|
243
include/follow.php
Normal file
243
include/follow.php
Normal file
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
|
||||
|
||||
//
|
||||
// Takes a $uid and a url/handle and adds a new contact
|
||||
// Currently if the contact is DFRN, interactive needs to be true, to redirect to the
|
||||
// dfrn_request page.
|
||||
|
||||
// Otherwise this can be used to bulk add statusnet contacts, twitter contacts, etc.
|
||||
// Returns an array
|
||||
// $return['success'] boolean true if successful
|
||||
// $return['message'] error text if success is false.
|
||||
|
||||
|
||||
|
||||
function new_contact($uid,$url,$interactive = false) {
|
||||
|
||||
$result = array('success' => false,'message' => '');
|
||||
|
||||
$a = get_app();
|
||||
|
||||
// remove ajax junk, e.g. Twitter
|
||||
|
||||
$url = str_replace('/#!/','/',$url);
|
||||
|
||||
if(! allowed_url($url)) {
|
||||
$result['message'] = t('Disallowed profile URL.');
|
||||
return $result;
|
||||
}
|
||||
|
||||
if(! $url) {
|
||||
$result['message'] = t('Connect URL missing.');
|
||||
return $result;
|
||||
}
|
||||
|
||||
$arr = array('url' => $url, 'contact' => array());
|
||||
|
||||
call_hooks('follow', $arr);
|
||||
|
||||
if(x($arr['contact'],'name'))
|
||||
$ret = $arr['contact'];
|
||||
else
|
||||
$ret = probe_url($url);
|
||||
|
||||
if($ret['network'] === NETWORK_DFRN) {
|
||||
if($interactive) {
|
||||
if(strlen($a->path))
|
||||
$myaddr = bin2hex($a->get_baseurl() . '/profile/' . $a->user['nickname']);
|
||||
else
|
||||
$myaddr = bin2hex($a->user['nickname'] . '@' . $a->get_hostname());
|
||||
|
||||
goaway($ret['request'] . "&addr=$myaddr");
|
||||
|
||||
// NOTREACHED
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(get_config('system','dfrn_only')) {
|
||||
$result['message'] = t('This site is not configured to allow communications with other networks.') . EOL;
|
||||
$result['message'] != t('No compatible communication protocols or feeds were discovered.') . EOL;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// This extra param just confuses things, remove it
|
||||
if($ret['network'] === NETWORK_DIASPORA)
|
||||
$ret['url'] = str_replace('?absolute=true','',$ret['url']);
|
||||
|
||||
|
||||
// do we have enough information?
|
||||
|
||||
if(! ((x($ret,'name')) && (x($ret,'poll')) && ((x($ret,'url')) || (x($ret,'addr'))))) {
|
||||
$result['message'] .= t('The profile address specified does not provide adequate information.') . EOL;
|
||||
if(! x($ret,'poll'))
|
||||
$result['message'] .= t('No compatible communication protocols or feeds were discovered.') . EOL;
|
||||
if(! x($ret,'name'))
|
||||
$result['message'] .= t('An author or name was not found.') . EOL;
|
||||
if(! x($ret,'url'))
|
||||
$result['message'] .= t('No browser URL could be matched to this address.') . EOL;
|
||||
if(strpos($url,'@') !== false) {
|
||||
$result['message'] .= t('Unable to match @-style Identity Address with a known protocol or email contact.') . EOL;
|
||||
$result['message'] .= t('Use mailto: in front of address to force email check.') . EOL;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
if($ret['network'] === NETWORK_OSTATUS && get_config('system','ostatus_disabled')) {
|
||||
$result['message'] .= t('The profile address specified belongs to a network which has been disabled on this site.') . EOL;
|
||||
$ret['notify'] = '';
|
||||
}
|
||||
|
||||
if(! $ret['notify']) {
|
||||
$result['message'] .= t('Limited profile. This person will be unable to receive direct/personal notifications from you.') . EOL;
|
||||
}
|
||||
|
||||
$writeable = ((($ret['network'] === NETWORK_OSTATUS) && ($ret['notify'])) ? 1 : 0);
|
||||
$hidden = (($ret['network'] === NETWORK_MAIL) ? 1 : 0);
|
||||
|
||||
if($ret['network'] === NETWORK_MAIL) {
|
||||
$writeable = 1;
|
||||
|
||||
}
|
||||
if($ret['network'] === NETWORK_DIASPORA)
|
||||
$writeable = 1;
|
||||
|
||||
// check if we already have a contact
|
||||
// the poll url is more reliable than the profile url, as we may have
|
||||
// indirect links or webfinger links
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `poll` = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($ret['poll'])
|
||||
);
|
||||
|
||||
|
||||
if(count($r)) {
|
||||
// update contact
|
||||
if($r[0]['rel'] == CONTACT_IS_FOLLOWER || ($network === NETWORK_DIASPORA && $r[0]['rel'] == CONTACT_IS_SHARING)) {
|
||||
q("UPDATE `contact` SET `rel` = %d , `readonly` = 0 WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval(CONTACT_IS_FRIEND),
|
||||
intval($r[0]['id']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
$new_relation = (($ret['network'] === NETWORK_MAIL) ? CONTACT_IS_FRIEND : CONTACT_IS_SHARING);
|
||||
if($ret['network'] === NETWORK_DIASPORA)
|
||||
$new_relation = CONTACT_IS_FOLLOWER;
|
||||
|
||||
// create contact record
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `batch`, `notify`, `poll`, `poco`, `name`, `nick`, `photo`, `network`, `pubkey`, `rel`, `priority`,
|
||||
`writable`, `hidden`, `blocked`, `readonly`, `pending` )
|
||||
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, 0, 0, 0 ) ",
|
||||
intval($uid),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($ret['url']),
|
||||
dbesc(normalise_link($ret['url'])),
|
||||
dbesc($ret['addr']),
|
||||
dbesc($ret['alias']),
|
||||
dbesc($ret['batch']),
|
||||
dbesc($ret['notify']),
|
||||
dbesc($ret['poll']),
|
||||
dbesc($ret['poco']),
|
||||
dbesc($ret['name']),
|
||||
dbesc($ret['nick']),
|
||||
dbesc($ret['photo']),
|
||||
dbesc($ret['network']),
|
||||
dbesc($ret['pubkey']),
|
||||
intval($new_relation),
|
||||
intval($ret['priority']),
|
||||
intval($writeable),
|
||||
intval($hidden)
|
||||
);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($ret['url']),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(! count($r)) {
|
||||
$result['message'] .= t('Unable to retrieve contact information.') . EOL;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$contact = $r[0];
|
||||
$contact_id = $r[0]['id'];
|
||||
|
||||
|
||||
$g = q("select def_gid from user where uid = %d limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
if($g && intval($g[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member($uid,'',$contact_id,$g[0]['def_gid']);
|
||||
}
|
||||
|
||||
require_once("Photo.php");
|
||||
|
||||
$photos = import_profile_photo($ret['photo'],$uid,$contact_id);
|
||||
|
||||
$r = q("UPDATE `contact` SET `photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`name-date` = '%s',
|
||||
`uri-date` = '%s',
|
||||
`avatar-date` = '%s'
|
||||
WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact_id)
|
||||
);
|
||||
|
||||
|
||||
// pull feed and consume it, which should subscribe to the hub.
|
||||
|
||||
proc_run('php',"include/poller.php","$contact_id");
|
||||
|
||||
// create a follow slap
|
||||
|
||||
$tpl = get_markup_template('follow_slap.tpl');
|
||||
$slap = replace_macros($tpl, array(
|
||||
'$name' => $a->user['username'],
|
||||
'$profile_page' => $a->get_baseurl() . '/profile/' . $a->user['nickname'],
|
||||
'$photo' => $a->contact['photo'],
|
||||
'$thumb' => $a->contact['thumb'],
|
||||
'$published' => datetime_convert('UTC','UTC', 'now', ATOM_TIME),
|
||||
'$item_id' => 'urn:X-dfrn:' . $a->get_hostname() . ':follow:' . random_string(),
|
||||
'$title' => '',
|
||||
'$type' => 'text',
|
||||
'$content' => t('following'),
|
||||
'$nick' => $a->user['nickname'],
|
||||
'$verb' => ACTIVITY_FOLLOW,
|
||||
'$ostat_follow' => ''
|
||||
));
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
if(($contact['network'] == NETWORK_OSTATUS) && (strlen($contact['notify']))) {
|
||||
require_once('include/salmon.php');
|
||||
slapper($r[0],$contact['notify'],$slap);
|
||||
}
|
||||
if($contact['network'] == NETWORK_DIASPORA) {
|
||||
require_once('include/diaspora.php');
|
||||
$ret = diaspora_share($a->user,$contact);
|
||||
logger('mod_follow: diaspora_share returns: ' . $ret);
|
||||
}
|
||||
}
|
||||
|
||||
$result['success'] = true;
|
||||
return $result;
|
||||
}
|
|
@ -97,7 +97,8 @@ function group_rmv_member($uid,$name,$member) {
|
|||
}
|
||||
|
||||
|
||||
function group_add_member($uid,$name,$member) {
|
||||
function group_add_member($uid,$name,$member,$gid = 0) {
|
||||
if(! $gid)
|
||||
$gid = group_byname($uid,$name);
|
||||
if((! $gid) || (! $uid) || (! $member))
|
||||
return false;
|
||||
|
@ -154,6 +155,32 @@ function group_public_members($gid) {
|
|||
}
|
||||
|
||||
|
||||
function mini_group_select($uid,$gid = 0) {
|
||||
|
||||
$grps = array();
|
||||
$o = '';
|
||||
|
||||
$r = q("SELECT * FROM `group` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC",
|
||||
intval($uid)
|
||||
);
|
||||
$grps[] = array('name' => '', 'id' => '0', 'selected' => '');
|
||||
if(count($r)) {
|
||||
foreach($r as $rr) {
|
||||
$grps[] = array('name' => $rr['name'], 'id' => $rr['id'], 'selected' => (($gid == $rr['id']) ? 'true' : ''));
|
||||
}
|
||||
|
||||
}
|
||||
logger('groups: ' . print_r($grps,true));
|
||||
|
||||
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
|
||||
'$label' => t('Default privacy group for new contacts'),
|
||||
'$groups' => $grps
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function group_side($every="contacts",$each="group",$edit = false, $group_id = 0, $cid = 0) {
|
||||
|
||||
|
|
172
include/items.php
Normal file → Executable file
172
include/items.php
Normal file → Executable file
|
@ -180,6 +180,10 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
|
|||
|
||||
foreach($items as $item) {
|
||||
|
||||
// prevent private email from leaking.
|
||||
if($item['network'] === NETWORK_MAIL)
|
||||
continue;
|
||||
|
||||
// public feeds get html, our own nodes use bbcode
|
||||
|
||||
if($public_feed) {
|
||||
|
@ -959,6 +963,8 @@ function tag_deliver($uid,$item_id) {
|
|||
return;
|
||||
|
||||
$community_page = (($u[0]['page-flags'] == PAGE_COMMUNITY) ? true : false);
|
||||
$prvgroup = (($u[0]['page-flags'] == PAGE_PRVGROUP) ? true : false);
|
||||
|
||||
|
||||
$i = q("select * from item where id = %d and uid = %d limit 1",
|
||||
intval($item_id),
|
||||
|
@ -1008,9 +1014,10 @@ function tag_deliver($uid,$item_id) {
|
|||
'otype' => 'item'
|
||||
));
|
||||
|
||||
if(! $community_page)
|
||||
if((! $community_page) && (! $prvgroup))
|
||||
return;
|
||||
|
||||
|
||||
// tgroup delivery - setup a second delivery chain
|
||||
// prevent delivery looping - only proceed
|
||||
// if the message originated elsewhere and is a top-level post
|
||||
|
@ -1031,8 +1038,11 @@ function tag_deliver($uid,$item_id) {
|
|||
|
||||
$private = ($u[0]['allow_cid'] || $u[0]['allow_gid'] || $u[0]['deny_cid'] || $u[0]['deny_gid']) ? 1 : 0;
|
||||
|
||||
q("update item set wall = 1, origin = 1, forum_mode = 1, `owner-name` = '%s', `owner-link` = '%s', `owner-avatar` = '%s',
|
||||
$forum_mode = (($prvgroup) ? 2 : 1);
|
||||
|
||||
q("update item set wall = 1, origin = 1, forum_mode = %d, `owner-name` = '%s', `owner-link` = '%s', `owner-avatar` = '%s',
|
||||
`private` = %d, `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s' where id = %d limit 1",
|
||||
intval($forum_mode),
|
||||
dbesc($c[0]['name']),
|
||||
dbesc($c[0]['url']),
|
||||
dbesc($c[0]['thumb']),
|
||||
|
@ -1057,9 +1067,6 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
|
|||
|
||||
$a = get_app();
|
||||
|
||||
// if((! strlen($contact['issued-id'])) && (! $contact['duplex']) && (! ($owner['page-flags'] == PAGE_COMMUNITY)))
|
||||
// return 3;
|
||||
|
||||
$idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
|
||||
|
||||
if($contact['duplex'] && $contact['dfrn-id'])
|
||||
|
@ -1124,6 +1131,9 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
|
|||
$rino_allowed = ((intval($res->rino) === 1) ? 1 : 0);
|
||||
$page = (($owner['page-flags'] == PAGE_COMMUNITY) ? 1 : 0);
|
||||
|
||||
if($owner['page-flags'] == PAGE_PRVGROUP)
|
||||
$page = 2;
|
||||
|
||||
$final_dfrn_id = '';
|
||||
|
||||
if($perm) {
|
||||
|
@ -1177,7 +1187,7 @@ function dfrn_deliver($owner,$contact,$atom, $dissolve = false) {
|
|||
$postvars['ssl_policy'] = $ssl_policy;
|
||||
|
||||
if($page)
|
||||
$postvars['page'] = '1';
|
||||
$postvars['page'] = $page;
|
||||
|
||||
if($rino && $rino_allowed && (! $dissolve)) {
|
||||
$key = substr(random_string(),0,16);
|
||||
|
@ -2194,7 +2204,7 @@ function local_delivery($importer,$data) {
|
|||
if($is_reply) {
|
||||
$community = false;
|
||||
|
||||
if($importer['page-flags'] == PAGE_COMMUNITY) {
|
||||
if($importer['page-flags'] == PAGE_COMMUNITY || $importer['page-flags'] == PAGE_PRVGROUP ) {
|
||||
$sql_extra = '';
|
||||
$community = true;
|
||||
logger('local_delivery: possible community reply');
|
||||
|
@ -2221,8 +2231,8 @@ function local_delivery($importer,$data) {
|
|||
if($r && count($r))
|
||||
$is_a_remote_comment = true;
|
||||
|
||||
// Does this have the characteristics of a community comment?
|
||||
// If it's a reply to a wall post on a community page it's a
|
||||
// Does this have the characteristics of a community or private group comment?
|
||||
// If it's a reply to a wall post on a community/prvgroup page it's a
|
||||
// valid community comment. Also forum_mode makes it valid for sure.
|
||||
// If neither, it's not.
|
||||
|
||||
|
@ -2711,6 +2721,12 @@ function new_follower($importer,$contact,$datarray,$item,$sharing = false) {
|
|||
);
|
||||
$a = get_app();
|
||||
if(count($r)) {
|
||||
|
||||
if(intval($r[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member($r[0]['uid'],'',$contact_record['id'],$r[0]['def_gid']);
|
||||
}
|
||||
|
||||
if(($r[0]['notify-flags'] & NOTIFY_INTRO) && ($r[0]['page-flags'] == PAGE_NORMAL)) {
|
||||
$email_tpl = get_intltext_template('follow_notify_eml.tpl');
|
||||
$email = replace_macros($email_tpl, array(
|
||||
|
@ -2820,7 +2836,7 @@ function atom_author($tag,$name,$uri,$h,$w,$photo) {
|
|||
return $o;
|
||||
}
|
||||
|
||||
function atom_entry($item,$type,$author,$owner,$comment = false) {
|
||||
function atom_entry($item,$type,$author,$owner,$comment = false,$cid = 0) {
|
||||
|
||||
$a = get_app();
|
||||
|
||||
|
@ -2832,7 +2848,7 @@ function atom_entry($item,$type,$author,$owner,$comment = false) {
|
|||
|
||||
|
||||
if($item['allow_cid'] || $item['allow_gid'] || $item['deny_cid'] || $item['deny_gid'])
|
||||
$body = fix_private_photos($item['body'],$owner['uid']);
|
||||
$body = fix_private_photos($item['body'],$owner['uid'],$item,$cid);
|
||||
else
|
||||
$body = $item['body'];
|
||||
|
||||
|
@ -2915,14 +2931,17 @@ function atom_entry($item,$type,$author,$owner,$comment = false) {
|
|||
return $o;
|
||||
}
|
||||
|
||||
function fix_private_photos($s,$uid) {
|
||||
function fix_private_photos($s,$uid, $item = null, $cid = 0) {
|
||||
$a = get_app();
|
||||
logger('fix_private_photos');
|
||||
|
||||
if(preg_match("/\[img\](.*?)\[\/img\]/is",$s,$matches)) {
|
||||
$image = $matches[1];
|
||||
logger('fix_private_photos: found photo ' . $image);
|
||||
if(stristr($image ,$a->get_baseurl() . '/photo/')) {
|
||||
logger('fix_private_photos', LOGGER_DEBUG);
|
||||
$site = substr($a->get_baseurl(),strpos($a->get_baseurl(),'://'));
|
||||
|
||||
if(preg_match("/\[img(.*?)\](.*?)\[\/img\]/is",$s,$matches)) {
|
||||
$image = $matches[2];
|
||||
logger('fix_private_photos: found photo ' . $image, LOGGER_DEBUG);
|
||||
if(stristr($image , $site . '/photo/')) {
|
||||
$replace = false;
|
||||
$i = basename($image);
|
||||
$i = str_replace('.jpg','',$i);
|
||||
$x = strpos($i,'-');
|
||||
|
@ -2935,17 +2954,86 @@ function fix_private_photos($s,$uid) {
|
|||
intval($uid)
|
||||
);
|
||||
if(count($r)) {
|
||||
logger('replacing photo');
|
||||
|
||||
// Check to see if we should replace this photo link with an embedded image
|
||||
// 1. No need to do so if the photo is public
|
||||
// 2. If there's a contact-id provided, see if they're in the access list
|
||||
// for the photo. If so, embed it.
|
||||
// 3. Otherwise, if we have an item, see if the item permissions match the photo
|
||||
// permissions, regardless of order but first check to see if they're an exact
|
||||
// match to save some processing overhead.
|
||||
|
||||
// Currently we only embed one private photo per message so as not to hit import
|
||||
// size limits at the receiving end.
|
||||
|
||||
// To embed multiples, we would need to parse out the embedded photos on message
|
||||
// receipt and limit size based only on the text component. Would also need to
|
||||
// ignore all photos during bbcode translation and item localisation, as these
|
||||
// will hit internal regex backtrace limits.
|
||||
|
||||
if(has_permissions($r[0])) {
|
||||
if($cid) {
|
||||
$recips = enumerate_permissions($r[0]);
|
||||
if(in_array($cid, $recips)) {
|
||||
$replace = true;
|
||||
}
|
||||
}
|
||||
elseif($item) {
|
||||
if(compare_permissions($item,$r[0]))
|
||||
$replace = true;
|
||||
}
|
||||
}
|
||||
if($replace) {
|
||||
logger('fix_private_photos: replacing photo', LOGGER_DEBUG);
|
||||
$s = str_replace($image, 'data:image/jpg;base64,' . base64_encode($r[0]['data']), $s);
|
||||
}
|
||||
}
|
||||
logger('fix_private_photos: replaced: ' . $s, LOGGER_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return($s);
|
||||
}
|
||||
|
||||
|
||||
function has_permissions($obj) {
|
||||
if(($obj['allow_cid'] != '') || ($obj['allow_gid'] != '') || ($obj['deny_cid'] != '') || ($obj['deny_gid'] != ''))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function compare_permissions($obj1,$obj2) {
|
||||
// first part is easy. Check that these are exactly the same.
|
||||
if(($obj1['allow_cid'] == $obj2['allow_cid'])
|
||||
&& ($obj1['allow_gid'] == $obj2['allow_gid'])
|
||||
&& ($obj1['deny_cid'] == $obj2['deny_cid'])
|
||||
&& ($obj1['deny_gid'] == $obj2['deny_gid']))
|
||||
return true;
|
||||
|
||||
// This is harder. Parse all the permissions and compare the resulting set.
|
||||
|
||||
$recipients1 = enumerate_permissions($obj1);
|
||||
$recipients2 = enumerate_permissions($obj2);
|
||||
sort($recipients1);
|
||||
sort($recipients2);
|
||||
if($recipients1 == $recipients2)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns an array of contact-ids that are allowed to see this object
|
||||
|
||||
function enumerate_permissions($obj) {
|
||||
require_once('include/group.php');
|
||||
$allow_people = expand_acl($obj['allow_cid']);
|
||||
$allow_groups = expand_groups(expand_acl($obj['allow_gid']));
|
||||
$deny_people = expand_acl($obj['deny_cid']);
|
||||
$deny_groups = expand_groups(expand_acl($obj['deny_gid']));
|
||||
$recipients = array_unique(array_merge($allow_people,$allow_groups));
|
||||
$deny = array_unique(array_merge($deny_people,$deny_groups));
|
||||
$recipients = array_diff($recipients,$deny);
|
||||
return $recipients;
|
||||
}
|
||||
|
||||
function item_getfeedtags($item) {
|
||||
$ret = array();
|
||||
|
@ -2992,13 +3080,20 @@ function item_getfeedattach($item) {
|
|||
|
||||
function item_expire($uid,$days) {
|
||||
|
||||
if((! $uid) || (! $days))
|
||||
if((! $uid) || ($days < 1))
|
||||
return;
|
||||
|
||||
// $expire_network_only = save your own wall posts
|
||||
// and just expire conversations started by others
|
||||
|
||||
$expire_network_only = get_pconfig($uid,'expire','network_only');
|
||||
$sql_extra = ((intval($expire_network_only)) ? " AND wall = 0 " : "");
|
||||
|
||||
$r = q("SELECT * FROM `item`
|
||||
WHERE `uid` = %d
|
||||
AND `created` < UTC_TIMESTAMP() - INTERVAL %d DAY
|
||||
AND `id` = `parent`
|
||||
$sql_extra
|
||||
AND `deleted` = 0",
|
||||
intval($uid),
|
||||
intval($days)
|
||||
|
@ -3184,6 +3279,41 @@ function drop_item($id,$interactive = true) {
|
|||
intval($r[0]['id'])
|
||||
);
|
||||
}
|
||||
|
||||
// Add a relayable_retraction signature for Diaspora. Note that we can't add a target_author_signature
|
||||
// if the comment was deleted by a remote user. That should be ok, because if a remote user is deleting
|
||||
// the comment, that means we're the home of the post, and Diaspora will only
|
||||
// check the parent_author_signature of retractions that it doesn't have to relay further
|
||||
//
|
||||
// I don't think this function gets called for an "unlike," but I'll check anyway
|
||||
$signed_text = $item['guid'] . ';' . ( ($item['verb'] === ACTIVITY_LIKE) ? 'Like' : 'Comment');
|
||||
|
||||
if(local_user() == $item['uid']) {
|
||||
|
||||
$handle = $a->user['nickname'] . '@' . substr($a->get_baseurl(), strpos($a->get_baseurl(),'://') + 3);
|
||||
$authorsig = base64_encode(rsa_sign($signed_text,$a->user['prvkey'],'sha256'));
|
||||
}
|
||||
else {
|
||||
$r = q("SELECT `nick`, `url` FROM `contact` WHERE `id` = '%d' LIMIT 1",
|
||||
$item['contact-id']
|
||||
);
|
||||
if(count($r)) {
|
||||
// The below handle only works for NETWORK_DFRN. I think that's ok, because this function
|
||||
// only handles DFRN deletes
|
||||
$handle_baseurl_start = strpos($r['url'],'://') + 3;
|
||||
$handle_baseurl_length = strpos($r['url'],'/profile') - $handle_baseurl_start;
|
||||
$handle = $r['nick'] . '@' . substr($r['url'], $handle_baseurl_start, $handle_baseurl_length);
|
||||
$authorsig = '';
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($handle))
|
||||
q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
|
||||
intval($item['id']),
|
||||
dbesc($signed_text),
|
||||
dbesc($authorsig),
|
||||
dbesc($handle)
|
||||
);
|
||||
}
|
||||
$drop_id = intval($item['id']);
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ function nav(&$a) {
|
|||
|
||||
/* 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 || $_SESSION['page_flags'] == PAGE_PRVGROUP) {
|
||||
$nav['introductions'] = array('notifications/intros', t('Introductions'), "", t('Friend Requests'));
|
||||
$nav['notifications'] = array('notifications', t('Notifications'), "", t('Notifications'));
|
||||
$nav['notifications']['all']=array('notifications/system', t('See all notifications'), "", "");
|
||||
|
|
|
@ -876,3 +876,167 @@ function fix_contact_ssl_policy(&$contact,$new_policy) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* xml2array() will convert the given XML text to an array in the XML structure.
|
||||
* Link: http://www.bin-co.com/php/scripts/xml2array/
|
||||
* Portions significantly re-written by mike@macgirvin.com for Friendica (namespaces, lowercase tags, get_attribute default changed, more...)
|
||||
* Arguments : $contents - The XML text
|
||||
* $namespaces - true or false include namespace information in the returned array as array elements.
|
||||
* $get_attributes - 1 or 0. If this is 1 the function will get the attributes as well as the tag values - this results in a different array structure in the return value.
|
||||
* $priority - Can be 'tag' or 'attribute'. This will change the way the resulting array sturcture. For 'tag', the tags are given more importance.
|
||||
* Return: The parsed XML in an array form. Use print_r() to see the resulting array structure.
|
||||
* Examples: $array = xml2array(file_get_contents('feed.xml'));
|
||||
* $array = xml2array(file_get_contents('feed.xml', true, 1, 'attribute'));
|
||||
*/
|
||||
|
||||
function xml2array($contents, $namespaces = true, $get_attributes=1, $priority = 'attribute') {
|
||||
if(!$contents) return array();
|
||||
|
||||
if(!function_exists('xml_parser_create')) {
|
||||
logger('xml2array: parser function missing');
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
|
||||
if($namespaces)
|
||||
$parser = @xml_parser_create_ns("UTF-8",':');
|
||||
else
|
||||
$parser = @xml_parser_create();
|
||||
|
||||
if(! $parser) {
|
||||
logger('xml2array: xml_parser_create: no resource');
|
||||
return array();
|
||||
}
|
||||
|
||||
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
|
||||
// http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
|
||||
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
|
||||
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
|
||||
@xml_parse_into_struct($parser, trim($contents), $xml_values);
|
||||
@xml_parser_free($parser);
|
||||
|
||||
if(! $xml_values) {
|
||||
logger('xml2array: libxml: parse error: ' . $contents, LOGGER_DATA);
|
||||
foreach(libxml_get_errors() as $err)
|
||||
logger('libxml: parse: ' . $err->code . " at " . $err->line . ":" . $err->column . " : " . $err->message, LOGGER_DATA);
|
||||
libxml_clear_errors();
|
||||
return;
|
||||
}
|
||||
|
||||
//Initializations
|
||||
$xml_array = array();
|
||||
$parents = array();
|
||||
$opened_tags = array();
|
||||
$arr = array();
|
||||
|
||||
$current = &$xml_array; // Reference
|
||||
|
||||
// Go through the tags.
|
||||
$repeated_tag_index = array(); // Multiple tags with same name will be turned into an array
|
||||
foreach($xml_values as $data) {
|
||||
unset($attributes,$value); // Remove existing values, or there will be trouble
|
||||
|
||||
// This command will extract these variables into the foreach scope
|
||||
// tag(string), type(string), level(int), attributes(array).
|
||||
extract($data); // We could use the array by itself, but this cooler.
|
||||
|
||||
$result = array();
|
||||
$attributes_data = array();
|
||||
|
||||
if(isset($value)) {
|
||||
if($priority == 'tag') $result = $value;
|
||||
else $result['value'] = $value; // Put the value in a assoc array if we are in the 'Attribute' mode
|
||||
}
|
||||
|
||||
//Set the attributes too.
|
||||
if(isset($attributes) and $get_attributes) {
|
||||
foreach($attributes as $attr => $val) {
|
||||
if($priority == 'tag') $attributes_data[$attr] = $val;
|
||||
else $result['@attributes'][$attr] = $val; // Set all the attributes in a array called 'attr'
|
||||
}
|
||||
}
|
||||
|
||||
// See tag status and do the needed.
|
||||
if($namespaces && strpos($tag,':')) {
|
||||
$namespc = substr($tag,0,strrpos($tag,':'));
|
||||
$tag = strtolower(substr($tag,strlen($namespc)+1));
|
||||
$result['@namespace'] = $namespc;
|
||||
}
|
||||
$tag = strtolower($tag);
|
||||
|
||||
if($type == "open") { // The starting of the tag '<tag>'
|
||||
$parent[$level-1] = &$current;
|
||||
if(!is_array($current) or (!in_array($tag, array_keys($current)))) { // Insert New tag
|
||||
$current[$tag] = $result;
|
||||
if($attributes_data) $current[$tag. '_attr'] = $attributes_data;
|
||||
$repeated_tag_index[$tag.'_'.$level] = 1;
|
||||
|
||||
$current = &$current[$tag];
|
||||
|
||||
} else { // There was another element with the same tag name
|
||||
|
||||
if(isset($current[$tag][0])) { // If there is a 0th element it is already an array
|
||||
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
|
||||
$repeated_tag_index[$tag.'_'.$level]++;
|
||||
} else { // This section will make the value an array if multiple tags with the same name appear together
|
||||
$current[$tag] = array($current[$tag],$result); // This will combine the existing item and the new item together to make an array
|
||||
$repeated_tag_index[$tag.'_'.$level] = 2;
|
||||
|
||||
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
|
||||
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
|
||||
unset($current[$tag.'_attr']);
|
||||
}
|
||||
|
||||
}
|
||||
$last_item_index = $repeated_tag_index[$tag.'_'.$level]-1;
|
||||
$current = &$current[$tag][$last_item_index];
|
||||
}
|
||||
|
||||
} elseif($type == "complete") { // Tags that ends in 1 line '<tag />'
|
||||
//See if the key is already taken.
|
||||
if(!isset($current[$tag])) { //New Key
|
||||
$current[$tag] = $result;
|
||||
$repeated_tag_index[$tag.'_'.$level] = 1;
|
||||
if($priority == 'tag' and $attributes_data) $current[$tag. '_attr'] = $attributes_data;
|
||||
|
||||
} else { // If taken, put all things inside a list(array)
|
||||
if(isset($current[$tag][0]) and is_array($current[$tag])) { // If it is already an array...
|
||||
|
||||
// ...push the new element into that array.
|
||||
$current[$tag][$repeated_tag_index[$tag.'_'.$level]] = $result;
|
||||
|
||||
if($priority == 'tag' and $get_attributes and $attributes_data) {
|
||||
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
|
||||
}
|
||||
$repeated_tag_index[$tag.'_'.$level]++;
|
||||
|
||||
} else { // If it is not an array...
|
||||
$current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
|
||||
$repeated_tag_index[$tag.'_'.$level] = 1;
|
||||
if($priority == 'tag' and $get_attributes) {
|
||||
if(isset($current[$tag.'_attr'])) { // The attribute of the last(0th) tag must be moved as well
|
||||
|
||||
$current[$tag]['0_attr'] = $current[$tag.'_attr'];
|
||||
unset($current[$tag.'_attr']);
|
||||
}
|
||||
|
||||
if($attributes_data) {
|
||||
$current[$tag][$repeated_tag_index[$tag.'_'.$level] . '_attr'] = $attributes_data;
|
||||
}
|
||||
}
|
||||
$repeated_tag_index[$tag.'_'.$level]++; // 0 and 1 indexes are already taken
|
||||
}
|
||||
}
|
||||
|
||||
} elseif($type == 'close') { // End of tag '</tag>'
|
||||
$current = &$parent[$level-1];
|
||||
}
|
||||
}
|
||||
|
||||
return($xml_array);
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ function notifier_run($argv, $argc){
|
|||
$uid = $r[0]['uid'];
|
||||
$updated = $r[0]['edited'];
|
||||
|
||||
// The following seems superfluous. We've already checked for "if (! intval($r[0]['parent']))" a few lines up
|
||||
if(! $parent_id)
|
||||
return;
|
||||
|
||||
|
@ -220,7 +221,7 @@ function notifier_run($argv, $argc){
|
|||
}
|
||||
|
||||
|
||||
if(($cmd === 'uplink') && (intval($parent['forum_mode'])) && (! $top_level)) {
|
||||
if(($cmd === 'uplink') && (intval($parent['forum_mode']) == 1) && (! $top_level)) {
|
||||
$relay_to_owner = true;
|
||||
}
|
||||
|
||||
|
@ -265,10 +266,10 @@ function notifier_run($argv, $argc){
|
|||
$deny_people = expand_acl($parent['deny_cid']);
|
||||
$deny_groups = expand_groups(expand_acl($parent['deny_gid']));
|
||||
|
||||
// if our parent is a forum, uplink to the origional author causing
|
||||
// a delivery fork
|
||||
// if our parent is a public forum (forum_mode == 1), uplink to the origional author causing
|
||||
// a delivery fork. private groups (forum_mode == 2) do not uplink
|
||||
|
||||
if(intval($parent['forum_mode']) && (! $top_level) && ($cmd !== 'uplink')) {
|
||||
if((intval($parent['forum_mode']) == 1) && (! $top_level) && ($cmd !== 'uplink')) {
|
||||
proc_run('php','include/notifier','uplink',$item_id);
|
||||
}
|
||||
|
||||
|
@ -345,7 +346,7 @@ function notifier_run($argv, $argc){
|
|||
if($mail) {
|
||||
$public_message = false; // mail is not public
|
||||
|
||||
$body = fix_private_photos($item['body'],$owner['uid']);
|
||||
$body = fix_private_photos($item['body'],$owner['uid'],null,$message[0]['contact-id']);
|
||||
|
||||
$atom .= replace_macros($mail_template, array(
|
||||
'$name' => xmlify($owner['name']),
|
||||
|
@ -478,17 +479,42 @@ function notifier_run($argv, $argc){
|
|||
}
|
||||
}
|
||||
|
||||
foreach($r as $contact) {
|
||||
|
||||
// This controls the number of deliveries to execute with each separate delivery process.
|
||||
// By default we'll perform one delivery per process. Assuming a hostile shared hosting
|
||||
// provider, this provides the greatest chance of deliveries if processes start getting
|
||||
// killed. We can also space them out with the delivery_interval to also help avoid them
|
||||
// getting whacked.
|
||||
|
||||
// If $deliveries_per_process > 1, we will chain this number of multiple deliveries
|
||||
// together into a single process. This will reduce the overall number of processes
|
||||
// spawned for each delivery, but they will run longer.
|
||||
|
||||
$deliveries_per_process = intval(get_config('system','delivery_batch_count'));
|
||||
if($deliveries_per_process <= 0)
|
||||
$deliveries_per_process = 1;
|
||||
|
||||
$this_batch = array();
|
||||
|
||||
for($x = 0; $x < count($r); $x ++) {
|
||||
$contact = $r[$x];
|
||||
|
||||
if($contact['self'])
|
||||
continue;
|
||||
|
||||
// potentially more than one recipient. Start a new process and space them out a bit.
|
||||
// we will deliver single recipient types of message and email receipients here.
|
||||
// we will deliver single recipient types of message and email recipients here.
|
||||
|
||||
if((! $mail) && (! $fsuggest) && (! $followup)) {
|
||||
proc_run('php','include/delivery.php',$cmd,$item_id,$contact['id']);
|
||||
|
||||
$this_batch[] = $contact['id'];
|
||||
|
||||
if(count($this_batch) == $deliveries_per_process) {
|
||||
proc_run('php','include/delivery.php',$cmd,$item_id,$this_batch);
|
||||
$this_batch = array();
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -571,7 +597,7 @@ function notifier_run($argv, $argc){
|
|||
break;
|
||||
case NETWORK_OSTATUS:
|
||||
|
||||
// Do not send to otatus if we are not configured to send to public networks
|
||||
// Do not send to ostatus if we are not configured to send to public networks
|
||||
if($owner['prvnets'])
|
||||
break;
|
||||
if(get_config('system','ostatus_disabled') || get_config('system','dfrn_only'))
|
||||
|
@ -712,18 +738,19 @@ function notifier_run($argv, $argc){
|
|||
// unsupported
|
||||
break;
|
||||
}
|
||||
elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
|
||||
// diaspora delete,
|
||||
elseif(($target_item['deleted']) && (($target_item['uri'] === $target_item['parent-uri']) || $followup)) {
|
||||
// send both top-level retractions and relayable retractions for owner to relay
|
||||
diaspora_send_retraction($target_item,$owner,$contact);
|
||||
break;
|
||||
}
|
||||
elseif($followup) {
|
||||
// send comments, likes and retractions of likes to owner to relay
|
||||
// send comments and likes to owner to relay
|
||||
diaspora_send_followup($target_item,$owner,$contact);
|
||||
break;
|
||||
}
|
||||
elseif($target_item['parent'] != $target_item['id']) {
|
||||
// we are the relay - send comments, likes and unlikes to our conversants
|
||||
elseif($target_item['uri'] !== $target_item['parent-uri']) {
|
||||
// we are the relay - send comments, likes and relayable_retractions
|
||||
// (of comments and likes) to our conversants
|
||||
diaspora_send_relay($target_item,$owner,$contact);
|
||||
break;
|
||||
}
|
||||
|
@ -833,6 +860,13 @@ function notifier_run($argv, $argc){
|
|||
|
||||
}
|
||||
|
||||
// If the item was deleted, clean up the `sign` table
|
||||
if($target_item['deleted']) {
|
||||
$r = q("DELETE FROM sign where `retract_iid` = %d",
|
||||
intval($target_item['id'])
|
||||
);
|
||||
}
|
||||
|
||||
logger('notifier: calling hooks', LOGGER_DEBUG);
|
||||
|
||||
if($normal_mode)
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
*/
|
||||
|
||||
|
||||
if(! function_exists('get_language')) {
|
||||
function get_language() {
|
||||
if(! function_exists('get_browser_language')) {
|
||||
function get_browser_language() {
|
||||
|
||||
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
if (x($_SERVER,'HTTP_ACCEPT_LANGUAGE')) {
|
||||
// break up string into pieces (languages and q factors)
|
||||
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
|
||||
$_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
|
||||
|
|
|
@ -25,7 +25,7 @@ function advanced_profile(&$a) {
|
|||
|
||||
$val = ((intval($a->profile['dob']))
|
||||
? day_translate(datetime_convert('UTC','UTC',$a->profile['dob'] . ' 00:00 +00:00',$year_bd_format))
|
||||
: day_translate(datetime_convert('UTC','UTC','2001-' . substr($a->profile['dob'],6) . ' 00:00 +00:00',$short_bd_format)));
|
||||
: day_translate(datetime_convert('UTC','UTC','2001-' . substr($a->profile['dob'],5) . ' 00:00 +00:00',$short_bd_format)));
|
||||
|
||||
$profile['birthday'] = array( t('Birthday:'), $val);
|
||||
|
||||
|
@ -39,11 +39,16 @@ function advanced_profile(&$a) {
|
|||
|
||||
if($a->profile['with']) $profile['marital']['with'] = $a->profile['with'];
|
||||
|
||||
if(strlen($a->profile['howlong']) && $a->profile['howlong'] !== '0000-00-00 00:00:00') {
|
||||
$profile['howlong'] = relative_date($a->profile['howlong'], t('for %1$d %2$s'));
|
||||
}
|
||||
|
||||
if($a->profile['sexual']) $profile['sexual'] = array( t('Sexual Preference:'), $a->profile['sexual'] );
|
||||
|
||||
if($a->profile['homepage']) $profile['homepage'] = array( t('Homepage:'), linkify($a->profile['homepage']) );
|
||||
|
||||
if($a->profile['hometown']) $profile['hometown'] = array( t('Hometown:'), linkify($a->profile['hometown']) );
|
||||
|
||||
if($a->profile['pub_keywords']) $profile['pub_keywords'] = array( t('Tags:'), $a->profile['pub_keywords']);
|
||||
|
||||
if($a->profile['politic']) $profile['politic'] = array( t('Political Views:'), $a->profile['politic']);
|
||||
|
|
|
@ -5,6 +5,8 @@ function gender_selector($current="",$suffix="") {
|
|||
$o = '';
|
||||
$select = array('', t('Male'), t('Female'), t('Currently Male'), t('Currently Female'), t('Mostly Male'), t('Mostly Female'), t('Transgender'), t('Intersex'), t('Transsexual'), t('Hermaphrodite'), t('Neuter'), t('Non-specific'), t('Other'), t('Undecided'));
|
||||
|
||||
call_hooks('gender_selector', $select);
|
||||
|
||||
$o .= "<select name=\"gender$suffix\" id=\"gender-select$suffix\" size=\"1\" >";
|
||||
foreach($select as $selection) {
|
||||
if($selection !== 'NOTRANSLATION') {
|
||||
|
@ -20,6 +22,9 @@ function sexpref_selector($current="",$suffix="") {
|
|||
$o = '';
|
||||
$select = array('', t('Males'), t('Females'), t('Gay'), t('Lesbian'), t('No Preference'), t('Bisexual'), t('Autosexual'), t('Abstinent'), t('Virgin'), t('Deviant'), t('Fetish'), t('Oodles'), t('Nonsexual'));
|
||||
|
||||
|
||||
call_hooks('sexpref_selector', $select);
|
||||
|
||||
$o .= "<select name=\"sexual$suffix\" id=\"sexual-select$suffix\" size=\"1\" >";
|
||||
foreach($select as $selection) {
|
||||
if($selection !== 'NOTRANSLATION') {
|
||||
|
@ -36,6 +41,8 @@ function marital_selector($current="",$suffix="") {
|
|||
$o = '';
|
||||
$select = array('', t('Single'), t('Lonely'), t('Available'), t('Unavailable'), t('Has crush'), t('Infatuated'), t('Dating'), t('Unfaithful'), t('Sex Addict'), t('Friends'), t('Friends/Benefits'), t('Casual'), t('Engaged'), t('Married'), t('Imaginarily married'), t('Partners'), t('Cohabiting'), t('Common law'), t('Happy'), t('Not looking'), t('Swinger'), t('Betrayed'), t('Separated'), t('Unstable'), t('Divorced'), t('Imaginarily divorced'), t('Widowed'), t('Uncertain'), t('It\'s complicated'), t('Don\'t care'), t('Ask me') );
|
||||
|
||||
call_hooks('marital_selector', $select);
|
||||
|
||||
$o .= "<select name=\"marital\" id=\"marital-select\" size=\"1\" >";
|
||||
foreach($select as $selection) {
|
||||
if($selection !== 'NOTRANSLATION') {
|
||||
|
|
|
@ -76,7 +76,7 @@ function authenticate_success($user_record, $login_initial = false, $interactive
|
|||
header('X-Account-Management-Status: active; name="' . $a->user['username'] . '"; id="' . $a->user['nickname'] .'"');
|
||||
|
||||
if($login_initial) {
|
||||
$l = get_language();
|
||||
$l = get_browser_language();
|
||||
|
||||
q("UPDATE `user` SET `login_date` = '%s', `language` = '%s' WHERE `uid` = %d LIMIT 1",
|
||||
dbesc(datetime_convert()),
|
||||
|
|
|
@ -71,6 +71,7 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
|
|||
|
||||
$name = $entry->displayName;
|
||||
|
||||
if(isset($entry->urls)) {
|
||||
foreach($entry->urls as $url) {
|
||||
if($url->type == 'profile') {
|
||||
$profile_url = $url->value;
|
||||
|
@ -81,12 +82,15 @@ function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isset($entry->photos)) {
|
||||
foreach($entry->photos as $photo) {
|
||||
if($photo->type == 'profile') {
|
||||
$profile_photo = $photo->value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if((! $name) || (! $profile_url) || (! $profile_photo))
|
||||
continue;
|
||||
|
|
|
@ -646,7 +646,7 @@ function search($s,$id='search-box',$url='/search',$save = false) {
|
|||
$a = get_app();
|
||||
$o = '<div id="' . $id . '">';
|
||||
$o .= '<form action="' . $a->get_baseurl((stristr($url,'network')) ? true : false) . $url . '" method="get" >';
|
||||
$o .= '<input type="text" name="search" id="search-text" value="' . $s .'" />';
|
||||
$o .= '<input type="text" name="search" id="search-text" placeholder="' . t('Search') . '" value="' . $s .'" />';
|
||||
$o .= '<input type="submit" name="submit" id="search-submit" value="' . t('Search') . '" />';
|
||||
if($save)
|
||||
$o .= '<input type="submit" name="save" id="search-save" value="' . t('Save') . '" />';
|
||||
|
@ -742,6 +742,8 @@ function smilies($s, $sample = false) {
|
|||
':homebrew',
|
||||
':coffee',
|
||||
':facepalm',
|
||||
':like',
|
||||
':dislike',
|
||||
'~friendika',
|
||||
'~friendica'
|
||||
|
||||
|
@ -778,6 +780,8 @@ function smilies($s, $sample = false) {
|
|||
'<img src="' . $a->get_baseurl() . '/images/beer_mug.gif" alt=":homebrew" />',
|
||||
'<img src="' . $a->get_baseurl() . '/images/coffee.gif" alt=":coffee" />',
|
||||
'<img src="' . $a->get_baseurl() . '/images/smiley-facepalm.gif" alt=":facepalm" />',
|
||||
'<img src="' . $a->get_baseurl() . '/images/like.gif" alt=":like" />',
|
||||
'<img src="' . $a->get_baseurl() . '/images/dislike.gif" alt=":dislike" />',
|
||||
'<a href="http://project.friendika.com">~friendika <img src="' . $a->get_baseurl() . '/images/friendika-16.png" alt="~friendika" /></a>',
|
||||
'<a href="http://friendica.com">~friendica <img src="' . $a->get_baseurl() . '/images/friendica-16.png" alt="~friendica" /></a>'
|
||||
);
|
||||
|
@ -887,6 +891,7 @@ function prepare_body($item,$attach = false) {
|
|||
} else
|
||||
$s = prepare_text($item['body']);
|
||||
|
||||
|
||||
$prep_arr = array('item' => $item, 'html' => $s);
|
||||
call_hooks('prepare_body', $prep_arr);
|
||||
$s = $prep_arr['html'];
|
||||
|
@ -901,9 +906,10 @@ function prepare_body($item,$attach = false) {
|
|||
foreach($arr as $r) {
|
||||
$matches = false;
|
||||
$icon = '';
|
||||
$cnt = preg_match('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches);
|
||||
$cnt = preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"\[\/attach\]|',$r,$matches, PREG_SET_ORDER);
|
||||
if($cnt) {
|
||||
$icontype = strtolower(substr($matches[3],0,strpos($matches[3],'/')));
|
||||
foreach($matches as $mtch) {
|
||||
$icontype = strtolower(substr($mtch[3],0,strpos($mtch[3],'/')));
|
||||
switch($icontype) {
|
||||
case 'video':
|
||||
case 'audio':
|
||||
|
@ -915,10 +921,15 @@ function prepare_body($item,$attach = false) {
|
|||
$icon = '<div class="attachtype icon s22 type-unkn"></div>';
|
||||
break;
|
||||
}
|
||||
$title = ((strlen(trim($matches[4]))) ? escape_tags(trim($matches[4])) : escape_tags($matches[1]));
|
||||
$title .= ' ' . $matches[2] . ' ' . t('bytes');
|
||||
$title = ((strlen(trim($mtch[4]))) ? escape_tags(trim($mtch[4])) : escape_tags($mtch[1]));
|
||||
$title .= ' ' . $mtch[2] . ' ' . t('bytes');
|
||||
if((local_user() == $item['uid']) && $item['contact-id'] != $a->contact['id'])
|
||||
$the_url = $a->get_baseurl() . '/redir/' . $item['contact-id'] . '?f=1&url=' . $mtch[1];
|
||||
else
|
||||
$the_url = $mtch[1];
|
||||
|
||||
$s .= '<a href="' . strip_tags($matches[1]) . '" title="' . $title . '" class="attachlink" target="external-link" >' . $icon . '</a>';
|
||||
$s .= '<a href="' . strip_tags($the_url) . '" title="' . $title . '" class="attachlink" target="external-link" >' . $icon . '</a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
$s .= '<div class="clear"></div></div>';
|
||||
|
|
327
include/user.php
Normal file
327
include/user.php
Normal file
|
@ -0,0 +1,327 @@
|
|||
<?php
|
||||
|
||||
require_once('include/config.php');
|
||||
require_once('include/network.php');
|
||||
require_once('include/plugin.php');
|
||||
require_once('include/text.php');
|
||||
require_once('include/pgettext.php');
|
||||
require_once('include/datetime.php');
|
||||
|
||||
function create_user($arr) {
|
||||
|
||||
// Required: { username, nickname, email } or { openid_url }
|
||||
|
||||
$a = get_app();
|
||||
$result = array('success' => false, 'user' => null, 'password' => '', 'message' => '');
|
||||
|
||||
$using_invites = get_config('system','invitation_only');
|
||||
$num_invites = get_config('system','number_invites');
|
||||
|
||||
|
||||
$invite_id = ((x($arr,'invite_id')) ? notags(trim($arr['invite_id'])) : '');
|
||||
$username = ((x($arr,'username')) ? notags(trim($arr['username'])) : '');
|
||||
$nickname = ((x($arr,'nickname')) ? notags(trim($arr['nickname'])) : '');
|
||||
$email = ((x($arr,'email')) ? notags(trim($arr['email'])) : '');
|
||||
$openid_url = ((x($arr,'openid_url')) ? notags(trim($arr['openid_url'])) : '');
|
||||
$photo = ((x($arr,'photo')) ? notags(trim($arr['photo'])) : '');
|
||||
$password = ((x($arr,'password')) ? trim($arr['password']) : '');
|
||||
$blocked = ((x($arr,'blocked')) ? intval($arr['blocked']) : 0);
|
||||
$verified = ((x($arr,'verified')) ? intval($arr['verified']) : 0);
|
||||
|
||||
$publish = ((x($arr,'profile_publish_reg') && intval($arr['profile_publish_reg'])) ? 1 : 0);
|
||||
$netpublish = ((strlen(get_config('system','directory_submit_url'))) ? $publish : 0);
|
||||
|
||||
$tmp_str = $openid_url;
|
||||
|
||||
if($using_invites) {
|
||||
if(! $invite_id) {
|
||||
$result['message'] .= t('An invitation is required.') . EOL;
|
||||
return $result;
|
||||
}
|
||||
$r = q("select * from register where `hash` = '%s' limit 1", dbesc($invite_id));
|
||||
if(! results($r)) {
|
||||
$result['message'] .= t('Invitation could not be verified.') . EOL;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
if((! x($username)) || (! x($email)) || (! x($nickname))) {
|
||||
if($openid_url) {
|
||||
if(! validate_url($tmp_str)) {
|
||||
$result['message'] .= t('Invalid OpenID url') . EOL;
|
||||
return $result;
|
||||
}
|
||||
$_SESSION['register'] = 1;
|
||||
$_SESSION['openid'] = $openid_url;
|
||||
require_once('library/openid.php');
|
||||
$openid = new LightOpenID;
|
||||
$openid->identity = $openid_url;
|
||||
$openid->returnUrl = $a->get_baseurl() . '/openid';
|
||||
$openid->required = array('namePerson/friendly', 'contact/email', 'namePerson');
|
||||
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
|
||||
goaway($openid->authUrl());
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
notice( t('Please enter the required information.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
if(! validate_url($tmp_str))
|
||||
$openid_url = '';
|
||||
|
||||
|
||||
$err = '';
|
||||
|
||||
// collapse multiple spaces in name
|
||||
$username = preg_replace('/ +/',' ',$username);
|
||||
|
||||
if(mb_strlen($username) > 48)
|
||||
$result['message'] .= t('Please use a shorter name.') . EOL;
|
||||
if(mb_strlen($username) < 3)
|
||||
$result['message'] .= t('Name too short.') . EOL;
|
||||
|
||||
// I don't really like having this rule, but it cuts down
|
||||
// on the number of auto-registrations by Russian spammers
|
||||
|
||||
// Using preg_match was completely unreliable, due to mixed UTF-8 regex support
|
||||
// $no_utf = get_config('system','no_utf');
|
||||
// $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' );
|
||||
|
||||
// So now we are just looking for a space in the full name.
|
||||
|
||||
$loose_reg = get_config('system','no_regfullname');
|
||||
if(! $loose_reg) {
|
||||
$username = mb_convert_case($username,MB_CASE_TITLE,'UTF-8');
|
||||
if(! strpos($username,' '))
|
||||
$result['message'] .= t("That doesn't appear to be your full \x28First Last\x29 name.") . EOL;
|
||||
}
|
||||
|
||||
|
||||
if(! allowed_email($email))
|
||||
$result['message'] .= t('Your email domain is not among those allowed on this site.') . EOL;
|
||||
|
||||
if((! valid_email($email)) || (! validate_email($email)))
|
||||
$result['message'] .= t('Not a valid email address.') . EOL;
|
||||
|
||||
// Disallow somebody creating an account using openid that uses the admin email address,
|
||||
// since openid bypasses email verification. We'll allow it if there is not yet an admin account.
|
||||
|
||||
if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) {
|
||||
$r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1",
|
||||
dbesc($email)
|
||||
);
|
||||
if(count($r))
|
||||
$result['message'] .= t('Cannot use that email.') . EOL;
|
||||
}
|
||||
|
||||
$nickname = $arr['nickname'] = strtolower($nickname);
|
||||
|
||||
if(! preg_match("/^[a-z][a-z0-9\-\_]*$/",$nickname))
|
||||
$result['message'] .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL;
|
||||
$r = q("SELECT `uid` FROM `user`
|
||||
WHERE `nickname` = '%s' LIMIT 1",
|
||||
dbesc($nickname)
|
||||
);
|
||||
if(count($r))
|
||||
$result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
|
||||
|
||||
// Check deleted accounts that had this nickname. Doesn't matter to us,
|
||||
// but could be a security issue for federated platforms.
|
||||
|
||||
$r = q("SELECT * FROM `userd`
|
||||
WHERE `username` = '%s' LIMIT 1",
|
||||
dbesc($nickname)
|
||||
);
|
||||
if(count($r))
|
||||
$result['message'] .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL;
|
||||
|
||||
if(strlen($result['message'])) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
$new_password = ((strlen($password)) ? $password : autoname(6) . mt_rand(100,9999));
|
||||
$new_password_encoded = hash('whirlpool',$new_password);
|
||||
|
||||
$result['password'] = $new_password;
|
||||
|
||||
require_once('include/crypto.php');
|
||||
|
||||
$keys = new_keypair(1024);
|
||||
|
||||
if($keys === false) {
|
||||
$result['message'] .= t('SERIOUS ERROR: Generation of security keys failed.') . EOL;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$prvkey = $keys['prvkey'];
|
||||
$pubkey = $keys['pubkey'];
|
||||
|
||||
/**
|
||||
*
|
||||
* Create another keypair for signing/verifying
|
||||
* salmon protocol messages. We have to use a slightly
|
||||
* less robust key because this won't be using openssl
|
||||
* but the phpseclib. Since it is PHP interpreted code
|
||||
* it is not nearly as efficient, and the larger keys
|
||||
* will take several minutes each to process.
|
||||
*
|
||||
*/
|
||||
|
||||
$sres = new_keypair(512);
|
||||
$sprvkey = $sres['prvkey'];
|
||||
$spubkey = $sres['pubkey'];
|
||||
|
||||
$r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,
|
||||
`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone` )
|
||||
VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC' )",
|
||||
dbesc(generate_user_guid()),
|
||||
dbesc($username),
|
||||
dbesc($new_password_encoded),
|
||||
dbesc($email),
|
||||
dbesc($openid_url),
|
||||
dbesc($nickname),
|
||||
dbesc($pubkey),
|
||||
dbesc($prvkey),
|
||||
dbesc($spubkey),
|
||||
dbesc($sprvkey),
|
||||
dbesc(datetime_convert()),
|
||||
intval($verified),
|
||||
intval($blocked)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$r = q("SELECT * FROM `user`
|
||||
WHERE `username` = '%s' AND `password` = '%s' LIMIT 1",
|
||||
dbesc($username),
|
||||
dbesc($new_password_encoded)
|
||||
);
|
||||
if($r !== false && count($r)) {
|
||||
$u = $r[0];
|
||||
$newuid = intval($r[0]['uid']);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$result['message'] .= t('An error occurred during registration. Please try again.') . EOL ;
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* if somebody clicked submit twice very quickly, they could end up with two accounts
|
||||
* due to race condition. Remove this one.
|
||||
*/
|
||||
|
||||
$r = q("SELECT `uid` FROM `user`
|
||||
WHERE `nickname` = '%s' ",
|
||||
dbesc($nickname)
|
||||
);
|
||||
if((count($r) > 1) && $newuid) {
|
||||
$result['message'] .= t('Nickname is already registered. Please choose another.') . EOL;
|
||||
q("DELETE FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($newuid)
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
|
||||
if(x($newuid) !== false) {
|
||||
$r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )
|
||||
VALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ",
|
||||
intval($newuid),
|
||||
t('default'),
|
||||
1,
|
||||
dbesc($username),
|
||||
dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"),
|
||||
intval($publish),
|
||||
intval($netpublish)
|
||||
|
||||
);
|
||||
if($r === false) {
|
||||
$result['message'] .= t('An error occurred creating your default profile. Please try again.') . EOL;
|
||||
// Start fresh next time.
|
||||
$r = q("DELETE FROM `user` WHERE `uid` = %d",
|
||||
intval($newuid));
|
||||
return $result;
|
||||
}
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,
|
||||
`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness` )
|
||||
VALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ",
|
||||
intval($newuid),
|
||||
datetime_convert(),
|
||||
dbesc($username),
|
||||
dbesc($nickname),
|
||||
dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/profile/$nickname"),
|
||||
dbesc(normalise_link($a->get_baseurl() . "/profile/$nickname")),
|
||||
dbesc($a->get_baseurl() . "/dfrn_request/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/dfrn_notify/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/dfrn_poll/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/dfrn_confirm/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/poco/$nickname"),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert())
|
||||
);
|
||||
|
||||
// Create a group with no members. This allows somebody to use it
|
||||
// right away as a default group for new contacts.
|
||||
|
||||
require_once('include/group.php');
|
||||
group_add($newuid, t('Friends'));
|
||||
|
||||
}
|
||||
|
||||
// if we have no OpenID photo try to look up an avatar
|
||||
if(! strlen($photo))
|
||||
$photo = avatar_img($email);
|
||||
|
||||
// unless there is no avatar-plugin loaded
|
||||
if(strlen($photo)) {
|
||||
require_once('include/Photo.php');
|
||||
$photo_failure = false;
|
||||
|
||||
$filename = basename($photo);
|
||||
$img_str = fetch_url($photo,true);
|
||||
$img = new Photo($img_str);
|
||||
if($img->is_valid()) {
|
||||
|
||||
$img->scaleImageSquare(175);
|
||||
|
||||
$hash = photo_new_resource();
|
||||
|
||||
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4 );
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
$img->scaleImage(80);
|
||||
|
||||
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5 );
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
$img->scaleImage(48);
|
||||
|
||||
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6 );
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
if(! $photo_failure) {
|
||||
q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ",
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
call_hooks('register_account', $newuid);
|
||||
|
||||
$result['success'] = true;
|
||||
$result['user'] = $u;
|
||||
return $result;
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ $install = ((file_exists('.htconfig.php') && filesize('.htconfig.php')) ? false
|
|||
|
||||
@include(".htconfig.php");
|
||||
|
||||
$lang = get_language();
|
||||
$lang = get_browser_language();
|
||||
|
||||
load_translation_table($lang);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
//
|
||||
var gLngMaxStateLength=0;
|
||||
var gLngMaxCountryLength=0;
|
||||
var gLngNumberCountries=252;
|
||||
var gLngNumberCountries=253;
|
||||
var gLngNumberStates=0;
|
||||
var gLngSelectedCountry=0;
|
||||
var gLngSelectedState=0;
|
||||
|
@ -17,7 +17,7 @@ var gArCountryInfo;
|
|||
var gArStateInfo;
|
||||
// NOTE:
|
||||
// Some editors may exhibit problems viewing 2803 characters...
|
||||
var sCountryString = "|Afghanistan|Albania|Algeria|American Samoa|Angola|Anguilla|Antartica|Antigua and Barbuda|Argentina|Armenia|Aruba|Ashmore and Cartier Island|Australia|Austria|Azerbaijan|Bahamas|Bahrain|Bangladesh|Barbados|Belarus|Belgium|Belize|Benin|Bermuda|Bhutan|Bolivia|Bosnia and Herzegovina|Botswana|Brazil|British Virgin Islands|Brunei|Bulgaria|Burkina Faso|Burma|Burundi|Cambodia|Cameroon|Canada|Cape Verde|Cayman Islands|Central African Republic|Chad|Chile|China|Christmas Island|Clipperton Island|Cocos (Keeling) Islands|Colombia|Comoros|Congo, Democratic Republic of the|Congo, Republic of the|Cook Islands|Costa Rica|Cote d'Ivoire|Croatia|Cuba|Cyprus|Czech Republic|Denmark|Djibouti|Dominica|Dominican Republic|Ecuador|Egypt|El Salvador|Equatorial Guinea|Eritrea|Estonia|Ethiopia|Europa Island|Falkland Islands (Islas Malvinas)|Faroe Islands|Fiji|Finland|France|French Guiana|French Polynesia|French Southern and Antarctic Lands|Gabon|Gambia, The|Gaza Strip|Georgia|Germany|Ghana|Gibraltar|Glorioso Islands|Greece|Greenland|Grenada|Guadeloupe|Guam|Guatemala|Guernsey|Guinea|Guinea-Bissau|Guyana|Haiti|Heard Island and McDonald Islands|Holy See (Vatican City)|Honduras|Hong Kong|Howland Island|Hungary|Iceland|India|Indonesia|Iran|Iraq|Ireland|Ireland, Northern|Israel|Italy|Jamaica|Jan Mayen|Japan|Jarvis Island|Jersey|Johnston Atoll|Jordan|Juan de Nova Island|Kazakhstan|Kenya|Kiribati|Korea, North|Korea, South|Kuwait|Kyrgyzstan|Laos|Latvia|Lebanon|Lesotho|Liberia|Libya|Liechtenstein|Lithuania|Luxembourg|Macau|Macedonia, Former Yugoslav Republic of|Madagascar|Malawi|Malaysia|Maldives|Mali|Malta|Man, Isle of|Marshall Islands|Martinique|Mauritania|Mauritius|Mayotte|Mexico|Micronesia, Federated States of|Midway Islands|Moldova|Monaco|Mongolia|Montserrat|Morocco|Mozambique|Namibia|Nauru|Nepal|Netherlands|Netherlands Antilles|New Caledonia|New Zealand|Nicaragua|Niger|Nigeria|Niue|Norfolk Island|Northern Mariana Islands|Norway|Oman|Pakistan|Palau|Panama|Papua New Guinea|Paraguay|Peru|Philippines|Pitcaim Islands|Poland|Portugal|Puerto Rico|Qatar|Reunion|Romainia|Russia|Rwanda|Saint Helena|Saint Kitts and Nevis|Saint Lucia|Saint Pierre and Miquelon|Saint Vincent and the Grenadines|Samoa|San Marino|Sao Tome and Principe|Saudi Arabia|Scotland|Senegal|Seychelles|Sierra Leone|Singapore|Slovakia|Slovenia|Solomon Islands|Somalia|South Africa|South Georgia and South Sandwich Islands|Spain|Spratly Islands|Sri Lanka|Sudan|Suriname|Svalbard|Swaziland|Sweden|Switzerland|Syria|Taiwan|Tajikistan|Tanzania|Thailand|Tobago|Toga|Tokelau|Tonga|Trinidad|Tunisia|Turkey|Turkmenistan|Tuvalu|Uganda|Ukraine|United Arab Emirates|United Kingdom|Uruguay|USA|Uzbekistan|Vanuatu|Venezuela|Vietnam|Virgin Islands|Wales|Wallis and Futuna|West Bank|Western Sahara|Yemen|Yugoslavia|Zambia|Zimbabwe";
|
||||
var sCountryString = "|Afghanistan|Albania|Algeria|American Samoa|Angola|Anguilla|Antartica|Antigua and Barbuda|Argentina|Armenia|Aruba|Ashmore and Cartier Island|Australia|Austria|Azerbaijan|Bahamas|Bahrain|Bangladesh|Barbados|Belarus|Belgium|Belize|Benin|Bermuda|Bhutan|Bolivia|Bosnia and Herzegovina|Botswana|Brazil|British Virgin Islands|Brunei|Bulgaria|Burkina Faso|Burma|Burundi|Cambodia|Cameroon|Canada|Cape Verde|Cayman Islands|Central African Republic|Chad|Chile|China|Christmas Island|Clipperton Island|Cocos (Keeling) Islands|Colombia|Comoros|Congo, Democratic Republic of the|Congo, Republic of the|Cook Islands|Costa Rica|Cote d'Ivoire|Croatia|Cuba|Cyprus|Czech Republic|Denmark|Djibouti|Dominica|Dominican Republic|Ecuador|Egypt|El Salvador|Equatorial Guinea|Eritrea|Estonia|Ethiopia|Europa Island|Falkland Islands (Islas Malvinas)|Faroe Islands|Fiji|Finland|France|French Guiana|French Polynesia|French Southern and Antarctic Lands|Gabon|Gambia, The|Gaza Strip|Georgia|Germany|Ghana|Gibraltar|Glorioso Islands|Greece|Greenland|Grenada|Guadeloupe|Guam|Guatemala|Guernsey|Guinea|Guinea-Bissau|Guyana|Haiti|Heard Island and McDonald Islands|Holy See (Vatican City)|Honduras|Hong Kong|Howland Island|Hungary|Iceland|India|Indonesia|Iran|Iraq|Ireland|Ireland, Northern|Israel|Italy|Jamaica|Jan Mayen|Japan|Jarvis Island|Jersey|Johnston Atoll|Jordan|Juan de Nova Island|Kazakhstan|Kenya|Kiribati|Korea, North|Korea, South|Kuwait|Kyrgyzstan|Laos|Latvia|Lebanon|Lesotho|Liberia|Libya|Liechtenstein|Lithuania|Luxembourg|Macau|Macedonia, Former Yugoslav Republic of|Madagascar|Malawi|Malaysia|Maldives|Mali|Malta|Man, Isle of|Marshall Islands|Martinique|Mauritania|Mauritius|Mayotte|Mexico|Micronesia, Federated States of|Midway Islands|Moldova|Monaco|Mongolia|Montserrat|Morocco|Mozambique|Namibia|Nauru|Nepal|Netherlands|Netherlands Antilles|New Caledonia|New Zealand|Nicaragua|Niger|Nigeria|Niue|Norfolk Island|Northern Mariana Islands|Norway|Oman|Pakistan|Palau|Panama|Papua New Guinea|Paraguay|Peru|Philippines|Pitcaim Islands|Poland|Portugal|Puerto Rico|Qatar|Reunion|Romainia|Russia|Rwanda|Saint Helena|Saint Kitts and Nevis|Saint Lucia|Saint Pierre and Miquelon|Saint Vincent and the Grenadines|Samoa|San Marino|Sao Tome and Principe|Saudi Arabia|Scotland|Senegal|Seychelles|Sierra Leone|Singapore|Slovakia|Slovenia|Solomon Islands|Somalia|South Africa|South Georgia and South Sandwich Islands|Spain|Spratly Islands|Sri Lanka|Sudan|Suriname|Svalbard|Swaziland|Sweden|Switzerland|Syria|Taiwan|Tajikistan|Tanzania|Thailand|Tobago|Toga|Tokelau|Tonga|Trinidad|Tunisia|Turkey|Turkmenistan|Tuvalu|Uganda|Ukraine|United Arab Emirates|United Kingdom|Uruguay|USA|Uzbekistan|Vanuatu|Venezuela|Vietnam|Virgin Islands|Wales|Wallis and Futuna|West Bank|Western Sahara|Yemen|Yugoslavia|Zambia|Zimbabwe|Friendicaland"
|
||||
var aStates = new Array();
|
||||
|
||||
aStates[0]="";
|
||||
|
@ -275,7 +275,7 @@ aStates[249]="|'Adan|'Ataq|Abyan|Al Bayda'|Al Hudaydah|Al Jawf|Al Mahrah|Al Mahw
|
|||
aStates[250]="|Kosovo|Montenegro|Serbia|Vojvodina";
|
||||
aStates[251]="|Central|Copperbelt|Eastern|Luapula|Lusaka|North-Western|Northern|Southern|Western";
|
||||
aStates[252]="|Bulawayo|Harare|ManicalandMashonaland Central|Mashonaland East|Mashonaland West|Masvingo|Matabeleland North|Matabeleland South|Midlands";
|
||||
|
||||
aStates[253]="|Self Hosted|Private Server|Architects Of Sleep|DFRN|Distributed Friend Network|Free-Beer.ch|Foojbook|Free-Haven|Friendica.eu|Friendika.me.4.it|Friendika - I Ask Questions|Frndc.com|Hipatia|Hungerfreunde|Kaluguran Community|Kak Ste?|Karl.Markx.pm|Loozah Social Club|MyFriendica.net|MyFriendNetwork|Oi!|OpenMindSpace|Recolutionari.es|Sysfu Social Club|theshi.re|Tumpambae|Uzmiac|Other";
|
||||
/*
|
||||
* gArCountryInfo
|
||||
* (0) Country name
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
|
||||
/* nav update event */
|
||||
$('nav').bind('nav-update', function(e,data){;
|
||||
var invalid = $(data).find('invalid').text();
|
||||
if(invalid == 1) { window.location.href=window.location.href }
|
||||
|
||||
var net = $(data).find('net').text();
|
||||
if(net == 0) { net = ''; $('#net-update').removeClass('show') } else { $('#net-update').addClass('show') }
|
||||
$('#net-update').html(net);
|
||||
|
@ -211,7 +214,8 @@
|
|||
function NavUpdate() {
|
||||
|
||||
if(! stopped) {
|
||||
$.get("ping",function(data) {
|
||||
var pingCmd = 'ping' + ((localUser != 0) ? '?f=&uid=' + localUser : '');
|
||||
$.get(pingCmd,function(data) {
|
||||
$(data).find('result').each(function() {
|
||||
// send nav-update event
|
||||
$('nav').trigger('nav-update', this);
|
||||
|
|
1708
library/langdet/Text/LanguageDetect.php
Normal file
1708
library/langdet/Text/LanguageDetect.php
Normal file
File diff suppressed because it is too large
Load diff
57
library/langdet/Text/LanguageDetect/Exception.php
Normal file
57
library/langdet/Text/LanguageDetect/Exception.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
class Text_LanguageDetect_Exception extends Exception
|
||||
{
|
||||
/**
|
||||
* Database file could not be found
|
||||
*/
|
||||
const DB_NOT_FOUND = 10;
|
||||
|
||||
/**
|
||||
* Database file found, but not readable
|
||||
*/
|
||||
const DB_NOT_READABLE = 11;
|
||||
|
||||
/**
|
||||
* Database file is empty
|
||||
*/
|
||||
const DB_EMPTY = 12;
|
||||
|
||||
/**
|
||||
* Database contents is not a PHP array
|
||||
*/
|
||||
const DB_NOT_ARRAY = 13;
|
||||
|
||||
/**
|
||||
* Magic quotes are activated
|
||||
*/
|
||||
const MAGIC_QUOTES = 14;
|
||||
|
||||
|
||||
/**
|
||||
* Parameter of invalid type passed to method
|
||||
*/
|
||||
const PARAM_TYPE = 20;
|
||||
|
||||
/**
|
||||
* Character in parameter is invalid
|
||||
*/
|
||||
const INVALID_CHAR = 21;
|
||||
|
||||
|
||||
/**
|
||||
* Language is not in the database
|
||||
*/
|
||||
const UNKNOWN_LANGUAGE = 30;
|
||||
|
||||
|
||||
/**
|
||||
* Error during block detection
|
||||
*/
|
||||
const BLOCK_DETECTION = 40;
|
||||
|
||||
|
||||
/**
|
||||
* Error while clustering languages
|
||||
*/
|
||||
const NO_HIGHEST_KEY = 50;
|
||||
}
|
341
library/langdet/Text/LanguageDetect/ISO639.php
Normal file
341
library/langdet/Text/LanguageDetect/ISO639.php
Normal file
|
@ -0,0 +1,341 @@
|
|||
<?php
|
||||
/**
|
||||
* Part of Text_LanguageDetect
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @copyright 2011 Christian Weiske <cweiske@php.net>
|
||||
* @license http://www.debian.org/misc/bsd.license BSD
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/package/Text_LanguageDetect/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides a mapping between the languages from lang.dat and the
|
||||
* ISO 639-1 and ISO-639-2 codes.
|
||||
*
|
||||
* Note that this class contains only languages that exist in lang.dat.
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @copyright 2011 Christian Weiske <cweiske@php.net>
|
||||
* @license http://www.debian.org/misc/bsd.license BSD
|
||||
* @link http://www.loc.gov/standards/iso639-2/php/code_list.php
|
||||
*/
|
||||
class Text_LanguageDetect_ISO639
|
||||
{
|
||||
/**
|
||||
* Maps all language names from the language database to the
|
||||
* ISO 639-1 2-letter language code.
|
||||
*
|
||||
* NULL indicates that there is no 2-letter code.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $nameToCode2 = array(
|
||||
'albanian' => 'sq',
|
||||
'arabic' => 'ar',
|
||||
'azeri' => 'az',
|
||||
'bengali' => 'bn',
|
||||
'bulgarian' => 'bg',
|
||||
'cebuano' => null,
|
||||
'croatian' => 'hr',
|
||||
'czech' => 'cs',
|
||||
'danish' => 'da',
|
||||
'dutch' => 'nl',
|
||||
'english' => 'en',
|
||||
'estonian' => 'et',
|
||||
'farsi' => 'fa',
|
||||
'finnish' => 'fi',
|
||||
'french' => 'fr',
|
||||
'german' => 'de',
|
||||
'hausa' => 'ha',
|
||||
'hawaiian' => null,
|
||||
'hindi' => 'hi',
|
||||
'hungarian' => 'hu',
|
||||
'icelandic' => 'is',
|
||||
'indonesian' => 'id',
|
||||
'italian' => 'it',
|
||||
'kazakh' => 'kk',
|
||||
'kyrgyz' => 'ky',
|
||||
'latin' => 'la',
|
||||
'latvian' => 'lv',
|
||||
'lithuanian' => 'lt',
|
||||
'macedonian' => 'mk',
|
||||
'mongolian' => 'mn',
|
||||
'nepali' => 'ne',
|
||||
'norwegian' => 'no',
|
||||
'pashto' => 'ps',
|
||||
'pidgin' => null,
|
||||
'polish' => 'pl',
|
||||
'portuguese' => 'pt',
|
||||
'romanian' => 'ro',
|
||||
'russian' => 'ru',
|
||||
'serbian' => 'sr',
|
||||
'slovak' => 'sk',
|
||||
'slovene' => 'sl',
|
||||
'somali' => 'so',
|
||||
'spanish' => 'es',
|
||||
'swahili' => 'sw',
|
||||
'swedish' => 'sv',
|
||||
'tagalog' => 'tl',
|
||||
'turkish' => 'tr',
|
||||
'ukrainian' => 'uk',
|
||||
'urdu' => 'ur',
|
||||
'uzbek' => 'uz',
|
||||
'vietnamese' => 'vi',
|
||||
'welsh' => 'cy',
|
||||
);
|
||||
|
||||
/**
|
||||
* Maps all language names from the language database to the
|
||||
* ISO 639-2 3-letter language code.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $nameToCode3 = array(
|
||||
'albanian' => 'sqi',
|
||||
'arabic' => 'ara',
|
||||
'azeri' => 'aze',
|
||||
'bengali' => 'ben',
|
||||
'bulgarian' => 'bul',
|
||||
'cebuano' => 'ceb',
|
||||
'croatian' => 'hrv',
|
||||
'czech' => 'ces',
|
||||
'danish' => 'dan',
|
||||
'dutch' => 'nld',
|
||||
'english' => 'eng',
|
||||
'estonian' => 'est',
|
||||
'farsi' => 'fas',
|
||||
'finnish' => 'fin',
|
||||
'french' => 'fra',
|
||||
'german' => 'deu',
|
||||
'hausa' => 'hau',
|
||||
'hawaiian' => 'haw',
|
||||
'hindi' => 'hin',
|
||||
'hungarian' => 'hun',
|
||||
'icelandic' => 'isl',
|
||||
'indonesian' => 'ind',
|
||||
'italian' => 'ita',
|
||||
'kazakh' => 'kaz',
|
||||
'kyrgyz' => 'kir',
|
||||
'latin' => 'lat',
|
||||
'latvian' => 'lav',
|
||||
'lithuanian' => 'lit',
|
||||
'macedonian' => 'mkd',
|
||||
'mongolian' => 'mon',
|
||||
'nepali' => 'nep',
|
||||
'norwegian' => 'nor',
|
||||
'pashto' => 'pus',
|
||||
'pidgin' => 'crp',
|
||||
'polish' => 'pol',
|
||||
'portuguese' => 'por',
|
||||
'romanian' => 'ron',
|
||||
'russian' => 'rus',
|
||||
'serbian' => 'srp',
|
||||
'slovak' => 'slk',
|
||||
'slovene' => 'slv',
|
||||
'somali' => 'som',
|
||||
'spanish' => 'spa',
|
||||
'swahili' => 'swa',
|
||||
'swedish' => 'swe',
|
||||
'tagalog' => 'tgl',
|
||||
'turkish' => 'tur',
|
||||
'ukrainian' => 'ukr',
|
||||
'urdu' => 'urd',
|
||||
'uzbek' => 'uzb',
|
||||
'vietnamese' => 'vie',
|
||||
'welsh' => 'cym',
|
||||
);
|
||||
|
||||
/**
|
||||
* Maps ISO 639-1 2-letter language codes to the language names
|
||||
* in the language database
|
||||
*
|
||||
* Not all languages have a 2 letter code, so some are missing
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $code2ToName = array(
|
||||
'ar' => 'arabic',
|
||||
'az' => 'azeri',
|
||||
'bg' => 'bulgarian',
|
||||
'bn' => 'bengali',
|
||||
'cs' => 'czech',
|
||||
'cy' => 'welsh',
|
||||
'da' => 'danish',
|
||||
'de' => 'german',
|
||||
'en' => 'english',
|
||||
'es' => 'spanish',
|
||||
'et' => 'estonian',
|
||||
'fa' => 'farsi',
|
||||
'fi' => 'finnish',
|
||||
'fr' => 'french',
|
||||
'ha' => 'hausa',
|
||||
'hi' => 'hindi',
|
||||
'hr' => 'croatian',
|
||||
'hu' => 'hungarian',
|
||||
'id' => 'indonesian',
|
||||
'is' => 'icelandic',
|
||||
'it' => 'italian',
|
||||
'kk' => 'kazakh',
|
||||
'ky' => 'kyrgyz',
|
||||
'la' => 'latin',
|
||||
'lt' => 'lithuanian',
|
||||
'lv' => 'latvian',
|
||||
'mk' => 'macedonian',
|
||||
'mn' => 'mongolian',
|
||||
'ne' => 'nepali',
|
||||
'nl' => 'dutch',
|
||||
'no' => 'norwegian',
|
||||
'pl' => 'polish',
|
||||
'ps' => 'pashto',
|
||||
'pt' => 'portuguese',
|
||||
'ro' => 'romanian',
|
||||
'ru' => 'russian',
|
||||
'sk' => 'slovak',
|
||||
'sl' => 'slovene',
|
||||
'so' => 'somali',
|
||||
'sq' => 'albanian',
|
||||
'sr' => 'serbian',
|
||||
'sv' => 'swedish',
|
||||
'sw' => 'swahili',
|
||||
'tl' => 'tagalog',
|
||||
'tr' => 'turkish',
|
||||
'uk' => 'ukrainian',
|
||||
'ur' => 'urdu',
|
||||
'uz' => 'uzbek',
|
||||
'vi' => 'vietnamese',
|
||||
);
|
||||
|
||||
/**
|
||||
* Maps ISO 639-2 3-letter language codes to the language names
|
||||
* in the language database.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $code3ToName = array(
|
||||
'ara' => 'arabic',
|
||||
'aze' => 'azeri',
|
||||
'ben' => 'bengali',
|
||||
'bul' => 'bulgarian',
|
||||
'ceb' => 'cebuano',
|
||||
'ces' => 'czech',
|
||||
'crp' => 'pidgin',
|
||||
'cym' => 'welsh',
|
||||
'dan' => 'danish',
|
||||
'deu' => 'german',
|
||||
'eng' => 'english',
|
||||
'est' => 'estonian',
|
||||
'fas' => 'farsi',
|
||||
'fin' => 'finnish',
|
||||
'fra' => 'french',
|
||||
'hau' => 'hausa',
|
||||
'haw' => 'hawaiian',
|
||||
'hin' => 'hindi',
|
||||
'hrv' => 'croatian',
|
||||
'hun' => 'hungarian',
|
||||
'ind' => 'indonesian',
|
||||
'isl' => 'icelandic',
|
||||
'ita' => 'italian',
|
||||
'kaz' => 'kazakh',
|
||||
'kir' => 'kyrgyz',
|
||||
'lat' => 'latin',
|
||||
'lav' => 'latvian',
|
||||
'lit' => 'lithuanian',
|
||||
'mkd' => 'macedonian',
|
||||
'mon' => 'mongolian',
|
||||
'nep' => 'nepali',
|
||||
'nld' => 'dutch',
|
||||
'nor' => 'norwegian',
|
||||
'pol' => 'polish',
|
||||
'por' => 'portuguese',
|
||||
'pus' => 'pashto',
|
||||
'rom' => 'romanian',
|
||||
'rus' => 'russian',
|
||||
'slk' => 'slovak',
|
||||
'slv' => 'slovene',
|
||||
'som' => 'somali',
|
||||
'spa' => 'spanish',
|
||||
'sqi' => 'albanian',
|
||||
'srp' => 'serbian',
|
||||
'swa' => 'swahili',
|
||||
'swe' => 'swedish',
|
||||
'tgl' => 'tagalog',
|
||||
'tur' => 'turkish',
|
||||
'ukr' => 'ukrainian',
|
||||
'urd' => 'urdu',
|
||||
'uzb' => 'uzbek',
|
||||
'vie' => 'vietnamese',
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the 2-letter ISO 639-1 code for the given language name.
|
||||
*
|
||||
* @param string $lang English language name like "swedish"
|
||||
*
|
||||
* @return string Two-letter language code (e.g. "sv") or NULL if not found
|
||||
*/
|
||||
public static function nameToCode2($lang)
|
||||
{
|
||||
$lang = strtolower($lang);
|
||||
if (!isset(self::$nameToCode2[$lang])) {
|
||||
return null;
|
||||
}
|
||||
return self::$nameToCode2[$lang];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 3-letter ISO 639-2 code for the given language name.
|
||||
*
|
||||
* @param string $lang English language name like "swedish"
|
||||
*
|
||||
* @return string Three-letter language code (e.g. "swe") or NULL if not found
|
||||
*/
|
||||
public static function nameToCode3($lang)
|
||||
{
|
||||
$lang = strtolower($lang);
|
||||
if (!isset(self::$nameToCode3[$lang])) {
|
||||
return null;
|
||||
}
|
||||
return self::$nameToCode3[$lang];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language name for the given 2-letter ISO 639-1 code.
|
||||
*
|
||||
* @param string $code Two-letter language code (e.g. "sv")
|
||||
*
|
||||
* @return string English language name like "swedish"
|
||||
*/
|
||||
public static function code2ToName($code)
|
||||
{
|
||||
$lang = strtolower($code);
|
||||
if (!isset(self::$code2ToName[$code])) {
|
||||
return null;
|
||||
}
|
||||
return self::$code2ToName[$code];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language name for the given 3-letter ISO 639-2 code.
|
||||
*
|
||||
* @param string $code Three-letter language code (e.g. "swe")
|
||||
*
|
||||
* @return string English language name like "swedish"
|
||||
*/
|
||||
public static function code3ToName($code)
|
||||
{
|
||||
$lang = strtolower($code);
|
||||
if (!isset(self::$code3ToName[$code])) {
|
||||
return null;
|
||||
}
|
||||
return self::$code3ToName[$code];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
349
library/langdet/Text/LanguageDetect/Parser.php
Normal file
349
library/langdet/Text/LanguageDetect/Parser.php
Normal file
|
@ -0,0 +1,349 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This class represents a text sample to be parsed.
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Nicholas Pisarro
|
||||
* @copyright 2006
|
||||
* @license BSD
|
||||
* @version CVS: $Id: Parser.php 322327 2012-01-15 17:55:59Z cweiske $
|
||||
* @link http://pear.php.net/package/Text_LanguageDetect/
|
||||
* @link http://langdetect.blogspot.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class represents a text sample to be parsed.
|
||||
*
|
||||
* This separates the analysis of a text sample from the primary LanguageDetect
|
||||
* class. After a new profile has been built, the data can be retrieved using
|
||||
* the accessor functions.
|
||||
*
|
||||
* This class is intended to be used by the Text_LanguageDetect class, not
|
||||
* end-users.
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Nicholas Pisarro
|
||||
* @copyright 2006
|
||||
* @license BSD
|
||||
* @version release: 0.3.0
|
||||
*/
|
||||
class Text_LanguageDetect_Parser extends Text_LanguageDetect
|
||||
{
|
||||
/**
|
||||
* the piece of text being parsed
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $_string;
|
||||
|
||||
/**
|
||||
* stores the trigram frequencies of the sample
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $_trigrams = array();
|
||||
|
||||
/**
|
||||
* stores the trigram ranks of the sample
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $_trigram_ranks = array();
|
||||
|
||||
/**
|
||||
* stores the unicode blocks of the sample
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $_unicode_blocks = array();
|
||||
|
||||
/**
|
||||
* Whether the parser should compile the unicode ranges
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_compile_unicode = false;
|
||||
|
||||
/**
|
||||
* Whether the parser should compile trigrams
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_compile_trigram = false;
|
||||
|
||||
/**
|
||||
* Whether the trigram parser should pad the beginning of the string
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_trigram_pad_start = false;
|
||||
|
||||
/**
|
||||
* Whether the unicode parser should skip non-alphabetical ascii chars
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_unicode_skip_symbols = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $string string to be parsed
|
||||
*/
|
||||
function Text_LanguageDetect_Parser($string) {
|
||||
$this->_string = $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a string is suitable for parsing
|
||||
*
|
||||
* @param string $str input string to test
|
||||
* @return bool true if acceptable, false if not
|
||||
*/
|
||||
public static function validateString($str) {
|
||||
if (!empty($str) && strlen($str) > 3 && preg_match('/\S/', $str)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* turn on/off trigram counting
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function prepareTrigram($bool = true)
|
||||
{
|
||||
$this->_compile_trigram = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* turn on/off unicode block counting
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function prepareUnicode($bool = true)
|
||||
{
|
||||
$this->_compile_unicode = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* turn on/off padding the beginning of the sample string
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function setPadStart($bool = true)
|
||||
{
|
||||
$this->_trigram_pad_start = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the unicode block counter skip non-alphabetical ascii chars?
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function setUnicodeSkipSymbols($bool = true)
|
||||
{
|
||||
$this->_unicode_skip_symbols = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the trigram ranks for the text sample
|
||||
*
|
||||
* @access public
|
||||
* @return array trigram ranks in the text sample
|
||||
*/
|
||||
function &getTrigramRanks()
|
||||
{
|
||||
return $this->_trigram_ranks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the trigram freqency table
|
||||
*
|
||||
* only used in testing to make sure the parser is working
|
||||
*
|
||||
* @access public
|
||||
* @return array trigram freqencies in the text sample
|
||||
*/
|
||||
function &getTrigramFreqs()
|
||||
{
|
||||
return $this->_trigram;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the array of unicode blocks
|
||||
*
|
||||
* @access public
|
||||
* @return array unicode blocks in the text sample
|
||||
*/
|
||||
function &getUnicodeBlocks()
|
||||
{
|
||||
return $this->_unicode_blocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the parsing operation
|
||||
*
|
||||
* Be sure to call the set*() functions to set options and the
|
||||
* prepare*() functions first to tell it what kind of data to compute
|
||||
*
|
||||
* Afterwards the get*() functions can be used to access the compiled
|
||||
* information.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function analyze()
|
||||
{
|
||||
$len = strlen($this->_string);
|
||||
$byte_counter = 0;
|
||||
|
||||
|
||||
// unicode startup
|
||||
if ($this->_compile_unicode) {
|
||||
$blocks = $this->_read_unicode_block_db();
|
||||
$block_count = count($blocks);
|
||||
|
||||
$skipped_count = 0;
|
||||
$unicode_chars = array();
|
||||
}
|
||||
|
||||
// trigram startup
|
||||
if ($this->_compile_trigram) {
|
||||
// initialize them as blank so the parser will skip the first two
|
||||
// (since it skips trigrams with more than 2 contiguous spaces)
|
||||
$a = ' ';
|
||||
$b = ' ';
|
||||
|
||||
// kludge
|
||||
// if it finds a valid trigram to start and the start pad option is
|
||||
// off, then set a variable that will be used to reduce this
|
||||
// trigram after parsing has finished
|
||||
if (!$this->_trigram_pad_start) {
|
||||
$a = $this->_next_char($this->_string, $byte_counter, true);
|
||||
|
||||
if ($a != ' ') {
|
||||
$b = $this->_next_char($this->_string, $byte_counter, true);
|
||||
$dropone = " $a$b";
|
||||
}
|
||||
|
||||
$byte_counter = 0;
|
||||
$a = ' ';
|
||||
$b = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
while ($byte_counter < $len) {
|
||||
$char = $this->_next_char($this->_string, $byte_counter, true);
|
||||
|
||||
|
||||
// language trigram detection
|
||||
if ($this->_compile_trigram) {
|
||||
if (!($b == ' ' && ($a == ' ' || $char == ' '))) {
|
||||
if (!isset($this->_trigram[$a . $b . $char])) {
|
||||
$this->_trigram[$a . $b . $char] = 1;
|
||||
} else {
|
||||
$this->_trigram[$a . $b . $char]++;
|
||||
}
|
||||
}
|
||||
|
||||
$a = $b;
|
||||
$b = $char;
|
||||
}
|
||||
|
||||
// unicode block detection
|
||||
if ($this->_compile_unicode) {
|
||||
if ($this->_unicode_skip_symbols
|
||||
&& strlen($char) == 1
|
||||
&& ($char < 'A' || $char > 'z'
|
||||
|| ($char > 'Z' && $char < 'a'))
|
||||
&& $char != "'") { // does not skip the apostrophe
|
||||
// since it's included in the language
|
||||
// models
|
||||
|
||||
$skipped_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// build an array of all the characters
|
||||
if (isset($unicode_chars[$char])) {
|
||||
$unicode_chars[$char]++;
|
||||
} else {
|
||||
$unicode_chars[$char] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// todo: add byte detection here
|
||||
}
|
||||
|
||||
// unicode cleanup
|
||||
if ($this->_compile_unicode) {
|
||||
foreach ($unicode_chars as $utf8_char => $count) {
|
||||
$search_result = $this->_unicode_block_name(
|
||||
$this->_utf8char2unicode($utf8_char), $blocks, $block_count);
|
||||
|
||||
if ($search_result != -1) {
|
||||
$block_name = $search_result[2];
|
||||
} else {
|
||||
$block_name = '[Malformatted]';
|
||||
}
|
||||
|
||||
if (isset($this->_unicode_blocks[$block_name])) {
|
||||
$this->_unicode_blocks[$block_name] += $count;
|
||||
} else {
|
||||
$this->_unicode_blocks[$block_name] = $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// trigram cleanup
|
||||
if ($this->_compile_trigram) {
|
||||
// pad the end
|
||||
if ($b != ' ') {
|
||||
if (!isset($this->_trigram["$a$b "])) {
|
||||
$this->_trigram["$a$b "] = 1;
|
||||
} else {
|
||||
$this->_trigram["$a$b "]++;
|
||||
}
|
||||
}
|
||||
|
||||
// perl compatibility; Language::Guess does not pad the beginning
|
||||
// kludge
|
||||
if (isset($dropone)) {
|
||||
if ($this->_trigram[$dropone] == 1) {
|
||||
unset($this->_trigram[$dropone]);
|
||||
} else {
|
||||
$this->_trigram[$dropone]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->_trigram)) {
|
||||
$this->_trigram_ranks = $this->_arr_rank($this->_trigram);
|
||||
} else {
|
||||
$this->_trigram_ranks = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
?>
|
1
library/langdet/data/lang.dat
Normal file
1
library/langdet/data/lang.dat
Normal file
File diff suppressed because one or more lines are too long
1
library/langdet/data/unicode_blocks.dat
Normal file
1
library/langdet/data/unicode_blocks.dat
Normal file
File diff suppressed because one or more lines are too long
35
library/langdet/docs/example_clui.php
Normal file
35
library/langdet/docs/example_clui.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* example usage (CLI)
|
||||
*
|
||||
* @package Text_LanguageDetect
|
||||
* @version CVS: $Id: example_clui.php 322305 2012-01-15 00:04:17Z clockwerx $
|
||||
*/
|
||||
|
||||
require_once 'Text/LanguageDetect.php';
|
||||
|
||||
$l = new Text_LanguageDetect;
|
||||
|
||||
$stdin = fopen('php://stdin', 'r');
|
||||
|
||||
echo "Supported languages:\n";
|
||||
$langs = $l->getLanguages();
|
||||
sort($langs);
|
||||
echo join(', ', $langs);
|
||||
|
||||
echo "\ntotal ", count($langs), "\n\n";
|
||||
|
||||
while ($line = fgets($stdin)) {
|
||||
$result = $l->detect($line, 4);
|
||||
print_r($result);
|
||||
$blocks = $l->detectUnicodeBlocks($line, true);
|
||||
print_r($blocks);
|
||||
}
|
||||
|
||||
fclose($stdin);
|
||||
unset($l);
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
?>
|
72
library/langdet/docs/example_web.php
Normal file
72
library/langdet/docs/example_web.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* example usage (web)
|
||||
*
|
||||
* @package Text_LanguageDetect
|
||||
* @version CVS: $Id: example_web.php 205493 2006-01-18 00:26:57Z taak $
|
||||
*/
|
||||
|
||||
// browsers will encode multi-byte characters wrong unless they think the page is utf8-encoded
|
||||
header('Content-type: text/html; charset=utf-8', true);
|
||||
|
||||
require_once 'Text/LanguageDetect.php';
|
||||
|
||||
$l = new Text_LanguageDetect;
|
||||
if (isset($_REQUEST['q'])) {
|
||||
$q = stripslashes($_REQUEST['q']);
|
||||
}
|
||||
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Text_LanguageDetect demonstration</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Text_LanguageDetect</h2>
|
||||
<?
|
||||
echo "<small>Supported languages:\n";
|
||||
$langs = $l->getLanguages();
|
||||
sort($langs);
|
||||
foreach ($langs as $lang) {
|
||||
echo ucfirst($lang), ', ';
|
||||
$i++;
|
||||
}
|
||||
|
||||
echo "<br />total $i</small><br /><br />";
|
||||
|
||||
?>
|
||||
<form method="post">
|
||||
Enter text to identify language (at least a couple of sentences):<br />
|
||||
<textarea name="q" wrap="virtual" cols="80" rows="8"><?= $q ?></textarea>
|
||||
<br />
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
<?
|
||||
if (isset($q) && strlen($q)) {
|
||||
$len = $l->utf8strlen($q);
|
||||
if ($len < 20) { // this value picked somewhat arbitrarily
|
||||
echo "Warning: string not very long ($len chars)<br />\n";
|
||||
}
|
||||
|
||||
$result = $l->detectConfidence($q);
|
||||
|
||||
if ($result == null) {
|
||||
echo "Text_LanguageDetect cannot identify this piece of text. <br /><br />\n";
|
||||
} else {
|
||||
echo "Text_LanguageDetect thinks this text is written in <b>{$result['language']}</b> ({$result['similarity']}, {$result['confidence']})<br /><br />\n";
|
||||
}
|
||||
|
||||
$result = $l->detectUnicodeBlocks($q, false);
|
||||
if (!empty($result)) {
|
||||
arsort($result);
|
||||
echo "Unicode blocks present: ", join(', ', array_keys($result)), "\n<br /><br />";
|
||||
}
|
||||
}
|
||||
|
||||
unset($l);
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
?>
|
||||
</body></html>
|
21
library/langdet/docs/iso.php
Normal file
21
library/langdet/docs/iso.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* Demonstrates how to use ISO language codes.
|
||||
*
|
||||
* The "name mode" changes the way languages are accepted and returned.
|
||||
*/
|
||||
require_once 'Text/LanguageDetect.php';
|
||||
$l = new Text_LanguageDetect();
|
||||
|
||||
|
||||
//will output the ISO 639-1 two-letter language code
|
||||
// "de"
|
||||
$l->setNameMode(2);
|
||||
echo $l->detectSimple('Das ist ein kleiner Text') . "\n";
|
||||
|
||||
//will output the ISO 639-2 three-letter language code
|
||||
// "deu"
|
||||
$l->setNameMode(3);
|
||||
echo $l->detectSimple('Das ist ein kleiner Text') . "\n";
|
||||
|
||||
?>
|
2056
library/langdet/tests/Text_LanguageDetectTest.php
Normal file
2056
library/langdet/tests/Text_LanguageDetectTest.php
Normal file
File diff suppressed because it is too large
Load diff
72
library/langdet/tests/Text_LanguageDetect_ISO639Test.php
Normal file
72
library/langdet/tests/Text_LanguageDetect_ISO639Test.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
set_include_path(
|
||||
__DIR__ . '/../' . PATH_SEPARATOR . get_include_path()
|
||||
);
|
||||
|
||||
require_once 'Text/LanguageDetect/ISO639.php';
|
||||
|
||||
class Text_LanguageDetect_ISO639Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testNameToCode2()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'de',
|
||||
Text_LanguageDetect_ISO639::nameToCode2('german')
|
||||
);
|
||||
}
|
||||
|
||||
public function testNameToCode2Fail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::nameToCode2('doesnotexist')
|
||||
);
|
||||
}
|
||||
|
||||
public function testNameToCode3()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'fra',
|
||||
Text_LanguageDetect_ISO639::nameToCode3('french')
|
||||
);
|
||||
}
|
||||
|
||||
public function testNameToCode3Fail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::nameToCode3('doesnotexist')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode2ToName()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'english',
|
||||
Text_LanguageDetect_ISO639::code2ToName('en')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode2ToNameFail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::code2ToName('nx')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode3ToName()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'romanian',
|
||||
Text_LanguageDetect_ISO639::code3ToName('rom')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode3ToNameFail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::code3ToName('nxx')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,3 +1,46 @@
|
|||
Version 3.5.0.1 (2012-05-10)
|
||||
Fixed bug where selection normalization logic would break the selections of parent elements using the element path.
|
||||
Fixed bug where the autolink plugin would include trailing dots in domain names in the link creation.
|
||||
Fixed bug where the autolink plugin would produce an error on older IE versions when pressing enter.
|
||||
Fixed bug where old IE versions would throw an error during initialization when the editor was placed in an size restricted div.
|
||||
Version 3.5 (2012-05-03)
|
||||
Fixed menu rendering issue if the document was in rtl mode.
|
||||
Fixed bug where the hide function would throw an error about a missing variable.
|
||||
Fixed bug where autolink wouldn't convert URLs when hitting enter on IE due to the new enter key logic.
|
||||
Fixed bug where formatting using shortcuts like ctrl+b wouldn't work properly the first time.
|
||||
Fixed bug where selection.setContent after a formatter call wouldn't generate formatted contents.
|
||||
Fixed bug where whitespace would be removed before/after invalid_elements when they where removed.
|
||||
Fixed bug where updating styles using the theme image dialog in non inline mode on IE9 would produce errors.
|
||||
Fixed bug where IE 8 would produce an error when using the contextmenu plugin.
|
||||
Fixed bug where delete/backspace could remove contents of noneditable elements.
|
||||
Fixed so background color in style preview gets computed from body element if the current style element is transparent.
|
||||
Version 3.5b3 (2012-03-29)
|
||||
Added cancel button to colour picker dialog.
|
||||
Added figure and figcaption to the html5 visualblocks plugin.
|
||||
Added default alignment options for the figure element.
|
||||
Fixed bug where empty inline elements within block elements would sometimes produce a br child element.
|
||||
Fixed bug where urls pointing to the same domain as the current one would cause undefined errors. Patch contributed by Paul Giberson.
|
||||
Fixed bug where enter inside an editable element inside an non editable element would split the element.
|
||||
Fixed bug where cut/copy/paste of noneditable elements didn't work.
|
||||
Fixed bug where backspace would sometimes produce font elements on WebKit.
|
||||
Fixed bug where WebKit would produce spans out of various inline elements when using backspace.
|
||||
Fixed bug where IE9 wouldn't properly update image styles when images where resized.
|
||||
Fixed bug where drag/drop of noneditable elements didn't work correctly.
|
||||
Fixed bug where applying formatting to all contents wouldn't work correctly when an end point was inside an empty bock. Patch contributed by Jose Luiz.
|
||||
Fixed bug where IE10 removed the scopeName from the DOM element interface and there for it produced an undefined string in element path.
|
||||
Fixed bug where the caret would be placed at an incorrect location if you applied block formatting while having the caret at the end of the block.
|
||||
Fixed bug where applying column changes using the cell dialog would only update the first column. Patch contributed by krzyko.
|
||||
Fixed bug where the visualblocks plugin would force editor focus if it was turned on by default.
|
||||
Fixed bug where the tabfocus plugin would tab to iframes these are now ignored.
|
||||
Fixed bug where format drop down list wouldn't show the currently active format for a parent element.
|
||||
Fixed bug where paste of plain text in IE 9 would remove the new line characters from text.
|
||||
Fixed bug where the menu buttons/split button menus wouldn't be opened at the right location on older IE versions.
|
||||
Fixed bug where Gecko browsers wouldn't properly display the right format when having the selection as specific places.
|
||||
Fixed bug where shift+enter inside the body when having forced_root_blocks set to false would throw an error.
|
||||
Fixed bug where the jQuery plugin would break the attr method of jQuery 1.7.2. Patch contributed by Markus Kemmerling.
|
||||
Fixed so options like content_css accepts and array as well as a comma separated string as input.
|
||||
Restructured the internal logic to make it more separate from Editor.js.
|
||||
Updated the Sizzle engine to the latest version.
|
||||
Version 3.5b2 (2012-03-15)
|
||||
Rewrote the enter key logic to normalize browser behavior.
|
||||
Fixed so enter within PRE elements produces a BR and shift+enter breaks/end the PRE. Can be disabled using the br_in_pre option.
|
||||
|
@ -19,15 +62,6 @@ Version 3.5b1 (2012-03-08)
|
|||
Fixed bug where the advlink dialog would produce an error about the addSelectAccessibility function not being defined.
|
||||
Fixed bug where the caret would be placed at an incorrect position if span was removed by the invalid_elements setting.
|
||||
Fixed bug where elements inside a white space preserve element like pre didn't inherit the behavior while parsing.
|
||||
Version 3.4.9.x (2012-02-xx)
|
||||
Improved behaviour of backspacing into a table to be consistant across browsers and disable backspace when cursor immediately follows a table.
|
||||
Improved edit CSS style plugin for single and multiple block selection and provide option to apply style to only selected text.
|
||||
Fixed bug in Chrome where moving caret down in table and pasting throws errors.
|
||||
Corrected reference to TinyMCE trim function.
|
||||
Fixed bug where Ignore All in IE did not remove the underline from the selected word.
|
||||
Fixed bug in html source editor word wrap option not wrapping text in Webkit browsers.
|
||||
Fixed bug where it was possible to insert an invalid colour in the color pop-up dialog.
|
||||
Fixed bug in Webkit where if anchor is on last line by itself caret can not be placed after it.
|
||||
Version 3.4.9 (2012-02-23)
|
||||
Added settings to wordcount plugin to configure update rate and checking wordcount on backspace and delete using wordcount_update_rate and wordcount_update_on_delete.
|
||||
Fixed bug in Webkit and IE where deleting empty paragraphs would remove entire editor contents.
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;if(tinyMCE.isIE){return}a.onKeyDown.add(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng().cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();
|
||||
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;a.onKeyDown.addToTop(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});if(tinyMCE.isIE){return}a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng(true).cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}var m=a.toString();if(m.charAt(m.length-1)=="."){a.setEnd(n,c-1)}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();
|
|
@ -22,16 +22,16 @@
|
|||
init : function(ed, url) {
|
||||
var t = this;
|
||||
|
||||
// Internet Explorer has built-in automatic linking
|
||||
if (tinyMCE.isIE)
|
||||
return;
|
||||
|
||||
// Add a key down handler
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
ed.onKeyDown.addToTop(function(ed, e) {
|
||||
if (e.keyCode == 13)
|
||||
return t.handleEnter(ed);
|
||||
});
|
||||
|
||||
// Internet Explorer has built-in automatic linking for most cases
|
||||
if (tinyMCE.isIE)
|
||||
return;
|
||||
|
||||
ed.onKeyPress.add(function(ed, e) {
|
||||
if (e.which == 41)
|
||||
return t.handleEclipse(ed);
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
// We need at least five characters to form a URL,
|
||||
// hence, at minimum, five characters from the beginning of the line.
|
||||
r = ed.selection.getRng().cloneRange();
|
||||
r = ed.selection.getRng(true).cloneRange();
|
||||
if (r.startOffset < 5) {
|
||||
// During testing, the caret is placed inbetween two text nodes.
|
||||
// The previous text node contains the URL.
|
||||
|
@ -124,6 +124,12 @@
|
|||
r.setEnd(endContainer, start);
|
||||
}
|
||||
|
||||
// Exclude last . from word like "www.site.com."
|
||||
var text = r.toString();
|
||||
if (text.charAt(text.length - 1) == '.') {
|
||||
r.setEnd(endContainer, start - 1);
|
||||
}
|
||||
|
||||
text = r.toString();
|
||||
matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();
|
||||
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6||document.compatMode=="BackCompat"){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();
|
|
@ -79,7 +79,7 @@
|
|||
vp.h -= 1;
|
||||
|
||||
// Use fixed position if it exists
|
||||
if (tinymce.isIE6)
|
||||
if (tinymce.isIE6 || document.compatMode == 'BackCompat')
|
||||
posCss = 'absolute;top:' + vp.y;
|
||||
else
|
||||
posCss = 'fixed;top:0';
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -261,12 +261,96 @@
|
|||
selection.collapse(start);
|
||||
}
|
||||
|
||||
function canDelete(backspace) {
|
||||
var rng, container, offset, nonEditableParent;
|
||||
|
||||
function removeNodeIfNotParent(node) {
|
||||
var parent = container;
|
||||
|
||||
while (parent) {
|
||||
if (parent === node) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
dom.remove(node);
|
||||
moveSelection();
|
||||
}
|
||||
|
||||
function isNextPrevTreeNodeNonEditable() {
|
||||
var node, walker, nonEmptyElements = ed.schema.getNonEmptyElements();
|
||||
|
||||
walker = new tinymce.dom.TreeWalker(container, ed.getBody());
|
||||
while (node = (backspace ? walker.prev() : walker.next())) {
|
||||
// Found IMG/INPUT etc
|
||||
if (nonEmptyElements[node.nodeName.toLowerCase()]) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found text node with contents
|
||||
if (node.nodeType === 3 && tinymce.trim(node.nodeValue).length > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found non editable node
|
||||
if (getContentEditable(node) === "false") {
|
||||
removeNodeIfNotParent(node);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the content node is within a non editable parent
|
||||
if (getNonEditableParent(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selection.isCollapsed()) {
|
||||
rng = selection.getRng(true);
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
container = getParentCaretContainer(container) || container;
|
||||
|
||||
// Is in noneditable parent
|
||||
if (nonEditableParent = getNonEditableParent(container)) {
|
||||
removeNodeIfNotParent(nonEditableParent);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the caret is in the middle of a text node
|
||||
if (container.nodeType == 3 && (backspace ? offset > 0 : offset < container.nodeValue.length)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve container index
|
||||
if (container.nodeType == 1) {
|
||||
container = container.childNodes[offset] || container;
|
||||
}
|
||||
|
||||
// Check if previous or next tree node is non editable then block the event
|
||||
if (isNextPrevTreeNodeNonEditable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
startElement = selection.getStart()
|
||||
endElement = selection.getEnd();
|
||||
|
||||
// Disable all key presses in contentEditable=false except delete or backspace
|
||||
nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement);
|
||||
if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) {
|
||||
// Is Ctrl+c, Ctrl+v or Ctrl+x then use default browser behavior
|
||||
if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
// Arrow left/right select the element and collapse left/right
|
||||
|
@ -298,6 +382,7 @@
|
|||
positionCaretOnElement(nonEditableParent, true);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
|
@ -315,23 +400,31 @@
|
|||
positionCaretOnElement(nonEditableParent, false);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ed.onMouseDown.addToTop(function(ed, e){
|
||||
// prevent collapsing selection to caret when clicking in a non-editable section
|
||||
ed.onMouseDown.addToTop(function(ed, e) {
|
||||
var node = ed.selection.getNode();
|
||||
|
||||
if (getContentEditable(node) === "false" && node == e.target) {
|
||||
e.preventDefault();
|
||||
// Expand selection on mouse down we can't block the default event since it's used for drag/drop
|
||||
moveSelection();
|
||||
}
|
||||
});
|
||||
|
||||
ed.onMouseUp.addToTop(moveSelection);
|
||||
ed.onKeyDown.addToTop(handleKey);
|
||||
ed.onKeyUp.addToTop(moveSelection);
|
||||
|
@ -341,6 +434,31 @@
|
|||
init : function(ed, url) {
|
||||
var editClass, nonEditClass, nonEditableRegExps;
|
||||
|
||||
// Converts configured regexps to noneditable span items
|
||||
function convertRegExpsToNonEditable(ed, args) {
|
||||
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
// Don't replace the variables when raw is used for example on undo/redo
|
||||
if (args.format == "raw") {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
content = content.replace(nonEditableRegExps[i], function(match) {
|
||||
var args = arguments, index = args[args.length - 2];
|
||||
|
||||
// Is value inside an attribute then don't replace
|
||||
if (index > 0 && content.charAt(index - 1) == '"') {
|
||||
return match;
|
||||
}
|
||||
|
||||
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
|
||||
});
|
||||
}
|
||||
|
||||
args.content = content;
|
||||
};
|
||||
|
||||
editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " ";
|
||||
nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
|
||||
|
||||
|
@ -354,24 +472,8 @@
|
|||
handleContentEditableSelection(ed);
|
||||
|
||||
if (nonEditableRegExps) {
|
||||
ed.onBeforeSetContent.add(function(ed, args) {
|
||||
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
// Don't replace the variables when raw is used for example on undo/redo
|
||||
if (args.format == "raw") {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
content = content.replace(nonEditableRegExps[i], function() {
|
||||
var args = arguments;
|
||||
|
||||
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
|
||||
});
|
||||
}
|
||||
|
||||
args.content = content;
|
||||
});
|
||||
ed.selection.onBeforeSetContent.add(convertRegExpsToNonEditable);
|
||||
ed.onBeforeSetContent.add(convertRegExpsToNonEditable);
|
||||
}
|
||||
|
||||
// Apply contentEditable true/false on elements with the noneditable/editable classes
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -359,7 +359,7 @@
|
|||
}
|
||||
|
||||
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
|
||||
if (tinymce.isIE && document.documentMode >= 9) {
|
||||
if (tinymce.isIE && document.documentMode >= 9 && /<(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)/.test(o.content)) {
|
||||
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
|
||||
process([[/(?:<br> [\s\r\n]+|<br>)*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:<br> [\s\r\n]+|<br>)*/g, '$1']]);
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})();
|
||||
(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]:not(iframe)");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})();
|
|
@ -22,7 +22,7 @@
|
|||
var x, i, f, el, v;
|
||||
|
||||
function find(d) {
|
||||
el = DOM.select(':input:enabled,*[tabindex]');
|
||||
el = DOM.select(':input:enabled,*[tabindex]:not(iframe)');
|
||||
|
||||
function canSelectRecursive(e) {
|
||||
return e.nodeName==="BODY" || (e.type != 'hidden' &&
|
||||
|
|
|
@ -137,7 +137,7 @@ function updateAction() {
|
|||
do {
|
||||
if (cell == tdElm)
|
||||
break;
|
||||
col += cell.getAttribute("colspan");
|
||||
col += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
|
||||
} while ((cell = nextCell(cell)) != null);
|
||||
|
||||
for (var i=0; i<rows.length; i++) {
|
||||
|
@ -152,7 +152,7 @@ function updateAction() {
|
|||
cell = updateCell(cell, true);
|
||||
break;
|
||||
}
|
||||
curr += cell.getAttribute("colspan");
|
||||
curr += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
|
||||
} while ((cell = nextCell(cell)) != null);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre {margin-left: 3px}
|
||||
section, article, address, hgroup, aside {margin: 1em 0 0 3px}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre, figure {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre, figure {margin-left: 3px}
|
||||
section, article, address, hgroup, aside, figure {margin: 0 0 1em 3px}
|
||||
|
||||
p {background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7)}
|
||||
h1 {background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==)}
|
||||
|
@ -17,3 +17,5 @@ address {background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH
|
|||
pre {background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==)}
|
||||
hgroup {background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7)}
|
||||
aside {background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=)}
|
||||
figure {background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7)}
|
||||
figcaption {border: 1px dashed #BBB}
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks")}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})();
|
||||
(function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks",false,null,{skip_focus:true})}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})();
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
ed.onInit.add(function() {
|
||||
if (ed.settings.visualblocks_default_state) {
|
||||
ed.execCommand('mceVisualBlocks');
|
||||
ed.execCommand('mceVisualBlocks', false, null, {skip_focus : true});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -62,12 +62,8 @@
|
|||
|
||||
<div class="mceActionPanel">
|
||||
<input type="submit" id="insert" name="insert" value="{#apply}" />
|
||||
|
||||
<div id="preview"></div>
|
||||
|
||||
<div id="previewblock">
|
||||
<label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" />
|
||||
</div>
|
||||
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();"/>
|
||||
<div id="preview_wrapper"><div id="previewblock"><label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" /></div><span id="preview"></span></div>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -69,6 +69,16 @@
|
|||
each(previewStyles.split(' '), function(name) {
|
||||
var value = dom.getStyle(previewElm, name, true);
|
||||
|
||||
// If background is transparent then check if the body has a background color we can use
|
||||
if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
|
||||
value = dom.getStyle(ed.getBody(), name, true);
|
||||
|
||||
// Ignore white since it's the default color, not the nicest fix
|
||||
if (dom.toHex(value).toLowerCase() == '#ffffff') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Old IE won't calculate the font size so we need to do that manually
|
||||
if (name == 'font-size') {
|
||||
if (/em|%$/.test(value)) {
|
||||
|
@ -608,7 +618,7 @@
|
|||
|
||||
// TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for.
|
||||
// Maybe actually inherit it from the original textara?
|
||||
n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')});
|
||||
n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '') + (ed.settings.directionality == "rtl" ? ' mceRtl' : '')});
|
||||
DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label);
|
||||
|
||||
if (!DOM.boxModel)
|
||||
|
@ -925,7 +935,7 @@
|
|||
},
|
||||
|
||||
_addToolbars : function(c, o) {
|
||||
var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup;
|
||||
var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup, toolbarsExist = false;
|
||||
|
||||
toolbarGroup = cf.createToolbarGroup('toolbargroup', {
|
||||
'name': ed.getLang('advanced.toolbar'),
|
||||
|
@ -941,6 +951,7 @@
|
|||
|
||||
// Create toolbar and add the controls
|
||||
for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
|
||||
toolbarsExist = true;
|
||||
tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
|
||||
|
||||
if (s['theme_advanced_buttons' + i + '_add'])
|
||||
|
@ -954,6 +965,9 @@
|
|||
|
||||
o.deltaHeight -= s.theme_advanced_row_height;
|
||||
}
|
||||
// Handle case when there are no toolbar buttons and ensure editor height is adjusted accordingly
|
||||
if (!toolbarsExist)
|
||||
o.deltaHeight -= s.theme_advanced_row_height;
|
||||
h.push(toolbarGroup.renderHTML());
|
||||
h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
|
||||
DOM.setHTML(n, h.join(''));
|
||||
|
@ -1112,7 +1126,7 @@
|
|||
}
|
||||
|
||||
if (c = cm.get('formatselect')) {
|
||||
p = getParent(DOM.isBlock);
|
||||
p = getParent(ed.dom.isBlock);
|
||||
|
||||
if (p)
|
||||
c.select(p.nodeName.toLowerCase());
|
||||
|
@ -1210,7 +1224,7 @@
|
|||
return;
|
||||
|
||||
// Handle prefix
|
||||
if (tinymce.isIE && n.scopeName !== 'HTML')
|
||||
if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName)
|
||||
na = n.scopeName + ':' + na;
|
||||
|
||||
// Remove internal prefix
|
||||
|
@ -1271,7 +1285,7 @@
|
|||
if (v) {
|
||||
ti += 'class: ' + v + ' ';
|
||||
|
||||
if (DOM.isBlock(n) || na == 'img' || na == 'span')
|
||||
if (ed.dom.isBlock(n) || na == 'img' || na == 'span')
|
||||
na += '.' + v;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,10 +104,12 @@ var ImageDialog = {
|
|||
},
|
||||
|
||||
updateStyle : function() {
|
||||
var dom = tinyMCEPopup.dom, st, v, f = document.forms[0];
|
||||
var dom = tinyMCEPopup.dom, st = {}, v, f = document.forms[0];
|
||||
|
||||
if (tinyMCEPopup.editor.settings.inline_styles) {
|
||||
st = tinyMCEPopup.dom.parseStyle(this.styleVal);
|
||||
tinymce.each(tinyMCEPopup.dom.parseStyle(this.styleVal), function(value, key) {
|
||||
st[key] = value;
|
||||
});
|
||||
|
||||
// Handle align
|
||||
v = getSelectValue(f, 'align');
|
||||
|
|
|
@ -94,11 +94,12 @@ h3 {font-size:14px;}
|
|||
#plugintable, #about #plugintable td {border:1px solid #919B9C;}
|
||||
#plugintable {width:96%; margin-top:10px;}
|
||||
#pluginscontainer {height:290px; overflow:auto;}
|
||||
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;}
|
||||
#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
|
||||
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
|
||||
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
|
||||
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
|
||||
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
|
||||
#colorpicker #light div {overflow:hidden;}
|
||||
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
|
||||
#colorpicker .panel_wrapper div.current {height:175px;}
|
||||
#colorpicker #namedcolors {width:150px;}
|
||||
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
/* Menu */
|
||||
.highcontrastSkin .mceNoIcons span.mceIcon {width:0;}
|
||||
.highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; }
|
||||
.highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; direction:ltr}
|
||||
.highcontrastSkin .mceMenu table {background:white; color: black}
|
||||
.highcontrastSkin .mceNoIcons a .mceText {padding-left:10px}
|
||||
.highcontrastSkin .mceMenu a, .highcontrastSkin .mceMenu span, .highcontrastSkin .mceMenu {display:block;background:white; color: black}
|
||||
|
@ -90,6 +90,10 @@
|
|||
.highcontrastSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
|
||||
.highcontrastSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
|
||||
|
||||
/* Rtl */
|
||||
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
|
||||
.mceRtl .mceMenuItem .mceText {text-align: right}
|
||||
|
||||
/* Formats */
|
||||
.highcontrastSkin .mce_p span.mceText {}
|
||||
.highcontrastSkin .mce_address span.mceText {font-style:italic}
|
||||
|
|
|
@ -105,11 +105,12 @@ h3 {font-size:14px;}
|
|||
#plugintable, #about #plugintable td {border:1px solid #919B9C;}
|
||||
#plugintable {width:96%; margin-top:10px;}
|
||||
#pluginscontainer {height:290px; overflow:auto;}
|
||||
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;}
|
||||
#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
|
||||
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
|
||||
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
|
||||
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
|
||||
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
|
||||
#colorpicker #light div {overflow:hidden;}
|
||||
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
|
||||
#colorpicker .panel_wrapper div.current {height:175px;}
|
||||
#colorpicker #namedcolors {width:150px;}
|
||||
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
.o2k7Skin .mce_forecolor span.mceAction, .o2k7Skin .mce_backcolor span.mceAction {height:15px;overflow:hidden}
|
||||
|
||||
/* Menu */
|
||||
.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD}
|
||||
.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD; direction:ltr}
|
||||
.o2k7Skin .mceNoIcons span.mceIcon {width:0;}
|
||||
.o2k7Skin .mceNoIcons a .mceText {padding-left:10px}
|
||||
.o2k7Skin .mceMenu table {background:#FFF}
|
||||
|
@ -112,6 +112,10 @@
|
|||
.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
|
||||
.o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
|
||||
|
||||
/* Rtl */
|
||||
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
|
||||
.mceRtl .mceMenuItem .mceText {text-align: right}
|
||||
|
||||
/* Formats */
|
||||
.o2k7Skin .mce_formatPreview a {font-size:10px}
|
||||
.o2k7Skin .mce_p span.mceText {}
|
||||
|
|
File diff suppressed because one or more lines are too long
4253
library/tinymce/jscripts/tiny_mce/tiny_mce_src.js
vendored
4253
library/tinymce/jscripts/tiny_mce/tiny_mce_src.js
vendored
File diff suppressed because it is too large
Load diff
16
mod/acctlink.php
Normal file
16
mod/acctlink.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
require_once('include/Scrape.php');
|
||||
|
||||
function acctlink_init(&$a) {
|
||||
|
||||
if(x($_GET,'addr')) {
|
||||
$addr = trim($_GET['addr']);
|
||||
$res = probe_url($addr);
|
||||
//logger('acctlink: ' . print_r($res,true));
|
||||
if($res['url']) {
|
||||
goaway($res['url']);
|
||||
killme();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -135,7 +135,7 @@ function acl_init(&$a){
|
|||
foreach($r as $g) {
|
||||
$x['photos'][] = $g['micro'];
|
||||
$x['links'][] = $g['url'];
|
||||
$x['suggestions'][] = $g['name']; // sprintf( t('%s [%s]'),$g['name'],$g['url']);
|
||||
$x['suggestions'][] = $g['name'];
|
||||
$x['data'][] = intval($g['id']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,7 +98,7 @@ function admin_content(&$a) {
|
|||
'plugins'=> Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
|
||||
'themes' => Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
|
||||
'dbsync' => Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
|
||||
'update' => Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
|
||||
//'update' => Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
|
||||
);
|
||||
|
||||
/* get plugins admin page */
|
||||
|
@ -115,7 +115,7 @@ function admin_content(&$a) {
|
|||
$aside['logs'] = Array($a->get_baseurl(true)."/admin/logs/", t("Logs"), "logs");
|
||||
|
||||
$t = get_markup_template("admin_aside.tpl");
|
||||
$a->page['aside'] = replace_macros( $t, array(
|
||||
$a->page['aside'] .= replace_macros( $t, array(
|
||||
'$admin' => $aside,
|
||||
'$h_pending' => t('User registrations waiting for confirmation'),
|
||||
'$admurl'=> $a->get_baseurl(true)."/admin/"
|
||||
|
@ -182,6 +182,7 @@ function admin_page_summary(&$a) {
|
|||
Array( t('Community/Celebrity Account'), 0),
|
||||
Array( t('Automatic Friend Account'), 0)
|
||||
);
|
||||
|
||||
$users=0;
|
||||
foreach ($r as $u){ $accounts[$u['page-flags']][1] = $u['count']; $users+= $u['count']; }
|
||||
|
||||
|
@ -190,10 +191,22 @@ function admin_page_summary(&$a) {
|
|||
$r = q("SELECT COUNT(id) as `count` FROM `register`");
|
||||
$pending = $r[0]['count'];
|
||||
|
||||
$r = q("select count(*) as total from deliverq where 1");
|
||||
$deliverq = (($r) ? $r[0]['total'] : 0);
|
||||
|
||||
$r = q("select count(*) as total from queue where 1");
|
||||
$queue = (($r) ? $r[0]['total'] : 0);
|
||||
|
||||
// We can do better, but this is a quick queue status
|
||||
|
||||
$queues = array( 'label' => t('Message queues'), 'deliverq' => $deliverq, 'queue' => $queue );
|
||||
|
||||
|
||||
$t = get_markup_template("admin_summary.tpl");
|
||||
return replace_macros($t, array(
|
||||
'$title' => t('Administration'),
|
||||
'$page' => t('Summary'),
|
||||
'$queues' => $queues,
|
||||
'$users' => Array( t('Registered users'), $users),
|
||||
'$accounts' => $accounts,
|
||||
'$pending' => Array( t('Pending registrations'), $pending),
|
||||
|
@ -417,7 +430,7 @@ function admin_page_site(&$a) {
|
|||
'$maximagesize' => array('maximagesize', t("Maximum image size"), get_config('system','maximagesize'), t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")),
|
||||
|
||||
'$register_policy' => array('register_policy', t("Register policy"), $a->config['register_policy'], "", $register_choices),
|
||||
'$register_text' => array('register_text', t("Register text"), htmlentities($a->config['register_text'], ENT_QUOTES), t("Will be displayed prominently on the registration page.")),
|
||||
'$register_text' => array('register_text', t("Register text"), htmlentities($a->config['register_text'], ENT_QUOTES, 'UTF-8'), t("Will be displayed prominently on the registration page.")),
|
||||
'$abandon_days' => array('abandon_days', t('Accounts abandoned after x days'), get_config('system','account_abandon_days'), t('Will not waste system resources polling external sites for abandonded accounts. Enter 0 for no time limit.')),
|
||||
'$allowed_sites' => array('allowed_sites', t("Allowed friend domains"), get_config('system','allowed_sites'), t("Comma separated list of domains which are allowed to establish friendships with this site. Wildcards are accepted. Empty to allow any domains")),
|
||||
'$allowed_email' => array('allowed_email', t("Allowed email domains"), get_config('system','allowed_email'), t("Comma separated list of domains which are allowed in email addresses for registrations to this site. Wildcards are accepted. Empty to allow any domains")),
|
||||
|
|
|
@ -63,7 +63,7 @@ function community_content(&$a, $update = 0) {
|
|||
}
|
||||
|
||||
$r = q("SELECT distinct(`item`.`uri`), `item`.*, `item`.`id` AS `item_id`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`,
|
||||
`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
|
||||
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`,
|
||||
`user`.`nickname`, `user`.`hidewall`
|
||||
|
|
|
@ -144,19 +144,12 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
|
|||
* worried about key leakage than anybody cracking it.
|
||||
*
|
||||
*/
|
||||
require_once('include/crypto.php');
|
||||
|
||||
$res = openssl_pkey_new(array(
|
||||
'digest_alg' => 'sha1',
|
||||
'private_key_bits' => 4096,
|
||||
'encrypt_key' => false )
|
||||
);
|
||||
$res = new_keypair(1024);
|
||||
|
||||
$private_key = '';
|
||||
|
||||
openssl_pkey_export($res, $private_key);
|
||||
|
||||
$pubkey = openssl_pkey_get_details($res);
|
||||
$public_key = $pubkey["key"];
|
||||
$private_key = $res['prvkey'];
|
||||
$public_key = $res['pubkey'];
|
||||
|
||||
// Save the private key. Send them the public key.
|
||||
|
||||
|
@ -209,6 +202,8 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
|
|||
|
||||
if($user[0]['page-flags'] == PAGE_COMMUNITY)
|
||||
$params['page'] = 1;
|
||||
if($user[0]['page-flags'] == PAGE_PRVGROUP)
|
||||
$params['page'] = 2;
|
||||
|
||||
logger('dfrn_confirm: Confirm: posting data to ' . $dfrn_confirm . ': ' . print_r($params,true), LOGGER_DATA);
|
||||
|
||||
|
@ -500,6 +495,16 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$g = q("select def_gid from user where uid = %d limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
if($contact && $g && intval($g[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member($uid,'',$contact['id'],$g[0]['def_gid']);
|
||||
}
|
||||
|
||||
// Let's send our user to the contact editor in case they want to
|
||||
// do anything special with this new friend.
|
||||
|
||||
|
@ -534,6 +539,9 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
|
|||
$page = ((x($_POST,'page')) ? intval($_POST['page']) : 0 );
|
||||
$version_id = ((x($_POST,'dfrn_version')) ? (float) $_POST['dfrn_version'] : 2.0);
|
||||
|
||||
$forum = (($page == 1) ? 1 : 0);
|
||||
$prv = (($page == 2) ? 1 : 0);
|
||||
|
||||
logger('dfrn_confirm: requestee contacted: ' . $node);
|
||||
|
||||
logger('dfrn_confirm: request: POST=' . print_r($_POST,true), LOGGER_DATA);
|
||||
|
@ -688,6 +696,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
|
|||
`pending` = 0,
|
||||
`duplex` = %d,
|
||||
`forum` = %d,
|
||||
`prv` = %d,
|
||||
`network` = '%s' WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
|
@ -698,7 +707,8 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
|
|||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($duplex),
|
||||
intval($page),
|
||||
intval($forum),
|
||||
intval($prv),
|
||||
dbesc(NETWORK_DFRN),
|
||||
intval($dfrn_record)
|
||||
);
|
||||
|
|
|
@ -17,6 +17,9 @@ function dfrn_notify_post(&$a) {
|
|||
$ssl_policy = ((x($_POST,'ssl_policy')) ? notags(trim($_POST['ssl_policy'])): 'none');
|
||||
$page = ((x($_POST,'page')) ? intval($_POST['page']) : 0);
|
||||
|
||||
$forum = (($page == 1) ? 1 : 0);
|
||||
$prv = (($page == 2) ? 1 : 0);
|
||||
|
||||
$writable = (-1);
|
||||
if($dfrn_version >= 2.21) {
|
||||
$writable = (($perm === 'rw') ? 1 : 0);
|
||||
|
@ -88,10 +91,11 @@ function dfrn_notify_post(&$a) {
|
|||
|
||||
$importer = $r[0];
|
||||
|
||||
if((($writable != (-1)) && ($writable != $importer['writable'])) || ($importer['forum'] != $page)) {
|
||||
q("UPDATE `contact` SET `writable` = %d, forum = %d WHERE `id` = %d LIMIT 1",
|
||||
if((($writable != (-1)) && ($writable != $importer['writable'])) || ($importer['forum'] != $forum) || ($importer['prv'] != $prv)) {
|
||||
q("UPDATE `contact` SET `writable` = %d, forum = %d, prv = %d WHERE `id` = %d LIMIT 1",
|
||||
intval(($writable == (-1)) ? $importer['writable'] : $writable),
|
||||
intval($page),
|
||||
intval($forum),
|
||||
intval($prv),
|
||||
intval($importer['id'])
|
||||
);
|
||||
if($writable != (-1))
|
||||
|
|
|
@ -68,7 +68,7 @@ function dfrn_request_post(&$a) {
|
|||
$dfrn_url = notags(trim($_POST['dfrn_url']));
|
||||
$aes_allow = (((x($_POST,'aes_allow')) && ($_POST['aes_allow'] == 1)) ? 1 : 0);
|
||||
$confirm_key = ((x($_POST,'confirm_key')) ? $_POST['confirm_key'] : "");
|
||||
|
||||
$hidden = ((x($_POST,'hidden-contact')) ? intval($_POST['hidden-contact']) : 0);
|
||||
$contact_record = null;
|
||||
|
||||
if(x($dfrn_url)) {
|
||||
|
@ -98,8 +98,9 @@ function dfrn_request_post(&$a) {
|
|||
}
|
||||
|
||||
if(is_array($contact_record)) {
|
||||
$r = q("UPDATE `contact` SET `ret-aes` = %d WHERE `id` = %d LIMIT 1",
|
||||
$r = q("UPDATE `contact` SET `ret-aes` = %d, hidden = %d WHERE `id` = %d LIMIT 1",
|
||||
intval($aes_allow),
|
||||
intval($hidden),
|
||||
intval($contact_record['id'])
|
||||
);
|
||||
}
|
||||
|
@ -144,8 +145,8 @@ function dfrn_request_post(&$a) {
|
|||
*/
|
||||
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`,`url`, `nurl`, `name`, `nick`, `photo`, `site-pubkey`,
|
||||
`request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`)
|
||||
VALUES ( %d, '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d)",
|
||||
`request`, `confirm`, `notify`, `poll`, `poco`, `network`, `aes_allow`, `hidden`)
|
||||
VALUES ( %d, '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
|
||||
intval(local_user()),
|
||||
datetime_convert(),
|
||||
dbesc($dfrn_url),
|
||||
|
@ -160,7 +161,8 @@ function dfrn_request_post(&$a) {
|
|||
$parms['dfrn-poll'],
|
||||
$parms['dfrn-poco'],
|
||||
dbesc(NETWORK_DFRN),
|
||||
intval($aes_allow)
|
||||
intval($aes_allow),
|
||||
intval($hidden)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -370,6 +372,14 @@ function dfrn_request_post(&$a) {
|
|||
if(count($r)) {
|
||||
$contact_id = $r[0]['id'];
|
||||
|
||||
$g = q("select def_gid from user where uid = %d limit 1",
|
||||
intval($uid)
|
||||
);
|
||||
if($g && intval($g[0]['def_gid'])) {
|
||||
require_once('include/group.php');
|
||||
group_add_member($uid,'',$contact_id,$g[0]['def_gid']);
|
||||
}
|
||||
|
||||
$photo = avatar_img($addr);
|
||||
|
||||
$r = q("UPDATE `contact` SET
|
||||
|
@ -641,6 +651,8 @@ function dfrn_request_content(&$a) {
|
|||
$o = replace_macros($tpl,array(
|
||||
'$dfrn_url' => $dfrn_url,
|
||||
'$aes_allow' => (($aes_allow) ? '<input type="hidden" name="aes_allow" value="1" />' : "" ),
|
||||
'$hidethem' => t('Hide this contact'),
|
||||
'$hidechecked' => '',
|
||||
'$confirm_key' => $confirm_key,
|
||||
'$welcome' => sprintf( t('Welcome home %s.'), $a->user['username']),
|
||||
'$please' => sprintf( t('Please confirm your introduction/connection request to %s.'), $dfrn_url),
|
||||
|
@ -672,7 +684,7 @@ function dfrn_request_content(&$a) {
|
|||
$auto_confirm = false;
|
||||
|
||||
if(count($r)) {
|
||||
if($r[0]['page-flags'] != PAGE_NORMAL)
|
||||
if(($r[0]['page-flags'] != PAGE_NORMAL) && ($r[0]['page-flags'] != PAGE_PRVGROUP))
|
||||
$auto_confirm = true;
|
||||
|
||||
if(! $auto_confirm) {
|
||||
|
|
|
@ -18,6 +18,9 @@ function dirfind_content(&$a) {
|
|||
|
||||
$search = notags(trim($_REQUEST['search']));
|
||||
|
||||
if(strpos($search,'@') === 0)
|
||||
$search = substr($search,1);
|
||||
|
||||
$o = '';
|
||||
|
||||
$o .= '<h2>' . t('People Search') . ' - ' . $search . '</h2>';
|
||||
|
|
214
mod/follow.php
214
mod/follow.php
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
|
||||
require_once('Scrape.php');
|
||||
require_once('include/follow.php');
|
||||
|
||||
function follow_init(&$a) {
|
||||
|
||||
|
@ -11,220 +12,19 @@ function follow_init(&$a) {
|
|||
}
|
||||
|
||||
$uid = local_user();
|
||||
$url = $orig_url = notags(trim($_REQUEST['url']));
|
||||
$url = notags(trim($_REQUEST['url']));
|
||||
$return_url = $_SESSION['return_url'];
|
||||
|
||||
|
||||
// remove ajax junk, e.g. Twitter
|
||||
$result = new_contact($uid,$url,true);
|
||||
|
||||
$url = str_replace('/#!/','/',$url);
|
||||
|
||||
if(! allowed_url($url)) {
|
||||
notice( t('Disallowed profile URL.') . EOL);
|
||||
goaway($return_url);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
|
||||
if(! $url) {
|
||||
notice( t('Connect URL missing.') . EOL);
|
||||
goaway($return_url);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
$arr = array('url' => $url, 'contact' => array());
|
||||
|
||||
call_hooks('follow', $arr);
|
||||
|
||||
if(x($arr['contact'],'name'))
|
||||
$ret = $arr['contact'];
|
||||
else
|
||||
$ret = probe_url($url);
|
||||
|
||||
if($ret['network'] === NETWORK_DFRN) {
|
||||
if(strlen($a->path))
|
||||
$myaddr = bin2hex($a->get_baseurl() . '/profile/' . $a->user['nickname']);
|
||||
else
|
||||
$myaddr = bin2hex($a->user['nickname'] . '@' . $a->get_hostname());
|
||||
|
||||
goaway($ret['request'] . "&addr=$myaddr");
|
||||
|
||||
// NOTREACHED
|
||||
}
|
||||
else {
|
||||
if(get_config('system','dfrn_only')) {
|
||||
notice( t('This site is not configured to allow communications with other networks.') . EOL);
|
||||
notice( t('No compatible communication protocols or feeds were discovered.') . EOL);
|
||||
goaway($return_url);
|
||||
}
|
||||
}
|
||||
|
||||
// This extra param just confuses things, remove it
|
||||
if($ret['network'] === NETWORK_DIASPORA)
|
||||
$ret['url'] = str_replace('?absolute=true','',$ret['url']);
|
||||
|
||||
|
||||
// do we have enough information?
|
||||
|
||||
if(! ((x($ret,'name')) && (x($ret,'poll')) && ((x($ret,'url')) || (x($ret,'addr'))))) {
|
||||
notice( t('The profile address specified does not provide adequate information.') . EOL);
|
||||
if(! x($ret,'poll'))
|
||||
notice( t('No compatible communication protocols or feeds were discovered.') . EOL);
|
||||
if(! x($ret,'name'))
|
||||
notice( t('An author or name was not found.') . EOL);
|
||||
if(! x($ret,'url'))
|
||||
notice( t('No browser URL could be matched to this address.') . EOL);
|
||||
if(strpos($url,'@') !== false) {
|
||||
notice( t('Unable to match @-style Identity Address with a known protocol or email contact.') . EOL);
|
||||
notice( t('Use mailto: in front of address to force email check.') . EOL);
|
||||
}
|
||||
if($result['success'] == false) {
|
||||
if($result['message'])
|
||||
notice($result['message']);
|
||||
goaway($return_url);
|
||||
}
|
||||
|
||||
if($ret['network'] === NETWORK_OSTATUS && get_config('system','ostatus_disabled')) {
|
||||
notice( t('The profile address specified belongs to a network which has been disabled on this site.') . EOL);
|
||||
$ret['notify'] = '';
|
||||
}
|
||||
|
||||
if(! $ret['notify']) {
|
||||
notice( t('Limited profile. This person will be unable to receive direct/personal notifications from you.') . EOL);
|
||||
}
|
||||
|
||||
$writeable = ((($ret['network'] === NETWORK_OSTATUS) && ($ret['notify'])) ? 1 : 0);
|
||||
$hidden = (($ret['network'] === NETWORK_MAIL) ? 1 : 0);
|
||||
|
||||
if($ret['network'] === NETWORK_MAIL) {
|
||||
$writeable = 1;
|
||||
|
||||
}
|
||||
if($ret['network'] === NETWORK_DIASPORA)
|
||||
$writeable = 1;
|
||||
|
||||
// check if we already have a contact
|
||||
// the poll url is more reliable than the profile url, as we may have
|
||||
// indirect links or webfinger links
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `poll` = '%s' LIMIT 1",
|
||||
intval($uid),
|
||||
dbesc($ret['poll'])
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
// update contact
|
||||
if($r[0]['rel'] == CONTACT_IS_FOLLOWER || ($network === NETWORK_DIASPORA && $r[0]['rel'] == CONTACT_IS_SHARING)) {
|
||||
q("UPDATE `contact` SET `rel` = %d , `readonly` = 0 WHERE `id` = %d AND `uid` = %d LIMIT 1",
|
||||
intval(CONTACT_IS_FRIEND),
|
||||
intval($r[0]['id']),
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
$new_relation = (($ret['network'] === NETWORK_MAIL) ? CONTACT_IS_FRIEND : CONTACT_IS_SHARING);
|
||||
if($ret['network'] === NETWORK_DIASPORA)
|
||||
$new_relation = CONTACT_IS_FOLLOWER;
|
||||
|
||||
// create contact record
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `batch`, `notify`, `poll`, `poco`, `name`, `nick`, `photo`, `network`, `pubkey`, `rel`, `priority`,
|
||||
`writable`, `hidden`, `blocked`, `readonly`, `pending` )
|
||||
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, 0, 0, 0 ) ",
|
||||
intval($uid),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc($ret['url']),
|
||||
dbesc(normalise_link($ret['url'])),
|
||||
dbesc($ret['addr']),
|
||||
dbesc($ret['alias']),
|
||||
dbesc($ret['batch']),
|
||||
dbesc($ret['notify']),
|
||||
dbesc($ret['poll']),
|
||||
dbesc($ret['poco']),
|
||||
dbesc($ret['name']),
|
||||
dbesc($ret['nick']),
|
||||
dbesc($ret['photo']),
|
||||
dbesc($ret['network']),
|
||||
dbesc($ret['pubkey']),
|
||||
intval($new_relation),
|
||||
intval($ret['priority']),
|
||||
intval($writeable),
|
||||
intval($hidden)
|
||||
);
|
||||
}
|
||||
|
||||
$r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($ret['url']),
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(! count($r)) {
|
||||
notice( t('Unable to retrieve contact information.') . EOL);
|
||||
goaway($return_url);
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
$contact = $r[0];
|
||||
$contact_id = $r[0]['id'];
|
||||
|
||||
require_once("Photo.php");
|
||||
|
||||
$photos = import_profile_photo($ret['photo'],$uid,$contact_id);
|
||||
|
||||
$r = q("UPDATE `contact` SET `photo` = '%s',
|
||||
`thumb` = '%s',
|
||||
`micro` = '%s',
|
||||
`name-date` = '%s',
|
||||
`uri-date` = '%s',
|
||||
`avatar-date` = '%s'
|
||||
WHERE `id` = %d LIMIT 1
|
||||
",
|
||||
dbesc($photos[0]),
|
||||
dbesc($photos[1]),
|
||||
dbesc($photos[2]),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
intval($contact_id)
|
||||
);
|
||||
|
||||
|
||||
// pull feed and consume it, which should subscribe to the hub.
|
||||
|
||||
proc_run('php',"include/poller.php","$contact_id");
|
||||
|
||||
// create a follow slap
|
||||
|
||||
$tpl = get_markup_template('follow_slap.tpl');
|
||||
$slap = replace_macros($tpl, array(
|
||||
'$name' => $a->user['username'],
|
||||
'$profile_page' => $a->get_baseurl() . '/profile/' . $a->user['nickname'],
|
||||
'$photo' => $a->contact['photo'],
|
||||
'$thumb' => $a->contact['thumb'],
|
||||
'$published' => datetime_convert('UTC','UTC', 'now', ATOM_TIME),
|
||||
'$item_id' => 'urn:X-dfrn:' . $a->get_hostname() . ':follow:' . random_string(),
|
||||
'$title' => '',
|
||||
'$type' => 'text',
|
||||
'$content' => t('following'),
|
||||
'$nick' => $a->user['nickname'],
|
||||
'$verb' => ACTIVITY_FOLLOW,
|
||||
'$ostat_follow' => ''
|
||||
));
|
||||
|
||||
$r = q("SELECT `contact`.*, `user`.* FROM `contact` LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
|
||||
WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
|
||||
intval($uid)
|
||||
);
|
||||
|
||||
if(count($r)) {
|
||||
if(($contact['network'] == NETWORK_OSTATUS) && (strlen($contact['notify']))) {
|
||||
require_once('include/salmon.php');
|
||||
slapper($r[0],$contact['notify'],$slap);
|
||||
}
|
||||
if($contact['network'] == NETWORK_DIASPORA) {
|
||||
require_once('include/diaspora.php');
|
||||
$ret = diaspora_share($a->user,$contact);
|
||||
logger('mod_follow: diaspora_share returns: ' . $ret);
|
||||
}
|
||||
}
|
||||
info( t('Contact added') . EOL);
|
||||
|
||||
if(strstr($return_url,'contacts'))
|
||||
goaway($a->get_baseurl() . '/contacts/' . $contact_id);
|
||||
|
|
|
@ -8,26 +8,10 @@ function hostxrd_init(&$a) {
|
|||
$pubkey = get_config('system','site_pubkey');
|
||||
|
||||
if(! $pubkey) {
|
||||
$res = new_keypair(1024);
|
||||
|
||||
// should only have to ever do this once.
|
||||
|
||||
$res=openssl_pkey_new(array(
|
||||
'digest_alg' => 'sha1',
|
||||
'private_key_bits' => 4096,
|
||||
'encrypt_key' => false ));
|
||||
|
||||
|
||||
$prvkey = '';
|
||||
|
||||
openssl_pkey_export($res, $prvkey);
|
||||
|
||||
// Get public key
|
||||
|
||||
$pkey = openssl_pkey_get_details($res);
|
||||
$pubkey = $pkey["key"];
|
||||
|
||||
set_config('system','site_prvkey', $prvkey);
|
||||
set_config('system','site_pubkey', $pubkey);
|
||||
set_config('system','site_prvkey', $res['prvkey']);
|
||||
set_config('system','site_pubkey', $res['pubkey']);
|
||||
}
|
||||
|
||||
$tpl = file_get_contents('view/xrd_host.tpl');
|
||||
|
|
96
mod/install.php
Normal file → Executable file
96
mod/install.php
Normal file → Executable file
|
@ -4,6 +4,12 @@ $install_wizard_pass=1;
|
|||
|
||||
|
||||
function install_init(&$a){
|
||||
|
||||
// $baseurl/install/testrwrite to test if rewite in .htaccess is working
|
||||
if ($a->argc==2 && $a->argv[1]=="testrewrite") {
|
||||
echo "ok";
|
||||
killme();
|
||||
}
|
||||
global $install_wizard_pass;
|
||||
if (x($_POST,'pass'))
|
||||
$install_wizard_pass = intval($_POST['pass']);
|
||||
|
@ -110,14 +116,7 @@ function install_content(&$a) {
|
|||
$wizard_status = "";
|
||||
$install_title = t('Friendica Social Communications Server - Setup');
|
||||
|
||||
if(x($a->data,'txt') && strlen($a->data['txt'])) {
|
||||
$tpl = get_markup_template('install.tpl');
|
||||
return replace_macros($tpl, array(
|
||||
'$title' => $install_title,
|
||||
'$pass' => t('Database connection'),
|
||||
'$text' => manual_config($a),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
if(x($a->data,'db_conn_failed')) {
|
||||
$install_wizard_pass = 2;
|
||||
|
@ -128,37 +127,18 @@ function install_content(&$a) {
|
|||
$wizard_status = t('Could not create table.');
|
||||
}
|
||||
|
||||
$db_return_text="";
|
||||
if(x($a->data,'db_installed')) {
|
||||
$txt = '<p style="font-size: 130%;">';
|
||||
$txt .= t('Your Friendica site database has been installed.') . EOL;
|
||||
$txt .= t('IMPORTANT: You will need to [manually] setup a scheduled task for the poller.') . EOL ;
|
||||
$txt .= t('Please see the file "INSTALL.txt".') . EOL ;
|
||||
$txt .= '<br />';
|
||||
$txt .= '<a href="' . $a->get_baseurl() . '/register' . '">' . t('Proceed to registration') . '</a>' ;
|
||||
$txt .= '</p>';
|
||||
|
||||
$tpl = get_markup_template('install.tpl');
|
||||
return replace_macros($tpl, array(
|
||||
'$title' => $install_title,
|
||||
'$pass' => t('Proceed with Installation'),
|
||||
'$text' => $txt,
|
||||
));
|
||||
|
||||
$db_return_text .= $txt;
|
||||
}
|
||||
|
||||
if(x($a->data,'db_failed')) {
|
||||
$txt = t('You may need to import the file "database.sql" manually using phpmyadmin or mysql.') . EOL;
|
||||
$txt .= t('Please see the file "INSTALL.txt".') . EOL ."<hr>" ;
|
||||
$txt .= "<pre>".$a->data['db_failed'] . "</pre>". EOL ;
|
||||
|
||||
$tpl = get_markup_template('install.tpl');
|
||||
return replace_macros($tpl, array(
|
||||
'$title' => $install_title,
|
||||
'$pass' => t('Database connection'),
|
||||
'$status' => t('Database import failed.'),
|
||||
'$text' => $txt,
|
||||
));
|
||||
|
||||
$db_return_text .= $txt;
|
||||
}
|
||||
|
||||
if($db && $db->connected) {
|
||||
|
@ -174,6 +154,19 @@ function install_content(&$a) {
|
|||
}
|
||||
}
|
||||
|
||||
if(x($a->data,'txt') && strlen($a->data['txt'])) {
|
||||
$tpl = get_markup_template('install.tpl');
|
||||
$db_return_text .= manual_config($a);
|
||||
}
|
||||
|
||||
if ($db_return_text!="") {
|
||||
return replace_macros($tpl, array(
|
||||
'$title' => $install_title,
|
||||
'$pass' => "",
|
||||
'$text' => $db_return_text . what_next(),
|
||||
));
|
||||
}
|
||||
|
||||
switch ($install_wizard_pass){
|
||||
case 1: { // System check
|
||||
|
||||
|
@ -191,6 +184,7 @@ function install_content(&$a) {
|
|||
|
||||
check_php($phpath, $checks);
|
||||
|
||||
check_htaccess($checks);
|
||||
|
||||
function check_passed($v, $c){
|
||||
if ($c['required'])
|
||||
|
@ -200,6 +194,7 @@ function install_content(&$a) {
|
|||
$checkspassed = array_reduce($checks, "check_passed", true);
|
||||
|
||||
|
||||
|
||||
$tpl = get_markup_template('install_checks.tpl');
|
||||
$o .= replace_macros($tpl, array(
|
||||
'$title' => $install_title,
|
||||
|
@ -321,14 +316,16 @@ function check_php(&$phpath, &$checks) {
|
|||
$help = "";
|
||||
if(!$passed) {
|
||||
$help .= t('Could not find a command line version of PHP in the web server PATH.'). EOL;
|
||||
$help .= t("If you don't have a command line version of PHP installed on server, you will not be able to run background polling via cron. See <a href='http://friendica.com/node/27'>'Activating scheduled tasks'</a>") . EOL ;
|
||||
$help .= EOL . EOL ;
|
||||
$tpl = get_markup_template('field_input.tpl');
|
||||
$help .= replace_macros($tpl, array(
|
||||
'$field' => array('phpath', t('PHP executable path'), $phpath, t('Enter full path to php executable')),
|
||||
'$field' => array('phpath', t('PHP executable path'), $phpath, t('Enter full path to php executable. You can leave this blank to continue the installation.')),
|
||||
));
|
||||
$phpath="";
|
||||
}
|
||||
|
||||
check_add($checks, t('Command line PHP'), $passed, true, $help);
|
||||
check_add($checks, t('Command line PHP').($passed?" (<tt>$phpath</tt>)":""), $passed, false, $help);
|
||||
|
||||
if($passed) {
|
||||
$str = autoname(8);
|
||||
|
@ -385,6 +382,7 @@ function check_funcs(&$checks) {
|
|||
check_add($ck_funcs, t('Apache mod_rewrite module'), true, true, "");
|
||||
}
|
||||
}
|
||||
|
||||
if(! function_exists('curl_init')){
|
||||
$ck_funcs[0]['status']= false;
|
||||
$ck_funcs[0]['help']= t('Error: libCURL PHP module required but not installed.');
|
||||
|
@ -422,11 +420,28 @@ function check_htconfig(&$checks) {
|
|||
$status=false;
|
||||
$help = t('The web installer needs to be able to create a file called ".htconfig.php" in the top folder of your web server and it is unable to do so.') .EOL;
|
||||
$help .= t('This is most often a permission setting, as the web server may not be able to write files in your folder - even if you can.').EOL;
|
||||
$help .= t('Please check with your site documentation or support people to see if this situation can be corrected.').EOL;
|
||||
$help .= t('If not, you may be required to perform a manual installation. Please see the file "INSTALL.txt" for instructions.').EOL;
|
||||
$help .= t('At the end of this procedure, we will give you a text to save in a file named .htconfig.php in your Friendica top folder.').EOL;
|
||||
$help .= t('You can alternatively skip this procedure and perform a manual installation. Please see the file "INSTALL.txt" for instructions.').EOL;
|
||||
}
|
||||
|
||||
check_add($checks, t('.htconfig.php is writable'), $status, true, $help);
|
||||
check_add($checks, t('.htconfig.php is writable'), $status, false, $help);
|
||||
|
||||
}
|
||||
|
||||
function check_htaccess(&$checks) {
|
||||
$a = get_app();
|
||||
$status = true;
|
||||
$help = "";
|
||||
if (function_exists('curl_init')){
|
||||
$test = fetch_url($a->get_baseurl()."/install/testrewrite");
|
||||
if ($test!="ok") {
|
||||
$status = false;
|
||||
$help = t('Url rewrite in .htaccess is not working. Check your server configuration.');
|
||||
}
|
||||
check_add($checks, t('Url rewrite is working'), $status, true, $help);
|
||||
} else {
|
||||
// cannot check modrewrite if libcurl is not installed
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -465,5 +480,16 @@ function load_database($db) {
|
|||
return $errors;
|
||||
}
|
||||
|
||||
function what_next() {
|
||||
$a = get_app();
|
||||
$baseurl = $a->get_baseurl();
|
||||
return
|
||||
t('<h1>What next</h1>')
|
||||
."<p>".t('IMPORTANT: You will need to [manually] setup a scheduled task for the poller.')
|
||||
.t('Please see the file "INSTALL.txt".')
|
||||
."</p><p>"
|
||||
.t("Go to your new Firendica node <a href='$baseurl/register'>registration page</a> and register as new user. Remember to use the same email you have entered as administrator email. This will allow you to enter the site admin panel.")
|
||||
."</p>";
|
||||
}
|
||||
|
||||
|
||||
|
|
50
mod/item.php
50
mod/item.php
|
@ -218,16 +218,25 @@ function item_post(&$a) {
|
|||
|
||||
$private = ((strlen($str_group_allow) || strlen($str_contact_allow) || strlen($str_group_deny) || strlen($str_contact_deny)) ? 1 : 0);
|
||||
|
||||
if(($parent_item) &&
|
||||
(($parent_item['private'])
|
||||
// If this is a comment, set the permissions from the parent.
|
||||
|
||||
if($parent_item) {
|
||||
$private = 0;
|
||||
|
||||
if(($parent_item['private'])
|
||||
|| strlen($parent_item['allow_cid'])
|
||||
|| strlen($parent_item['allow_gid'])
|
||||
|| strlen($parent_item['deny_cid'])
|
||||
|| strlen($parent_item['deny_gid'])
|
||||
)) {
|
||||
|| strlen($parent_item['deny_gid'])) {
|
||||
$private = 1;
|
||||
}
|
||||
|
||||
$str_contact_allow = $parent_item['allow_cid'];
|
||||
$str_group_allow = $parent_item['allow_gid'];
|
||||
$str_contact_deny = $parent_item['deny_cid'];
|
||||
$str_group_deny = $parent_item['deny_gid'];
|
||||
}
|
||||
|
||||
$pubmail_enable = ((x($_REQUEST,'pubmail_enable') && intval($_REQUEST['pubmail_enable']) && (! $private)) ? 1 : 0);
|
||||
|
||||
// if using the API, we won't see pubmail_enable - figure out if it should be set
|
||||
|
@ -281,19 +290,17 @@ function item_post(&$a) {
|
|||
$author = null;
|
||||
$self = false;
|
||||
|
||||
if(($_SESSION['uid']) && ($_SESSION['uid'] == $profile_uid)) {
|
||||
if((local_user()) && (local_user() == $profile_uid)) {
|
||||
$self = true;
|
||||
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1",
|
||||
intval($_SESSION['uid'])
|
||||
);
|
||||
}
|
||||
else {
|
||||
if((x($_SESSION,'visitor_id')) && (intval($_SESSION['visitor_id']))) {
|
||||
elseif(remote_user()) {
|
||||
$r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
|
||||
intval($_SESSION['visitor_id'])
|
||||
intval(remote_user())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if(count($r)) {
|
||||
$author = $r[0];
|
||||
|
@ -302,7 +309,7 @@ function item_post(&$a) {
|
|||
|
||||
// get contact info for owner
|
||||
|
||||
if($profile_uid == $_SESSION['uid']) {
|
||||
if($profile_uid == local_user()) {
|
||||
$contact_record = $author;
|
||||
}
|
||||
else {
|
||||
|
@ -313,8 +320,6 @@ function item_post(&$a) {
|
|||
$contact_record = $r[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
$post_type = notags(trim($_REQUEST['type']));
|
||||
|
||||
if($post_type === 'net-comment') {
|
||||
|
@ -350,13 +355,15 @@ function item_post(&$a) {
|
|||
$image_uri = substr($image_uri,0, strpos($image_uri,'-'));
|
||||
if(! strlen($image_uri))
|
||||
continue;
|
||||
$srch = '<' . intval($contact_record['id']) . '>';
|
||||
$srch = '<' . intval($contact_id) . '>';
|
||||
|
||||
$r = q("SELECT `id` FROM `photo` WHERE `allow_cid` = '%s' AND `allow_gid` = '' AND `deny_cid` = '' AND `deny_gid` = ''
|
||||
AND `resource-id` = '%s' AND `uid` = %d LIMIT 1",
|
||||
dbesc($srch),
|
||||
dbesc($image_uri),
|
||||
intval($profile_uid)
|
||||
);
|
||||
|
||||
if(! count($r))
|
||||
continue;
|
||||
|
||||
|
@ -446,6 +453,7 @@ function item_post(&$a) {
|
|||
|
||||
$tagged = array();
|
||||
|
||||
$private_forum = false;
|
||||
|
||||
if(count($tags)) {
|
||||
foreach($tags as $tag) {
|
||||
|
@ -464,10 +472,21 @@ function item_post(&$a) {
|
|||
continue;
|
||||
|
||||
$success = handle_tag($a, $body, $inform, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag);
|
||||
if($success)
|
||||
if($success['replaced'])
|
||||
$tagged[] = $tag;
|
||||
if(is_array($success['contact']) && intval($success['contact']['prv'])) {
|
||||
$private_forum = true;
|
||||
$private_id = $success['contact']['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(($private_forum) && (! $parent) && (! $private)) {
|
||||
// we tagged a private forum in a top level post and the message was public.
|
||||
// Restrict it.
|
||||
$private = 1;
|
||||
$str_contact_allow = '<' . $private_id . '>';
|
||||
}
|
||||
|
||||
$attachments = '';
|
||||
$match = false;
|
||||
|
@ -886,6 +905,7 @@ function item_content(&$a) {
|
|||
function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) {
|
||||
|
||||
$replaced = false;
|
||||
$r = null;
|
||||
|
||||
//is it a hash tag?
|
||||
if(strpos($tag,'#') === 0) {
|
||||
|
@ -1016,5 +1036,5 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) {
|
|||
}
|
||||
}
|
||||
|
||||
return $replaced;
|
||||
return array('replaced' => $replaced, 'contact' => $r[0]);
|
||||
}
|
||||
|
|
123
mod/like.php
Normal file → Executable file
123
mod/like.php
Normal file → Executable file
|
@ -104,7 +104,8 @@ function like_content(&$a) {
|
|||
return;
|
||||
}
|
||||
|
||||
$r = q("SELECT `id` FROM `item` WHERE `verb` = '%s' AND `deleted` = 0
|
||||
|
||||
$r = q("SELECT * FROM `item` WHERE `verb` = '%s' AND `deleted` = 0
|
||||
AND `contact-id` = %d AND ( `parent` = '%s' OR `parent-uri` = '%s') LIMIT 1",
|
||||
dbesc($activity),
|
||||
intval($contact['id']),
|
||||
|
@ -112,13 +113,70 @@ function like_content(&$a) {
|
|||
dbesc($item_id)
|
||||
);
|
||||
if(count($r)) {
|
||||
$like_item = $r[0];
|
||||
|
||||
// Already voted, undo it
|
||||
$r = q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1",
|
||||
dbesc(datetime_convert()),
|
||||
intval($r[0]['id'])
|
||||
intval($like_item['id'])
|
||||
);
|
||||
|
||||
proc_run('php',"include/notifier.php","like","$post_id");
|
||||
// Clean up the `sign` table
|
||||
$r = q("DELETE FROM `sign` WHERE `iid` = %d",
|
||||
intval($like_item['id'])
|
||||
);
|
||||
|
||||
// Save the author information for the unlike in case we need to relay to Diaspora
|
||||
// Note that we can only create a signature for a user of the local server. We don't have
|
||||
// a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it
|
||||
// means we are the relay, and for relayable_retractions, Diaspora
|
||||
// only checks the parent_author_signature if it doesn't have to relay further
|
||||
//
|
||||
// If $item['resource-id'] exists, it means the item is a photo. Diaspora doesn't support
|
||||
// likes on photos, so don't bother.
|
||||
|
||||
if(($activity === ACTIVITY_LIKE) && (! $item['resource-id'])) {
|
||||
$signed_text = $like_item['guid'] . ';' . 'Like';
|
||||
|
||||
if( $contact['network'] === NETWORK_DIASPORA)
|
||||
$diaspora_handle = $contact['addr'];
|
||||
else { // Only works for NETWORK_DFRN
|
||||
$contact_baseurl_start = strpos($contact['url'],'://') + 3;
|
||||
$contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start;
|
||||
$contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
|
||||
$diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
|
||||
|
||||
// Get contact's private key if he's a user of the local Friendica server
|
||||
$r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1",
|
||||
dbesc($contact['url'])
|
||||
);
|
||||
|
||||
if( $r) {
|
||||
$contact_uid = $r['uid'];
|
||||
$r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1",
|
||||
intval($contact_uid)
|
||||
);
|
||||
|
||||
if( $r)
|
||||
$authorsig = base64_encode(rsa_sign($signed_text,$r['prvkey'],'sha256'));
|
||||
}
|
||||
}
|
||||
|
||||
if(! isset($authorsig))
|
||||
$authorsig = '';
|
||||
|
||||
q("insert into sign (`retract_iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
|
||||
intval($like_item['id']),
|
||||
dbesc($signed_text),
|
||||
dbesc($authorsig),
|
||||
dbesc($diaspora_handle)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// proc_run('php',"include/notifier.php","like","$post_id"); // $post_id isn't defined here!
|
||||
$like_item_id = $like_item['id'];
|
||||
proc_run('php',"include/notifier.php","like","$like_item_id");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -191,6 +249,65 @@ EOT;
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
// Save the author information for the like in case we need to relay to Diaspora
|
||||
// Note that we can only create a signature for a user of the local server. We don't have
|
||||
// a key for remote users. That is ok, because if a remote user is "unlike"ing a post, it
|
||||
// means we are the relay, and for relayable_retractions, Diaspora
|
||||
// only checks the parent_author_signature if it doesn't have to relay further
|
||||
|
||||
if(($activity === ACTIVITY_LIKE) && ($post_type === t('status'))) {
|
||||
if( $contact['network'] === NETWORK_DIASPORA)
|
||||
$diaspora_handle = $contact['addr'];
|
||||
else { // Only works for NETWORK_DFRN
|
||||
$contact_baseurl_start = strpos($contact['url'],'://') + 3;
|
||||
$contact_baseurl_length = strpos($contact['url'],'/profile') - $contact_baseurl_start;
|
||||
$contact_baseurl = substr($contact['url'], $contact_baseurl_start, $contact_baseurl_length);
|
||||
$diaspora_handle = $contact['nick'] . '@' . $contact_baseurl;
|
||||
|
||||
// Get contact's private key if he's a user of the local Friendica server
|
||||
$r = q("SELECT `contact`.`uid` FROM `contact` WHERE `url` = '%s' AND `self` = 1 LIMIT 1",
|
||||
dbesc($contact['url'])
|
||||
);
|
||||
|
||||
if( $r) {
|
||||
$contact_uid = $r['uid'];
|
||||
$r = q("SELECT prvkey FROM user WHERE uid = %d LIMIT 1",
|
||||
intval($contact_uid)
|
||||
);
|
||||
|
||||
if( $r)
|
||||
$contact_uprvkey = $r['prvkey'];
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("SELECT guid, parent FROM `item` WHERE id = %d LIMIT 1",
|
||||
intval($post_id)
|
||||
);
|
||||
if( $r) {
|
||||
$p = q("SELECT guid FROM `item` WHERE id = %d AND parent = %d LIMIT 1",
|
||||
intval($r[0]['parent']),
|
||||
intval($r[0]['parent'])
|
||||
);
|
||||
if( $p) {
|
||||
$signed_text = $r[0]['guid'] . ';Post;' . $p[0]['guid'] . ';true;' . $diaspora_handle;
|
||||
|
||||
if(isset($contact_uprvkey))
|
||||
$authorsig = base64_encode(rsa_sign($signed_text,$contact_uprvkey,'sha256'));
|
||||
else
|
||||
$authorsig = '';
|
||||
|
||||
q("insert into sign (`iid`,`signed_text`,`signature`,`signer`) values (%d,'%s','%s','%s') ",
|
||||
intval($post_id),
|
||||
dbesc($signed_text),
|
||||
dbesc($authorsig),
|
||||
dbesc($diaspora_handle)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$arr['id'] = $post_id;
|
||||
|
||||
call_hooks('post_local_end', $arr);
|
||||
|
|
|
@ -211,7 +211,8 @@ function message_content(&$a) {
|
|||
'$parent' => '',
|
||||
'$upload' => t('Upload photo'),
|
||||
'$insert' => t('Insert web link'),
|
||||
'$wait' => t('Please wait')
|
||||
'$wait' => t('Please wait'),
|
||||
'$submit' => t('Submit')
|
||||
));
|
||||
|
||||
return $o;
|
||||
|
|
|
@ -108,6 +108,10 @@ function network_content(&$a, $update = 0) {
|
|||
return login(false);
|
||||
}
|
||||
|
||||
$arr = array('query' => $a->query_string);
|
||||
|
||||
call_hooks('network_content_init', $arr);
|
||||
|
||||
$o = '';
|
||||
|
||||
// item filter tabs
|
||||
|
@ -398,11 +402,23 @@ function network_content(&$a, $update = 0) {
|
|||
|
||||
if(x($_GET,'search')) {
|
||||
$search = escape_tags($_GET['search']);
|
||||
if (get_config('system','use_fulltext_engine')) {
|
||||
if(strpos($search,'#') === 0)
|
||||
$sql_extra .= sprintf(" AND (MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode)) ",
|
||||
dbesc(protect_sprintf($search))
|
||||
);
|
||||
else
|
||||
$sql_extra .= sprintf(" AND (MATCH(`item`.`body`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode)) ",
|
||||
dbesc(protect_sprintf($search)),
|
||||
dbesc(protect_sprintf($search))
|
||||
);
|
||||
} else {
|
||||
$sql_extra .= sprintf(" AND ( `item`.`body` like '%s' OR `item`.`tag` like '%s' ) ",
|
||||
dbesc(protect_sprintf('%' . $search . '%')),
|
||||
dbesc(protect_sprintf('%]' . $search . '[%'))
|
||||
);
|
||||
}
|
||||
}
|
||||
if(strlen($file)) {
|
||||
$sql_extra .= file_tag_file_query('item',unxmlify($file));
|
||||
}
|
||||
|
@ -410,15 +426,22 @@ function network_content(&$a, $update = 0) {
|
|||
if($conv) {
|
||||
$myurl = $a->get_baseurl() . '/profile/'. $a->user['nickname'];
|
||||
$myurl = substr($myurl,strpos($myurl,'://')+3);
|
||||
$myurl = str_replace(array('www.','.'),array('','\\.'),$myurl);
|
||||
$myurl = str_replace('www.','',$myurl);
|
||||
$diasp_url = str_replace('/profile/','/u/',$myurl);
|
||||
$sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` like '%s' or `tag` like '%s' or tag like '%s' )) ",
|
||||
dbesc(protect_sprintf('%s' . $myurl)),
|
||||
dbesc(protect_sprintf('%' . $myurl . '\\]%')),
|
||||
dbesc(protect_sprintf('%' . $diasp_url . '\\]%'))
|
||||
if (get_config('system','use_fulltext_engine'))
|
||||
$sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where (MATCH(`author-link`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(`tag`) AGAINST ('".'"%s"'."' in boolean mode) or MATCH(tag) AGAINST ('".'"%s"'."' in boolean mode))) ",
|
||||
dbesc(protect_sprintf($myurl)),
|
||||
dbesc(protect_sprintf($myurl)),
|
||||
dbesc(protect_sprintf($diasp_url))
|
||||
);
|
||||
else
|
||||
$sql_extra .= sprintf(" AND `item`.`parent` IN (SELECT distinct(`parent`) from item where ( `author-link` like '%s' or `tag` like '%s' or tag like '%s' )) ",
|
||||
dbesc(protect_sprintf('%' . $myurl)),
|
||||
dbesc(protect_sprintf('%' . $myurl . ']%')),
|
||||
dbesc(protect_sprintf('%' . $diasp_url . ']%'))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($update) {
|
||||
|
||||
|
@ -511,7 +534,7 @@ function network_content(&$a, $update = 0) {
|
|||
$parents_str = implode(', ', $parents_arr);
|
||||
|
||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`, `contact`.`writable`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`, `contact`.`writable`,
|
||||
`contact`.`network`, `contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
|
||||
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
|
||||
FROM `item`, `contact`
|
||||
|
|
|
@ -80,8 +80,9 @@ function notes_content(&$a,$update = false) {
|
|||
|
||||
$r = q("SELECT COUNT(*) AS `total`
|
||||
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
|
||||
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0 AND `item`.`deleted` = 0
|
||||
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
||||
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 and `item`.`moderated` = 0
|
||||
AND `item`.`deleted` = 0 AND `item`.`type` = 'note'
|
||||
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `contact`.`self` = 1
|
||||
AND `item`.`id` = `item`.`parent` AND `item`.`wall` = 0
|
||||
$sql_extra ",
|
||||
intval(local_user())
|
||||
|
@ -95,8 +96,9 @@ function notes_content(&$a,$update = false) {
|
|||
|
||||
$r = q("SELECT `item`.`id` AS `item_id`, `contact`.`uid` AS `contact-uid`
|
||||
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
|
||||
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0 and `item`.`moderated` = 0
|
||||
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
|
||||
WHERE `item`.`uid` = %d AND `item`.`visible` = 1 AND `item`.`deleted` = 0
|
||||
and `item`.`moderated` = 0 AND `item`.`type` = 'note'
|
||||
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0 AND `contact`.`self` = 1
|
||||
AND `item`.`id` = `item`.`parent` AND `item`.`wall` = 0
|
||||
$sql_extra
|
||||
ORDER BY `item`.`created` DESC LIMIT %d ,%d ",
|
||||
|
@ -115,7 +117,7 @@ function notes_content(&$a,$update = false) {
|
|||
$parents_str = implode(', ', $parents_arr);
|
||||
|
||||
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`, `contact`.`rel`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`network`, `contact`.`rel`,
|
||||
`contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
|
||||
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
|
||||
FROM `item` LEFT JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
|
||||
|
|
|
@ -28,6 +28,8 @@ function photo_init(&$a) {
|
|||
}
|
||||
}*/
|
||||
|
||||
$prvcachecontrol = false;
|
||||
|
||||
switch($a->argc) {
|
||||
case 4:
|
||||
$person = $a->argv[3];
|
||||
|
@ -134,6 +136,7 @@ function photo_init(&$a) {
|
|||
);
|
||||
if(count($r)) {
|
||||
$data = file_get_contents('images/nosign.jpg');
|
||||
$prvcachecontrol = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,8 +182,22 @@ function photo_init(&$a) {
|
|||
}
|
||||
|
||||
header("Content-type: image/jpeg");
|
||||
|
||||
if($prvcachecontrol) {
|
||||
|
||||
// it is a private photo that they have no permission to view.
|
||||
// tell the browser not to cache it, in case they authenticate
|
||||
// and subsequently have permission to see it
|
||||
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + (3600*24)) . " GMT");
|
||||
header("Cache-Control: max-age=" . (3600*24));
|
||||
|
||||
}
|
||||
echo $data;
|
||||
killme();
|
||||
// NOTREACHED
|
||||
|
|
|
@ -287,6 +287,7 @@ function photos_post(&$a) {
|
|||
|
||||
if(($a->argc > 2) && ((x($_POST,'desc') !== false) || (x($_POST,'newtag') !== false)) || (x($_POST,'albname') !== false)) {
|
||||
|
||||
|
||||
$desc = ((x($_POST,'desc')) ? notags(trim($_POST['desc'])) : '');
|
||||
$rawtags = ((x($_POST,'newtag')) ? notags(trim($_POST['newtag'])) : '');
|
||||
$item_id = ((x($_POST,'item_id')) ? intval($_POST['item_id']) : 0);
|
||||
|
@ -302,6 +303,60 @@ function photos_post(&$a) {
|
|||
$albname = datetime_convert('UTC',date_default_timezone_get(),'now', 'Y');
|
||||
|
||||
|
||||
if((x($_POST,'rotate') !== false) && (intval($_POST['rotate']) == 1)) {
|
||||
logger('rotate');
|
||||
|
||||
$r = q("select * from photo where `resource-id` = '%s' and uid = %d and scale = 0 limit 1",
|
||||
dbesc($resource_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
if(count($r)) {
|
||||
$ph = new Photo($r[0]['data']);
|
||||
if($ph->is_valid()) {
|
||||
$ph->rotate(270);
|
||||
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
|
||||
$x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 0 limit 1",
|
||||
dbesc($ph->imageString()),
|
||||
intval($height),
|
||||
intval($width),
|
||||
dbesc($resource_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
|
||||
if($width > 640 || $height > 640) {
|
||||
$ph->scaleImage(640);
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
|
||||
$x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 1 limit 1",
|
||||
dbesc($ph->imageString()),
|
||||
intval($height),
|
||||
intval($width),
|
||||
dbesc($resource_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
}
|
||||
|
||||
if($width > 320 || $height > 320) {
|
||||
$ph->scaleImage(320);
|
||||
$width = $ph->getWidth();
|
||||
$height = $ph->getHeight();
|
||||
|
||||
$x = q("update photo set data = '%s', height = %d, width = %d where `resource-id` = '%s' and uid = %d and scale = 2 limit 1",
|
||||
dbesc($ph->imageString()),
|
||||
intval($height),
|
||||
intval($width),
|
||||
dbesc($resource_id),
|
||||
intval($page_owner_uid)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$p = q("SELECT * FROM `photo` WHERE `resource-id` = '%s' AND `uid` = %d ORDER BY `scale` DESC",
|
||||
dbesc($resource_id),
|
||||
intval($page_owner_uid)
|
||||
|
@ -977,9 +1032,16 @@ function photos_content(&$a) {
|
|||
|
||||
$tpl = get_markup_template('photo_album.tpl');
|
||||
if(count($r))
|
||||
$twist = 'rotright';
|
||||
foreach($r as $rr) {
|
||||
if($twist == 'rotright')
|
||||
$twist = 'rotleft';
|
||||
else
|
||||
$twist = 'rotright';
|
||||
|
||||
$o .= replace_macros($tpl,array(
|
||||
'$id' => $rr['id'],
|
||||
'$twist' => ' ' . $twist . rand(2,4),
|
||||
'$photolink' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'],
|
||||
'$phototitle' => t('View Photo'),
|
||||
'$imgsrc' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg',
|
||||
|
@ -1098,7 +1160,7 @@ function photos_content(&$a) {
|
|||
$photo = array(
|
||||
'href' => $a->get_baseurl() . '/photo/' . $hires['resource-id'] . '-' . $hires['scale'] . '.jpg',
|
||||
'title'=> t('View Full Size'),
|
||||
'src' => $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.jpg'
|
||||
'src' => $a->get_baseurl() . '/photo/' . $lores['resource-id'] . '-' . $lores['scale'] . '.jpg' . '?f=&_u=' . datetime_convert('','','','ymdhis')
|
||||
);
|
||||
|
||||
if($nextlink)
|
||||
|
@ -1178,6 +1240,7 @@ function photos_content(&$a) {
|
|||
$edit_tpl = get_markup_template('photo_edit.tpl');
|
||||
$edit = replace_macros($edit_tpl, array(
|
||||
'$id' => $ph[0]['id'],
|
||||
'$rotate' => t('Rotate CW'),
|
||||
'$album' => template_escape($ph[0]['album']),
|
||||
'$newalbum' => t('New album name'),
|
||||
'$nickname' => $a->data['user']['nickname'],
|
||||
|
@ -1400,9 +1463,16 @@ function photos_content(&$a) {
|
|||
|
||||
$photos = array();
|
||||
if(count($r)) {
|
||||
$twist = 'rotright';
|
||||
foreach($r as $rr) {
|
||||
if($twist == 'rotright')
|
||||
$twist = 'rotleft';
|
||||
else
|
||||
$twist = 'rotright';
|
||||
|
||||
$photos[] = array(
|
||||
'id' => $rr['id'],
|
||||
'twist' => ' ' . $twist . rand(2,4),
|
||||
'link' => $a->get_baseurl() . '/photos/' . $a->data['user']['nickname'] . '/image/' . $rr['resource-id'],
|
||||
'title' => t('View Photo'),
|
||||
'src' => $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . ((($rr['scale']) == 6) ? 4 : $rr['scale']) . '.jpg',
|
||||
|
|
|
@ -10,8 +10,16 @@ function ping_init(&$a) {
|
|||
<result>";
|
||||
|
||||
$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
|
||||
|
||||
if(local_user()){
|
||||
|
||||
// Different login session than the page that is calling us.
|
||||
|
||||
if(intval($_GET['uid']) && intval($_GET['uid']) != local_user()) {
|
||||
echo '<invalid>1</invalid></result>';
|
||||
killme();
|
||||
}
|
||||
|
||||
$firehose = intval(get_pconfig(local_user(),'system','notify_full'));
|
||||
|
||||
$t = q("select count(*) as total from notify where uid = %d and seen = 0",
|
||||
|
|
|
@ -242,7 +242,7 @@ function profile_content(&$a, $update = 0) {
|
|||
$parents_str = implode(', ', $parents_arr);
|
||||
|
||||
$items = q("SELECT `item`.*, `item`.`id` AS `item_id`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`network`, `contact`.`rel`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`network`, `contact`.`rel`,
|
||||
`contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
|
||||
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`
|
||||
FROM `item`, `contact`
|
||||
|
|
|
@ -62,9 +62,15 @@ function profiles_post(&$a) {
|
|||
$pub_keywords = notags(trim($_POST['pub_keywords']));
|
||||
$prv_keywords = notags(trim($_POST['prv_keywords']));
|
||||
$marital = notags(trim($_POST['marital']));
|
||||
$howlong = notags(trim($_POST['howlong']));
|
||||
|
||||
$with = ((x($_POST,'with')) ? notags(trim($_POST['with'])) : '');
|
||||
|
||||
if(! strlen($howlong))
|
||||
$howlong = '0000-00-00 00:00:00';
|
||||
else
|
||||
$howlong = datetime_convert(date_default_timezone_get(),'UTC',$howlong);
|
||||
|
||||
// linkify the relationship target if applicable
|
||||
|
||||
$withchanged = false;
|
||||
|
@ -120,6 +126,7 @@ function profiles_post(&$a) {
|
|||
|
||||
$sexual = notags(trim($_POST['sexual']));
|
||||
$homepage = notags(trim($_POST['homepage']));
|
||||
$hometown = notags(trim($_POST['hometown']));
|
||||
$politic = notags(trim($_POST['politic']));
|
||||
$religion = notags(trim($_POST['religion']));
|
||||
|
||||
|
@ -146,7 +153,7 @@ function profiles_post(&$a) {
|
|||
$value = $marital;
|
||||
}
|
||||
if($withchanged) {
|
||||
$changes[] = '♥ ' . t('Romantic Partner');
|
||||
$changes[] = '[color=#ff0000]♥[/color] ' . t('Romantic Partner');
|
||||
$value = strip_tags($with);
|
||||
}
|
||||
if($work != $orig[0]['work']) {
|
||||
|
@ -176,9 +183,18 @@ function profiles_post(&$a) {
|
|||
$changes[] = t('Interests');
|
||||
$value = $interest;
|
||||
}
|
||||
if($address != $orig[0]['address'] || $locality != $orig[0]['locality'] || $region != $orig[0]['region']
|
||||
if($address != $orig[0]['address']) {
|
||||
$changes[] = t('Address');
|
||||
// New address not sent in notifications, potential privacy issues
|
||||
// in case this leaks to unintended recipients. Yes, it's in the public
|
||||
// profile but that doesn't mean we have to broadcast it to everybody.
|
||||
}
|
||||
if($locality != $orig[0]['locality'] || $region != $orig[0]['region']
|
||||
|| $country_name != $orig[0]['country-name']) {
|
||||
$changes[] = t('Location');
|
||||
$comma1 = ((($locality) && ($region || $country_name)) ? ', ' : ' ');
|
||||
$comma2 = (($region && $country_name) ? ', ' : '');
|
||||
$value = $locality . $comma1 . $region . $comma2 . $country_name;
|
||||
}
|
||||
|
||||
profile_activity($changes,$value);
|
||||
|
@ -198,8 +214,10 @@ function profiles_post(&$a) {
|
|||
`country-name` = '%s',
|
||||
`marital` = '%s',
|
||||
`with` = '%s',
|
||||
`howlong` = '%s',
|
||||
`sexual` = '%s',
|
||||
`homepage` = '%s',
|
||||
`hometown` = '%s',
|
||||
`politic` = '%s',
|
||||
`religion` = '%s',
|
||||
`pub_keywords` = '%s',
|
||||
|
@ -228,8 +246,10 @@ function profiles_post(&$a) {
|
|||
dbesc($country_name),
|
||||
dbesc($marital),
|
||||
dbesc($with),
|
||||
dbesc($howlong),
|
||||
dbesc($sexual),
|
||||
dbesc($homepage),
|
||||
dbesc($hometown),
|
||||
dbesc($politic),
|
||||
dbesc($religion),
|
||||
dbesc($pub_keywords),
|
||||
|
@ -329,7 +349,7 @@ function profile_activity($changed, $value) {
|
|||
|
||||
if($t == 1 && strlen($value)) {
|
||||
$message = sprintf( t('%1$s changed %2$s to “%3$s”'), $A, $changes, $value);
|
||||
$message .= "\n\n" . sprintf( t(" - Visit %1$s\'s %2$s"), $A, $prof);
|
||||
$message .= "\n\n" . sprintf( t(' - Visit %1$s\'s %2$s'), $A, $prof);
|
||||
}
|
||||
else
|
||||
$message = sprintf( t('%1$s has an updated %2$s, changing %3$s.'), $A, $prof, $changes);
|
||||
|
@ -549,8 +569,10 @@ function profiles_content(&$a) {
|
|||
'$lbl_marital' => t('<span class="heart">♥</span> Marital Status:'),
|
||||
'$lbl_with' => t("Who: \x28if applicable\x29"),
|
||||
'$lbl_ex1' => t('Examples: cathy123, Cathy Williams, cathy@example.com'),
|
||||
'$lbl_howlong' => t('Since [date]:'),
|
||||
'$lbl_sexual' => t('Sexual Preference:'),
|
||||
'$lbl_homepage' => t('Homepage URL:'),
|
||||
'$lbl_hometown' => t('Hometown:'),
|
||||
'$lbl_politic' => t('Political Views:'),
|
||||
'$lbl_religion' => t('Religious Views:'),
|
||||
'$lbl_pubkey' => t('Public Keywords:'),
|
||||
|
@ -586,9 +608,11 @@ function profiles_content(&$a) {
|
|||
'$gender' => gender_selector($r[0]['gender']),
|
||||
'$marital' => marital_selector($r[0]['marital']),
|
||||
'$with' => strip_tags($r[0]['with']),
|
||||
'$howlong' => ($r[0]['howlong'] === '0000-00-00 00:00:00' ? '' : datetime_convert('UTC',date_default_timezone_get(),$r[0]['howlong'])),
|
||||
'$sexual' => sexpref_selector($r[0]['sexual']),
|
||||
'$about' => $r[0]['about'],
|
||||
'$homepage' => $r[0]['homepage'],
|
||||
'$hometown' => $r[0]['hometown'],
|
||||
'$politic' => $r[0]['politic'],
|
||||
'$religion' => $r[0]['religion'],
|
||||
'$pub_keywords' => $r[0]['pub_keywords'],
|
||||
|
|
|
@ -6,7 +6,7 @@ function redir_init(&$a) {
|
|||
|
||||
// traditional DFRN
|
||||
|
||||
if(local_user() && $a->argc == 2 && intval($a->argv[1])) {
|
||||
if(local_user() && $a->argc > 1 && intval($a->argv[1])) {
|
||||
|
||||
$cid = $a->argv[1];
|
||||
|
||||
|
|
348
mod/register.php
348
mod/register.php
|
@ -43,347 +43,49 @@ function register_post(&$a) {
|
|||
break;
|
||||
}
|
||||
|
||||
$using_invites = get_config('system','invitation_only');
|
||||
$num_invites = get_config('system','number_invites');
|
||||
require_once('include/user.php');
|
||||
|
||||
$arr = $_POST;
|
||||
|
||||
$invite_id = ((x($_POST,'invite_id')) ? notags(trim($_POST['invite_id'])) : '');
|
||||
$username = ((x($_POST,'username')) ? notags(trim($_POST['username'])) : '');
|
||||
$nickname = ((x($_POST,'nickname')) ? notags(trim($_POST['nickname'])) : '');
|
||||
$email = ((x($_POST,'email')) ? notags(trim($_POST['email'])) : '');
|
||||
$openid_url = ((x($_POST,'openid_url')) ? notags(trim($_POST['openid_url'])) : '');
|
||||
$photo = ((x($_POST,'photo')) ? notags(trim($_POST['photo'])) : '');
|
||||
$publish = ((x($_POST,'profile_publish_reg') && intval($_POST['profile_publish_reg'])) ? 1 : 0);
|
||||
$arr['blocked'] = $blocked;
|
||||
$arr['verified'] = $verified;
|
||||
|
||||
$netpublish = ((strlen(get_config('system','directory_submit_url'))) ? $publish : 0);
|
||||
$result = create_user($arr);
|
||||
|
||||
$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($openid_url) {
|
||||
if(! validate_url($tmp_str)) {
|
||||
notice( t('Invalid OpenID url') . EOL);
|
||||
return;
|
||||
}
|
||||
$_SESSION['register'] = 1;
|
||||
$_SESSION['openid'] = $openid_url;
|
||||
require_once('library/openid.php');
|
||||
$openid = new LightOpenID;
|
||||
$openid->identity = $openid_url;
|
||||
$openid->returnUrl = $a->get_baseurl() . '/openid';
|
||||
$openid->required = array('namePerson/friendly', 'contact/email', 'namePerson');
|
||||
$openid->optional = array('namePerson/first','media/image/aspect11','media/image/default');
|
||||
goaway($openid->authUrl());
|
||||
// NOTREACHED
|
||||
}
|
||||
|
||||
notice( t('Please enter the required information.') . EOL );
|
||||
if(! $result['success']) {
|
||||
notice($result['message']);
|
||||
return;
|
||||
}
|
||||
|
||||
if(! validate_url($tmp_str))
|
||||
$openid_url = '';
|
||||
|
||||
|
||||
$err = '';
|
||||
|
||||
// collapse multiple spaces in name
|
||||
$username = preg_replace('/ +/',' ',$username);
|
||||
|
||||
if(mb_strlen($username) > 48)
|
||||
$err .= t('Please use a shorter name.') . EOL;
|
||||
if(mb_strlen($username) < 3)
|
||||
$err .= t('Name too short.') . EOL;
|
||||
|
||||
// I don't really like having this rule, but it cuts down
|
||||
// on the number of auto-registrations by Russian spammers
|
||||
|
||||
// Using preg_match was completely unreliable, due to mixed UTF-8 regex support
|
||||
// $no_utf = get_config('system','no_utf');
|
||||
// $pat = (($no_utf) ? '/^[a-zA-Z]* [a-zA-Z]*$/' : '/^\p{L}* \p{L}*$/u' );
|
||||
|
||||
// So now we are just looking for a space in the full name.
|
||||
|
||||
$loose_reg = get_config('system','no_regfullname');
|
||||
if(! $loose_reg) {
|
||||
$username = mb_convert_case($username,MB_CASE_TITLE,'UTF-8');
|
||||
if(! strpos($username,' '))
|
||||
$err .= t("That doesn't appear to be your full \x28First Last\x29 name.") . EOL;
|
||||
}
|
||||
|
||||
|
||||
if(! allowed_email($email))
|
||||
$err .= t('Your email domain is not among those allowed on this site.') . EOL;
|
||||
|
||||
if((! valid_email($email)) || (! validate_email($email)))
|
||||
$err .= t('Not a valid email address.') . EOL;
|
||||
|
||||
// Disallow somebody creating an account using openid that uses the admin email address,
|
||||
// since openid bypasses email verification. We'll allow it if there is not yet an admin account.
|
||||
|
||||
if((x($a->config,'admin_email')) && (strcasecmp($email,$a->config['admin_email']) == 0) && strlen($openid_url)) {
|
||||
$r = q("SELECT * FROM `user` WHERE `email` = '%s' LIMIT 1",
|
||||
dbesc($email)
|
||||
);
|
||||
if(count($r))
|
||||
$err .= t('Cannot use that email.') . EOL;
|
||||
}
|
||||
|
||||
$nickname = $_POST['nickname'] = strtolower($nickname);
|
||||
|
||||
if(! preg_match("/^[a-z][a-z0-9\-\_]*$/",$nickname))
|
||||
$err .= t('Your "nickname" can only contain "a-z", "0-9", "-", and "_", and must also begin with a letter.') . EOL;
|
||||
$r = q("SELECT `uid` FROM `user`
|
||||
WHERE `nickname` = '%s' LIMIT 1",
|
||||
dbesc($nickname)
|
||||
);
|
||||
if(count($r))
|
||||
$err .= t('Nickname is already registered. Please choose another.') . EOL;
|
||||
|
||||
// Check deleted accounts that had this nickname. Doesn't matter to us,
|
||||
// but could be a security issue for federated platforms.
|
||||
|
||||
$r = q("SELECT * FROM `userd`
|
||||
WHERE `username` = '%s' LIMIT 1",
|
||||
dbesc($nickname)
|
||||
);
|
||||
if(count($r))
|
||||
$err .= t('Nickname was once registered here and may not be re-used. Please choose another.') . EOL;
|
||||
|
||||
if(strlen($err)) {
|
||||
notice( $err );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
$new_password = autoname(6) . mt_rand(100,9999);
|
||||
$new_password_encoded = hash('whirlpool',$new_password);
|
||||
|
||||
$res=openssl_pkey_new(array(
|
||||
'digest_alg' => 'sha1',
|
||||
'private_key_bits' => 4096,
|
||||
'encrypt_key' => false ));
|
||||
|
||||
// Get private key
|
||||
|
||||
if(empty($res)) {
|
||||
notice( t('SERIOUS ERROR: Generation of security keys failed.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
$prvkey = '';
|
||||
|
||||
openssl_pkey_export($res, $prvkey);
|
||||
|
||||
// Get public key
|
||||
|
||||
$pkey = openssl_pkey_get_details($res);
|
||||
$pubkey = $pkey["key"];
|
||||
|
||||
/**
|
||||
*
|
||||
* Create another keypair for signing/verifying
|
||||
* salmon protocol messages. We have to use a slightly
|
||||
* less robust key because this won't be using openssl
|
||||
* but the phpseclib. Since it is PHP interpreted code
|
||||
* it is not nearly as efficient, and the larger keys
|
||||
* will take several minutes each to process.
|
||||
*
|
||||
*/
|
||||
|
||||
$sres=openssl_pkey_new(array(
|
||||
'digest_alg' => 'sha1',
|
||||
'private_key_bits' => 512,
|
||||
'encrypt_key' => false ));
|
||||
|
||||
// Get private key
|
||||
|
||||
$sprvkey = '';
|
||||
|
||||
openssl_pkey_export($sres, $sprvkey);
|
||||
|
||||
// Get public key
|
||||
|
||||
$spkey = openssl_pkey_get_details($sres);
|
||||
$spubkey = $spkey["key"];
|
||||
|
||||
$r = q("INSERT INTO `user` ( `guid`, `username`, `password`, `email`, `openid`, `nickname`,
|
||||
`pubkey`, `prvkey`, `spubkey`, `sprvkey`, `register_date`, `verified`, `blocked`, `timezone` )
|
||||
VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, 'UTC' )",
|
||||
dbesc(generate_user_guid()),
|
||||
dbesc($username),
|
||||
dbesc($new_password_encoded),
|
||||
dbesc($email),
|
||||
dbesc($openid_url),
|
||||
dbesc($nickname),
|
||||
dbesc($pubkey),
|
||||
dbesc($prvkey),
|
||||
dbesc($spubkey),
|
||||
dbesc($sprvkey),
|
||||
dbesc(datetime_convert()),
|
||||
intval($verified),
|
||||
intval($blocked)
|
||||
);
|
||||
|
||||
if($r) {
|
||||
$r = q("SELECT `uid` FROM `user`
|
||||
WHERE `username` = '%s' AND `password` = '%s' LIMIT 1",
|
||||
dbesc($username),
|
||||
dbesc($new_password_encoded)
|
||||
);
|
||||
if($r !== false && count($r))
|
||||
$newuid = intval($r[0]['uid']);
|
||||
}
|
||||
else {
|
||||
notice( t('An error occurred during registration. Please try again.') . EOL );
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* if somebody clicked submit twice very quickly, they could end up with two accounts
|
||||
* due to race condition. Remove this one.
|
||||
*/
|
||||
|
||||
$r = q("SELECT `uid` FROM `user`
|
||||
WHERE `nickname` = '%s' ",
|
||||
dbesc($nickname)
|
||||
);
|
||||
if((count($r) > 1) && $newuid) {
|
||||
$err .= t('Nickname is already registered. Please choose another.') . EOL;
|
||||
q("DELETE FROM `user` WHERE `uid` = %d LIMIT 1",
|
||||
intval($newuid)
|
||||
);
|
||||
notice ($err);
|
||||
return;
|
||||
}
|
||||
|
||||
if(x($newuid) !== false) {
|
||||
$r = q("INSERT INTO `profile` ( `uid`, `profile-name`, `is-default`, `name`, `photo`, `thumb`, `publish`, `net-publish` )
|
||||
VALUES ( %d, '%s', %d, '%s', '%s', '%s', %d, %d ) ",
|
||||
intval($newuid),
|
||||
'default',
|
||||
1,
|
||||
dbesc($username),
|
||||
dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"),
|
||||
intval($publish),
|
||||
intval($netpublish)
|
||||
|
||||
);
|
||||
if($r === false) {
|
||||
notice( t('An error occurred creating your default profile. Please try again.') . EOL );
|
||||
// Start fresh next time.
|
||||
$r = q("DELETE FROM `user` WHERE `uid` = %d",
|
||||
intval($newuid));
|
||||
return;
|
||||
}
|
||||
$r = q("INSERT INTO `contact` ( `uid`, `created`, `self`, `name`, `nick`, `photo`, `thumb`, `micro`, `blocked`, `pending`, `url`, `nurl`,
|
||||
`request`, `notify`, `poll`, `confirm`, `poco`, `name-date`, `uri-date`, `avatar-date`, `closeness` )
|
||||
VALUES ( %d, '%s', 1, '%s', '%s', '%s', '%s', '%s', 0, 0, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 0 ) ",
|
||||
intval($newuid),
|
||||
datetime_convert(),
|
||||
dbesc($username),
|
||||
dbesc($nickname),
|
||||
dbesc($a->get_baseurl() . "/photo/profile/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/photo/avatar/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/photo/micro/{$newuid}.jpg"),
|
||||
dbesc($a->get_baseurl() . "/profile/$nickname"),
|
||||
dbesc(normalise_link($a->get_baseurl() . "/profile/$nickname")),
|
||||
dbesc($a->get_baseurl() . "/dfrn_request/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/dfrn_notify/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/dfrn_poll/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/dfrn_confirm/$nickname"),
|
||||
dbesc($a->get_baseurl() . "/poco/$nickname"),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert()),
|
||||
dbesc(datetime_convert())
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// if we have no OpenID photo try to look up an avatar
|
||||
if(! strlen($photo))
|
||||
$photo = avatar_img($email);
|
||||
|
||||
// unless there is no avatar-plugin loaded
|
||||
if(strlen($photo)) {
|
||||
require_once('include/Photo.php');
|
||||
$photo_failure = false;
|
||||
|
||||
$filename = basename($photo);
|
||||
$img_str = fetch_url($photo,true);
|
||||
$img = new Photo($img_str);
|
||||
if($img->is_valid()) {
|
||||
|
||||
$img->scaleImageSquare(175);
|
||||
|
||||
$hash = photo_new_resource();
|
||||
|
||||
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 4 );
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
$img->scaleImage(80);
|
||||
|
||||
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 5 );
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
$img->scaleImage(48);
|
||||
|
||||
$r = $img->store($newuid, 0, $hash, $filename, t('Profile Photos'), 6 );
|
||||
|
||||
if($r === false)
|
||||
$photo_failure = true;
|
||||
|
||||
if(! $photo_failure) {
|
||||
q("UPDATE `photo` SET `profile` = 1 WHERE `resource-id` = '%s' ",
|
||||
dbesc($hash)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
$user = $result['user'];
|
||||
|
||||
if($netpublish && $a->config['register_policy'] != REGISTER_APPROVE) {
|
||||
$url = $a->get_baseurl() . "/profile/$nickname";
|
||||
$url = $a->get_baseurl() . '/profile/' . $user['nickname'];
|
||||
proc_run('php',"include/directory.php","$url");
|
||||
}
|
||||
|
||||
$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'])) : '');
|
||||
|
||||
call_hooks('register_account', $newuid);
|
||||
|
||||
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);
|
||||
set_pconfig($user['uid'],'system','invites_remaining',$num_invites);
|
||||
}
|
||||
|
||||
$email_tpl = get_intltext_template("register_open_eml.tpl");
|
||||
$email_tpl = replace_macros($email_tpl, array(
|
||||
'$sitename' => $a->config['sitename'],
|
||||
'$siteurl' => $a->get_baseurl(),
|
||||
'$username' => $username,
|
||||
'$email' => $email,
|
||||
'$password' => $new_password,
|
||||
'$uid' => $newuid ));
|
||||
'$username' => $user['username'],
|
||||
'$email' => $user['email'],
|
||||
'$password' => $result['password'],
|
||||
'$uid' => $user['uid'] ));
|
||||
|
||||
$res = mail($email, sprintf(t('Registration details for %s'), $a->config['sitename']),
|
||||
$res = mail($user['email'], sprintf(t('Registration details for %s'), $a->config['sitename']),
|
||||
$email_tpl,
|
||||
'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
|
||||
. 'Content-type: text/plain; charset=UTF-8' . "\n"
|
||||
|
@ -408,8 +110,8 @@ function register_post(&$a) {
|
|||
$r = q("INSERT INTO `register` ( `hash`, `created`, `uid`, `password`, `language` ) VALUES ( '%s', '%s', %d, '%s', '%s' ) ",
|
||||
dbesc($hash),
|
||||
dbesc(datetime_convert()),
|
||||
intval($newuid),
|
||||
dbesc($new_password),
|
||||
intval($user['uid']),
|
||||
dbesc($result['password']),
|
||||
dbesc($lang)
|
||||
);
|
||||
|
||||
|
@ -423,17 +125,17 @@ function register_post(&$a) {
|
|||
|
||||
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);
|
||||
set_pconfig($user['uid'],'system','invites_remaining',$num_invites);
|
||||
}
|
||||
|
||||
$email_tpl = get_intltext_template("register_verify_eml.tpl");
|
||||
$email_tpl = replace_macros($email_tpl, array(
|
||||
'$sitename' => $a->config['sitename'],
|
||||
'$siteurl' => $a->get_baseurl(),
|
||||
'$username' => $username,
|
||||
'$email' => $email,
|
||||
'$password' => $new_password,
|
||||
'$uid' => $newuid,
|
||||
'$username' => $user['username'],
|
||||
'$email' => $user['email'],
|
||||
'$password' => $result['password'],
|
||||
'$uid' => $user['uid'],
|
||||
'$hash' => $hash
|
||||
));
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ function search_content(&$a) {
|
|||
|
||||
$o = '<div id="live-search"></div>' . "\r\n";
|
||||
|
||||
$o .= '<h3>' . t('Search This Site') . '</h3>';
|
||||
$o .= '<h3>' . t('Search') . '</h3>';
|
||||
|
||||
if(x($a->data,'search'))
|
||||
$search = notags(trim($a->data['search']));
|
||||
|
@ -96,13 +96,29 @@ function search_content(&$a) {
|
|||
|
||||
$o .= search($search,'search-box','/search',((local_user()) ? true : false));
|
||||
|
||||
if(strpos($search,'#') === 0) {
|
||||
$tag = true;
|
||||
$search = substr($search,1);
|
||||
}
|
||||
if(strpos($search,'@') === 0) {
|
||||
require_once('mod/dirfind.php');
|
||||
return dirfind_content($a);
|
||||
}
|
||||
|
||||
if(! $search)
|
||||
return $o;
|
||||
|
||||
if (get_config('system','use_fulltext_engine')) {
|
||||
if($tag)
|
||||
$sql_extra = sprintf(" AND `item`.`tag` REGEXP '%s' ", dbesc('\\]' . preg_quote($search) . '\\['));
|
||||
$sql_extra = sprintf(" AND MATCH (`item`.`tag`) AGAINST ('".'"%s"'."' in boolean mode) ", '#'.dbesc(protect_sprintf($search)));
|
||||
else
|
||||
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(preg_quote($search)));
|
||||
$sql_extra = sprintf(" AND MATCH (`item`.`body`) AGAINST ('".'"%s"'."' in boolean mode) ", dbesc(protect_sprintf($search)));
|
||||
} else {
|
||||
if($tag)
|
||||
$sql_extra = sprintf(" AND `item`.`tag` REGEXP '%s' ", dbesc('\\]' . protect_sprintf(preg_quote($search)) . '\\['));
|
||||
else
|
||||
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(protect_sprintf(preg_quote($search))));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -130,7 +146,7 @@ function search_content(&$a) {
|
|||
}
|
||||
|
||||
$r = q("SELECT distinct(`item`.`uri`), `item`.*, `item`.`id` AS `item_id`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`rel`,
|
||||
`contact`.`name`, `contact`.`photo`, `contact`.`url`, `contact`.`alias`, `contact`.`rel`,
|
||||
`contact`.`network`, `contact`.`thumb`, `contact`.`self`, `contact`.`writable`,
|
||||
`contact`.`id` AS `cid`, `contact`.`uid` AS `contact-uid`,
|
||||
`user`.`nickname`
|
||||
|
|
|
@ -15,6 +15,7 @@ function get_theme_config_file($theme){
|
|||
}
|
||||
|
||||
function settings_init(&$a) {
|
||||
|
||||
// These lines provide the javascript needed by the acl selector
|
||||
|
||||
$a->page['htmlhead'] .= "<script> var ispublic = '" . t('everybody') . "';" ;
|
||||
|
@ -86,6 +87,7 @@ EOT;
|
|||
$tabtpl = get_markup_template("generic_links_widget.tpl");
|
||||
$a->page['aside'] = replace_macros($tabtpl, array(
|
||||
'$title' => t('Settings'),
|
||||
'$class' => 'settings-widget',
|
||||
'$items' => $tabs,
|
||||
));
|
||||
|
||||
|
@ -330,14 +332,14 @@ function settings_post(&$a) {
|
|||
$openid = ((x($_POST,'openid_url')) ? notags(trim($_POST['openid_url'])) : '');
|
||||
$maxreq = ((x($_POST,'maxreq')) ? intval($_POST['maxreq']) : 0);
|
||||
$expire = ((x($_POST,'expire')) ? intval($_POST['expire']) : 0);
|
||||
$def_gid = ((x($_POST,'group-selection')) ? intval($_POST['group-selection']) : 0);
|
||||
|
||||
|
||||
$expire_items = ((x($_POST,'expire_items')) ? intval($_POST['expire_items']) : 0);
|
||||
$expire_notes = ((x($_POST,'expire_notes')) ? intval($_POST['expire_notes']) : 0);
|
||||
$expire_starred = ((x($_POST,'expire_starred')) ? intval($_POST['expire_starred']) : 0);
|
||||
$expire_photos = ((x($_POST,'expire_photos'))? intval($_POST['expire_photos']) : 0);
|
||||
|
||||
|
||||
$expire_network_only = ((x($_POST,'expire_network_only'))? intval($_POST['expire_network_only']) : 0);
|
||||
|
||||
$allow_location = (((x($_POST,'allow_location')) && (intval($_POST['allow_location']) == 1)) ? 1: 0);
|
||||
$publish = (((x($_POST,'profile_in_directory')) && (intval($_POST['profile_in_directory']) == 1)) ? 1: 0);
|
||||
|
@ -355,7 +357,6 @@ function settings_post(&$a) {
|
|||
$post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0);
|
||||
$post_profilechange = (($_POST['post_profilechange'] == 1) ? 1: 0);
|
||||
|
||||
|
||||
$notify = 0;
|
||||
|
||||
if(x($_POST,'notify1'))
|
||||
|
@ -434,6 +435,7 @@ function settings_post(&$a) {
|
|||
set_pconfig(local_user(),'expire','notes', $expire_notes);
|
||||
set_pconfig(local_user(),'expire','starred', $expire_starred);
|
||||
set_pconfig(local_user(),'expire','photos', $expire_photos);
|
||||
set_pconfig(local_user(),'expire','network_only', $expire_network_only);
|
||||
|
||||
set_pconfig(local_user(),'system','suggestme', $suggestme);
|
||||
set_pconfig(local_user(),'system','post_newfriend', $post_newfriend);
|
||||
|
@ -441,7 +443,20 @@ function settings_post(&$a) {
|
|||
set_pconfig(local_user(),'system','post_profilechange', $post_profilechange);
|
||||
|
||||
|
||||
$r = q("UPDATE `user` SET `username` = '%s', `email` = '%s', `openid` = '%s', `timezone` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `notify-flags` = %d, `page-flags` = %d, `default-location` = '%s', `allow_location` = %d, `maxreq` = %d, `expire` = %d, `openidserver` = '%s', `blockwall` = %d, `hidewall` = %d, `blocktags` = %d, `unkmail` = %d, `cntunkmail` = %d WHERE `uid` = %d LIMIT 1",
|
||||
if($page_flags == PAGE_PRVGROUP) {
|
||||
$hidewall = 1;
|
||||
if((! $str_contact_allow) && (! $str_group_allow) && (! $str_contact_deny) && (! $str_group_deny)) {
|
||||
if($def_gid) {
|
||||
info( t('Private forum has no privacy permissions. Using default privacy group.'). EOL);
|
||||
$str_group_allow = '<' . $def_gid . '>';
|
||||
}
|
||||
else {
|
||||
notice( t('Private forum has no privacy permissions and no default privacy group.') . EOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$r = q("UPDATE `user` SET `username` = '%s', `email` = '%s', `openid` = '%s', `timezone` = '%s', `allow_cid` = '%s', `allow_gid` = '%s', `deny_cid` = '%s', `deny_gid` = '%s', `notify-flags` = %d, `page-flags` = %d, `default-location` = '%s', `allow_location` = %d, `maxreq` = %d, `expire` = %d, `openidserver` = '%s', `def_gid` = %d, `blockwall` = %d, `hidewall` = %d, `blocktags` = %d, `unkmail` = %d, `cntunkmail` = %d WHERE `uid` = %d LIMIT 1",
|
||||
dbesc($username),
|
||||
dbesc($email),
|
||||
dbesc($openid),
|
||||
|
@ -457,6 +472,7 @@ function settings_post(&$a) {
|
|||
intval($maxreq),
|
||||
intval($expire),
|
||||
dbesc($openidserver),
|
||||
intval($def_gid),
|
||||
intval($blockwall),
|
||||
intval($hidewall),
|
||||
intval($blocktags),
|
||||
|
@ -797,6 +813,9 @@ function settings_content(&$a) {
|
|||
$expire_photos = get_pconfig(local_user(), 'expire','photos');
|
||||
$expire_photos = (($expire_photos===false)? '0' : $expire_photos); // default if not set: 0
|
||||
|
||||
$expire_network_only = get_pconfig(local_user(), 'expire','network_only');
|
||||
$expire_network_only = (($expire_network_only===false)? '0' : $expire_network_only); // default if not set: 0
|
||||
|
||||
|
||||
$suggestme = get_pconfig(local_user(), 'system','suggestme');
|
||||
$suggestme = (($suggestme===false)? '0': $suggestme); // default if not set: 0
|
||||
|
@ -818,21 +837,27 @@ function settings_content(&$a) {
|
|||
|
||||
$pageset_tpl = get_markup_template('pagetypes.tpl');
|
||||
$pagetype = replace_macros($pageset_tpl,array(
|
||||
'$page_normal' => array('page-flags', t('Normal Account'), PAGE_NORMAL,
|
||||
'$page_normal' => array('page-flags', t('Normal Account Page'), PAGE_NORMAL,
|
||||
t('This account is a normal personal profile'),
|
||||
($a->user['page-flags'] == PAGE_NORMAL)),
|
||||
|
||||
'$page_soapbox' => array('page-flags', t('Soapbox Account'), PAGE_SOAPBOX,
|
||||
'$page_soapbox' => array('page-flags', t('Soapbox Page'), PAGE_SOAPBOX,
|
||||
t('Automatically approve all connection/friend requests as read-only fans'),
|
||||
($a->user['page-flags'] == PAGE_SOAPBOX)),
|
||||
|
||||
'$page_community' => array('page-flags', t('Community/Celebrity Account'), PAGE_COMMUNITY,
|
||||
'$page_community' => array('page-flags', t('Community Forum/Celebrity Account'), PAGE_COMMUNITY,
|
||||
t('Automatically approve all connection/friend requests as read-write fans'),
|
||||
($a->user['page-flags'] == PAGE_COMMUNITY)),
|
||||
|
||||
'$page_freelove' => array('page-flags', t('Automatic Friend Account'), PAGE_FREELOVE,
|
||||
'$page_freelove' => array('page-flags', t('Automatic Friend Page'), PAGE_FREELOVE,
|
||||
t('Automatically approve all connection/friend requests as friends'),
|
||||
($a->user['page-flags'] == PAGE_FREELOVE)),
|
||||
|
||||
'$page_prvgroup' => array('page-flags', t('Private Forum [Experimental]'), PAGE_PRVGROUP,
|
||||
t('Private forum - approved members only'),
|
||||
($a->user['page-flags'] == PAGE_PRVGROUP)),
|
||||
|
||||
|
||||
));
|
||||
|
||||
$noid = get_config('system','no_openid');
|
||||
|
@ -932,8 +957,12 @@ function settings_content(&$a) {
|
|||
'notes' => array('expire_notes', t("Expire personal notes:"), $expire_notes, '', array(t('No'),t('Yes'))),
|
||||
'starred' => array('expire_starred', t("Expire starred posts:"), $expire_starred, '', array(t('No'),t('Yes'))),
|
||||
'photos' => array('expire_photos', t("Expire photos:"), $expire_photos, '', array(t('No'),t('Yes'))),
|
||||
'network_only' => array('expire_network_only', t("Only expire posts by others:"), $expire_network_only, '', array(t('No'),t('Yes'))),
|
||||
);
|
||||
|
||||
require_once('include/group.php');
|
||||
$group_select = mini_group_select(local_user(),$a->user['def_gid']);
|
||||
|
||||
$o .= replace_macros($stpl,array(
|
||||
'$ptitle' => t('Account Settings'),
|
||||
|
||||
|
@ -941,7 +970,6 @@ function settings_content(&$a) {
|
|||
'$baseurl' => $a->get_baseurl(true),
|
||||
'$uid' => local_user(),
|
||||
'$form_security_token' => get_form_security_token("settings"),
|
||||
|
||||
'$nickname_block' => $prof_addr,
|
||||
|
||||
'$h_pass' => t('Password Settings'),
|
||||
|
@ -968,6 +996,10 @@ function settings_content(&$a) {
|
|||
'$suggestme' => $suggestme,
|
||||
'$blockwall'=> $blockwall, // array('blockwall', t('Allow friends to post to your profile page:'), !$blockwall, ''),
|
||||
'$blocktags'=> $blocktags, // array('blocktags', t('Allow friends to tag your posts:'), !$blocktags, ''),
|
||||
|
||||
'$group_select' => $group_select,
|
||||
|
||||
|
||||
'$expire' => $expire_arr,
|
||||
|
||||
'$profile_in_dir' => $profile_in_dir,
|
||||
|
@ -993,7 +1025,8 @@ function settings_content(&$a) {
|
|||
'$notify7' => array('notify7', t('You are tagged in a post'), ($notify & NOTIFY_TAGSELF), NOTIFY_TAGSELF, ''),
|
||||
|
||||
|
||||
'$h_advn' => t('Advanced Page Settings'),
|
||||
'$h_advn' => t('Advanced Account/Page Type Settings'),
|
||||
'$h_descadvn' => t('Change the behaviour of this account for special situations'),
|
||||
'$pagetype' => $pagetype,
|
||||
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ function wallmessage_post(&$a) {
|
|||
}
|
||||
|
||||
// Work around doubled linefeeds in Tinymce 3.5b2
|
||||
dbg(1);
|
||||
|
||||
$body = str_replace("\r\n","\n",$body);
|
||||
$body = str_replace("\n\n","\n",$body);
|
||||
|
||||
|
@ -67,7 +67,7 @@ dbg(1);
|
|||
default:
|
||||
info( t('Message sent.') . EOL );
|
||||
}
|
||||
dbg(0);
|
||||
|
||||
// goaway($a->get_baseurl() . '/profile/' . $user['nickname']);
|
||||
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue