forked from GNUsocial/gnu-social
Merge branch '0.8.x' into queuemanager
This commit is contained in:
commit
5f9a4ebef4
10
README
10
README
@ -906,6 +906,9 @@ sslserver: use an alternate server name for SSL URLs, like
|
|||||||
parameters correctly so that both the SSL server and the
|
parameters correctly so that both the SSL server and the
|
||||||
"normal" server can access the session cookie and
|
"normal" server can access the session cookie and
|
||||||
preferably other cookies as well.
|
preferably other cookies as well.
|
||||||
|
shorturllength: Length of URL at which URLs in a message exceeding 140
|
||||||
|
characters will be sent to the user's chosen
|
||||||
|
shortening service.
|
||||||
|
|
||||||
db
|
db
|
||||||
--
|
--
|
||||||
@ -1081,6 +1084,13 @@ debug: if turned on, this will make the XMPP library blurt out all of
|
|||||||
public: an array of JIDs to send _all_ notices to. This is useful for
|
public: an array of JIDs to send _all_ notices to. This is useful for
|
||||||
participating in third-party search and archiving services.
|
participating in third-party search and archiving services.
|
||||||
|
|
||||||
|
invite
|
||||||
|
------
|
||||||
|
|
||||||
|
For configuring invites.
|
||||||
|
|
||||||
|
enabled: Whether to allow users to send invites. Default true.
|
||||||
|
|
||||||
tag
|
tag
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -58,6 +58,11 @@ class Attachment_ajaxAction extends AttachmentAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
$this->showPage();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show core.
|
* Show core.
|
||||||
*
|
*
|
||||||
|
@ -45,6 +45,12 @@ require_once INSTALLDIR.'/actions/attachment.php';
|
|||||||
|
|
||||||
class Attachment_thumbnailAction extends AttachmentAction
|
class Attachment_thumbnailAction extends AttachmentAction
|
||||||
{
|
{
|
||||||
|
|
||||||
|
function handle($args)
|
||||||
|
{
|
||||||
|
$this->showPage();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show page, a template method.
|
* Show page, a template method.
|
||||||
*
|
*
|
||||||
@ -74,45 +80,5 @@ class Attachment_thumbnailAction extends AttachmentAction
|
|||||||
$this->element('img', array('src' => $file_thumbnail->url, 'alt' => 'Thumbnail'));
|
$this->element('img', array('src' => $file_thumbnail->url, 'alt' => 'Thumbnail'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Last-modified date for page
|
|
||||||
*
|
|
||||||
* When was the content of this page last modified? Based on notice,
|
|
||||||
* profile, avatar.
|
|
||||||
*
|
|
||||||
* @return int last-modified date as unix timestamp
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
function lastModified()
|
|
||||||
{
|
|
||||||
return max(strtotime($this->notice->created),
|
|
||||||
strtotime($this->profile->modified),
|
|
||||||
($this->avatar) ? strtotime($this->avatar->modified) : 0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An entity tag for this page
|
|
||||||
*
|
|
||||||
* Shows the ETag for the page, based on the notice ID and timestamps
|
|
||||||
* for the notice, profile, and avatar. It's weak, since we change
|
|
||||||
* the date text "one hour ago", etc.
|
|
||||||
*
|
|
||||||
* @return string etag
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
function etag()
|
|
||||||
{
|
|
||||||
$avtime = ($this->avatar) ?
|
|
||||||
strtotime($this->avatar->modified) : 0;
|
|
||||||
|
|
||||||
return 'W/"' . implode(':', array($this->arg('action'),
|
|
||||||
common_language(),
|
|
||||||
$this->notice->id,
|
|
||||||
strtotime($this->notice->created),
|
|
||||||
strtotime($this->profile->modified),
|
|
||||||
$avtime)) . '"';
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,17 +107,11 @@ class ConversationAction extends Action
|
|||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$offset = ($this->page-1) * NOTICES_PER_PAGE;
|
$notices = Notice::conversationStream($this->id, 0, null);
|
||||||
$limit = NOTICES_PER_PAGE + 1;
|
|
||||||
|
|
||||||
$notices = Notice::conversationStream($this->id, $offset, $limit);
|
|
||||||
|
|
||||||
$ct = new ConversationTree($notices, $this);
|
$ct = new ConversationTree($notices, $this);
|
||||||
|
|
||||||
$cnt = $ct->show();
|
$cnt = $ct->show();
|
||||||
|
|
||||||
$this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE,
|
|
||||||
$this->page, 'conversation', array('id' => $this->id));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,8 +140,25 @@ class ConversationTree extends NoticeList
|
|||||||
|
|
||||||
function show()
|
function show()
|
||||||
{
|
{
|
||||||
$cnt = 0;
|
$cnt = $this->_buildTree();
|
||||||
|
|
||||||
|
$this->out->elementStart('div', array('id' =>'notices_primary'));
|
||||||
|
$this->out->element('h2', null, _('Notices'));
|
||||||
|
$this->out->elementStart('ol', array('class' => 'notices xoxo'));
|
||||||
|
|
||||||
|
if (array_key_exists('root', $this->tree)) {
|
||||||
|
$rootid = $this->tree['root'][0];
|
||||||
|
$this->showNoticePlus($rootid);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->elementEnd('ol');
|
||||||
|
$this->out->elementEnd('div');
|
||||||
|
|
||||||
|
return $cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _buildTree()
|
||||||
|
{
|
||||||
$this->tree = array();
|
$this->tree = array();
|
||||||
$this->table = array();
|
$this->table = array();
|
||||||
|
|
||||||
@ -169,18 +180,6 @@ class ConversationTree extends NoticeList
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->out->elementStart('div', array('id' =>'notices_primary'));
|
|
||||||
$this->out->element('h2', null, _('Notices'));
|
|
||||||
$this->out->elementStart('ol', array('class' => 'notices xoxo'));
|
|
||||||
|
|
||||||
if (array_key_exists('root', $this->tree)) {
|
|
||||||
$rootid = $this->tree['root'][0];
|
|
||||||
$this->showNoticePlus($rootid);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->out->elementEnd('ol');
|
|
||||||
$this->out->elementEnd('div');
|
|
||||||
|
|
||||||
return $cnt;
|
return $cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ class DisfavorAction extends Action
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$fave = new Fave();
|
$fave = new Fave();
|
||||||
$fave->user_id = $this->id;
|
$fave->user_id = $user->id;
|
||||||
$fave->notice_id = $notice->id;
|
$fave->notice_id = $notice->id;
|
||||||
if (!$fave->find(true)) {
|
if (!$fave->find(true)) {
|
||||||
$this->clientError(_('This notice is not a favorite!'));
|
$this->clientError(_('This notice is not a favorite!'));
|
||||||
|
@ -12,8 +12,6 @@
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://laconi.ca/
|
* @link http://laconi.ca/
|
||||||
*
|
*
|
||||||
|
|
||||||
/*
|
|
||||||
* Laconica - a distributed open-source microblogging tool
|
* Laconica - a distributed open-source microblogging tool
|
||||||
* Copyright (C) 2008, 2009, Control Yourself, Inc.
|
* Copyright (C) 2008, 2009, Control Yourself, Inc.
|
||||||
*
|
*
|
||||||
|
@ -34,19 +34,37 @@ if (!defined('LACONICA')) {
|
|||||||
|
|
||||||
require_once INSTALLDIR . '/lib/designsettings.php';
|
require_once INSTALLDIR . '/lib/designsettings.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a group's design
|
||||||
|
*
|
||||||
|
* Saves a design for a given group
|
||||||
|
*
|
||||||
|
* @category Settings
|
||||||
|
* @package Laconica
|
||||||
|
* @author Zach Copley <zach@controlyourself.ca>
|
||||||
|
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://laconi.ca/
|
||||||
|
*/
|
||||||
|
|
||||||
class GroupDesignSettingsAction extends DesignSettingsAction
|
class GroupDesignSettingsAction extends DesignSettingsAction
|
||||||
{
|
{
|
||||||
var $group = null;
|
var $group = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare to run
|
* Sets the right action for the form, and passes request args into
|
||||||
|
* the base action
|
||||||
|
*
|
||||||
|
* @param array $args misc. arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function prepare($args)
|
function prepare($args)
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
if (!common_config('inboxes','enabled')) {
|
if (!common_config('inboxes', 'enabled')) {
|
||||||
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
$this->serverError(_('Inboxes must be enabled for groups to work'));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -57,7 +75,7 @@ class GroupDesignSettingsAction extends DesignSettingsAction
|
|||||||
}
|
}
|
||||||
|
|
||||||
$nickname_arg = $this->trimmed('nickname');
|
$nickname_arg = $this->trimmed('nickname');
|
||||||
$nickname = common_canonical_nickname($nickname_arg);
|
$nickname = common_canonical_nickname($nickname_arg);
|
||||||
|
|
||||||
// Permanent redirect on non-canonical nickname
|
// Permanent redirect on non-canonical nickname
|
||||||
|
|
||||||
@ -158,7 +176,8 @@ class GroupDesignSettingsAction extends DesignSettingsAction
|
|||||||
* @return Design
|
* @return Design
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getWorkingDesign() {
|
function getWorkingDesign()
|
||||||
|
{
|
||||||
|
|
||||||
$design = null;
|
$design = null;
|
||||||
|
|
||||||
@ -273,9 +292,9 @@ class GroupDesignSettingsAction extends DesignSettingsAction
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$original = clone($this->group);
|
$original = clone($this->group);
|
||||||
$this->group->design_id = $id;
|
$this->group->design_id = $id;
|
||||||
$result = $this->group->update($original);
|
$result = $this->group->update($original);
|
||||||
|
|
||||||
if (empty($result)) {
|
if (empty($result)) {
|
||||||
common_log_db_error($original, 'UPDATE', __FILE__);
|
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||||
|
@ -167,6 +167,15 @@ class GroupMemberListItem extends ProfileListItem
|
|||||||
$this->group = $group;
|
$this->group = $group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showFullName()
|
||||||
|
{
|
||||||
|
parent::showFullName();
|
||||||
|
if ($this->profile->isAdmin($this->group)) {
|
||||||
|
$this->out->text(' ');
|
||||||
|
$this->out->element('span', 'role', _('Admin'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showActions()
|
function showActions()
|
||||||
{
|
{
|
||||||
$this->startActions();
|
$this->startActions();
|
||||||
|
@ -116,6 +116,7 @@ class groupRssAction extends Rss10Action
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$notices = array();
|
||||||
$notice = $group->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
|
$notice = $group->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
while ($notice->fetch()) {
|
||||||
|
@ -115,6 +115,7 @@ class GroupsAction extends Action
|
|||||||
$groups->orderBy('created DESC');
|
$groups->orderBy('created DESC');
|
||||||
$groups->limit($offset, $limit);
|
$groups->limit($offset, $limit);
|
||||||
|
|
||||||
|
$cnt = 0;
|
||||||
if ($groups->find()) {
|
if ($groups->find()) {
|
||||||
$gl = new GroupList($groups, null, $this);
|
$gl = new GroupList($groups, null, $this);
|
||||||
$cnt = $gl->show();
|
$cnt = $gl->show();
|
||||||
|
@ -35,7 +35,9 @@ class InviteAction extends CurrentUserDesignAction
|
|||||||
function handle($args)
|
function handle($args)
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
parent::handle($args);
|
||||||
if (!common_logged_in()) {
|
if (!common_config('invite', 'enabled')) {
|
||||||
|
$this->clientError(_('Invites have been disabled.'));
|
||||||
|
} else if (!common_logged_in()) {
|
||||||
$this->clientError(sprintf(_('You must be logged in to invite other users to use %s'),
|
$this->clientError(sprintf(_('You must be logged in to invite other users to use %s'),
|
||||||
common_config('site', 'name')));
|
common_config('site', 'name')));
|
||||||
return;
|
return;
|
||||||
|
@ -67,11 +67,16 @@ class NoticesearchrssAction extends Rss10Action
|
|||||||
|
|
||||||
if (!$limit) $limit = 20;
|
if (!$limit) $limit = 20;
|
||||||
$search_engine->limit(0, $limit, true);
|
$search_engine->limit(0, $limit, true);
|
||||||
$search_engine->query($q);
|
if (false === $search_engine->query($q)) {
|
||||||
$notice->find();
|
$cnt = 0;
|
||||||
|
} else {
|
||||||
|
$cnt = $notice->find();
|
||||||
|
}
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
if ($cnt > 0) {
|
||||||
$notices[] = clone($notice);
|
while ($notice->fetch()) {
|
||||||
|
$notices[] = clone($notice);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $notices;
|
return $notices;
|
||||||
|
@ -182,8 +182,10 @@ class PublicAction extends Action
|
|||||||
$message .= _('Be the first to post!');
|
$message .= _('Be the first to post!');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$message .= _('Why not [register an account](%%action.register%%) and be the first to post!');
|
if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
|
||||||
}
|
$message .= _('Why not [register an account](%%action.register%%) and be the first to post!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
$this->raw(common_markup_to_html($message));
|
$this->raw(common_markup_to_html($message));
|
||||||
|
@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php';
|
|||||||
* @link http://laconi.ca/
|
* @link http://laconi.ca/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ShowfavoritesAction extends CurrentUserDesignAction
|
class ShowfavoritesAction extends OwnerDesignAction
|
||||||
{
|
{
|
||||||
/** User we're getting the faves of */
|
/** User we're getting the faves of */
|
||||||
var $user = null;
|
var $user = null;
|
||||||
|
@ -331,6 +331,7 @@ class ShowgroupAction extends GroupDesignAction
|
|||||||
{
|
{
|
||||||
$this->showMembers();
|
$this->showMembers();
|
||||||
$this->showStatistics();
|
$this->showStatistics();
|
||||||
|
$this->showAdmins();
|
||||||
$cloud = new GroupTagCloudSection($this, $this->group);
|
$cloud = new GroupTagCloudSection($this, $this->group);
|
||||||
$cloud->show();
|
$cloud->show();
|
||||||
}
|
}
|
||||||
@ -369,6 +370,18 @@ class ShowgroupAction extends GroupDesignAction
|
|||||||
$this->elementEnd('div');
|
$this->elementEnd('div');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show list of admins
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
|
||||||
|
function showAdmins()
|
||||||
|
{
|
||||||
|
$adminSection = new GroupAdminSection($this, $this->group);
|
||||||
|
$adminSection->show();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show some statistics
|
* Show some statistics
|
||||||
*
|
*
|
||||||
@ -423,3 +436,34 @@ class ShowgroupAction extends GroupDesignAction
|
|||||||
$this->elementEnd('div');
|
$this->elementEnd('div');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GroupAdminSection extends ProfileSection
|
||||||
|
{
|
||||||
|
var $group;
|
||||||
|
|
||||||
|
function __construct($out, $group)
|
||||||
|
{
|
||||||
|
parent::__construct($out);
|
||||||
|
$this->group = $group;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProfiles()
|
||||||
|
{
|
||||||
|
return $this->group->getAdmins();
|
||||||
|
}
|
||||||
|
|
||||||
|
function title()
|
||||||
|
{
|
||||||
|
return _('Admins');
|
||||||
|
}
|
||||||
|
|
||||||
|
function divId()
|
||||||
|
{
|
||||||
|
return 'group_admins';
|
||||||
|
}
|
||||||
|
|
||||||
|
function moreUrl()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -45,7 +45,7 @@ require_once INSTALLDIR.'/lib/feedlist.php';
|
|||||||
* @link http://laconi.ca/
|
* @link http://laconi.ca/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ShownoticeAction extends Action
|
class ShownoticeAction extends OwnerDesignAction
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Notice object to show
|
* Notice object to show
|
||||||
@ -83,18 +83,25 @@ class ShownoticeAction extends Action
|
|||||||
|
|
||||||
$this->notice = Notice::staticGet($id);
|
$this->notice = Notice::staticGet($id);
|
||||||
|
|
||||||
if (!$this->notice) {
|
if (empty($this->notice)) {
|
||||||
$this->clientError(_('No such notice.'), 404);
|
$this->clientError(_('No such notice.'), 404);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->profile = $this->notice->getProfile();
|
$this->profile = $this->notice->getProfile();
|
||||||
|
|
||||||
if (!$this->profile) {
|
if (empty($this->profile)) {
|
||||||
$this->serverError(_('Notice has no profile'), 500);
|
$this->serverError(_('Notice has no profile'), 500);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->user = User::staticGet('id', $this->profile->id);
|
||||||
|
|
||||||
|
if (empty($this->user)) {
|
||||||
|
$this->serverError(_('Not a local notice'), 500);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$this->avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE);
|
$this->avatar = $this->profile->getAvatar(AVATAR_PROFILE_SIZE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -158,8 +165,14 @@ class ShownoticeAction extends Action
|
|||||||
|
|
||||||
function title()
|
function title()
|
||||||
{
|
{
|
||||||
|
if (!empty($this->profile->fullname)) {
|
||||||
|
$base = $this->profile->fullname . ' (' . $this->user->nickname . ') ';
|
||||||
|
} else {
|
||||||
|
$base = $this->user->nickname;
|
||||||
|
}
|
||||||
|
|
||||||
return sprintf(_('%1$s\'s status on %2$s'),
|
return sprintf(_('%1$s\'s status on %2$s'),
|
||||||
$this->profile->nickname,
|
$base,
|
||||||
common_exact_date($this->notice->created));
|
common_exact_date($this->notice->created));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,11 +63,13 @@ class SupAction extends Action
|
|||||||
# XXX: cache this. Depends on how big this protocol becomes;
|
# XXX: cache this. Depends on how big this protocol becomes;
|
||||||
# Re-doing this query every 15 seconds isn't the end of the world.
|
# Re-doing this query every 15 seconds isn't the end of the world.
|
||||||
|
|
||||||
|
$divider = common_sql_date(time() - $seconds);
|
||||||
|
|
||||||
$notice->query('SELECT profile_id, max(id) AS max_id ' .
|
$notice->query('SELECT profile_id, max(id) AS max_id ' .
|
||||||
'FROM notice ' .
|
'FROM notice ' .
|
||||||
((common_config('db','type') == 'pgsql') ?
|
((common_config('db','type') == 'pgsql') ?
|
||||||
'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' :
|
'WHERE extract(epoch from created) > (extract(epoch from now()) - ' . $seconds . ') ' :
|
||||||
'WHERE created > (now() - ' . $seconds . ') ' ) .
|
'WHERE created > "'.$divider.'" ' ) .
|
||||||
'GROUP BY profile_id');
|
'GROUP BY profile_id');
|
||||||
|
|
||||||
$updates = array();
|
$updates = array();
|
||||||
|
@ -165,24 +165,30 @@ class TwitapisearchatomAction extends TwitterapiAction
|
|||||||
$search_engine->set_sort_mode('chron');
|
$search_engine->set_sort_mode('chron');
|
||||||
$search_engine->limit(($this->page - 1) * $this->rpp,
|
$search_engine->limit(($this->page - 1) * $this->rpp,
|
||||||
$this->rpp + 1, true);
|
$this->rpp + 1, true);
|
||||||
$search_engine->query($q);
|
if (false === $search_engine->query($q)) {
|
||||||
$this->cnt = $notice->find();
|
$this->cnt = 0;
|
||||||
|
} else {
|
||||||
|
$this->cnt = $notice->find();
|
||||||
|
}
|
||||||
|
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
|
$this->max_id = 0;
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
if ($this->cnt > 0) {
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
|
||||||
++$cnt;
|
++$cnt;
|
||||||
|
|
||||||
if (!$this->max_id) {
|
if (!$this->max_id) {
|
||||||
$this->max_id = $notice->id;
|
$this->max_id = $notice->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($cnt > $this->rpp) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$notices[] = clone($notice);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($cnt > $this->rpp) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $notices;
|
return $notices;
|
||||||
|
@ -124,8 +124,11 @@ class TwitapisearchjsonAction extends TwitterapiAction
|
|||||||
$search_engine = $notice->getSearchEngine('identica_notices');
|
$search_engine = $notice->getSearchEngine('identica_notices');
|
||||||
$search_engine->set_sort_mode('chron');
|
$search_engine->set_sort_mode('chron');
|
||||||
$search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1, true);
|
$search_engine->limit(($this->page - 1) * $this->rpp, $this->rpp + 1, true);
|
||||||
$search_engine->query($q);
|
if (false === $search_engine->query($q)) {
|
||||||
$cnt = $notice->find();
|
$cnt = 0;
|
||||||
|
} else {
|
||||||
|
$cnt = $notice->find();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: since_id, lang, geocode
|
// TODO: since_id, lang, geocode
|
||||||
|
|
||||||
@ -146,4 +149,4 @@ class TwitapisearchjsonAction extends TwitterapiAction
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,16 +34,37 @@ if (!defined('LACONICA')) {
|
|||||||
|
|
||||||
require_once INSTALLDIR . '/lib/designsettings.php';
|
require_once INSTALLDIR . '/lib/designsettings.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a user's design
|
||||||
|
*
|
||||||
|
* Saves a design for a given user
|
||||||
|
*
|
||||||
|
* @category Settings
|
||||||
|
* @package Laconica
|
||||||
|
* @author Zach Copley <zach@controlyourself.ca>
|
||||||
|
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://laconi.ca/
|
||||||
|
*/
|
||||||
|
|
||||||
class UserDesignSettingsAction extends DesignSettingsAction
|
class UserDesignSettingsAction extends DesignSettingsAction
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Sets the right action for the form, and passes request args into
|
||||||
|
* the base action
|
||||||
|
*
|
||||||
|
* @param array $args misc. arguments
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
function prepare($args)
|
function prepare($args)
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
$this->submitaction = common_local_url('userdesignsettings');
|
$this->submitaction = common_local_url('userdesignsettings');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title of the page
|
* Title of the page
|
||||||
*
|
*
|
||||||
@ -72,19 +93,20 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
*
|
*
|
||||||
* @return Design
|
* @return Design
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getWorkingDesign() {
|
function getWorkingDesign()
|
||||||
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
$user = common_current_user();
|
||||||
$design = $user->getDesign();
|
$design = $user->getDesign();
|
||||||
|
|
||||||
if (empty($design)) {
|
if (empty($design)) {
|
||||||
$design = $this->defaultDesign();
|
$design = $this->defaultDesign();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $design;
|
return $design;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Content area of the page
|
* Content area of the page
|
||||||
*
|
*
|
||||||
@ -92,7 +114,7 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$this->showDesignForm($this->getWorkingDesign());
|
$this->showDesignForm($this->getWorkingDesign());
|
||||||
@ -106,14 +128,19 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
|
|
||||||
function saveDesign()
|
function saveDesign()
|
||||||
{
|
{
|
||||||
try {
|
foreach ($this->args as $key => $val) {
|
||||||
|
if (preg_match('/(#ho|ho)Td.*g/i', $val)) {
|
||||||
|
$this->sethd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
$bgcolor = new WebColor($this->trimmed('design_background'));
|
$bgcolor = new WebColor($this->trimmed('design_background'));
|
||||||
$ccolor = new WebColor($this->trimmed('design_content'));
|
$ccolor = new WebColor($this->trimmed('design_content'));
|
||||||
$sbcolor = new WebColor($this->trimmed('design_sidebar'));
|
$sbcolor = new WebColor($this->trimmed('design_sidebar'));
|
||||||
$tcolor = new WebColor($this->trimmed('design_text'));
|
$tcolor = new WebColor($this->trimmed('design_text'));
|
||||||
$lcolor = new WebColor($this->trimmed('design_links'));
|
$lcolor = new WebColor($this->trimmed('design_links'));
|
||||||
|
|
||||||
} catch (WebColorException $e) {
|
} catch (WebColorException $e) {
|
||||||
$this->showForm($e->getMessage());
|
$this->showForm($e->getMessage());
|
||||||
return;
|
return;
|
||||||
@ -137,7 +164,7 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
$tile = true;
|
$tile = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
$design = $user->getDesign();
|
$design = $user->getDesign();
|
||||||
|
|
||||||
if (!empty($design)) {
|
if (!empty($design)) {
|
||||||
@ -184,9 +211,9 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
$user->design_id = $id;
|
$user->design_id = $id;
|
||||||
$result = $user->update($original);
|
$result = $user->update($original);
|
||||||
|
|
||||||
if (empty($result)) {
|
if (empty($result)) {
|
||||||
common_log_db_error($original, 'UPDATE', __FILE__);
|
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||||
@ -203,4 +230,56 @@ class UserDesignSettingsAction extends DesignSettingsAction
|
|||||||
|
|
||||||
$this->showForm(_('Design preferences saved.'), true);
|
$this->showForm(_('Design preferences saved.'), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternate default colors
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
|
||||||
|
function sethd()
|
||||||
|
{
|
||||||
|
|
||||||
|
$user = common_current_user();
|
||||||
|
$design = $user->getDesign();
|
||||||
|
|
||||||
|
$user->query('BEGIN');
|
||||||
|
|
||||||
|
// alternate colors
|
||||||
|
$design = new Design();
|
||||||
|
|
||||||
|
$design->backgroundcolor = 16184329;
|
||||||
|
$design->contentcolor = 16059904;
|
||||||
|
$design->sidebarcolor = 16059904;
|
||||||
|
$design->textcolor = 0;
|
||||||
|
$design->linkcolor = 16777215;
|
||||||
|
|
||||||
|
$design->setDisposition(false, true, false);
|
||||||
|
|
||||||
|
$id = $design->insert();
|
||||||
|
|
||||||
|
if (empty($id)) {
|
||||||
|
common_log_db_error($id, 'INSERT', __FILE__);
|
||||||
|
$this->showForm(_('Unable to save your design settings!'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$original = clone($user);
|
||||||
|
$user->design_id = $id;
|
||||||
|
$result = $user->update($original);
|
||||||
|
|
||||||
|
if (empty($result)) {
|
||||||
|
common_log_db_error($original, 'UPDATE', __FILE__);
|
||||||
|
$this->showForm(_('Unable to save your design settings!'));
|
||||||
|
$user->query('ROLLBACK');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->query('COMMIT');
|
||||||
|
|
||||||
|
$this->saveBackgroundImage($design);
|
||||||
|
|
||||||
|
$this->showForm(_('Enjoy your hotdog!'), true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -795,7 +795,7 @@ class Notice extends Memcached_DataObject
|
|||||||
$notice->selectAdd(); // clears it
|
$notice->selectAdd(); // clears it
|
||||||
$notice->selectAdd('id');
|
$notice->selectAdd('id');
|
||||||
|
|
||||||
$notice->whereAdd('conversation = '.$id);
|
$notice->conversation = $id;
|
||||||
|
|
||||||
$notice->orderBy('id DESC');
|
$notice->orderBy('id DESC');
|
||||||
|
|
||||||
|
@ -132,6 +132,13 @@ class Status_network extends DB_DataObject
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$sn = self::memGet('hostname', strtolower($servername));
|
$sn = self::memGet('hostname', strtolower($servername));
|
||||||
|
|
||||||
|
if (empty($sn)) {
|
||||||
|
// Try for a no-www address
|
||||||
|
if (0 == strncasecmp($servername, 'www.', 4)) {
|
||||||
|
$sn = self::memGet('hostname', strtolower(substr($servername, 4)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($sn)) {
|
if (!empty($sn)) {
|
||||||
|
@ -126,6 +126,30 @@ class User_group extends Memcached_DataObject
|
|||||||
return $members;
|
return $members;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAdmins($offset=0, $limit=null)
|
||||||
|
{
|
||||||
|
$qry =
|
||||||
|
'SELECT profile.* ' .
|
||||||
|
'FROM profile JOIN group_member '.
|
||||||
|
'ON profile.id = group_member.profile_id ' .
|
||||||
|
'WHERE group_member.group_id = %d ' .
|
||||||
|
'AND group_member.is_admin = 1 ' .
|
||||||
|
'ORDER BY group_member.modified ASC ';
|
||||||
|
|
||||||
|
if ($limit != null) {
|
||||||
|
if (common_config('db','type') == 'pgsql') {
|
||||||
|
$qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
|
||||||
|
} else {
|
||||||
|
$qry .= ' LIMIT ' . $offset . ', ' . $limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$admins = new Profile();
|
||||||
|
|
||||||
|
$admins->query(sprintf($qry, $this->id));
|
||||||
|
return $admins;
|
||||||
|
}
|
||||||
|
|
||||||
function getBlocked($offset=0, $limit=null)
|
function getBlocked($offset=0, $limit=null)
|
||||||
{
|
{
|
||||||
$qry =
|
$qry =
|
||||||
|
@ -86,6 +86,9 @@ $config['sphinx']['port'] = 3312;
|
|||||||
// $config['xmpp']['public'][] = 'someindexer@example.net';
|
// $config['xmpp']['public'][] = 'someindexer@example.net';
|
||||||
// $config['xmpp']['debug'] = false;
|
// $config['xmpp']['debug'] = false;
|
||||||
|
|
||||||
|
// Turn off invites
|
||||||
|
// $config['invite']['enabled'] = false;
|
||||||
|
|
||||||
// Default locale info
|
// Default locale info
|
||||||
// $config['site']['timezone'] = 'Pacific/Auckland';
|
// $config['site']['timezone'] = 'Pacific/Auckland';
|
||||||
// $config['site']['language'] = 'en_NZ';
|
// $config['site']['language'] = 'en_NZ';
|
||||||
|
849
extlib/Mail/mimeDecode.php
Normal file
849
extlib/Mail/mimeDecode.php
Normal file
@ -0,0 +1,849 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* The Mail_mimeDecode class is used to decode mail/mime messages
|
||||||
|
*
|
||||||
|
* This class will parse a raw mime email and return
|
||||||
|
* the structure. Returned structure is similar to
|
||||||
|
* that returned by imap_fetchstructure().
|
||||||
|
*
|
||||||
|
* +----------------------------- IMPORTANT ------------------------------+
|
||||||
|
* | Usage of this class compared to native php extensions such as |
|
||||||
|
* | mailparse or imap, is slow and may be feature deficient. If available|
|
||||||
|
* | you are STRONGLY recommended to use the php extensions. |
|
||||||
|
* +----------------------------------------------------------------------+
|
||||||
|
*
|
||||||
|
* Compatible with PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* LICENSE: This LICENSE is in the BSD license style.
|
||||||
|
* Copyright (c) 2002-2003, Richard Heyes <richard@phpguru.org>
|
||||||
|
* Copyright (c) 2003-2006, PEAR <pear-group@php.net>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or
|
||||||
|
* without modification, are permitted provided that the following
|
||||||
|
* conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* - Neither the name of the authors, nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||||
|
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @category Mail
|
||||||
|
* @package Mail_Mime
|
||||||
|
* @author Richard Heyes <richard@phpguru.org>
|
||||||
|
* @author George Schlossnagle <george@omniti.com>
|
||||||
|
* @author Cipriano Groenendal <cipri@php.net>
|
||||||
|
* @author Sean Coates <sean@php.net>
|
||||||
|
* @copyright 2003-2006 PEAR <pear-group@php.net>
|
||||||
|
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||||
|
* @version CVS: $Id: mimeDecode.php,v 1.48 2006/12/03 13:43:33 cipri Exp $
|
||||||
|
* @link http://pear.php.net/package/Mail_mime
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* require PEAR
|
||||||
|
*
|
||||||
|
* This package depends on PEAR to raise errors.
|
||||||
|
*/
|
||||||
|
require_once 'PEAR.php';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Mail_mimeDecode class is used to decode mail/mime messages
|
||||||
|
*
|
||||||
|
* This class will parse a raw mime email and return the structure.
|
||||||
|
* Returned structure is similar to that returned by imap_fetchstructure().
|
||||||
|
*
|
||||||
|
* +----------------------------- IMPORTANT ------------------------------+
|
||||||
|
* | Usage of this class compared to native php extensions such as |
|
||||||
|
* | mailparse or imap, is slow and may be feature deficient. If available|
|
||||||
|
* | you are STRONGLY recommended to use the php extensions. |
|
||||||
|
* +----------------------------------------------------------------------+
|
||||||
|
*
|
||||||
|
* @category Mail
|
||||||
|
* @package Mail_Mime
|
||||||
|
* @author Richard Heyes <richard@phpguru.org>
|
||||||
|
* @author George Schlossnagle <george@omniti.com>
|
||||||
|
* @author Cipriano Groenendal <cipri@php.net>
|
||||||
|
* @author Sean Coates <sean@php.net>
|
||||||
|
* @copyright 2003-2006 PEAR <pear-group@php.net>
|
||||||
|
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||||
|
* @version Release: @package_version@
|
||||||
|
* @link http://pear.php.net/package/Mail_mime
|
||||||
|
*/
|
||||||
|
class Mail_mimeDecode extends PEAR
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The raw email to decode
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The header part of the input
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_header;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The body part of the input
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_body;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If an error occurs, this is used to store the message
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to determine whether to include bodies in the
|
||||||
|
* returned object.
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_include_bodies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to determine whether to decode bodies
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_decode_bodies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to determine whether to decode headers
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_decode_headers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* Sets up the object, initialise the variables, and splits and
|
||||||
|
* stores the header and body of the input.
|
||||||
|
*
|
||||||
|
* @param string The input to decode
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function Mail_mimeDecode($input)
|
||||||
|
{
|
||||||
|
list($header, $body) = $this->_splitBodyHeader($input);
|
||||||
|
|
||||||
|
$this->_input = $input;
|
||||||
|
$this->_header = $header;
|
||||||
|
$this->_body = $body;
|
||||||
|
$this->_decode_bodies = false;
|
||||||
|
$this->_include_bodies = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins the decoding process. If called statically
|
||||||
|
* it will create an object and call the decode() method
|
||||||
|
* of it.
|
||||||
|
*
|
||||||
|
* @param array An array of various parameters that determine
|
||||||
|
* various things:
|
||||||
|
* include_bodies - Whether to include the body in the returned
|
||||||
|
* object.
|
||||||
|
* decode_bodies - Whether to decode the bodies
|
||||||
|
* of the parts. (Transfer encoding)
|
||||||
|
* decode_headers - Whether to decode headers
|
||||||
|
* input - If called statically, this will be treated
|
||||||
|
* as the input
|
||||||
|
* @return object Decoded results
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function decode($params = null)
|
||||||
|
{
|
||||||
|
// determine if this method has been called statically
|
||||||
|
$isStatic = !(isset($this) && get_class($this) == __CLASS__);
|
||||||
|
|
||||||
|
// Have we been called statically?
|
||||||
|
// If so, create an object and pass details to that.
|
||||||
|
if ($isStatic AND isset($params['input'])) {
|
||||||
|
|
||||||
|
$obj = new Mail_mimeDecode($params['input']);
|
||||||
|
$structure = $obj->decode($params);
|
||||||
|
|
||||||
|
// Called statically but no input
|
||||||
|
} elseif ($isStatic) {
|
||||||
|
return PEAR::raiseError('Called statically and no input given');
|
||||||
|
|
||||||
|
// Called via an object
|
||||||
|
} else {
|
||||||
|
$this->_include_bodies = isset($params['include_bodies']) ?
|
||||||
|
$params['include_bodies'] : false;
|
||||||
|
$this->_decode_bodies = isset($params['decode_bodies']) ?
|
||||||
|
$params['decode_bodies'] : false;
|
||||||
|
$this->_decode_headers = isset($params['decode_headers']) ?
|
||||||
|
$params['decode_headers'] : false;
|
||||||
|
|
||||||
|
$structure = $this->_decode($this->_header, $this->_body);
|
||||||
|
if ($structure === false) {
|
||||||
|
$structure = $this->raiseError($this->_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the decoding. Decodes the body string passed to it
|
||||||
|
* If it finds certain content-types it will call itself in a
|
||||||
|
* recursive fashion
|
||||||
|
*
|
||||||
|
* @param string Header section
|
||||||
|
* @param string Body section
|
||||||
|
* @return object Results of decoding process
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _decode($headers, $body, $default_ctype = 'text/plain')
|
||||||
|
{
|
||||||
|
$return = new stdClass;
|
||||||
|
$return->headers = array();
|
||||||
|
$headers = $this->_parseHeaders($headers);
|
||||||
|
|
||||||
|
foreach ($headers as $value) {
|
||||||
|
if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {
|
||||||
|
$return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]);
|
||||||
|
$return->headers[strtolower($value['name'])][] = $value['value'];
|
||||||
|
|
||||||
|
} elseif (isset($return->headers[strtolower($value['name'])])) {
|
||||||
|
$return->headers[strtolower($value['name'])][] = $value['value'];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$return->headers[strtolower($value['name'])] = $value['value'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset($headers);
|
||||||
|
while (list($key, $value) = each($headers)) {
|
||||||
|
$headers[$key]['name'] = strtolower($headers[$key]['name']);
|
||||||
|
switch ($headers[$key]['name']) {
|
||||||
|
|
||||||
|
case 'content-type':
|
||||||
|
$content_type = $this->_parseHeaderValue($headers[$key]['value']);
|
||||||
|
|
||||||
|
if (preg_match('/([0-9a-z+.-]+)\/([0-9a-z+.-]+)/i', $content_type['value'], $regs)) {
|
||||||
|
$return->ctype_primary = $regs[1];
|
||||||
|
$return->ctype_secondary = $regs[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($content_type['other'])) {
|
||||||
|
while (list($p_name, $p_value) = each($content_type['other'])) {
|
||||||
|
$return->ctype_parameters[$p_name] = $p_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'content-disposition':
|
||||||
|
$content_disposition = $this->_parseHeaderValue($headers[$key]['value']);
|
||||||
|
$return->disposition = $content_disposition['value'];
|
||||||
|
if (isset($content_disposition['other'])) {
|
||||||
|
while (list($p_name, $p_value) = each($content_disposition['other'])) {
|
||||||
|
$return->d_parameters[$p_name] = $p_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'content-transfer-encoding':
|
||||||
|
$content_transfer_encoding = $this->_parseHeaderValue($headers[$key]['value']);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($content_type)) {
|
||||||
|
switch (strtolower($content_type['value'])) {
|
||||||
|
case 'text/plain':
|
||||||
|
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
|
||||||
|
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'text/html':
|
||||||
|
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
|
||||||
|
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body) : null;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'multipart/parallel':
|
||||||
|
case 'multipart/appledouble': // Appledouble mail
|
||||||
|
case 'multipart/report': // RFC1892
|
||||||
|
case 'multipart/signed': // PGP
|
||||||
|
case 'multipart/digest':
|
||||||
|
case 'multipart/alternative':
|
||||||
|
case 'multipart/related':
|
||||||
|
case 'multipart/mixed':
|
||||||
|
if(!isset($content_type['other']['boundary'])){
|
||||||
|
$this->_error = 'No boundary found for ' . $content_type['value'] . ' part';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$default_ctype = (strtolower($content_type['value']) === 'multipart/digest') ? 'message/rfc822' : 'text/plain';
|
||||||
|
|
||||||
|
$parts = $this->_boundarySplit($body, $content_type['other']['boundary']);
|
||||||
|
for ($i = 0; $i < count($parts); $i++) {
|
||||||
|
list($part_header, $part_body) = $this->_splitBodyHeader($parts[$i]);
|
||||||
|
$part = $this->_decode($part_header, $part_body, $default_ctype);
|
||||||
|
if($part === false)
|
||||||
|
$part = $this->raiseError($this->_error);
|
||||||
|
$return->parts[] = $part;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'message/rfc822':
|
||||||
|
$obj = &new Mail_mimeDecode($body);
|
||||||
|
$return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies,
|
||||||
|
'decode_bodies' => $this->_decode_bodies,
|
||||||
|
'decode_headers' => $this->_decode_headers));
|
||||||
|
unset($obj);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if(!isset($content_transfer_encoding['value']))
|
||||||
|
$content_transfer_encoding['value'] = '7bit';
|
||||||
|
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $content_transfer_encoding['value']) : $body) : null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$ctype = explode('/', $default_ctype);
|
||||||
|
$return->ctype_primary = $ctype[0];
|
||||||
|
$return->ctype_secondary = $ctype[1];
|
||||||
|
$this->_include_bodies ? $return->body = ($this->_decode_bodies ? $this->_decodeBody($body) : $body) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the output of the above function, this will return an
|
||||||
|
* array of references to the parts, indexed by mime number.
|
||||||
|
*
|
||||||
|
* @param object $structure The structure to go through
|
||||||
|
* @param string $mime_number Internal use only.
|
||||||
|
* @return array Mime numbers
|
||||||
|
*/
|
||||||
|
function &getMimeNumbers(&$structure, $no_refs = false, $mime_number = '', $prepend = '')
|
||||||
|
{
|
||||||
|
$return = array();
|
||||||
|
if (!empty($structure->parts)) {
|
||||||
|
if ($mime_number != '') {
|
||||||
|
$structure->mime_id = $prepend . $mime_number;
|
||||||
|
$return[$prepend . $mime_number] = &$structure;
|
||||||
|
}
|
||||||
|
for ($i = 0; $i < count($structure->parts); $i++) {
|
||||||
|
|
||||||
|
|
||||||
|
if (!empty($structure->headers['content-type']) AND substr(strtolower($structure->headers['content-type']), 0, 8) == 'message/') {
|
||||||
|
$prepend = $prepend . $mime_number . '.';
|
||||||
|
$_mime_number = '';
|
||||||
|
} else {
|
||||||
|
$_mime_number = ($mime_number == '' ? $i + 1 : sprintf('%s.%s', $mime_number, $i + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
$arr = &Mail_mimeDecode::getMimeNumbers($structure->parts[$i], $no_refs, $_mime_number, $prepend);
|
||||||
|
foreach ($arr as $key => $val) {
|
||||||
|
$no_refs ? $return[$key] = '' : $return[$key] = &$arr[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($mime_number == '') {
|
||||||
|
$mime_number = '1';
|
||||||
|
}
|
||||||
|
$structure->mime_id = $prepend . $mime_number;
|
||||||
|
$no_refs ? $return[$prepend . $mime_number] = '' : $return[$prepend . $mime_number] = &$structure;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a string containing a header and body
|
||||||
|
* section, this function will split them (at the first
|
||||||
|
* blank line) and return them.
|
||||||
|
*
|
||||||
|
* @param string Input to split apart
|
||||||
|
* @return array Contains header and body section
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _splitBodyHeader($input)
|
||||||
|
{
|
||||||
|
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
|
||||||
|
return array($match[1], $match[2]);
|
||||||
|
}
|
||||||
|
$this->_error = 'Could not split header and body';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse headers given in $input and return
|
||||||
|
* as assoc array.
|
||||||
|
*
|
||||||
|
* @param string Headers to parse
|
||||||
|
* @return array Contains parsed headers
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _parseHeaders($input)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ($input !== '') {
|
||||||
|
// Unfold the input
|
||||||
|
$input = preg_replace("/\r?\n/", "\r\n", $input);
|
||||||
|
$input = preg_replace("/\r\n(\t| )+/", ' ', $input);
|
||||||
|
$headers = explode("\r\n", trim($input));
|
||||||
|
|
||||||
|
foreach ($headers as $value) {
|
||||||
|
$hdr_name = substr($value, 0, $pos = strpos($value, ':'));
|
||||||
|
$hdr_value = substr($value, $pos+1);
|
||||||
|
if($hdr_value[0] == ' ')
|
||||||
|
$hdr_value = substr($hdr_value, 1);
|
||||||
|
|
||||||
|
$return[] = array(
|
||||||
|
'name' => $hdr_name,
|
||||||
|
'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$return = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to parse a header value,
|
||||||
|
* extract first part, and any secondary
|
||||||
|
* parts (after ;) This function is not as
|
||||||
|
* robust as it could be. Eg. header comments
|
||||||
|
* in the wrong place will probably break it.
|
||||||
|
*
|
||||||
|
* @param string Header value to parse
|
||||||
|
* @return array Contains parsed result
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _parseHeaderValue($input)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (($pos = strpos($input, ';')) !== false) {
|
||||||
|
|
||||||
|
$return['value'] = trim(substr($input, 0, $pos));
|
||||||
|
$input = trim(substr($input, $pos+1));
|
||||||
|
|
||||||
|
if (strlen($input) > 0) {
|
||||||
|
|
||||||
|
// This splits on a semi-colon, if there's no preceeding backslash
|
||||||
|
// Now works with quoted values; had to glue the \; breaks in PHP
|
||||||
|
// the regex is already bordering on incomprehensible
|
||||||
|
$splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/';
|
||||||
|
preg_match_all($splitRegex, $input, $matches);
|
||||||
|
$parameters = array();
|
||||||
|
for ($i=0; $i<count($matches[0]); $i++) {
|
||||||
|
$param = $matches[0][$i];
|
||||||
|
while (substr($param, -2) == '\;') {
|
||||||
|
$param .= $matches[0][++$i];
|
||||||
|
}
|
||||||
|
$parameters[] = $param;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($parameters); $i++) {
|
||||||
|
$param_name = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ ");
|
||||||
|
$param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ ");
|
||||||
|
if ($param_value[0] == '"') {
|
||||||
|
$param_value = substr($param_value, 1, -1);
|
||||||
|
}
|
||||||
|
$return['other'][$param_name] = $param_value;
|
||||||
|
$return['other'][strtolower($param_name)] = $param_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$return['value'] = trim($input);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function splits the input based
|
||||||
|
* on the given boundary
|
||||||
|
*
|
||||||
|
* @param string Input to parse
|
||||||
|
* @return array Contains array of resulting mime parts
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _boundarySplit($input, $boundary)
|
||||||
|
{
|
||||||
|
$parts = array();
|
||||||
|
|
||||||
|
$bs_possible = substr($boundary, 2, -2);
|
||||||
|
$bs_check = '\"' . $bs_possible . '\"';
|
||||||
|
|
||||||
|
if ($boundary == $bs_check) {
|
||||||
|
$boundary = $bs_possible;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp = explode('--' . $boundary, $input);
|
||||||
|
|
||||||
|
for ($i = 1; $i < count($tmp) - 1; $i++) {
|
||||||
|
$parts[] = $tmp[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a header, this function will decode it
|
||||||
|
* according to RFC2047. Probably not *exactly*
|
||||||
|
* conformant, but it does pass all the given
|
||||||
|
* examples (in RFC2047).
|
||||||
|
*
|
||||||
|
* @param string Input header value to decode
|
||||||
|
* @return string Decoded header value
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _decodeHeader($input)
|
||||||
|
{
|
||||||
|
// Remove white space between encoded-words
|
||||||
|
$input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
|
||||||
|
|
||||||
|
// For each encoded-word...
|
||||||
|
while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
|
||||||
|
|
||||||
|
$encoded = $matches[1];
|
||||||
|
$charset = $matches[2];
|
||||||
|
$encoding = $matches[3];
|
||||||
|
$text = $matches[4];
|
||||||
|
|
||||||
|
switch (strtolower($encoding)) {
|
||||||
|
case 'b':
|
||||||
|
$text = base64_decode($text);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
$text = str_replace('_', ' ', $text);
|
||||||
|
preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
|
||||||
|
foreach($matches[1] as $value)
|
||||||
|
$text = str_replace('='.$value, chr(hexdec($value)), $text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = str_replace($encoded, $text, $input);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a body string and an encoding type,
|
||||||
|
* this function will decode and return it.
|
||||||
|
*
|
||||||
|
* @param string Input body to decode
|
||||||
|
* @param string Encoding type to use.
|
||||||
|
* @return string Decoded body
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _decodeBody($input, $encoding = '7bit')
|
||||||
|
{
|
||||||
|
switch (strtolower($encoding)) {
|
||||||
|
case '7bit':
|
||||||
|
return $input;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'quoted-printable':
|
||||||
|
return $this->_quotedPrintableDecode($input);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'base64':
|
||||||
|
return base64_decode($input);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a quoted-printable string, this
|
||||||
|
* function will decode and return it.
|
||||||
|
*
|
||||||
|
* @param string Input body to decode
|
||||||
|
* @return string Decoded body
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _quotedPrintableDecode($input)
|
||||||
|
{
|
||||||
|
// Remove soft line breaks
|
||||||
|
$input = preg_replace("/=\r?\n/", '', $input);
|
||||||
|
|
||||||
|
// Replace encoded characters
|
||||||
|
$input = preg_replace('/=([a-f0-9]{2})/ie', "chr(hexdec('\\1'))", $input);
|
||||||
|
|
||||||
|
return $input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the input for uuencoded files and returns
|
||||||
|
* an array of them. Can be called statically, eg:
|
||||||
|
*
|
||||||
|
* $files =& Mail_mimeDecode::uudecode($some_text);
|
||||||
|
*
|
||||||
|
* It will check for the begin 666 ... end syntax
|
||||||
|
* however and won't just blindly decode whatever you
|
||||||
|
* pass it.
|
||||||
|
*
|
||||||
|
* @param string Input body to look for attahcments in
|
||||||
|
* @return array Decoded bodies, filenames and permissions
|
||||||
|
* @access public
|
||||||
|
* @author Unknown
|
||||||
|
*/
|
||||||
|
function &uudecode($input)
|
||||||
|
{
|
||||||
|
// Find all uuencoded sections
|
||||||
|
preg_match_all("/begin ([0-7]{3}) (.+)\r?\n(.+)\r?\nend/Us", $input, $matches);
|
||||||
|
|
||||||
|
for ($j = 0; $j < count($matches[3]); $j++) {
|
||||||
|
|
||||||
|
$str = $matches[3][$j];
|
||||||
|
$filename = $matches[2][$j];
|
||||||
|
$fileperm = $matches[1][$j];
|
||||||
|
|
||||||
|
$file = '';
|
||||||
|
$str = preg_split("/\r?\n/", trim($str));
|
||||||
|
$strlen = count($str);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $strlen; $i++) {
|
||||||
|
$pos = 1;
|
||||||
|
$d = 0;
|
||||||
|
$len=(int)(((ord(substr($str[$i],0,1)) -32) - ' ') & 077);
|
||||||
|
|
||||||
|
while (($d + 3 <= $len) AND ($pos + 4 <= strlen($str[$i]))) {
|
||||||
|
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
|
||||||
|
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
|
||||||
|
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
|
||||||
|
$c3 = (ord(substr($str[$i],$pos+3,1)) ^ 0x20);
|
||||||
|
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
|
||||||
|
|
||||||
|
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
|
||||||
|
|
||||||
|
$file .= chr(((($c2 - ' ') & 077) << 6) | (($c3 - ' ') & 077));
|
||||||
|
|
||||||
|
$pos += 4;
|
||||||
|
$d += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($d + 2 <= $len) && ($pos + 3 <= strlen($str[$i]))) {
|
||||||
|
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
|
||||||
|
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
|
||||||
|
$c2 = (ord(substr($str[$i],$pos+2,1)) ^ 0x20);
|
||||||
|
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
|
||||||
|
|
||||||
|
$file .= chr(((($c1 - ' ') & 077) << 4) | ((($c2 - ' ') & 077) >> 2));
|
||||||
|
|
||||||
|
$pos += 3;
|
||||||
|
$d += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($d + 1 <= $len) && ($pos + 2 <= strlen($str[$i]))) {
|
||||||
|
$c0 = (ord(substr($str[$i],$pos,1)) ^ 0x20);
|
||||||
|
$c1 = (ord(substr($str[$i],$pos+1,1)) ^ 0x20);
|
||||||
|
$file .= chr(((($c0 - ' ') & 077) << 2) | ((($c1 - ' ') & 077) >> 4));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$files[] = array('filename' => $filename, 'fileperm' => $fileperm, 'filedata' => $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSendArray() returns the arguments required for Mail::send()
|
||||||
|
* used to build the arguments for a mail::send() call
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* $mailtext = Full email (for example generated by a template)
|
||||||
|
* $decoder = new Mail_mimeDecode($mailtext);
|
||||||
|
* $parts = $decoder->getSendArray();
|
||||||
|
* if (!PEAR::isError($parts) {
|
||||||
|
* list($recipents,$headers,$body) = $parts;
|
||||||
|
* $mail = Mail::factory('smtp');
|
||||||
|
* $mail->send($recipents,$headers,$body);
|
||||||
|
* } else {
|
||||||
|
* echo $parts->message;
|
||||||
|
* }
|
||||||
|
* @return mixed array of recipeint, headers,body or Pear_Error
|
||||||
|
* @access public
|
||||||
|
* @author Alan Knowles <alan@akbkhome.com>
|
||||||
|
*/
|
||||||
|
function getSendArray()
|
||||||
|
{
|
||||||
|
// prevent warning if this is not set
|
||||||
|
$this->_decode_headers = FALSE;
|
||||||
|
$headerlist =$this->_parseHeaders($this->_header);
|
||||||
|
$to = "";
|
||||||
|
if (!$headerlist) {
|
||||||
|
return $this->raiseError("Message did not contain headers");
|
||||||
|
}
|
||||||
|
foreach($headerlist as $item) {
|
||||||
|
$header[$item['name']] = $item['value'];
|
||||||
|
switch (strtolower($item['name'])) {
|
||||||
|
case "to":
|
||||||
|
case "cc":
|
||||||
|
case "bcc":
|
||||||
|
$to = ",".$item['value'];
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($to == "") {
|
||||||
|
return $this->raiseError("Message did not contain any recipents");
|
||||||
|
}
|
||||||
|
$to = substr($to,1);
|
||||||
|
return array($to,$header,$this->_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a xml copy of the output of
|
||||||
|
* Mail_mimeDecode::decode. Pass the output in as the
|
||||||
|
* argument. This function can be called statically. Eg:
|
||||||
|
*
|
||||||
|
* $output = $obj->decode();
|
||||||
|
* $xml = Mail_mimeDecode::getXML($output);
|
||||||
|
*
|
||||||
|
* The DTD used for this should have been in the package. Or
|
||||||
|
* alternatively you can get it from cvs, or here:
|
||||||
|
* http://www.phpguru.org/xmail/xmail.dtd.
|
||||||
|
*
|
||||||
|
* @param object Input to convert to xml. This should be the
|
||||||
|
* output of the Mail_mimeDecode::decode function
|
||||||
|
* @return string XML version of input
|
||||||
|
* @access public
|
||||||
|
*/
|
||||||
|
function getXML($input)
|
||||||
|
{
|
||||||
|
$crlf = "\r\n";
|
||||||
|
$output = '<?xml version=\'1.0\'?>' . $crlf .
|
||||||
|
'<!DOCTYPE email SYSTEM "http://www.phpguru.org/xmail/xmail.dtd">' . $crlf .
|
||||||
|
'<email>' . $crlf .
|
||||||
|
Mail_mimeDecode::_getXML($input) .
|
||||||
|
'</email>';
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function that does the actual conversion to xml. Does a single
|
||||||
|
* mimepart at a time.
|
||||||
|
*
|
||||||
|
* @param object Input to convert to xml. This is a mimepart object.
|
||||||
|
* It may or may not contain subparts.
|
||||||
|
* @param integer Number of tabs to indent
|
||||||
|
* @return string XML version of input
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _getXML($input, $indent = 1)
|
||||||
|
{
|
||||||
|
$htab = "\t";
|
||||||
|
$crlf = "\r\n";
|
||||||
|
$output = '';
|
||||||
|
$headers = @(array)$input->headers;
|
||||||
|
|
||||||
|
foreach ($headers as $hdr_name => $hdr_value) {
|
||||||
|
|
||||||
|
// Multiple headers with this name
|
||||||
|
if (is_array($headers[$hdr_name])) {
|
||||||
|
for ($i = 0; $i < count($hdr_value); $i++) {
|
||||||
|
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value[$i], $indent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only one header of this sort
|
||||||
|
} else {
|
||||||
|
$output .= Mail_mimeDecode::_getXML_helper($hdr_name, $hdr_value, $indent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($input->parts)) {
|
||||||
|
for ($i = 0; $i < count($input->parts); $i++) {
|
||||||
|
$output .= $crlf . str_repeat($htab, $indent) . '<mimepart>' . $crlf .
|
||||||
|
Mail_mimeDecode::_getXML($input->parts[$i], $indent+1) .
|
||||||
|
str_repeat($htab, $indent) . '</mimepart>' . $crlf;
|
||||||
|
}
|
||||||
|
} elseif (isset($input->body)) {
|
||||||
|
$output .= $crlf . str_repeat($htab, $indent) . '<body><![CDATA[' .
|
||||||
|
$input->body . ']]></body>' . $crlf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to _getXML(). Returns xml of a header.
|
||||||
|
*
|
||||||
|
* @param string Name of header
|
||||||
|
* @param string Value of header
|
||||||
|
* @param integer Number of tabs to indent
|
||||||
|
* @return string XML version of input
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
function _getXML_helper($hdr_name, $hdr_value, $indent)
|
||||||
|
{
|
||||||
|
$htab = "\t";
|
||||||
|
$crlf = "\r\n";
|
||||||
|
$return = '';
|
||||||
|
|
||||||
|
$new_hdr_value = ($hdr_name != 'received') ? Mail_mimeDecode::_parseHeaderValue($hdr_value) : array('value' => $hdr_value);
|
||||||
|
$new_hdr_name = str_replace(' ', '-', ucwords(str_replace('-', ' ', $hdr_name)));
|
||||||
|
|
||||||
|
// Sort out any parameters
|
||||||
|
if (!empty($new_hdr_value['other'])) {
|
||||||
|
foreach ($new_hdr_value['other'] as $paramname => $paramvalue) {
|
||||||
|
$params[] = str_repeat($htab, $indent) . $htab . '<parameter>' . $crlf .
|
||||||
|
str_repeat($htab, $indent) . $htab . $htab . '<paramname>' . htmlspecialchars($paramname) . '</paramname>' . $crlf .
|
||||||
|
str_repeat($htab, $indent) . $htab . $htab . '<paramvalue>' . htmlspecialchars($paramvalue) . '</paramvalue>' . $crlf .
|
||||||
|
str_repeat($htab, $indent) . $htab . '</parameter>' . $crlf;
|
||||||
|
}
|
||||||
|
|
||||||
|
$params = implode('', $params);
|
||||||
|
} else {
|
||||||
|
$params = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$return = str_repeat($htab, $indent) . '<header>' . $crlf .
|
||||||
|
str_repeat($htab, $indent) . $htab . '<headername>' . htmlspecialchars($new_hdr_name) . '</headername>' . $crlf .
|
||||||
|
str_repeat($htab, $indent) . $htab . '<headervalue>' . htmlspecialchars($new_hdr_value['value']) . '</headervalue>' . $crlf .
|
||||||
|
$params .
|
||||||
|
str_repeat($htab, $indent) . '</header>' . $crlf;
|
||||||
|
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of class
|
@ -27,7 +27,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** XMPPHP_XMLStream */
|
/** XMPPHP_XMLStream */
|
||||||
require_once "XMPP.php";
|
require_once dirname(__FILE__) . "/XMPP.php";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XMPPHP Main Class
|
* XMPPHP Main Class
|
||||||
|
@ -27,13 +27,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** XMPPHP_Exception */
|
/** XMPPHP_Exception */
|
||||||
require_once 'Exception.php';
|
require_once dirname(__FILE__) . '/Exception.php';
|
||||||
|
|
||||||
/** XMPPHP_XMLObj */
|
/** XMPPHP_XMLObj */
|
||||||
require_once 'XMLObj.php';
|
require_once dirname(__FILE__) . '/XMLObj.php';
|
||||||
|
|
||||||
/** XMPPHP_Log */
|
/** XMPPHP_Log */
|
||||||
require_once 'Log.php';
|
require_once dirname(__FILE__) . '/Log.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XMPPHP XML Stream
|
* XMPPHP XML Stream
|
||||||
@ -375,7 +375,7 @@ class XMPPHP_XMLStream {
|
|||||||
* integer -> process for this amount of time
|
* integer -> process for this amount of time
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private function __process($maximum=0) {
|
private function __process($maximum=5) {
|
||||||
|
|
||||||
$remaining = $maximum;
|
$remaining = $maximum;
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** XMPPHP_XMLStream */
|
/** XMPPHP_XMLStream */
|
||||||
require_once "XMLStream.php";
|
require_once dirname(__FILE__) . "/XMLStream.php";
|
||||||
require_once "Roster.php";
|
require_once dirname(__FILE__) . "/Roster.php";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XMPPHP Main Class
|
* XMPPHP Main Class
|
||||||
@ -208,6 +208,15 @@ class XMPPHP_XMPP extends XMPPHP_XMLStream {
|
|||||||
|
|
||||||
$this->send($out);
|
$this->send($out);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Send Auth request
|
||||||
|
*
|
||||||
|
* @param string $jid
|
||||||
|
*/
|
||||||
|
public function subscribe($jid) {
|
||||||
|
$this->send("<presence type='subscribe' to='{$jid}' from='{$this->fulljid}' />");
|
||||||
|
#$this->send("<presence type='subscribed' to='{$jid}' from='{$this->fulljid}' />");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message handler
|
* Message handler
|
||||||
|
@ -72,6 +72,12 @@ function checkPrereqs()
|
|||||||
<?
|
<?
|
||||||
$pass = false;
|
$pass = false;
|
||||||
}
|
}
|
||||||
|
if (!is_writable(INSTALLDIR.'/background/')) {
|
||||||
|
?><p class="error">Cannot write background directory: <code><?php echo INSTALLDIR; ?>/background/</code></p>
|
||||||
|
<p>On your server, try this command: <code>chmod a+w <?php echo INSTALLDIR; ?>/background/</code></p>
|
||||||
|
<?
|
||||||
|
$pass = false;
|
||||||
|
}
|
||||||
|
|
||||||
return $pass;
|
return $pass;
|
||||||
}
|
}
|
||||||
|
271
js/jquery.joverlay.js
Normal file
271
js/jquery.joverlay.js
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
/* Copyright (c) 2009 Alvaro A. Lima Jr http://alvarojunior.com/jquery/joverlay.html
|
||||||
|
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
||||||
|
* Version: 0.7.1 (JUN 15, 2009)
|
||||||
|
* Requires: jQuery 1.3+
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
// Global vars
|
||||||
|
var isIE6 = $.browser.msie && $.browser.version == 6.0; // =(
|
||||||
|
var JOVERLAY_TIMER = null;
|
||||||
|
var JOVERLAY_ELEMENT_PREV = null;
|
||||||
|
|
||||||
|
$.fn.jOverlay = function(options) {
|
||||||
|
|
||||||
|
// Element exist?
|
||||||
|
if ( $('#jOverlay').length ) {$.closeOverlay();}
|
||||||
|
|
||||||
|
// Clear Element Prev
|
||||||
|
JOVERLAY_ELEMENT_PREV = null;
|
||||||
|
|
||||||
|
// Clear Timer
|
||||||
|
if (JOVERLAY_TIMER !== null) {
|
||||||
|
clearTimeout( JOVERLAY_TIMER );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Options
|
||||||
|
var options = $.extend({}, $.fn.jOverlay.options, options);
|
||||||
|
|
||||||
|
// private function
|
||||||
|
function center(id) {
|
||||||
|
if (options.center) {
|
||||||
|
$.center(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var element = this.is('*') ? this : '#jOverlayContent';
|
||||||
|
var position = isIE6 ? 'absolute' : 'fixed';
|
||||||
|
var isImage = /([^\/\\]+)\.(png|gif|jpeg|jpg|bmp)$/i.test( options.url );
|
||||||
|
|
||||||
|
var imgLoading = options.imgLoading ? "<img id='jOverlayLoading' src='"+options.imgLoading+"' style='position:"+position+"; z-index:"+(options.zIndex + 9)+";'/>" : '';
|
||||||
|
|
||||||
|
$('body').prepend(imgLoading + "<div id='jOverlay' />"
|
||||||
|
+ "<div id='jOverlayContent' style='position:"+position+"; z-index:"+(options.zIndex + 5)+"; display:none;'/>"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Loading Centered
|
||||||
|
$('#jOverlayLoading').load(function(){
|
||||||
|
center(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
//IE 6 FIX
|
||||||
|
if ( isIE6 ) {
|
||||||
|
$('select').hide();
|
||||||
|
$('#jOverlayContent select').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overlay Style
|
||||||
|
$('#jOverlay').css({
|
||||||
|
backgroundColor : options.color,
|
||||||
|
position : position,
|
||||||
|
top : '0px',
|
||||||
|
left : '0px',
|
||||||
|
filter : 'alpha(opacity='+ (options.opacity * 100) +')', // IE =(
|
||||||
|
opacity : options.opacity, // Good Browser =D
|
||||||
|
zIndex : options.zIndex,
|
||||||
|
width : !isIE6 ? '100%' : $(window).width() + 'px',
|
||||||
|
height : !isIE6 ? '100%' : $(document).height() + 'px'
|
||||||
|
}).show();
|
||||||
|
|
||||||
|
// ELEMENT
|
||||||
|
if ( this.is('*') ) {
|
||||||
|
|
||||||
|
JOVERLAY_ELEMENT_PREV = this.prev();
|
||||||
|
|
||||||
|
$('#jOverlayContent').html(
|
||||||
|
this.show().attr('display', options.autoHide ? 'none' : this.css('display') )
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !isImage ) {
|
||||||
|
|
||||||
|
center('#jOverlayContent');
|
||||||
|
|
||||||
|
$('#jOverlayContent').show();
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if ( !options.url && $.isFunction( options.success ) ) {
|
||||||
|
options.success( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMAGE
|
||||||
|
if ( isImage ) {
|
||||||
|
|
||||||
|
$('<img/>').load(function(){
|
||||||
|
var resize = $.resize(this.width, this.height);
|
||||||
|
|
||||||
|
$(this).css({
|
||||||
|
width : resize.width,
|
||||||
|
height : resize.height
|
||||||
|
});
|
||||||
|
|
||||||
|
$( element ).html(this);
|
||||||
|
|
||||||
|
center('#jOverlayContent');
|
||||||
|
|
||||||
|
$('#jOverlayLoading').fadeOut(500);
|
||||||
|
$('#jOverlayContent').show();
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if ( $.isFunction( options.success ) ) {
|
||||||
|
options.success( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
}).error(function(){
|
||||||
|
alert('Image ('+options.url+') not found.');
|
||||||
|
$.closeOverlay();
|
||||||
|
}).attr({'src' : options.url, 'alt' : options.url});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// AJAX
|
||||||
|
if ( options.url && !isImage ) {
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: options.method,
|
||||||
|
data: options.data,
|
||||||
|
url: options.url,
|
||||||
|
success: function(responseText) {
|
||||||
|
|
||||||
|
$('#jOverlayLoading').fadeOut(500);
|
||||||
|
|
||||||
|
$( element ).html(responseText).show();
|
||||||
|
|
||||||
|
center('#jOverlayContent');
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if ($.isFunction( options.success )) {
|
||||||
|
options.success(responseText);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
error : function() {
|
||||||
|
alert('URL ('+options.url+') not found.');
|
||||||
|
$.closeOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// :(
|
||||||
|
if ( isIE6 ) {
|
||||||
|
|
||||||
|
// Window scroll
|
||||||
|
$(window).scroll(function(){
|
||||||
|
center('#jOverlayContent');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Window resize
|
||||||
|
$(window).resize(function(){
|
||||||
|
|
||||||
|
$('#jOverlay').css({
|
||||||
|
width: $(window).width() + 'px',
|
||||||
|
height: $(document).height() + 'px'
|
||||||
|
});
|
||||||
|
|
||||||
|
center('#jOverlayContent');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Press ESC to close
|
||||||
|
$(document).keydown(function(event){
|
||||||
|
if (event.keyCode == 27) {
|
||||||
|
$.closeOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Click to close
|
||||||
|
if ( options.bgClickToClose ) {
|
||||||
|
$('#jOverlay').click($.closeOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout (auto-close)
|
||||||
|
// time in millis to wait before auto-close
|
||||||
|
// set to 0 to disable
|
||||||
|
if ( Number(options.timeout) > 0 ) {
|
||||||
|
jOverlayTimer = setTimeout( $.closeOverlay, Number(options.timeout) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADD CSS
|
||||||
|
$('#jOverlayContent').css(options.css || {});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resizing large images - orginal by Christian Montoya.
|
||||||
|
// Edited by - Cody Lindley (http://www.codylindley.com) (Thickbox 3.1)
|
||||||
|
$.resize = function(imageWidth, imageHeight) {
|
||||||
|
var x = $(window).width() - 150;
|
||||||
|
var y = $(window).height() - 150;
|
||||||
|
if (imageWidth > x) {
|
||||||
|
imageHeight = imageHeight * (x / imageWidth);
|
||||||
|
imageWidth = x;
|
||||||
|
if (imageHeight > y) {
|
||||||
|
imageWidth = imageWidth * (y / imageHeight);
|
||||||
|
imageHeight = y;
|
||||||
|
}
|
||||||
|
} else if (imageHeight > y) {
|
||||||
|
imageWidth = imageWidth * (y / imageHeight);
|
||||||
|
imageHeight = y;
|
||||||
|
if (imageWidth > x) {
|
||||||
|
imageHeight = imageHeight * (x / imageWidth);
|
||||||
|
imageWidth = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {width:imageWidth, height:imageHeight};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Centered Element
|
||||||
|
$.center = function(element) {
|
||||||
|
var element = $(element);
|
||||||
|
var elemWidth = element.width();
|
||||||
|
|
||||||
|
element.css({
|
||||||
|
width : elemWidth + 'px',
|
||||||
|
marginLeft : '-' + (elemWidth / 2) + 'px',
|
||||||
|
marginTop : '-' + element.height() / 2 + 'px',
|
||||||
|
height : 'auto',
|
||||||
|
top : !isIE6 ? '50%' : $(window).scrollTop() + ($(window).height() / 2) + 'px',
|
||||||
|
left : '50%'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// Options default
|
||||||
|
$.fn.jOverlay.options = {
|
||||||
|
method : 'GET',
|
||||||
|
data : '',
|
||||||
|
url : '',
|
||||||
|
color : '#000',
|
||||||
|
opacity : '0.6',
|
||||||
|
zIndex : 9999,
|
||||||
|
center : true,
|
||||||
|
imgLoading : '',
|
||||||
|
bgClickToClose : true,
|
||||||
|
success : null,
|
||||||
|
timeout : 0,
|
||||||
|
autoHide : true,
|
||||||
|
css : {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close
|
||||||
|
$.closeOverlay = function() {
|
||||||
|
|
||||||
|
if (isIE6) { $("select").show(); }
|
||||||
|
|
||||||
|
if ( JOVERLAY_ELEMENT_PREV !== null ) {
|
||||||
|
if ( JOVERLAY_ELEMENT_PREV !== null ) {
|
||||||
|
var element = $('#jOverlayContent').children();
|
||||||
|
JOVERLAY_ELEMENT_PREV.after( element.css('display', element.attr('display') ) );
|
||||||
|
element.removeAttr('display');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#jOverlayLoading, #jOverlayContent, #jOverlay').remove();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery);
|
5
js/jquery.joverlay.min.js
vendored
5
js/jquery.joverlay.min.js
vendored
@ -1,6 +1,7 @@
|
|||||||
/* Copyright (c) 2009 Alvaro A. Lima Jr http://alvarojunior.com/jquery/joverlay.html
|
/* Copyright (c) 2009 Alvaro A. Lima Jr http://alvarojunior.com/jquery/joverlay.html
|
||||||
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
||||||
* Version: 0.6 (Abr 23, 2009)
|
* Version: 0.7.1 (JUN 15, 2009
|
||||||
* Requires: jQuery 1.3+
|
* Requires: jQuery 1.3+
|
||||||
|
* Packer from http://dean.edwards.name/packer/
|
||||||
*/
|
*/
|
||||||
(function($){var f=$.browser.msie&&$.browser.version==6.0;var g=null;$.fn.jOverlay=function(b){var b=$.extend({},$.fn.jOverlay.options,b);if(g!=null){clearTimeout(g)}var c=this.is('*')?this:'#jOverlayContent';var d=f?'absolute':'fixed';var e=b.imgLoading?"<img id='jOverlayLoading' src='"+b.imgLoading+"' style='position:"+d+"; z-index:"+(b.zIndex+9)+";'/>":'';$('body').prepend(e+"<div id='jOverlay' />"+"<div id='jOverlayContent' style='position:"+d+"; z-index:"+(b.zIndex+5)+"; display:none;'/>");$('#jOverlayLoading').load(function(){if(b.center){$.center(this)}});if(f){$("select").hide();$("#jOverlayContent select").show()}$('#jOverlay').css({backgroundColor:b.color,position:d,top:'0px',left:'0px',filter:'alpha(opacity='+(b.opacity*100)+')',opacity:b.opacity,zIndex:b.zIndex,width:!f?'100%':$(window).width()+'px',height:!f?'100%':$(document).height()+'px'}).show();if(this.is('*')){$('#jOverlayContent').html(this.addClass('jOverlayChildren').show()).show();if(b.center){$.center('#jOverlayContent')}if(!b.url&&$.isFunction(b.success)){b.success(this.html())}}if(b.url){$.ajax({type:b.method,data:b.data,url:b.url,success:function(a){$('#jOverlayLoading').fadeOut(600);$(c).html(a).show();if(b.center){$.center('#jOverlayContent')}if($.isFunction(b.success)){b.success(a)}}})}if(f){$(window).scroll(function(){if(b.center){$.center('#jOverlayContent')}});$(window).resize(function(){$('#jOverlay').css({width:$(window).width()+'px',height:$(document).height()+'px'});if(b.center){$.center('#jOverlayContent')}})}$(document).keydown(function(a){if(a.keyCode==27){$.closeOverlay()}});if(b.bgClickToClose){$('#jOverlay').click($.closeOverlay)}if(Number(b.timeout)>0){g=setTimeout($.closeOverlay,Number(b.timeout))}};$.center=function(a){var a=$(a);var b=a.height();var c=a.width();a.css({width:c+'px',marginLeft:'-'+(c/2)+'px',marginTop:'-'+b/2+'px',height:'auto',top:!f?'50%':$(window).scrollTop()+($(window).height()/2)+"px",left:'50%'})};$.fn.jOverlay.options={method:'GET',data:'',url:'',color:'#000',opacity:'0.6',zIndex:9999,center:true,imgLoading:'',bgClickToClose:true,success:null,timeout:0};$.closeOverlay=function(){if(f){$("select").show()}$('#jOverlayContent .jOverlayChildren').hide().prependTo($('body'));$('#jOverlayLoading, #jOverlayContent, #jOverlay').remove()}})(jQuery);
|
(function($){var g=$.browser.msie&&$.browser.version==6.0;var h=null;var i=null;$.fn.jOverlay=function(b){if($('#jOverlay').length){$.closeOverlay()}i=null;if(h!==null){clearTimeout(h)}var b=$.extend({},$.fn.jOverlay.options,b);function center(a){if(b.center){$.center(a)}}var c=this.is('*')?this:'#jOverlayContent';var d=g?'absolute':'fixed';var e=/([^\/\\]+)\.(png|gif|jpeg|jpg|bmp)$/i.test(b.url);var f=b.imgLoading?"<img id='jOverlayLoading' src='"+b.imgLoading+"' style='position:"+d+"; z-index:"+(b.zIndex+9)+";'/>":'';$('body').prepend(f+"<div id='jOverlay' />"+"<div id='jOverlayContent' style='position:"+d+"; z-index:"+(b.zIndex+5)+"; display:none;'/>");$('#jOverlayLoading').load(function(){center(this)});if(g){$('select').hide();$('#jOverlayContent select').show()}$('#jOverlay').css({backgroundColor:b.color,position:d,top:'0px',left:'0px',filter:'alpha(opacity='+(b.opacity*100)+')',opacity:b.opacity,zIndex:b.zIndex,width:!g?'100%':$(window).width()+'px',height:!g?'100%':$(document).height()+'px'}).show();if(this.is('*')){i=this.prev();$('#jOverlayContent').html(this.show().attr('display',b.autoHide?'none':this.css('display')));if(!e){center('#jOverlayContent');$('#jOverlayContent').show();if(!b.url&&$.isFunction(b.success)){b.success(this)}}}if(e){$('<img/>').load(function(){var a=$.resize(this.width,this.height);$(this).css({width:a.width,height:a.height});$(c).html(this);center('#jOverlayContent');$('#jOverlayLoading').fadeOut(500);$('#jOverlayContent').show();if($.isFunction(b.success)){b.success(this)}}).error(function(){alert('Image ('+b.url+') not found.');$.closeOverlay()}).attr({'src':b.url,'alt':b.url})}if(b.url&&!e){$.ajax({type:b.method,data:b.data,url:b.url,success:function(a){$('#jOverlayLoading').fadeOut(500);$(c).html(a).show();center('#jOverlayContent');if($.isFunction(b.success)){b.success(a)}},error:function(){alert('URL ('+b.url+') not found.');$.closeOverlay()}})}if(g){$(window).scroll(function(){center('#jOverlayContent')});$(window).resize(function(){$('#jOverlay').css({width:$(window).width()+'px',height:$(document).height()+'px'});center('#jOverlayContent')})}$(document).keydown(function(a){if(a.keyCode==27){$.closeOverlay()}});if(b.bgClickToClose){$('#jOverlay').click($.closeOverlay)}if(Number(b.timeout)>0){jOverlayTimer=setTimeout($.closeOverlay,Number(b.timeout))}$('#jOverlayContent').css(b.css||{})};$.resize=function(a,b){var x=$(window).width()-150;var y=$(window).height()-150;if(a>x){b=b*(x/a);a=x;if(b>y){a=a*(y/b);b=y}}else if(b>y){a=a*(y/b);b=y;if(a>x){b=b*(x/a);a=x}}return{width:a,height:b}};$.center=function(a){var a=$(a);var b=a.width();a.css({width:b+'px',marginLeft:'-'+(b/2)+'px',marginTop:'-'+a.height()/2+'px',height:'auto',top:!g?'50%':$(window).scrollTop()+($(window).height()/2)+'px',left:'50%'})};$.fn.jOverlay.options={method:'GET',data:'',url:'',color:'#000',opacity:'0.6',zIndex:9999,center:true,imgLoading:'',bgClickToClose:true,success:null,timeout:0,autoHide:true,css:{}};$.closeOverlay=function(){if(g){$("select").show()}if(i!==null){if(i!==null){var a=$('#jOverlayContent').children();i.after(a.css('display',a.attr('display')));a.removeAttr('display')}}$('#jOverlayLoading, #jOverlayContent, #jOverlay').remove()}})(jQuery);
|
||||||
|
12
js/util.js
12
js/util.js
@ -272,21 +272,23 @@ function NoticeAttachments() {
|
|||||||
color : '#000',
|
color : '#000',
|
||||||
opacity : '0.6',
|
opacity : '0.6',
|
||||||
zIndex : 99,
|
zIndex : 99,
|
||||||
center : true,
|
center : false,
|
||||||
imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif',
|
imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif',
|
||||||
bgClickToClose : true,
|
bgClickToClose : true,
|
||||||
success : function() {
|
success : function() {
|
||||||
$('#jOverlayContent').append('<button>×</button>');
|
$('#jOverlayContent').append('<button>×</button>');
|
||||||
$('#jOverlayContent button').click($.closeOverlay);
|
$('#jOverlayContent button').click($.closeOverlay);
|
||||||
},
|
},
|
||||||
timeout : 0
|
timeout : 0,
|
||||||
|
autoHide : true,
|
||||||
|
css : {'max-width':'502px', 'top':'22.5%', 'left':'32.5%'}
|
||||||
};
|
};
|
||||||
|
|
||||||
$('#content .notice a.attachment').click(function() {
|
$('#content .notice a.attachment').click(function() {
|
||||||
$().jOverlay({url: $('address .url')[0].href+'/attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
|
$().jOverlay({url: $('address .url')[0].href+'attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
var t;
|
var t;
|
||||||
$("body:not(#shownotice) #content .notice a.thumbnail").hover(
|
$("body:not(#shownotice) #content .notice a.thumbnail").hover(
|
||||||
function() {
|
function() {
|
||||||
@ -296,7 +298,7 @@ function NoticeAttachments() {
|
|||||||
|
|
||||||
if (anchor.children('img').length == 0) {
|
if (anchor.children('img').length == 0) {
|
||||||
t = setTimeout(function() {
|
t = setTimeout(function() {
|
||||||
$.get($('address .url')[0].href+'/attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
|
$.get($('address .url')[0].href+'attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
|
||||||
anchor.append(data);
|
anchor.append(data);
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
@ -40,7 +40,7 @@ class ShortUrlApi
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function is_long($url) {
|
private function is_long($url) {
|
||||||
return strlen($url) >= $this->long_limit;
|
return strlen($url) >= common_config('site', 'shorturllength');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function http_post($data) {
|
protected function http_post($data) {
|
||||||
|
@ -247,7 +247,6 @@ class Action extends HTMLOutputter // lawsuit
|
|||||||
'src' => common_path('js/jquery.joverlay.min.js')),
|
'src' => common_path('js/jquery.joverlay.min.js')),
|
||||||
' ');
|
' ');
|
||||||
|
|
||||||
|
|
||||||
Event::handle('EndShowJQueryScripts', array($this));
|
Event::handle('EndShowJQueryScripts', array($this));
|
||||||
}
|
}
|
||||||
if (Event::handle('StartShowLaconicaScripts', array($this))) {
|
if (Event::handle('StartShowLaconicaScripts', array($this))) {
|
||||||
@ -422,11 +421,13 @@ class Action extends HTMLOutputter // lawsuit
|
|||||||
$this->menuItem(common_local_url('smssettings'),
|
$this->menuItem(common_local_url('smssettings'),
|
||||||
_('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect');
|
_('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect');
|
||||||
}
|
}
|
||||||
$this->menuItem(common_local_url('invite'),
|
if (common_config('invite', 'enabled')) {
|
||||||
_('Invite'),
|
$this->menuItem(common_local_url('invite'),
|
||||||
sprintf(_('Invite friends and colleagues to join you on %s'),
|
_('Invite'),
|
||||||
common_config('site', 'name')),
|
sprintf(_('Invite friends and colleagues to join you on %s'),
|
||||||
false, 'nav_invitecontact');
|
common_config('site', 'name')),
|
||||||
|
false, 'nav_invitecontact');
|
||||||
|
}
|
||||||
$this->menuItem(common_local_url('logout'),
|
$this->menuItem(common_local_url('logout'),
|
||||||
_('Logout'), _('Logout from the site'), false, 'nav_logout');
|
_('Logout'), _('Logout from the site'), false, 'nav_logout');
|
||||||
}
|
}
|
||||||
@ -964,12 +965,16 @@ class Action extends HTMLOutputter // lawsuit
|
|||||||
$action = $this->trimmed('action');
|
$action = $this->trimmed('action');
|
||||||
$args = $this->args;
|
$args = $this->args;
|
||||||
unset($args['action']);
|
unset($args['action']);
|
||||||
|
if (common_config('site', 'fancy')) {
|
||||||
|
unset($args['p']);
|
||||||
|
}
|
||||||
if (array_key_exists('submit', $args)) {
|
if (array_key_exists('submit', $args)) {
|
||||||
unset($args['submit']);
|
unset($args['submit']);
|
||||||
}
|
}
|
||||||
foreach (array_keys($_COOKIE) as $cookie) {
|
foreach (array_keys($_COOKIE) as $cookie) {
|
||||||
unset($args[$cookie]);
|
unset($args[$cookie]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return common_local_url($action, $args);
|
return common_local_url($action, $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +120,7 @@ $config =
|
|||||||
'private' => false,
|
'private' => false,
|
||||||
'ssl' => 'never',
|
'ssl' => 'never',
|
||||||
'sslserver' => null,
|
'sslserver' => null,
|
||||||
|
'shorturllength' => 30,
|
||||||
'dupelimit' => 60), # default for same person saying the same thing
|
'dupelimit' => 60), # default for same person saying the same thing
|
||||||
'syslog' =>
|
'syslog' =>
|
||||||
array('appname' => 'laconica', # for syslog
|
array('appname' => 'laconica', # for syslog
|
||||||
@ -175,6 +176,8 @@ $config =
|
|||||||
'host' => null, # only set if != server
|
'host' => null, # only set if != server
|
||||||
'debug' => false, # print extra debug info
|
'debug' => false, # print extra debug info
|
||||||
'public' => array()), # JIDs of users who want to receive the public stream
|
'public' => array()), # JIDs of users who want to receive the public stream
|
||||||
|
'invite' =>
|
||||||
|
array('enabled' => true),
|
||||||
'sphinx' =>
|
'sphinx' =>
|
||||||
array('enabled' => false,
|
array('enabled' => false,
|
||||||
'server' => 'localhost',
|
'server' => 'localhost',
|
||||||
|
@ -23,6 +23,13 @@ if (!defined('LACONICA')) {
|
|||||||
|
|
||||||
class Daemon
|
class Daemon
|
||||||
{
|
{
|
||||||
|
var $daemonize = true;
|
||||||
|
|
||||||
|
function __construct($daemonize = true)
|
||||||
|
{
|
||||||
|
$this->daemonize = $daemonize;
|
||||||
|
}
|
||||||
|
|
||||||
function name()
|
function name()
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
@ -129,12 +136,16 @@ class Daemon
|
|||||||
common_log(LOG_INFO, $this->name() . ' already running. Exiting.');
|
common_log(LOG_INFO, $this->name() . ' already running. Exiting.');
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if ($this->background()) {
|
|
||||||
$this->writePidFile();
|
if ($this->daemonize) {
|
||||||
$this->changeUser();
|
common_log(LOG_INFO, 'Backgrounding daemon "'.$this->name().'"');
|
||||||
$this->run();
|
$this->background();
|
||||||
$this->clearPidFile();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->writePidFile();
|
||||||
|
$this->changeUser();
|
||||||
|
$this->run();
|
||||||
|
$this->clearPidFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
function run()
|
function run()
|
||||||
|
@ -35,6 +35,20 @@ if (!defined('LACONICA')) {
|
|||||||
require_once INSTALLDIR . '/lib/accountsettingsaction.php';
|
require_once INSTALLDIR . '/lib/accountsettingsaction.php';
|
||||||
require_once INSTALLDIR . '/lib/webcolor.php';
|
require_once INSTALLDIR . '/lib/webcolor.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for setting a user or group design
|
||||||
|
*
|
||||||
|
* Shows the design setting form and also handles some things like saving
|
||||||
|
* background images, and fetching a default design
|
||||||
|
*
|
||||||
|
* @category Settings
|
||||||
|
* @package Laconica
|
||||||
|
* @author Zach Copley <zach@controlyourself.ca>
|
||||||
|
* @author Sarven Capadisli <csarven@controlyourself.ca>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://laconi.ca/
|
||||||
|
*/
|
||||||
|
|
||||||
class DesignSettingsAction extends AccountSettingsAction
|
class DesignSettingsAction extends AccountSettingsAction
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -63,6 +77,14 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
'with a background image and a colour palette of your choice.');
|
'with a background image and a colour palette of your choice.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the design settings form
|
||||||
|
*
|
||||||
|
* @param Design $design a working design to show
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
|
||||||
function showDesignForm($design)
|
function showDesignForm($design)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -94,7 +116,8 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
|
|
||||||
if (!empty($design->backgroundimage)) {
|
if (!empty($design->backgroundimage)) {
|
||||||
|
|
||||||
$this->elementStart('li', array('id' => 'design_background-image_onoff'));
|
$this->elementStart('li', array('id' =>
|
||||||
|
'design_background-image_onoff'));
|
||||||
|
|
||||||
$this->element('img', array('src' =>
|
$this->element('img', array('src' =>
|
||||||
Design::url($design->backgroundimage)));
|
Design::url($design->backgroundimage)));
|
||||||
@ -136,7 +159,7 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->checkbox('design_background-image_repeat',
|
$this->checkbox('design_background-image_repeat',
|
||||||
_('Tile background image'),
|
_('Tile background image'),
|
||||||
($design->disposition & BACKGROUND_TILE) ? true : false );
|
($design->disposition & BACKGROUND_TILE) ? true : false);
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,18 +235,19 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
'maxlength' => '7',
|
'maxlength' => '7',
|
||||||
'size' => '7',
|
'size' => '7',
|
||||||
'value' => '#' . $lcolor->hexValue()));
|
'value' => '#' . $lcolor->hexValue()));
|
||||||
|
$this->elementEnd('li');
|
||||||
|
|
||||||
$this->elementEnd('li');
|
} catch (WebColorException $e) {
|
||||||
|
common_log(LOG_ERR, 'Bad color values in design ID: ' .$design->id);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (WebColorException $e) {
|
$this->elementEnd('ul');
|
||||||
common_log(LOG_ERR, 'Bad color values in design ID: ' .
|
$this->elementEnd('fieldset');
|
||||||
$design->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->elementEnd('ul');
|
$this->submit('defaults', _('Use defaults'), 'submit form_action-default',
|
||||||
$this->elementEnd('fieldset');
|
'defaults', _('Restore default designs'));
|
||||||
|
|
||||||
$this->element('input', array('id' => 'settings_design_reset',
|
$this->element('input', array('id' => 'settings_design_reset',
|
||||||
'type' => 'reset',
|
'type' => 'reset',
|
||||||
'value' => 'Reset',
|
'value' => 'Reset',
|
||||||
'class' => 'submit form_action-primary',
|
'class' => 'submit form_action-primary',
|
||||||
@ -271,8 +295,8 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
|
|
||||||
if ($this->arg('save')) {
|
if ($this->arg('save')) {
|
||||||
$this->saveDesign();
|
$this->saveDesign();
|
||||||
} else if ($this->arg('reset')) {
|
} else if ($this->arg('defaults')) {
|
||||||
$this->resetDesign();
|
$this->restoreDefaults();
|
||||||
} else {
|
} else {
|
||||||
$this->showForm(_('Unexpected form submission.'));
|
$this->showForm(_('Unexpected form submission.'));
|
||||||
}
|
}
|
||||||
@ -316,7 +340,7 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a default user design
|
* Get a default design
|
||||||
*
|
*
|
||||||
* @return Design design
|
* @return Design design
|
||||||
*/
|
*/
|
||||||
@ -358,7 +382,16 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
return $design;
|
return $design;
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveBackgroundImage($design) {
|
/**
|
||||||
|
* Save the background image, if any, and set its disposition
|
||||||
|
*
|
||||||
|
* @param Design $design a working design to attach the img to
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
|
||||||
|
function saveBackgroundImage($design)
|
||||||
|
{
|
||||||
|
|
||||||
// Now that we have a Design ID we can add a file to the design.
|
// Now that we have a Design ID we can add a file to the design.
|
||||||
// XXX: This is an additional DB hit, but figured having the image
|
// XXX: This is an additional DB hit, but figured having the image
|
||||||
@ -371,12 +404,12 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
$filepath = null;
|
$filepath = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$imagefile =
|
$imagefile =
|
||||||
ImageFile::fromUpload('design_background-image_file');
|
ImageFile::fromUpload('design_background-image_file');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$this->showForm($e->getMessage());
|
$this->showForm($e->getMessage());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$filename = Design::filename($design->id,
|
$filename = Design::filename($design->id,
|
||||||
image_type_to_extension($imagefile->type),
|
image_type_to_extension($imagefile->type),
|
||||||
@ -386,7 +419,14 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
|
|
||||||
move_uploaded_file($imagefile->filepath, $filepath);
|
move_uploaded_file($imagefile->filepath, $filepath);
|
||||||
|
|
||||||
|
// delete any old backround img laying around
|
||||||
|
|
||||||
|
if (isset($design->backgroundimage)) {
|
||||||
|
@unlink(Design::path($design->backgroundimage));
|
||||||
|
}
|
||||||
|
|
||||||
$original = clone($design);
|
$original = clone($design);
|
||||||
|
|
||||||
$design->backgroundimage = $filename;
|
$design->backgroundimage = $filename;
|
||||||
|
|
||||||
// default to on, no tile
|
// default to on, no tile
|
||||||
@ -403,4 +443,35 @@ class DesignSettingsAction extends AccountSettingsAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the user or group design to system defaults
|
||||||
|
*
|
||||||
|
* @return nothing
|
||||||
|
*/
|
||||||
|
|
||||||
|
function restoreDefaults()
|
||||||
|
{
|
||||||
|
$design = $this->getWorkingDesign();
|
||||||
|
$default = $this->defaultDesign();
|
||||||
|
$original = clone($design);
|
||||||
|
|
||||||
|
$design->backgroundcolor = $default->backgroundcolor;
|
||||||
|
$design->contentcolor = $default->contentcolor;
|
||||||
|
$design->sidebarcolor = $default->sidebarcolor;
|
||||||
|
$design->textcolor = $default->textcolor;
|
||||||
|
$design->linkcolor = $default->linkcolor;
|
||||||
|
|
||||||
|
$design->setDisposition(false, true, false);
|
||||||
|
|
||||||
|
$result = $design->update($original);
|
||||||
|
|
||||||
|
if ($result === false) {
|
||||||
|
common_log_db_error($design, 'UPDATE', __FILE__);
|
||||||
|
$this->showForm(_('Couldn\'t update your design.'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->showForm(_('Design defaults restored.'), true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -213,12 +213,14 @@ class FacebookAction extends Action
|
|||||||
array('href' => 'index.php', 'title' => _('Home')), _('Home'));
|
array('href' => 'index.php', 'title' => _('Home')), _('Home'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
|
|
||||||
$this->elementStart('li',
|
if (common_config('invite', 'enabled')) {
|
||||||
array('class' =>
|
$this->elementStart('li',
|
||||||
($this->action == 'facebookinvite') ? 'current' : 'facebook_invite'));
|
array('class' =>
|
||||||
$this->element('a',
|
($this->action == 'facebookinvite') ? 'current' : 'facebook_invite'));
|
||||||
array('href' => 'invite.php', 'title' => _('Invite')), _('Invite'));
|
$this->element('a',
|
||||||
$this->elementEnd('li');
|
array('href' => 'invite.php', 'title' => _('Invite')), _('Invite'));
|
||||||
|
$this->elementEnd('li');
|
||||||
|
}
|
||||||
|
|
||||||
$this->elementStart('li',
|
$this->elementStart('li',
|
||||||
array('class' =>
|
array('class' =>
|
||||||
|
@ -130,30 +130,46 @@ class GroupEditForm extends Form
|
|||||||
|
|
||||||
function formData()
|
function formData()
|
||||||
{
|
{
|
||||||
|
if ($this->group) {
|
||||||
|
$id = $this->group->id;
|
||||||
|
$nickname = $this->group->nickname;
|
||||||
|
$fullname = $this->group->fullname;
|
||||||
|
$homepage = $this->group->homepage;
|
||||||
|
$description = $this->group->description;
|
||||||
|
$location = $this->group->location;
|
||||||
|
} else {
|
||||||
|
$id = '';
|
||||||
|
$nickname = '';
|
||||||
|
$fullname = '';
|
||||||
|
$homepage = '';
|
||||||
|
$description = '';
|
||||||
|
$location = '';
|
||||||
|
}
|
||||||
|
|
||||||
$this->out->elementStart('ul', 'form_data');
|
$this->out->elementStart('ul', 'form_data');
|
||||||
$this->out->elementStart('li');
|
$this->out->elementStart('li');
|
||||||
$this->out->hidden('groupid', $this->group->id);
|
$this->out->hidden('groupid', $id);
|
||||||
$this->out->input('nickname', _('Nickname'),
|
$this->out->input('nickname', _('Nickname'),
|
||||||
($this->out->arg('nickname')) ? $this->out->arg('nickname') : $this->group->nickname,
|
($this->out->arg('nickname')) ? $this->out->arg('nickname') : $nickname,
|
||||||
_('1-64 lowercase letters or numbers, no punctuation or spaces'));
|
_('1-64 lowercase letters or numbers, no punctuation or spaces'));
|
||||||
$this->out->elementEnd('li');
|
$this->out->elementEnd('li');
|
||||||
$this->out->elementStart('li');
|
$this->out->elementStart('li');
|
||||||
$this->out->input('fullname', _('Full name'),
|
$this->out->input('fullname', _('Full name'),
|
||||||
($this->out->arg('fullname')) ? $this->out->arg('fullname') : $this->group->fullname);
|
($this->out->arg('fullname')) ? $this->out->arg('fullname') : $fullname);
|
||||||
$this->out->elementEnd('li');
|
$this->out->elementEnd('li');
|
||||||
$this->out->elementStart('li');
|
$this->out->elementStart('li');
|
||||||
$this->out->input('homepage', _('Homepage'),
|
$this->out->input('homepage', _('Homepage'),
|
||||||
($this->out->arg('homepage')) ? $this->out->arg('homepage') : $this->group->homepage,
|
($this->out->arg('homepage')) ? $this->out->arg('homepage') : $homepage,
|
||||||
_('URL of the homepage or blog of the group or topic'));
|
_('URL of the homepage or blog of the group or topic'));
|
||||||
$this->out->elementEnd('li');
|
$this->out->elementEnd('li');
|
||||||
$this->out->elementStart('li');
|
$this->out->elementStart('li');
|
||||||
$this->out->textarea('description', _('Description'),
|
$this->out->textarea('description', _('Description'),
|
||||||
($this->out->arg('description')) ? $this->out->arg('description') : $this->group->description,
|
($this->out->arg('description')) ? $this->out->arg('description') : $description,
|
||||||
_('Describe the group or topic in 140 chars'));
|
_('Describe the group or topic in 140 chars'));
|
||||||
$this->out->elementEnd('li');
|
$this->out->elementEnd('li');
|
||||||
$this->out->elementStart('li');
|
$this->out->elementStart('li');
|
||||||
$this->out->input('location', _('Location'),
|
$this->out->input('location', _('Location'),
|
||||||
($this->out->arg('location')) ? $this->out->arg('location') : $this->group->location,
|
($this->out->arg('location')) ? $this->out->arg('location') : $location,
|
||||||
_('Location for the group, if any, like "City, State (or Region), Country"'));
|
_('Location for the group, if any, like "City, State (or Region), Country"'));
|
||||||
$this->out->elementEnd('li');
|
$this->out->elementEnd('li');
|
||||||
if (common_config('group', 'maxaliases') > 0) {
|
if (common_config('group', 'maxaliases') > 0) {
|
||||||
|
@ -89,6 +89,7 @@ class JSONSearchResultsList
|
|||||||
function show()
|
function show()
|
||||||
{
|
{
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
|
$this->max_id = 0;
|
||||||
|
|
||||||
$time_start = microtime(true);
|
$time_start = microtime(true);
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ function get_all_languages() {
|
|||||||
'el' => array('q' => 0.1, 'lang' => 'el', 'name' => 'Greek', 'direction' => 'ltr'),
|
'el' => array('q' => 0.1, 'lang' => 'el', 'name' => 'Greek', 'direction' => 'ltr'),
|
||||||
'en-us' => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'),
|
'en-us' => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'),
|
||||||
'en-gb' => array('q' => 1, 'lang' => 'en_GB', 'name' => 'English (British)', 'direction' => 'ltr'),
|
'en-gb' => array('q' => 1, 'lang' => 'en_GB', 'name' => 'English (British)', 'direction' => 'ltr'),
|
||||||
'en' => array('q' => 1, 'lang' => 'en', 'name' => 'English', 'direction' => 'ltr'),
|
'en' => array('q' => 1, 'lang' => 'en_US', 'name' => 'English (US)', 'direction' => 'ltr'),
|
||||||
'es' => array('q' => 1, 'lang' => 'es', 'name' => 'Spanish', 'direction' => 'ltr'),
|
'es' => array('q' => 1, 'lang' => 'es', 'name' => 'Spanish', 'direction' => 'ltr'),
|
||||||
'fi' => array('q' => 1, 'lang' => 'fi', 'name' => 'Finnish', 'direction' => 'ltr'),
|
'fi' => array('q' => 1, 'lang' => 'fi', 'name' => 'Finnish', 'direction' => 'ltr'),
|
||||||
'fr-fr' => array('q' => 1, 'lang' => 'fr_FR', 'name' => 'French', 'direction' => 'ltr'),
|
'fr-fr' => array('q' => 1, 'lang' => 'fr_FR', 'name' => 'French', 'direction' => 'ltr'),
|
||||||
|
@ -108,7 +108,9 @@ class ProfileAction extends OwnerDesignAction
|
|||||||
|
|
||||||
$this->element('h2', null, _('Subscriptions'));
|
$this->element('h2', null, _('Subscriptions'));
|
||||||
|
|
||||||
if ($profile) {
|
$cnt = 0;
|
||||||
|
|
||||||
|
if (!empty($profile)) {
|
||||||
$pml = new ProfileMiniList($profile, $this);
|
$pml = new ProfileMiniList($profile, $this);
|
||||||
$cnt = $pml->show();
|
$cnt = $pml->show();
|
||||||
if ($cnt == 0) {
|
if ($cnt == 0) {
|
||||||
@ -137,7 +139,9 @@ class ProfileAction extends OwnerDesignAction
|
|||||||
|
|
||||||
$this->element('h2', null, _('Subscribers'));
|
$this->element('h2', null, _('Subscribers'));
|
||||||
|
|
||||||
if ($profile) {
|
$cnt = 0;
|
||||||
|
|
||||||
|
if (!empty($profile)) {
|
||||||
$pml = new ProfileMiniList($profile, $this);
|
$pml = new ProfileMiniList($profile, $this);
|
||||||
$cnt = $pml->show();
|
$cnt = $pml->show();
|
||||||
if ($cnt == 0) {
|
if ($cnt == 0) {
|
||||||
|
@ -47,6 +47,7 @@ define('PROFILES_PER_MINILIST', 27);
|
|||||||
|
|
||||||
class ProfileMiniList extends ProfileList
|
class ProfileMiniList extends ProfileList
|
||||||
{
|
{
|
||||||
|
|
||||||
function startList()
|
function startList()
|
||||||
{
|
{
|
||||||
$this->out->elementStart('ul', 'entities users xoxo');
|
$this->out->elementStart('ul', 'entities users xoxo');
|
||||||
@ -56,6 +57,23 @@ class ProfileMiniList extends ProfileList
|
|||||||
{
|
{
|
||||||
return new ProfileMiniListItem($profile, $this->action);
|
return new ProfileMiniListItem($profile, $this->action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showProfiles()
|
||||||
|
{
|
||||||
|
$cnt = 0;
|
||||||
|
|
||||||
|
while ($this->profile->fetch()) {
|
||||||
|
$cnt++;
|
||||||
|
if ($cnt > PROFILES_PER_MINILIST) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$pli = $this->newListItem($this->profile);
|
||||||
|
$pli->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $cnt;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ProfileMiniListItem extends ProfileListItem
|
class ProfileMiniListItem extends ProfileListItem
|
||||||
|
@ -31,8 +31,10 @@ class QueueHandler extends Daemon
|
|||||||
{
|
{
|
||||||
var $_id = 'generic';
|
var $_id = 'generic';
|
||||||
|
|
||||||
function QueueHandler($id=null)
|
function __construct($id=null, $daemonize=true)
|
||||||
{
|
{
|
||||||
|
parent::__construct($daemonize);
|
||||||
|
|
||||||
if ($id) {
|
if ($id) {
|
||||||
$this->set_id($id);
|
$this->set_id($id);
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ class SubGroupNav extends Widget
|
|||||||
$this->user->nickname),
|
$this->user->nickname),
|
||||||
$action == 'usergroups',
|
$action == 'usergroups',
|
||||||
'nav_usergroups');
|
'nav_usergroups');
|
||||||
if (!is_null($cur) && $this->user->id === $cur->id) {
|
if (common_config('invite', 'enabled') && !is_null($cur) && $this->user->id === $cur->id) {
|
||||||
$this->out->menuItem(common_local_url('invite'),
|
$this->out->menuItem(common_local_url('invite'),
|
||||||
_('Invite'),
|
_('Invite'),
|
||||||
sprintf(_('Invite friends and colleagues to join you on %s'),
|
sprintf(_('Invite friends and colleagues to join you on %s'),
|
||||||
|
63
lib/util.php
63
lib/util.php
@ -114,7 +114,7 @@ function common_check_user($nickname, $password)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$user = User::staticGet('nickname', $nickname);
|
$user = User::staticGet('nickname', $nickname);
|
||||||
if (is_null($user)) {
|
if (is_null($user) || $user === false) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (0 == strcmp(common_munge_password($password, $user->id),
|
if (0 == strcmp(common_munge_password($password, $user->id),
|
||||||
@ -145,7 +145,6 @@ function common_ensure_session()
|
|||||||
}
|
}
|
||||||
if (!common_have_session()) {
|
if (!common_have_session()) {
|
||||||
if (common_config('sessions', 'handle')) {
|
if (common_config('sessions', 'handle')) {
|
||||||
common_log(LOG_INFO, "Using our own session handler");
|
|
||||||
Session::setSaveHandler();
|
Session::setSaveHandler();
|
||||||
}
|
}
|
||||||
@session_start();
|
@session_start();
|
||||||
@ -500,17 +499,19 @@ function common_linkify($url) {
|
|||||||
// It comes in special'd, so we unspecial it before passing to the stringifying
|
// It comes in special'd, so we unspecial it before passing to the stringifying
|
||||||
// functions
|
// functions
|
||||||
$url = htmlspecialchars_decode($url);
|
$url = htmlspecialchars_decode($url);
|
||||||
$display = File_redirection::_canonUrl($url);
|
|
||||||
|
$canon = File_redirection::_canonUrl($url);
|
||||||
|
|
||||||
$longurl_data = File_redirection::where($url);
|
$longurl_data = File_redirection::where($url);
|
||||||
if (is_array($longurl_data)) {
|
if (is_array($longurl_data)) {
|
||||||
$longurl = $longurl_data['url'];
|
$longurl = $longurl_data['url'];
|
||||||
} elseif (is_string($longurl_data)) {
|
} elseif (is_string($longurl_data)) {
|
||||||
$longurl = $longurl_data;
|
$longurl = $longurl_data;
|
||||||
} else {
|
} else {
|
||||||
die('impossible to linkify');
|
throw new ServerException("Can't linkify url '$url'");
|
||||||
}
|
}
|
||||||
|
|
||||||
$attrs = array('href' => $longurl, 'rel' => 'external');
|
$attrs = array('href' => $canon, 'rel' => 'external');
|
||||||
|
|
||||||
$is_attachment = false;
|
$is_attachment = false;
|
||||||
$attachment_id = null;
|
$attachment_id = null;
|
||||||
@ -528,13 +529,13 @@ function common_linkify($url) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if this URL is an attachment, then we set class='attachment' and id='attahcment-ID'
|
// if this URL is an attachment, then we set class='attachment' and id='attahcment-ID'
|
||||||
// where ID is the id of the attachment for the given URL.
|
// where ID is the id of the attachment for the given URL.
|
||||||
//
|
//
|
||||||
// we need a better test telling what can be shown as an attachment
|
// we need a better test telling what can be shown as an attachment
|
||||||
// we're currently picking up oembeds only.
|
// we're currently picking up oembeds only.
|
||||||
// I think the best option is another file_view table in the db
|
// I think the best option is another file_view table in the db
|
||||||
// and associated dbobject.
|
// and associated dbobject.
|
||||||
|
|
||||||
$query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'";
|
$query = "select file_oembed.file_id as file_id from file join file_oembed on file.id = file_oembed.file_id where file.url='$longurl'";
|
||||||
$file = new File;
|
$file = new File;
|
||||||
@ -564,7 +565,7 @@ function common_linkify($url) {
|
|||||||
$attrs['id'] = "attachment-{$attachment_id}";
|
$attrs['id'] = "attachment-{$attachment_id}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return XMLStringer::estring('a', $attrs, $display);
|
return XMLStringer::estring('a', $attrs, $url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function common_shorten_links($text)
|
function common_shorten_links($text)
|
||||||
@ -982,15 +983,20 @@ function common_ensure_syslog()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function common_log_line($priority, $msg)
|
||||||
|
{
|
||||||
|
static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR',
|
||||||
|
'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG');
|
||||||
|
return date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
function common_log($priority, $msg, $filename=null)
|
function common_log($priority, $msg, $filename=null)
|
||||||
{
|
{
|
||||||
$logfile = common_config('site', 'logfile');
|
$logfile = common_config('site', 'logfile');
|
||||||
if ($logfile) {
|
if ($logfile) {
|
||||||
$log = fopen($logfile, "a");
|
$log = fopen($logfile, "a");
|
||||||
if ($log) {
|
if ($log) {
|
||||||
static $syslog_priorities = array('LOG_EMERG', 'LOG_ALERT', 'LOG_CRIT', 'LOG_ERR',
|
$output = common_log_line($priority, $msg);
|
||||||
'LOG_WARNING', 'LOG_NOTICE', 'LOG_INFO', 'LOG_DEBUG');
|
|
||||||
$output = date('Y-m-d H:i:s') . ' ' . $syslog_priorities[$priority] . ': ' . $msg . "\n";
|
|
||||||
fwrite($log, $output);
|
fwrite($log, $output);
|
||||||
fclose($log);
|
fclose($log);
|
||||||
}
|
}
|
||||||
@ -1221,18 +1227,39 @@ function common_canonical_sms($sms)
|
|||||||
function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
|
function common_error_handler($errno, $errstr, $errfile, $errline, $errcontext)
|
||||||
{
|
{
|
||||||
switch ($errno) {
|
switch ($errno) {
|
||||||
|
|
||||||
|
case E_ERROR:
|
||||||
|
case E_COMPILE_ERROR:
|
||||||
|
case E_CORE_ERROR:
|
||||||
case E_USER_ERROR:
|
case E_USER_ERROR:
|
||||||
common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline)");
|
case E_PARSE:
|
||||||
exit(1);
|
case E_RECOVERABLE_ERROR:
|
||||||
|
common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline) [ABORT]");
|
||||||
|
die();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case E_WARNING:
|
||||||
|
case E_COMPILE_WARNING:
|
||||||
|
case E_CORE_WARNING:
|
||||||
case E_USER_WARNING:
|
case E_USER_WARNING:
|
||||||
common_log(LOG_WARNING, "[$errno] $errstr ($errfile:$errline)");
|
common_log(LOG_WARNING, "[$errno] $errstr ($errfile:$errline)");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case E_NOTICE:
|
||||||
case E_USER_NOTICE:
|
case E_USER_NOTICE:
|
||||||
common_log(LOG_NOTICE, "[$errno] $errstr ($errfile:$errline)");
|
common_log(LOG_NOTICE, "[$errno] $errstr ($errfile:$errline)");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case E_STRICT:
|
||||||
|
case E_DEPRECATED:
|
||||||
|
case E_USER_DEPRECATED:
|
||||||
|
// XXX: config variable to log this stuff, too
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
common_log(LOG_ERR, "[$errno] $errstr ($errfile:$errline) [UNKNOWN LEVEL, die()'ing]");
|
||||||
|
die();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: show error page if we're on the Web
|
// FIXME: show error page if we're on the Web
|
||||||
|
@ -66,7 +66,7 @@ class FBConnectauthAction extends Action
|
|||||||
// User is already logged in. Does she already have a linked Facebook acct?
|
// User is already logged in. Does she already have a linked Facebook acct?
|
||||||
$flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_CONNECT_SERVICE);
|
$flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_CONNECT_SERVICE);
|
||||||
|
|
||||||
if ($flink) {
|
if (!empty($flink)) {
|
||||||
|
|
||||||
// User already has a linked Facebook account and shouldn't be here
|
// User already has a linked Facebook account and shouldn't be here
|
||||||
common_debug('There is already a local user (' . $flink->user_id .
|
common_debug('There is already a local user (' . $flink->user_id .
|
||||||
@ -337,7 +337,7 @@ class FBConnectauthAction extends Action
|
|||||||
if ($flink) {
|
if ($flink) {
|
||||||
$user = $flink->getUser();
|
$user = $flink->getUser();
|
||||||
|
|
||||||
if ($user) {
|
if (!empty($user)) {
|
||||||
|
|
||||||
common_debug("Logged in Facebook user $flink->foreign_id as user $user->id ($user->nickname)");
|
common_debug("Logged in Facebook user $flink->foreign_id as user $user->id ($user->nickname)");
|
||||||
|
|
||||||
|
@ -10,22 +10,21 @@
|
|||||||
#site_nav_global_primary #nav_fb {
|
#site_nav_global_primary #nav_fb {
|
||||||
position:relative;
|
position:relative;
|
||||||
margin-left:18px;
|
margin-left:18px;
|
||||||
margin-right:-7px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav_fb .fb_profile_pic_rendered img {
|
#nav_fb #fbc_profile-pic {
|
||||||
position:relative;
|
position:absolute;
|
||||||
top:3px;
|
top:-3px;
|
||||||
left:0;
|
left:-18px;
|
||||||
display:inline;
|
display:inline;
|
||||||
border:1px solid #3B5998;
|
border:1px solid #3B5998;
|
||||||
padding:1px;
|
padding:1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav_fb img {
|
#nav_fb #fb_favicon {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
top:-13px;
|
top:-13px;
|
||||||
left:-11px;
|
left:-25px;
|
||||||
display:inline;
|
display:inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,100 +69,158 @@ class FBConnectPlugin extends Plugin
|
|||||||
// Add in xmlns:fb
|
// Add in xmlns:fb
|
||||||
function onStartShowHTML($action)
|
function onStartShowHTML($action)
|
||||||
{
|
{
|
||||||
// XXX: Horrible hack to make Safari, FF2, and Chrome work with
|
|
||||||
// Facebook Connect. These browser cannot use Facebook's
|
|
||||||
// DOM parsing routines unless the mime type of the page is
|
|
||||||
// text/html even though Facebook Connect uses XHTML. This is
|
|
||||||
// A bug in Facebook Connect, and this is a temporary solution
|
|
||||||
// until they fix their JavaScript libs.
|
|
||||||
header('Content-Type: text/html');
|
|
||||||
|
|
||||||
$action->extraHeaders();
|
if ($this->reqFbScripts($action)) {
|
||||||
|
|
||||||
$action->startXML('html',
|
// XXX: Horrible hack to make Safari, FF2, and Chrome work with
|
||||||
'-//W3C//DTD XHTML 1.0 Strict//EN',
|
// Facebook Connect. These browser cannot use Facebook's
|
||||||
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd');
|
// DOM parsing routines unless the mime type of the page is
|
||||||
|
// text/html even though Facebook Connect uses XHTML. This is
|
||||||
|
// A bug in Facebook Connect, and this is a temporary solution
|
||||||
|
// until they fix their JavaScript libs.
|
||||||
|
header('Content-Type: text/html');
|
||||||
|
|
||||||
$language = $action->getLanguage();
|
$action->extraHeaders();
|
||||||
|
|
||||||
$action->elementStart('html',
|
$action->startXML('html',
|
||||||
array('xmlns' => 'http://www.w3.org/1999/xhtml',
|
'-//W3C//DTD XHTML 1.0 Strict//EN',
|
||||||
'xmlns:fb' => 'http://www.facebook.com/2008/fbml',
|
'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd');
|
||||||
'xml:lang' => $language,
|
|
||||||
'lang' => $language));
|
|
||||||
|
|
||||||
return false;
|
$language = $action->getLanguage();
|
||||||
|
|
||||||
|
$action->elementStart('html',
|
||||||
|
array('xmlns' => 'http://www.w3.org/1999/xhtml',
|
||||||
|
'xmlns:fb' => 'http://www.facebook.com/2008/fbml',
|
||||||
|
'xml:lang' => $language,
|
||||||
|
'lang' => $language));
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this script needs to appear in the <body>
|
// Note: this script needs to appear in the <body>
|
||||||
|
|
||||||
function onStartShowHeader($action)
|
function onStartShowHeader($action)
|
||||||
{
|
{
|
||||||
$apikey = common_config('facebook', 'apikey');
|
if ($this->reqFbScripts($action)) {
|
||||||
$plugin_path = common_path('plugins/FBConnect');
|
|
||||||
|
|
||||||
$login_url = common_local_url('FBConnectAuth');
|
$apikey = common_config('facebook', 'apikey');
|
||||||
$logout_url = common_local_url('logout');
|
$plugin_path = common_path('plugins/FBConnect');
|
||||||
|
|
||||||
// XXX: Facebook says we don't need this FB_RequireFeatures(),
|
$login_url = common_local_url('FBConnectAuth');
|
||||||
// but we actually do, for IE and Safari. Gar.
|
$logout_url = common_local_url('logout');
|
||||||
|
|
||||||
$html = sprintf('<script type="text/javascript">
|
// XXX: Facebook says we don't need this FB_RequireFeatures(),
|
||||||
window.onload = function () {
|
// but we actually do, for IE and Safari. Gar.
|
||||||
FB_RequireFeatures(
|
|
||||||
["XFBML"],
|
|
||||||
function() {
|
|
||||||
FB.Facebook.init("%s", "../xd_receiver.html");
|
|
||||||
}
|
|
||||||
); }
|
|
||||||
|
|
||||||
function goto_login() {
|
$html = sprintf('<script type="text/javascript">
|
||||||
window.location = "%s";
|
window.onload = function () {
|
||||||
}
|
FB_RequireFeatures(
|
||||||
|
["XFBML"],
|
||||||
|
function() {
|
||||||
|
FB.Facebook.init("%s", "../xd_receiver.html");
|
||||||
|
}
|
||||||
|
); }
|
||||||
|
|
||||||
function goto_logout() {
|
function goto_login() {
|
||||||
window.location = "%s";
|
window.location = "%s";
|
||||||
}
|
}
|
||||||
</script>', $apikey,
|
|
||||||
$login_url, $logout_url);
|
function goto_logout() {
|
||||||
|
window.location = "%s";
|
||||||
|
}
|
||||||
|
</script>', $apikey,
|
||||||
|
$login_url, $logout_url);
|
||||||
|
|
||||||
|
$action->raw($html);
|
||||||
|
}
|
||||||
|
|
||||||
$action->raw($html);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this script needs to appear as close as possible to </body>
|
// Note: this script needs to appear as close as possible to </body>
|
||||||
|
|
||||||
function onEndShowFooter($action)
|
function onEndShowFooter($action)
|
||||||
{
|
{
|
||||||
|
if ($this->reqFbScripts($action)) {
|
||||||
|
|
||||||
$action->element('script',
|
$action->element('script',
|
||||||
array('type' => 'text/javascript',
|
array('type' => 'text/javascript',
|
||||||
'src' => 'http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php'),
|
'src' => 'http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php'),
|
||||||
'');
|
'');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEndShowLaconicaStyles($action)
|
function onEndShowLaconicaStyles($action)
|
||||||
{
|
{
|
||||||
$action->element('link', array('rel' => 'stylesheet',
|
|
||||||
'type' => 'text/css',
|
if ($this->reqFbScripts($action)) {
|
||||||
'href' => common_path('plugins/FBConnect/FBConnectPlugin.css')));
|
|
||||||
|
$action->element('link', array('rel' => 'stylesheet',
|
||||||
|
'type' => 'text/css',
|
||||||
|
'href' => common_path('plugins/FBConnect/FBConnectPlugin.css')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStartPrimaryNav($action)
|
/**
|
||||||
|
* Does the Action we're plugged into require the FB Scripts? We only
|
||||||
|
* want to output FB namespace, scripts, CSS, etc. on the pages that
|
||||||
|
* really need them.
|
||||||
|
*
|
||||||
|
* @param Action the action in question
|
||||||
|
*
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
|
||||||
|
function reqFbScripts($action) {
|
||||||
|
|
||||||
|
// If you're logged in w/FB Connect, you always need the FB stuff
|
||||||
|
|
||||||
|
$fbuid = $this->loggedIn();
|
||||||
|
|
||||||
|
if (!empty($fbuid)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List of actions that require FB stuff
|
||||||
|
|
||||||
|
$needy = array('FBConnectLoginAction',
|
||||||
|
'FBConnectauthAction',
|
||||||
|
'FBConnectSettingsAction');
|
||||||
|
|
||||||
|
if (in_array(get_class($action), $needy)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the user currently logged in with FB Connect?
|
||||||
|
*
|
||||||
|
* @return mixed $fbuid the Facebook ID of the logged in user, or null
|
||||||
|
*/
|
||||||
|
|
||||||
|
function loggedIn()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
if ($user) {
|
if (!empty($user)) {
|
||||||
|
|
||||||
$flink = Foreign_link::getByUserId($user->id,
|
$flink = Foreign_link::getByUserId($user->id,
|
||||||
FACEBOOK_CONNECT_SERVICE);
|
FACEBOOK_CONNECT_SERVICE);
|
||||||
$fbuid = 0;
|
$fbuid = 0;
|
||||||
|
|
||||||
if ($flink) {
|
if (!empty($flink)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$facebook = getFacebook();
|
$facebook = getFacebook();
|
||||||
$fbuid = getFacebook()->get_loggedin_user();
|
$fbuid = getFacebook()->get_loggedin_user();
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
common_log(LOG_WARNING,
|
common_log(LOG_WARNING,
|
||||||
@ -170,24 +228,48 @@ class FBConnectPlugin extends Plugin
|
|||||||
$e->getMessage());
|
$e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display Facebook Logged in indicator w/Facebook favicon
|
|
||||||
|
|
||||||
if ($fbuid > 0) {
|
if ($fbuid > 0) {
|
||||||
|
return $fbuid;
|
||||||
$action->elementStart('li', array('id' => 'nav_fb'));
|
|
||||||
$action->elementStart('fb:profile-pic', array('uid' => $flink->foreign_id,
|
|
||||||
'linked' => 'false',
|
|
||||||
'width' => 16,
|
|
||||||
'height' => 16));
|
|
||||||
$action->elementEnd('fb:profile-pic');
|
|
||||||
|
|
||||||
$iconurl = common_path('/plugins/FBConnect/fbfavicon.ico');
|
|
||||||
$action->element('img', array('src' => $iconurl));
|
|
||||||
|
|
||||||
$action->elementEnd('li');
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onStartPrimaryNav($action)
|
||||||
|
{
|
||||||
|
|
||||||
|
$user = common_current_user();
|
||||||
|
|
||||||
|
if (!empty($user)) {
|
||||||
|
|
||||||
|
$fbuid = $this->loggedIn();
|
||||||
|
|
||||||
|
if (!empty($fbuid)) {
|
||||||
|
|
||||||
|
/* Default FB silhouette pic for FB users who haven't
|
||||||
|
uploaded a profile pic yet. */
|
||||||
|
|
||||||
|
$silhouetteUrl =
|
||||||
|
'http://static.ak.fbcdn.net/pics/q_silhouette.gif';
|
||||||
|
|
||||||
|
$url = $this->getProfilePicURL($fbuid);
|
||||||
|
|
||||||
|
$action->elementStart('li', array('id' => 'nav_fb'));
|
||||||
|
|
||||||
|
$action->element('img', array('id' => 'fbc_profile-pic',
|
||||||
|
'src' => (!empty($url)) ? $url : $silhouetteUrl,
|
||||||
|
'alt' => 'Facebook Connect User',
|
||||||
|
'width' => '16'), '');
|
||||||
|
|
||||||
|
$iconurl = common_path('plugins/FBConnect/fbfavicon.ico');
|
||||||
|
$action->element('img', array('id' => 'fb_favicon',
|
||||||
|
'src' => $iconurl));
|
||||||
|
|
||||||
|
$action->elementEnd('li');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$action->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
|
$action->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
|
||||||
_('Home'), _('Personal profile and friends timeline'), false, 'nav_home');
|
_('Home'), _('Personal profile and friends timeline'), false, 'nav_home');
|
||||||
@ -200,14 +282,16 @@ class FBConnectPlugin extends Plugin
|
|||||||
$action->menuItem(common_local_url('smssettings'),
|
$action->menuItem(common_local_url('smssettings'),
|
||||||
_('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect');
|
_('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect');
|
||||||
}
|
}
|
||||||
$action->menuItem(common_local_url('invite'),
|
if (common_config('invite', 'enabled')) {
|
||||||
_('Invite'),
|
$action->menuItem(common_local_url('invite'),
|
||||||
sprintf(_('Invite friends and colleagues to join you on %s'),
|
_('Invite'),
|
||||||
common_config('site', 'name')),
|
sprintf(_('Invite friends and colleagues to join you on %s'),
|
||||||
false, 'nav_invitecontact');
|
common_config('site', 'name')),
|
||||||
|
false, 'nav_invitecontact');
|
||||||
|
}
|
||||||
|
|
||||||
// Need to override the Logout link to make it do FB stuff
|
// Need to override the Logout link to make it do FB stuff
|
||||||
if ($flink && $fbuid > 0) {
|
if (!empty($fbuid)) {
|
||||||
|
|
||||||
$logout_url = common_local_url('logout');
|
$logout_url = common_local_url('logout');
|
||||||
$title = _('Logout from the site');
|
$title = _('Logout from the site');
|
||||||
@ -245,7 +329,7 @@ class FBConnectPlugin extends Plugin
|
|||||||
|
|
||||||
function onStartShowLocalNavBlock($action)
|
function onStartShowLocalNavBlock($action)
|
||||||
{
|
{
|
||||||
$action_name = get_class($action);
|
$action_name = get_class($action);
|
||||||
|
|
||||||
$login_actions = array('LoginAction', 'RegisterAction',
|
$login_actions = array('LoginAction', 'RegisterAction',
|
||||||
'OpenidloginAction', 'FBConnectLoginAction');
|
'OpenidloginAction', 'FBConnectLoginAction');
|
||||||
@ -256,7 +340,7 @@ class FBConnectPlugin extends Plugin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$connect_actions = array('SmssettingsAction',
|
$connect_actions = array('SmssettingsAction', 'ImsettingsAction',
|
||||||
'TwittersettingsAction', 'FBConnectSettingsAction');
|
'TwittersettingsAction', 'FBConnectSettingsAction');
|
||||||
|
|
||||||
if (in_array($action_name, $connect_actions)) {
|
if (in_array($action_name, $connect_actions)) {
|
||||||
@ -270,23 +354,13 @@ class FBConnectPlugin extends Plugin
|
|||||||
|
|
||||||
function onStartLogout($action)
|
function onStartLogout($action)
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$flink = Foreign_link::getByUserId($user->id, FACEBOOK_CONNECT_SERVICE);
|
|
||||||
|
|
||||||
$action->logout();
|
$action->logout();
|
||||||
|
$fbuid = $this->loggedIn();
|
||||||
|
|
||||||
if ($flink) {
|
if (!empty($fbuid)) {
|
||||||
|
|
||||||
$facebook = getFacebook();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$fbuid = $facebook->get_loggedin_user();
|
$facebook = getFacebook();
|
||||||
|
$facebook->expire_session();
|
||||||
if ($fbuid > 0) {
|
|
||||||
$facebook->logout(common_local_url('public'));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
common_log(LOG_WARNING, 'Could\'t logout of Facebook: ' .
|
common_log(LOG_WARNING, 'Could\'t logout of Facebook: ' .
|
||||||
$e->getMessage());
|
$e->getMessage());
|
||||||
@ -296,4 +370,28 @@ class FBConnectPlugin extends Plugin
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getProfilePicURL($fbuid)
|
||||||
|
{
|
||||||
|
|
||||||
|
$facebook = getFacebook();
|
||||||
|
$url = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
$fqry = 'SELECT pic_square FROM user WHERE uid = %s';
|
||||||
|
|
||||||
|
$result = $facebook->api_client->fql_query(sprintf($fqry, $fbuid));
|
||||||
|
|
||||||
|
if (!empty($result)) {
|
||||||
|
$url = $result[0]['pic_square'];
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
common_log(LOG_WARNING, "Facebook client failure requesting profile pic!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,14 +63,21 @@ if (isset($longoptions)) {
|
|||||||
|
|
||||||
$parser = new Console_Getopt();
|
$parser = new Console_Getopt();
|
||||||
|
|
||||||
list($options, $args) = $parser->getopt($argv, $shortoptions, $longoptions);
|
$result = $parser->getopt($argv, $shortoptions, $longoptions);
|
||||||
|
|
||||||
|
if (PEAR::isError($result)) {
|
||||||
|
print $result->getMessage()."\n";
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
list($options, $args) = $result;
|
||||||
|
}
|
||||||
|
|
||||||
function show_help()
|
function show_help()
|
||||||
{
|
{
|
||||||
global $helptext;
|
global $helptext;
|
||||||
|
|
||||||
$_default_help_text = <<<END_OF_DEFAULT
|
$_default_help_text = <<<END_OF_DEFAULT
|
||||||
General options:
|
General options:
|
||||||
|
|
||||||
-q --quiet Quiet (little output)
|
-q --quiet Quiet (little output)
|
||||||
-v --verbose Verbose (lots of output)
|
-v --verbose Verbose (lots of output)
|
||||||
@ -80,11 +87,11 @@ General options:
|
|||||||
-h --help Show this message and quit.
|
-h --help Show this message and quit.
|
||||||
|
|
||||||
END_OF_DEFAULT;
|
END_OF_DEFAULT;
|
||||||
if (isset($helptext)) {
|
if (isset($helptext)) {
|
||||||
print $helptext;
|
print $helptext;
|
||||||
}
|
}
|
||||||
print $_default_help_text;
|
print $_default_help_text;
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($options as $option) {
|
foreach ($options as $option) {
|
||||||
@ -115,24 +122,53 @@ require_once INSTALLDIR . '/lib/common.php';
|
|||||||
|
|
||||||
set_error_handler('common_error_handler');
|
set_error_handler('common_error_handler');
|
||||||
|
|
||||||
function have_option($str)
|
function _make_matches($opt, $alt)
|
||||||
{
|
{
|
||||||
global $options;
|
$matches = array();
|
||||||
foreach ($options as $option) {
|
|
||||||
if ($option[0] == $str) {
|
if (strlen($opt) > 1 && 0 != strncmp($opt, '--', 2)) {
|
||||||
return true;
|
$matches[] = '--'.$opt;
|
||||||
}
|
} else {
|
||||||
}
|
$matches[] = $opt;
|
||||||
return false;
|
}
|
||||||
|
|
||||||
|
if (!empty($alt)) {
|
||||||
|
if (strlen($alt) > 1 && 0 != strncmp($alt, '--', 2)) {
|
||||||
|
$matches[] = '--'.$alt;
|
||||||
|
} else {
|
||||||
|
$matches[] = $alt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_option_value($str)
|
function have_option($opt, $alt=null)
|
||||||
{
|
{
|
||||||
global $options;
|
global $options;
|
||||||
foreach ($options as $option) {
|
|
||||||
if ($option[0] == $str) {
|
$matches = _make_matches($opt, $alt);
|
||||||
return $option[1];
|
|
||||||
}
|
foreach ($options as $option) {
|
||||||
}
|
if (in_array($option[0], $matches)) {
|
||||||
return null;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_option_value($opt, $alt=null)
|
||||||
|
{
|
||||||
|
global $options;
|
||||||
|
|
||||||
|
$matches = _make_matches($opt, $alt);
|
||||||
|
|
||||||
|
foreach ($options as $option) {
|
||||||
|
if (in_array($option[0], $matches)) {
|
||||||
|
return $option[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
@ -24,22 +24,17 @@ require_once INSTALLDIR.'/scripts/commandline.inc';
|
|||||||
|
|
||||||
common_log(LOG_INFO, 'Fixing up conversations.');
|
common_log(LOG_INFO, 'Fixing up conversations.');
|
||||||
|
|
||||||
$notice = new Notice();
|
$nid = new Notice();
|
||||||
$notice->whereAdd('conversation is null');
|
$nid->query('select id, reply_to from notice where conversation is null');
|
||||||
$notice->orderBy('id');
|
|
||||||
|
|
||||||
$cnt = $notice->find();
|
while ($nid->fetch()) {
|
||||||
|
|
||||||
print "Found $cnt notices.\n";
|
$cid = null;
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
$notice = new Notice();
|
||||||
|
|
||||||
print "$notice->id =>";
|
if (empty($nid->reply_to)) {
|
||||||
|
$cid = $nid->id;
|
||||||
$orig = clone($notice);
|
|
||||||
|
|
||||||
if (empty($notice->reply_to)) {
|
|
||||||
$notice->conversation = $notice->id;
|
|
||||||
} else {
|
} else {
|
||||||
$reply = Notice::staticGet('id', $notice->reply_to);
|
$reply = Notice::staticGet('id', $notice->reply_to);
|
||||||
|
|
||||||
@ -52,6 +47,9 @@ while ($notice->fetch()) {
|
|||||||
} else {
|
} else {
|
||||||
$notice->conversation = $reply->conversation;
|
$notice->conversation = $reply->conversation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unset($reply);
|
||||||
|
$reply = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
print "$notice->conversation";
|
print "$notice->conversation";
|
||||||
@ -63,5 +61,10 @@ while ($notice->fetch()) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$notice = null;
|
||||||
|
$orig = null;
|
||||||
|
unset($notice);
|
||||||
|
unset($orig);
|
||||||
|
|
||||||
print ".\n";
|
print ".\n";
|
||||||
}
|
}
|
||||||
|
71
scripts/showcache.php
Normal file
71
scripts/showcache.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Laconica - a distributed open-source microblogging tool
|
||||||
|
* Copyright (C) 2009, Control Yourself, Inc.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
|
$shortoptions = "t:c:v:k:";
|
||||||
|
|
||||||
|
$helptext = <<<ENDOFHELP
|
||||||
|
USAGE: showcache.php <args>
|
||||||
|
shows the cached object based on the args
|
||||||
|
|
||||||
|
-t table Table to look up
|
||||||
|
-c column Column to look up, default "id"
|
||||||
|
-v value Value to look up
|
||||||
|
-k key Key to look up; other args are ignored
|
||||||
|
|
||||||
|
ENDOFHELP;
|
||||||
|
|
||||||
|
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||||
|
|
||||||
|
$karg = get_option_value('k');
|
||||||
|
|
||||||
|
if (!empty($karg)) {
|
||||||
|
$k = common_cache_key($karg);
|
||||||
|
} else {
|
||||||
|
$table = get_option_value('t');
|
||||||
|
if (empty($table)) {
|
||||||
|
die("No table or key specified\n");
|
||||||
|
}
|
||||||
|
$column = get_option_value('c');
|
||||||
|
if (empty($column)) {
|
||||||
|
$column = 'id';
|
||||||
|
}
|
||||||
|
$value = get_option_value('v');
|
||||||
|
|
||||||
|
$k = Memcached_DataObject::cacheKey($table, $column, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
print "Checking key '$k'...\n";
|
||||||
|
|
||||||
|
$c = common_memcache();
|
||||||
|
|
||||||
|
if (empty($c)) {
|
||||||
|
die("Can't initialize cache object!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj = $c->get($k);
|
||||||
|
|
||||||
|
if (empty($obj)) {
|
||||||
|
print "Empty.\n";
|
||||||
|
} else {
|
||||||
|
var_dump($obj);
|
||||||
|
print "\n";
|
||||||
|
}
|
@ -25,9 +25,14 @@ define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
|||||||
define('MAXCHILDREN', 2);
|
define('MAXCHILDREN', 2);
|
||||||
define('POLL_INTERVAL', 60); // in seconds
|
define('POLL_INTERVAL', 60); // in seconds
|
||||||
|
|
||||||
|
$shortoptions = 'i::';
|
||||||
|
$longoptions = array('id::');
|
||||||
|
|
||||||
$helptext = <<<END_OF_TRIM_HELP
|
$helptext = <<<END_OF_TRIM_HELP
|
||||||
Batch script for retrieving Twitter messages from foreign service.
|
Batch script for retrieving Twitter messages from foreign service.
|
||||||
|
|
||||||
|
-i --id Identity (default 'generic')
|
||||||
|
|
||||||
END_OF_TRIM_HELP;
|
END_OF_TRIM_HELP;
|
||||||
|
|
||||||
require_once INSTALLDIR.'/scripts/commandline.inc';
|
require_once INSTALLDIR.'/scripts/commandline.inc';
|
||||||
@ -64,7 +69,7 @@ class TwitterStatusFetcher extends Daemon
|
|||||||
|
|
||||||
function name()
|
function name()
|
||||||
{
|
{
|
||||||
return ('twitterstatusfetcher.generic');
|
return ('twitterstatusfetcher.'.$this->_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -625,6 +630,16 @@ class TwitterStatusFetcher extends Daemon
|
|||||||
|
|
||||||
declare(ticks = 1);
|
declare(ticks = 1);
|
||||||
|
|
||||||
$fetcher = new TwitterStatusFetcher();
|
if (have_option('i')) {
|
||||||
|
$id = get_option_value('i');
|
||||||
|
} else if (have_option('--id')) {
|
||||||
|
$id = get_option_value('--id');
|
||||||
|
} else if (count($args) > 0) {
|
||||||
|
$id = $args[0];
|
||||||
|
} else {
|
||||||
|
$id = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fetcher = new TwitterStatusFetcher($id);
|
||||||
$fetcher->runOnce();
|
$fetcher->runOnce();
|
||||||
|
|
||||||
|
@ -20,13 +20,14 @@
|
|||||||
|
|
||||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||||
|
|
||||||
$shortoptions = 'i::';
|
$shortoptions = 'fi::';
|
||||||
$longoptions = array('id::');
|
$longoptions = array('id::', 'foreground');
|
||||||
|
|
||||||
$helptext = <<<END_OF_XMPP_HELP
|
$helptext = <<<END_OF_XMPP_HELP
|
||||||
Daemon script for receiving new notices from Jabber users.
|
Daemon script for receiving new notices from Jabber users.
|
||||||
|
|
||||||
-i --id Identity (default none)
|
-i --id Identity (default none)
|
||||||
|
-f --foreground Stay in the foreground (default background)
|
||||||
|
|
||||||
END_OF_XMPP_HELP;
|
END_OF_XMPP_HELP;
|
||||||
|
|
||||||
@ -42,8 +43,10 @@ require_once INSTALLDIR . '/lib/daemon.php';
|
|||||||
|
|
||||||
class XMPPDaemon extends Daemon
|
class XMPPDaemon extends Daemon
|
||||||
{
|
{
|
||||||
function XMPPDaemon($resource=null)
|
function __construct($resource=null, $daemonize=true)
|
||||||
{
|
{
|
||||||
|
parent::__construct($daemonize);
|
||||||
|
|
||||||
static $attrs = array('server', 'port', 'user', 'password', 'host');
|
static $attrs = array('server', 'port', 'user', 'password', 'host');
|
||||||
|
|
||||||
foreach ($attrs as $attr)
|
foreach ($attrs as $attr)
|
||||||
@ -62,7 +65,6 @@ class XMPPDaemon extends Daemon
|
|||||||
|
|
||||||
function connect()
|
function connect()
|
||||||
{
|
{
|
||||||
|
|
||||||
$connect_to = ($this->host) ? $this->host : $this->server;
|
$connect_to = ($this->host) ? $this->host : $this->server;
|
||||||
|
|
||||||
$this->log(LOG_INFO, "Connecting to $connect_to on port $this->port");
|
$this->log(LOG_INFO, "Connecting to $connect_to on port $this->port");
|
||||||
@ -73,10 +75,17 @@ class XMPPDaemon extends Daemon
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->log(LOG_INFO, "Connected");
|
||||||
|
|
||||||
$this->conn->setReconnectTimeout(600);
|
$this->conn->setReconnectTimeout(600);
|
||||||
|
|
||||||
|
$this->log(LOG_INFO, "Sending initial presence.");
|
||||||
|
|
||||||
jabber_send_presence("Send me a message to post a notice", 'available',
|
jabber_send_presence("Send me a message to post a notice", 'available',
|
||||||
null, 'available', 100);
|
null, 'available', 100);
|
||||||
|
|
||||||
|
$this->log(LOG_INFO, "Done connecting.");
|
||||||
|
|
||||||
return !$this->conn->isDisconnected();
|
return !$this->conn->isDisconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,17 +98,23 @@ class XMPPDaemon extends Daemon
|
|||||||
{
|
{
|
||||||
if ($this->connect()) {
|
if ($this->connect()) {
|
||||||
|
|
||||||
|
$this->log(LOG_DEBUG, "Initializing stanza handlers.");
|
||||||
|
|
||||||
$this->conn->addEventHandler('message', 'handle_message', $this);
|
$this->conn->addEventHandler('message', 'handle_message', $this);
|
||||||
$this->conn->addEventHandler('presence', 'handle_presence', $this);
|
$this->conn->addEventHandler('presence', 'handle_presence', $this);
|
||||||
$this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
|
$this->conn->addEventHandler('reconnect', 'handle_reconnect', $this);
|
||||||
|
|
||||||
|
$this->log(LOG_DEBUG, "Beginning processing loop.");
|
||||||
|
|
||||||
$this->conn->process();
|
$this->conn->process();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_reconnect(&$pl)
|
function handle_reconnect(&$pl)
|
||||||
{
|
{
|
||||||
|
$this->log(LOG_DEBUG, "Got reconnection callback.");
|
||||||
$this->conn->processUntil('session_start');
|
$this->conn->processUntil('session_start');
|
||||||
|
$this->log(LOG_DEBUG, "Sending reconnection presence.");
|
||||||
$this->conn->presence('Send me a message to post a notice', 'available', null, 'available', 100);
|
$this->conn->presence('Send me a message to post a notice', 'available', null, 'available', 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,21 +126,27 @@ class XMPPDaemon extends Daemon
|
|||||||
|
|
||||||
function handle_message(&$pl)
|
function handle_message(&$pl)
|
||||||
{
|
{
|
||||||
|
$from = jabber_normalize_jid($pl['from']);
|
||||||
|
|
||||||
if ($pl['type'] != 'chat') {
|
if ($pl['type'] != 'chat') {
|
||||||
return;
|
$this->log(LOG_WARNING, "Ignoring message of type ".$pl['type']." from $from.");
|
||||||
}
|
|
||||||
if (mb_strlen($pl['body']) == 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$from = jabber_normalize_jid($pl['from']);
|
if (mb_strlen($pl['body']) == 0) {
|
||||||
|
$this->log(LOG_WARNING, "Ignoring message with empty body from $from.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
# Forwarded from another daemon (probably a broadcaster) for
|
# Forwarded from another daemon (probably a broadcaster) for
|
||||||
# us to handle
|
# us to handle
|
||||||
|
|
||||||
if ($this->is_self($from)) {
|
if ($this->is_self($from)) {
|
||||||
|
$this->log(LOG_INFO, "Got forwarded notice from self ($from).");
|
||||||
$from = $this->get_ofrom($pl);
|
$from = $this->get_ofrom($pl);
|
||||||
|
$this->log(LOG_INFO, "Originally sent by $from.");
|
||||||
if (is_null($from) || $this->is_self($from)) {
|
if (is_null($from) || $this->is_self($from)) {
|
||||||
|
$this->log(LOG_INFO, "Ignoring notice originally sent by $from.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,6 +161,7 @@ class XMPPDaemon extends Daemon
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ($this->handle_command($user, $pl['body'])) {
|
if ($this->handle_command($user, $pl['body'])) {
|
||||||
|
$this->log(LOG_INFO, "Command messag by $from handled.");
|
||||||
return;
|
return;
|
||||||
} else if ($this->is_autoreply($pl['body'])) {
|
} else if ($this->is_autoreply($pl['body'])) {
|
||||||
$this->log(LOG_INFO, 'Ignoring auto reply from ' . $from);
|
$this->log(LOG_INFO, 'Ignoring auto reply from ' . $from);
|
||||||
@ -148,12 +170,20 @@ class XMPPDaemon extends Daemon
|
|||||||
$this->log(LOG_INFO, 'Ignoring OTR from ' . $from);
|
$this->log(LOG_INFO, 'Ignoring OTR from ' . $from);
|
||||||
return;
|
return;
|
||||||
} else if ($this->is_direct($pl['body'])) {
|
} else if ($this->is_direct($pl['body'])) {
|
||||||
|
$this->log(LOG_INFO, 'Got a direct message ' . $from);
|
||||||
|
|
||||||
preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to);
|
preg_match_all('/d[\ ]*([a-z0-9]{1,64})/', $pl['body'], $to);
|
||||||
|
|
||||||
$to = preg_replace('/^d([\ ])*/', '', $to[0][0]);
|
$to = preg_replace('/^d([\ ])*/', '', $to[0][0]);
|
||||||
$body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']);
|
$body = preg_replace('/d[\ ]*('. $to .')[\ ]*/', '', $pl['body']);
|
||||||
|
|
||||||
|
$this->log(LOG_INFO, 'Direct message from '. $user->nickname . ' to ' . $to);
|
||||||
|
|
||||||
$this->add_direct($user, $body, $to, $from);
|
$this->add_direct($user, $body, $to, $from);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
$this->log(LOG_INFO, 'Posting a notice from ' . $user->nickname);
|
||||||
|
|
||||||
$this->add_notice($user, $pl);
|
$this->add_notice($user, $pl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,6 +291,7 @@ class XMPPDaemon extends Daemon
|
|||||||
$notice = Notice::saveNew($user->id, $content_shortened, 'xmpp');
|
$notice = Notice::saveNew($user->id, $content_shortened, 'xmpp');
|
||||||
if (is_string($notice)) {
|
if (is_string($notice)) {
|
||||||
$this->log(LOG_ERR, $notice);
|
$this->log(LOG_ERR, $notice);
|
||||||
|
$this->from_site($user->jabber, $notice);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
common_broadcast_notice($notice);
|
common_broadcast_notice($notice);
|
||||||
@ -307,7 +338,14 @@ class XMPPDaemon extends Daemon
|
|||||||
|
|
||||||
function log($level, $msg)
|
function log($level, $msg)
|
||||||
{
|
{
|
||||||
common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg);
|
$text = 'XMPPDaemon('.$this->resource.'): '.$msg;
|
||||||
|
common_log($level, $text);
|
||||||
|
if (!$this->daemonize)
|
||||||
|
{
|
||||||
|
$line = common_log_line($level, $text);
|
||||||
|
echo $line;
|
||||||
|
echo "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function subscribed($to)
|
function subscribed($to)
|
||||||
@ -323,16 +361,16 @@ if (common_config('xmpp','enabled')==false) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (have_option('i')) {
|
if (have_option('i', 'id')) {
|
||||||
$id = get_option_value('i');
|
$id = get_option_value('i', 'id');
|
||||||
} else if (have_option('--id')) {
|
|
||||||
$id = get_option_value('--id');
|
|
||||||
} else if (count($args) > 0) {
|
} else if (count($args) > 0) {
|
||||||
$id = $args[0];
|
$id = $args[0];
|
||||||
} else {
|
} else {
|
||||||
$id = null;
|
$id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$daemon = new XMPPDaemon($id);
|
$foreground = have_option('f', 'foreground');
|
||||||
|
|
||||||
|
$daemon = new XMPPDaemon($id, !$foreground);
|
||||||
|
|
||||||
$daemon->runOnce();
|
$daemon->runOnce();
|
||||||
|
@ -206,7 +206,10 @@ border-radius:4px;
|
|||||||
padding:0 7px;
|
padding:0 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form_settings input.form_action-default {
|
||||||
|
margin-right:11px;
|
||||||
|
}
|
||||||
|
.form_settings input.form_action-default,
|
||||||
.form_settings input.form_action-primary {
|
.form_settings input.form_action-primary {
|
||||||
padding:0;
|
padding:0;
|
||||||
}
|
}
|
||||||
@ -270,7 +273,6 @@ clear:both;
|
|||||||
margin-bottom:18px;
|
margin-bottom:18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#anon_notice {
|
#anon_notice {
|
||||||
float:left;
|
float:left;
|
||||||
width:43.2%;
|
width:43.2%;
|
||||||
@ -285,7 +287,6 @@ font-size:1.1em;
|
|||||||
font-weight:bold;
|
font-weight:bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#footer {
|
#footer {
|
||||||
float:left;
|
float:left;
|
||||||
width:64%;
|
width:64%;
|
||||||
@ -588,16 +589,16 @@ font-weight:normal;
|
|||||||
content: ")";
|
content: ")";
|
||||||
font-weight:normal;
|
font-weight:normal;
|
||||||
}
|
}
|
||||||
|
.entity_profile dt,
|
||||||
.entity_profile dt {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
.entity_profile h2 {
|
.entity_profile h2 {
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
.entity_profile .role {
|
||||||
|
margin-left:11px;
|
||||||
|
font-style:italic;
|
||||||
|
}
|
||||||
/* entity_profile */
|
/* entity_profile */
|
||||||
|
|
||||||
|
|
||||||
/*entity_actions*/
|
/*entity_actions*/
|
||||||
.entity_actions {
|
.entity_actions {
|
||||||
float:right;
|
float:right;
|
||||||
@ -726,7 +727,6 @@ margin-bottom:0;
|
|||||||
min-height:60px;
|
min-height:60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.profile .form_group_join legend,
|
.profile .form_group_join legend,
|
||||||
.profile .form_group_leave legend,
|
.profile .form_group_leave legend,
|
||||||
.profile .form_user_subscribe legend,
|
.profile .form_user_subscribe legend,
|
||||||
@ -761,13 +761,11 @@ display:inline;
|
|||||||
margin-right:11px;
|
margin-right:11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.profile .entity_profile .form_subscription_edit label {
|
.profile .entity_profile .form_subscription_edit label {
|
||||||
font-weight:normal;
|
font-weight:normal;
|
||||||
margin-right:11px;
|
margin-right:11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* NOTICE */
|
/* NOTICE */
|
||||||
.notice,
|
.notice,
|
||||||
.profile {
|
.profile {
|
||||||
@ -790,7 +788,6 @@ width:95%;
|
|||||||
float:left;
|
float:left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* NOTICES */
|
/* NOTICES */
|
||||||
#notices_primary {
|
#notices_primary {
|
||||||
float:left;
|
float:left;
|
||||||
@ -962,7 +959,6 @@ border:0;
|
|||||||
padding:0;
|
padding:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.notice .attachment {
|
.notice .attachment {
|
||||||
position:relative;
|
position:relative;
|
||||||
padding-left:16px;
|
padding-left:16px;
|
||||||
@ -1031,7 +1027,13 @@ border-radius:7px;
|
|||||||
-moz-border-radius:7px;
|
-moz-border-radius:7px;
|
||||||
-webkit-border-radius:7px;
|
-webkit-border-radius:7px;
|
||||||
}
|
}
|
||||||
|
#jOverlayContent #content img {
|
||||||
|
max-width:480px;
|
||||||
|
}
|
||||||
|
#jOverlayLoading {
|
||||||
|
top:22.5%;
|
||||||
|
left:40%;
|
||||||
|
}
|
||||||
#attachment_view #oembed_info {
|
#attachment_view #oembed_info {
|
||||||
margin-top:11px;
|
margin-top:11px;
|
||||||
}
|
}
|
||||||
@ -1059,7 +1061,6 @@ margin-bottom:18px;
|
|||||||
padding-left:20px;
|
padding-left:20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#filter_tags {
|
#filter_tags {
|
||||||
margin-bottom:11px;
|
margin-bottom:11px;
|
||||||
float:left;
|
float:left;
|
||||||
@ -1105,8 +1106,6 @@ top:3px;
|
|||||||
left:3px;
|
left:3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.pagination {
|
.pagination {
|
||||||
float:left;
|
float:left;
|
||||||
clear:both;
|
clear:both;
|
||||||
@ -1152,7 +1151,6 @@ padding-right:30px;
|
|||||||
}
|
}
|
||||||
/* END: NOTICE */
|
/* END: NOTICE */
|
||||||
|
|
||||||
|
|
||||||
.hentry .entry-content p {
|
.hentry .entry-content p {
|
||||||
margin-bottom:18px;
|
margin-bottom:18px;
|
||||||
}
|
}
|
||||||
@ -1169,7 +1167,6 @@ margin-bottom:18px;
|
|||||||
margin-left:18px;
|
margin-left:18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TOP_POSTERS */
|
/* TOP_POSTERS */
|
||||||
.section tbody td {
|
.section tbody td {
|
||||||
padding-right:18px;
|
padding-right:18px;
|
||||||
@ -1197,7 +1194,6 @@ margin-right:0;
|
|||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* tagcloud */
|
/* tagcloud */
|
||||||
.tag-cloud {
|
.tag-cloud {
|
||||||
list-style-type:none;
|
list-style-type:none;
|
||||||
@ -1280,6 +1276,10 @@ clear:both;
|
|||||||
margin-bottom:0;
|
margin-bottom:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#form_settings_design #settings_design_background-image img {
|
||||||
|
max-width:480px;
|
||||||
|
}
|
||||||
|
|
||||||
#form_settings_design #settings_design_color .form_data,
|
#form_settings_design #settings_design_color .form_data,
|
||||||
#form_settings_design #color-picker {
|
#form_settings_design #color-picker {
|
||||||
float:left;
|
float:left;
|
||||||
|
Loading…
Reference in New Issue
Block a user