Merge branch 'master' of github.com:annando/friendica

This commit is contained in:
Michael 2012-05-19 16:55:33 +02:00
commit 6342b3e0bd
915 changed files with 38082 additions and 88096 deletions

153
boot.php
View File

@ -9,9 +9,9 @@ require_once('include/nav.php');
require_once('include/cache.php');
define ( 'FRIENDICA_PLATFORM', 'Friendica');
define ( 'FRIENDICA_VERSION', '2.3.1318' );
define ( 'FRIENDICA_VERSION', '3.0.1346' );
define ( 'DFRN_PROTOCOL_VERSION', '2.23' );
define ( 'DB_UPDATE_VERSION', 1138 );
define ( 'DB_UPDATE_VERSION', 1144 );
define ( 'EOL', "<br />\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
@ -29,6 +29,12 @@ define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
define ( 'JPEG_QUALITY', 100 );
/**
* Not yet used
*/
define ( 'DEFAULT_DB_ENGINE', 'MyISAM' );
/**
* SSL redirection policies
*/
@ -73,6 +79,14 @@ define ( 'HOOK_HOOK', 0);
define ( 'HOOK_FILE', 1);
define ( 'HOOK_FUNCTION', 2);
/**
* DB update return values
*/
define ( 'UPDATE_SUCCESS', 0);
define ( 'UPDATE_FAILED', 1);
/**
*
* page/profile types
@ -109,6 +123,8 @@ define ( 'NETWORK_XMPP', 'xmpp'); // XMPP
define ( 'NETWORK_MYSPACE', 'mysp'); // MySpace
define ( 'NETWORK_GPLUS', 'goog'); // Google+
define ( 'NETWORK_PHANTOM', 'unkn'); // Place holder
/**
* These numbers are used in stored permissions
* and existing allocations MUST NEVER BE CHANGED
@ -128,6 +144,8 @@ $netgroup_ids = array(
NETWORK_XMPP => (-10),
NETWORK_MYSPACE => (-11),
NETWORK_GPLUS => (-12),
NETWORK_PHANTOM => (-127),
);
@ -193,6 +211,8 @@ define ( 'ACTIVITY_REQ_FRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'request-friend' );
define ( 'ACTIVITY_UNFRIEND', NAMESPACE_ACTIVITY_SCHEMA . 'remove-friend' );
define ( 'ACTIVITY_FOLLOW', NAMESPACE_ACTIVITY_SCHEMA . 'follow' );
define ( 'ACTIVITY_UNFOLLOW', NAMESPACE_ACTIVITY_SCHEMA . 'stop-following' );
define ( 'ACTIVITY_JOIN', NAMESPACE_ACTIVITY_SCHEMA . 'join' );
define ( 'ACTIVITY_POST', NAMESPACE_ACTIVITY_SCHEMA . 'post' );
define ( 'ACTIVITY_UPDATE', NAMESPACE_ACTIVITY_SCHEMA . 'update' );
define ( 'ACTIVITY_TAG', NAMESPACE_ACTIVITY_SCHEMA . 'tag' );
@ -205,6 +225,7 @@ define ( 'ACTIVITY_OBJ_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'photo' );
define ( 'ACTIVITY_OBJ_P_PHOTO', NAMESPACE_ACTIVITY_SCHEMA . 'profile-photo' );
define ( 'ACTIVITY_OBJ_ALBUM', NAMESPACE_ACTIVITY_SCHEMA . 'photo-album' );
define ( 'ACTIVITY_OBJ_EVENT', NAMESPACE_ACTIVITY_SCHEMA . 'event' );
define ( 'ACTIVITY_OBJ_GROUP', NAMESPACE_ACTIVITY_SCHEMA . 'group' );
define ( 'ACTIVITY_OBJ_TAGTERM', NAMESPACE_DFRN . '/tagterm' );
define ( 'ACTIVITY_OBJ_PROFILE', NAMESPACE_DFRN . '/profile' );
@ -658,32 +679,29 @@ if(! function_exists('check_config')) {
// call the specific update
// global $db;
// $db->excep(TRUE);
// try {
// $db->beginTransaction();
$func = 'update_' . $x;
$func($a);
// $db->commit();
// } catch(Exception $ex) {
// $db->rollback();
// //send the administrator an e-mail
// $email_tpl = get_intltext_template("update_fail_eml.tpl");
// $email_tpl = replace_macros($email_tpl, array(
// '$sitename' => $a->config['sitename'],
// '$siteurl' => $a->get_baseurl(),
// '$update' => $x,
// '$error' => $ex->getMessage()));
// $subject=sprintf(t('Update Error at %s'), $a->get_baseurl());
$func = 'update_' . $x;
$retval = $func();
if($retval) {
//send the administrator an e-mail
$email_tpl = get_intltext_template("update_fail_eml.tpl");
$email_msg = replace_macros($email_tpl, array(
'$sitename' => $a->config['sitename'],
'$siteurl' => $a->get_baseurl(),
'$update' => $x,
'$error' => sprintf( t('Update %s failed. See error logs.'), $x)
));
$subject=sprintf(t('Update Error at %s'), $a->get_baseurl());
// mail($a->config['admin_email'], $subject, $text,
// 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
// . 'Content-type: text/plain; charset=UTF-8' . "\n"
// . 'Content-transfer-encoding: 8bit' );
// //try the logger
// logger('update failed: '.$ex->getMessage().EOL);
// }
// $db->excep(FALSE);
mail($a->config['admin_email'], $subject, $email_msg,
'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n"
. 'Content-transfer-encoding: 8bit' );
//try the logger
logger('CRITICAL: Update Failed: '. $x);
}
else
set_config('database','update_' . $x, 'success');
}
}
set_config('system','build', DB_UPDATE_VERSION);
@ -725,9 +743,10 @@ if(! function_exists('check_config')) {
foreach($installed as $i) {
if(! in_array($i['name'],$plugins_arr)) {
uninstall_plugin($i['name']);
}
else
}
else {
$installed_arr[] = $i['name'];
}
}
}
@ -1174,11 +1193,7 @@ if(! function_exists('get_birthdays')) {
}
$classtoday = $istoday ? ' birthday-today ' : '';
if($total) {
$o .= '<div id="birthday-notice" class="birthday-notice fakelink' . $classtoday . '" onclick=openClose(\'birthday-wrapper\'); >' . t('Birthday Reminders') . ' ' . '(' . $total . ')' . '</div>';
$o .= '<div id="birthday-wrapper" style="display: none;" ><div id="birthday-title">' . t('Birthdays this week:') . '</div>';
$o .= '<div id="birthday-title-end"></div>';
foreach($r as $rr) {
foreach($r as &$rr) {
if(! strlen($rr['name']))
continue;
@ -1196,15 +1211,24 @@ if(! function_exists('get_birthdays')) {
$url = $a->get_baseurl() . '/redir/' . $rr['cid'];
}
$o .= '<div class="birthday-list" id="birthday-' . $rr['eid'] . '"><a class="birthday-link$sparkle" target="redir" href="'
. $url . '">' . $rr['name'] . '</a> '
. day_translate(datetime_convert('UTC', $a->timezone, $rr['start'], $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . t('[today]') : '')
. '</div>' ;
$rr['link'] = $url;
$rr['title'] = $rr['name'];
$rr['date'] = day_translate(datetime_convert('UTC', $a->timezone, $rr['start'], $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . t('[today]') : '');
$rr['startime'] = Null;
$rr['today'] = $today;
}
$o .= '</div></div>';
}
}
return $o;
$tpl = get_markup_template("birthdays_reminder.tpl");
return replace_macros($tpl, array(
'$baseurl' => $a->get_baseurl(),
'$classtoday' => $classtoday,
'$count' => $total,
'$event_reminders' => t('Birthday Reminders'),
'$event_title' => t('Birthdays this week:'),
'$events' => $r,
));
}
}
@ -1215,7 +1239,6 @@ if(! function_exists('get_events')) {
require_once('include/bbcode.php');
$a = get_app();
$o = '';
if(! local_user())
return $o;
@ -1242,18 +1265,15 @@ if(! function_exists('get_events')) {
if($strt === datetime_convert('UTC',$a->timezone,'now','Y-m-d'))
$istoday = true;
}
$classtoday = (($istoday) ? ' event-today ' : '');
$classtoday = (($istoday) ? 'event-today' : '');
$o .= '<div id="event-notice" class="birthday-notice fakelink' . $classtoday . '" onclick=openClose(\'event-wrapper\'); >' . t('Event Reminders') . ' ' . '(' . count($r) . ')' . '</div>';
$o .= '<div id="event-wrapper" style="display: none;" ><div id="event-title">' . t('Events this week:') . '</div>';
$o .= '<div id="event-title-end"></div>';
foreach($r as $rr) {
foreach($r as &$rr) {
if($rr['adjust'])
$md = datetime_convert('UTC',$a->timezone,$rr['start'],'Y/m\#\l\i\n\k\-j');
$md = datetime_convert('UTC',$a->timezone,$rr['start'],'Y/m');
else
$md = datetime_convert('UTC','UTC',$rr['start'],'Y/m\#\l\i\n\k\-j');
$md = datetime_convert('UTC','UTC',$rr['start'],'Y/m');
$md .= "/#link-".$rr['id'];
$title = substr(strip_tags(bbcode($rr['desc'])),0,32) . '... ';
if(! $title)
@ -1261,15 +1281,24 @@ if(! function_exists('get_events')) {
$strt = datetime_convert('UTC',$rr['convert'] ? $a->timezone : 'UTC',$rr['start']);
$today = ((substr($strt,0,10) === datetime_convert('UTC',$a->timezone,'now','Y-m-d')) ? true : false);
$o .= '<div class="event-list" id="event-' . $rr['eid'] . '"></a> <a href="events/' . $md . '">' . $title . '</a>'
. day_translate(datetime_convert('UTC', $rr['adjust'] ? $a->timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : '')
. '</div>' ;
$rr['link'] = $md;
$rr['title'] = $title;
$rr['date'] = day_translate(datetime_convert('UTC', $rr['adjust'] ? $a->timezone : 'UTC', $rr['start'], $bd_format)) . (($today) ? ' ' . t('[today]') : '');
$rr['startime'] = $strt;
$rr['today'] = $today;
}
$o .= '</div></div>';
}
return $o;
$tpl = get_markup_template("events_reminder.tpl");
return replace_macros($tpl, array(
'$baseurl' => $a->get_baseurl(),
'$classtoday' => $classtoday,
'$count' => count($r),
'$event_reminders' => t('Event Reminders'),
'$event_title' => t('Events this week:'),
'$events' => $r,
));
}
}
@ -1453,16 +1482,19 @@ if(! function_exists('profile_tabs')){
'label'=>t('Status'),
'url' => $url,
'sel' => ((!isset($tab)&&$a->argv[0]=='profile')?'active':''),
'title' => t('Status Messages and Posts'),
),
array(
'label' => t('Profile'),
'url' => $url.'/?tab=profile',
'sel' => ((isset($tab) && $tab=='profile')?'active':''),
'title' => t('Profile Details'),
),
array(
'label' => t('Photos'),
'url' => $a->get_baseurl() . '/photos/' . $nickname,
'sel' => ((!isset($tab)&&$a->argv[0]=='photos')?'active':''),
'title' => t('Photo Albums'),
),
);
@ -1471,11 +1503,13 @@ if(! function_exists('profile_tabs')){
'label' => t('Events'),
'url' => $a->get_baseurl() . '/events',
'sel' =>((!isset($tab)&&$a->argv[0]=='events')?'active':''),
'title' => t('Events and Calendar'),
);
$tabs[] = array(
'label' => t('Personal Notes'),
'url' => $a->get_baseurl() . '/notes',
'sel' =>((!isset($tab)&&$a->argv[0]=='notes')?'active':''),
'title' => t('Only You Can See This'),
);
}
@ -1495,6 +1529,15 @@ function get_my_url() {
return false;
}
function zrl_init(&$a) {
$tmp_str = get_my_url();
if(validate_url($tmp_str)) {
proc_run('php','include/gprobe.php',bin2hex($tmp_str));
$arr = array('zrl' => $tmp_str, 'url' => $a->cmd);
call_hooks('zrl_init',$arr);
}
}
function zrl($s,$force = false) {
if(! strlen($s))
return $s;

19
convert_innodb.sql Normal file
View 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';

View File

@ -16,9 +16,11 @@ CREATE TABLE IF NOT EXISTS `addon` (
`name` char(255) NOT NULL,
`version` char(255) NOT NULL,
`installed` tinyint(1) NOT NULL DEFAULT '0',
`hidden` tinyint(1) NOT NULL DEFAULT '0',
`timestamp` bigint(20) NOT NULL DEFAULT '0',
`plugin_admin` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
PRIMARY KEY (`id`),
KEY `hidden` (`hidden`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
@ -172,6 +174,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
`writable` tinyint(1) NOT NULL DEFAULT '0',
`forum` 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',
`rating` tinyint(1) NOT NULL DEFAULT '0' COMMENT '0-5 reputation, 0 unknown, 1 call police, 5 inscrutable',
`reason` text NOT NULL COMMENT 'why a rating was given - will help friends decide to make friends or not',
@ -197,6 +200,7 @@ CREATE TABLE IF NOT EXISTS `contact` (
KEY `nurl` (`nurl`),
KEY `pending` (`pending`),
KEY `hidden` (`hidden`),
KEY `archive` (`archive`),
KEY `forum` (`forum`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@ -380,11 +384,13 @@ CREATE TABLE IF NOT EXISTS `glink` (
`cid` int(11) NOT NULL,
`uid` int(11) NOT NULL,
`gcid` int(11) NOT NULL,
`zcid` int(11) NOT NULL,
`updated` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `cid` (`cid`),
KEY `uid` (`uid`),
KEY `gcid` (`gcid`),
KEY `zcid` (`zcid`),
KEY `updated` (`updated`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
@ -1017,9 +1023,12 @@ CREATE TABLE IF NOT EXISTS `user` (
`pwdreset` char(255) NOT NULL,
`maxreq` int(11) NOT NULL DEFAULT '10',
`expire` int(10) unsigned NOT NULL DEFAULT '0',
`account_removed` tinyint(1) NOT NULL DEFAULT '0',
`account_expired` tinyint(1) NOT NULL DEFAULT '0',
`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,
@ -1034,7 +1043,9 @@ CREATE TABLE IF NOT EXISTS `user` (
KEY `blocked` (`blocked`),
KEY `verified` (`verified`),
KEY `unkmail` (`unkmail`),
KEY `cntunkmail` (`cntunkmail`)
KEY `cntunkmail` (`cntunkmail`),
KEY `account_removed` (`account_removed`),
KEY `service_class` (`service_class`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-- --------------------------------------------------------

View File

@ -69,7 +69,7 @@ $a->config['system']['rino_encrypt'] = true;
// allowed themes (change this from admin panel after installation)
$a->config['system']['allowed_themes'] = 'dispy,quattro,testbubble,vier,darkbubble,darkzero,duepuntozero,greenzero,purplezero,quattro-green,slackr,diabook,diabook-blue';
$a->config['system']['allowed_themes'] = 'dispy,quattro,vier,darkzero,duepuntozero,greenzero,purplezero,slackr,diabook';
// default system theme

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -51,6 +51,21 @@ function user_remove($uid) {
function contact_remove($id) {
$r = q("select uid from contact where id = %d limit 1",
intval($id)
);
if((! count($r)) || (! intval($r[0]['uid'])))
return;
$archive = get_pconfig($r[0]['uid'], 'system','archive_removed_contacts');
if($archive) {
q("update contact set `archive` = 1, `network` = 'none', `writable` = 0 where id = %d limit 1",
intval($id)
);
return;
}
q("DELETE FROM `contact` WHERE `id` = %d LIMIT 1",
intval($id)
);
@ -73,6 +88,49 @@ function contact_remove($id) {
}
// sends an unfriend message. Does not remove the contact
function terminate_friendship($user,$self,$contact) {
$a = get_app();
require_once('include/datetime.php');
if($contact['network'] === NETWORK_OSTATUS) {
$slap = replace_macros(get_markup_template('follow_slap.tpl'), array(
'$name' => $user['username'],
'$profile_page' => $a->get_baseurl() . '/profile/' . $user['nickname'],
'$photo' => $self['photo'],
'$thumb' => $self['thumb'],
'$published' => datetime_convert('UTC','UTC', 'now', ATOM_TIME),
'$item_id' => 'urn:X-dfrn:' . $a->get_hostname() . ':unfollow:' . random_string(),
'$title' => '',
'$type' => 'text',
'$content' => t('stopped following'),
'$nick' => $user['nickname'],
'$verb' => 'http://ostatus.org/schema/1.0/unfollow', // ACTIVITY_UNFOLLOW,
'$ostat_follow' => '' // '<as:verb>http://ostatus.org/schema/1.0/unfollow</as:verb>' . "\r\n"
));
if((x($contact,'notify')) && (strlen($contact['notify']))) {
require_once('include/salmon.php');
slapper($user,$contact['notify'],$slap);
}
}
elseif($contact['network'] === NETWORK_DIASPORA) {
require_once('include/diaspora.php');
diaspora_unshare($user,$contact);
}
elseif($contact['network'] === NETWORK_DFRN) {
require_once('include/items.php');
dfrn_deliver($user,$contact,'placeholder', 1);
}
}
// Contact has refused to recognise us as a friend. We will start a countdown.
// If they still don't recognise us in 32 days, the relationship is over,
// and we won't waste any more time trying to communicate with them.
@ -151,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);

View File

@ -282,7 +282,7 @@ function scrape_feed($url) {
}
}
if(! $basename)
$basename = substr($url,0,strrpos($url,'/')) . '/';
$basename = implode('/', array_slice(explode('/',$url),0,3)) . '/';
$items = $dom->getElementsByTagName('link');

View File

@ -122,7 +122,7 @@ function contact_selector($selname, $selclass, $preselected = false, $options) {
$o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"" . $x['size'] . "$\" $tabindex >\r\n";
$r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `notify` != ''
WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
$sql_extra
ORDER BY `name` ASC ",
intval(local_user())
@ -188,7 +188,7 @@ function contact_select($selname, $selclass, $preselected = false, $size = 4, $p
$o .= "<select name=\"{$selname}[]\" id=\"$selclass\" class=\"$selclass\" multiple=\"multiple\" size=\"$size\" $tabindex >\r\n";
$r = q("SELECT `id`, `name`, `url`, `network` FROM `contact`
WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `notify` != ''
WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
$sql_extra
ORDER BY `name` ASC ",
intval(local_user())

View File

@ -380,7 +380,7 @@
$nick = $name;
// Generating a random ID
if (!array_key_exists($nick, $usercache))
if (is_null($usercache[$nick]) or !array_key_exists($nick, $usercache))
$usercache[$nick] = mt_rand(2000000, 2100000);
$ret = array(
@ -567,8 +567,17 @@
$_REQUEST['profile_uid'] = local_user();
if(requestdata('parent'))
$_REQUEST['type'] = 'net-comment';
else
else {
$_REQUEST['type'] = 'wall';
if(x($_FILES,'media')) {
// upload the image if we have one
$_REQUEST['hush']='yeah'; //tell wall_upload function to return img info instead of echo
require_once('mod/wall_upload.php');
$media = wall_upload_post($a);
if(strlen($media)>0)
$_REQUEST['body'] .= "\n\n".$media;
}
}
// set this so that the item_post() function is quiet and doesn't redirect or emit json

View File

@ -298,6 +298,9 @@ function bbcode($Text,$preserve_nl = false) {
$Text = preg_replace_callback("/\[nobb\](.*?)\[\/nobb\]/ism", 'bb_unspacefy_and_trim',$Text);
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim',$Text);
$Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/','&$1;',$Text);
// fix any escaped ampersands that may have been converted into links
$Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&amp\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text);
if(strlen($saved_image))

View File

@ -14,22 +14,40 @@
}
public static function set($key,$value) {
$r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
dbesc($key)
);
if(count($r)) {
q("UPDATE `cache` SET `v` = '%s', `updated = '%s' WHERE `k` = '%s' limit 1",
dbesc($value),
dbesc(datetime_convert()),
dbesc($key));
}
else {
q("INSERT INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
q("REPLACE INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
dbesc($key),
dbesc($value),
dbesc(datetime_convert()));
}
}
/*
*
* Leaving this legacy code temporaily to see how REPLACE fares
* as opposed to non-atomic checks when faced with fast moving key duplication.
* As a MySQL extension it isn't portable, but we're not yet very portable.
*/
/*
* $r = q("SELECT * FROM `cache` WHERE `k`='%s' limit 1",
* dbesc($key)
* );
* if(count($r)) {
* q("UPDATE `cache` SET `v` = '%s', `updated = '%s' WHERE `k` = '%s' limit 1",
* dbesc($value),
* dbesc(datetime_convert()),
* dbesc($key));
* }
* else {
* q("INSERT INTO `cache` (`k`,`v`,`updated`) VALUES ('%s','%s','%s')",
* dbesc($key),
* dbesc($value),
* dbesc(datetime_convert()));
* }
* }
*/
public static function clear(){
q("DELETE FROM `cache` WHERE `updated` < '%s'",

View File

@ -133,3 +133,60 @@ function categories_widget($baseurl,$selected = '') {
));
}
function common_friends_visitor_widget($profile_uid) {
$a = get_app();
if(local_user() == $profile_uid)
return;
$cid = $zcid = 0;
if(can_write_wall($a,$profile_uid))
$cid = remote_user();
else {
if(get_my_url()) {
$r = q("select id from contact where nurl = '%s' and uid = %d limit 1",
dbesc(normalise_link(get_my_url())),
intval($profile_uid)
);
if(count($r))
$cid = $r[0]['id'];
else {
$r = q("select id from gcontact where nurl = '%s' limit 1",
dbesc(normalise_link(get_my_url()))
);
if(count($r))
$zcid = $r[0]['id'];
}
}
}
if($cid == 0 && $zcid == 0)
return;
require_once('include/socgraph.php');
if($cid)
$t = count_common_friends($profile_uid,$cid);
else
$t = count_common_friends_zcid($profile_uid,$zcid);
if(! $t)
return;
if($cid)
$r = common_friends($profile_uid,$cid,0,5,true);
else
$r = common_friends_zcid($profile_uid,$zcid,0,5,true);
return replace_macros(get_markup_template('remote_friends_common.tpl'), array(
'$desc' => sprintf( tt("%d contact in common", "%d contacts in common", $t), $t),
'$base' => $a->get_baseurl(),
'$uid' => $profile_uid,
'$cid' => (($cid) ? $cid : '0'),
'$linkmore' => (($t > 5) ? 'true' : ''),
'$more' => t('show more'),
'$items' => $r
));
};

View File

@ -278,6 +278,9 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
else
$nickname = $a->user['nickname'];
// prevent private email from leaking.
if($item['network'] === NETWORK_MAIL && local_user() != $item['uid'])
continue;
$profile_name = ((strlen($item['author-name'])) ? $item['author-name'] : $item['name']);
if($item['author-link'] && (! $item['author-name']))
@ -447,8 +450,8 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
else {
// prevent private email reply to public conversation from leaking.
if($item['private'] && ! $threads[$threadsid]['private'])
continue;
if($item['network'] === NETWORK_MAIL && local_user() != $item['uid'])
continue;
$comments_seen ++;
$comment_lastcollapsed = false;
@ -553,6 +556,14 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
'$myphoto' => $a->contact['thumb'],
'$comment' => t('Comment'),
'$submit' => t('Submit'),
'$edbold' => t('Bold'),
'$editalic' => t('Italic'),
'$eduline' => t('Underline'),
'$edquote' => t('Quote'),
'$edcode' => t('Code'),
'$edimg' => t('Image'),
'$edurl' => t('Link'),
'$edvideo' => t('Video'),
'$preview' => t('Preview'),
'$ww' => (($mode === 'network') ? $commentww : '')
));
@ -951,7 +962,7 @@ function status_editor($a,$x, $notes_cid = 0, $popup=false) {
$tpl = replace_macros($tpl,array('$jotplugins' => $jotplugins));
$o .= replace_macros($tpl,array(
'$return_path' => $a->cmd,
'$return_path' => $a->query_string,
'$action' => $a->get_baseurl(true) . '/item',
'$share' => (x($x,'button') ? $x['button'] : t('Share')),
'$upload' => t('Upload photo'),

View File

@ -75,22 +75,28 @@ class dba {
if((! $this->db) || (! $this->connected))
return false;
$this->error = '';
if($this->mysqli)
$result = @$this->db->query($sql);
else
$result = @mysql_query($sql,$this->db);
if($this->mysqli) {
if($this->db->errno)
$this->error = $this->db->error;
}
elseif(mysql_errno($this->db))
$this->error = mysql_error($this->db);
if(strlen($this->error)) {
logger('dba: ' . $this->error);
}
if($this->debug) {
$mesg = '';
if($this->mysqli) {
if($this->db->errno)
logger('dba: ' . $this->db->error);
}
elseif(mysql_errno($this->db))
logger('dba: ' . mysql_error($this->db));
if($result === false)
$mesg = 'false';
elseif($result === true)
@ -102,7 +108,9 @@ class dba {
$mesg = mysql_num_rows($result) . ' results' . EOL;
}
$str = 'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg . EOL;
$str = 'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg
. (($this->error) ? ' error: ' . $this->error : '')
. EOL;
logger('dba: ' . $str );
}
@ -114,9 +122,9 @@ class dba {
*/
if($result === false) {
logger('dba: ' . printable($sql) . ' returned false.');
logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
if(file_exists('dbfail.out'))
file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n", FILE_APPEND);
file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
}
if(($result === true) || ($result === false))

View File

@ -38,153 +38,167 @@ function delivery_run($argv, $argc){
$cmd = $argv[1];
$item_id = intval($argv[2]);
$contact_id = intval($argv[3]);
// Some other process may have delivered this item already.
for($x = 3; $x < $argc; $x ++) {
$r = q("select * from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
dbesc($cmd),
dbesc($item_id),
dbesc($contact_id)
);
if(! count($r)) {
return;
}
$contact_id = intval($argv[x]);
// It's ours to deliver. Remove it from the queue.
// Some other process may have delivered this item already.
q("delete from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
dbesc($cmd),
dbesc($item_id),
dbesc($contact_id)
);
if((! $item_id) || (! $contact_id))
return;
$expire = false;
$top_level = false;
$recipients = array();
$url_recipients = array();
$normal_mode = true;
$recipients[] = $contact_id;
if($cmd === 'expire') {
$normal_mode = false;
$expire = true;
$items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP() - INTERVAL 30 MINUTE",
intval($item_id)
$r = q("select * from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
dbesc($cmd),
dbesc($item_id),
dbesc($contact_id)
);
$uid = $item_id;
$item_id = 0;
if(! count($items))
return;
}
else {
if(! count($r)) {
continue;
}
// find ancestors
$r = q("SELECT * FROM `item` WHERE `id` = %d and visible = 1 and moderated = 0 LIMIT 1",
intval($item_id)
);
if((! count($r)) || (! intval($r[0]['parent']))) {
return;
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)
$maxsysload = 50;
if(function_exists('sys_getloadavg')) {
$load = sys_getloadavg();
if(intval($load[0]) > $maxsysload) {
logger('system: load ' . $load . ' too high. Delivery deferred to next queue run.');
return;
}
}
$target_item = $r[0];
$parent_id = intval($r[0]['parent']);
$uid = $r[0]['uid'];
$updated = $r[0]['edited'];
// It's ours to deliver. Remove it from the queue.
if(! $parent_id)
return;
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d and visible = 1 and moderated = 0 ORDER BY `id` ASC",
intval($parent_id)
q("delete from deliverq where cmd = '%s' and item = %d and contact = %d limit 1",
dbesc($cmd),
dbesc($item_id),
dbesc($contact_id)
);
if(! count($items)) {
return;
}
if((! $item_id) || (! $contact_id))
continue;
$icontacts = null;
$contacts_arr = array();
foreach($items as $item)
if(! in_array($item['contact-id'],$contacts_arr))
$contacts_arr[] = intval($item['contact-id']);
if(count($contacts_arr)) {
$str_contacts = implode(',',$contacts_arr);
$icontacts = q("SELECT * FROM `contact`
WHERE `id` IN ( $str_contacts ) "
$expire = false;
$top_level = false;
$recipients = array();
$url_recipients = array();
$normal_mode = true;
$recipients[] = $contact_id;
if($cmd === 'expire') {
$normal_mode = false;
$expire = true;
$items = q("SELECT * FROM `item` WHERE `uid` = %d AND `wall` = 1
AND `deleted` = 1 AND `changed` > UTC_TIMESTAMP() - INTERVAL 30 MINUTE",
intval($item_id)
);
$uid = $item_id;
$item_id = 0;
if(! count($items))
continue;
}
if( ! ($icontacts && count($icontacts)))
return;
else {
// avoid race condition with deleting entries
// find ancestors
$r = q("SELECT * FROM `item` WHERE `id` = %d and visible = 1 and moderated = 0 LIMIT 1",
intval($item_id)
);
if($items[0]['deleted']) {
if((! count($r)) || (! intval($r[0]['parent']))) {
continue;
}
$target_item = $r[0];
$parent_id = intval($r[0]['parent']);
$uid = $r[0]['uid'];
$updated = $r[0]['edited'];
if(! $parent_id)
continue;
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
FROM `item` LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id` WHERE `parent` = %d and visible = 1 and moderated = 0 ORDER BY `id` ASC",
intval($parent_id)
);
if(! count($items)) {
continue;
}
$icontacts = null;
$contacts_arr = array();
foreach($items as $item)
$item['deleted'] = 1;
if(! in_array($item['contact-id'],$contacts_arr))
$contacts_arr[] = intval($item['contact-id']);
if(count($contacts_arr)) {
$str_contacts = implode(',',$contacts_arr);
$icontacts = q("SELECT * FROM `contact`
WHERE `id` IN ( $str_contacts ) "
);
}
if( ! ($icontacts && count($icontacts)))
continue;
// avoid race condition with deleting entries
if($items[0]['deleted']) {
foreach($items as $item)
$item['deleted'] = 1;
}
if((count($items) == 1) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
logger('delivery: top level post');
$top_level = true;
}
}
if((count($items) == 1) && ($items[0]['uri'] === $items[0]['parent-uri'])) {
logger('delivery: top level post');
$top_level = true;
}
}
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
`user`.`page-flags`, `user`.`prvnets`
FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
intval($uid)
);
$r = q("SELECT `contact`.*, `user`.`pubkey` AS `upubkey`, `user`.`prvkey` AS `uprvkey`,
`user`.`timezone`, `user`.`nickname`, `user`.`sprvkey`, `user`.`spubkey`,
`user`.`page-flags`, `user`.`prvnets`
FROM `contact` LEFT JOIN `user` ON `user`.`uid` = `contact`.`uid`
WHERE `contact`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
intval($uid)
);
if(! count($r))
continue;
if(! count($r))
return;
$owner = $r[0];
$owner = $r[0];
$walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
$walltowall = ((($top_level) && ($owner['id'] != $items[0]['contact-id'])) ? true : false);
$public_message = true;
$public_message = true;
// fill this in with a single salmon slap if applicable
// fill this in with a single salmon slap if applicable
$slap = '';
$slap = '';
require_once('include/group.php');
require_once('include/group.php');
$parent = $items[0];
$parent = $items[0];
// This is IMPORTANT!!!!
// This is IMPORTANT!!!!
// We will only send a "notify owner to relay" or followup message if the referenced post
// originated on our system by virtue of having our hostname somewhere
// in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
// if $parent['wall'] == 1 we will already have the parent message in our array
// and we will relay the whole lot.
// expire sends an entire group of expire messages and cannot be forwarded.
// However the conversation owner will be a part of the conversation and will
// be notified during this run.
// Other DFRN conversation members will be alerted during polled updates.
// We will only send a "notify owner to relay" or followup message if the referenced post
// originated on our system by virtue of having our hostname somewhere
// in the URI, AND it was a comment (not top_level) AND the parent originated elsewhere.
// if $parent['wall'] == 1 we will already have the parent message in our array
// and we will relay the whole lot.
// expire sends an entire group of expire messages and cannot be forwarded.
// However the conversation owner will be a part of the conversation and will
// be notified during this run.
// Other DFRN conversation members will be alerted during polled updates.
// Diaspora members currently are not notified of expirations, and other networks have
// either limited or no ability to process deletions. We should at least fix Diaspora
// by stringing togther an array of retractions and sending them onward.
// Diaspora members currently are not notified of expirations, and other networks have
// either limited or no ability to process deletions. We should at least fix Diaspora
// by stringing togther an array of retractions and sending them onward.
$localhost = $a->get_hostname();
if(strpos($localhost,':'))
$localhost = substr($localhost,0,strpos($localhost,':'));
$localhost = $a->get_hostname();
if(strpos($localhost,':'))
$localhost = substr($localhost,0,strpos($localhost,':'));
/**
*
@ -194,171 +208,71 @@ function delivery_run($argv, $argc){
*
*/
if((! $top_level) && ($parent['wall'] == 0) && (! $expire) && (stristr($target_item['uri'],$localhost))) {
logger('relay denied for delivery agent.');
if((! $top_level) && ($parent['wall'] == 0) && (! $expire) && (stristr($target_item['uri'],$localhost))) {
logger('relay denied for delivery agent.');
/* no relay allowed for direct contact delivery */
return;
}
/* no relay allowed for direct contact delivery */
continue;
}
if((strlen($parent['allow_cid']))
|| (strlen($parent['allow_gid']))
|| (strlen($parent['deny_cid']))
|| (strlen($parent['deny_gid']))) {
$public_message = false; // private recipients, not public
}
if((strlen($parent['allow_cid']))
|| (strlen($parent['allow_gid']))
|| (strlen($parent['deny_cid']))
|| (strlen($parent['deny_gid']))) {
$public_message = false; // private recipients, not public
}
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `blocked` = 0 AND `pending` = 0",
intval($contact_id)
);
$r = q("SELECT * FROM `contact` WHERE `id` = %d AND `blocked` = 0 AND `pending` = 0",
intval($contact_id)
);
if(count($r))
$contact = $r[0];
if(count($r))
$contact = $r[0];
$hubxml = feed_hublinks();
$hubxml = feed_hublinks();
logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA);
logger('notifier: slaps: ' . print_r($slaps,true), LOGGER_DATA);
require_once('include/salmon.php');
require_once('include/salmon.php');
if($contact['self'])
return;
if($contact['self'])
continue;
$deliver_status = 0;
$deliver_status = 0;
switch($contact['network']) {
switch($contact['network']) {
case NETWORK_DFRN :
logger('notifier: dfrndelivery: ' . $contact['name']);
case NETWORK_DFRN :
logger('notifier: dfrndelivery: ' . $contact['name']);
$feed_template = get_markup_template('atom_feed.tpl');
$mail_template = get_markup_template('atom_mail.tpl');
$feed_template = get_markup_template('atom_feed.tpl');
$mail_template = get_markup_template('atom_mail.tpl');
$atom = '';
$atom = '';
$birthday = feed_birthday($owner['uid'],$owner['timezone']);
$birthday = feed_birthday($owner['uid'],$owner['timezone']);
if(strlen($birthday))
$birthday = '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>';
if(strlen($birthday))
$birthday = '<dfrn:birthday>' . xmlify($birthday) . '</dfrn:birthday>';
$atom .= replace_macros($feed_template, array(
'$version' => xmlify(FRIENDICA_VERSION),
'$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ),
'$feed_title' => xmlify($owner['name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
'$hub' => $hubxml,
'$salmon' => '', // private feed, we don't use salmon here
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$photo' => xmlify($owner['photo']),
'$thumb' => xmlify($owner['thumb']),
'$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
'$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
'$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) ,
'$birthday' => $birthday,
'$community' => (($owner['page-flags'] == PAGE_COMMUNITY) ? '<dfrn:community>1</dfrn:community>' : '')
));
foreach($items as $item) {
if(! $item['parent'])
continue;
// private emails may be in included in public conversations. Filter them.
if(($public_message) && $item['private'])
continue;
$item_contact = get_item_contact($item,$icontacts);
if(! $item_contact)
continue;
if($normal_mode) {
if($item_id == $item['id'] || $item['id'] == $item['parent'])
$atom .= atom_entry($item,'text',null,$owner,true);
}
else
$atom .= atom_entry($item,'text',null,$owner,true);
}
$atom .= '</feed>' . "\r\n";
logger('notifier: ' . $atom, LOGGER_DATA);
$basepath = implode('/', array_slice(explode('/',$contact['url']),0,3));
// perform local delivery if we are on the same site
if(link_compare($basepath,$a->get_baseurl())) {
$nickname = basename($contact['url']);
if($contact['issued-id'])
$sql_extra = sprintf(" AND `dfrn-id` = '%s' ", dbesc($contact['issued-id']));
else
$sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($contact['dfrn-id']));
$x = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`,
`contact`.`pubkey` AS `cpubkey`,
`contact`.`prvkey` AS `cprvkey`,
`contact`.`thumb` AS `thumb`,
`contact`.`url` as `url`,
`contact`.`name` as `senderName`,
`user`.*
FROM `contact`
LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND `contact`.`network` = '%s' AND `user`.`nickname` = '%s'
$sql_extra
AND `user`.`account_expired` = 0 LIMIT 1",
dbesc(NETWORK_DFRN),
dbesc($nickname)
);
if(count($x)) {
if($owner['page-flags'] == PAGE_COMMUNITY && ! $x[0]['writable']) {
q("update contact set writable = 1 where id = %d limit 1",
intval($x[0]['id'])
);
$x[0]['writable'] = 1;
}
$ssl_policy = get_config('system','ssl_policy');
fix_contact_ssl_policy($x[0],$ssl_policy);
// If we are setup as a soapbox we aren't accepting input from this person
if($x[0]['page-flags'] == PAGE_SOAPBOX)
break;
require_once('library/simplepie/simplepie.inc');
logger('mod-delivery: local delivery');
local_delivery($x[0],$atom);
break;
}
}
$deliver_status = dfrn_deliver($owner,$contact,$atom);
logger('notifier: dfrn_delivery returns ' . $deliver_status);
if($deliver_status == (-1)) {
logger('notifier: delivery failed: queuing message');
add_to_queue($contact['id'],NETWORK_DFRN,$atom);
}
break;
case NETWORK_OSTATUS :
// Do not send to otatus 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'))
break;
// only send salmon if public - e.g. if it's ok to notify
// a public hub, it's ok to send a salmon
if(($public_message) && (! $expire)) {
$slaps = array();
$atom .= replace_macros($feed_template, array(
'$version' => xmlify(FRIENDICA_VERSION),
'$feed_id' => xmlify($a->get_baseurl() . '/profile/' . $owner['nickname'] ),
'$feed_title' => xmlify($owner['name']),
'$feed_updated' => xmlify(datetime_convert('UTC', 'UTC', $updated . '+00:00' , ATOM_TIME)) ,
'$hub' => $hubxml,
'$salmon' => '', // private feed, we don't use salmon here
'$name' => xmlify($owner['name']),
'$profile_page' => xmlify($owner['url']),
'$photo' => xmlify($owner['photo']),
'$thumb' => xmlify($owner['thumb']),
'$picdate' => xmlify(datetime_convert('UTC','UTC',$owner['avatar-date'] . '+00:00' , ATOM_TIME)) ,
'$uridate' => xmlify(datetime_convert('UTC','UTC',$owner['uri-date'] . '+00:00' , ATOM_TIME)) ,
'$namdate' => xmlify(datetime_convert('UTC','UTC',$owner['name-date'] . '+00:00' , ATOM_TIME)) ,
'$birthday' => $birthday,
'$community' => (($owner['page-flags'] == PAGE_COMMUNITY) ? '<dfrn:community>1</dfrn:community>' : '')
));
foreach($items as $item) {
if(! $item['parent'])
@ -372,152 +286,260 @@ function delivery_run($argv, $argc){
if(! $item_contact)
continue;
if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
$slaps[] = atom_entry($item,'html',null,$owner,true);
if($normal_mode) {
if($item_id == $item['id'] || $item['id'] == $item['parent'])
$atom .= atom_entry($item,'text',null,$owner,true);
}
else
$atom .= atom_entry($item,'text',null,$owner,true);
}
logger('notifier: slapdelivery: ' . $contact['name']);
foreach($slaps as $slappy) {
if($contact['notify']) {
$deliver_status = slapper($owner,$contact['notify'],$slappy);
if($deliver_status == (-1)) {
// queue message for redelivery
add_to_queue($contact['id'],NETWORK_OSTATUS,$slappy);
$atom .= '</feed>' . "\r\n";
logger('notifier: ' . $atom, LOGGER_DATA);
$basepath = implode('/', array_slice(explode('/',$contact['url']),0,3));
// perform local delivery if we are on the same site
if(link_compare($basepath,$a->get_baseurl())) {
$nickname = basename($contact['url']);
if($contact['issued-id'])
$sql_extra = sprintf(" AND `dfrn-id` = '%s' ", dbesc($contact['issued-id']));
else
$sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($contact['dfrn-id']));
$x = q("SELECT `contact`.*, `contact`.`uid` AS `importer_uid`,
`contact`.`pubkey` AS `cpubkey`,
`contact`.`prvkey` AS `cprvkey`,
`contact`.`thumb` AS `thumb`,
`contact`.`url` as `url`,
`contact`.`name` as `senderName`,
`user`.*
FROM `contact`
LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND `contact`.`network` = '%s' AND `user`.`nickname` = '%s'
$sql_extra
AND `user`.`account_expired` = 0 LIMIT 1",
dbesc(NETWORK_DFRN),
dbesc($nickname)
);
if(count($x)) {
if($owner['page-flags'] == PAGE_COMMUNITY && ! $x[0]['writable']) {
q("update contact set writable = 1 where id = %d limit 1",
intval($x[0]['id'])
);
$x[0]['writable'] = 1;
}
$ssl_policy = get_config('system','ssl_policy');
fix_contact_ssl_policy($x[0],$ssl_policy);
// If we are setup as a soapbox we aren't accepting input from this person
if($x[0]['page-flags'] == PAGE_SOAPBOX)
break;
require_once('library/simplepie/simplepie.inc');
logger('mod-delivery: local delivery');
local_delivery($x[0],$atom);
break;
}
}
if(! was_recently_delayed($contact['id']))
$deliver_status = dfrn_deliver($owner,$contact,$atom);
else
$deliver_status = (-1);
logger('notifier: dfrn_delivery returns ' . $deliver_status);
if($deliver_status == (-1)) {
logger('notifier: delivery failed: queuing message');
add_to_queue($contact['id'],NETWORK_DFRN,$atom);
}
break;
case NETWORK_OSTATUS :
// Do not send to otatus 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'))
break;
// only send salmon if public - e.g. if it's ok to notify
// a public hub, it's ok to send a salmon
if(($public_message) && (! $expire)) {
$slaps = array();
foreach($items as $item) {
if(! $item['parent'])
continue;
// private emails may be in included in public conversations. Filter them.
if(($public_message) && $item['private'])
continue;
$item_contact = get_item_contact($item,$icontacts);
if(! $item_contact)
continue;
if(($top_level) && ($public_message) && ($item['author-link'] === $item['owner-link']) && (! $expire))
$slaps[] = atom_entry($item,'html',null,$owner,true);
}
logger('notifier: slapdelivery: ' . $contact['name']);
foreach($slaps as $slappy) {
if($contact['notify']) {
if(! was_recently_delayed($contact['id']))
$deliver_status = slapper($owner,$contact['notify'],$slappy);
else
$deliver_status = (-1);
if($deliver_status == (-1)) {
// queue message for redelivery
add_to_queue($contact['id'],NETWORK_OSTATUS,$slappy);
}
}
}
}
}
break;
case NETWORK_MAIL :
case NETWORK_MAIL2:
if(get_config('system','dfrn_only'))
break;
// WARNING: does not currently convert to RFC2047 header encodings, etc.
$addr = $contact['addr'];
if(! strlen($addr))
break;
if($cmd === 'wall-new' || $cmd === 'comment-new') {
case NETWORK_MAIL :
case NETWORK_MAIL2:
$it = null;
if($cmd === 'wall-new')
$it = $items[0];
else {
$r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($argv[2]),
if(get_config('system','dfrn_only'))
break;
// WARNING: does not currently convert to RFC2047 header encodings, etc.
$addr = $contact['addr'];
if(! strlen($addr))
break;
if($cmd === 'wall-new' || $cmd === 'comment-new') {
$it = null;
if($cmd === 'wall-new')
$it = $items[0];
else {
$r = q("SELECT * FROM `item` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($argv[2]),
intval($uid)
);
if(count($r))
$it = $r[0];
}
if(! $it)
break;
$local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
intval($uid)
);
if(count($r))
$it = $r[0];
}
if(! $it)
break;
if(! count($local_user))
break;
$reply_to = '';
$r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
intval($uid)
);
if($r1 && $r1[0]['reply_to'])
$reply_to = $r1[0]['reply_to'];
$local_user = q("SELECT * FROM `user` WHERE `uid` = %d LIMIT 1",
intval($uid)
);
if(! count($local_user))
break;
$reply_to = '';
$r1 = q("SELECT * FROM `mailacct` WHERE `uid` = %d LIMIT 1",
intval($uid)
);
if($r1 && $r1[0]['reply_to'])
$reply_to = $r1[0]['reply_to'];
$subject = (($it['title']) ? email_header_encode($it['title'],'UTF-8') : t("\x28no subject\x29")) ;
$subject = (($it['title']) ? email_header_encode($it['title'],'UTF-8') : t("\x28no subject\x29")) ;
// only expose our real email address to true friends
// only expose our real email address to true friends
if(($contact['rel'] == CONTACT_IS_FRIEND) && (! $contact['blocked']))
$headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . $local_user[0]['email'] . '>' . "\n";
else
$headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . t('noreply') . '@' . $a->get_hostname() . '>' . "\n";
if(($contact['rel'] == CONTACT_IS_FRIEND) && (! $contact['blocked']))
$headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . $local_user[0]['email'] . '>' . "\n";
else
$headers = 'From: ' . email_header_encode($local_user[0]['username'],'UTF-8') . ' <' . t('noreply') . '@' . $a->get_hostname() . '>' . "\n";
if($reply_to)
$headers .= 'Reply-to: ' . $reply_to . "\n";
if($reply_to)
$headers .= 'Reply-to: ' . $reply_to . "\n";
// for testing purposes: Collect exported mails
// $file = tempnam("/tmp/friendica/", "mail-out-");
// file_put_contents($file, json_encode($it));
$headers .= 'Message-Id: <' . iri2msgid($it['uri']). '>' . "\n";
// for testing purposes: Collect exported mails
// $file = tempnam("/tmp/friendica/", "mail-out-");
// file_put_contents($file, json_encode($it));
//logger("Mail: uri: ".$it['uri']." parent-uri ".$it['parent-uri'], LOGGER_DEBUG);
//logger("Mail: Data: ".print_r($it, true), LOGGER_DEBUG);
//logger("Mail: Data: ".print_r($it, true), LOGGER_DATA);
$headers .= 'Message-Id: <' . iri2msgid($it['uri']). '>' . "\n";
if($it['uri'] !== $it['parent-uri']) {
$headers .= 'References: <' . iri2msgid($it['parent-uri']) . '>' . "\n";
if(!strlen($it['title'])) {
$r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1",
dbesc($it['parent-uri']));
//logger("Mail: uri: ".$it['uri']." parent-uri ".$it['parent-uri'], LOGGER_DEBUG);
//logger("Mail: Data: ".print_r($it, true), LOGGER_DEBUG);
//logger("Mail: Data: ".print_r($it, true), LOGGER_DATA);
if($it['uri'] !== $it['parent-uri']) {
$headers .= 'References: <' . iri2msgid($it['parent-uri']) . '>' . "\n";
if(!strlen($it['title'])) {
$r = q("SELECT `title` FROM `item` WHERE `parent-uri` = '%s' LIMIT 1",
dbesc($it['parent-uri']));
if(count($r) AND ($r[0]['title'] != ''))
$subject = $r[0]['title'];
if(count($r) AND ($r[0]['title'] != ''))
$subject = $r[0]['title'];
}
if(strncasecmp($subject,'RE:',3))
$subject = 'Re: '.$subject;
}
if(strncasecmp($subject,'RE:',3))
$subject = 'Re: '.$subject;
email_send($addr, $subject, $headers, $it);
}
email_send($addr, $subject, $headers, $it);
}
break;
case NETWORK_DIASPORA :
if($public_message)
$loc = 'public batch ' . $contact['batch'];
else
$loc = $contact['name'];
logger('delivery: diaspora batch deliver: ' . $loc);
if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode))
break;
if((! $contact['pubkey']) && (! $public_message))
case NETWORK_DIASPORA :
if($public_message)
$loc = 'public batch ' . $contact['batch'];
else
$loc = $contact['name'];
logger('delivery: diaspora batch deliver: ' . $loc);
if(get_config('system','dfrn_only') || (! get_config('system','diaspora_enabled')) || (! $normal_mode))
break;
if((! $contact['pubkey']) && (! $public_message))
break;
if($target_item['verb'] === ACTIVITY_DISLIKE) {
// unsupported
break;
}
elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
logger('delivery: diaspora retract: ' . $loc);
// diaspora delete,
diaspora_send_retraction($target_item,$owner,$contact,$public_message);
break;
}
elseif($target_item['parent'] != $target_item['id']) {
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;
}
elseif(($top_level) && (! $walltowall)) {
// currently no workable solution for sending walltowall
logger('delivery: diaspora status: ' . $loc);
diaspora_send_status($target_item,$owner,$contact,$public_message);
break;
}
logger('delivery: diaspora unknown mode: ' . $contact['name']);
break;
if($target_item['verb'] === ACTIVITY_DISLIKE) {
// unsupported
case NETWORK_FEED :
case NETWORK_FACEBOOK :
if(get_config('system','dfrn_only'))
break;
default:
break;
}
elseif(($target_item['deleted']) && ($target_item['verb'] !== ACTIVITY_LIKE)) {
logger('delivery: diaspora retract: ' . $loc);
// diaspora delete,
diaspora_send_retraction($target_item,$owner,$contact,$public_message);
break;
}
elseif($target_item['parent'] != $target_item['id']) {
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;
}
elseif(($top_level) && (! $walltowall)) {
// currently no workable solution for sending walltowall
logger('delivery: diaspora status: ' . $loc);
diaspora_send_status($target_item,$owner,$contact,$public_message);
break;
}
logger('delivery: diaspora unknown mode: ' . $contact['name']);
break;
case NETWORK_FEED :
case NETWORK_FACEBOOK :
if(get_config('system','dfrn_only'))
break;
default:
break;
}
}
return;

View File

@ -569,6 +569,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
@ -706,10 +714,10 @@ function diaspora_post($importer,$xml) {
continue;
$basetag = str_replace('_',' ',substr($tag,1));
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
@ -872,10 +880,10 @@ function diaspora_reshare($importer,$xml) {
$basetag = str_replace('_',' ',substr($tag,1));
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
@ -1113,10 +1121,10 @@ function diaspora_comment($importer,$xml,$msg) {
$basetag = str_replace('_',' ',substr($tag,1));
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
$body = str_replace($tag,'#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]',$body);
if(strlen($str_tags))
$str_tags .= ',';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
$str_tags .= '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
continue;
}
}
@ -1172,7 +1180,7 @@ function diaspora_comment($importer,$xml,$msg) {
proc_run('php','include/notifier.php','comment',$message_id);
}
$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0 ",
dbesc($parent_item['uri']),
intval($importer['uid'])
);
@ -2298,14 +2306,20 @@ function diaspora_transmit($owner,$contact,$slap,$public_batch) {
logger('diaspora_transmit: ' . $logid . ' ' . $dest_url);
if(! intval(get_config('system','diaspora_test')))
post_url($dest_url . '/', $slap);
else {
logger('diaspora_transmit: test_mode');
return 200;
if(was_recently_delayed($contact['id'])) {
$return_code = 0;
}
$return_code = $a->get_curl_code();
else {
if(! intval(get_config('system','diaspora_test'))) {
post_url($dest_url . '/', $slap);
$return_code = $a->get_curl_code();
}
else {
logger('diaspora_transmit: test_mode');
return 200;
}
}
logger('diaspora_transmit: ' . $logid . ' returns: ' . $return_code);
if((! $return_code) || (($return_code == 503) && (stristr($a->get_curl_headers(),'retry-after')))) {

View File

@ -402,8 +402,8 @@ class enotify {
*/
static public function send($params) {
$fromName = email_header_encode($params['fromName'],'UTF-8');
$messageSubject = email_header_encode($params['messageSubject'],'UTF-8');
$fromName = email_header_encode(html_entity_decode($params['fromName'],ENT_QUOTES,'UTF-8'),'UTF-8');
$messageSubject = email_header_encode(html_entity_decode($params['messageSubject'],ENT_QUOTES,'UTF-8'),'UTF-8');
// generate a mime boundary
$mimeBoundary =rand(0,9)."-"

View File

@ -32,7 +32,11 @@ function expire_run($argv, $argc){
// physically remove anything that has been deleted for more than two months
$r = q("delete from item where deleted = 1 and changed < UTC_TIMESTAMP() - INTERVAL 60 DAY");
q("optimize table item");
// make this optional as it could have a performance impact on large sites
if(intval(get_config('system','optimize_items')))
q("optimize table item");
logger('expire: start');

65
include/gprobe.php Normal file
View File

@ -0,0 +1,65 @@
<?php
require_once("boot.php");
require_once('include/Scrape.php');
require_once('include/socgraph.php');
function gprobe_run($argv, $argc){
global $a, $db;
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/session.php');
require_once('include/datetime.php');
load_config('config');
load_config('system');
$a->set_baseurl(get_config('system','url'));
load_hooks();
if($argc != 2)
return;
$url = hex2bin($argv[1]);
$r = q("select * from gcontact where nurl = '%s' limit 1",
dbesc(normalise_link($url))
);
if(! count($r)) {
$arr = probe_url($url);
if(count($arr) && x($arr,'network') && $arr['network'] === NETWORK_DFRN) {
q("insert into `gcontact` (`name`,`url`,`nurl`,`photo`)
values ( '%s', '%s', '%s', '%s') ",
dbesc($arr['name']),
dbesc($arr['url']),
dbesc(normalise_link($arr['url'])),
dbesc($arr['photo'])
);
}
$r = q("select * from gcontact where nurl = '%s' limit 1",
dbesc(normalise_link($url))
);
}
if(count($r))
poco_load(0,0,$r[0]['id'], str_replace('/profile/','/poco/',$r[0]['url']));
return;
}
if (array_search(__file__,get_included_files())===0){
gprobe_run($argv,$argc);
killme();
}

View File

@ -97,8 +97,9 @@ function group_rmv_member($uid,$name,$member) {
}
function group_add_member($uid,$name,$member) {
$gid = group_byname($uid,$name);
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) {

View File

@ -83,7 +83,7 @@ function collecturls($message) {
$urls = array();
foreach ($result as $treffer) {
// A list of some links that should be ignored
$list = array("/user/", "/tag/", "/group/", "/profile/", "/search?search=", "mailto:", "/u/", "/node/",
$list = array("/user/", "/tag/", "/group/", "/profile/", "/search?search=", "/search?tag=", "mailto:", "/u/", "/node/",
"//facebook.com/profile.php?id=", "//plus.google.com/");
foreach ($list as $listitem)
if (strpos($treffer[1], $listitem) !== false)

View File

@ -119,7 +119,7 @@ function get_feed_for(&$a, $dfrn_id, $owner_nick, $last_update, $direction = 0)
$check_date = datetime_convert('UTC','UTC',$last_update,'Y-m-d H:i:s');
$r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
`contact`.`name`, `contact`.`photo`, `contact`.`url`,
`contact`.`name`, `contact`.`network`, `contact`.`photo`, `contact`.`url`,
`contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,
`contact`.`thumb`, `contact`.`dfrn-id`, `contact`.`self`,
`contact`.`id` AS `contact-id`, `contact`.`uid` AS `contact-uid`,
@ -952,13 +952,15 @@ function tag_deliver($uid,$item_id) {
$mention = false;
$u = q("select uid, nickname, language, username, email, `page-flags`, `notify-flags` from user where uid = %d limit 1",
$u = q("select * from user where uid = %d limit 1",
intval($uid)
);
if(! count($u))
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 +1010,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
@ -1027,10 +1030,23 @@ function tag_deliver($uid,$item_id) {
if(! count($c))
return;
q("update item set wall = 1, origin = 1, forum_mode = 1, `owner-name` = '%s', `owner-link` = '%s', `owner-avatar` = '%s' where id = %d limit 1",
// also reset all the privacy bits to the forum default permissions
$private = ($u[0]['allow_cid'] || $u[0]['allow_gid'] || $u[0]['deny_cid'] || $u[0]['deny_gid']) ? 1 : 0;
$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']),
intval($private),
dbesc($u[0]['allow_cid']),
dbesc($u[0]['allow_gid']),
dbesc($u[0]['deny_cid']),
dbesc($u[0]['deny_gid']),
intval($item_id)
);
@ -2184,7 +2200,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');
@ -2211,8 +2227,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.
@ -2227,10 +2243,10 @@ function local_delivery($importer,$data) {
logger('local_delivery: received remote comment');
$is_like = false;
// remote reply to our post. Import and then notify everybody else.
$datarray = get_atom_elements($feed,$item);
$r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
$r = q("SELECT `id`, `uid`, `last-child`, `edited`, `body` FROM `item` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
dbesc($item_id),
intval($importer['importer_uid'])
);
@ -2266,14 +2282,22 @@ function local_delivery($importer,$data) {
// return 0;
// }
// our user with $importer['importer_uid'] is the owner
$own = q("select name,url,thumb from contact where uid = %d and self = 1 limit 1",
intval($importer['importer_uid'])
);
$datarray['type'] = 'remote-comment';
$datarray['wall'] = 1;
$datarray['parent-uri'] = $parent_uri;
$datarray['uid'] = $importer['importer_uid'];
$datarray['owner-name'] = $r[0]['name'];
$datarray['owner-link'] = $r[0]['url'];
$datarray['owner-avatar'] = $r[0]['thumb'];
$datarray['owner-name'] = $own[0]['name'];
$datarray['owner-link'] = $own[0]['url'];
$datarray['owner-avatar'] = $own[0]['thumb'];
$datarray['contact-id'] = $importer['id'];
if(($datarray['verb'] === ACTIVITY_LIKE) || ($datarray['verb'] === ACTIVITY_DISLIKE)) {
$is_like = true;
$datarray['type'] = 'activity';
@ -2290,26 +2314,34 @@ function local_delivery($importer,$data) {
}
if(($datarray['verb'] === ACTIVITY_TAG) && ($datarray['object-type'] === ACTIVITY_OBJ_TAGTERM)) {
$xo = parse_xml_string($datarray['object'],false);
$xt = parse_xml_string($datarray['target'],false);
if(($xt->type == ACTIVITY_OBJ_NOTE) && ($xt->id == $r[0]['uri'])) {
if(($xt->type == ACTIVITY_OBJ_NOTE) && ($xt->id)) {
// fetch the parent item
$tagp = q("select * from item where uri = '%s' and uid = %d limit 1",
dbesc($xt->id),
intval($importer['importer_uid'])
);
if(! count($tagp))
continue;
// extract tag, if not duplicate, and this user allows tags, add to parent item
if($xo->id && $xo->content) {
$newtag = '#[url=' . $xo->id . ']'. $xo->content . '[/url]';
if(! (stristr($r[0]['tag'],$newtag))) {
if(! (stristr($tagp[0]['tag'],$newtag))) {
$i = q("SELECT `blocktags` FROM `user` where `uid` = %d LIMIT 1",
intval($importer['importer_uid'])
);
if(count($i) && ! ($i[0]['blocktags'])) {
q("UPDATE item SET tag = '%s' WHERE id = %d LIMIT 1",
dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . $newtag),
intval($r[0]['id'])
if(count($i) && ! intval($i[0]['blocktags'])) {
q("UPDATE item SET tag = '%s', `edited` = '%s' WHERE id = %d LIMIT 1",
dbesc($tagp[0]['tag'] . (strlen($tagp[0]['tag']) ? ',' : '') . $newtag),
intval($tagp[0]['id']),
dbesc(datetime_convert())
);
}
}
@ -2479,7 +2511,7 @@ function local_delivery($importer,$data) {
if(!x($datarray['type']) || $datarray['type'] != 'activity') {
$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 ",
$myconv = q("SELECT `author-link`, `author-avatar`, `parent` FROM `item` WHERE `parent-uri` = '%s' AND `uid` = %d AND `parent` != 0 AND `deleted` = 0",
dbesc($parent_uri),
intval($importer['importer_uid'])
);
@ -2685,6 +2717,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(
@ -3013,32 +3051,7 @@ function item_expire($uid,$days) {
if($expire_items==0 && $item['type']!='note')
continue;
$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($item['id'])
);
$r = q("DELETE FROM item_id where iid in (select id from item where parent = %d) and uid = %d",
intval($item['id']),
intval($uid)
);
$r = q("DELETE FROM sign where iid in (select id from item where parent = %d) and uid = %d",
intval($item['id']),
intval($uid)
);
// kill the kids
$r = q("UPDATE `item` SET `deleted` = 1, `edited` = '%s', `changed` = '%s' WHERE `parent-uri` = '%s' AND `uid` = %d ",
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc($item['parent-uri']),
intval($item['uid'])
);
drop_item($item['id'],false);
}
proc_run('php',"include/notifier.php","expire","$uid");
@ -3100,6 +3113,25 @@ function drop_item($id,$interactive = true) {
intval($item['id'])
);
// clean up categories and tags so they don't end up as orphans
$matches = false;
$cnt = preg_match_all('/<(.*?)>/',$item['file'],$matches,PREG_SET_ORDER);
if($cnt) {
foreach($matches as $mtch) {
file_tag_unsave_file($item['uid'],$item['id'],$mtch[1],true);
}
}
$matches = false;
$cnt = preg_match_all('/\[(.*?)\]/',$item['file'],$matches,PREG_SET_ORDER);
if($cnt) {
foreach($matches as $mtch) {
file_tag_unsave_file($item['uid'],$item['id'],$mtch[1],false);
}
}
// If item is a link to a photo resource, nuke all the associated photos
// (visitors will not have photo resources)
// This only applies to photos uploaded from the photos page. Photos inserted into a post do not
@ -3123,6 +3155,17 @@ function drop_item($id,$interactive = true) {
// ignore the result
}
// clean up item_id and sign meta-data tables
$r = q("DELETE FROM item_id where iid in (select id from item where parent = %d and uid = %d)",
intval($item['id']),
intval($item['uid'])
);
$r = q("DELETE FROM sign where iid in (select id from item where parent = %d and uid = %d)",
intval($item['id']),
intval($item['uid'])
);
// If it's the parent of a comment thread, kill all the kids
@ -3155,7 +3198,7 @@ function drop_item($id,$interactive = true) {
}
}
$drop_id = intval($item['id']);
// send the notification upstream/downstream as the case may be
if(! $interactive)

View File

@ -583,7 +583,7 @@ function fetch_xrd_links($url) {
// Take a URL from the wild, prepend http:// if necessary
// and check DNS to see if it's real
// and check DNS to see if it's real (or check if is a valid IP address)
// return true if it's OK, false if something is wrong with it
if(! function_exists('validate_url')) {
@ -596,7 +596,7 @@ function validate_url(&$url) {
$url = 'http://' . $url;
$h = @parse_url($url);
if(($h) && (dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR))) {
if(($h) && (dns_get_record($h['host'], DNS_A + DNS_CNAME + DNS_PTR) || filter_var($h['host'], FILTER_VALIDATE_IP) )) {
return true;
}
return false;
@ -611,7 +611,7 @@ function validate_email($addr) {
return false;
$h = substr($addr,strpos($addr,'@') + 1);
if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX))) {
if(($h) && (dns_get_record($h, DNS_A + DNS_CNAME + DNS_PTR + DNS_MX) || filter_var($h['host'], FILTER_VALIDATE_IP) )) {
return true;
}
return false;
@ -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);
}

View File

@ -47,7 +47,7 @@ function notifier_run($argv, $argc){
$a->set_baseurl(get_config('system','url'));
logger('notifier: invoked: ' . print_r($argv,true));
logger('notifier: invoked: ' . print_r($argv,true), LOGGER_DEBUG);
$cmd = $argv[1];
@ -220,7 +220,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 +265,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);
}
@ -304,7 +304,7 @@ function notifier_run($argv, $argc){
$conversant_str = dbesc(implode(', ',$conversants));
}
$r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0");
$r = q("SELECT * FROM `contact` WHERE `id` IN ( $conversant_str ) AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0");
if(count($r))
$contacts = $r;
@ -478,6 +478,12 @@ function notifier_run($argv, $argc){
}
}
$deliveries_per_process = intval(get_config('system','delivery_batch_count'));
if($deliveries_per_process <= 0)
$deliveries_per_process = 1;
$this_batch = array();
foreach($r as $contact) {
if($contact['self'])
continue;
@ -486,6 +492,7 @@ function notifier_run($argv, $argc){
// we will deliver single recipient types of message and email receipients here.
if((! $mail) && (! $fsuggest) && (! $followup)) {
// deliveries per process not yet implemented, 1 delivery per process.
proc_run('php','include/delivery.php',$cmd,$item_id,$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
@ -520,7 +527,8 @@ function notifier_run($argv, $argc){
`user`.*
FROM `contact`
LEFT JOIN `user` ON `contact`.`uid` = `user`.`uid`
WHERE `contact`.`blocked` = 0 AND `contact`.`pending` = 0
WHERE `contact`.`blocked` = 0 AND `contact`.`archive` = 0
AND `contact`.`pending` = 0
AND `contact`.`network` = '%s' AND `user`.`nickname` = '%s'
$sql_extra
AND `user`.`account_expired` = 0 LIMIT 1",
@ -769,7 +777,7 @@ function notifier_run($argv, $argc){
);
$r2 = q("SELECT `id`, `name`,`network` FROM `contact`
WHERE `network` in ( '%s', '%s') AND `uid` = %d AND `blocked` = 0 AND `pending` = 0
WHERE `network` in ( '%s', '%s') AND `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
AND `rel` != %d order by rand() ",
dbesc(NETWORK_DFRN),
dbesc(NETWORK_MAIL2),
@ -832,6 +840,8 @@ function notifier_run($argv, $argc){
}
logger('notifier: calling hooks', LOGGER_DEBUG);
if($normal_mode)
call_hooks('notifier_normal',$target_item);

523
include/onepoll.php Normal file
View File

@ -0,0 +1,523 @@
<?php
require_once("boot.php");
function onepoll_run($argv, $argc){
global $a, $db;
if(is_null($a)) {
$a = new App;
}
if(is_null($db)) {
@include(".htconfig.php");
require_once("dba.php");
$db = new dba($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
};
require_once('include/session.php');
require_once('include/datetime.php');
require_once('library/simplepie/simplepie.inc');
require_once('include/items.php');
require_once('include/Contact.php');
require_once('include/email.php');
require_once('include/socgraph.php');
require_once('include/pidfile.php');
require_once('include/queue_fn.php');
load_config('config');
load_config('system');
$a->set_baseurl(get_config('system','url'));
load_hooks();
logger('onepoll: start');
$abandon_days = intval(get_config('system','account_abandon_days'));
if($abandon_days < 1)
$abandon_days = 0;
$manual_id = 0;
$generation = 0;
$hub_update = false;
$force = false;
$restart = false;
if(($argc > 1) && (intval($argv[1])))
$contact_id = intval($argv[1]);
if(! $contact_id) {
logger('onepoll: no contact');
return;
}
if(was_recently_delayed($contact_id))
return;
$d = datetime_convert();
// Only poll from those with suitable relationships,
// and which have a polling address and ignore Diaspora since
// we are unable to match those posts with a Diaspora GUID and prevent duplicates.
$abandon_sql = (($abandon_days)
? sprintf(" AND `user`.`login_date` > UTC_TIMESTAMP() - INTERVAL %d DAY ", intval($abandon_days))
: ''
);
$contacts = q("SELECT `contact`.* FROM `contact`
WHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''
AND NOT `network` IN ( '%s', '%s' )
AND `contact`.`id` = %d
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
AND `contact`.`archive` = 0 LIMIT 1",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
dbesc(NETWORK_DIASPORA),
dbesc(NETWORK_FACEBOOK),
intval($contact_id)
);
if(! count($contacts)) {
return;
}
$contact = $contacts[0];
$xml = false;
$t = $contact['last-update'];
if($contact['subhub']) {
$interval = get_config('system','pushpoll_frequency');
$contact['priority'] = (($interval !== false) ? intval($interval) : 3);
$hub_update = false;
if(datetime_convert('UTC','UTC', 'now') > datetime_convert('UTC','UTC', $t . " + 1 day"))
$hub_update = true;
}
else
$hub_update = false;
$importer_uid = $contact['uid'];
$r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` LEFT JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
intval($importer_uid)
);
if(! count($r))
return;
$importer = $r[0];
logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
$last_update = (($contact['last-update'] === '0000-00-00 00:00:00')
? datetime_convert('UTC','UTC','now - 7 days', ATOM_TIME)
: datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME)
);
if($contact['network'] === NETWORK_DFRN) {
$idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
if(intval($contact['duplex']) && $contact['dfrn-id'])
$idtosend = '0:' . $orig_id;
if(intval($contact['duplex']) && $contact['issued-id'])
$idtosend = '1:' . $orig_id;
// they have permission to write to us. We already filtered this in the contact query.
$perm = 'rw';
$url = $contact['poll'] . '?dfrn_id=' . $idtosend
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION
. '&type=data&last_update=' . $last_update
. '&perm=' . $perm ;
$handshake_xml = fetch_url($url);
logger('onepoll: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA);
if(! $handshake_xml) {
logger("poller: $url appears to be dead - marking for death ");
// dead connection - might be a transient event, or this might
// mean the software was uninstalled or the domain expired.
// Will keep trying for one month.
mark_for_death($contact);
// set the last-update so we don't keep polling
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
return;
}
if(! strstr($handshake_xml,'<?xml')) {
logger('poller: response from ' . $url . ' did not contain XML.');
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
return;
}
$res = parse_xml_string($handshake_xml);
if(intval($res->status) == 1) {
logger("poller: $url replied status 1 - marking for death ");
// we may not be friends anymore. Will keep trying for one month.
// set the last-update so we don't keep polling
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
mark_for_death($contact);
}
else {
if($contact['term-date'] != '0000-00-00 00:00:00') {
logger("poller: $url back from the dead - removing mark for death");
unmark_for_death($contact);
}
}
if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
return;
if(((float) $res->dfrn_version > 2.21) && ($contact['poco'] == '')) {
q("update contact set poco = '%s' where id = %d limit 1",
dbesc(str_replace('/profile/','/poco/', $contact['url'])),
intval($contact['id'])
);
}
$postvars = array();
$sent_dfrn_id = hex2bin((string) $res->dfrn_id);
$challenge = hex2bin((string) $res->challenge);
$final_dfrn_id = '';
if(($contact['duplex']) && strlen($contact['prvkey'])) {
openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
}
else {
openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
}
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if(strpos($final_dfrn_id,':') == 1)
$final_dfrn_id = substr($final_dfrn_id,2);
if($final_dfrn_id != $orig_id) {
logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id);
// did not decode properly - cannot trust this site
return;
}
$postvars['dfrn_id'] = $idtosend;
$postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
$postvars['perm'] = 'rw';
$xml = post_url($contact['poll'],$postvars);
}
elseif(($contact['network'] === NETWORK_OSTATUS)
|| ($contact['network'] === NETWORK_DIASPORA)
|| ($contact['network'] === NETWORK_FEED) ) {
// Upgrading DB fields from an older Friendica version
// Will only do this once per notify-enabled OStatus contact
// or if relationship changes
$stat_writeable = ((($contact['notify']) && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND)) ? 1 : 0);
if($stat_writeable != $contact['writable']) {
q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1",
intval($stat_writeable),
intval($contact['id'])
);
}
// Are we allowed to import from this person?
if($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly'])
return;
$xml = fetch_url($contact['poll']);
}
elseif($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) {
logger("onepoll: mail: Fetching", LOGGER_DEBUG);
$mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
if($mail_disabled)
return;
logger("onepoll: Mail: Enabled", LOGGER_DEBUG);
$mbox = null;
$x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
intval($importer_uid)
);
$mailconf = q("SELECT * FROM `mailacct` WHERE `server` != '' AND `uid` = %d LIMIT 1",
intval($importer_uid)
);
if(count($x) && count($mailconf)) {
$mailbox = construct_mailbox_name($mailconf[0]);
$password = '';
openssl_private_decrypt(hex2bin($mailconf[0]['pass']),$password,$x[0]['prvkey']);
$mbox = email_connect($mailbox,$mailconf[0]['user'],$password);
unset($password);
logger("Mail: Connect");
if($mbox) {
q("UPDATE `mailacct` SET `last_check` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($mailconf[0]['id']),
intval($importer_uid)
);
}
}
if($mbox) {
$msgs = email_poll($mbox,$contact['addr']);
if(count($msgs)) {
logger("Mail: Parsing ".count($msgs)." mails.", LOGGER_DEBUG);
foreach($msgs as $msg_uid) {
logger("Mail: Parsing mail ".$msg_uid, LOGGER_DATA);
$datarray = array();
$meta = email_msg_meta($mbox,$msg_uid);
$headers = email_msg_headers($mbox,$msg_uid);
// look for a 'references' header and try and match with a parent item we have locally.
$raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : '');
$datarray['uri'] = msgid2iri(trim($meta->message_id,'<>'));
if($raw_refs) {
$refs_arr = explode(' ', $raw_refs);
if(count($refs_arr)) {
for($x = 0; $x < count($refs_arr); $x ++)
$refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'";
}
$qstr = implode(',',$refs_arr);
$r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
intval($importer_uid)
);
if(count($r))
$datarray['parent-uri'] = $r[0]['uri'];
}
if(! x($datarray,'parent-uri'))
$datarray['parent-uri'] = $datarray['uri'];
// Have we seen it before?
$r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1",
intval($importer_uid),
dbesc($datarray['uri'])
);
if(count($r)) {
// logger("Mail: Seen before ".$msg_uid);
if($meta->deleted && ! $r[0]['deleted']) {
q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($r[0]['id'])
);
}
switch ($mailconf[0]['action']) {
case 0:
break;
case 1:
logger("Mail: Deleting ".$msg_uid);
imap_delete($mbox, $msg_uid, FT_UID);
break;
case 2:
logger("Mail: Mark as seen ".$msg_uid);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
break;
case 3:
logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
if ($mailconf[0]['movetofolder'] != "")
imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
break;
}
continue;
}
// Decoding the header
$subject = imap_mime_header_decode($meta->subject);
$datarray['title'] = "";
foreach($subject as $subpart)
if ($subpart->charset != "default")
$datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text);
else
$datarray['title'] .= $subpart->text;
$datarray['title'] = notags(trim($datarray['title']));
//$datarray['title'] = notags(trim($meta->subject));
$datarray['created'] = datetime_convert('UTC','UTC',$meta->date);
// Is it reply?
$reply = ((substr(strtolower($datarray['title']), 0, 3) == "re:") or
(substr(strtolower($datarray['title']), 0, 3) == "re-") or
(raw_refs != ""));
$r = email_get_msg($mbox,$msg_uid, $reply);
if(! $r) {
logger("Mail: can't fetch msg ".$msg_uid);
continue;
}
$datarray['body'] = escape_tags($r['body']);
logger("Mail: Importing ".$msg_uid);
// some mailing lists have the original author as 'from' - add this sender info to msg body.
// todo: adding a gravatar for the original author would be cool
if(! stristr($meta->from,$contact['addr'])) {
$from = imap_mime_header_decode($meta->from);
$fromdecoded = "";
foreach($from as $frompart)
if ($frompart->charset != "default")
$fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text);
else
$fromdecoded .= $frompart->text;
$datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body'];
}
$datarray['uid'] = $importer_uid;
$datarray['contact-id'] = $contact['id'];
if($datarray['parent-uri'] === $datarray['uri'])
$datarray['private'] = 1;
if(($contact['network'] === NETWORK_MAIL) && (! get_pconfig($importer_uid,'system','allow_public_email_replies'))) {
$datarray['private'] = 1;
$datarray['allow_cid'] = '<' . $contact['id'] . '>';
}
$datarray['author-name'] = $contact['name'];
$datarray['author-link'] = 'mailbox';
$datarray['author-avatar'] = $contact['photo'];
$stored_item = item_store($datarray);
q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d",
dbesc($datarray['parent-uri']),
intval($importer_uid)
);
q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1",
intval($stored_item)
);
switch ($mailconf[0]['action']) {
case 0:
break;
case 1:
logger("Mail: Deleting ".$msg_uid);
imap_delete($mbox, $msg_uid, FT_UID);
break;
case 2:
logger("Mail: Mark as seen ".$msg_uid);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
break;
case 3:
logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
if ($mailconf[0]['movetofolder'] != "")
imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
break;
}
}
}
imap_close($mbox);
}
}
elseif($contact['network'] === NETWORK_FACEBOOK) {
// This is picked up by the Facebook plugin on a cron hook.
// Ignored here.
}
if($xml) {
logger('poller: received xml : ' . $xml, LOGGER_DATA);
if((! strstr($xml,'<?xml')) && (! strstr($xml,'<rss'))) {
logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
return;
}
consume_feed($xml,$importer,$contact,$hub,1,1);
// do it twice. Ensures that children of parents which may be later in the stream aren't tossed
consume_feed($xml,$importer,$contact,$hub,1,2);
$hubmode = 'subscribe';
if($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly'])
$hubmode = 'unsubscribe';
if((strlen($hub)) && ($hub_update) && ($contact['rel'] != CONTACT_IS_FOLLOWER)) {
logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
$hubs = explode(',', $hub);
if(count($hubs)) {
foreach($hubs as $h) {
$h = trim($h);
if(! strlen($h))
continue;
subscribe_to_hub($h,$importer,$contact,$hubmode);
}
}
}
}
$updated = datetime_convert();
$r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc($updated),
dbesc($updated),
intval($contact['id'])
);
// load current friends if possible.
if($contact['poco']) {
$r = q("SELECT count(*) as total from glink
where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
intval($contact['id'])
);
}
if(count($r)) {
if(! $r[0]['total']) {
poco_load($contact['id'],$importer_uid,0,$contact['poco']);
}
}
return;
}
if (array_search(__file__,get_included_files())===0){
onepoll_run($argv,$argc);
killme();
}

View File

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

View File

@ -5,7 +5,7 @@
if (! function_exists('uninstall_plugin')){
function uninstall_plugin($plugin){
logger("Addons: uninstalling " . $plugin);
q("DELETE FROM `addon` WHERE `name` = '%s' LIMIT 1",
q("DELETE FROM `addon` WHERE `name` = '%s' ",
dbesc($plugin)
);
@ -37,6 +37,16 @@ function install_plugin($plugin) {
intval($t),
$plugin_admin
);
// we can add the following with the previous SQL
// once most site tables have been updated.
// This way the system won't fall over dead during the update.
if(file_exists('addon/' . $plugin . '/.hidden')) {
q("update addon set hidden = 1 where name = '%s' limit 1",
dbesc($plugin)
);
}
return true;
}
else {
@ -60,8 +70,10 @@ function reload_plugins() {
$installed = array();
$parr = explode(',',$plugins);
if(count($parr)) {
foreach($parr as $pl) {
$pl = trim($pl);
$fname = 'addon/' . $pl . '/' . $pl . '.php';
@ -91,6 +103,7 @@ function reload_plugins() {
}
}
}
}}
@ -153,6 +166,14 @@ function call_hooks($name, &$data = null) {
$func = $hook[HOOK_FUNCTION];
$func($a,$data);
}
else {
// remove orphan hooks
q("delete from hook where hook = '%s' and file = '$s' and function = '%s' limit 1",
dbesc($hook[HOOK_HOOK]),
dbesc($hook[HOOK_FILE]),
dbesc($hook[HOOK_FUNCTION])
);
}
}
}
}

View File

@ -30,6 +30,17 @@ function poller_run($argv, $argc){
load_config('config');
load_config('system');
$maxsysload = intval(get_config('system','maxloadavg'));
if($maxsysload < 1)
$maxsysload = 50;
if(function_exists('sys_getloadavg')) {
$load = sys_getloadavg();
if(intval($load[0]) > $maxsysload) {
logger('system: load ' . $load . ' too high. Poller deferred to next scheduled run.');
return;
}
}
$lockpath = get_config('system','lockpath');
if ($lockpath != '') {
$pidfile = new pidfile($lockpath, 'poller.lck');
@ -39,6 +50,8 @@ function poller_run($argv, $argc){
}
}
$a->set_baseurl(get_config('system','url'));
load_hooks();
@ -113,6 +126,10 @@ function poller_run($argv, $argc){
$force = true;
}
$interval = intval(get_config('system','poll_interval'));
if(! $interval)
$interval = ((get_config('system','delivery_interval') === false) ? 3 : intval(get_config('system','delivery_interval')));
$sql_extra = (($manual_id) ? " AND `id` = $manual_id " : "");
reload_plugins();
@ -136,6 +153,7 @@ function poller_run($argv, $argc){
AND NOT `network` IN ( '%s', '%s' )
$sql_extra
AND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0
AND `contact`.`archive` = 0
AND `user`.`account_expired` = 0 $abandon_sql ORDER BY RAND()",
intval(CONTACT_IS_SHARING),
intval(CONTACT_IS_FRIEND),
@ -224,440 +242,12 @@ function poller_run($argv, $argc){
continue;
}
// Check to see if we are running out of memory - if so spawn a new process and kill this one
$avail_memory = return_bytes(ini_get('memory_limit'));
$memused = memory_get_peak_usage(true);
if(intval($avail_memory)) {
if(($memused / $avail_memory) > 0.95) {
if($generation + 1 > 10) {
logger('poller: maximum number of spawns exceeded. Terminating.');
killme();
}
logger('poller: memory exceeded. ' . $memused . ' bytes used. Spawning new poll.');
proc_run('php', 'include/poller.php', 'restart', (string) $generation + 1);
killme();
}
}
$importer_uid = $contact['uid'];
$r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` LEFT JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1",
intval($importer_uid)
);
if(! count($r))
continue;
$importer = $r[0];
logger("poller: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}");
$last_update = (($contact['last-update'] === '0000-00-00 00:00:00')
? datetime_convert('UTC','UTC','now - 30 days', ATOM_TIME)
: datetime_convert('UTC','UTC',$contact['last-update'], ATOM_TIME)
);
if($contact['network'] === NETWORK_DFRN) {
$idtosend = $orig_id = (($contact['dfrn-id']) ? $contact['dfrn-id'] : $contact['issued-id']);
if(intval($contact['duplex']) && $contact['dfrn-id'])
$idtosend = '0:' . $orig_id;
if(intval($contact['duplex']) && $contact['issued-id'])
$idtosend = '1:' . $orig_id;
// they have permission to write to us. We already filtered this in the contact query.
$perm = 'rw';
$url = $contact['poll'] . '?dfrn_id=' . $idtosend
. '&dfrn_version=' . DFRN_PROTOCOL_VERSION
. '&type=data&last_update=' . $last_update
. '&perm=' . $perm ;
$handshake_xml = fetch_url($url);
logger('poller: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA);
if(! $handshake_xml) {
logger("poller: $url appears to be dead - marking for death ");
// dead connection - might be a transient event, or this might
// mean the software was uninstalled or the domain expired.
// Will keep trying for one month.
mark_for_death($contact);
// set the last-update so we don't keep polling
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
continue;
}
if(! strstr($handshake_xml,'<?xml')) {
logger('poller: response from ' . $url . ' did not contain XML.');
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
continue;
}
$res = parse_xml_string($handshake_xml);
if(intval($res->status) == 1) {
logger("poller: $url replied status 1 - marking for death ");
// we may not be friends anymore. Will keep trying for one month.
// set the last-update so we don't keep polling
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
mark_for_death($contact);
}
else {
if($contact['term-date'] != '0000-00-00 00:00:00') {
logger("poller: $url back from the dead - removing mark for death");
unmark_for_death($contact);
}
}
if((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id)))
continue;
if(((float) $res->dfrn_version > 2.21) && ($contact['poco'] == '')) {
q("update contact set poco = '%s' where id = %d limit 1",
dbesc(str_replace('/profile/','/poco/', $contact['url'])),
intval($contact['id'])
);
}
$postvars = array();
$sent_dfrn_id = hex2bin((string) $res->dfrn_id);
$challenge = hex2bin((string) $res->challenge);
$final_dfrn_id = '';
if(($contact['duplex']) && strlen($contact['prvkey'])) {
openssl_private_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['prvkey']);
openssl_private_decrypt($challenge,$postvars['challenge'],$contact['prvkey']);
}
else {
openssl_public_decrypt($sent_dfrn_id,$final_dfrn_id,$contact['pubkey']);
openssl_public_decrypt($challenge,$postvars['challenge'],$contact['pubkey']);
}
$final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
if(strpos($final_dfrn_id,':') == 1)
$final_dfrn_id = substr($final_dfrn_id,2);
if($final_dfrn_id != $orig_id) {
logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id);
// did not decode properly - cannot trust this site
continue;
}
$postvars['dfrn_id'] = $idtosend;
$postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION;
$postvars['perm'] = 'rw';
$xml = post_url($contact['poll'],$postvars);
}
elseif(($contact['network'] === NETWORK_OSTATUS)
|| ($contact['network'] === NETWORK_DIASPORA)
|| ($contact['network'] === NETWORK_FEED) ) {
// Upgrading DB fields from an older Friendica version
// Will only do this once per notify-enabled OStatus contact
// or if relationship changes
$stat_writeable = ((($contact['notify']) && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND)) ? 1 : 0);
if($stat_writeable != $contact['writable']) {
q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1",
intval($stat_writeable),
intval($contact['id'])
);
}
// Are we allowed to import from this person?
if($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly'])
continue;
$xml = fetch_url($contact['poll']);
}
elseif($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) {
logger("Mail: Fetching");
$mail_disabled = ((function_exists('imap_open') && (! get_config('system','imap_disabled'))) ? 0 : 1);
if($mail_disabled)
continue;
logger("Mail: Enabled");
$mbox = null;
$x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1",
intval($importer_uid)
);
$mailconf = q("SELECT * FROM `mailacct` WHERE `server` != '' AND `uid` = %d LIMIT 1",
intval($importer_uid)
);
if(count($x) && count($mailconf)) {
$mailbox = construct_mailbox_name($mailconf[0]);
$password = '';
openssl_private_decrypt(hex2bin($mailconf[0]['pass']),$password,$x[0]['prvkey']);
$mbox = email_connect($mailbox,$mailconf[0]['user'],$password);
unset($password);
logger("Mail: Connect");
if($mbox) {
q("UPDATE `mailacct` SET `last_check` = '%s' WHERE `id` = %d AND `uid` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($mailconf[0]['id']),
intval($importer_uid)
);
}
}
if($mbox) {
logger("Mail: mbox");
$msgs = email_poll($mbox,$contact['addr']);
if(count($msgs)) {
logger("Mail: Parsing ".count($msgs)." mails.");
foreach($msgs as $msg_uid) {
logger("Mail: Parsing mail ".$msg_uid);
$datarray = array();
$meta = email_msg_meta($mbox,$msg_uid);
$headers = email_msg_headers($mbox,$msg_uid);
// look for a 'references' header and try and match with a parent item we have locally.
$raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : '');
$datarray['uri'] = msgid2iri(trim($meta->message_id,'<>'));
if($raw_refs) {
$refs_arr = explode(' ', $raw_refs);
if(count($refs_arr)) {
for($x = 0; $x < count($refs_arr); $x ++)
$refs_arr[$x] = "'" . msgid2iri(str_replace(array('<','>',' '),array('','',''),dbesc($refs_arr[$x]))) . "'";
}
$qstr = implode(',',$refs_arr);
$r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( $qstr ) AND `uid` = %d LIMIT 1",
intval($importer_uid)
);
if(count($r))
$datarray['parent-uri'] = $r[0]['uri'];
}
if(! x($datarray,'parent-uri'))
$datarray['parent-uri'] = $datarray['uri'];
// Have we seen it before?
$r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1",
intval($importer_uid),
dbesc($datarray['uri'])
);
if(count($r)) {
logger("Mail: Seen before ".$msg_uid);
if($meta->deleted && ! $r[0]['deleted']) {
q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($r[0]['id'])
);
}
switch ($mailconf[0]['action']) {
case 0:
break;
case 1:
logger("Mail: Deleting ".$msg_uid);
imap_delete($mbox, $msg_uid, FT_UID);
break;
case 2:
logger("Mail: Mark as seen ".$msg_uid);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
break;
case 3:
logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
if ($mailconf[0]['movetofolder'] != "")
imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
break;
}
continue;
}
// Decoding the header
$subject = imap_mime_header_decode($meta->subject);
$datarray['title'] = "";
foreach($subject as $subpart)
if ($subpart->charset != "default")
$datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text);
else
$datarray['title'] .= $subpart->text;
$datarray['title'] = notags(trim($datarray['title']));
//$datarray['title'] = notags(trim($meta->subject));
$datarray['created'] = datetime_convert('UTC','UTC',$meta->date);
// Is it reply?
$reply = ((substr(strtolower($datarray['title']), 0, 3) == "re:") or
(substr(strtolower($datarray['title']), 0, 3) == "re-") or
(raw_refs != ""));
$r = email_get_msg($mbox,$msg_uid, $reply);
if(! $r) {
logger("Mail: can't fetch msg ".$msg_uid);
continue;
}
$datarray['body'] = escape_tags($r['body']);
logger("Mail: Importing ".$msg_uid);
// some mailing lists have the original author as 'from' - add this sender info to msg body.
// todo: adding a gravatar for the original author would be cool
if(! stristr($meta->from,$contact['addr'])) {
$from = imap_mime_header_decode($meta->from);
$fromdecoded = "";
foreach($from as $frompart)
if ($frompart->charset != "default")
$fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text);
else
$fromdecoded .= $frompart->text;
$datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body'];
}
$datarray['uid'] = $importer_uid;
$datarray['contact-id'] = $contact['id'];
if($datarray['parent-uri'] === $datarray['uri'])
$datarray['private'] = 1;
if(($contact['network'] === NETWORK_MAIL) && (! get_pconfig($importer_uid,'system','allow_public_email_replies'))) {
$datarray['private'] = 1;
$datarray['allow_cid'] = '<' . $contact['id'] . '>';
}
$datarray['author-name'] = $contact['name'];
$datarray['author-link'] = 'mailbox';
$datarray['author-avatar'] = $contact['photo'];
$stored_item = item_store($datarray);
q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d",
dbesc($datarray['parent-uri']),
intval($importer_uid)
);
q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d LIMIT 1",
intval($stored_item)
);
switch ($mailconf[0]['action']) {
case 0:
break;
case 1:
logger("Mail: Deleting ".$msg_uid);
imap_delete($mbox, $msg_uid, FT_UID);
break;
case 2:
logger("Mail: Mark as seen ".$msg_uid);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
break;
case 3:
logger("Mail: Moving ".$msg_uid." to ".$mailconf[0]['movetofolder']);
imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID);
if ($mailconf[0]['movetofolder'] != "")
imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID);
break;
}
}
}
imap_close($mbox);
}
}
elseif($contact['network'] === NETWORK_FACEBOOK) {
// This is picked up by the Facebook plugin on a cron hook.
// Ignored here.
}
if($xml) {
logger('poller: received xml : ' . $xml, LOGGER_DATA);
if(! strstr($xml,'<?xml')) {
logger('poller: post_handshake: response from ' . $url . ' did not contain XML.');
$r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc(datetime_convert()),
intval($contact['id'])
);
continue;
}
consume_feed($xml,$importer,$contact,$hub,1,1);
// do it twice. Ensures that children of parents which may be later in the stream aren't tossed
consume_feed($xml,$importer,$contact,$hub,1,2);
$hubmode = 'subscribe';
if($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly'])
$hubmode = 'unsubscribe';
if((strlen($hub)) && ($hub_update) && ($contact['rel'] != CONTACT_IS_FOLLOWER)) {
logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : ' . $importer['name']);
$hubs = explode(',', $hub);
if(count($hubs)) {
foreach($hubs as $h) {
$h = trim($h);
if(! strlen($h))
continue;
subscribe_to_hub($h,$importer,$contact,$hubmode);
}
}
}
}
$updated = datetime_convert();
$r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d LIMIT 1",
dbesc($updated),
dbesc($updated),
intval($contact['id'])
);
// load current friends if possible.
if($contact['poco']) {
$r = q("SELECT count(*) as total from glink
where `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY",
intval($contact['id'])
);
}
if(count($r)) {
if(! $r[0]['total']) {
poco_load($contact['id'],$importer_uid,$contact['poco']);
}
}
// loop - next contact
proc_run('php','include/onepoll.php',$contact['id']);
if($interval)
@time_sleep_until(microtime(true) + (float) $interval);
}
}
return;
}

View File

@ -7,8 +7,10 @@ function gender_selector($current="",$suffix="") {
$o .= "<select name=\"gender$suffix\" id=\"gender-select$suffix\" size=\"1\" >";
foreach($select as $selection) {
$selected = (($selection == $current) ? ' selected="selected" ' : '');
$o .= "<option value=\"$selection\" $selected >$selection</option>";
if($selection !== 'NOTRANSLATION') {
$selected = (($selection == $current) ? ' selected="selected" ' : '');
$o .= "<option value=\"$selection\" $selected >$selection</option>";
}
}
$o .= '</select>';
return $o;
@ -20,8 +22,10 @@ function sexpref_selector($current="",$suffix="") {
$o .= "<select name=\"sexual$suffix\" id=\"sexual-select$suffix\" size=\"1\" >";
foreach($select as $selection) {
$selected = (($selection == $current) ? ' selected="selected" ' : '');
$o .= "<option value=\"$selection\" $selected >$selection</option>";
if($selection !== 'NOTRANSLATION') {
$selected = (($selection == $current) ? ' selected="selected" ' : '');
$o .= "<option value=\"$selection\" $selected >$selection</option>";
}
}
$o .= '</select>';
return $o;
@ -34,8 +38,10 @@ function marital_selector($current="",$suffix="") {
$o .= "<select name=\"marital\" id=\"marital-select\" size=\"1\" >";
foreach($select as $selection) {
$selected = (($selection == $current) ? ' selected="selected" ' : '');
$o .= "<option value=\"$selection\" $selected >$selection</option>";
if($selection !== 'NOTRANSLATION') {
$selected = (($selection == $current) ? ' selected="selected" ' : '');
$o .= "<option value=\"$selection\" $selected >$selection</option>";
}
}
$o .= '</select>';
return $o;

View File

@ -15,6 +15,17 @@ function remove_queue_item($id) {
);
}
function was_recently_delayed($cid) {
$r = q("SELECT `id` FROM `queue` WHERE `cid` = %d
and last > UTC_TIMESTAMP() - interval 15 minute limit 1",
intval($cid)
);
if(count($r))
return true;
return false;
}
function add_to_queue($cid,$network,$msg,$batch = false) {

View File

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

View File

@ -20,7 +20,7 @@ require_once('include/datetime.php');
function poco_load($cid,$uid = 0,$url = null) {
function poco_load($cid,$uid = 0,$zcid = 0,$url = null) {
$a = get_app();
if($cid) {
@ -53,7 +53,6 @@ function poco_load($cid,$uid = 0,$url = null) {
if(($a->get_curl_code() > 299) || (! $s))
return;
$j = json_decode($s);
logger('poco_load: json: ' . print_r($j,true),LOGGER_DATA);
@ -81,7 +80,6 @@ function poco_load($cid,$uid = 0,$url = null) {
$connect_url = str_replace('acct:' , '', $url->value);
continue;
}
}
foreach($entry->photos as $photo) {
if($photo->type == 'profile') {
@ -101,11 +99,12 @@ function poco_load($cid,$uid = 0,$url = null) {
$gcid = $x[0]['id'];
if($x[0]['name'] != $name || $x[0]['photo'] != $profile_photo) {
q("update gcontact set `name` = '%s', `photo` = '%s', `connect` = '%s'
q("update gcontact set `name` = '%s', `photo` = '%s', `connect` = '%s', `url` = '%s'
where `nurl` = '%s' limit 1",
dbesc($name),
dbesc($profile_photo),
dbesc($connect_url),
dbesc($profile_url),
dbesc(normalise_link($profile_url))
);
}
@ -128,34 +127,38 @@ function poco_load($cid,$uid = 0,$url = null) {
if(! $gcid)
return;
$r = q("select * from glink where `cid` = %d and `uid` = %d and `gcid` = %d limit 1",
$r = q("select * from glink where `cid` = %d and `uid` = %d and `gcid` = %d and `zcid` = %d limit 1",
intval($cid),
intval($uid),
intval($gcid)
intval($gcid),
intval($zcid)
);
if(! count($r)) {
q("insert into glink ( `cid`,`uid`,`gcid`,`updated`) values (%d,%d,%d,'%s') ",
q("insert into glink ( `cid`,`uid`,`gcid`,`zcid`, `updated`) values (%d,%d,%d,%d, '%s') ",
intval($cid),
intval($uid),
intval($gcid),
intval($zcid),
dbesc(datetime_convert())
);
}
else {
q("update glink set updated = '%s' where `cid` = %d and `uid` = %d and `gcid` = %d limit 1",
q("update glink set updated = '%s' where `cid` = %d and `uid` = %d and `gcid` = %d and zcid = %d limit 1",
dbesc(datetime_convert()),
intval($cid),
intval($uid),
intval($gcid)
intval($gcid),
intval($zcid)
);
}
}
logger("poco_load: loaded $total entries",LOGGER_DEBUG);
q("delete from glink where `cid` = %d and `uid` = %d and `updated` < UTC_TIMESTAMP - INTERVAL 2 DAY",
q("delete from glink where `cid` = %d and `uid` = %d and `zcid` = %d and `updated` < UTC_TIMESTAMP - INTERVAL 2 DAY",
intval($cid),
intval($uid)
intval($uid),
intval($zcid)
);
}
@ -166,37 +169,85 @@ function count_common_friends($uid,$cid) {
$r = q("SELECT count(*) as `total`
FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`cid` = %d and `glink`.`uid` = %d
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and id != %d ) ",
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d ) ",
intval($cid),
intval($uid),
intval($uid),
intval($cid)
);
// logger("count_common_friends: $uid $cid {$r[0]['total']}");
if(count($r))
return $r[0]['total'];
return 0;
}
function common_friends($uid,$cid,$start = 0,$limit=9999,$shuffle = false) {
if($shuffle)
$sql_extra = " order by rand() ";
else
$sql_extra = " order by `gcontact`.`name` asc ";
$r = q("SELECT `gcontact`.*
FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`cid` = %d and `glink`.`uid` = %d
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d )
$sql_extra limit %d, %d",
intval($cid),
intval($uid),
intval($uid),
intval($cid),
intval($start),
intval($limit)
);
return $r;
}
function count_common_friends_zcid($uid,$zcid) {
$r = q("SELECT count(*) as `total`
FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`zcid` = %d
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 ) ",
intval($zcid),
intval($uid)
);
if(count($r))
return $r[0]['total'];
return 0;
}
function common_friends_zcid($uid,$zcid,$start = 0, $limit = 9999,$shuffle) {
function common_friends($uid,$cid) {
if($shuffle)
$sql_extra = " order by rand() ";
else
$sql_extra = " order by `gcontact`.`name` asc ";
$r = q("SELECT `gcontact`.*
FROM `glink` left join `gcontact` on `glink`.`gcid` = `gcontact`.`id`
where `glink`.`cid` = %d and `glink`.`uid` = %d
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and id != %d )
order by `gcontact`.`name` asc ",
intval($cid),
where `glink`.`zcid` = %d
and `gcontact`.`nurl` in (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 )
$sql_extra limit %d, %d",
intval($zcid),
intval($uid),
intval($uid),
intval($cid)
intval($start),
intval($limit)
);
return $r;
}
function count_all_friends($uid,$cid) {
$r = q("SELECT count(*) as `total`
@ -254,7 +305,7 @@ function suggestion_query($uid, $start = 0, $limit = 80) {
$r2 = q("SELECT gcontact.* from gcontact
left join glink on glink.gcid = gcontact.id
where glink.uid = 0 and glink.cid = 0 and not gcontact.nurl in ( select nurl from contact where uid = %d )
where glink.uid = 0 and glink.cid = 0 and glink.zcid = 0 and not gcontact.nurl in ( select nurl from contact where uid = %d )
and not gcontact.name in ( select name from contact where uid = %d )
and not gcontact.id in ( select gcid from gcign where uid = %d )
order by rand() limit %d, %d ",
@ -276,7 +327,7 @@ function update_suggestions() {
$done = array();
poco_load(0,0,$a->get_baseurl() . '/poco');
poco_load(0,0,0,$a->get_baseurl() . '/poco');
$done[] = $a->get_baseurl() . '/poco';
@ -288,7 +339,7 @@ function update_suggestions() {
foreach($j->entries as $entry) {
$url = $entry->url . '/poco';
if(! in_array($url,$done))
poco_load(0,0,$entry->url . '/poco');
poco_load(0,0,0,$entry->url . '/poco');
}
}
}
@ -302,7 +353,7 @@ function update_suggestions() {
foreach($r as $rr) {
$base = substr($rr['poco'],0,strrpos($rr['poco'],'/'));
if(! in_array($base,$done))
poco_load(0,0,$base);
poco_load(0,0,0,$base);
}
}
}

View File

@ -558,7 +558,7 @@ function contact_block() {
if((! is_array($a->profile)) || ($a->profile['hide-friends']))
return $o;
$r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0",
$r = q("SELECT COUNT(*) AS `total` FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 AND `archive` = 0",
intval($a->profile['uid'])
);
if(count($r)) {
@ -569,7 +569,7 @@ function contact_block() {
$micropro = Null;
} else {
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 ORDER BY RAND() LIMIT %d",
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 and `pending` = 0 AND `hidden` = 0 AND `archive` = 0 ORDER BY RAND() LIMIT %d",
intval($a->profile['uid']),
intval($shown)
);
@ -930,7 +930,8 @@ function prepare_body($item,$attach = false) {
foreach($matches as $mtch) {
if(strlen($x))
$x .= ',';
$x .= xmlify(file_tag_decode($mtch[1]));
$x .= xmlify(file_tag_decode($mtch[1]))
. ((local_user() == $item['uid']) ? ' <a href="' . $a->get_baseurl() . '/filerm/' . $item['id'] . '?f=&cat=' . xmlify(file_tag_decode($mtch[1])) . '" title="' . t('remove') . '" >' . t('[remove]') . '</a>' : '');
}
if(strlen($x))
$s .= '<div class="categorytags"><span>' . t('Categories:') . ' </span>' . $x . '</div>';
@ -1466,12 +1467,16 @@ function file_tag_save_file($uid,$item,$file) {
return true;
}
function file_tag_unsave_file($uid,$item,$file) {
function file_tag_unsave_file($uid,$item,$file,$cat = false) {
$result = false;
if(! intval($uid))
return false;
$pattern = '[' . file_tag_encode($file) . ']' ;
if($cat == true)
$pattern = '<' . file_tag_encode($file) . '>' ;
else
$pattern = '[' . file_tag_encode($file) . ']' ;
$r = q("select file from item where id = %d and uid = %d limit 1",
intval($item),
@ -1486,13 +1491,14 @@ function file_tag_unsave_file($uid,$item,$file) {
intval($uid)
);
$r = q("select file from item where uid = %d " . file_tag_file_query('item',$file),
$r = q("select file from item where uid = %d and deleted = 0 " . file_tag_file_query('item',$file,(($cat) ? 'category' : 'file')),
intval($uid)
);
if(! count($r)) {
$saved = get_pconfig($uid,'system','filetags');
set_pconfig($uid,'system','filetags',str_replace($pattern,'',$saved));
}
return true;
}
@ -1518,3 +1524,9 @@ function fix_mce_lf($s) {
$s = str_replace("\n\n","\n",$s);
return $s;
}
function protect_sprintf($s) {
return(str_replace('%','%%',$s));
}

View File

@ -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);
@ -92,13 +92,10 @@ if((x($_SESSION,'language')) && ($_SESSION['language'] !== $lang)) {
load_translation_table($lang);
}
if(x($_GET,'zrl')) {
if((x($_GET,'zrl')) && (! $install)) {
$_SESSION['my_url'] = $_GET['zrl'];
$a->query_string = preg_replace('/[\?&]zrl=(.*?)([\?&]|$)/is','',$a->query_string);
if(! $install) {
$arr = array('zrl' => $_SESSION['my_url'], 'url' => $a->cmd);
call_hooks('zrl_init',$arr);
}
zrl_init($a);
}
/**

View File

@ -73,7 +73,16 @@
setupFieldRichtext();
/* popup menus */
function close_last_popup_menu() {
if(last_popup_menu) {
last_popup_menu.hide();
last_popup_button.removeClass("selected");
last_popup_menu = null;
last_popup_button = null;
}
}
$('a[rel^=#]').click(function(e){
close_last_popup_menu();
menu = $( $(this).attr('rel') );
e.preventDefault();
e.stopPropagation();
@ -90,12 +99,7 @@
return false;
});
$('html').click(function() {
if(last_popup_menu) {
last_popup_menu.hide();
last_popup_button.removeClass("selected");
last_popup_menu = null;
last_popup_button = null;
}
close_last_popup_menu();
});
// fancyboxes

4
library/jquery_ac/README Normal file
View File

@ -0,0 +1,4 @@
This is jquery.autocomplete from
http://www.devbridge.com/projects/autocomplete/jquery/

View File

@ -0,0 +1,395 @@
/**
* Ajax Autocomplete for jQuery, version 1.1.3
* (c) 2010 Tomas Kirda
*
* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
* For details, see the web site: http://www.devbridge.com/projects/autocomplete/jquery/
*
* Last Review: 04/19/2010
* Heavily modified for contact completion in Friendica (add photos, hover tips. etc.) 11-May-2012 mike@macgirvin.com
*/
/*jslint onevar: true, evil: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */
/*global window: true, document: true, clearInterval: true, setInterval: true, jQuery: true */
(function($) {
var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g');
function fnFormatResult(value, data, currentValue) {
var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')';
return value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
}
function Autocomplete(el, options) {
this.el = $(el);
this.el.attr('autocomplete', 'off');
this.suggestions = [];
this.data = [];
this.badQueries = [];
this.selectedIndex = -1;
this.currentValue = this.el.val();
this.intervalId = 0;
this.cachedResponse = [];
this.onChangeInterval = null;
this.ignoreValueChange = false;
this.serviceUrl = options.serviceUrl;
this.isLocal = false;
this.options = {
autoSubmit: false,
minChars: 1,
maxHeight: 300,
deferRequestBy: 0,
width: 0,
highlight: true,
params: {},
fnFormatResult: fnFormatResult,
delimiter: null,
zIndex: 9999
};
this.initialize();
this.setOptions(options);
}
$.fn.autocomplete = function(options) {
return new Autocomplete(this.get(0)||$('<input />'), options);
};
Autocomplete.prototype = {
killerFn: null,
initialize: function() {
var me, uid, autocompleteElId;
me = this;
uid = Math.floor(Math.random()*0x100000).toString(16);
autocompleteElId = 'Autocomplete_' + uid;
this.killerFn = function(e) {
if ($(e.target).parents('.autocomplete').size() === 0) {
me.killSuggestions();
me.disableKillerFn();
}
};
if (!this.options.width) { this.options.width = this.el.width(); }
this.mainContainerId = 'AutocompleteContainter_' + uid;
$('<div id="' + this.mainContainerId + '" style="position:absolute;z-index:9999;"><div class="autocomplete-w1"><div class="autocomplete" id="' + autocompleteElId + '" style="display:none; width:300px;"></div></div></div>').appendTo('body');
this.container = $('#' + autocompleteElId);
this.fixPosition();
if (window.opera) {
this.el.keypress(function(e) { me.onKeyPress(e); });
} else {
this.el.keydown(function(e) { me.onKeyPress(e); });
}
this.el.keyup(function(e) { me.onKeyUp(e); });
this.el.blur(function() { me.enableKillerFn(); });
this.el.focus(function() { me.fixPosition(); });
},
setOptions: function(options){
var o = this.options;
$.extend(o, options);
if(o.lookup){
this.isLocal = true;
if($.isArray(o.lookup)){ o.lookup = { suggestions:o.lookup, data:[] }; }
}
$('#'+this.mainContainerId).css({ zIndex:o.zIndex });
this.container.css({ maxHeight: o.maxHeight + 'px', width:o.width });
},
clearCache: function(){
this.cachedResponse = [];
this.badQueries = [];
},
disable: function(){
this.disabled = true;
},
enable: function(){
this.disabled = false;
},
fixPosition: function() {
var offset = this.el.offset();
$('#' + this.mainContainerId).css({ top: (offset.top + this.el.innerHeight()) + 'px', left: offset.left + 'px' });
},
enableKillerFn: function() {
var me = this;
$(document).bind('click', me.killerFn);
},
disableKillerFn: function() {
var me = this;
$(document).unbind('click', me.killerFn);
},
killSuggestions: function() {
var me = this;
this.stopKillSuggestions();
this.intervalId = window.setInterval(function() { me.hide(); me.stopKillSuggestions(); }, 300);
},
stopKillSuggestions: function() {
window.clearInterval(this.intervalId);
},
onKeyPress: function(e) {
if (this.disabled || !this.enabled) { return; }
// return will exit the function
// and event will not be prevented
switch (e.keyCode) {
case 27: //KEY_ESC:
this.el.val(this.currentValue);
this.hide();
break;
case 9: //KEY_TAB:
case 13: //KEY_RETURN:
if (this.selectedIndex === -1) {
this.hide();
return;
}
this.select(this.selectedIndex);
if(e.keyCode === 9){ return; }
break;
case 38: //KEY_UP:
this.moveUp();
break;
case 40: //KEY_DOWN:
this.moveDown();
break;
default:
return;
}
e.stopImmediatePropagation();
e.preventDefault();
},
onKeyUp: function(e) {
if(this.disabled){ return; }
switch (e.keyCode) {
case 38: //KEY_UP:
case 40: //KEY_DOWN:
return;
}
clearInterval(this.onChangeInterval);
if (this.currentValue !== this.el.val()) {
if (this.options.deferRequestBy > 0) {
// Defer lookup in case when value changes very quickly:
var me = this;
this.onChangeInterval = setInterval(function() { me.onValueChange(); }, this.options.deferRequestBy);
} else {
this.onValueChange();
}
}
},
onValueChange: function() {
clearInterval(this.onChangeInterval);
this.currentValue = this.el.val();
var q = this.getQuery(this.currentValue);
this.selectedIndex = -1;
if (this.ignoreValueChange) {
this.ignoreValueChange = false;
return;
}
if (q === '' || q.length < this.options.minChars) {
this.hide();
} else {
this.getSuggestions(q);
}
},
getQuery: function(val) {
var d, arr;
d = this.options.delimiter;
if (!d) { return $.trim(val); }
arr = val.split(d);
return $.trim(arr[arr.length - 1]);
},
getSuggestionsLocal: function(q) {
var ret, arr, len, val, i;
arr = this.options.lookup;
len = arr.suggestions.length;
ret = { suggestions:[], data:[] };
q = q.toLowerCase();
for(i=0; i< len; i++){
val = arr.suggestions[i];
if(val.toLowerCase().indexOf(q) === 0){
ret.suggestions.push(val);
ret.data.push(arr.data[i]);
}
}
return ret;
},
getSuggestions: function(q) {
var cr, me;
cr = this.isLocal ? this.getSuggestionsLocal(q) : this.cachedResponse[q];
if (cr && $.isArray(cr.suggestions)) {
this.suggestions = cr.suggestions;
this.data = cr.data;
this.suggest();
} else if (!this.isBadQuery(q)) {
me = this;
me.options.params.query = q;
$.get(this.serviceUrl, me.options.params, function(txt) { me.processResponse(txt); }, 'text');
}
},
isBadQuery: function(q) {
var i = this.badQueries.length;
while (i--) {
if (q.indexOf(this.badQueries[i]) === 0) { return true; }
}
return false;
},
hide: function() {
this.enabled = false;
this.selectedIndex = -1;
this.container.hide();
},
suggest: function() {
if (this.suggestions.length === 0) {
this.hide();
return;
}
var me, len, div, f, v, i, s, mOver, mClick, l, img;
me = this;
len = this.suggestions.length;
f = this.options.fnFormatResult;
v = this.getQuery(this.currentValue);
mOver = function(xi) { return function() { me.activate(xi); }; };
mClick = function(xi) { return function() { me.select(xi); }; };
this.container.hide().empty();
for (i = 0; i < len; i++) {
s = this.suggestions[i];
l = this.links[i];
img = '<img height="24" width="24" src="' + this.photos[i] + '" alt="' + s + '" />&nbsp;';
div = $((me.selectedIndex === i ? '<div class="selected"' : '<div') + ' title="' + l + '">' + img + f(s, this.data[i], v) + '</div>');
div.mouseover(mOver(i));
div.click(mClick(i));
this.container.append(div);
}
this.enabled = true;
this.container.show();
},
processResponse: function(text) {
var response;
try {
response = eval('(' + text + ')');
} catch (err) { return; }
if (!$.isArray(response.data)) { response.data = []; }
if(!this.options.noCache){
this.cachedResponse[response.query] = response;
if (response.suggestions.length === 0) { this.badQueries.push(response.query); }
}
if (response.query === this.getQuery(this.currentValue)) {
this.photos = response.photos;
this.links = response.links;
this.suggestions = response.suggestions;
this.data = response.data;
this.suggest();
}
},
activate: function(index) {
var divs, activeItem;
divs = this.container.children();
// Clear previous selection:
if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
$(divs.get(this.selectedIndex)).removeClass();
}
this.selectedIndex = index;
if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
activeItem = divs.get(this.selectedIndex);
$(activeItem).addClass('selected');
}
return activeItem;
},
deactivate: function(div, index) {
div.className = '';
if (this.selectedIndex === index) { this.selectedIndex = -1; }
},
select: function(i) {
var selectedValue, f;
selectedValue = this.suggestions[i];
if (selectedValue) {
this.el.val(selectedValue);
if (this.options.autoSubmit) {
f = this.el.parents('form');
if (f.length > 0) { f.get(0).submit(); }
}
this.ignoreValueChange = true;
this.hide();
this.onSelect(i);
}
},
moveUp: function() {
if (this.selectedIndex === -1) { return; }
if (this.selectedIndex === 0) {
this.container.children().get(0).className = '';
this.selectedIndex = -1;
this.el.val(this.currentValue);
return;
}
this.adjustScroll(this.selectedIndex - 1);
},
moveDown: function() {
if (this.selectedIndex === (this.suggestions.length - 1)) { return; }
this.adjustScroll(this.selectedIndex + 1);
},
adjustScroll: function(i) {
var activeItem, offsetTop, upperBound, lowerBound;
activeItem = this.activate(i);
offsetTop = activeItem.offsetTop;
upperBound = this.container.scrollTop();
lowerBound = upperBound + this.options.maxHeight - 25;
if (offsetTop < upperBound) {
this.container.scrollTop(offsetTop);
} else if (offsetTop > lowerBound) {
this.container.scrollTop(offsetTop - this.options.maxHeight + 25);
}
this.el.val(this.getValue(this.suggestions[i]));
},
onSelect: function(i) {
var me, fn, s, d;
me = this;
fn = me.options.onSelect;
s = me.suggestions[i];
d = me.data[i];
me.el.val(me.getValue(s));
if ($.isFunction(fn)) { fn(s, d, me.el); }
},
getValue: function(value){
var del, currVal, arr, me;
me = this;
del = me.options.delimiter;
if (!del) { return value; }
currVal = me.currentValue;
arr = currVal.split(del);
if (arr.length === 1) { return value; }
return currVal.substr(0, currVal.length - arr[arr.length - 1].length) + value;
}
};
}(jQuery));

19
library/jquery_ac/jquery-1.3.2.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,390 @@
/**
* Ajax Autocomplete for jQuery, version 1.1.3
* (c) 2010 Tomas Kirda
*
* Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
* For details, see the web site: http://www.devbridge.com/projects/autocomplete/jquery/
*
* Last Review: 04/19/2010
*/
/*jslint onevar: true, evil: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */
/*global window: true, document: true, clearInterval: true, setInterval: true, jQuery: true */
(function($) {
var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g');
function fnFormatResult(value, data, currentValue) {
var pattern = '(' + currentValue.replace(reEscape, '\\$1') + ')';
return value.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
}
function Autocomplete(el, options) {
this.el = $(el);
this.el.attr('autocomplete', 'off');
this.suggestions = [];
this.data = [];
this.badQueries = [];
this.selectedIndex = -1;
this.currentValue = this.el.val();
this.intervalId = 0;
this.cachedResponse = [];
this.onChangeInterval = null;
this.ignoreValueChange = false;
this.serviceUrl = options.serviceUrl;
this.isLocal = false;
this.options = {
autoSubmit: false,
minChars: 1,
maxHeight: 300,
deferRequestBy: 0,
width: 0,
highlight: true,
params: {},
fnFormatResult: fnFormatResult,
delimiter: null,
zIndex: 9999
};
this.initialize();
this.setOptions(options);
}
$.fn.autocomplete = function(options) {
return new Autocomplete(this.get(0)||$('<input />'), options);
};
Autocomplete.prototype = {
killerFn: null,
initialize: function() {
var me, uid, autocompleteElId;
me = this;
uid = Math.floor(Math.random()*0x100000).toString(16);
autocompleteElId = 'Autocomplete_' + uid;
this.killerFn = function(e) {
if ($(e.target).parents('.autocomplete').size() === 0) {
me.killSuggestions();
me.disableKillerFn();
}
};
if (!this.options.width) { this.options.width = this.el.width(); }
this.mainContainerId = 'AutocompleteContainter_' + uid;
$('<div id="' + this.mainContainerId + '" style="position:absolute;z-index:9999;"><div class="autocomplete-w1"><div class="autocomplete" id="' + autocompleteElId + '" style="display:none; width:300px;"></div></div></div>').appendTo('body');
this.container = $('#' + autocompleteElId);
this.fixPosition();
if (window.opera) {
this.el.keypress(function(e) { me.onKeyPress(e); });
} else {
this.el.keydown(function(e) { me.onKeyPress(e); });
}
this.el.keyup(function(e) { me.onKeyUp(e); });
this.el.blur(function() { me.enableKillerFn(); });
this.el.focus(function() { me.fixPosition(); });
},
setOptions: function(options){
var o = this.options;
$.extend(o, options);
if(o.lookup){
this.isLocal = true;
if($.isArray(o.lookup)){ o.lookup = { suggestions:o.lookup, data:[] }; }
}
$('#'+this.mainContainerId).css({ zIndex:o.zIndex });
this.container.css({ maxHeight: o.maxHeight + 'px', width:o.width });
},
clearCache: function(){
this.cachedResponse = [];
this.badQueries = [];
},
disable: function(){
this.disabled = true;
},
enable: function(){
this.disabled = false;
},
fixPosition: function() {
var offset = this.el.offset();
$('#' + this.mainContainerId).css({ top: (offset.top + this.el.innerHeight()) + 'px', left: offset.left + 'px' });
},
enableKillerFn: function() {
var me = this;
$(document).bind('click', me.killerFn);
},
disableKillerFn: function() {
var me = this;
$(document).unbind('click', me.killerFn);
},
killSuggestions: function() {
var me = this;
this.stopKillSuggestions();
this.intervalId = window.setInterval(function() { me.hide(); me.stopKillSuggestions(); }, 300);
},
stopKillSuggestions: function() {
window.clearInterval(this.intervalId);
},
onKeyPress: function(e) {
if (this.disabled || !this.enabled) { return; }
// return will exit the function
// and event will not be prevented
switch (e.keyCode) {
case 27: //KEY_ESC:
this.el.val(this.currentValue);
this.hide();
break;
case 9: //KEY_TAB:
case 13: //KEY_RETURN:
if (this.selectedIndex === -1) {
this.hide();
return;
}
this.select(this.selectedIndex);
if(e.keyCode === 9){ return; }
break;
case 38: //KEY_UP:
this.moveUp();
break;
case 40: //KEY_DOWN:
this.moveDown();
break;
default:
return;
}
e.stopImmediatePropagation();
e.preventDefault();
},
onKeyUp: function(e) {
if(this.disabled){ return; }
switch (e.keyCode) {
case 38: //KEY_UP:
case 40: //KEY_DOWN:
return;
}
clearInterval(this.onChangeInterval);
if (this.currentValue !== this.el.val()) {
if (this.options.deferRequestBy > 0) {
// Defer lookup in case when value changes very quickly:
var me = this;
this.onChangeInterval = setInterval(function() { me.onValueChange(); }, this.options.deferRequestBy);
} else {
this.onValueChange();
}
}
},
onValueChange: function() {
clearInterval(this.onChangeInterval);
this.currentValue = this.el.val();
var q = this.getQuery(this.currentValue);
this.selectedIndex = -1;
if (this.ignoreValueChange) {
this.ignoreValueChange = false;
return;
}
if (q === '' || q.length < this.options.minChars) {
this.hide();
} else {
this.getSuggestions(q);
}
},
getQuery: function(val) {
var d, arr;
d = this.options.delimiter;
if (!d) { return $.trim(val); }
arr = val.split(d);
return $.trim(arr[arr.length - 1]);
},
getSuggestionsLocal: function(q) {
var ret, arr, len, val, i;
arr = this.options.lookup;
len = arr.suggestions.length;
ret = { suggestions:[], data:[] };
q = q.toLowerCase();
for(i=0; i< len; i++){
val = arr.suggestions[i];
if(val.toLowerCase().indexOf(q) === 0){
ret.suggestions.push(val);
ret.data.push(arr.data[i]);
}
}
return ret;
},
getSuggestions: function(q) {
var cr, me;
cr = this.isLocal ? this.getSuggestionsLocal(q) : this.cachedResponse[q];
if (cr && $.isArray(cr.suggestions)) {
this.suggestions = cr.suggestions;
this.data = cr.data;
this.suggest();
} else if (!this.isBadQuery(q)) {
me = this;
me.options.params.query = q;
$.get(this.serviceUrl, me.options.params, function(txt) { me.processResponse(txt); }, 'text');
}
},
isBadQuery: function(q) {
var i = this.badQueries.length;
while (i--) {
if (q.indexOf(this.badQueries[i]) === 0) { return true; }
}
return false;
},
hide: function() {
this.enabled = false;
this.selectedIndex = -1;
this.container.hide();
},
suggest: function() {
if (this.suggestions.length === 0) {
this.hide();
return;
}
var me, len, div, f, v, i, s, mOver, mClick;
me = this;
len = this.suggestions.length;
f = this.options.fnFormatResult;
v = this.getQuery(this.currentValue);
mOver = function(xi) { return function() { me.activate(xi); }; };
mClick = function(xi) { return function() { me.select(xi); }; };
this.container.hide().empty();
for (i = 0; i < len; i++) {
s = this.suggestions[i];
div = $((me.selectedIndex === i ? '<div class="selected"' : '<div') + ' title="' + s + '">' + f(s, this.data[i], v) + '</div>');
div.mouseover(mOver(i));
div.click(mClick(i));
this.container.append(div);
}
this.enabled = true;
this.container.show();
},
processResponse: function(text) {
var response;
try {
response = eval('(' + text + ')');
} catch (err) { return; }
if (!$.isArray(response.data)) { response.data = []; }
if(!this.options.noCache){
this.cachedResponse[response.query] = response;
if (response.suggestions.length === 0) { this.badQueries.push(response.query); }
}
if (response.query === this.getQuery(this.currentValue)) {
this.suggestions = response.suggestions;
this.data = response.data;
this.suggest();
}
},
activate: function(index) {
var divs, activeItem;
divs = this.container.children();
// Clear previous selection:
if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
$(divs.get(this.selectedIndex)).removeClass();
}
this.selectedIndex = index;
if (this.selectedIndex !== -1 && divs.length > this.selectedIndex) {
activeItem = divs.get(this.selectedIndex);
$(activeItem).addClass('selected');
}
return activeItem;
},
deactivate: function(div, index) {
div.className = '';
if (this.selectedIndex === index) { this.selectedIndex = -1; }
},
select: function(i) {
var selectedValue, f;
selectedValue = this.suggestions[i];
if (selectedValue) {
this.el.val(selectedValue);
if (this.options.autoSubmit) {
f = this.el.parents('form');
if (f.length > 0) { f.get(0).submit(); }
}
this.ignoreValueChange = true;
this.hide();
this.onSelect(i);
}
},
moveUp: function() {
if (this.selectedIndex === -1) { return; }
if (this.selectedIndex === 0) {
this.container.children().get(0).className = '';
this.selectedIndex = -1;
this.el.val(this.currentValue);
return;
}
this.adjustScroll(this.selectedIndex - 1);
},
moveDown: function() {
if (this.selectedIndex === (this.suggestions.length - 1)) { return; }
this.adjustScroll(this.selectedIndex + 1);
},
adjustScroll: function(i) {
var activeItem, offsetTop, upperBound, lowerBound;
activeItem = this.activate(i);
offsetTop = activeItem.offsetTop;
upperBound = this.container.scrollTop();
lowerBound = upperBound + this.options.maxHeight - 25;
if (offsetTop < upperBound) {
this.container.scrollTop(offsetTop);
} else if (offsetTop > lowerBound) {
this.container.scrollTop(offsetTop - this.options.maxHeight + 25);
}
this.el.val(this.getValue(this.suggestions[i]));
},
onSelect: function(i) {
var me, fn, s, d;
me = this;
fn = me.options.onSelect;
s = me.suggestions[i];
d = me.data[i];
me.el.val(me.getValue(s));
if ($.isFunction(fn)) { fn(s, d, me.el); }
},
getValue: function(value){
var del, currVal, arr, me;
me = this;
del = me.options.delimiter;
if (!del) { return value; }
currVal = me.currentValue;
arr = currVal.split(del);
if (arr.length === 1) { return value; }
return currVal.substr(0, currVal.length - arr[arr.length - 1].length) + value;
}
};
}(jQuery));

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,6 @@

.autocomplete-w1 { background:url(img/shadow.png) no-repeat bottom right; position:absolute; top:0px; left:0px; margin:8px 0 0 6px; /* IE6 fix: */ _background:none; _margin:0; }
.autocomplete { border:1px solid #999; background:#FFF; cursor:default; text-align:left; max-height:350px; overflow:auto; margin:-6px 6px 6px -6px; /* IE6 specific: */ _height:350px; _margin:0; _overflow-x:hidden; }
.autocomplete .selected { background:#F0F0F0; }
.autocomplete div { padding:2px 5px; white-space:nowrap; }
.autocomplete strong { font-weight:normal; color:#3399FF; }

File diff suppressed because it is too large Load Diff

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

View 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];
}
}
?>

View 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: */
?>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View 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: */
?>

View 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>

View 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";
?>

File diff suppressed because it is too large Load Diff

View 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')
);
}
}
?>

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,174 +1,180 @@
/**
* editor_plugin_src.js
*
* Copyright 2011, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://tinymce.moxiecode.com/license
* Contributing: http://tinymce.moxiecode.com/contributing
*/
(function() {
tinymce.create('tinymce.plugins.AutolinkPlugin', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
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) {
if (e.keyCode == 13)
return t.handleEnter(ed);
});
ed.onKeyPress.add(function(ed, e) {
if (e.which == 41)
return t.handleEclipse(ed);
});
// Add a key up handler
ed.onKeyUp.add(function(ed, e) {
if (e.keyCode == 32)
return t.handleSpacebar(ed);
});
},
handleEclipse : function(ed) {
this.parseCurrentLine(ed, -1, '(', true);
},
handleSpacebar : function(ed) {
this.parseCurrentLine(ed, 0, '', true);
},
handleEnter : function(ed) {
this.parseCurrentLine(ed, -1, '', false);
},
parseCurrentLine : function(ed, end_offset, delimiter, goback) {
var r, end, start, endContainer, bookmark, text, matches, prev, len;
// 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();
if (r.startOffset < 5) {
// During testing, the caret is placed inbetween two text nodes.
// The previous text node contains the URL.
prev = r.endContainer.previousSibling;
if (prev == null) {
if (r.endContainer.firstChild == null || r.endContainer.firstChild.nextSibling == null)
return;
prev = r.endContainer.firstChild.nextSibling;
}
len = prev.length;
r.setStart(prev, len);
r.setEnd(prev, len);
if (r.endOffset < 5)
return;
end = r.endOffset;
endContainer = prev;
} else {
endContainer = r.endContainer;
// Get a text node
if (endContainer.nodeType != 3 && endContainer.firstChild) {
while (endContainer.nodeType != 3 && endContainer.firstChild)
endContainer = endContainer.firstChild;
r.setStart(endContainer, 0);
r.setEnd(endContainer, endContainer.nodeValue.length);
}
if (r.endOffset == 1)
end = 2;
else
end = r.endOffset - 1 - end_offset;
}
start = end;
do
{
// Move the selection one character backwards.
r.setStart(endContainer, end - 2);
r.setEnd(endContainer, end - 1);
end -= 1;
// Loop until one of the following is found: a blank space, &nbsp;, delimeter, (end-2) >= 0
} while (r.toString() != ' ' && r.toString() != '' && r.toString().charCodeAt(0) != 160 && (end -2) >= 0 && r.toString() != delimiter);
if (r.toString() == delimiter || r.toString().charCodeAt(0) == 160) {
r.setStart(endContainer, end);
r.setEnd(endContainer, start);
end += 1;
} else if (r.startOffset == 0) {
r.setStart(endContainer, 0);
r.setEnd(endContainer, start);
}
else {
r.setStart(endContainer, end);
r.setEnd(endContainer, start);
}
text = r.toString();
matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);
if (matches) {
if (matches[1] == 'www.') {
matches[1] = 'http://www.';
} else if (/@$/.test(matches[1])) {
matches[1] = 'mailto:' + matches[1];
}
bookmark = ed.selection.getBookmark();
ed.selection.setRng(r);
tinyMCE.execCommand('createlink',false, matches[1] + matches[2]);
ed.selection.moveToBookmark(bookmark);
// TODO: Determine if this is still needed.
if (tinyMCE.isWebKit) {
// move the caret to its original position
ed.selection.collapse(false);
var max = Math.min(endContainer.length, start + 1);
r.setStart(endContainer, max);
r.setEnd(endContainer, max);
ed.selection.setRng(r);
}
}
},
/**
* Returns information about the plugin as a name/value array.
* The current keys are longname, author, authorurl, infourl and version.
*
* @return {Object} Name/value array containing information about the plugin.
*/
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
};
}
});
// Register plugin
tinymce.PluginManager.add('autolink', tinymce.plugins.AutolinkPlugin);
})();
/**
* editor_plugin_src.js
*
* Copyright 2011, Moxiecode Systems AB
* Released under LGPL License.
*
* License: http://tinymce.moxiecode.com/license
* Contributing: http://tinymce.moxiecode.com/contributing
*/
(function() {
tinymce.create('tinymce.plugins.AutolinkPlugin', {
/**
* Initializes the plugin, this will be executed after the plugin has been created.
* This call is done before the editor instance has finished it's initialization so use the onInit event
* of the editor instance to intercept that event.
*
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
* @param {string} url Absolute URL to where the plugin is located.
*/
init : function(ed, url) {
var t = this;
// Add a key down handler
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);
});
// Add a key up handler
ed.onKeyUp.add(function(ed, e) {
if (e.keyCode == 32)
return t.handleSpacebar(ed);
});
},
handleEclipse : function(ed) {
this.parseCurrentLine(ed, -1, '(', true);
},
handleSpacebar : function(ed) {
this.parseCurrentLine(ed, 0, '', true);
},
handleEnter : function(ed) {
this.parseCurrentLine(ed, -1, '', false);
},
parseCurrentLine : function(ed, end_offset, delimiter, goback) {
var r, end, start, endContainer, bookmark, text, matches, prev, len;
// 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(true).cloneRange();
if (r.startOffset < 5) {
// During testing, the caret is placed inbetween two text nodes.
// The previous text node contains the URL.
prev = r.endContainer.previousSibling;
if (prev == null) {
if (r.endContainer.firstChild == null || r.endContainer.firstChild.nextSibling == null)
return;
prev = r.endContainer.firstChild.nextSibling;
}
len = prev.length;
r.setStart(prev, len);
r.setEnd(prev, len);
if (r.endOffset < 5)
return;
end = r.endOffset;
endContainer = prev;
} else {
endContainer = r.endContainer;
// Get a text node
if (endContainer.nodeType != 3 && endContainer.firstChild) {
while (endContainer.nodeType != 3 && endContainer.firstChild)
endContainer = endContainer.firstChild;
r.setStart(endContainer, 0);
r.setEnd(endContainer, endContainer.nodeValue.length);
}
if (r.endOffset == 1)
end = 2;
else
end = r.endOffset - 1 - end_offset;
}
start = end;
do
{
// Move the selection one character backwards.
r.setStart(endContainer, end - 2);
r.setEnd(endContainer, end - 1);
end -= 1;
// Loop until one of the following is found: a blank space, &nbsp;, delimeter, (end-2) >= 0
} while (r.toString() != ' ' && r.toString() != '' && r.toString().charCodeAt(0) != 160 && (end -2) >= 0 && r.toString() != delimiter);
if (r.toString() == delimiter || r.toString().charCodeAt(0) == 160) {
r.setStart(endContainer, end);
r.setEnd(endContainer, start);
end += 1;
} else if (r.startOffset == 0) {
r.setStart(endContainer, 0);
r.setEnd(endContainer, start);
}
else {
r.setStart(endContainer, end);
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);
if (matches) {
if (matches[1] == 'www.') {
matches[1] = 'http://www.';
} else if (/@$/.test(matches[1])) {
matches[1] = 'mailto:' + matches[1];
}
bookmark = ed.selection.getBookmark();
ed.selection.setRng(r);
tinyMCE.execCommand('createlink',false, matches[1] + matches[2]);
ed.selection.moveToBookmark(bookmark);
// TODO: Determine if this is still needed.
if (tinyMCE.isWebKit) {
// move the caret to its original position
ed.selection.collapse(false);
var max = Math.min(endContainer.length, start + 1);
r.setStart(endContainer, max);
r.setEnd(endContainer, max);
ed.selection.setRng(r);
}
}
},
/**
* Returns information about the plugin as a name/value array.
* The current keys are longname, author, authorurl, infourl and version.
*
* @return {Object} Name/value array containing information about the plugin.
*/
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
};
}
});
// Register plugin
tinymce.PluginManager.add('autolink', tinymce.plugins.AutolinkPlugin);
})();

View File

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

View File

@ -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 it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -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,26 +472,10 @@
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
ed.parser.addAttributeFilter('class', function(nodes) {
var i = nodes.length, className, node;

File diff suppressed because one or more lines are too long

View File

@ -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>&nbsp;[\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>&nbsp;[\s\r\n]+|<br>)*/g, '$1']]);

View File

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

View File

@ -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' &&

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/* Generic */
body {
font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px;
background:#F0F0EE;
background:#F0F0EE;
color: black;
padding:0;
margin:8px 8px 0 8px;
@ -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;}

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,14 @@ function acl_init(&$a){
$type = (x($_REQUEST,'type')?$_REQUEST['type']:"");
// For use with jquery.autocomplete for private mail completion
if(x($_REQUEST,'query') && strlen($_REQUEST['query'])) {
$type = 'm';
$search = $_REQUEST['query'];
}
if ($search!=""){
$sql_extra = "AND `name` LIKE '%%".dbesc($search)."%%'";
$sql_extra2 = "AND (`attag` LIKE '%%".dbesc($search)."%%' OR `name` LIKE '%%".dbesc($search)."%%' OR `nick` LIKE '%%".dbesc($search)."%%')";
@ -33,11 +41,27 @@ function acl_init(&$a){
if ($type=='' || $type=='c'){
$r = q("SELECT COUNT(`id`) AS c FROM `contact`
WHERE `uid` = %d AND `self` = 0
AND `blocked` = 0 AND `pending` = 0
AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
AND `notify` != '' $sql_extra2" ,
intval(local_user())
);
$contact_count = (int)$r[0]['c'];
}
elseif ($type == 'm') {
// autocomplete for Private Messages
$r = q("SELECT COUNT(`id`) AS c FROM `contact`
WHERE `uid` = %d AND `self` = 0
AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
AND `network` IN ('%s','%s','%s') $sql_extra2" ,
intval(local_user()),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_ZOT),
dbesc(NETWORK_DIASPORA)
);
$contact_count = (int)$r[0]['c'];
} else {
$contact_count = 0;
}
@ -78,11 +102,48 @@ function acl_init(&$a){
if ($type=='' || $type=='c'){
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact`
WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `notify` != ''
WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0 AND `notify` != ''
$sql_extra2
ORDER BY `name` ASC ",
intval(local_user())
);
}
elseif($type == 'm') {
$r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag` FROM `contact`
WHERE `uid` = %d AND `self` = 0 AND `blocked` = 0 AND `pending` = 0 AND `archive` = 0
AND `network` IN ('%s','%s','%s')
$sql_extra2
ORDER BY `name` ASC ",
intval(local_user()),
dbesc(NETWORK_DFRN),
dbesc(NETWORK_ZOT),
dbesc(NETWORK_DIASPORA)
);
}
else
$r = array();
if($type == 'm') {
$x = array();
$x['query'] = $search;
$x['photos'] = array();
$x['links'] = array();
$x['suggestions'] = array();
$x['data'] = array();
if(count($r)) {
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['data'][] = intval($g['id']);
}
}
echo json_encode($x);
killme();
}
if(count($r)) {
foreach($r as $g){
$contacts[] = array(
"type" => "c",
@ -93,11 +154,9 @@ function acl_init(&$a){
"link" => $g['url'],
"nick" => ($g['attag']) ? $g['attag'] : $g['nick'],
);
}
}
}
$items = array_merge($groups, $contacts);
$o = array(

View File

@ -61,6 +61,9 @@ function admin_post(&$a){
case 'logs':
admin_page_logs_post($a);
break;
case 'dbsync':
admin_page_dbsync_post($a);
break;
case 'update':
admin_page_remoteupdate_post($a);
break;
@ -94,7 +97,8 @@ function admin_content(&$a) {
'users' => Array($a->get_baseurl(true)."/admin/users/", t("Users") , "users"),
'plugins'=> Array($a->get_baseurl(true)."/admin/plugins/", t("Plugins") , "plugins"),
'themes' => Array($a->get_baseurl(true)."/admin/themes/", t("Themes") , "themes"),
'update' => Array($a->get_baseurl(true)."/admin/update/", t("Update") , "update")
'dbsync' => Array($a->get_baseurl(true)."/admin/dbsync/", t('DB updates'), "dbsync"),
'update' => Array($a->get_baseurl(true)."/admin/update/", t("Software Update") , "update")
);
/* get plugins admin page */
@ -142,6 +146,9 @@ function admin_content(&$a) {
case 'logs':
$o = admin_page_logs($a);
break;
case 'dbsync':
$o = admin_page_dbsync($a);
break;
case 'update':
$o = admin_page_remoteupdate($a);
break;
@ -235,6 +242,9 @@ function admin_page_site_post(&$a){
$proxyuser = ((x($_POST,'proxyuser')) ? notags(trim($_POST['proxyuser'])) : '');
$proxy = ((x($_POST,'proxy')) ? notags(trim($_POST['proxy'])) : '');
$timeout = ((x($_POST,'timeout')) ? intval(trim($_POST['timeout'])) : 60);
$delivery_interval = ((x($_POST,'delivery_interval'))? intval(trim($_POST['delivery_interval'])) : 0);
$poll_interval = ((x($_POST,'poll_interval'))? intval(trim($_POST['poll_interval'])) : 0);
$maxloadavg = ((x($_POST,'maxloadavg')) ? intval(trim($_POST['maxloadavg'])) : 50);
$dfrn_only = ((x($_POST,'dfrn_only')) ? True : False);
$ostatus_disabled = !((x($_POST,'ostatus_disabled')) ? True : False);
$diaspora_enabled = ((x($_POST,'diaspora_enabled')) ? True : False);
@ -281,7 +291,9 @@ function admin_page_site_post(&$a){
}
}
set_config('system','ssl_policy',$ssl_policy);
set_config('system','delivery_interval',$delivery_interval);
set_config('system','poll_interval',$poll_interval);
set_config('system','maxloadavg',$maxloadavg);
set_config('config','sitename',$sitename);
if ($banner==""){
// don't know why, but del_config doesn't work...
@ -425,7 +437,9 @@ function admin_page_site(&$a) {
'$proxyuser' => array('proxyuser', t("Proxy user"), get_config('system','proxyuser'), ""),
'$proxy' => array('proxy', t("Proxy URL"), get_config('system','proxy'), ""),
'$timeout' => array('timeout', t("Network timeout"), (x(get_config('system','curl_timeout'))?get_config('system','curl_timeout'):60), t("Value is in seconds. Set to 0 for unlimited (not recommended).")),
'$delivery_interval' => array('delivery_interval', t("Delivery interval"), (x(get_config('system','delivery_interval'))?get_config('system','delivery_interval'):2), t("Delay background delivery processes by this many seconds to reduce system load. Recommend: 4-5 for shared hosts, 2-3 for virtual private servers. 0-1 for large dedicated servers.")),
'$poll_interval' => array('poll_interval', t("Poll interval"), (x(get_config('system','poll_interval'))?get_config('system','poll_interval'):2), t("Delay background polling processes by this many seconds to reduce system load. If 0, use delivery interval.")),
'$maxloadavg' => array('maxloadavg', t("Maximum Load Average"), ((intval(get_config('system','maxloadavg')) > 0)?get_config('system','maxloadavg'):50), t("Maximum system load before delivery and poll processes are deferred - default 50.")),
'$form_security_token' => get_form_security_token("admin_site"),
));
@ -433,6 +447,62 @@ function admin_page_site(&$a) {
}
function admin_page_dbsync(&$a) {
$o = '';
if($a->argc > 3 && intval($a->argv[3]) && $a->argv[2] === 'mark') {
set_config('database', 'update_' . intval($a->argv[3]), 'success');
info( t('Update has been marked successful') . EOL);
goaway($a->get_baseurl(true) . '/admin/dbsync');
}
if($a->argc > 2 && intval($a->argv[2])) {
require_once('update.php');
$func = 'update_' . intval($a->argv[2]);
if(function_exists($func)) {
$retval = $func();
if($retval === UPDATE_FAILED) {
$o .= sprintf( t('Executing %s failed. Check system logs.'), $func);
}
elseif($retval === UPDATE_SUCCESS) {
$o .= sprintf( t('Update %s was successfully applied.', $func));
set_config('database',$func, 'success');
}
else
$o .= sprintf( t('Update %s did not return a status. Unknown if it succeeded.'), $func);
}
else
$o .= sprintf( t('Update function %s could not be found.'), $func);
return $o;
}
$failed = array();
$r = q("select * from config where `cat` = 'database' ");
if(count($r)) {
foreach($r as $rr) {
$upd = intval(substr($rr['k'],7));
if($upd < 1139 || $rr['v'] === 'success')
continue;
$failed[] = $upd;
}
}
if(! count($failed))
return '<h3>' . t('No failed updates.') . '</h3>';
$o = replace_macros(get_markup_template('failed_updates.tpl'),array(
'$base' => $a->get_baseurl(true),
'$banner' => t('Failed Updates'),
'$desc' => t('This does not include updates prior to 1139, which did not return a status.'),
'$mark' => t('Mark success (if update was manually applied)'),
'$apply' => t('Attempt to execute this update step automatically'),
'$failed' => $failed
));
return $o;
}
/**
* Users admin page
*
@ -977,7 +1047,6 @@ readable.");
$size = 5000000;
$seek = fseek($fp,0-$size,SEEK_END);
if($seek === 0) {
fgets($fp); // throw away the first partial line
$data = escape_tags(fread($fp,$size));
while(! feof($fp))
$data .= escape_tags(fread($fp,4096));

View File

@ -5,25 +5,33 @@ require_once('include/socgraph.php');
function common_content(&$a) {
$o = '';
if(! local_user()) {
notice( t('Permission denied.') . EOL);
$cmd = $a->argv[1];
$uid = intval($a->argv[2]);
$cid = intval($a->argv[3]);
$zcid = 0;
if($cmd !== 'loc' && $cmd != 'rem')
return;
if(! $uid)
return;
if($cmd === 'loc' && $cid) {
$c = q("select name, url, photo from contact where id = %d and uid = %d limit 1",
intval($cid),
intval($uid)
);
}
if($a->argc > 1)
$cid = intval($a->argv[1]);
if(! $cid)
return;
$c = q("select name, url, photo from contact where id = %d and uid = %d limit 1",
intval($cid),
intval(local_user())
);
else {
$c = q("select name, url, photo from contact where self = 1 and uid = %d limit 1",
intval($uid)
);
}
$a->page['aside'] .= '<div class="vcard">'
. '<div class="fn label">' . $c[0]['name'] . '</div>'
. '<div id="profile-photo-wrapper">'
. '<a href="/contacts/' . $cid . '"><img class="photo" width="175" height="175"
. '<img class="photo" width="175" height="175"
src="' . $c[0]['photo'] . '" alt="' . $c[0]['name'] . '" /></div>'
. '</div>';
@ -33,13 +41,52 @@ function common_content(&$a) {
$o .= '<h2>' . t('Common Friends') . '</h2>';
// $o .= '<h3>' . sprintf( t('You and %s'),$c[0]['name']) . '</h3>';
if(! $cid) {
if(get_my_url()) {
$r = q("select id from contact where nurl = '%s' and uid = %d limit 1",
dbesc(normalise_link(get_my_url())),
intval($profile_uid)
);
if(count($r))
$cid = $r[0]['id'];
else {
$r = q("select id from gcontact where nurl = '%s' limit 1",
dbesc(normalise_link(get_my_url()))
);
if(count($r))
$zcid = $r[0]['id'];
}
}
}
$r = common_friends(local_user(),$cid);
if($cid == 0 && $zcid == 0)
return;
if($cid)
$t = count_common_friends($uid,$cid);
else
$t = count_common_friends_zcid($uid,$zcid);
$a->set_pager_total($t);
if(! $t) {
notice( t('No contacts in common.') . EOL);
return $o;
}
if($cid)
$r = common_friends($uid,$cid);
else
$r = common_friends_zcid($uid,$zcid);
if(! count($r)) {
$o .= t('No friends in common.');
return $o;
}

View File

@ -144,7 +144,7 @@ function contacts_content(&$a) {
goaway($a->get_baseurl(true) . '/contacts');
return; // NOTREACHED
}
if($cmd === 'update') {
// pull feed and consume it, which should subscribe to the hub.
@ -182,40 +182,27 @@ function contacts_content(&$a) {
return; // NOTREACHED
}
if($cmd === 'archive') {
$archived = (($orig_record[0]['archive']) ? 0 : 1);
$r = q("UPDATE `contact` SET `archive` = %d WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($archived),
intval($contact_id),
intval(local_user())
);
if($r) {
//notice( t('Contact has been ') . (($archived) ? t('archived') : t('unarchived')) . EOL );
info( (($archived) ? t('Contact has been archived') : t('Contact has been unarchived')) . EOL );
}
goaway($a->get_baseurl(true) . '/contacts/' . $contact_id);
return; // NOTREACHED
}
if($cmd === 'drop') {
// create an unfollow slap
require_once('include/Contact.php');
if($orig_record[0]['network'] === NETWORK_OSTATUS) {
$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() . ':unfollow:' . random_string(),
'$title' => '',
'$type' => 'text',
'$content' => t('stopped following'),
'$nick' => $a->user['nickname'],
'$verb' => 'http://ostatus.org/schema/1.0/unfollow', // ACTIVITY_UNFOLLOW,
'$ostat_follow' => '' // '<as:verb>http://ostatus.org/schema/1.0/unfollow</as:verb>' . "\r\n"
));
if((x($orig_record[0],'notify')) && (strlen($orig_record[0]['notify']))) {
require_once('include/salmon.php');
slapper($a->user,$orig_record[0]['notify'],$slap);
}
}
elseif($orig_record[0]['network'] === NETWORK_DIASPORA) {
require_once('include/diaspora.php');
diaspora_unshare($a->user,$orig_record[0]);
}
elseif($orig_record[0]['network'] === NETWORK_DFRN) {
require_once('include/items.php');
dfrn_deliver($a->user,$orig_record[0],'placeholder', 1);
}
terminate_friendship($a->user,$a->contact,$orig_record[0]);
contact_remove($orig_record[0]['id']);
info( t('Contact has been removed.') . EOL );
@ -303,16 +290,26 @@ function contacts_content(&$a) {
'label' => (($contact['blocked']) ? t('Unblock') : t('Block') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/block',
'sel' => '',
'title' => t('Toggle Blocked status'),
),
array(
'label' => (($contact['readonly']) ? t('Unignore') : t('Ignore') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/ignore',
'sel' => '',
'title' => t('Toggle Ignored status'),
),
array(
'label' => (($contact['archive']) ? t('Unarchive') : t('Archive') ),
'url' => $a->get_baseurl(true) . '/contacts/' . $contact_id . '/archive',
'sel' => '',
'title' => t('Toggle Archive status'),
),
array(
'label' => t('Repair'),
'url' => $a->get_baseurl(true) . '/crepair/' . $contact_id,
'sel' => '',
'title' => t('Advanced Contact Settings'),
)
);
$tab_tpl = get_markup_template('common_tabs.tpl');
@ -328,7 +325,7 @@ function contacts_content(&$a) {
'$lbl_info1' => t('Contact Information / Notes'),
'$infedit' => t('Edit contact notes'),
'$common_text' => $common_text,
'$common_link' => $a->get_baseurl(true) . '/common/' . $contact['id'],
'$common_link' => $a->get_baseurl(true) . '/common/loc/' . local_user() . '/' . $contact['id'],
'$all_friends' => $all_friends,
'$relation_text' => $relation_text,
'$visit' => sprintf( t('Visit %s\'s profile [%s]'),$contact['name'],$contact['url']),
@ -353,6 +350,7 @@ function contacts_content(&$a) {
'$info' => $contact['info'],
'$blocked' => (($contact['blocked']) ? t('Currently blocked') : ''),
'$ignored' => (($contact['readonly']) ? t('Currently ignored') : ''),
'$archived' => (($contact['archive']) ? t('Currently archived') : ''),
'$hidden' => array('hidden', t('Hide this contact from others'), ($contact['hidden'] == 1), t('Replies/likes to your public posts <strong>may</strong> still be visible')),
'$photo' => $contact['photo'],
'$name' => $contact['name'],
@ -394,6 +392,10 @@ function contacts_content(&$a) {
$sql_extra = " AND `readonly` = 1 ";
$ignored = true;
}
elseif(($a->argc == 2) && ($a->argv[1] === 'archived')) {
$sql_extra = " AND `archive` = 1 ";
$archived = true;
}
else
$sql_extra = " AND `blocked` = 0 ";
@ -405,34 +407,47 @@ function contacts_content(&$a) {
'label' => t('Suggestions'),
'url' => $a->get_baseurl(true) . '/suggest',
'sel' => '',
'title' => t('Suggest potential friends'),
),
array(
'label' => t('All Contacts'),
'url' => $a->get_baseurl(true) . '/contacts/all',
'sel' => ($all) ? 'active' : '',
'title' => t('Show all contacts'),
),
array(
'label' => t('Unblocked Contacts'),
'label' => t('Unblocked'),
'url' => $a->get_baseurl(true) . '/contacts',
'sel' => ((! $all) && (! $blocked) && (! $hidden) && (! $search) && (! $nets) && (! $ignored)) ? 'active' : '',
'sel' => ((! $all) && (! $blocked) && (! $hidden) && (! $search) && (! $nets) && (! $ignored) && (! $archived)) ? 'active' : '',
'title' => t('Only show unblocked contacts'),
),
array(
'label' => t('Blocked Contacts'),
'label' => t('Blocked'),
'url' => $a->get_baseurl(true) . '/contacts/blocked',
'sel' => ($blocked) ? 'active' : '',
'title' => t('Only show blocked contacts'),
),
array(
'label' => t('Ignored Contacts'),
'label' => t('Ignored'),
'url' => $a->get_baseurl(true) . '/contacts/ignored',
'sel' => ($ignored) ? 'active' : '',
'title' => t('Only show ignored contacts'),
),
array(
'label' => t('Hidden Contacts'),
'label' => t('Archived'),
'url' => $a->get_baseurl(true) . '/contacts/archived',
'sel' => ($archived) ? 'active' : '',
'title' => t('Only show archived contacts'),
),
array(
'label' => t('Hidden'),
'url' => $a->get_baseurl(true) . '/contacts/hidden',
'sel' => ($hidden) ? 'active' : '',
'title' => t('Only show hidden contacts'),
),
);

View File

@ -207,7 +207,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
if($duplex == 1)
$params['duplex'] = 1;
if($user['page-flags'] == PAGE_COMMUNITY)
if($user[0]['page-flags'] == PAGE_COMMUNITY)
$params['page'] = 1;
logger('dfrn_confirm: Confirm: posting data to ' . $dfrn_confirm . ': ' . print_r($params,true), LOGGER_DATA);
@ -434,7 +434,8 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
else
$contact = null;
if(isset($new_relation) && $new_relation == CONTACT_IS_FRIEND) {
if((isset($new_relation) && $new_relation == CONTACT_IS_FRIEND)) {
if(($contact) && ($contact['network'] === NETWORK_DIASPORA)) {
require_once('include/diaspora.php');
@ -447,7 +448,8 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
$r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
intval($uid)
);
if((count($r)) && ($activity) && (! $hidden)) {
if((count($r)) && ($r[0]['hide-friends'] == 0) && ($activity) && (! $hidden)) {
require_once('include/items.php');
@ -468,12 +470,15 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
$arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
$arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
$arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
$arr['verb'] = ACTIVITY_FRIEND;
$arr['object-type'] = ACTIVITY_OBJ_PERSON;
$A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
$APhoto = '[url=' . $self[0]['url'] . ']' . '[img]' . $self[0]['thumb'] . '[/img][/url]';
$B = '[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
$BPhoto = '[url=' . $contact['url'] . ']' . '[img]' . $contact['thumb'] . '[/img][/url]';
$arr['verb'] = ACTIVITY_FRIEND;
$arr['object-type'] = ACTIVITY_OBJ_PERSON;
$arr['body'] = sprintf( t('%1$s is now friends with %2$s'), $A, $B)."\n\n\n".$BPhoto;
$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $contact['name'] . '</title>'
@ -481,6 +486,7 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
$arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $contact['url'] . '" />' . "\n");
$arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $contact['thumb'] . '" />' . "\n");
$arr['object'] .= '</link></object>' . "\n";
$arr['last-child'] = 1;
$arr['allow_cid'] = $user[0]['allow_cid'];
@ -494,6 +500,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[0]['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.
@ -710,6 +726,10 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
WHERE `contact`.`id` = %d LIMIT 1",
intval($dfrn_record)
);
if(count($r))
$combined = $r[0];
if((count($r)) && ($r[0]['notify-flags'] & NOTIFY_CONFIRM)) {
push_lang($r[0]['language']);
@ -738,6 +758,65 @@ function dfrn_confirm_post(&$a,$handsfree = null) {
}
pop_lang();
}
// Send a new friend post if we are allowed to...
if($page && intval(get_pconfig($local_uid,'system','post_joingroup'))) {
$r = q("SELECT `hide-friends` FROM `profile` WHERE `uid` = %d AND `is-default` = 1 LIMIT 1",
intval($local_uid)
);
if((count($r)) && ($r[0]['hide-friends'] == 0)) {
require_once('include/items.php');
$self = q("SELECT * FROM `contact` WHERE `self` = 1 AND `uid` = %d LIMIT 1",
intval($local_uid)
);
if(count($self)) {
$arr = array();
$arr['uri'] = $arr['parent-uri'] = item_new_uri($a->get_hostname(), $local_uid);
$arr['uid'] = $local_uid;
$arr['contact-id'] = $self[0]['id'];
$arr['wall'] = 1;
$arr['type'] = 'wall';
$arr['gravity'] = 0;
$arr['origin'] = 1;
$arr['author-name'] = $arr['owner-name'] = $self[0]['name'];
$arr['author-link'] = $arr['owner-link'] = $self[0]['url'];
$arr['author-avatar'] = $arr['owner-avatar'] = $self[0]['thumb'];
$A = '[url=' . $self[0]['url'] . ']' . $self[0]['name'] . '[/url]';
$APhoto = '[url=' . $self[0]['url'] . ']' . '[img]' . $self[0]['thumb'] . '[/img][/url]';
$B = '[url=' . $combined['url'] . ']' . $combined['name'] . '[/url]';
$BPhoto = '[url=' . $combined['url'] . ']' . '[img]' . $combined['thumb'] . '[/img][/url]';
$arr['verb'] = ACTIVITY_JOIN;
$arr['object-type'] = ACTIVITY_OBJ_GROUP;
$arr['body'] = sprintf( t('%1$s has joined %2$s'), $A, $B)."\n\n\n" .$BPhoto;
$arr['object'] = '<object><type>' . ACTIVITY_OBJ_GROUP . '</type><title>' . $combined['name'] . '</title>'
. '<id>' . $combined['url'] . '/' . $combined['name'] . '</id>';
$arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $combined['url'] . '" />' . "\n");
$arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $combined['thumb'] . '" />' . "\n");
$arr['object'] .= '</link></object>' . "\n";
$arr['last-child'] = 1;
$arr['allow_cid'] = $user[0]['allow_cid'];
$arr['allow_gid'] = $user[0]['allow_gid'];
$arr['deny_cid'] = $user[0]['deny_cid'];
$arr['deny_gid'] = $user[0]['deny_gid'];
$i = item_store($arr);
if($i)
proc_run('php',"include/notifier.php","activity","$i");
}
}
}
xml_status(0); // Success
return; // NOTREACHED

View File

@ -314,7 +314,7 @@ function dfrn_request_post(&$a) {
if($email_follow) {
if(! strpos($url,'@')) {
if(! validate_email($url)) {
notice( t('Invalid email address.') . EOL);
return;
}
@ -346,11 +346,79 @@ function dfrn_request_post(&$a) {
}
}
$r = q("insert into contact ( uid, created, addr, name, nick, url, nurl, poll, notify, blocked, pending, network, rel )
values( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d ) ",
intval($uid),
dbesc(datetime_convert()),
dbesc($addr),
dbesc($name),
dbesc($nick),
dbesc($url),
dbesc($nurl),
dbesc($poll),
dbesc($notify),
intval($blocked),
intval($pending),
dbesc($network),
intval($rel)
);
$r = q("select id from contact where poll = '%s' and uid = %d limit 1",
dbesc($poll),
intval($uid)
);
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
`photo` = '%s',
`thumb` = '%s',
`micro` = '%s',
`name-date` = '%s',
`uri-date` = '%s',
`avatar-date` = '%s',
`hidden` = 0,
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)
);
}
// contact is created. Now create an introduction
$hash = random_string();
$r = q("insert into intro ( uid, `contact-id`, knowyou, note, hash, datetime, blocked )
values( %d , %d, %d, '%s', '%s', '%s', %d ) ",
intval($uid),
intval($contact_id),
((x($_POST,'knowyou') && ($_POST['knowyou'] == 1)) ? 1 : 0),
dbesc(notags(trim($_POST['dfrn-request-message']))),
dbesc($hash),
dbesc(datetime_convert()),
1
);
// Next send an email verify form to the requestor.
}
else {
// Canonicalise email-style profile locator
@ -640,7 +708,8 @@ function dfrn_request_content(&$a) {
'node' => $r[0]['nickname'],
'dfrn_id' => $r[0]['issued-id'],
'intro_id' => $intro[0]['id'],
'duplex' => (($r[0]['page-flags'] == PAGE_FREELOVE) ? 1 : 0)
'duplex' => (($r[0]['page-flags'] == PAGE_FREELOVE) ? 1 : 0),
'activity' => intval(get_pconfig($r[0]['uid'],'system','post_newfriend'))
);
dfrn_confirm_post($a,$handsfree);
}
@ -693,6 +762,11 @@ function dfrn_request_content(&$a) {
$myaddr = ((x($_GET,'address')) ? $_GET['address'] : '');
}
// last, try a zrl
if(! strlen($myaddr))
$myaddr = get_my_url();
$target_addr = $a->profile['nickname'] . '@' . substr(z_root(), strpos(z_root(),'://') + 3 );

View File

@ -28,6 +28,9 @@ function events_post(&$a) {
$adjust = intval($_POST['adjust']);
$nofinish = intval($_POST['nofinish']);
// The default setting for the `private` field in event_store() is false, so mirror that
$private_event = false;
$start = sprintf('%d-%d-%d %d:%d:0',$startyear,$startmonth,$startday,$starthour,$startminute);
if($nofinish)
@ -65,14 +68,38 @@ function events_post(&$a) {
$share = ((intval($_POST['share'])) ? intval($_POST['share']) : 0);
$c = q("select id from contact where uid = %d and self = 1 limit 1",
intval(local_user())
);
if(count($c))
$self = $c[0]['id'];
else
$self = 0;
if($share) {
$str_group_allow = perms2str($_POST['group_allow']);
$str_contact_allow = perms2str($_POST['contact_allow']);
$str_group_deny = perms2str($_POST['group_deny']);
$str_contact_deny = perms2str($_POST['contact_deny']);
// Undo the pseudo-contact of self, since there are real contacts now
if( strpos($str_contact_allow, '<' . $self . '>') !== false )
{
$str_contact_allow = str_replace('<' . $self . '>', '', $str_contact_allow);
}
// Make sure to set the `private` field as true. This is necessary to
// have the posts show up correctly in Diaspora if an event is created
// as visible only to self at first, but then edited to display to others.
if( strlen($str_group_allow) or strlen($str_contact_allow) or strlen($str_group_deny) or strlen($str_contact_deny) )
{
$private_event = true;
}
}
else {
$str_contact_allow = '<' . local_user() . '>';
// Note: do not set `private` field for self-only events. It will
// keep even you from seeing them!
$str_contact_allow = '<' . $self . '>';
$str_group_allow = $str_contact_deny = $str_group_deny = '';
}
@ -91,6 +118,7 @@ function events_post(&$a) {
$datarray['allow_gid'] = $str_group_allow;
$datarray['deny_cid'] = $str_contact_deny;
$datarray['deny_gid'] = $str_group_deny;
$datarray['private'] = $private_event;
$datarray['id'] = $event_id;
$datarray['created'] = $created;
$datarray['edited'] = $edited;

View File

@ -7,12 +7,18 @@ function filerm_content(&$a) {
}
$term = unxmlify(trim($_GET['term']));
$cat = unxmlify(trim($_GET['cat']));
$category = (($cat) ? true : false);
if($category)
$term = $cat;
$item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
logger('filerm: tag ' . $term . ' item ' . $item_id);
if($item_id && strlen($term))
file_tag_unsave_file(local_user(),$item_id,$term);
file_tag_unsave_file(local_user(),$item_id,$term, $category);
if(x($_SESSION,'return_url'))
goaway($a->get_baseurl() . '/' . $_SESSION['return_url']);

View File

@ -10,7 +10,10 @@ function follow_init(&$a) {
// NOTREACHED
}
$uid = local_user();
$url = $orig_url = notags(trim($_REQUEST['url']));
$return_url = $_SESSION['return_url'];
// remove ajax junk, e.g. Twitter
@ -18,19 +21,25 @@ function follow_init(&$a) {
if(! allowed_url($url)) {
notice( t('Disallowed profile URL.') . EOL);
goaway($_SESSION['return_url']);
goaway($return_url);
// NOTREACHED
}
if(! $url) {
notice( t('Connect URL missing.') . EOL);
goaway($_SESSION['return_url']);
goaway($return_url);
// NOTREACHED
}
$arr = array('url' => $url, 'contact' => array());
$ret = probe_url($url);
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))
@ -46,11 +55,11 @@ function follow_init(&$a) {
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($_SESSION['return_url']);
goaway($return_url);
}
}
// This just confuses things, remove it
// This extra param just confuses things, remove it
if($ret['network'] === NETWORK_DIASPORA)
$ret['url'] = str_replace('?absolute=true','',$ret['url']);
@ -65,9 +74,11 @@ function follow_init(&$a) {
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('Unable to match @-style Identity Address with a known protocol or email contact');
goaway($_SESSION['return_url']);
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);
}
goaway($return_url);
}
if($ret['network'] === NETWORK_OSTATUS && get_config('system','ostatus_disabled')) {
@ -94,17 +105,18 @@ function follow_init(&$a) {
// indirect links or webfinger links
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `poll` = '%s' LIMIT 1",
intval(local_user()),
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(local_user())
intval($uid)
);
}
}
@ -118,7 +130,7 @@ function follow_init(&$a) {
$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(local_user()),
intval($uid),
dbesc(datetime_convert()),
dbesc($ret['url']),
dbesc(normalise_link($ret['url'])),
@ -142,21 +154,30 @@ function follow_init(&$a) {
$r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
dbesc($ret['url']),
intval(local_user())
intval($uid)
);
if(! count($r)) {
notice( t('Unable to retrieve contact information.') . EOL);
goaway($_SESSION['return_url']);
goaway($return_url);
// NOTREACHED
}
$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'],local_user(),$contact_id);
$photos = import_profile_photo($ret['photo'],$uid,$contact_id);
$r = q("UPDATE `contact` SET `photo` = '%s',
`thumb` = '%s',
@ -200,7 +221,7 @@ function follow_init(&$a) {
$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(local_user())
intval($uid)
);
if(count($r)) {
@ -215,9 +236,9 @@ function follow_init(&$a) {
}
}
if(strstr($_SESSION['return_url'],'contacts'))
if(strstr($return_url,'contacts'))
goaway($a->get_baseurl() . '/contacts/' . $contact_id);
goaway($_SESSION['return_url']);
goaway($return_url);
// NOTREACHED
}

View File

@ -18,10 +18,18 @@ function friendica_init(&$a) {
$admin = false;
}
$visible_plugins = array();
if(is_array($a->plugins) && count($a->plugins)) {
$r = q("select * from addon where hidden = 0");
if(count($r))
foreach($r as $rr)
$visible_plugins[] = $rr['name'];
}
$data = Array(
'version' => FRIENDICA_VERSION,
'url' => z_root(),
'plugins' => $a->plugins,
'plugins' => $visible_plugins,
'register_policy' => $register_policy[$a->config['register_policy']],
'admin' => $admin,
'site_name' => $a->config['sitename'],
@ -54,9 +62,18 @@ function friendica_content(&$a) {
$o .= '<p></p>';
if(count($a->plugins)) {
$visible_plugins = array();
if(is_array($a->plugins) && count($a->plugins)) {
$r = q("select * from addon where hidden = 0");
if(count($r))
foreach($r as $rr)
$visible_plugins[] = $rr['name'];
}
if(count($visible_plugins)) {
$o .= '<p>' . t('Installed plugins/addons/apps:') . '</p>';
$sorted = $a->plugins;
$sorted = $visible_plugins;
$s = '';
sort($sorted);
foreach($sorted as $p) {

View File

@ -444,9 +444,28 @@ function item_post(&$a) {
$tags[] = '@' . $parent_contact['nick'];
}
$tagged = array();
if(count($tags)) {
foreach($tags as $tag) {
handle_tag($a, $body, $inform, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag);
// If we already tagged 'Robert Johnson', don't try and tag 'Robert'.
// Robert Johnson should be first in the $tags array
$fullnametagged = false;
for($x = 0; $x < count($tagged); $x ++) {
if(stristr($tagged[$x],$tag . ' ')) {
$fullnametagged = true;
break;
}
}
if($fullnametagged)
continue;
$success = handle_tag($a, $body, $inform, $str_tags, (local_user()) ? local_user() : $profile_uid , $tag);
if($success)
$tagged[] = $tag;
}
}
@ -861,21 +880,27 @@ function item_content(&$a) {
* @param unknown_type $str_tags string to add the tag to
* @param unknown_type $profile_uid
* @param unknown_type $tag the tag to replace
*
* @return boolean true if replaced, false if not replaced
*/
function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) {
$replaced = false;
//is it a hash tag?
if(strpos($tag,'#') === 0) {
//if the tag is replaced...
if(strpos($tag,'[url='))
//...do nothing
return;
return $replaced;
//base tag has the tags name only
$basetag = str_replace('_',' ',substr($tag,1));
//create text for link
$newtag = '#[url=' . $a->get_baseurl() . '/search?search=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
$newtag = '#[url=' . $a->get_baseurl() . '/search?tag=' . rawurlencode($basetag) . ']' . $basetag . '[/url]';
//replace tag by the link
$body = str_replace($tag, $newtag, $body);
$replaced = true;
//is the link already in str_tags?
if(! stristr($str_tags,$newtag)) {
//append or set str_tags
@ -883,13 +908,13 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) {
$str_tags .= ',';
$str_tags .= $newtag;
}
return;
return $replaced;
}
//is it a person tag?
if(strpos($tag,'@') === 0) {
//is it already replaced?
if(strpos($tag,'[url='))
return;
return $replaced;
$stat = false;
//get the person's name
$name = substr($tag,1);
@ -965,6 +990,7 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) {
}
//if there is an url for this persons profile
if(isset($profile)) {
$replaced = true;
//create profile link
$profile = str_replace(',','%2c',$profile);
$newtag = '@[url=' . $profile . ']' . $newname . '[/url]';
@ -989,4 +1015,6 @@ function handle_tag($a, &$body, &$inform, &$str_tags, $profile_uid, $tag) {
}
}
}
return $replaced;
}

View File

@ -4,20 +4,7 @@ require_once('include/acl_selectors.php');
require_once('include/message.php');
function message_init(&$a) {
$tabs = array(
/*
array(
'label' => t('All'),
'url'=> $a->get_baseurl(true) . '/message',
'sel'=> ($a->argc == 1),
),
array(
'label' => t('Sent'),
'url' => $a->get_baseurl(true) . '/message/sent',
'sel'=> ($a->argv[1] == 'sent'),
),
*/
);
$tabs = array();
$new = array(
'label' => t('New Message'),
'url' => $a->get_baseurl(true) . '/message/new',
@ -29,6 +16,25 @@ function message_init(&$a) {
'$tabs'=>$tabs,
'$new'=>$new,
));
$base = $a->get_baseurl();
$a->page['htmlhead'] .= '<script src="' . $a->get_baseurl(true) . '/library/jquery_ac/friendica.complete.js" ></script>';
$a->page['htmlhead'] .= <<< EOT
<script>$(document).ready(function() {
var a;
a = $("#recip").autocomplete({
serviceUrl: '$base/acl',
width: 350,
onSelect: function(value,data) {
$("#recip-complete").val(data);
}
});
});
</script>
EOT;
}
@ -93,10 +99,6 @@ function message_content(&$a) {
$myprofile = $a->get_baseurl(true) . '/profile/' . $a->user['nickname'];
$tpl = get_markup_template('mail_head.tpl');
$header = replace_macros($tpl, array(
'$messages' => t('Messages'),
@ -170,12 +172,36 @@ function message_content(&$a) {
));
$preselect = (isset($a->argv[2])?array($a->argv[2]):false);
$prename = $preurl = $preid = '';
if($preselect) {
$r = q("select name, url, id from contact where uid = %d and id = %d limit 1",
intval(local_user()),
intval($a->argv[2])
);
if(count($r)) {
$prename = $r[0]['name'];
$preurl = $r[0]['url'];
$preid = $r[0]['id'];
}
}
$prefill = (($preselect) ? $prename : '');
// the ugly select box
$select = contact_select('messageto','message-to-select', $preselect, 4, true, false, false, 10);
$tpl = get_markup_template('prv_message.tpl');
$o .= replace_macros($tpl,array(
'$header' => t('Send Private Message'),
'$to' => t('To:'),
'$showinputs' => 'true',
'$prefill' => $prefill,
'$autocomp' => $autocomp,
'$preid' => $preid,
'$subject' => t('Subject:'),
'$subjtxt' => ((x($_REQUEST,'subject')) ? strip_tags($_REQUEST['subject']) : ''),
'$text' => ((x($_REQUEST,'body')) ? escape_tags(htmlspecialchars($_REQUEST['body'])) : ''),
@ -198,7 +224,7 @@ function message_content(&$a) {
$o .= $header;
$r = q("SELECT count(*) AS `total` FROM `mail`
WHERE `mail`.`uid` = %d AND `from-url` $eq '%s' GROUP BY `parent-uri` ORDER BY `created` DESC",
WHERE `mail`.`uid` = %d GROUP BY `parent-uri` ORDER BY `created` DESC",
intval(local_user()),
dbesc($myprofile)
);
@ -313,6 +339,29 @@ function message_content(&$a) {
$from_url = $a->get_baseurl(true) . '/redir/' . $message['contact-id'];
$sparkle = ' sparkle';
}
$Text = $message['body'];
$saved_image = '';
$img_start = strpos($Text,'[img]data:');
$img_end = strpos($Text,'[/img]');
if($img_start !== false && $img_end !== false && $img_end > $img_start) {
$start_fragment = substr($Text,0,$img_start);
$img_start += strlen('[img]');
$saved_image = substr($Text,$img_start,$img_end - $img_start);
$end_fragment = substr($Text,$img_end + strlen('[/img]'));
$Text = $start_fragment . '[!#saved_image#!]' . $end_fragment;
$search = '/\[url\=(.*?)\]\[!#saved_image#!\]\[\/url\]' . '/is';
$replace = '[url=' . z_path() . '/redir/' . $message['contact-id']
. '?f=1&url=' . '$1' . '][!#saved_image#!][/url]' ;
$Text = preg_replace($search,$replace,$Text);
if(strlen($saved_image))
$message['body'] = str_replace('[!#saved_image#!]', '[img]' . $saved_image . '[/img]',$Text);
}
$mails[] = array(
'id' => $message['id'],
'from_name' => template_escape($message['from-name']),
@ -328,9 +377,10 @@ function message_content(&$a) {
$seen = $message['seen'];
}
$select = $message['name'] . '<input type="hidden" name="messageto" value="' . $contact_id . '" />';
$parent = '<input type="hidden" name="replyto" value="' . $message['parent-uri'] . '" />';
$tpl = get_markup_template('mail_display.tpl');
$o = replace_macros($tpl, array(
@ -345,6 +395,7 @@ function message_content(&$a) {
// reply
'$header' => t('Send Reply'),
'$to' => t('To:'),
'$showinputs' => '',
'$subject' => t('Subject:'),
'$subjtxt' => template_escape($message['title']),
'$readonly' => ' readonly="readonly" style="background: #BBBBBB;" ',

View File

@ -171,37 +171,44 @@ function network_content(&$a, $update = 0) {
'label' => t('Commented Order'),
'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . ((x($_GET,'cid')) ? '?f=&cid=' . $_GET['cid'] : ''),
'sel'=>$all_active,
'title'=> t('Sort by Comment Date'),
),
array(
'label' => t('Posted Order'),
'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . '?f=&order=post' . ((x($_GET,'cid')) ? '&cid=' . $_GET['cid'] : ''),
'sel'=>$postord_active,
'title' => t('Sort by Post Date'),
),
array(
'label' => t('Personal'),
'url' => $a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&conv=1',
'sel' => $conv_active,
'title' => t('Posts that mention or involve you'),
),
array(
'label' => t('New'),
'url' => $a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . '/new' . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : ''),
'sel' => $new_active,
'title' => t('Activity Stream - by date'),
),
array(
'label' => t('Starred'),
'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&star=1',
'sel'=>$starred_active,
'title' => t('Favourite Posts'),
),
array(
'label' => t('Shared Links'),
'url'=>$a->get_baseurl(true) . '/' . str_replace('/new', '', $a->cmd) . ((x($_GET,'cid')) ? '/?f=&cid=' . $_GET['cid'] : '') . '&bmark=1',
'sel'=>$bookmarked_active,
'title'=> t('Interesting Links'),
),
// array(
// 'label' => t('Spam'),
// 'url'=>$a->get_baseurl(true) . '/network?f=&spam=1'
// 'sel'=> $spam_active,
// 'title' => t('Posts flagged as SPAM'),
// ),
@ -333,7 +340,7 @@ function network_content(&$a, $update = 0) {
info( t('Group is empty'));
}
$sql_extra = " AND `item`.`parent` IN ( SELECT DISTINCT(`parent`) FROM `item` WHERE 1 $sql_options AND ( `contact-id` IN ( $contact_str ) OR `allow_gid` REGEXP '<" . intval($group) . ">' ) and deleted = 0 ) ";
$sql_extra = " AND `item`.`parent` IN ( SELECT DISTINCT(`parent`) FROM `item` WHERE 1 $sql_options AND ( `contact-id` IN ( $contact_str ) OR `allow_gid` like '" . protect_sprintf('%<' . intval($group) . '>%') . "' ) and deleted = 0 ) ";
$o = '<h2>' . t('Group: ') . $r[0]['name'] . '</h2>' . $o;
}
elseif($cid) {
@ -391,9 +398,9 @@ function network_content(&$a, $update = 0) {
if(x($_GET,'search')) {
$search = escape_tags($_GET['search']);
$sql_extra .= sprintf(" AND ( `item`.`body` REGEXP '%s' OR `item`.`tag` REGEXP '%s' ) ",
dbesc(preg_quote($search)),
dbesc('\\]' . preg_quote($search) . '\\[')
$sql_extra .= sprintf(" AND ( `item`.`body` like '%s' OR `item`.`tag` like '%s' ) ",
dbesc(protect_sprintf('%' . $search . '%')),
dbesc(protect_sprintf('%]' . $search . '[%'))
);
}
if(strlen($file)) {
@ -405,10 +412,10 @@ function network_content(&$a, $update = 0) {
$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 . '\\]')
$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 . '\\]%'))
);
}

View File

@ -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");
header("Expires: " . gmdate("D, d M Y H:i:s", time() + (3600*24)) . " GMT");
header("Cache-Control: max-age=" . (3600*24));
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

View File

@ -134,6 +134,8 @@ function ping_init(&$a) {
function xmlize($href, $name, $url, $photo, $date, $seen, $message){
$data = array('href' => &$href, 'name' => &$name, 'url'=>&$url, 'photo'=>&$photo, 'date'=>&$date, 'seen'=>&$seen, 'messsage'=>&$message);
call_hooks('ping_xmlize', $data);
$notsxml = '<note href="%s" name="%s" url="%s" photo="%s" date="%s" seen="%s" >%s</note>';
return sprintf ( $notsxml,
xmlify($href), xmlify($name), xmlify($url), xmlify($photo), xmlify($date), xmlify($seen), xmlify($message)

View File

@ -32,6 +32,8 @@ function profile_init(&$a) {
profile_load($a,$which,$profile);
$userblock = (($a->profile['hidewall'] && (! local_user()) && (! remote_user())) ? true : false);
if((x($a->profile,'page-flags')) && ($a->profile['page-flags'] == PAGE_COMMUNITY)) {
$a->page['htmlhead'] .= '<meta name="friendica.community" content="true" />';
}
@ -41,8 +43,8 @@ function profile_init(&$a) {
$delegate = ((strstr($a->profile['openid'],'://')) ? $a->profile['openid'] : 'http://' . $a->profile['openid']);
$a->page['htmlhead'] .= '<link rel="openid.delegate" href="' . $delegate . '" />' . "\r\n";
}
if(! $blocked) {
// site block
if((! $blocked) && (! $userblock)) {
$keywords = ((x($a->profile,'pub_keywords')) ? $a->profile['pub_keywords'] : '');
$keywords = str_replace(array('#',',',' ',',,'),array('',' ',',',','),$keywords);
if(strlen($keywords))
@ -141,6 +143,10 @@ function profile_content(&$a, $update = 0) {
return $o;
}
$o .= common_friends_visitor_widget($a->profile['profile_uid']);
if(x($_SESSION,'new_member') && $_SESSION['new_member'] && $is_owner)
$o .= '<a href="newmember" id="newmember-tips" style="font-size: 1.2em;"><b>' . t('Tips for New Members') . '</b></a>' . EOL;

View File

@ -139,21 +139,49 @@ function profiles_post(&$a) {
$changes = array();
$value = '';
if($is_default) {
if($marital != $orig[0]['marital']) $changes[] = '&hearts; ' . t('Marital Status');
if($withchanged) $changes[] = '&hearts; ' . t('Romantic Partner');
if($work != $orig[0]['work']) $changes[] = t('Work/Employment');
if($religion != $orig[0]['religion']) $changes[] = t('Religion');
if($politic != $orig[0]['politic']) $changes[] = t('Political Views');
if($gender != $orig[0]['gender']) $changes[] = t('Gender');
if($sexual != $orig[0]['sexual']) $changes[] = t('Sexual Preference');
if($homepage != $orig[0]['homepage']) $changes[] = t('Homepage');
if($interest != $orig[0]['interest']) $changes[] = t('Interests');
if($marital != $orig[0]['marital']) {
$changes[] = '[color=#ff0000]&hearts;[/color] ' . t('Marital Status');
$value = $marital;
}
if($withchanged) {
$changes[] = '&hearts; ' . t('Romantic Partner');
$value = strip_tags($with);
}
if($work != $orig[0]['work']) {
$changes[] = t('Work/Employment');
}
if($religion != $orig[0]['religion']) {
$changes[] = t('Religion');
$value = $religion;
}
if($politic != $orig[0]['politic']) {
$changes[] = t('Political Views');
$value = $politic;
}
if($gender != $orig[0]['gender']) {
$changes[] = t('Gender');
$value = $gender;
}
if($sexual != $orig[0]['sexual']) {
$changes[] = t('Sexual Preference');
$value = $sexual;
}
if($homepage != $orig[0]['homepage']) {
$changes[] = t('Homepage');
$value = $homepage;
}
if($interest != $orig[0]['interest']) {
$changes[] = t('Interests');
$value = $interest;
}
if($address != $orig[0]['address'] || $locality != $orig[0]['locality'] || $region != $orig[0]['region']
|| $country_name != $orig[0]['country_name'])
$changes[] = t('Location');
|| $country_name != $orig[0]['country-name']) {
$changes[] = t('Location');
}
profile_activity($changes);
profile_activity($changes,$value);
}
@ -245,7 +273,7 @@ function profiles_post(&$a) {
}
function profile_activity($changed) {
function profile_activity($changed, $value) {
$a = get_app();
if(! local_user() || ! is_array($changed) || ! count($changed))
@ -289,7 +317,7 @@ function profile_activity($changed) {
foreach($changed as $ch) {
if(strlen($changes)) {
if ($z == ($t - 1))
$changes .= ' and ';
$changes .= t(' and ');
else
$changes .= ', ';
}
@ -299,7 +327,15 @@ function profile_activity($changed) {
$prof = '[url=' . $self[0]['url'] . '?tab=profile' . ']' . t('public profile') . '[/url]';
$arr['body'] = sprintf( t('%1$s has an updated %2$s, changing %3$s.'), $A, $prof, $changes);
if($t == 1 && strlen($value)) {
$message = sprintf( t('%1$s changed %2$s to &ldquo;%3$s&rdquo;'), $A, $changes, $value);
$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);
$arr['body'] = $message;
$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PROFILE . '</type><title>' . $self[0]['name'] . '</title>'
. '<id>' . $self[0]['url'] . '/' . $self[0]['name'] . '</id>';

View File

@ -87,11 +87,32 @@ function search_content(&$a) {
else
$search = ((x($_GET,'search')) ? notags(trim(rawurldecode($_GET['search']))) : '');
$tag = false;
if(x($_GET,'tag')) {
$tag = true;
$search = ((x($_GET,'tag')) ? notags(trim(rawurldecode($_GET['tag']))) : '');
}
$o .= search($search,'search-box','/search',((local_user()) ? true : false));
if(strpos($search,'#') === 0) {
$tag = true;
$search = substr($search,1);
}
if(! $search)
return $o;
if($tag)
$sql_extra = sprintf(" AND `item`.`tag` REGEXP '%s' ", dbesc('\\]' . preg_quote($search) . '\\['));
else
$sql_extra = sprintf(" AND `item`.`body` REGEXP '%s' ", dbesc(preg_quote($search)));
// Here is the way permissions work in the search module...
// Only public posts can be shown
// OR your own posts if you are a logged in member
@ -103,10 +124,8 @@ function search_content(&$a) {
AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND `item`.`private` = 0 AND `user`.`hidewall` = 0)
OR `item`.`uid` = %d )
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND ( `item`.`body` REGEXP '%s' OR `item`.`tag` REGEXP '%s' ) group by `item`.`uri` ",
intval(local_user()),
dbesc(preg_quote($search)),
dbesc('\\]' . preg_quote($search) . '\\[')
$sql_extra group by `item`.`uri` ",
intval(local_user())
);
if(count($r))
@ -127,18 +146,19 @@ function search_content(&$a) {
AND (( `item`.`allow_cid` = '' AND `item`.`allow_gid` = '' AND `item`.`deny_cid` = '' AND `item`.`deny_gid` = '' AND `item`.`private` = 0 AND `user`.`hidewall` = 0 )
OR `item`.`uid` = %d )
AND `contact`.`blocked` = 0 AND `contact`.`pending` = 0
AND ( `item`.`body` REGEXP '%s' OR `item`.`tag` REGEXP '%s' )
$sql_extra
group by `item`.`uri`
ORDER BY `received` DESC LIMIT %d , %d ",
intval(local_user()),
dbesc(preg_quote($search)),
dbesc('\\]' . preg_quote($search) . '\\['),
intval($a->pager['start']),
intval($a->pager['itemspage'])
);
$o .= '<h2>Search results for: ' . $search . '</h2>';
if($tag)
$o .= '<h2>Items tagged with: ' . $search . '</h2>';
else
$o .= '<h2>Search results for: ' . $search . '</h2>';
$o .= conversation($a,$r,'search',false);

View File

@ -75,6 +75,11 @@ EOT;
'label' => t('Export personal data'),
'url' => $a->get_baseurl(true) . '/uexport',
'selected' => ''
),
array(
'label' => t('Remove account'),
'url' => $a->get_baseurl(true) . '/removeme',
'selected' => ''
)
);
@ -325,6 +330,7 @@ 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);
@ -347,9 +353,9 @@ function settings_post(&$a) {
$hide_friends = (($_POST['hide-friends'] == 1) ? 1: 0);
$hidewall = (($_POST['hidewall'] == 1) ? 1: 0);
$post_newfriend = (($_POST['post_newfriend'] == 1) ? 1: 0);
$post_joingroup = (($_POST['post_joingroup'] == 1) ? 1: 0);
$post_profilechange = (($_POST['post_profilechange'] == 1) ? 1: 0);
$notify = 0;
if(x($_POST,'notify1'))
@ -431,10 +437,24 @@ function settings_post(&$a) {
set_pconfig(local_user(),'system','suggestme', $suggestme);
set_pconfig(local_user(),'system','post_newfriend', $post_newfriend);
set_pconfig(local_user(),'system','post_joingroup', $post_joingroup);
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),
@ -450,6 +470,7 @@ function settings_post(&$a) {
intval($maxreq),
intval($expire),
dbesc($openidserver),
intval($def_gid),
intval($blockwall),
intval($hidewall),
intval($blocktags),
@ -696,8 +717,8 @@ function settings_content(&$a) {
$allowed_themes_raw = explode(',',$allowed_themes_str);
$allowed_themes = array();
if(count($allowed_themes_raw))
foreach($allowed_themes_raw as $x)
if(strlen(trim($x)))
foreach($allowed_themes_raw as $x)
if(strlen(trim($x)) && is_dir("view/theme/$x"))
$allowed_themes[] = trim($x);
@ -797,6 +818,9 @@ function settings_content(&$a) {
$post_newfriend = get_pconfig(local_user(), 'system','post_newfriend');
$post_newfriend = (($post_newfriend===false)? '0': $post_newfriend); // default if not set: 0
$post_joingroup = get_pconfig(local_user(), 'system','post_joingroup');
$post_joingroup = (($post_joingroup===false)? '0': $post_joingroup); // default if not set: 0
$post_profilechange = get_pconfig(local_user(), 'system','post_profilechange');
$post_profilechange = (($post_profilechange===false)? '0': $post_profilechange); // default if not set: 0
@ -823,6 +847,13 @@ function settings_content(&$a) {
'$page_freelove' => array('page-flags', t('Automatic Friend Account'), 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'), PAGE_PRVGROUP,
t('Private forum - approved members only [Experimental]'),
($a->user['page-flags'] == PAGE_PRVGROUP)),
'$experimental' => ( (intval(get_config('system','prvgroup_testing'))) ? 'true' : ''),
));
$noid = get_config('system','no_openid');
@ -924,6 +955,9 @@ function settings_content(&$a) {
'photos' => array('expire_photos', t("Expire photos:"), $expire_photos, '', 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'),
@ -931,7 +965,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'),
@ -958,6 +991,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,
@ -971,6 +1008,7 @@ function settings_content(&$a) {
'$h_not' => t('Notification Settings'),
'$activity_options' => t('By default post a status message when:'),
'$post_newfriend' => array('post_newfriend', t('accepting a friend request'), $post_newfriend, ''),
'$post_joingroup' => array('post_joingroup', t('joining a forum/community'), $post_joingroup, ''),
'$post_profilechange' => array('post_profilechange', t('making an <em>interesting</em> profile change'), $post_profilechange, ''),
'$lbl_not' => t('Send a notification email when:'),
'$notify1' => array('notify1', t('You receive an introduction'), ($notify & NOTIFY_INTRO), NOTIFY_INTRO, ''),

View File

@ -66,14 +66,14 @@ function tagger_content(&$a) {
}
$uri = item_new_uri($a->get_hostname(),$owner_uid);
$xterm = xmlify($term);
$post_type = (($item['resource-id']) ? t('photo') : t('status'));
$targettype = (($item['resource-id']) ? ACTIVITY_OBJ_PHOTO : ACTIVITY_OBJ_NOTE );
$link = xmlify('<link rel="alternate" type="text/html" href="'
. $a->get_baseurl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
$body = $item['body'];
$body = xmlify($item['body']);
$target = <<< EOT
<target>
@ -86,7 +86,7 @@ function tagger_content(&$a) {
</target>
EOT;
$tagid = $a->get_baseurl() . '/search?search=' . $term;
$tagid = $a->get_baseurl() . '/search?tag=' . $term;
$objtype = ACTIVITY_OBJ_TAGTERM;
$obj = <<< EOT
@ -95,8 +95,8 @@ EOT;
<local>1</local>
<id>$tagid</id>
<link>$tagid</link>
<title>$term</title>
<content>$term</content>
<title>$xterm</title>
<content>$xterm</content>
</object>
EOT;
@ -105,7 +105,7 @@ EOT;
if(! isset($bodyverb))
return;
$termlink = html_entity_decode('&#x2317;') . '[url=' . $a->get_baseurl() . '/search?search=' . urlencode($term) . ']'. $term . '[/url]';
$termlink = html_entity_decode('&#x2317;') . '[url=' . $a->get_baseurl() . '/search?tag=' . urlencode($term) . ']'. $term . '[/url]';
$arr = array();
@ -161,7 +161,7 @@ EOT;
if((! $blocktags) && (! stristr($item['tag'], ']' . $term . '[' ))) {
q("update item set tag = '%s' where id = %d limit 1",
dbesc($item['tag'] . (strlen($item['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?search=' . $term . ']'. $term . '[/url]'),
dbesc($item['tag'] . (strlen($item['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?tag=' . $term . ']'. $term . '[/url]'),
intval($item['id'])
);
}
@ -177,7 +177,7 @@ EOT;
);
if(count($x) && !$x[0]['blocktags'] && (! stristr($r[0]['tag'], ']' . $term . '['))) {
q("update item set tag = '%s' where id = %d limit 1",
dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?search=' . $term . ']'. $term . '[/url]'),
dbesc($r[0]['tag'] . (strlen($r[0]['tag']) ? ',' : '') . '#[url=' . $a->get_baseurl() . '/search?tag=' . $term . ']'. $term . '[/url]'),
intval($r[0]['id'])
);
}

View File

@ -24,13 +24,13 @@ function viewcontacts_content(&$a) {
}
$r = q("SELECT COUNT(*) as `total` FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 ",
$r = q("SELECT COUNT(*) as `total` FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0 ",
intval($a->profile['uid'])
);
if(count($r))
$a->set_pager_total($r[0]['total']);
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 ORDER BY `name` ASC LIMIT %d , %d ",
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0 ORDER BY `name` ASC LIMIT %d , %d ",
intval($a->profile['uid']),
intval($a->pager['start']),
intval($a->pager['itemspage'])

Some files were not shown because too many files have changed in this diff Show More