mirror of
https://github.com/friendica/friendica
synced 2024-12-25 05:20:15 +00:00
Merge branch 'master' of github.com:annando/friendica
This commit is contained in:
commit
6342b3e0bd
915 changed files with 38082 additions and 88096 deletions
149
boot.php
149
boot.php
|
@ -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());
|
||||
$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, $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');
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
set_config('system','build', DB_UPDATE_VERSION);
|
||||
|
@ -726,10 +744,11 @@ if(! function_exists('check_config')) {
|
|||
if(! in_array($i['name'],$plugins_arr)) {
|
||||
uninstall_plugin($i['name']);
|
||||
}
|
||||
else
|
||||
else {
|
||||
$installed_arr[] = $i['name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($plugins_arr)) {
|
||||
foreach($plugins_arr as $p) {
|
||||
|
@ -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>' ;
|
||||
}
|
||||
$o .= '</div></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;
|
||||
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -1262,14 +1282,23 @@ 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
19
convert_innodb.sql
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
ALTER TABLE `profile` DROP INDEX `pub_keywords` ;
|
||||
ALTER TABLE `profile` DROP INDEX `prv_keywords` ;
|
||||
|
||||
ALTER TABLE `item` DROP INDEX `title` ;
|
||||
ALTER TABLE `item` DROP INDEX `body` ;
|
||||
ALTER TABLE `item` DROP INDEX `allow_cid` ;
|
||||
ALTER TABLE `item` DROP INDEX `allow_gid` ;
|
||||
ALTER TABLE `item` DROP INDEX `deny_cid` ;
|
||||
ALTER TABLE `item` DROP INDEX `deny_gid` ;
|
||||
ALTER TABLE `item` DROP INDEX `tag` ;
|
||||
ALTER TABLE `item` DROP INDEX `file` ;
|
||||
|
||||
|
||||
SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' engine=InnoDB;')
|
||||
FROM information_schema.tables
|
||||
WHERE engine = 'MyISAM';
|
||||
|
15
database.sql
15
database.sql
|
@ -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;
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
|
|
@ -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 |
|
@ -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);
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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('/\[\&\;([#a-z0-9]+)\;\]/','&$1;',$Text);
|
||||
|
||||
// fix any escaped ampersands that may have been converted into links
|
||||
$Text = preg_replace("/\<(.*?)(src|href)=(.*?)\&\;(.*?)\>/ism",'<$1$2=$3&$4>',$Text);
|
||||
if(strlen($saved_image))
|
||||
|
|
|
@ -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'",
|
||||
|
|
|
@ -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
|
||||
));
|
||||
|
||||
};
|
|
@ -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,7 +450,7 @@ function conversation(&$a, $items, $mode, $update, $preview = false) {
|
|||
else {
|
||||
|
||||
// prevent private email reply to public conversation from leaking.
|
||||
if($item['private'] && ! $threads[$threadsid]['private'])
|
||||
if($item['network'] === NETWORK_MAIL && local_user() != $item['uid'])
|
||||
continue;
|
||||
|
||||
$comments_seen ++;
|
||||
|
@ -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'),
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -38,7 +38,10 @@ function delivery_run($argv, $argc){
|
|||
|
||||
$cmd = $argv[1];
|
||||
$item_id = intval($argv[2]);
|
||||
$contact_id = intval($argv[3]);
|
||||
|
||||
for($x = 3; $x < $argc; $x ++) {
|
||||
|
||||
$contact_id = intval($argv[x]);
|
||||
|
||||
// Some other process may have delivered this item already.
|
||||
|
||||
|
@ -48,8 +51,19 @@ function delivery_run($argv, $argc){
|
|||
dbesc($contact_id)
|
||||
);
|
||||
if(! count($r)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
}
|
||||
|
||||
// It's ours to deliver. Remove it from the queue.
|
||||
|
||||
|
@ -60,7 +74,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if((! $item_id) || (! $contact_id))
|
||||
return;
|
||||
continue;
|
||||
|
||||
$expire = false;
|
||||
$top_level = false;
|
||||
|
@ -81,7 +95,7 @@ function delivery_run($argv, $argc){
|
|||
$uid = $item_id;
|
||||
$item_id = 0;
|
||||
if(! count($items))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
|
||||
|
@ -91,7 +105,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if((! count($r)) || (! intval($r[0]['parent']))) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
$target_item = $r[0];
|
||||
|
@ -100,7 +114,7 @@ function delivery_run($argv, $argc){
|
|||
$updated = $r[0]['edited'];
|
||||
|
||||
if(! $parent_id)
|
||||
return;
|
||||
continue;
|
||||
|
||||
|
||||
$items = q("SELECT `item`.*, `sign`.`signed_text`,`sign`.`signature`,`sign`.`signer`
|
||||
|
@ -109,7 +123,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if(! count($items)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
$icontacts = null;
|
||||
|
@ -124,7 +138,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
}
|
||||
if( ! ($icontacts && count($icontacts)))
|
||||
return;
|
||||
continue;
|
||||
|
||||
// avoid race condition with deleting entries
|
||||
|
||||
|
@ -148,7 +162,7 @@ function delivery_run($argv, $argc){
|
|||
);
|
||||
|
||||
if(! count($r))
|
||||
return;
|
||||
continue;
|
||||
|
||||
$owner = $r[0];
|
||||
|
||||
|
@ -198,7 +212,7 @@ function delivery_run($argv, $argc){
|
|||
logger('relay denied for delivery agent.');
|
||||
|
||||
/* no relay allowed for direct contact delivery */
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((strlen($parent['allow_cid']))
|
||||
|
@ -222,7 +236,7 @@ function delivery_run($argv, $argc){
|
|||
require_once('include/salmon.php');
|
||||
|
||||
if($contact['self'])
|
||||
return;
|
||||
continue;
|
||||
|
||||
$deliver_status = 0;
|
||||
|
||||
|
@ -336,7 +350,10 @@ function delivery_run($argv, $argc){
|
|||
}
|
||||
}
|
||||
|
||||
if(! was_recently_delayed($contact['id']))
|
||||
$deliver_status = dfrn_deliver($owner,$contact,$atom);
|
||||
else
|
||||
$deliver_status = (-1);
|
||||
|
||||
logger('notifier: dfrn_delivery returns ' . $deliver_status);
|
||||
|
||||
|
@ -379,7 +396,11 @@ function delivery_run($argv, $argc){
|
|||
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);
|
||||
|
@ -519,6 +540,7 @@ function delivery_run($argv, $argc){
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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')))
|
||||
if(was_recently_delayed($contact['id'])) {
|
||||
$return_code = 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
$return_code = $a->get_curl_code();
|
||||
logger('diaspora_transmit: ' . $logid . ' returns: ' . $return_code);
|
||||
|
||||
if((! $return_code) || (($return_code == 503) && (stristr($a->get_curl_headers(),'retry-after')))) {
|
||||
|
|
|
@ -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)."-"
|
||||
|
|
|
@ -32,6 +32,10 @@ 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");
|
||||
|
||||
// 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
65
include/gprobe.php
Normal 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();
|
||||
}
|
|
@ -97,7 +97,8 @@ function group_rmv_member($uid,$name,$member) {
|
|||
}
|
||||
|
||||
|
||||
function group_add_member($uid,$name,$member) {
|
||||
function group_add_member($uid,$name,$member,$gid = 0) {
|
||||
if(! $gid)
|
||||
$gid = group_byname($uid,$name);
|
||||
if((! $gid) || (! $uid) || (! $member))
|
||||
return false;
|
||||
|
@ -154,6 +155,32 @@ function group_public_members($gid) {
|
|||
}
|
||||
|
||||
|
||||
function mini_group_select($uid,$gid = 0) {
|
||||
|
||||
$grps = array();
|
||||
$o = '';
|
||||
|
||||
$r = q("SELECT * FROM `group` WHERE `deleted` = 0 AND `uid` = %d ORDER BY `name` ASC",
|
||||
intval($uid)
|
||||
);
|
||||
$grps[] = array('name' => '', 'id' => '0', 'selected' => '');
|
||||
if(count($r)) {
|
||||
foreach($r as $rr) {
|
||||
$grps[] = array('name' => $rr['name'], 'id' => $rr['id'], 'selected' => (($gid == $rr['id']) ? 'true' : ''));
|
||||
}
|
||||
|
||||
}
|
||||
logger('groups: ' . print_r($grps,true));
|
||||
|
||||
$o = replace_macros(get_markup_template('group_selection.tpl'), array(
|
||||
'$label' => t('Default privacy group for new contacts'),
|
||||
'$groups' => $grps
|
||||
));
|
||||
return $o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function group_side($every="contacts",$each="group",$edit = false, $group_id = 0, $cid = 0) {
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,8 +2243,8 @@ 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);
|
||||
|
||||
$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",
|
||||
dbesc($item_id),
|
||||
|
@ -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';
|
||||
|
@ -2291,25 +2315,33 @@ 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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
523
include/onepoll.php
Normal 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();
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
proc_run('php','include/onepoll.php',$contact['id']);
|
||||
if($interval)
|
||||
@time_sleep_until(microtime(true) + (float) $interval);
|
||||
}
|
||||
}
|
||||
|
||||
$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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,9 +7,11 @@ function gender_selector($current="",$suffix="") {
|
|||
|
||||
$o .= "<select name=\"gender$suffix\" id=\"gender-select$suffix\" size=\"1\" >";
|
||||
foreach($select as $selection) {
|
||||
if($selection !== 'NOTRANSLATION') {
|
||||
$selected = (($selection == $current) ? ' selected="selected" ' : '');
|
||||
$o .= "<option value=\"$selection\" $selected >$selection</option>";
|
||||
}
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
|
@ -20,9 +22,11 @@ function sexpref_selector($current="",$suffix="") {
|
|||
|
||||
$o .= "<select name=\"sexual$suffix\" id=\"sexual-select$suffix\" size=\"1\" >";
|
||||
foreach($select as $selection) {
|
||||
if($selection !== 'NOTRANSLATION') {
|
||||
$selected = (($selection == $current) ? ' selected="selected" ' : '');
|
||||
$o .= "<option value=\"$selection\" $selected >$selection</option>";
|
||||
}
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
|
@ -34,9 +38,11 @@ function marital_selector($current="",$suffix="") {
|
|||
|
||||
$o .= "<select name=\"marital\" id=\"marital-select\" size=\"1\" >";
|
||||
foreach($select as $selection) {
|
||||
if($selection !== 'NOTRANSLATION') {
|
||||
$selected = (($selection == $current) ? ' selected="selected" ' : '');
|
||||
$o .= "<option value=\"$selection\" $selected >$selection</option>";
|
||||
}
|
||||
}
|
||||
$o .= '</select>';
|
||||
return $o;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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",
|
||||
intval($cid),
|
||||
intval($uid),
|
||||
intval($gcid)
|
||||
);
|
||||
if(! count($r)) {
|
||||
q("insert into glink ( `cid`,`uid`,`gcid`,`updated`) values (%d,%d,%d,'%s') ",
|
||||
$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($zcid)
|
||||
);
|
||||
if(! count($r)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,13 +1467,17 @@ 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;
|
||||
|
||||
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),
|
||||
intval($uid)
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
16
js/main.js
16
js/main.js
|
@ -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
4
library/jquery_ac/README
Normal file
|
@ -0,0 +1,4 @@
|
|||
This is jquery.autocomplete from
|
||||
|
||||
http://www.devbridge.com/projects/autocomplete/jquery/
|
||||
|
395
library/jquery_ac/friendica.complete.js
Normal file
395
library/jquery_ac/friendica.complete.js
Normal 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 + '" /> ';
|
||||
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
19
library/jquery_ac/jquery-1.3.2.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
11
library/jquery_ac/jquery.autocomplete-min.js
vendored
Normal file
11
library/jquery_ac/jquery.autocomplete-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
390
library/jquery_ac/jquery.autocomplete.js
Normal file
390
library/jquery_ac/jquery.autocomplete.js
Normal 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));
|
BIN
library/jquery_ac/shadow.png
Normal file
BIN
library/jquery_ac/shadow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
6
library/jquery_ac/styles.css
Normal file
6
library/jquery_ac/styles.css
Normal 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; }
|
1708
library/langdet/Text/LanguageDetect.php
Normal file
1708
library/langdet/Text/LanguageDetect.php
Normal file
File diff suppressed because it is too large
Load diff
57
library/langdet/Text/LanguageDetect/Exception.php
Normal file
57
library/langdet/Text/LanguageDetect/Exception.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
class Text_LanguageDetect_Exception extends Exception
|
||||
{
|
||||
/**
|
||||
* Database file could not be found
|
||||
*/
|
||||
const DB_NOT_FOUND = 10;
|
||||
|
||||
/**
|
||||
* Database file found, but not readable
|
||||
*/
|
||||
const DB_NOT_READABLE = 11;
|
||||
|
||||
/**
|
||||
* Database file is empty
|
||||
*/
|
||||
const DB_EMPTY = 12;
|
||||
|
||||
/**
|
||||
* Database contents is not a PHP array
|
||||
*/
|
||||
const DB_NOT_ARRAY = 13;
|
||||
|
||||
/**
|
||||
* Magic quotes are activated
|
||||
*/
|
||||
const MAGIC_QUOTES = 14;
|
||||
|
||||
|
||||
/**
|
||||
* Parameter of invalid type passed to method
|
||||
*/
|
||||
const PARAM_TYPE = 20;
|
||||
|
||||
/**
|
||||
* Character in parameter is invalid
|
||||
*/
|
||||
const INVALID_CHAR = 21;
|
||||
|
||||
|
||||
/**
|
||||
* Language is not in the database
|
||||
*/
|
||||
const UNKNOWN_LANGUAGE = 30;
|
||||
|
||||
|
||||
/**
|
||||
* Error during block detection
|
||||
*/
|
||||
const BLOCK_DETECTION = 40;
|
||||
|
||||
|
||||
/**
|
||||
* Error while clustering languages
|
||||
*/
|
||||
const NO_HIGHEST_KEY = 50;
|
||||
}
|
341
library/langdet/Text/LanguageDetect/ISO639.php
Normal file
341
library/langdet/Text/LanguageDetect/ISO639.php
Normal file
|
@ -0,0 +1,341 @@
|
|||
<?php
|
||||
/**
|
||||
* Part of Text_LanguageDetect
|
||||
*
|
||||
* PHP version 5
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @copyright 2011 Christian Weiske <cweiske@php.net>
|
||||
* @license http://www.debian.org/misc/bsd.license BSD
|
||||
* @version SVN: $Id$
|
||||
* @link http://pear.php.net/package/Text_LanguageDetect/
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides a mapping between the languages from lang.dat and the
|
||||
* ISO 639-1 and ISO-639-2 codes.
|
||||
*
|
||||
* Note that this class contains only languages that exist in lang.dat.
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Christian Weiske <cweiske@php.net>
|
||||
* @copyright 2011 Christian Weiske <cweiske@php.net>
|
||||
* @license http://www.debian.org/misc/bsd.license BSD
|
||||
* @link http://www.loc.gov/standards/iso639-2/php/code_list.php
|
||||
*/
|
||||
class Text_LanguageDetect_ISO639
|
||||
{
|
||||
/**
|
||||
* Maps all language names from the language database to the
|
||||
* ISO 639-1 2-letter language code.
|
||||
*
|
||||
* NULL indicates that there is no 2-letter code.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $nameToCode2 = array(
|
||||
'albanian' => 'sq',
|
||||
'arabic' => 'ar',
|
||||
'azeri' => 'az',
|
||||
'bengali' => 'bn',
|
||||
'bulgarian' => 'bg',
|
||||
'cebuano' => null,
|
||||
'croatian' => 'hr',
|
||||
'czech' => 'cs',
|
||||
'danish' => 'da',
|
||||
'dutch' => 'nl',
|
||||
'english' => 'en',
|
||||
'estonian' => 'et',
|
||||
'farsi' => 'fa',
|
||||
'finnish' => 'fi',
|
||||
'french' => 'fr',
|
||||
'german' => 'de',
|
||||
'hausa' => 'ha',
|
||||
'hawaiian' => null,
|
||||
'hindi' => 'hi',
|
||||
'hungarian' => 'hu',
|
||||
'icelandic' => 'is',
|
||||
'indonesian' => 'id',
|
||||
'italian' => 'it',
|
||||
'kazakh' => 'kk',
|
||||
'kyrgyz' => 'ky',
|
||||
'latin' => 'la',
|
||||
'latvian' => 'lv',
|
||||
'lithuanian' => 'lt',
|
||||
'macedonian' => 'mk',
|
||||
'mongolian' => 'mn',
|
||||
'nepali' => 'ne',
|
||||
'norwegian' => 'no',
|
||||
'pashto' => 'ps',
|
||||
'pidgin' => null,
|
||||
'polish' => 'pl',
|
||||
'portuguese' => 'pt',
|
||||
'romanian' => 'ro',
|
||||
'russian' => 'ru',
|
||||
'serbian' => 'sr',
|
||||
'slovak' => 'sk',
|
||||
'slovene' => 'sl',
|
||||
'somali' => 'so',
|
||||
'spanish' => 'es',
|
||||
'swahili' => 'sw',
|
||||
'swedish' => 'sv',
|
||||
'tagalog' => 'tl',
|
||||
'turkish' => 'tr',
|
||||
'ukrainian' => 'uk',
|
||||
'urdu' => 'ur',
|
||||
'uzbek' => 'uz',
|
||||
'vietnamese' => 'vi',
|
||||
'welsh' => 'cy',
|
||||
);
|
||||
|
||||
/**
|
||||
* Maps all language names from the language database to the
|
||||
* ISO 639-2 3-letter language code.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $nameToCode3 = array(
|
||||
'albanian' => 'sqi',
|
||||
'arabic' => 'ara',
|
||||
'azeri' => 'aze',
|
||||
'bengali' => 'ben',
|
||||
'bulgarian' => 'bul',
|
||||
'cebuano' => 'ceb',
|
||||
'croatian' => 'hrv',
|
||||
'czech' => 'ces',
|
||||
'danish' => 'dan',
|
||||
'dutch' => 'nld',
|
||||
'english' => 'eng',
|
||||
'estonian' => 'est',
|
||||
'farsi' => 'fas',
|
||||
'finnish' => 'fin',
|
||||
'french' => 'fra',
|
||||
'german' => 'deu',
|
||||
'hausa' => 'hau',
|
||||
'hawaiian' => 'haw',
|
||||
'hindi' => 'hin',
|
||||
'hungarian' => 'hun',
|
||||
'icelandic' => 'isl',
|
||||
'indonesian' => 'ind',
|
||||
'italian' => 'ita',
|
||||
'kazakh' => 'kaz',
|
||||
'kyrgyz' => 'kir',
|
||||
'latin' => 'lat',
|
||||
'latvian' => 'lav',
|
||||
'lithuanian' => 'lit',
|
||||
'macedonian' => 'mkd',
|
||||
'mongolian' => 'mon',
|
||||
'nepali' => 'nep',
|
||||
'norwegian' => 'nor',
|
||||
'pashto' => 'pus',
|
||||
'pidgin' => 'crp',
|
||||
'polish' => 'pol',
|
||||
'portuguese' => 'por',
|
||||
'romanian' => 'ron',
|
||||
'russian' => 'rus',
|
||||
'serbian' => 'srp',
|
||||
'slovak' => 'slk',
|
||||
'slovene' => 'slv',
|
||||
'somali' => 'som',
|
||||
'spanish' => 'spa',
|
||||
'swahili' => 'swa',
|
||||
'swedish' => 'swe',
|
||||
'tagalog' => 'tgl',
|
||||
'turkish' => 'tur',
|
||||
'ukrainian' => 'ukr',
|
||||
'urdu' => 'urd',
|
||||
'uzbek' => 'uzb',
|
||||
'vietnamese' => 'vie',
|
||||
'welsh' => 'cym',
|
||||
);
|
||||
|
||||
/**
|
||||
* Maps ISO 639-1 2-letter language codes to the language names
|
||||
* in the language database
|
||||
*
|
||||
* Not all languages have a 2 letter code, so some are missing
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $code2ToName = array(
|
||||
'ar' => 'arabic',
|
||||
'az' => 'azeri',
|
||||
'bg' => 'bulgarian',
|
||||
'bn' => 'bengali',
|
||||
'cs' => 'czech',
|
||||
'cy' => 'welsh',
|
||||
'da' => 'danish',
|
||||
'de' => 'german',
|
||||
'en' => 'english',
|
||||
'es' => 'spanish',
|
||||
'et' => 'estonian',
|
||||
'fa' => 'farsi',
|
||||
'fi' => 'finnish',
|
||||
'fr' => 'french',
|
||||
'ha' => 'hausa',
|
||||
'hi' => 'hindi',
|
||||
'hr' => 'croatian',
|
||||
'hu' => 'hungarian',
|
||||
'id' => 'indonesian',
|
||||
'is' => 'icelandic',
|
||||
'it' => 'italian',
|
||||
'kk' => 'kazakh',
|
||||
'ky' => 'kyrgyz',
|
||||
'la' => 'latin',
|
||||
'lt' => 'lithuanian',
|
||||
'lv' => 'latvian',
|
||||
'mk' => 'macedonian',
|
||||
'mn' => 'mongolian',
|
||||
'ne' => 'nepali',
|
||||
'nl' => 'dutch',
|
||||
'no' => 'norwegian',
|
||||
'pl' => 'polish',
|
||||
'ps' => 'pashto',
|
||||
'pt' => 'portuguese',
|
||||
'ro' => 'romanian',
|
||||
'ru' => 'russian',
|
||||
'sk' => 'slovak',
|
||||
'sl' => 'slovene',
|
||||
'so' => 'somali',
|
||||
'sq' => 'albanian',
|
||||
'sr' => 'serbian',
|
||||
'sv' => 'swedish',
|
||||
'sw' => 'swahili',
|
||||
'tl' => 'tagalog',
|
||||
'tr' => 'turkish',
|
||||
'uk' => 'ukrainian',
|
||||
'ur' => 'urdu',
|
||||
'uz' => 'uzbek',
|
||||
'vi' => 'vietnamese',
|
||||
);
|
||||
|
||||
/**
|
||||
* Maps ISO 639-2 3-letter language codes to the language names
|
||||
* in the language database.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $code3ToName = array(
|
||||
'ara' => 'arabic',
|
||||
'aze' => 'azeri',
|
||||
'ben' => 'bengali',
|
||||
'bul' => 'bulgarian',
|
||||
'ceb' => 'cebuano',
|
||||
'ces' => 'czech',
|
||||
'crp' => 'pidgin',
|
||||
'cym' => 'welsh',
|
||||
'dan' => 'danish',
|
||||
'deu' => 'german',
|
||||
'eng' => 'english',
|
||||
'est' => 'estonian',
|
||||
'fas' => 'farsi',
|
||||
'fin' => 'finnish',
|
||||
'fra' => 'french',
|
||||
'hau' => 'hausa',
|
||||
'haw' => 'hawaiian',
|
||||
'hin' => 'hindi',
|
||||
'hrv' => 'croatian',
|
||||
'hun' => 'hungarian',
|
||||
'ind' => 'indonesian',
|
||||
'isl' => 'icelandic',
|
||||
'ita' => 'italian',
|
||||
'kaz' => 'kazakh',
|
||||
'kir' => 'kyrgyz',
|
||||
'lat' => 'latin',
|
||||
'lav' => 'latvian',
|
||||
'lit' => 'lithuanian',
|
||||
'mkd' => 'macedonian',
|
||||
'mon' => 'mongolian',
|
||||
'nep' => 'nepali',
|
||||
'nld' => 'dutch',
|
||||
'nor' => 'norwegian',
|
||||
'pol' => 'polish',
|
||||
'por' => 'portuguese',
|
||||
'pus' => 'pashto',
|
||||
'rom' => 'romanian',
|
||||
'rus' => 'russian',
|
||||
'slk' => 'slovak',
|
||||
'slv' => 'slovene',
|
||||
'som' => 'somali',
|
||||
'spa' => 'spanish',
|
||||
'sqi' => 'albanian',
|
||||
'srp' => 'serbian',
|
||||
'swa' => 'swahili',
|
||||
'swe' => 'swedish',
|
||||
'tgl' => 'tagalog',
|
||||
'tur' => 'turkish',
|
||||
'ukr' => 'ukrainian',
|
||||
'urd' => 'urdu',
|
||||
'uzb' => 'uzbek',
|
||||
'vie' => 'vietnamese',
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the 2-letter ISO 639-1 code for the given language name.
|
||||
*
|
||||
* @param string $lang English language name like "swedish"
|
||||
*
|
||||
* @return string Two-letter language code (e.g. "sv") or NULL if not found
|
||||
*/
|
||||
public static function nameToCode2($lang)
|
||||
{
|
||||
$lang = strtolower($lang);
|
||||
if (!isset(self::$nameToCode2[$lang])) {
|
||||
return null;
|
||||
}
|
||||
return self::$nameToCode2[$lang];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the 3-letter ISO 639-2 code for the given language name.
|
||||
*
|
||||
* @param string $lang English language name like "swedish"
|
||||
*
|
||||
* @return string Three-letter language code (e.g. "swe") or NULL if not found
|
||||
*/
|
||||
public static function nameToCode3($lang)
|
||||
{
|
||||
$lang = strtolower($lang);
|
||||
if (!isset(self::$nameToCode3[$lang])) {
|
||||
return null;
|
||||
}
|
||||
return self::$nameToCode3[$lang];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language name for the given 2-letter ISO 639-1 code.
|
||||
*
|
||||
* @param string $code Two-letter language code (e.g. "sv")
|
||||
*
|
||||
* @return string English language name like "swedish"
|
||||
*/
|
||||
public static function code2ToName($code)
|
||||
{
|
||||
$lang = strtolower($code);
|
||||
if (!isset(self::$code2ToName[$code])) {
|
||||
return null;
|
||||
}
|
||||
return self::$code2ToName[$code];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language name for the given 3-letter ISO 639-2 code.
|
||||
*
|
||||
* @param string $code Three-letter language code (e.g. "swe")
|
||||
*
|
||||
* @return string English language name like "swedish"
|
||||
*/
|
||||
public static function code3ToName($code)
|
||||
{
|
||||
$lang = strtolower($code);
|
||||
if (!isset(self::$code3ToName[$code])) {
|
||||
return null;
|
||||
}
|
||||
return self::$code3ToName[$code];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
349
library/langdet/Text/LanguageDetect/Parser.php
Normal file
349
library/langdet/Text/LanguageDetect/Parser.php
Normal file
|
@ -0,0 +1,349 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This class represents a text sample to be parsed.
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Nicholas Pisarro
|
||||
* @copyright 2006
|
||||
* @license BSD
|
||||
* @version CVS: $Id: Parser.php 322327 2012-01-15 17:55:59Z cweiske $
|
||||
* @link http://pear.php.net/package/Text_LanguageDetect/
|
||||
* @link http://langdetect.blogspot.com/
|
||||
*/
|
||||
|
||||
/**
|
||||
* This class represents a text sample to be parsed.
|
||||
*
|
||||
* This separates the analysis of a text sample from the primary LanguageDetect
|
||||
* class. After a new profile has been built, the data can be retrieved using
|
||||
* the accessor functions.
|
||||
*
|
||||
* This class is intended to be used by the Text_LanguageDetect class, not
|
||||
* end-users.
|
||||
*
|
||||
* @category Text
|
||||
* @package Text_LanguageDetect
|
||||
* @author Nicholas Pisarro
|
||||
* @copyright 2006
|
||||
* @license BSD
|
||||
* @version release: 0.3.0
|
||||
*/
|
||||
class Text_LanguageDetect_Parser extends Text_LanguageDetect
|
||||
{
|
||||
/**
|
||||
* the piece of text being parsed
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $_string;
|
||||
|
||||
/**
|
||||
* stores the trigram frequencies of the sample
|
||||
*
|
||||
* @access private
|
||||
* @var string
|
||||
*/
|
||||
var $_trigrams = array();
|
||||
|
||||
/**
|
||||
* stores the trigram ranks of the sample
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $_trigram_ranks = array();
|
||||
|
||||
/**
|
||||
* stores the unicode blocks of the sample
|
||||
*
|
||||
* @access private
|
||||
* @var array
|
||||
*/
|
||||
var $_unicode_blocks = array();
|
||||
|
||||
/**
|
||||
* Whether the parser should compile the unicode ranges
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_compile_unicode = false;
|
||||
|
||||
/**
|
||||
* Whether the parser should compile trigrams
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_compile_trigram = false;
|
||||
|
||||
/**
|
||||
* Whether the trigram parser should pad the beginning of the string
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_trigram_pad_start = false;
|
||||
|
||||
/**
|
||||
* Whether the unicode parser should skip non-alphabetical ascii chars
|
||||
*
|
||||
* @access private
|
||||
* @var bool
|
||||
*/
|
||||
var $_unicode_skip_symbols = true;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @access private
|
||||
* @param string $string string to be parsed
|
||||
*/
|
||||
function Text_LanguageDetect_Parser($string) {
|
||||
$this->_string = $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a string is suitable for parsing
|
||||
*
|
||||
* @param string $str input string to test
|
||||
* @return bool true if acceptable, false if not
|
||||
*/
|
||||
public static function validateString($str) {
|
||||
if (!empty($str) && strlen($str) > 3 && preg_match('/\S/', $str)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* turn on/off trigram counting
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function prepareTrigram($bool = true)
|
||||
{
|
||||
$this->_compile_trigram = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* turn on/off unicode block counting
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function prepareUnicode($bool = true)
|
||||
{
|
||||
$this->_compile_unicode = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* turn on/off padding the beginning of the sample string
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function setPadStart($bool = true)
|
||||
{
|
||||
$this->_trigram_pad_start = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the unicode block counter skip non-alphabetical ascii chars?
|
||||
*
|
||||
* @access public
|
||||
* @param bool $bool true for on, false for off
|
||||
*/
|
||||
function setUnicodeSkipSymbols($bool = true)
|
||||
{
|
||||
$this->_unicode_skip_symbols = $bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the trigram ranks for the text sample
|
||||
*
|
||||
* @access public
|
||||
* @return array trigram ranks in the text sample
|
||||
*/
|
||||
function &getTrigramRanks()
|
||||
{
|
||||
return $this->_trigram_ranks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the trigram freqency table
|
||||
*
|
||||
* only used in testing to make sure the parser is working
|
||||
*
|
||||
* @access public
|
||||
* @return array trigram freqencies in the text sample
|
||||
*/
|
||||
function &getTrigramFreqs()
|
||||
{
|
||||
return $this->_trigram;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the array of unicode blocks
|
||||
*
|
||||
* @access public
|
||||
* @return array unicode blocks in the text sample
|
||||
*/
|
||||
function &getUnicodeBlocks()
|
||||
{
|
||||
return $this->_unicode_blocks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the parsing operation
|
||||
*
|
||||
* Be sure to call the set*() functions to set options and the
|
||||
* prepare*() functions first to tell it what kind of data to compute
|
||||
*
|
||||
* Afterwards the get*() functions can be used to access the compiled
|
||||
* information.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
function analyze()
|
||||
{
|
||||
$len = strlen($this->_string);
|
||||
$byte_counter = 0;
|
||||
|
||||
|
||||
// unicode startup
|
||||
if ($this->_compile_unicode) {
|
||||
$blocks = $this->_read_unicode_block_db();
|
||||
$block_count = count($blocks);
|
||||
|
||||
$skipped_count = 0;
|
||||
$unicode_chars = array();
|
||||
}
|
||||
|
||||
// trigram startup
|
||||
if ($this->_compile_trigram) {
|
||||
// initialize them as blank so the parser will skip the first two
|
||||
// (since it skips trigrams with more than 2 contiguous spaces)
|
||||
$a = ' ';
|
||||
$b = ' ';
|
||||
|
||||
// kludge
|
||||
// if it finds a valid trigram to start and the start pad option is
|
||||
// off, then set a variable that will be used to reduce this
|
||||
// trigram after parsing has finished
|
||||
if (!$this->_trigram_pad_start) {
|
||||
$a = $this->_next_char($this->_string, $byte_counter, true);
|
||||
|
||||
if ($a != ' ') {
|
||||
$b = $this->_next_char($this->_string, $byte_counter, true);
|
||||
$dropone = " $a$b";
|
||||
}
|
||||
|
||||
$byte_counter = 0;
|
||||
$a = ' ';
|
||||
$b = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
while ($byte_counter < $len) {
|
||||
$char = $this->_next_char($this->_string, $byte_counter, true);
|
||||
|
||||
|
||||
// language trigram detection
|
||||
if ($this->_compile_trigram) {
|
||||
if (!($b == ' ' && ($a == ' ' || $char == ' '))) {
|
||||
if (!isset($this->_trigram[$a . $b . $char])) {
|
||||
$this->_trigram[$a . $b . $char] = 1;
|
||||
} else {
|
||||
$this->_trigram[$a . $b . $char]++;
|
||||
}
|
||||
}
|
||||
|
||||
$a = $b;
|
||||
$b = $char;
|
||||
}
|
||||
|
||||
// unicode block detection
|
||||
if ($this->_compile_unicode) {
|
||||
if ($this->_unicode_skip_symbols
|
||||
&& strlen($char) == 1
|
||||
&& ($char < 'A' || $char > 'z'
|
||||
|| ($char > 'Z' && $char < 'a'))
|
||||
&& $char != "'") { // does not skip the apostrophe
|
||||
// since it's included in the language
|
||||
// models
|
||||
|
||||
$skipped_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// build an array of all the characters
|
||||
if (isset($unicode_chars[$char])) {
|
||||
$unicode_chars[$char]++;
|
||||
} else {
|
||||
$unicode_chars[$char] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// todo: add byte detection here
|
||||
}
|
||||
|
||||
// unicode cleanup
|
||||
if ($this->_compile_unicode) {
|
||||
foreach ($unicode_chars as $utf8_char => $count) {
|
||||
$search_result = $this->_unicode_block_name(
|
||||
$this->_utf8char2unicode($utf8_char), $blocks, $block_count);
|
||||
|
||||
if ($search_result != -1) {
|
||||
$block_name = $search_result[2];
|
||||
} else {
|
||||
$block_name = '[Malformatted]';
|
||||
}
|
||||
|
||||
if (isset($this->_unicode_blocks[$block_name])) {
|
||||
$this->_unicode_blocks[$block_name] += $count;
|
||||
} else {
|
||||
$this->_unicode_blocks[$block_name] = $count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// trigram cleanup
|
||||
if ($this->_compile_trigram) {
|
||||
// pad the end
|
||||
if ($b != ' ') {
|
||||
if (!isset($this->_trigram["$a$b "])) {
|
||||
$this->_trigram["$a$b "] = 1;
|
||||
} else {
|
||||
$this->_trigram["$a$b "]++;
|
||||
}
|
||||
}
|
||||
|
||||
// perl compatibility; Language::Guess does not pad the beginning
|
||||
// kludge
|
||||
if (isset($dropone)) {
|
||||
if ($this->_trigram[$dropone] == 1) {
|
||||
unset($this->_trigram[$dropone]);
|
||||
} else {
|
||||
$this->_trigram[$dropone]--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->_trigram)) {
|
||||
$this->_trigram_ranks = $this->_arr_rank($this->_trigram);
|
||||
} else {
|
||||
$this->_trigram_ranks = array();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
?>
|
1
library/langdet/data/lang.dat
Normal file
1
library/langdet/data/lang.dat
Normal file
File diff suppressed because one or more lines are too long
1
library/langdet/data/unicode_blocks.dat
Normal file
1
library/langdet/data/unicode_blocks.dat
Normal file
File diff suppressed because one or more lines are too long
35
library/langdet/docs/example_clui.php
Normal file
35
library/langdet/docs/example_clui.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* example usage (CLI)
|
||||
*
|
||||
* @package Text_LanguageDetect
|
||||
* @version CVS: $Id: example_clui.php 322305 2012-01-15 00:04:17Z clockwerx $
|
||||
*/
|
||||
|
||||
require_once 'Text/LanguageDetect.php';
|
||||
|
||||
$l = new Text_LanguageDetect;
|
||||
|
||||
$stdin = fopen('php://stdin', 'r');
|
||||
|
||||
echo "Supported languages:\n";
|
||||
$langs = $l->getLanguages();
|
||||
sort($langs);
|
||||
echo join(', ', $langs);
|
||||
|
||||
echo "\ntotal ", count($langs), "\n\n";
|
||||
|
||||
while ($line = fgets($stdin)) {
|
||||
$result = $l->detect($line, 4);
|
||||
print_r($result);
|
||||
$blocks = $l->detectUnicodeBlocks($line, true);
|
||||
print_r($blocks);
|
||||
}
|
||||
|
||||
fclose($stdin);
|
||||
unset($l);
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
?>
|
72
library/langdet/docs/example_web.php
Normal file
72
library/langdet/docs/example_web.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* example usage (web)
|
||||
*
|
||||
* @package Text_LanguageDetect
|
||||
* @version CVS: $Id: example_web.php 205493 2006-01-18 00:26:57Z taak $
|
||||
*/
|
||||
|
||||
// browsers will encode multi-byte characters wrong unless they think the page is utf8-encoded
|
||||
header('Content-type: text/html; charset=utf-8', true);
|
||||
|
||||
require_once 'Text/LanguageDetect.php';
|
||||
|
||||
$l = new Text_LanguageDetect;
|
||||
if (isset($_REQUEST['q'])) {
|
||||
$q = stripslashes($_REQUEST['q']);
|
||||
}
|
||||
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<title>Text_LanguageDetect demonstration</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Text_LanguageDetect</h2>
|
||||
<?
|
||||
echo "<small>Supported languages:\n";
|
||||
$langs = $l->getLanguages();
|
||||
sort($langs);
|
||||
foreach ($langs as $lang) {
|
||||
echo ucfirst($lang), ', ';
|
||||
$i++;
|
||||
}
|
||||
|
||||
echo "<br />total $i</small><br /><br />";
|
||||
|
||||
?>
|
||||
<form method="post">
|
||||
Enter text to identify language (at least a couple of sentences):<br />
|
||||
<textarea name="q" wrap="virtual" cols="80" rows="8"><?= $q ?></textarea>
|
||||
<br />
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
<?
|
||||
if (isset($q) && strlen($q)) {
|
||||
$len = $l->utf8strlen($q);
|
||||
if ($len < 20) { // this value picked somewhat arbitrarily
|
||||
echo "Warning: string not very long ($len chars)<br />\n";
|
||||
}
|
||||
|
||||
$result = $l->detectConfidence($q);
|
||||
|
||||
if ($result == null) {
|
||||
echo "Text_LanguageDetect cannot identify this piece of text. <br /><br />\n";
|
||||
} else {
|
||||
echo "Text_LanguageDetect thinks this text is written in <b>{$result['language']}</b> ({$result['similarity']}, {$result['confidence']})<br /><br />\n";
|
||||
}
|
||||
|
||||
$result = $l->detectUnicodeBlocks($q, false);
|
||||
if (!empty($result)) {
|
||||
arsort($result);
|
||||
echo "Unicode blocks present: ", join(', ', array_keys($result)), "\n<br /><br />";
|
||||
}
|
||||
}
|
||||
|
||||
unset($l);
|
||||
|
||||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||||
|
||||
?>
|
||||
</body></html>
|
21
library/langdet/docs/iso.php
Normal file
21
library/langdet/docs/iso.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
/**
|
||||
* Demonstrates how to use ISO language codes.
|
||||
*
|
||||
* The "name mode" changes the way languages are accepted and returned.
|
||||
*/
|
||||
require_once 'Text/LanguageDetect.php';
|
||||
$l = new Text_LanguageDetect();
|
||||
|
||||
|
||||
//will output the ISO 639-1 two-letter language code
|
||||
// "de"
|
||||
$l->setNameMode(2);
|
||||
echo $l->detectSimple('Das ist ein kleiner Text') . "\n";
|
||||
|
||||
//will output the ISO 639-2 three-letter language code
|
||||
// "deu"
|
||||
$l->setNameMode(3);
|
||||
echo $l->detectSimple('Das ist ein kleiner Text') . "\n";
|
||||
|
||||
?>
|
2056
library/langdet/tests/Text_LanguageDetectTest.php
Normal file
2056
library/langdet/tests/Text_LanguageDetectTest.php
Normal file
File diff suppressed because it is too large
Load diff
72
library/langdet/tests/Text_LanguageDetect_ISO639Test.php
Normal file
72
library/langdet/tests/Text_LanguageDetect_ISO639Test.php
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
set_include_path(
|
||||
__DIR__ . '/../' . PATH_SEPARATOR . get_include_path()
|
||||
);
|
||||
|
||||
require_once 'Text/LanguageDetect/ISO639.php';
|
||||
|
||||
class Text_LanguageDetect_ISO639Test extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testNameToCode2()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'de',
|
||||
Text_LanguageDetect_ISO639::nameToCode2('german')
|
||||
);
|
||||
}
|
||||
|
||||
public function testNameToCode2Fail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::nameToCode2('doesnotexist')
|
||||
);
|
||||
}
|
||||
|
||||
public function testNameToCode3()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'fra',
|
||||
Text_LanguageDetect_ISO639::nameToCode3('french')
|
||||
);
|
||||
}
|
||||
|
||||
public function testNameToCode3Fail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::nameToCode3('doesnotexist')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode2ToName()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'english',
|
||||
Text_LanguageDetect_ISO639::code2ToName('en')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode2ToNameFail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::code2ToName('nx')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode3ToName()
|
||||
{
|
||||
$this->assertEquals(
|
||||
'romanian',
|
||||
Text_LanguageDetect_ISO639::code3ToName('rom')
|
||||
);
|
||||
}
|
||||
|
||||
public function testCode3ToNameFail()
|
||||
{
|
||||
$this->assertNull(
|
||||
Text_LanguageDetect_ISO639::code3ToName('nxx')
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,3 +1,46 @@
|
|||
Version 3.5.0.1 (2012-05-10)
|
||||
Fixed bug where selection normalization logic would break the selections of parent elements using the element path.
|
||||
Fixed bug where the autolink plugin would include trailing dots in domain names in the link creation.
|
||||
Fixed bug where the autolink plugin would produce an error on older IE versions when pressing enter.
|
||||
Fixed bug where old IE versions would throw an error during initialization when the editor was placed in an size restricted div.
|
||||
Version 3.5 (2012-05-03)
|
||||
Fixed menu rendering issue if the document was in rtl mode.
|
||||
Fixed bug where the hide function would throw an error about a missing variable.
|
||||
Fixed bug where autolink wouldn't convert URLs when hitting enter on IE due to the new enter key logic.
|
||||
Fixed bug where formatting using shortcuts like ctrl+b wouldn't work properly the first time.
|
||||
Fixed bug where selection.setContent after a formatter call wouldn't generate formatted contents.
|
||||
Fixed bug where whitespace would be removed before/after invalid_elements when they where removed.
|
||||
Fixed bug where updating styles using the theme image dialog in non inline mode on IE9 would produce errors.
|
||||
Fixed bug where IE 8 would produce an error when using the contextmenu plugin.
|
||||
Fixed bug where delete/backspace could remove contents of noneditable elements.
|
||||
Fixed so background color in style preview gets computed from body element if the current style element is transparent.
|
||||
Version 3.5b3 (2012-03-29)
|
||||
Added cancel button to colour picker dialog.
|
||||
Added figure and figcaption to the html5 visualblocks plugin.
|
||||
Added default alignment options for the figure element.
|
||||
Fixed bug where empty inline elements within block elements would sometimes produce a br child element.
|
||||
Fixed bug where urls pointing to the same domain as the current one would cause undefined errors. Patch contributed by Paul Giberson.
|
||||
Fixed bug where enter inside an editable element inside an non editable element would split the element.
|
||||
Fixed bug where cut/copy/paste of noneditable elements didn't work.
|
||||
Fixed bug where backspace would sometimes produce font elements on WebKit.
|
||||
Fixed bug where WebKit would produce spans out of various inline elements when using backspace.
|
||||
Fixed bug where IE9 wouldn't properly update image styles when images where resized.
|
||||
Fixed bug where drag/drop of noneditable elements didn't work correctly.
|
||||
Fixed bug where applying formatting to all contents wouldn't work correctly when an end point was inside an empty bock. Patch contributed by Jose Luiz.
|
||||
Fixed bug where IE10 removed the scopeName from the DOM element interface and there for it produced an undefined string in element path.
|
||||
Fixed bug where the caret would be placed at an incorrect location if you applied block formatting while having the caret at the end of the block.
|
||||
Fixed bug where applying column changes using the cell dialog would only update the first column. Patch contributed by krzyko.
|
||||
Fixed bug where the visualblocks plugin would force editor focus if it was turned on by default.
|
||||
Fixed bug where the tabfocus plugin would tab to iframes these are now ignored.
|
||||
Fixed bug where format drop down list wouldn't show the currently active format for a parent element.
|
||||
Fixed bug where paste of plain text in IE 9 would remove the new line characters from text.
|
||||
Fixed bug where the menu buttons/split button menus wouldn't be opened at the right location on older IE versions.
|
||||
Fixed bug where Gecko browsers wouldn't properly display the right format when having the selection as specific places.
|
||||
Fixed bug where shift+enter inside the body when having forced_root_blocks set to false would throw an error.
|
||||
Fixed bug where the jQuery plugin would break the attr method of jQuery 1.7.2. Patch contributed by Markus Kemmerling.
|
||||
Fixed so options like content_css accepts and array as well as a comma separated string as input.
|
||||
Restructured the internal logic to make it more separate from Editor.js.
|
||||
Updated the Sizzle engine to the latest version.
|
||||
Version 3.5b2 (2012-03-15)
|
||||
Rewrote the enter key logic to normalize browser behavior.
|
||||
Fixed so enter within PRE elements produces a BR and shift+enter breaks/end the PRE. Can be disabled using the br_in_pre option.
|
||||
|
@ -19,15 +62,6 @@ Version 3.5b1 (2012-03-08)
|
|||
Fixed bug where the advlink dialog would produce an error about the addSelectAccessibility function not being defined.
|
||||
Fixed bug where the caret would be placed at an incorrect position if span was removed by the invalid_elements setting.
|
||||
Fixed bug where elements inside a white space preserve element like pre didn't inherit the behavior while parsing.
|
||||
Version 3.4.9.x (2012-02-xx)
|
||||
Improved behaviour of backspacing into a table to be consistant across browsers and disable backspace when cursor immediately follows a table.
|
||||
Improved edit CSS style plugin for single and multiple block selection and provide option to apply style to only selected text.
|
||||
Fixed bug in Chrome where moving caret down in table and pasting throws errors.
|
||||
Corrected reference to TinyMCE trim function.
|
||||
Fixed bug where Ignore All in IE did not remove the underline from the selected word.
|
||||
Fixed bug in html source editor word wrap option not wrapping text in Webkit browsers.
|
||||
Fixed bug where it was possible to insert an invalid colour in the color pop-up dialog.
|
||||
Fixed bug in Webkit where if anchor is on last line by itself caret can not be placed after it.
|
||||
Version 3.4.9 (2012-02-23)
|
||||
Added settings to wordcount plugin to configure update rate and checking wordcount on backspace and delete using wordcount_update_rate and wordcount_update_on_delete.
|
||||
Fixed bug in Webkit and IE where deleting empty paragraphs would remove entire editor contents.
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;if(tinyMCE.isIE){return}a.onKeyDown.add(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng().cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();
|
||||
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;a.onKeyDown.addToTop(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});if(tinyMCE.isIE){return}a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng(true).cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}var m=a.toString();if(m.charAt(m.length-1)=="."){a.setEnd(n,c-1)}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();
|
|
@ -22,16 +22,16 @@
|
|||
init : function(ed, url) {
|
||||
var t = this;
|
||||
|
||||
// Internet Explorer has built-in automatic linking
|
||||
if (tinyMCE.isIE)
|
||||
return;
|
||||
|
||||
// Add a key down handler
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
ed.onKeyDown.addToTop(function(ed, e) {
|
||||
if (e.keyCode == 13)
|
||||
return t.handleEnter(ed);
|
||||
});
|
||||
|
||||
// Internet Explorer has built-in automatic linking for most cases
|
||||
if (tinyMCE.isIE)
|
||||
return;
|
||||
|
||||
ed.onKeyPress.add(function(ed, e) {
|
||||
if (e.which == 41)
|
||||
return t.handleEclipse(ed);
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
// We need at least five characters to form a URL,
|
||||
// hence, at minimum, five characters from the beginning of the line.
|
||||
r = ed.selection.getRng().cloneRange();
|
||||
r = ed.selection.getRng(true).cloneRange();
|
||||
if (r.startOffset < 5) {
|
||||
// During testing, the caret is placed inbetween two text nodes.
|
||||
// The previous text node contains the URL.
|
||||
|
@ -124,6 +124,12 @@
|
|||
r.setEnd(endContainer, start);
|
||||
}
|
||||
|
||||
// Exclude last . from word like "www.site.com."
|
||||
var text = r.toString();
|
||||
if (text.charAt(text.length - 1) == '.') {
|
||||
r.setEnd(endContainer, start - 1);
|
||||
}
|
||||
|
||||
text = r.toString();
|
||||
matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();
|
||||
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6||document.compatMode=="BackCompat"){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();
|
|
@ -79,7 +79,7 @@
|
|||
vp.h -= 1;
|
||||
|
||||
// Use fixed position if it exists
|
||||
if (tinymce.isIE6)
|
||||
if (tinymce.isIE6 || document.compatMode == 'BackCompat')
|
||||
posCss = 'absolute;top:' + vp.y;
|
||||
else
|
||||
posCss = 'fixed;top:0';
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -261,12 +261,96 @@
|
|||
selection.collapse(start);
|
||||
}
|
||||
|
||||
function canDelete(backspace) {
|
||||
var rng, container, offset, nonEditableParent;
|
||||
|
||||
function removeNodeIfNotParent(node) {
|
||||
var parent = container;
|
||||
|
||||
while (parent) {
|
||||
if (parent === node) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
dom.remove(node);
|
||||
moveSelection();
|
||||
}
|
||||
|
||||
function isNextPrevTreeNodeNonEditable() {
|
||||
var node, walker, nonEmptyElements = ed.schema.getNonEmptyElements();
|
||||
|
||||
walker = new tinymce.dom.TreeWalker(container, ed.getBody());
|
||||
while (node = (backspace ? walker.prev() : walker.next())) {
|
||||
// Found IMG/INPUT etc
|
||||
if (nonEmptyElements[node.nodeName.toLowerCase()]) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found text node with contents
|
||||
if (node.nodeType === 3 && tinymce.trim(node.nodeValue).length > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found non editable node
|
||||
if (getContentEditable(node) === "false") {
|
||||
removeNodeIfNotParent(node);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the content node is within a non editable parent
|
||||
if (getNonEditableParent(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selection.isCollapsed()) {
|
||||
rng = selection.getRng(true);
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
container = getParentCaretContainer(container) || container;
|
||||
|
||||
// Is in noneditable parent
|
||||
if (nonEditableParent = getNonEditableParent(container)) {
|
||||
removeNodeIfNotParent(nonEditableParent);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the caret is in the middle of a text node
|
||||
if (container.nodeType == 3 && (backspace ? offset > 0 : offset < container.nodeValue.length)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve container index
|
||||
if (container.nodeType == 1) {
|
||||
container = container.childNodes[offset] || container;
|
||||
}
|
||||
|
||||
// Check if previous or next tree node is non editable then block the event
|
||||
if (isNextPrevTreeNodeNonEditable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
startElement = selection.getStart()
|
||||
endElement = selection.getEnd();
|
||||
|
||||
// Disable all key presses in contentEditable=false except delete or backspace
|
||||
nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement);
|
||||
if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) {
|
||||
// Is Ctrl+c, Ctrl+v or Ctrl+x then use default browser behavior
|
||||
if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
// Arrow left/right select the element and collapse left/right
|
||||
|
@ -298,6 +382,7 @@
|
|||
positionCaretOnElement(nonEditableParent, true);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
|
@ -315,23 +400,31 @@
|
|||
positionCaretOnElement(nonEditableParent, false);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ed.onMouseDown.addToTop(function(ed, e){
|
||||
// prevent collapsing selection to caret when clicking in a non-editable section
|
||||
ed.onMouseDown.addToTop(function(ed, e) {
|
||||
var node = ed.selection.getNode();
|
||||
|
||||
if (getContentEditable(node) === "false" && node == e.target) {
|
||||
e.preventDefault();
|
||||
// Expand selection on mouse down we can't block the default event since it's used for drag/drop
|
||||
moveSelection();
|
||||
}
|
||||
});
|
||||
|
||||
ed.onMouseUp.addToTop(moveSelection);
|
||||
ed.onKeyDown.addToTop(handleKey);
|
||||
ed.onKeyUp.addToTop(moveSelection);
|
||||
|
@ -341,6 +434,31 @@
|
|||
init : function(ed, url) {
|
||||
var editClass, nonEditClass, nonEditableRegExps;
|
||||
|
||||
// Converts configured regexps to noneditable span items
|
||||
function convertRegExpsToNonEditable(ed, args) {
|
||||
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
// Don't replace the variables when raw is used for example on undo/redo
|
||||
if (args.format == "raw") {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
content = content.replace(nonEditableRegExps[i], function(match) {
|
||||
var args = arguments, index = args[args.length - 2];
|
||||
|
||||
// Is value inside an attribute then don't replace
|
||||
if (index > 0 && content.charAt(index - 1) == '"') {
|
||||
return match;
|
||||
}
|
||||
|
||||
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
|
||||
});
|
||||
}
|
||||
|
||||
args.content = content;
|
||||
};
|
||||
|
||||
editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " ";
|
||||
nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
|
||||
|
||||
|
@ -354,24 +472,8 @@
|
|||
handleContentEditableSelection(ed);
|
||||
|
||||
if (nonEditableRegExps) {
|
||||
ed.onBeforeSetContent.add(function(ed, args) {
|
||||
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
// Don't replace the variables when raw is used for example on undo/redo
|
||||
if (args.format == "raw") {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
content = content.replace(nonEditableRegExps[i], function() {
|
||||
var args = arguments;
|
||||
|
||||
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
|
||||
});
|
||||
}
|
||||
|
||||
args.content = content;
|
||||
});
|
||||
ed.selection.onBeforeSetContent.add(convertRegExpsToNonEditable);
|
||||
ed.onBeforeSetContent.add(convertRegExpsToNonEditable);
|
||||
}
|
||||
|
||||
// Apply contentEditable true/false on elements with the noneditable/editable classes
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -359,7 +359,7 @@
|
|||
}
|
||||
|
||||
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
|
||||
if (tinymce.isIE && document.documentMode >= 9) {
|
||||
if (tinymce.isIE && document.documentMode >= 9 && /<(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)/.test(o.content)) {
|
||||
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
|
||||
process([[/(?:<br> [\s\r\n]+|<br>)*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:<br> [\s\r\n]+|<br>)*/g, '$1']]);
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})();
|
||||
(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]:not(iframe)");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})();
|
|
@ -22,7 +22,7 @@
|
|||
var x, i, f, el, v;
|
||||
|
||||
function find(d) {
|
||||
el = DOM.select(':input:enabled,*[tabindex]');
|
||||
el = DOM.select(':input:enabled,*[tabindex]:not(iframe)');
|
||||
|
||||
function canSelectRecursive(e) {
|
||||
return e.nodeName==="BODY" || (e.type != 'hidden' &&
|
||||
|
|
|
@ -137,7 +137,7 @@ function updateAction() {
|
|||
do {
|
||||
if (cell == tdElm)
|
||||
break;
|
||||
col += cell.getAttribute("colspan");
|
||||
col += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
|
||||
} while ((cell = nextCell(cell)) != null);
|
||||
|
||||
for (var i=0; i<rows.length; i++) {
|
||||
|
@ -152,7 +152,7 @@ function updateAction() {
|
|||
cell = updateCell(cell, true);
|
||||
break;
|
||||
}
|
||||
curr += cell.getAttribute("colspan");
|
||||
curr += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
|
||||
} while ((cell = nextCell(cell)) != null);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre {margin-left: 3px}
|
||||
section, article, address, hgroup, aside {margin: 1em 0 0 3px}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre, figure {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre, figure {margin-left: 3px}
|
||||
section, article, address, hgroup, aside, figure {margin: 0 0 1em 3px}
|
||||
|
||||
p {background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7)}
|
||||
h1 {background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==)}
|
||||
|
@ -17,3 +17,5 @@ address {background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH
|
|||
pre {background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==)}
|
||||
hgroup {background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7)}
|
||||
aside {background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=)}
|
||||
figure {background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7)}
|
||||
figcaption {border: 1px dashed #BBB}
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks")}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})();
|
||||
(function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks",false,null,{skip_focus:true})}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})();
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
ed.onInit.add(function() {
|
||||
if (ed.settings.visualblocks_default_state) {
|
||||
ed.execCommand('mceVisualBlocks');
|
||||
ed.execCommand('mceVisualBlocks', false, null, {skip_focus : true});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -62,12 +62,8 @@
|
|||
|
||||
<div class="mceActionPanel">
|
||||
<input type="submit" id="insert" name="insert" value="{#apply}" />
|
||||
|
||||
<div id="preview"></div>
|
||||
|
||||
<div id="previewblock">
|
||||
<label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" />
|
||||
</div>
|
||||
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();"/>
|
||||
<div id="preview_wrapper"><div id="previewblock"><label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" /></div><span id="preview"></span></div>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -69,6 +69,16 @@
|
|||
each(previewStyles.split(' '), function(name) {
|
||||
var value = dom.getStyle(previewElm, name, true);
|
||||
|
||||
// If background is transparent then check if the body has a background color we can use
|
||||
if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
|
||||
value = dom.getStyle(ed.getBody(), name, true);
|
||||
|
||||
// Ignore white since it's the default color, not the nicest fix
|
||||
if (dom.toHex(value).toLowerCase() == '#ffffff') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Old IE won't calculate the font size so we need to do that manually
|
||||
if (name == 'font-size') {
|
||||
if (/em|%$/.test(value)) {
|
||||
|
@ -608,7 +618,7 @@
|
|||
|
||||
// TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for.
|
||||
// Maybe actually inherit it from the original textara?
|
||||
n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')});
|
||||
n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '') + (ed.settings.directionality == "rtl" ? ' mceRtl' : '')});
|
||||
DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label);
|
||||
|
||||
if (!DOM.boxModel)
|
||||
|
@ -925,7 +935,7 @@
|
|||
},
|
||||
|
||||
_addToolbars : function(c, o) {
|
||||
var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup;
|
||||
var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup, toolbarsExist = false;
|
||||
|
||||
toolbarGroup = cf.createToolbarGroup('toolbargroup', {
|
||||
'name': ed.getLang('advanced.toolbar'),
|
||||
|
@ -941,6 +951,7 @@
|
|||
|
||||
// Create toolbar and add the controls
|
||||
for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
|
||||
toolbarsExist = true;
|
||||
tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
|
||||
|
||||
if (s['theme_advanced_buttons' + i + '_add'])
|
||||
|
@ -954,6 +965,9 @@
|
|||
|
||||
o.deltaHeight -= s.theme_advanced_row_height;
|
||||
}
|
||||
// Handle case when there are no toolbar buttons and ensure editor height is adjusted accordingly
|
||||
if (!toolbarsExist)
|
||||
o.deltaHeight -= s.theme_advanced_row_height;
|
||||
h.push(toolbarGroup.renderHTML());
|
||||
h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
|
||||
DOM.setHTML(n, h.join(''));
|
||||
|
@ -1112,7 +1126,7 @@
|
|||
}
|
||||
|
||||
if (c = cm.get('formatselect')) {
|
||||
p = getParent(DOM.isBlock);
|
||||
p = getParent(ed.dom.isBlock);
|
||||
|
||||
if (p)
|
||||
c.select(p.nodeName.toLowerCase());
|
||||
|
@ -1210,7 +1224,7 @@
|
|||
return;
|
||||
|
||||
// Handle prefix
|
||||
if (tinymce.isIE && n.scopeName !== 'HTML')
|
||||
if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName)
|
||||
na = n.scopeName + ':' + na;
|
||||
|
||||
// Remove internal prefix
|
||||
|
@ -1271,7 +1285,7 @@
|
|||
if (v) {
|
||||
ti += 'class: ' + v + ' ';
|
||||
|
||||
if (DOM.isBlock(n) || na == 'img' || na == 'span')
|
||||
if (ed.dom.isBlock(n) || na == 'img' || na == 'span')
|
||||
na += '.' + v;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,10 +104,12 @@ var ImageDialog = {
|
|||
},
|
||||
|
||||
updateStyle : function() {
|
||||
var dom = tinyMCEPopup.dom, st, v, f = document.forms[0];
|
||||
var dom = tinyMCEPopup.dom, st = {}, v, f = document.forms[0];
|
||||
|
||||
if (tinyMCEPopup.editor.settings.inline_styles) {
|
||||
st = tinyMCEPopup.dom.parseStyle(this.styleVal);
|
||||
tinymce.each(tinyMCEPopup.dom.parseStyle(this.styleVal), function(value, key) {
|
||||
st[key] = value;
|
||||
});
|
||||
|
||||
// Handle align
|
||||
v = getSelectValue(f, 'align');
|
||||
|
|
|
@ -94,11 +94,12 @@ h3 {font-size:14px;}
|
|||
#plugintable, #about #plugintable td {border:1px solid #919B9C;}
|
||||
#plugintable {width:96%; margin-top:10px;}
|
||||
#pluginscontainer {height:290px; overflow:auto;}
|
||||
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;}
|
||||
#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
|
||||
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
|
||||
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
|
||||
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
|
||||
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
|
||||
#colorpicker #light div {overflow:hidden;}
|
||||
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
|
||||
#colorpicker .panel_wrapper div.current {height:175px;}
|
||||
#colorpicker #namedcolors {width:150px;}
|
||||
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
/* Menu */
|
||||
.highcontrastSkin .mceNoIcons span.mceIcon {width:0;}
|
||||
.highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; }
|
||||
.highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; direction:ltr}
|
||||
.highcontrastSkin .mceMenu table {background:white; color: black}
|
||||
.highcontrastSkin .mceNoIcons a .mceText {padding-left:10px}
|
||||
.highcontrastSkin .mceMenu a, .highcontrastSkin .mceMenu span, .highcontrastSkin .mceMenu {display:block;background:white; color: black}
|
||||
|
@ -90,6 +90,10 @@
|
|||
.highcontrastSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
|
||||
.highcontrastSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
|
||||
|
||||
/* Rtl */
|
||||
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
|
||||
.mceRtl .mceMenuItem .mceText {text-align: right}
|
||||
|
||||
/* Formats */
|
||||
.highcontrastSkin .mce_p span.mceText {}
|
||||
.highcontrastSkin .mce_address span.mceText {font-style:italic}
|
||||
|
|
|
@ -105,11 +105,12 @@ h3 {font-size:14px;}
|
|||
#plugintable, #about #plugintable td {border:1px solid #919B9C;}
|
||||
#plugintable {width:96%; margin-top:10px;}
|
||||
#pluginscontainer {height:290px; overflow:auto;}
|
||||
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;}
|
||||
#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
|
||||
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
|
||||
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
|
||||
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
|
||||
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
|
||||
#colorpicker #light div {overflow:hidden;}
|
||||
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
|
||||
#colorpicker .panel_wrapper div.current {height:175px;}
|
||||
#colorpicker #namedcolors {width:150px;}
|
||||
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}
|
||||
|
|
|
@ -86,7 +86,7 @@
|
|||
.o2k7Skin .mce_forecolor span.mceAction, .o2k7Skin .mce_backcolor span.mceAction {height:15px;overflow:hidden}
|
||||
|
||||
/* Menu */
|
||||
.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD}
|
||||
.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD; direction:ltr}
|
||||
.o2k7Skin .mceNoIcons span.mceIcon {width:0;}
|
||||
.o2k7Skin .mceNoIcons a .mceText {padding-left:10px}
|
||||
.o2k7Skin .mceMenu table {background:#FFF}
|
||||
|
@ -112,6 +112,10 @@
|
|||
.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
|
||||
.o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
|
||||
|
||||
/* Rtl */
|
||||
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
|
||||
.mceRtl .mceMenuItem .mceText {text-align: right}
|
||||
|
||||
/* Formats */
|
||||
.o2k7Skin .mce_formatPreview a {font-size:10px}
|
||||
.o2k7Skin .mce_p span.mceText {}
|
||||
|
|
File diff suppressed because one or more lines are too long
4253
library/tinymce/jscripts/tiny_mce/tiny_mce_src.js
vendored
4253
library/tinymce/jscripts/tiny_mce/tiny_mce_src.js
vendored
File diff suppressed because it is too large
Load diff
67
mod/acl.php
67
mod/acl.php
|
@ -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",
|
||||
|
@ -94,10 +155,8 @@ function acl_init(&$a){
|
|||
"nick" => ($g['attag']) ? $g['attag'] : $g['nick'],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$items = array_merge($groups, $contacts);
|
||||
|
||||
$o = array(
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -5,25 +5,33 @@ require_once('include/socgraph.php');
|
|||
function common_content(&$a) {
|
||||
|
||||
$o = '';
|
||||
if(! local_user()) {
|
||||
notice( t('Permission denied.') . EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
if($a->argc > 1)
|
||||
$cid = intval($a->argv[1]);
|
||||
if(! $cid)
|
||||
$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(local_user())
|
||||
intval($uid)
|
||||
);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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'),
|
||||
),
|
||||
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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,18 +21,24 @@ 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());
|
||||
|
||||
call_hooks('follow', $arr);
|
||||
|
||||
if(x($arr['contact'],'name'))
|
||||
$ret = $arr['contact'];
|
||||
else
|
||||
$ret = probe_url($url);
|
||||
|
||||
if($ret['network'] === NETWORK_DFRN) {
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
38
mod/item.php
38
mod/item.php
|
@ -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,20 +880,26 @@ 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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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'),
|
||||
|
@ -171,11 +173,35 @@ 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,10 +377,11 @@ 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(
|
||||
'$thread_id' => $a->argv[1],
|
||||
|
@ -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;" ',
|
||||
|
|
|
@ -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 . '\\]%'))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@ function photo_init(&$a) {
|
|||
}
|
||||
}*/
|
||||
|
||||
$prvcachecontrol = false;
|
||||
|
||||
switch($a->argc) {
|
||||
case 4:
|
||||
$person = $a->argv[3];
|
||||
|
@ -134,6 +136,7 @@ function photo_init(&$a) {
|
|||
);
|
||||
if(count($r)) {
|
||||
$data = file_get_contents('images/nosign.jpg');
|
||||
$prvcachecontrol = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,8 +182,22 @@ function photo_init(&$a) {
|
|||
}
|
||||
|
||||
header("Content-type: image/jpeg");
|
||||
|
||||
if($prvcachecontrol) {
|
||||
|
||||
// it is a private photo that they have no permission to view.
|
||||
// tell the browser not to cache it, in case they authenticate
|
||||
// and subsequently have permission to see it
|
||||
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
header("Expires: " . gmdate("D, d M Y H:i:s", time() + (3600*24)) . " GMT");
|
||||
header("Cache-Control: max-age=" . (3600*24));
|
||||
|
||||
}
|
||||
echo $data;
|
||||
killme();
|
||||
// NOTREACHED
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -139,21 +139,49 @@ function profiles_post(&$a) {
|
|||
|
||||
|
||||
$changes = array();
|
||||
$value = '';
|
||||
if($is_default) {
|
||||
if($marital != $orig[0]['marital']) $changes[] = '♥ ' . t('Marital Status');
|
||||
if($withchanged) $changes[] = '♥ ' . 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]♥[/color] ' . t('Marital Status');
|
||||
$value = $marital;
|
||||
}
|
||||
if($withchanged) {
|
||||
$changes[] = '♥ ' . 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'])
|
||||
|| $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 “%3$s”'), $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>';
|
||||
|
|
|
@ -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,17 +146,18 @@ 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'])
|
||||
|
||||
);
|
||||
|
||||
if($tag)
|
||||
$o .= '<h2>Items tagged with: ' . $search . '</h2>';
|
||||
else
|
||||
$o .= '<h2>Search results for: ' . $search . '</h2>';
|
||||
|
||||
$o .= conversation($a,$r,'search',false);
|
||||
|
|
|
@ -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),
|
||||
|
@ -697,7 +718,7 @@ function settings_content(&$a) {
|
|||
$allowed_themes = array();
|
||||
if(count($allowed_themes_raw))
|
||||
foreach($allowed_themes_raw as $x)
|
||||
if(strlen(trim($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, ''),
|
||||
|
|
|
@ -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('⌗') . '[url=' . $a->get_baseurl() . '/search?search=' . urlencode($term) . ']'. $term . '[/url]';
|
||||
$termlink = html_entity_decode('⌗') . '[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'])
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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'])
|
||||
|
|
|
@ -5,19 +5,26 @@ require_once('Photo.php');
|
|||
function wall_upload_post(&$a) {
|
||||
|
||||
if($a->argc > 1) {
|
||||
if(! x($_FILES,'media')) {
|
||||
$nick = $a->argv[1];
|
||||
$r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1",
|
||||
dbesc($nick)
|
||||
);
|
||||
|
||||
if(! count($r))
|
||||
return;
|
||||
|
||||
}
|
||||
else {
|
||||
$user_info = api_get_user($a);
|
||||
$r = q("SELECT `user`.*, `contact`.`id` FROM `user` LEFT JOIN `contact` on `user`.`uid` = `contact`.`uid` WHERE `user`.`nickname` = '%s' AND `user`.`blocked` = 0 and `contact`.`self` = 1 LIMIT 1",
|
||||
dbesc($user_info['screen_name'])
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
|
||||
|
||||
$can_post = false;
|
||||
$visitor = 0;
|
||||
|
||||
|
@ -47,12 +54,19 @@ function wall_upload_post(&$a) {
|
|||
killme();
|
||||
}
|
||||
|
||||
if(! x($_FILES,'userfile'))
|
||||
if(! x($_FILES,'userfile') && ! x($_FILES,'media'))
|
||||
killme();
|
||||
|
||||
if(x($_FILES,'userfile')) {
|
||||
$src = $_FILES['userfile']['tmp_name'];
|
||||
$filename = basename($_FILES['userfile']['name']);
|
||||
$filesize = intval($_FILES['userfile']['size']);
|
||||
}
|
||||
elseif(x($_FILES,'media')) {
|
||||
$src = $_FILES['media']['tmp_name'];
|
||||
$filename = basename($_FILES['media']['name']);
|
||||
$filesize = intval($_FILES['media']['size']);
|
||||
}
|
||||
|
||||
$maximagesize = get_config('system','maximagesize');
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue