Merge branch '0.8.x' of git@gitorious.org:+laconica-developers/laconica/dev into upload
Conflicts: js/util.js lib/attachmentlist.php
This commit is contained in:
commit
ebeb5f744c
49
README
49
README
|
@ -694,6 +694,13 @@ to users on a remote site. (Or not... it's not well tested.) The
|
|||
Upgrading
|
||||
=========
|
||||
|
||||
IMPORTANT NOTE: Laconica 0.7.4 introduced a fix for some
|
||||
incorrectly-stored international characters ("UTF-8"). For new
|
||||
installations, it will now store non-ASCII characters correctly.
|
||||
However, older installations will have the incorrect storage, and will
|
||||
consequently show up "wrong" in browsers. See below for how to deal
|
||||
with this situation.
|
||||
|
||||
If you've been using Laconica 0.6, 0.5 or lower, or if you've been
|
||||
tracking the "git" version of the software, you will probably want
|
||||
to upgrade and keep your existing data. There is no automated upgrade
|
||||
|
@ -783,6 +790,29 @@ problem.
|
|||
3. When fixup_inboxes is finished, you can set the enabled flag to
|
||||
'true'.
|
||||
|
||||
UTF-8 Database
|
||||
--------------
|
||||
|
||||
Laconica 0.7.4 introduced a fix for some incorrectly-stored
|
||||
international characters ("UTF-8"). This fix is not
|
||||
backwards-compatible; installations from before 0.7.4 will show
|
||||
non-ASCII characters of old notices incorrectly. This section explains
|
||||
what to do.
|
||||
|
||||
0. You can disable the new behaviour by setting the 'db''utf8' config
|
||||
option to "false". You should only do this until you're ready to
|
||||
convert your DB to the new format.
|
||||
1. When you're ready to convert, you can run the fixup_utf8.php script
|
||||
in the scripts/ subdirectory. If you've had the "new behaviour"
|
||||
enabled (probably a good idea), you can give the ID of the first
|
||||
"new" notice as a parameter, and only notices before that one will
|
||||
be converted. Notices are converted in reverse chronological order,
|
||||
so the most recent (and visible) ones will be converted first. The
|
||||
script should work whether or not you have the 'db''utf8' config
|
||||
option enabled.
|
||||
2. When you're ready, set $config['db']['utf8'] to true, so that
|
||||
new notices will be stored correctly.
|
||||
|
||||
Configuration options
|
||||
=====================
|
||||
|
||||
|
@ -910,6 +940,10 @@ mirror: you can set this to an array of DSNs, like the above
|
|||
and adding the slaves to this array. Note that if you want some
|
||||
requests to go to the 'database' (master) server, you'll need
|
||||
to include it in this array, too.
|
||||
utf8: whether to talk to the database in UTF-8 mode. This is the default
|
||||
with new installations, but older sites may want to turn it off
|
||||
until they get their databases fixed up. See "UTF-8 database"
|
||||
above for details.
|
||||
|
||||
syslog
|
||||
------
|
||||
|
@ -1162,6 +1196,21 @@ reporturl: URL to post statistics to. Defaults to Laconica developers'
|
|||
set 'run' to 'never' than to set this value to something
|
||||
nonsensical.
|
||||
|
||||
|
||||
attachments
|
||||
-----------
|
||||
|
||||
The software lets users upload files with their notices. You can configure
|
||||
the types of accepted files by mime types and a trio of quota options:
|
||||
per file, per user (total), per user per month.
|
||||
|
||||
supported: an array of mime types you accept to store and distribute,
|
||||
like 'image/gif', 'video/mpeg', 'audio/mpeg', etc.
|
||||
file_quota: maximum size for a single file upload in bytes.
|
||||
user_quota: total size in bytes a user can store.
|
||||
monthly_quota: total size permitted in the current month.
|
||||
|
||||
|
||||
Troubleshooting
|
||||
===============
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ class ApiAction extends Action
|
|||
$this->process_command();
|
||||
} else {
|
||||
# basic authentication failed
|
||||
common_log(LOG_WARNING, "Failed API auth attempt, nickname: $nickname.");
|
||||
$this->show_basic_auth_error();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,14 +179,14 @@ class ConversationTree extends NoticeList
|
|||
|
||||
$this->out->elementStart('div', array('id' =>'notices_primary'));
|
||||
$this->out->element('h2', null, _('Notices'));
|
||||
$this->out->elementStart('ul', array('class' => '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('ul');
|
||||
$this->out->elementEnd('ol');
|
||||
$this->out->elementEnd('div');
|
||||
|
||||
return $cnt;
|
||||
|
@ -215,13 +215,13 @@ class ConversationTree extends NoticeList
|
|||
if (array_key_exists($id, $this->tree)) {
|
||||
$children = $this->tree[$id];
|
||||
|
||||
$this->out->elementStart('ul', array('class' => 'notices'));
|
||||
$this->out->elementStart('ol', array('class' => 'notices'));
|
||||
|
||||
foreach ($children as $child) {
|
||||
$this->showNoticePlus($child);
|
||||
}
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('ol');
|
||||
}
|
||||
|
||||
$this->out->elementEnd('li');
|
||||
|
|
|
@ -70,7 +70,7 @@ class DesignsettingsAction extends AccountSettingsAction
|
|||
function showContent()
|
||||
{
|
||||
$user = common_current_user();
|
||||
$this->elementStart('form', array('method' => 'POST',
|
||||
$this->elementStart('form', array('method' => 'post',
|
||||
'id' => 'form_settings_design',
|
||||
'class' => 'form_settings',
|
||||
'action' =>
|
||||
|
|
|
@ -208,10 +208,10 @@ class ShownoticeAction extends Action
|
|||
|
||||
function showContent()
|
||||
{
|
||||
$this->elementStart('ul', array('class' => 'notices'));
|
||||
$this->elementStart('ol', array('class' => 'notices xoxo'));
|
||||
$nli = new NoticeListItem($this->notice, $this);
|
||||
$nli->show();
|
||||
$this->elementEnd('ul');
|
||||
$this->elementEnd('ol');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -11,7 +11,7 @@ class Foreign_link extends Memcached_DataObject
|
|||
|
||||
public $__table = 'foreign_link'; // table name
|
||||
public $user_id; // int(4) primary_key not_null
|
||||
public $foreign_id; // int(4) primary_key not_null
|
||||
public $foreign_id; // bigint(8) primary_key not_null unsigned
|
||||
public $service; // int(4) primary_key not_null
|
||||
public $credentials; // varchar(255)
|
||||
public $noticesync; // tinyint(1) not_null default_1
|
||||
|
|
|
@ -227,4 +227,22 @@ class Memcached_DataObject extends DB_DataObject
|
|||
$c->set($ckey, $cached, MEMCACHE_COMPRESSED, $expiry);
|
||||
return new ArrayWrapper($cached);
|
||||
}
|
||||
|
||||
// We overload so that 'SET NAMES "utf8"' is called for
|
||||
// each connection
|
||||
|
||||
function _connect()
|
||||
{
|
||||
global $_DB_DATAOBJECT;
|
||||
$exists = !empty($this->_database_dsn_md5) &&
|
||||
isset($_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5]);
|
||||
$result = parent::_connect();
|
||||
if (!$exists) {
|
||||
$DB = &$_DB_DATAOBJECT['CONNECTIONS'][$this->_database_dsn_md5];
|
||||
if (common_config('db', 'utf8')) {
|
||||
$DB->query('SET NAMES "utf8"');
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,7 +285,7 @@ create table foreign_user (
|
|||
|
||||
create table foreign_link (
|
||||
user_id int comment 'link to user on this system, if exists' references user (id),
|
||||
foreign_id int comment 'link ' references foreign_user(id),
|
||||
foreign_id bigint unsigned comment 'link to user on foreign service, if exists' references foreign_user(id),
|
||||
service int not null comment 'foreign key to service' references foreign_service(id),
|
||||
credentials varchar(255) comment 'authc credentials, typically a password',
|
||||
noticesync tinyint not null default 1 comment 'notice synchronization, bit 1 = sync outgoing, bit 2 = sync incoming, bit 3 = filter local replies',
|
||||
|
|
|
@ -2,6 +2,7 @@ INSERT INTO notice_source
|
|||
(code, name, url, created)
|
||||
VALUES
|
||||
('adium', 'Adium', 'http://www.adiumx.com/', now()),
|
||||
('AgentSolo.com','AgentSolo.com','http://www.agentsolo.com/', now()),
|
||||
('betwittered','BeTwittered','http://www.32hours.com/betwitteredinfo/', now()),
|
||||
('bti','bti','http://gregkh.github.com/bti/', now()),
|
||||
('cliqset', 'Cliqset', 'http://www.cliqset.com/', now()),
|
||||
|
@ -29,6 +30,7 @@ VALUES
|
|||
('pingvine','PingVine','http://pingvine.com/', now()),
|
||||
('pocketwit','PockeTwit','http://code.google.com/p/pocketwit/', now()),
|
||||
('posty','Posty','http://spreadingfunkyness.com/posty/', now()),
|
||||
('qtwitter','qTwitter','http://qtwitter.ayoy.net/', now()),
|
||||
('royalewithcheese','Royale With Cheese','http://p.hellyeah.org/', now()),
|
||||
('rssdent','rssdent','http://github.com/zcopley/rssdent/tree/master', now()),
|
||||
('rygh.no','rygh.no','http://rygh.no/', now()),
|
||||
|
|
51
js/util.js
51
js/util.js
|
@ -250,6 +250,7 @@ $(document).ready(function(){
|
|||
$("#form_notice").each(addAjaxHidden);
|
||||
NoticeHover();
|
||||
NoticeReply();
|
||||
NoticeAttachments();
|
||||
});
|
||||
|
||||
|
||||
|
@ -288,3 +289,53 @@ function NoticeReplySet(nick,id) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function NoticeAttachments() {
|
||||
$.fn.jOverlay.options = {
|
||||
method : 'GET',
|
||||
data : '',
|
||||
url : '',
|
||||
color : '#000',
|
||||
opacity : '0.6',
|
||||
zIndex : 99,
|
||||
center : true,
|
||||
imgLoading : $('address .url')[0].href+'theme/base/images/illustrations/illu_progress_loading-01.gif',
|
||||
bgClickToClose : true,
|
||||
success : function() {
|
||||
$('#jOverlayContent').append('<button>×</button>');
|
||||
$('#jOverlayContent button').click($.closeOverlay);
|
||||
},
|
||||
timeout : 0
|
||||
};
|
||||
|
||||
$('a.attachment').click(function() {
|
||||
$().jOverlay({url: $('address .url')[0].href+'/attachment/' + ($(this).attr('id').substring('attachment'.length + 1)) + '/ajax'});
|
||||
return false;
|
||||
});
|
||||
|
||||
var t;
|
||||
$("body:not(#shownotice) a.thumbnail").hover(
|
||||
function() {
|
||||
var anchor = $(this);
|
||||
$("a.thumbnail").children('img').hide();
|
||||
anchor.closest(".entry-title").addClass('ov');
|
||||
|
||||
if (anchor.children('img').length == 0) {
|
||||
t = setTimeout(function() {
|
||||
$.get($('address .url')[0].href+'/attachment/' + (anchor.attr('id').substring('attachment'.length + 1)) + '/thumbnail', null, function(data) {
|
||||
anchor.append(data);
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
else {
|
||||
anchor.children('img').show();
|
||||
}
|
||||
},
|
||||
function() {
|
||||
clearTimeout(t);
|
||||
$("a.thumbnail").children('img').hide();
|
||||
$(this).closest(".entry-title").removeClass('ov');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,11 +83,10 @@ class AttachmentList extends Widget
|
|||
$atts = new File;
|
||||
$att = $atts->getAttachments($this->notice->id);
|
||||
if (empty($att)) return 0;
|
||||
|
||||
$this->out->elementStart('dl', array('id' =>'attachment'));
|
||||
$this->out->elementStart('dl', array('id' =>'attachments'));
|
||||
$this->out->element('dt', null, _('Attachments'));
|
||||
$this->out->elementStart('dd');
|
||||
$this->out->elementStart('ul', array('class' => 'attachments'));
|
||||
$this->out->elementStart('ol', array('class' => 'attachments'));
|
||||
|
||||
foreach ($att as $n=>$attachment) {
|
||||
$item = $this->newListItem($attachment);
|
||||
|
@ -95,7 +94,7 @@ class AttachmentList extends Widget
|
|||
}
|
||||
|
||||
$this->out->elementEnd('dd');
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('ol');
|
||||
$this->out->elementEnd('dl');
|
||||
|
||||
return count($att);
|
||||
|
|
|
@ -208,6 +208,7 @@ $config['db'] =
|
|||
'require_prefix' => 'classes/',
|
||||
'class_prefix' => '',
|
||||
'mirror' => null,
|
||||
'utf8' => true,
|
||||
'db_driver' => 'DB', # XXX: JanRain libs only work with DB
|
||||
'quote_identifiers' => false,
|
||||
'type' => 'mysql' );
|
||||
|
|
|
@ -86,7 +86,7 @@ class NoticeList extends Widget
|
|||
{
|
||||
$this->out->elementStart('div', array('id' =>'notices_primary'));
|
||||
$this->out->element('h2', null, _('Notices'));
|
||||
$this->out->elementStart('ul', array('class' => 'notices'));
|
||||
$this->out->elementStart('ol', array('class' => 'notices xoxo'));
|
||||
|
||||
$cnt = 0;
|
||||
|
||||
|
@ -101,7 +101,7 @@ class NoticeList extends Widget
|
|||
$item->show();
|
||||
}
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('ol');
|
||||
$this->out->elementEnd('div');
|
||||
|
||||
return $cnt;
|
||||
|
|
|
@ -52,12 +52,12 @@ class NoticeSection extends Section
|
|||
{
|
||||
$notices = $this->getNotices();
|
||||
$cnt = 0;
|
||||
$this->out->elementStart('ul', 'notices');
|
||||
$this->out->elementStart('ol', 'notices xoxo');
|
||||
while ($notices->fetch() && ++$cnt <= NOTICES_PER_SECTION) {
|
||||
$this->showNotice($notices);
|
||||
}
|
||||
|
||||
$this->out->elementEnd('ul');
|
||||
$this->out->elementEnd('ol');
|
||||
return ($cnt > NOTICES_PER_SECTION);
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,28 @@ class FBConnectauthAction extends Action
|
|||
parent::handle($args);
|
||||
|
||||
if (common_is_real_login()) {
|
||||
$this->clientError(_('Already logged in.'));
|
||||
|
||||
// User is already logged in. Does she already have a linked Facebook acct?
|
||||
$flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_CONNECT_SERVICE);
|
||||
|
||||
if ($flink) {
|
||||
|
||||
// User already has a linked Facebook account and shouldn't be here
|
||||
common_debug('There is already a local user (' . $flink->user_id .
|
||||
') linked with this Facebook (' . $this->fbuid . ').');
|
||||
|
||||
// We don't want these cookies
|
||||
getFacebook()->clear_cookie_state();
|
||||
|
||||
$this->clientError(_('There is already a local user linked with this Facebook.'));
|
||||
|
||||
} else {
|
||||
|
||||
// User came from the Facebook connect settings tab, and
|
||||
// probably just wants to link/relink their Facebook account
|
||||
$this->connectUser();
|
||||
}
|
||||
|
||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
|
||||
$token = $this->trimmed('token');
|
||||
|
@ -78,7 +99,7 @@ class FBConnectauthAction extends Action
|
|||
}
|
||||
$this->createNewUser();
|
||||
} else if ($this->arg('connect')) {
|
||||
$this->connectUser();
|
||||
$this->connectNewUser();
|
||||
} else {
|
||||
common_debug(print_r($this->args, true), __FILE__);
|
||||
$this->showForm(_('Something weird happened.'),
|
||||
|
@ -259,7 +280,7 @@ class FBConnectauthAction extends Action
|
|||
303);
|
||||
}
|
||||
|
||||
function connectUser()
|
||||
function connectNewUser()
|
||||
{
|
||||
$nickname = $this->trimmed('nickname');
|
||||
$password = $this->trimmed('password');
|
||||
|
@ -290,6 +311,23 @@ class FBConnectauthAction extends Action
|
|||
$this->goHome($user->nickname);
|
||||
}
|
||||
|
||||
function connectUser()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
$result = $this->flinkUser($user->id, $this->fbuid);
|
||||
|
||||
if (!$result) {
|
||||
$this->serverError(_('Error connecting user to Facebook.'));
|
||||
return;
|
||||
}
|
||||
|
||||
common_debug("Connected Facebook user $this->fbuid to local user $user->id");
|
||||
|
||||
// Return to Facebook connection settings tab
|
||||
common_redirect(common_local_url('FBConnectSettings'), 303);
|
||||
}
|
||||
|
||||
function tryLogin()
|
||||
{
|
||||
common_debug("Trying Facebook Login...");
|
||||
|
|
|
@ -143,23 +143,6 @@ class FBConnectPlugin extends Plugin
|
|||
|
||||
if ($user) {
|
||||
|
||||
$action->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
|
||||
_('Home'), _('Personal profile and friends timeline'), false, 'nav_home');
|
||||
$action->menuItem(common_local_url('profilesettings'),
|
||||
_('Account'), _('Change your email, avatar, password, profile'), false, 'nav_account');
|
||||
if (common_config('xmpp', 'enabled')) {
|
||||
$action->menuItem(common_local_url('imsettings'),
|
||||
_('Connect'), _('Connect to IM, SMS, Twitter'), false, 'nav_connect');
|
||||
} else {
|
||||
$action->menuItem(common_local_url('smssettings'),
|
||||
_('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect');
|
||||
}
|
||||
$action->menuItem(common_local_url('invite'),
|
||||
_('Invite'),
|
||||
sprintf(_('Invite friends and colleagues to join you on %s'),
|
||||
common_config('site', 'name')),
|
||||
false, 'nav_invitecontact');
|
||||
|
||||
$flink = Foreign_link::getByUserId($user->id, FACEBOOK_CONNECT_SERVICE);
|
||||
$fbuid = 0;
|
||||
|
||||
|
@ -195,9 +178,25 @@ class FBConnectPlugin extends Plugin
|
|||
}
|
||||
}
|
||||
|
||||
// Need to override the Logout link to make it do FB stuff
|
||||
$action->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
|
||||
_('Home'), _('Personal profile and friends timeline'), false, 'nav_home');
|
||||
$action->menuItem(common_local_url('profilesettings'),
|
||||
_('Account'), _('Change your email, avatar, password, profile'), false, 'nav_account');
|
||||
if (common_config('xmpp', 'enabled')) {
|
||||
$action->menuItem(common_local_url('imsettings'),
|
||||
_('Connect'), _('Connect to IM, SMS, Twitter'), false, 'nav_connect');
|
||||
} else {
|
||||
$action->menuItem(common_local_url('smssettings'),
|
||||
_('Connect'), _('Connect to SMS, Twitter'), false, 'nav_connect');
|
||||
}
|
||||
$action->menuItem(common_local_url('invite'),
|
||||
_('Invite'),
|
||||
sprintf(_('Invite friends and colleagues to join you on %s'),
|
||||
common_config('site', 'name')),
|
||||
false, 'nav_invitecontact');
|
||||
|
||||
if ($fbuid > 0) {
|
||||
// Need to override the Logout link to make it do FB stuff
|
||||
if ($flink && $fbuid > 0) {
|
||||
|
||||
$logout_url = common_local_url('logout');
|
||||
$title = _('Logout from the site');
|
||||
|
@ -258,11 +257,19 @@ class FBConnectPlugin extends Plugin
|
|||
return true;
|
||||
}
|
||||
|
||||
function onEndLogout($action)
|
||||
function onStartLogout($action)
|
||||
{
|
||||
try {
|
||||
$user = common_current_user();
|
||||
|
||||
$flink = Foreign_link::getByUserId($user->id, FACEBOOK_CONNECT_SERVICE);
|
||||
|
||||
$action->logout();
|
||||
|
||||
if ($flink) {
|
||||
|
||||
$facebook = getFacebook();
|
||||
|
||||
try {
|
||||
$fbuid = $facebook->get_loggedin_user();
|
||||
|
||||
if ($fbuid > 0) {
|
||||
|
@ -275,4 +282,7 @@ class FBConnectPlugin extends Plugin
|
|||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,41 +78,40 @@ class FBConnectSettingsAction extends ConnectSettingsAction
|
|||
function showContent()
|
||||
{
|
||||
$user = common_current_user();
|
||||
|
||||
$flink = Foreign_link::getByUserID($user->id, FACEBOOK_CONNECT_SERVICE);
|
||||
|
||||
if (!$flink) {
|
||||
|
||||
$this->element('p', 'form_note',
|
||||
_('There is no Facebook user connected to this account.'));
|
||||
|
||||
$this->element('fb:login-button', array('onlogin' => 'goto_login()',
|
||||
'length' => 'long'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->element('p', 'form_note',
|
||||
_('Connected Facebook user:'));
|
||||
|
||||
$this->elementStart('p', array('class' => 'facebook-user-display'));
|
||||
$this->elementStart('fb:profile-pic',
|
||||
array('uid' => $flink->foreign_id,
|
||||
'size' => 'square',
|
||||
'linked' => 'true',
|
||||
'facebook-logo' => 'true'));
|
||||
$this->elementEnd('fb:profile-pic');
|
||||
|
||||
$this->elementStart('fb:name', array('uid' => $flink->foreign_id));
|
||||
$this->elementEnd('fb:name');
|
||||
$this->elementEnd('p');
|
||||
|
||||
$this->elementStart('form', array('method' => 'post',
|
||||
'id' => 'form_settings_facebook',
|
||||
'class' => 'form_settings',
|
||||
'action' =>
|
||||
common_local_url('FBConnectSettings')));
|
||||
|
||||
if (!$flink) {
|
||||
|
||||
$this->element('p', 'instructions',
|
||||
_('There is no Facebook user connected to this account.'));
|
||||
|
||||
$this->element('fb:login-button', array('onlogin' => 'goto_login()',
|
||||
'length' => 'long'));
|
||||
|
||||
} else {
|
||||
|
||||
$this->element('p', 'form_note',
|
||||
_('Connected Facebook user'));
|
||||
|
||||
$this->elementStart('p', array('class' => 'facebook-user-display'));
|
||||
$this->elementStart('fb:profile-pic',
|
||||
array('uid' => $flink->foreign_id,
|
||||
'size' => 'small',
|
||||
'linked' => 'true',
|
||||
'facebook-logo' => 'true'));
|
||||
$this->elementEnd('fb:profile-pic');
|
||||
|
||||
$this->elementStart('fb:name', array('uid' => $flink->foreign_id,
|
||||
'useyou' => 'false'));
|
||||
$this->elementEnd('fb:name');
|
||||
$this->elementEnd('p');
|
||||
|
||||
$this->hidden('token', common_session_token());
|
||||
|
||||
$this->elementStart('fieldset');
|
||||
|
@ -131,10 +130,21 @@ class FBConnectSettingsAction extends ConnectSettingsAction
|
|||
$this->text(_(' first.'));
|
||||
$this->elementEnd('p');
|
||||
} else {
|
||||
|
||||
$note = 'Keep your %s account but disconnect from Facebook. ' .
|
||||
'You\'ll use your %s password to log in.';
|
||||
|
||||
$site = common_config('site', 'name');
|
||||
|
||||
$this->element('p', 'instructions',
|
||||
sprintf($note, $site, $site));
|
||||
|
||||
$this->submit('disconnect', _('Disconnect'));
|
||||
}
|
||||
|
||||
$this->elementEnd('fieldset');
|
||||
}
|
||||
|
||||
$this->elementEnd('form');
|
||||
}
|
||||
|
||||
|
@ -171,8 +181,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction
|
|||
|
||||
try {
|
||||
|
||||
// XXX: not sure what exactly to do here
|
||||
|
||||
// Clear FB Connect cookies out
|
||||
$facebook = getFacebook();
|
||||
$facebook->clear_cookie_state();
|
||||
|
||||
|
@ -182,7 +191,7 @@ class FBConnectSettingsAction extends ConnectSettingsAction
|
|||
$e->getMessage());
|
||||
}
|
||||
|
||||
$this->showForm(_('Facebook user disconnected.'), true);
|
||||
$this->showForm(_('You have disconnected from Facebook.'), true);
|
||||
|
||||
} else {
|
||||
$this->showForm(_('Not sure what you\'re trying to do.'));
|
||||
|
|
141
scripts/fixup_utf8.php
Normal file
141
scripts/fixup_utf8.php
Normal file
|
@ -0,0 +1,141 @@
|
|||
#!/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/>.
|
||||
*/
|
||||
|
||||
# Abort if called from a web server
|
||||
if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
|
||||
print "This script must be run from the command line\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ini_set("max_execution_time", "0");
|
||||
ini_set("max_input_time", "0");
|
||||
set_time_limit(0);
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
define('INSTALLDIR', realpath(dirname(__FILE__) . '/..'));
|
||||
define('LACONICA', true);
|
||||
|
||||
require_once(INSTALLDIR . '/lib/common.php');
|
||||
require_once('DB.php');
|
||||
|
||||
function fixup_utf8($id) {
|
||||
|
||||
$dbl = doConnect('latin1');
|
||||
|
||||
if (empty($dbl)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dbu = doConnect('utf8');
|
||||
|
||||
if (empty($dbu)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do a separate DB connection
|
||||
|
||||
$sth = $dbu->prepare("UPDATE notice SET content = UNHEX(?), rendered = UNHEX(?) WHERE id = ?");
|
||||
|
||||
if (PEAR::isError($sth)) {
|
||||
echo "ERROR: " . $sth->getMessage() . "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
$sql = 'SELECT id, content, rendered FROM notice ' .
|
||||
'WHERE LENGTH(content) != CHAR_LENGTH(content)';
|
||||
|
||||
if (!empty($id)) {
|
||||
$sql .= ' AND id < ' . $id;
|
||||
}
|
||||
|
||||
$sql .= ' ORDER BY id DESC';
|
||||
|
||||
$rn = $dbl->query($sql);
|
||||
|
||||
if (PEAR::isError($rn)) {
|
||||
echo "ERROR: " . $rn->getMessage() . "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
echo "Number of rows: " . $rn->numRows() . "\n";
|
||||
|
||||
$notice = array();
|
||||
|
||||
while (DB_OK == $rn->fetchInto($notice)) {
|
||||
|
||||
$id = ($notice[0])+0;
|
||||
$content = bin2hex($notice[1]);
|
||||
$rendered = bin2hex($notice[2]);
|
||||
|
||||
echo "$id...";
|
||||
|
||||
$result =& $dbu->execute($sth, array($content, $rendered, $id));
|
||||
|
||||
if (PEAR::isError($result)) {
|
||||
echo "ERROR: " . $result->getMessage() . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$cnt = $dbu->affectedRows();
|
||||
|
||||
if ($cnt != 1) {
|
||||
echo "ERROR: 0 rows affected\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$notice = Notice::staticGet('id', $id);
|
||||
$notice->decache();
|
||||
|
||||
echo "OK\n";
|
||||
}
|
||||
}
|
||||
|
||||
function doConnect($charset)
|
||||
{
|
||||
$db = DB::connect(common_config('db', 'database'),
|
||||
array('persistent' => false));
|
||||
|
||||
if (PEAR::isError($db)) {
|
||||
echo "ERROR: " . $db->getMessage() . "\n";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$result = $db->query("SET NAMES $charset");
|
||||
|
||||
if (PEAR::isError($result)) {
|
||||
echo "ERROR: " . $result->getMessage() . "\n";
|
||||
$db->disconnect();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$result = $db->autoCommit(true);
|
||||
|
||||
if (PEAR::isError($result)) {
|
||||
echo "ERROR: " . $result->getMessage() . "\n";
|
||||
$db->disconnect();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $db;
|
||||
}
|
||||
|
||||
$id = ($argc > 1) ? $argv[1] : null;
|
||||
|
||||
fixup_utf8($id);
|
|
@ -855,20 +855,6 @@ display:inline-block;
|
|||
text-transform:lowercase;
|
||||
}
|
||||
|
||||
.notice .attachment {
|
||||
position:relative;
|
||||
}
|
||||
.notice .attachment img {
|
||||
position:absolute;
|
||||
top:18px;
|
||||
left:0;
|
||||
z-index:99;
|
||||
}
|
||||
#shownotice .notice .attachment img {
|
||||
position:static;
|
||||
}
|
||||
|
||||
|
||||
.notice-options {
|
||||
position:relative;
|
||||
font-size:0.95em;
|
||||
|
@ -936,6 +922,75 @@ padding:0;
|
|||
}
|
||||
|
||||
|
||||
.notice .attachment {
|
||||
position:relative;
|
||||
padding-left:16px;
|
||||
}
|
||||
#attachments .attachment {
|
||||
padding-left:0;
|
||||
}
|
||||
.notice .attachment img {
|
||||
position:absolute;
|
||||
top:18px;
|
||||
left:0;
|
||||
z-index:99;
|
||||
}
|
||||
#shownotice .notice .attachment img {
|
||||
position:static;
|
||||
}
|
||||
|
||||
#attachments {
|
||||
clear:both;
|
||||
float:left;
|
||||
width:100%;
|
||||
margin-top:18px;
|
||||
}
|
||||
#attachments dt {
|
||||
font-weight:bold;
|
||||
font-size:1.3em;
|
||||
margin-bottom:4px;
|
||||
}
|
||||
|
||||
#attachments ol li {
|
||||
margin-bottom:18px;
|
||||
list-style-type:decimal;
|
||||
float:left;
|
||||
clear:both;
|
||||
}
|
||||
|
||||
#jOverlayContent,
|
||||
#jOverlayContent #content,
|
||||
#jOverlayContent #content_inner {
|
||||
width: auto !important;
|
||||
margin-bottom:0;
|
||||
}
|
||||
#jOverlayContent #content {
|
||||
padding:11px;
|
||||
min-height:auto;
|
||||
}
|
||||
#jOverlayContent .external span {
|
||||
display:block;
|
||||
margin-bottom:11px;
|
||||
}
|
||||
#jOverlayContent button {
|
||||
position:absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
width:29px;
|
||||
height:29px;
|
||||
text-align:center;
|
||||
font-weight:bold;
|
||||
padding:0;
|
||||
}
|
||||
#jOverlayContent h1 {
|
||||
max-width:475px;
|
||||
}
|
||||
#jOverlayContent #content {
|
||||
border-radius:7px;
|
||||
-moz-border-radius:7px;
|
||||
-webkit-border-radius:7px;
|
||||
}
|
||||
|
||||
#usergroups #new_group {
|
||||
float: left;
|
||||
margin-right: 2em;
|
||||
|
@ -1182,6 +1237,7 @@ width:33%;
|
|||
}
|
||||
#settings_design_color .form_data label {
|
||||
float:none;
|
||||
display:block;
|
||||
}
|
||||
#settings_design_color .form_data .swatch {
|
||||
padding:11px;
|
||||
|
|
|
@ -30,3 +30,9 @@ margin-right:4px;
|
|||
.entity_profile {
|
||||
width:64%;
|
||||
}
|
||||
#jOverlayContent .notice * {
|
||||
z-index:1;
|
||||
}
|
||||
#jOverlayContent .notice .attachment img {
|
||||
z-index:9999;
|
||||
}
|
||||
|
|
BIN
theme/base/images/icons/twotone/green/clip-02.gif
Normal file
BIN
theme/base/images/icons/twotone/green/clip-02.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 70 B |
|
@ -175,6 +175,12 @@ background-image:url(../../base/images/icons/twotone/green/shield.gif);
|
|||
}
|
||||
|
||||
/* NOTICES */
|
||||
.notice .attachment {
|
||||
background:transparent url(../../base/images/icons/twotone/green/clip-02.gif) no-repeat 0 45%;
|
||||
}
|
||||
#attachments .attachment {
|
||||
background:none;
|
||||
}
|
||||
.notice-options .notice_reply a,
|
||||
.notice-options form input.submit {
|
||||
background-color:transparent;
|
||||
|
|
|
@ -175,6 +175,12 @@ background-image:url(../../base/images/icons/twotone/green/shield.gif);
|
|||
}
|
||||
|
||||
/* NOTICES */
|
||||
.notice .attachment {
|
||||
background:transparent url(../../base/images/icons/twotone/green/clip-02.gif) no-repeat 0 45%;
|
||||
}
|
||||
#attachments .attachment {
|
||||
background:none;
|
||||
}
|
||||
.notice-options .notice_reply a,
|
||||
.notice-options form input.submit {
|
||||
background-color:transparent;
|
||||
|
|
Loading…
Reference in New Issue
Block a user