summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README26
-rw-r--r--actions/public.php11
-rw-r--r--actions/recoverpassword.php22
-rw-r--r--actions/showgroup.php15
-rw-r--r--actions/showstream.php14
-rw-r--r--apple-touch-icon.pngbin0 -> 6265 bytes
-rw-r--r--classes/Notice.php94
-rw-r--r--classes/User.php145
-rw-r--r--config.php.sample10
-rw-r--r--db/notice_source.sql3
-rw-r--r--js/util.js2
-rw-r--r--lib/action.php27
-rw-r--r--lib/common.php5
-rw-r--r--lib/jabber.php57
-rw-r--r--lib/language.php2
-rw-r--r--lib/logingroupnav.php20
-rw-r--r--lib/messageform.php10
-rw-r--r--lib/noticeform.php9
-rw-r--r--lib/noticelist.php1
-rw-r--r--lib/router.php30
-rw-r--r--lib/rssaction.php18
-rw-r--r--lib/twitterapi.php30
-rw-r--r--lib/util.php31
-rw-r--r--plugins/LinkbackPlugin.php11
-rw-r--r--plugins/PiwikAnalyticsPlugin.php104
-rw-r--r--theme/base/css/display.css58
-rw-r--r--theme/base/css/ie6.css3
-rw-r--r--theme/base/images/icons/icon_processing.gifbin0 -> 673 bytes
-rw-r--r--theme/default/css/display.css8
-rw-r--r--theme/identica/css/display.css9
30 files changed, 535 insertions, 240 deletions
diff --git a/README b/README
index 71760ce4f..95f9edcea 100644
--- a/README
+++ b/README
@@ -877,7 +877,7 @@ This section is a catch-all for site-wide variables.
name: the name of your site, like 'YourCompany Microblog'.
server: the server part of your site's URLs, like 'example.net'.
-path: The path part of your site's URLs, like 'mublog' or '/'
+path: The path part of your site's URLs, like 'mublog' or ''
(installed in root).
fancy: whether or not your site uses fancy URLs (see Fancy URLs
section above). Default is false.
@@ -925,6 +925,16 @@ dupelimit: Time in which it's not OK for the same person to post the
same notice; default = 60 seconds.
logo: URL of an image file to use as the logo for the site. Overrides
the logo in the theme, if any.
+ssl: Whether to use SSL and https:// URLs for some or all pages.
+ Possible values are 'always' (use it for all pages), 'never'
+ (don't use it for any pages), or 'sometimes' (use it for
+ sensitive pages that include passwords like login and registration,
+ but not for regular pages). Default to 'never'.
+sslserver: use an alternate server name for SSL URLs, like
+ 'secure.example.org'. You should be careful to set cookie
+ parameters correctly so that both the SSL server and the
+ "normal" server can access the session cookie and
+ preferably other cookies as well.
db
--
@@ -1169,6 +1179,20 @@ banned: an array of usernames and/or profile IDs of 'banned' profiles.
not be accepted at all. (Compare with blacklisted users above,
whose posts just won't show up in the public stream.)
+newuser
+-------
+
+Options with new users.
+
+subscribe: nickname of a user account to automatically subscribe new
+ users to. Typically this would be system account for e.g.
+ service updates or announcements. Users are able to unsub
+ if they want. Default is null; no auto subscribe.
+welcome: nickname of a user account that sends welcome messages to new
+ users. Can be the same as 'subscribe' account, although on
+ busy servers it may be a good idea to keep that one just for
+ 'urgent' messages. Default is null; no message.
+
Troubleshooting
===============
diff --git a/actions/public.php b/actions/public.php
index a20ae4032..9b22e0a2c 100644
--- a/actions/public.php
+++ b/actions/public.php
@@ -207,9 +207,14 @@ class PublicAction extends Action
function showAnonymousMessage()
{
- $m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
- 'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
- '[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
+ if (! (common_config('site','closed') || common_config('site','inviteonly'))) {
+ $m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
+ 'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
+ '[Join now](%%action.register%%) to share notices about yourself with friends, family, and colleagues! ([Read more](%%doc.help%%))');
+ } else {
+ $m = _('This is %%site.name%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
+ 'based on the Free Software [Laconica](http://laconi.ca/) tool.');
+ }
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');
diff --git a/actions/recoverpassword.php b/actions/recoverpassword.php
index eeb6b2516..620fe7eb8 100644
--- a/actions/recoverpassword.php
+++ b/actions/recoverpassword.php
@@ -181,13 +181,21 @@ class RecoverpasswordAction extends Action
function showRecoverForm()
{
$this->elementStart('form', array('method' => 'post',
- 'id' => 'recoverpassword',
+ 'id' => 'form_password_recover',
+ 'class' => 'form_settings',
'action' => common_local_url('recoverpassword')));
+ $this->elementStart('fieldset');
+ $this->element('legend', null, _('Password recover'));
+ $this->elementStart('ul', 'form_data');
+ $this->elementStart('li');
$this->input('nicknameoremail', _('Nickname or email'),
$this->trimmed('nicknameoremail'),
_('Your nickname on this server, ' .
'or your registered email address.'));
+ $this->elementEnd('li');
+ $this->elementEnd('ul');
$this->submit('recover', _('Recover'));
+ $this->elementEnd('fieldset');
$this->elementEnd('form');
}
@@ -213,14 +221,24 @@ class RecoverpasswordAction extends Action
function showResetForm()
{
$this->elementStart('form', array('method' => 'post',
- 'id' => 'recoverpassword',
+ 'id' => 'form_password_change',
+ 'class' => 'form_settings',
'action' => common_local_url('recoverpassword')));
+ $this->elementStart('fieldset');
+ $this->element('legend', null, _('Password change'));
$this->hidden('token', common_session_token());
+ $this->elementStart('ul', 'form_data');
+ $this->elementStart('li');
$this->password('newpassword', _('New password'),
_('6 or more characters, and don\'t forget it!'));
+ $this->elementEnd('li');
+ $this->elementStart('li');
$this->password('confirm', _('Confirm'),
_('Same as password above'));
+ $this->elementEnd('li');
+ $this->elementEnd('ul');
$this->submit('reset', _('Reset'));
+ $this->elementEnd('fieldset');
$this->elementEnd('form');
}
diff --git a/actions/showgroup.php b/actions/showgroup.php
index 95d2914ba..79445851f 100644
--- a/actions/showgroup.php
+++ b/actions/showgroup.php
@@ -396,11 +396,18 @@ class ShowgroupAction extends Action
function showAnonymousMessage()
{
- $m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
- 'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
- 'short messages about their life and interests. '.
- '[Join now](%%%%action.register%%%%) to become part of this group and many more! ([Read more](%%%%doc.help%%%%))'),
+ if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
+ $m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
+ 'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
+ 'short messages about their life and interests. '.
+ '[Join now](%%%%action.register%%%%) to become part of this group and many more! ([Read more](%%%%doc.help%%%%))'),
$this->group->nickname);
+ } else {
+ $m = sprintf(_('**%s** is a user group on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
+ 'based on the Free Software [Laconica](http://laconi.ca/) tool. Its members share ' .
+ 'short messages about their life and interests. '),
+ $this->group->nickname);
+ }
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');
diff --git a/actions/showstream.php b/actions/showstream.php
index 9b6536293..f5886f3d3 100644
--- a/actions/showstream.php
+++ b/actions/showstream.php
@@ -535,10 +535,16 @@ class ShowstreamAction extends Action
function showAnonymousMessage()
{
- $m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
- 'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
- '[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
- $this->user->nickname, $this->user->nickname);
+ if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
+ $m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
+ 'based on the Free Software [Laconica](http://laconi.ca/) tool. ' .
+ '[Join now](%%%%action.register%%%%) to follow **%s**\'s notices and many more! ([Read more](%%%%doc.help%%%%))'),
+ $this->user->nickname, $this->user->nickname);
+ } else {
+ $m = sprintf(_('**%s** has an account on %%%%site.name%%%%, a [micro-blogging](http://en.wikipedia.org/wiki/Micro-blogging) service ' .
+ 'based on the Free Software [Laconica](http://laconi.ca/) tool. '),
+ $this->user->nickname, $this->user->nickname);
+ }
$this->elementStart('div', array('id' => 'anon_notice'));
$this->raw(common_markup_to_html($m));
$this->elementEnd('div');
diff --git a/apple-touch-icon.png b/apple-touch-icon.png
new file mode 100644
index 000000000..d129298d4
--- /dev/null
+++ b/apple-touch-icon.png
Binary files differ
diff --git a/classes/Notice.php b/classes/Notice.php
index 3087e39a7..44a6aeb98 100644
--- a/classes/Notice.php
+++ b/classes/Notice.php
@@ -799,4 +799,98 @@ class Notice extends Memcached_DataObject
}
}
}
+
+ function asAtomEntry($namespace=false, $source=false)
+ {
+ $profile = $this->getProfile();
+
+ $xs = new XMLStringer(true);
+
+ if ($namespace) {
+ $attrs = array('xmlns' => 'http://www.w3.org/2005/Atom',
+ 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0');
+ } else {
+ $attrs = array();
+ }
+
+ $xs->elementStart('entry', $attrs);
+
+ if ($source) {
+ $xs->elementStart('source');
+ $xs->element('title', null, $profile->nickname . " - " . common_config('site', 'name'));
+ $xs->element('link', array('href' => $profile->profileurl));
+ $user = User::staticGet('id', $profile->id);
+ if (!empty($user)) {
+ $atom_feed = common_local_url('api',
+ array('apiaction' => 'statuses',
+ 'method' => 'user_timeline',
+ 'argument' => $profile->nickname.'.atom'));
+ $xs->element('link', array('rel' => 'self',
+ 'type' => 'application/atom+xml',
+ 'href' => $profile->profileurl));
+ $xs->element('link', array('rel' => 'license',
+ 'href' => common_config('license', 'url')));
+ }
+
+ $xs->element('icon', null, $profile->avatarUrl(AVATAR_PROFILE_SIZE));
+ }
+
+ $xs->elementStart('author');
+ $xs->element('name', null, $profile->nickname);
+ $xs->element('uri', null, $profile->profileurl);
+ $xs->elementEnd('author');
+
+ if ($source) {
+ $xs->elementEnd('source');
+ }
+
+ $xs->element('title', null, $this->content);
+ $xs->element('summary', null, $this->content);
+
+ $xs->element('link', array('rel' => 'alternate',
+ 'href' => $this->bestUrl()));
+
+ $xs->element('id', null, $this->uri);
+
+ $xs->element('published', null, common_date_w3dtf($this->created));
+ $xs->element('updated', null, common_date_w3dtf($this->modified));
+
+ if ($this->reply_to) {
+ $reply_notice = Notice::staticGet('id', $this->reply_to);
+ if (!empty($reply_notice)) {
+ $xs->element('link', array('rel' => 'related',
+ 'href' => $reply_notice->bestUrl()));
+ $xs->element('thr:in-reply-to',
+ array('ref' => $reply_notice->uri,
+ 'href' => $reply_notice->bestUrl()));
+ }
+ }
+
+ $xs->element('content', array('type' => 'html'), $this->rendered);
+
+ $tag = new Notice_tag();
+ $tag->notice_id = $this->id;
+ if ($tag->find()) {
+ while ($tag->fetch()) {
+ $xs->element('category', array('term' => $tag->tag));
+ }
+ }
+ $tag->free();
+
+ $xs->elementEnd('entry');
+
+ return $xs->getString();
+ }
+
+ function bestUrl()
+ {
+ if (!empty($this->url)) {
+ return $this->url;
+ } else if (!empty($this->uri) && preg_match('/^https?:/', $this->uri)) {
+ return $this->uri;
+ } else {
+ return common_local_url('shownotice',
+ array('notice' => $this->id));
+ }
+ }
}
diff --git a/classes/User.php b/classes/User.php
index d9f30bec5..3b9b5cd83 100644
--- a/classes/User.php
+++ b/classes/User.php
@@ -1,7 +1,7 @@
<?php
/*
* Laconica - a distributed open-source microblogging tool
- * Copyright (C) 2008, Controlez-Vous, Inc.
+ * Copyright (C) 2008, 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
@@ -17,11 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-if (!defined('LACONICA')) { exit(1); }
+if (!defined('LACONICA')) {
+ exit(1);
+}
/**
* Table Definition for user
*/
+
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
require_once 'Validate.php';
@@ -79,13 +82,13 @@ class User extends Memcached_DataObject
function isSubscribed($other)
{
assert(!is_null($other));
- # XXX: cache results of this query
+ // XXX: cache results of this query
$sub = Subscription::pkeyGet(array('subscriber' => $this->id,
'subscribed' => $other->id));
return (is_null($sub)) ? false : true;
}
- # 'update' won't write key columns, so we have to do it ourselves.
+ // 'update' won't write key columns, so we have to do it ourselves.
function updateKeys(&$orig)
{
@@ -96,7 +99,7 @@ class User extends Memcached_DataObject
}
}
if (count($parts) == 0) {
- # No changes
+ // No changes
return true;
}
$toupdate = implode(', ', $parts);
@@ -117,7 +120,7 @@ class User extends Memcached_DataObject
function allowed_nickname($nickname)
{
- # XXX: should already be validated for size, content, etc.
+ // XXX: should already be validated for size, content, etc.
static $blacklist = array('rss', 'xrds', 'doc', 'main',
'settings', 'notice', 'user',
'search', 'avatar', 'tag', 'tags',
@@ -147,7 +150,7 @@ class User extends Memcached_DataObject
$sub->subscriber = $this->id;
$sub->subscribed = $other->id;
- $sub->created = common_sql_now(); # current time
+ $sub->created = common_sql_now(); // current time
if (!$sub->insert()) {
return false;
@@ -173,7 +176,7 @@ class User extends Memcached_DataObject
static function register($fields) {
- # MAGICALLY put fields into current scope
+ // MAGICALLY put fields into current scope
extract($fields);
@@ -211,11 +214,11 @@ class User extends Memcached_DataObject
$user->id = $id;
$user->nickname = $nickname;
- if (!empty($password)) { # may not have a password for OpenID users
+ if (!empty($password)) { // may not have a password for OpenID users
$user->password = common_munge_password($password, $id);
}
- # Users who respond to invite email have proven their ownership of that address
+ // Users who respond to invite email have proven their ownership of that address
if (!empty($code)) {
$invite = Invitation::staticGet($code);
@@ -240,7 +243,7 @@ class User extends Memcached_DataObject
return false;
}
- # Everyone is subscribed to themself
+ // Everyone is subscribed to themself
$subscription = new Subscription();
$subscription->subscriber = $user->id;
@@ -273,16 +276,58 @@ class User extends Memcached_DataObject
$user->emailChanged();
}
+ // Default system subscription
+
+ $defnick = common_config('newuser', 'default');
+
+ if (!empty($defnick)) {
+ $defuser = User::staticGet('nickname', $defnick);
+ if (empty($defuser)) {
+ common_log(LOG_WARNING, sprintf("Default user %s does not exist.", $defnick),
+ __FILE__);
+ } else {
+ $defsub = new Subscription();
+ $defsub->subscriber = $user->id;
+ $defsub->subscribed = $defuser->id;
+ $defsub->created = $user->created;
+
+ $result = $defsub->insert();
+
+ if (!$result) {
+ common_log_db_error($defsub, 'INSERT', __FILE__);
+ return false;
+ }
+ }
+ }
+
$profile->query('COMMIT');
if ($email && !$user->email) {
mail_confirm_address($user, $confirm->code, $profile->nickname, $email);
}
+ // Welcome message
+
+ $welcome = common_config('newuser', 'welcome');
+
+ if (!empty($welcome)) {
+ $welcomeuser = User::staticGet('nickname', $welcome);
+ if (empty($welcomeuser)) {
+ common_log(LOG_WARNING, sprintf("Welcome user %s does not exist.", $defnick),
+ __FILE__);
+ } else {
+ $notice = Notice::saveNew($welcomeuser->id,
+ sprintf(_('Welcome to %1$s, @%2$s!'),
+ common_config('site', 'name'),
+ $user->nickname),
+ 'system');
+ }
+ }
+
return $user;
}
- # Things we do when the email changes
+ // Things we do when the email changes
function emailChanged()
{
@@ -303,46 +348,46 @@ class User extends Memcached_DataObject
{
$cache = common_memcache();
- # XXX: Kind of a hack.
+ // XXX: Kind of a hack.
if ($cache) {
- # This is the stream of favorite notices, in rev chron
- # order. This forces it into cache.
+ // This is the stream of favorite notices, in rev chron
+ // order. This forces it into cache.
$faves = $this->favoriteNotices(0, NOTICE_CACHE_WINDOW);
$cnt = 0;
while ($faves->fetch()) {
if ($faves->id < $notice->id) {
- # If we passed it, it's not a fave
+ // If we passed it, it's not a fave
return false;
} else if ($faves->id == $notice->id) {
- # If it matches a cached notice, then it's a fave
+ // If it matches a cached notice, then it's a fave
return true;
}
$cnt++;
}
- # If we're not past the end of the cache window,
- # then the cache has all available faves, so this one
- # is not a fave.
+ // If we're not past the end of the cache window,
+ // then the cache has all available faves, so this one
+ // is not a fave.
if ($cnt < NOTICE_CACHE_WINDOW) {
return false;
}
- # Otherwise, cache doesn't have all faves;
- # fall through to the default
+ // Otherwise, cache doesn't have all faves;
+ // fall through to the default
}
$fave = Fave::pkeyGet(array('user_id' => $this->id,
'notice_id' => $notice->id));
return ((is_null($fave)) ? false : true);
}
+
function mutuallySubscribed($other)
{
return $this->isSubscribed($other) &&
$other->isSubscribed($this);
}
- function mutuallySubscribedUsers()
- {
-
- # 3-way join; probably should get cached
- $UT = common_config('db','type')=='pgsql'?'"user"':'user';
+ function mutuallySubscribedUsers()
+ {
+ // 3-way join; probably should get cached
+ $UT = common_config('db','type')=='pgsql'?'"user"':'user';
$qry = "SELECT $UT.* " .
"FROM subscription sub1 JOIN $UT ON sub1.subscribed = $UT.id " .
"JOIN subscription sub2 ON $UT.id = sub2.subscriber " .
@@ -365,8 +410,8 @@ class User extends Memcached_DataObject
$offset, $limit, $since_id, $before_id, null, $since);
}
- function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
- {
+ function getNotices($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
+ {
$profile = $this->getProfile();
if (!$profile) {
return null;
@@ -375,8 +420,8 @@ class User extends Memcached_DataObject
}
}
- function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE)
- {
+ function favoriteNotices($offset=0, $limit=NOTICES_PER_PAGE)
+ {
$qry =
'SELECT notice.* ' .
'FROM notice JOIN fave ON notice.id = fave.notice_id ' .
@@ -386,12 +431,12 @@ class User extends Memcached_DataObject
$offset, $limit);
}
- function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
- {
+ function noticesWithFriends($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0, $since=null)
+ {
$enabled = common_config('inboxes', 'enabled');
- # Complicated code, depending on whether we support inboxes yet
- # XXX: make this go away when inboxes become mandatory
+ // Complicated code, depending on whether we support inboxes yet
+ // XXX: make this go away when inboxes become mandatory
if ($enabled === false ||
($enabled == 'transitional' && $this->inboxed == 0)) {
@@ -401,13 +446,13 @@ class User extends Memcached_DataObject
'WHERE subscription.subscriber = %d ';
$order = null;
} else if ($enabled === true ||
- ($enabled == 'transitional' && $this->inboxed == 1)) {
+ ($enabled == 'transitional' && $this->inboxed == 1)) {
$qry =
'SELECT notice.* ' .
'FROM notice JOIN notice_inbox ON notice.id = notice_inbox.notice_id ' .
'WHERE notice_inbox.user_id = %d ';
- # NOTE: we override ORDER
+ // NOTE: we override ORDER
$order = null;
}
return Notice::getStream(sprintf($qry, $this->id),
@@ -416,35 +461,34 @@ class User extends Memcached_DataObject
$order, $since);
}
- function blowFavesCache()
- {
+ function blowFavesCache()
+ {
$cache = common_memcache();
if ($cache) {
- # Faves don't happen chronologically, so we need to blow
- # ;last cache, too
+ // Faves don't happen chronologically, so we need to blow
+ // ;last cache, too
$cache->delete(common_cache_key('user:faves:'.$this->id));
$cache->delete(common_cache_key('user:faves:'.$this->id).';last');
}
}
- function getSelfTags()
- {
+ function getSelfTags()
+ {
return Profile_tag::getTags($this->id, $this->id);
}
- function setSelfTags($newtags)
- {
+ function setSelfTags($newtags)
+ {
return Profile_tag::setTags($this->id, $this->id, $newtags);
}
function block($other)
{
-
- # Add a new block record
+ // Add a new block record
$block = new Profile_block();
- # Begin a transaction
+ // Begin a transaction
$block->query('BEGIN');
@@ -458,7 +502,7 @@ class User extends Memcached_DataObject
return false;
}
- # Cancel their subscription, if it exists
+ // Cancel their subscription, if it exists
$sub = Subscription::pkeyGet(array('subscriber' => $other->id,
'subscribed' => $this->id));
@@ -478,8 +522,7 @@ class User extends Memcached_DataObject
function unblock($other)
{
-
- # Get the block record
+ // Get the block record
$block = Profile_block::get($this->id, $other->id);
diff --git a/config.php.sample b/config.php.sample
index 529e86f15..d62a54fe7 100644
--- a/config.php.sample
+++ b/config.php.sample
@@ -174,3 +174,13 @@ $config['sphinx']['port'] = 3312;
#http://taguri.org/ Examples:
#$config['integration']['taguri'] = 'example.net,2008';
#$config['integration']['taguri'] = 'admin@example.net,2009-03-09'
+
+#Don't use SSL
+#$config['site']['ssl'] = 'never';
+#Use SSL only for sensitive pages (like login, password change)
+#$config['site']['ssl'] = 'sometimes';
+#Use SSL for all pages
+#$config['site']['ssl'] = 'always';
+
+#Use a different hostname for SSL-encrypted pages
+#$config['site']['sslserver'] = 'secure.example.org';
diff --git a/db/notice_source.sql b/db/notice_source.sql
index 5e2d413c0..d28a09383 100644
--- a/db/notice_source.sql
+++ b/db/notice_source.sql
@@ -19,6 +19,7 @@ VALUES
('identichat','identichat','http://identichat.prosody.im/', now()),
('identitwitch','IdentiTwitch','http://richfish.org/identitwitch/', now()),
('mbpidgin','mbpidgin','http://code.google.com/p/microblog-purple/', now()),
+ ('Mobidentica', 'Mobidentica', 'http://www.substanceofcode.com/software/mobidentica/', now()),
('moconica','Moconica','http://moconica.com/', now()),
('pocketwit','PockeTwit','http://code.google.com/p/pocketwit/', now()),
('posty','Posty','http://spreadingfunkyness.com/posty/', now()),
@@ -44,4 +45,4 @@ VALUES
('twitux','Twitux','http://live.gnome.org/DanielMorales/Twitux', now()),
('twitvim','TwitVim','http://vim.sourceforge.net/scripts/script.php?script_id=2204', now()),
('urfastr','urfastr','http://urfastr.net/', now()),
- ('adium', 'Adium', 'http://www.adiumx.com/', now()));
+ ('adium', 'Adium', 'http://www.adiumx.com/', now());
diff --git a/js/util.js b/js/util.js
index 3ad038612..81139744f 100644
--- a/js/util.js
+++ b/js/util.js
@@ -161,6 +161,7 @@ $(document).ready(function(){
$("#form_notice").addClass("warning");
return false;
}
+ $("#form_notice").addClass("processing");
$("#notice_action-submit").attr("disabled", "disabled");
$("#notice_action-submit").addClass("disabled");
return true;
@@ -179,6 +180,7 @@ $(document).ready(function(){
NoticeHover();
NoticeReply();
}
+ $("#form_notice").removeClass("processing");
$("#notice_action-submit").removeAttr("disabled");
$("#notice_action-submit").removeClass("disabled");
}
diff --git a/lib/action.php b/lib/action.php
index 975c2bfcb..f0baa062c 100644
--- a/lib/action.php
+++ b/lib/action.php
@@ -112,6 +112,7 @@ class Action extends HTMLOutputter // lawsuit
// XXX: attributes (profile?)
$this->elementStart('head');
$this->showTitle();
+ $this->showShortcutIcon();
$this->showStylesheets();
$this->showScripts();
$this->showOpenSearch();
@@ -148,6 +149,32 @@ class Action extends HTMLOutputter // lawsuit
}
/**
+ * Show themed shortcut icon
+ *
+ * @return nothing
+ */
+ function showShortcutIcon()
+ {
+ if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/favicon.ico')) {
+ $this->element('link', array('rel' => 'shortcut icon',
+ 'href' => theme_path('favicon.ico')));
+ } else {
+ $this->element('link', array('rel' => 'shortcut icon',
+ 'href' => common_path('favicon.ico')));
+ }
+
+ if (common_config('site', 'mobile')) {
+ if (is_readable(INSTALLDIR . '/theme/' . common_config('site', 'theme') . '/apple-touch-icon.png')) {
+ $this->element('link', array('rel' => 'apple-touch-icon',
+ 'href' => theme_path('apple-touch-icon.png')));
+ } else {
+ $this->element('link', array('rel' => 'apple-touch-icon',
+ 'href' => common_path('apple-touch-icon.png')));
+ }
+ }
+ }
+
+ /**
* Show stylesheets
*
* @return nothing
diff --git a/lib/common.php b/lib/common.php
index 1ca9e521b..c2037c3ad 100644
--- a/lib/common.php
+++ b/lib/common.php
@@ -87,6 +87,8 @@ $config =
'closed' => false,
'inviteonly' => false,
'private' => false,
+ 'ssl' => 'never',
+ 'sslserver' => null,
'dupelimit' => 60), # default for same person saying the same thing
'syslog' =>
array('appname' => 'laconica', # for syslog
@@ -151,6 +153,9 @@ $config =
array('notify' => array()),
'inboxes' =>
array('enabled' => true), # on by default for new sites
+ 'newuser' =>
+ array('subscribe' => null,
+ 'welcome' => null),
);
$config['db'] = &PEAR::getStaticProperty('DB_DataObject','options');
diff --git a/lib/jabber.php b/lib/jabber.php
index 3cd3b0d37..7d584ad01 100644
--- a/lib/jabber.php
+++ b/lib/jabber.php
@@ -163,50 +163,25 @@ function jabber_send_notice($to, $notice)
function jabber_format_entry($profile, $notice)
{
- // FIXME: notice url might be remote
-
- $noticeurl = common_local_url('shownotice',
- array('notice' => $notice->id));
-
- $msg = jabber_format_notice($profile, $notice);
-
- $self_url = common_local_url('userrss', array('nickname' => $profile->nickname));
-
- $entry = "\n<entry xmlns='http://www.w3.org/2005/Atom'>\n";
- $entry .= "<source>\n";
- $entry .= "<title>" . $profile->nickname . " - " . common_config('site', 'name') . "</title>\n";
- $entry .= "<link href='" . htmlspecialchars($profile->profileurl) . "'/>\n";
- $entry .= "<link rel='self' type='application/rss+xml' href='" . $self_url . "'/>\n";
- $entry .= "<author><name>" . $profile->nickname . "</name></author>\n";
- $entry .= "<icon>" . $profile->avatarUrl(AVATAR_PROFILE_SIZE) . "</icon>\n";
- $entry .= "</source>\n";
- $entry .= "<title>" . htmlspecialchars($msg) . "</title>\n";
- $entry .= "<summary>" . htmlspecialchars($msg) . "</summary>\n";
- $entry .= "<link rel='alternate' href='" . $noticeurl . "' />\n";
- $entry .= "<id>". $notice->uri . "</id>\n";
- $entry .= "<published>".common_date_w3dtf($notice->created)."</published>\n";
- $entry .= "<updated>".common_date_w3dtf($notice->modified)."</updated>\n";
- if ($notice->reply_to) {
- $replyurl = common_local_url('shownotice',
- array('notice' => $notice->reply_to));
- $entry .= "<link rel='related' href='" . $replyurl . "'/>\n";
+ $entry = $notice->asAtomEntry(true, true);
+
+ $xs = new XMLStringer();
+ $xs->elementStart('html', array('xmlns' => 'http://jabber.org/protocol/xhtml-im'));
+ $xs->elementStart('body', array('xmlns' => 'http://www.w3.org/1999/xhtml'));
+ $xs->element('a', array('href' => $profile->profileurl),
+ $profile->nickname);
+ $xs->text(": ");
+ if (!empty($notice->rendered)) {
+ $xs->raw($notice->rendered);
+ } else {
+ $xs->raw(common_render_content($notice->content, $notice));
}
- $entry .= "</entry>\n";
-
- $html = "\n<html xmlns='http://jabber.org/protocol/xhtml-im'>\n";
- $html .= "<body xmlns='http://www.w3.org/1999/xhtml'>\n";
- $html .= "<a href='".htmlspecialchars($profile->profileurl)."'>".$profile->nickname."</a>: ";
- $html .= ($notice->rendered) ? $notice->rendered : common_render_content($notice->content, $notice);
- $html .= "\n</body>\n";
- $html .= "\n</html>\n";
-
- $address = "<addresses xmlns='http://jabber.org/protocol/address'>\n";
- $address .= "<address type='replyto' jid='" . jabber_daemon_address() . "' />\n";
- $address .= "</addresses>\n";
+ $xs->elementEnd('body');
+ $xs->elementEnd('html');
- // FIXME: include a pubsub event, too.
+ $html = $xs->getString();
- return $html . $entry . $address;
+ return $html . ' ' . $entry;
}
/**
diff --git a/lib/language.php b/lib/language.php
index 6791df699..cd6498d30 100644
--- a/lib/language.php
+++ b/lib/language.php
@@ -115,7 +115,7 @@ function get_all_languages() {
'he' => array('q' => 0.5, 'lang' => 'he_IL', 'name' => 'Hebrew', 'direction' => 'rtl'),
'it' => array('q' => 1, 'lang' => 'it_IT', 'name' => 'Italian', 'direction' => 'ltr'),
'jp' => array('q' => 0.5, 'lang' => 'ja_JP', 'name' => 'Japanese', 'direction' => 'ltr'),
- 'ko' => array('q' => 0.9, 'lang' => 'ko', 'name' => 'Korean', 'direction' => 'ltr'),
+ 'ko' => array('q' => 0.9, 'lang' => 'ko_KR', 'name' => 'Korean', 'direction' => 'ltr'),
'mk' => array('q' => 0.5, 'lang' => 'mk_MK', 'name' => 'Macedonian', 'direction' => 'ltr'),
'nb' => array('q' => 0.1, 'lang' => 'nb_NO', 'name' => 'Norwegian (Bokmål)', 'direction' => 'ltr'),
'no' => array('q' => 0.1, 'lang' => 'nb_NO', 'name' => 'Norwegian (Bokmål)', 'direction' => 'ltr'),
diff --git a/lib/logingroupnav.php b/lib/logingroupnav.php
index fd909581f..f23985f3a 100644
--- a/lib/logingroupnav.php
+++ b/lib/logingroupnav.php
@@ -70,16 +70,16 @@ class LoginGroupNav extends Widget
function show()
{
// action => array('prompt', 'title')
- $menu =
- array('login' =>
- array(_('Login'),
- _('Login with a username and password')),
- 'register' =>
- array(_('Register'),
- _('Sign up for a new account')),
- 'openidlogin' =>
- array(_('OpenID'),
- _('Login or register with OpenID')));
+ $menu = array();
+
+ $menu['login'] = array(_('Login'),
+ _('Login with a username and password'));
+ if (!(common_config('site','closed') || common_config('site','inviteonly'))) {
+ $menu['register'] = array(_('Register'),
+ _('Sign up for a new account'));
+ }
+ $menu['openidlogin'] = array(_('OpenID'),
+ _('Login or register with OpenID'));
$action_name = $this->action->trimmed('action');
$this->action->elementStart('ul', array('class' => 'nav'));
diff --git a/lib/messageform.php b/lib/messageform.php
index f41508305..b8878ec1f 100644
--- a/lib/messageform.php
+++ b/lib/messageform.php
@@ -132,20 +132,14 @@ class MessageForm extends Form
$mutual_users->free();
unset($mutual_users);
- $this->out->elementStart('ul', 'form_data');
- $this->out->elementStart('li', array('id' => 'notice_to'));
$this->out->dropdown('to', _('To'), $mutual, null, false,
($this->to) ? $this->to->id : null);
- $this->out->elementEnd('li');
- $this->out->elementStart('li', array('id' => 'notice_text'));
$this->out->element('textarea', array('id' => 'notice_data-text',
'cols' => 35,
'rows' => 4,
'name' => 'content'),
($this->content) ? $this->content : '');
- $this->out->elementEnd('li');
- $this->out->elementEnd('ul');
}
/**
@@ -156,14 +150,10 @@ class MessageForm extends Form
function formActions()
{
- $this->out->elementStart('ul', 'form_actions');
- $this->out->elementStart('li', array('id' => 'notice_submit'));
$this->out->element('input', array('id' => 'notice_action-submit',
'class' => 'submit',
'name' => 'message_send',
'type' => 'submit',
'value' => _('Send')));
- $this->out->elementEnd('li');
- $this->out->elementEnd('ul');
}
}
diff --git a/lib/noticeform.php b/lib/noticeform.php
index 0c991c969..606b5d028 100644
--- a/lib/noticeform.php
+++ b/lib/noticeform.php
@@ -134,9 +134,6 @@ class NoticeForm extends Form
function formData()
{
-
- $this->out->elementStart('ul', 'form_data');
- $this->out->elementStart('li', array('id' => 'notice_text'));
$this->out->element('label', array('for' => 'notice_data-text'),
sprintf(_('What\'s up, %s?'), $this->user->nickname));
// XXX: vary by defined max size
@@ -145,8 +142,6 @@ class NoticeForm extends Form
'rows' => 4,
'name' => 'status_textarea'),
($this->content) ? $this->content : '');
- $this->out->elementEnd('li');
- $this->out->elementEnd('ul');
$this->out->elementStart('dl', 'form_note');
$this->out->element('dt', null, _('Available characters'));
@@ -168,14 +163,10 @@ class NoticeForm extends Form
function formActions()
{
- $this->out->elementStart('ul', 'form_actions');
- $this->out->elementStart('li', array('id' => 'notice_submit'));
$this->out->element('input', array('id' => 'notice_action-submit',
'class' => 'submit',
'name' => 'status_submit',
'type' => 'submit',
'value' => _('Send')));
- $this->out->elementEnd('li');
- $this->out->elementEnd('ul');
}
}
diff --git a/lib/noticelist.php b/lib/noticelist.php
index 8523f2e63..4182d8808 100644
--- a/lib/noticelist.php
+++ b/lib/noticelist.php
@@ -391,6 +391,7 @@ class NoticeListItem extends Widget
case 'xmpp':
case 'mail':
case 'omb':
+ case 'system':
case 'api':
$this->out->element('dd', null, $source_name);
break;
diff --git a/lib/router.php b/lib/router.php
index 135e07a0f..ae5b5e16b 100644
--- a/lib/router.php
+++ b/lib/router.php
@@ -68,8 +68,8 @@ class Router
}
}
- function initialize() {
-
+ function initialize()
+ {
$m = Net_URL_Mapper::getInstance();
// In the "root"
@@ -136,10 +136,17 @@ class Router
foreach (array('group', 'people', 'notice') as $s) {
$m->connect('search/'.$s, array('action' => $s.'search'));
- $m->connect('search/'.$s.'?q=:q', array('action' => $s.'search'), array('q' => '.+'));
+ $m->connect('search/'.$s.'?q=:q',
+ array('action' => $s.'search'),
+ array('q' => '.+'));
}
+ // The second of these is needed to make the link work correctly
+ // when inserted into the page. The first is needed to match the
+ // route on the way in. Seems to be another Net_URL_Mapper bug to me.
$m->connect('search/notice/rss', array('action' => 'noticesearchrss'));
+ $m->connect('search/notice/rss?q=:q', array('action' => 'noticesearchrss'),
+ array('q' => '.+'));
// notice
@@ -259,8 +266,8 @@ class Router
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
$m->connect('api/direct_messages/sent.'.$e,
array('action' => 'api',
- 'apiaction' => 'direct_messages',
- 'method' => 'sent.'.$e));
+ 'apiaction' => 'direct_messages',
+ 'method' => 'sent.'.$e));
}
$m->connect('api/direct_messages/destroy/:argument',
@@ -324,9 +331,9 @@ class Router
foreach (array('xml', 'json', 'rss', 'atom') as $e) {
$m->connect('api/favorites.'.$e,
- array('action' => 'api',
- 'apiaction' => 'favorites',
- 'method' => 'favorites.'.$e));
+ array('action' => 'api',
+ 'apiaction' => 'favorites',
+ 'method' => 'favorites.'.$e));
}
// notifications
@@ -411,7 +418,7 @@ class Router
$match = $this->m->match($path);
} catch (Net_URL_Mapper_InvalidException $e) {
common_log(LOG_ERR, "Problem getting route for $path - " .
- $e->getMessage());
+ $e->getMessage());
$cac = new ClientErrorAction("Page not found.", 404);
$cac->showPage();
}
@@ -434,10 +441,11 @@ class Router
// Due to a bug in the Net_URL_Mapper code, the returned URL may
// contain a malformed query of the form ?p1=v1?p2=v2?p3=v3. We
// repair that here rather than modifying the upstream code...
- $qpos = strpos($url,'?');
+
+ $qpos = strpos($url, '?');
if ($qpos !== false) {
$url = substr($url, 0, $qpos+1) .
- str_replace('?', '&', substr($url, $qpos+1));
+ str_replace('?', '&', substr($url, $qpos+1));
}
return $url;
}
diff --git a/lib/rssaction.php b/lib/rssaction.php
index 66c2d9e8c..ddba862dc 100644
--- a/lib/rssaction.php
+++ b/lib/rssaction.php
@@ -94,11 +94,11 @@ class Rss10Action extends Action
function handle($args)
{
- // Get the list of notices
- $this->notices = $this->getNotices();
// Parent handling, including cache check
parent::handle($args);
- $this->showRss($this->limit);
+ // Get the list of notices
+ $this->notices = $this->getNotices($this->limit);
+ $this->showRss();
}
/**
@@ -132,15 +132,13 @@ class Rss10Action extends Action
return null;
}
- function showRss($limit=0)
+ function showRss()
{
- $notices = $this->getNotices($limit);
-
$this->initRss();
- $this->showChannel($notices);
+ $this->showChannel();
$this->showImage();
- foreach ($notices as $n) {
+ foreach ($this->notices as $n) {
$this->showItem($n);
}
@@ -148,7 +146,7 @@ class Rss10Action extends Action
$this->endRss();
}
- function showChannel($notices)
+ function showChannel()
{
$channel = $this->getChannel();
@@ -167,7 +165,7 @@ class Rss10Action extends Action
$this->elementStart('items');
$this->elementStart('rdf:Seq');
- foreach ($notices as $notice) {
+ foreach ($this->notices as $notice) {
$this->element('sioct:MicroblogPost', array('rdf:resource' => $notice->uri));
}
diff --git a/lib/twitterapi.php b/lib/twitterapi.php
index e7239acd5..b8357c688 100644
--- a/lib/twitterapi.php
+++ b/lib/twitterapi.php
@@ -238,21 +238,6 @@ class TwitterapiAction extends Action
$this->elementEnd('item');
}
- function show_twitter_atom_entry($entry)
- {
- $this->elementStart('entry');
- $this->element('title', null, $entry['title']);
- $this->element('content', array('type' => 'html'), $entry['content']);
- $this->element('id', null, $entry['id']);
- $this->element('published', null, $entry['published']);
- $this->element('updated', null, $entry['updated']);
- $this->element('link', array('href' => $entry['link'], 'rel' => 'alternate', 'type' => 'text/html'), null);
- $this->elementStart('author');
- $this->element('name', null, $entry['author']);
- $this->elementEnd('author');
- $this->elementEnd('entry');
- }
-
function show_json_objects($objects)
{
print(json_encode($objects));
@@ -383,7 +368,7 @@ class TwitterapiAction extends Action
}
if (!is_null($selfuri)) {
- $this->element('link', array('href' => $selfuri,
+ $this->element('link', array('href' => $selfuri,
'rel' => 'self', 'type' => 'application/atom+xml'), null);
}
@@ -392,13 +377,11 @@ class TwitterapiAction extends Action
if (is_array($notice)) {
foreach ($notice as $n) {
- $entry = $this->twitter_rss_entry_array($n);
- $this->show_twitter_atom_entry($entry);
+ $this->raw($n->asAtomEntry());
}
} else {
while ($notice->fetch()) {
- $entry = $this->twitter_rss_entry_array($notice);
- $this->show_twitter_atom_entry($entry);
+ $this->raw($notice->asAtomEntry());
}
}
@@ -578,13 +561,16 @@ class TwitterapiAction extends Action
function init_twitter_atom()
{
$this->startXML();
- $this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom', 'xml:lang' => 'en-US'));
+ // FIXME: don't hardcode the language here!
+ $this->elementStart('feed', array('xmlns' => 'http://www.w3.org/2005/Atom',
+ 'xml:lang' => 'en-US',
+ 'xmlns:thr' => 'http://purl.org/syndication/thread/1.0'));
}
function end_twitter_atom()
{
- $this->endXML();
$this->elementEnd('feed');
+ $this->endXML();
}
function show_profile($profile, $content_type='xml', $notice=null)
diff --git a/lib/util.php b/lib/util.php
index ef73adc36..fdcae0aca 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -721,25 +721,46 @@ function common_relative_profile($sender, $nickname, $dt=null)
function common_local_url($action, $args=null, $params=null, $fragment=null)
{
+ static $sensitive = array('login', 'register', 'passwordsettings',
+ 'twittersettings', 'finishopenidlogin',
+ 'api');
+
$r = Router::get();
$path = $r->build($action, $args, $params, $fragment);
+ $ssl = in_array($action, $sensitive);
+
if (common_config('site','fancy')) {
- $url = common_path(mb_substr($path, 1));
+ $url = common_path(mb_substr($path, 1), $ssl);
} else {
if (mb_strpos($path, '/index.php') === 0) {
- $url = common_path(mb_substr($path, 1));
+ $url = common_path(mb_substr($path, 1), $ssl);
} else {
- $url = common_path('index.php'.$path);
+ $url = common_path('index.php'.$path, $ssl);
}
}
return $url;
}
-function common_path($relative)
+function common_path($relative, $ssl=false)
{
$pathpart = (common_config('site', 'path')) ? common_config('site', 'path')."/" : '';
- return "http://".common_config('site', 'server').'/'.$pathpart.$relative;
+
+ if (($ssl && (common_config('site', 'ssl') === 'sometimes'))
+ || common_config('site', 'ssl') === 'always') {
+ $proto = 'https';
+ if (is_string(common_config('site', 'sslserver')) &&
+ mb_strlen(common_config('site', 'sslserver')) > 0) {
+ $serverpart = common_config('site', 'sslserver');
+ } else {
+ $serverpart = common_config('site', 'server');
+ }
+ } else {
+ $proto = 'http';
+ $serverpart = common_config('site', 'server');
+ }
+
+ return $proto.'://'.$serverpart.'/'.$pathpart.$relative;
}
function common_date_string($dt)
diff --git a/plugins/LinkbackPlugin.php b/plugins/LinkbackPlugin.php
index 1b5365100..56a26176b 100644
--- a/plugins/LinkbackPlugin.php
+++ b/plugins/LinkbackPlugin.php
@@ -105,12 +105,13 @@ class LinkbackPlugin extends Plugin
$pb = $match[1];
}
- $tb = $this->getTrackback($result->body, $result->final_url);
-
- if (!empty($tb)) {
- $this->trackback($result->final_url, $tb);
- } else if (!empty($pb)) {
+ if (!empty($pb)) {
$this->pingback($result->final_url, $pb);
+ } else {
+ $tb = $this->getTrackback($result->body, $result->final_url);
+ if (!empty($tb)) {
+ $this->trackback($result->final_url, $tb);
+ }
}
return $orig;
diff --git a/plugins/PiwikAnalyticsPlugin.php b/plugins/PiwikAnalyticsPlugin.php
new file mode 100644
index 000000000..d2c52354e
--- /dev/null
+++ b/plugins/PiwikAnalyticsPlugin.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Laconica, the distributed open-source microblogging tool
+ *
+ * Plugin to use Piwik Analytics
+ *
+ * PHP version 5
+ *
+ * LICENCE: 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/>.
+ *
+ * @category Plugin
+ * @package Laconica
+ * @author Evan Prodromou <evan@controlyourself.ca>
+ * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
+ * @copyright 2008 Control Yourself, Inc.
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://laconi.ca/
+ */
+
+if (!defined('LACONICA')) {
+ exit(1);
+}
+
+/**
+ * Plugin to use Piwik Analytics (based on the Google Analytics plugin by Evan)
+ *
+ * This plugin will spoot out the correct JavaScript spell to invoke
+ * Piwik Analytics on a page.
+ *
+ * To use this plugin please add the following three lines to your config.php
+ *
+ * require_once('plugins/PiwikAnalyticsPlugin.php');
+ * $pa = new PiwikAnalyticsPlugin("example.com/piwik/","id");
+ *
+ * exchange example.com/piwik/ with the url to your piwik installation and
+ * make sure you don't forget the final /
+ * exchange id with the ID your laconica installation has in your Piwik analytics
+ *
+ * @category Plugin
+ * @package Laconica
+ * @author Tobias Diekershoff <tobias.diekershoff@gmx.net>
+ * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
+ * @link http://laconi.ca/
+ *
+ * @see Event
+ */
+
+class PiwikAnalyticsPlugin extends Plugin
+{
+ /** the base of your Piwik installation */
+ var $piwikroot = null;
+ /** the Piwik Id of your laconica installation */
+ var $piwikId = null;
+
+ /**
+ * constructor
+ *
+ * @param string $root Piwik root URL
+ * @param string $id Piwik ID of this app
+ */
+
+ function __construct($root=null, $id=null)
+ {
+ $this->piwikroot = $root;
+ $this->piwikid = $id;
+ parent::__construct();
+ }
+
+ /**
+ * Called when all scripts have been shown
+ *
+ * @param Action $action Current action
+ *
+ * @return boolean ignored
+ */
+
+ function onEndShowScripts($action)
+ {
+ $js1 = 'var pkBaseURL = (("https:" == document.location.protocol) ? "https://'.
+ $this->piwikroot.'" : "http://'.$this->piwikroot.
+ '"); document.write(unescape("%3Cscript src=\'" + pkBaseURL + "piwik.js\''.
+ ' type=\'text/javascript\'%3E%3C/script%3E"));';
+ $js2 = 'piwik_action_name = ""; piwik_idsite = '.$this->piwikid.
+ '; piwik_url = pkBaseURL + "piwik.php"; piwik_log(piwik_action_name, piwik_idsite, piwik_url);';
+ $action->elementStart('script', array('type' => 'text/javascript'));
+ $action->raw($js1);
+ $action->elementEnd('script');
+ $action->elementStart('script', array('type' => 'text/javascript'));
+ $action->raw($js2);
+ $action->elementEnd('script');
+ return true;
+ }
+} \ No newline at end of file
diff --git a/theme/base/css/display.css b/theme/base/css/display.css
index c741ed4cb..997342429 100644
--- a/theme/base/css/display.css
+++ b/theme/base/css/display.css
@@ -150,7 +150,9 @@ font-weight:bold;
#form_openid_login legend,
#form_search legend,
#form_invite legend,
-#form_notice_delete legend {
+#form_notice_delete legend,
+#form_password_recover legend,
+#form_password_change legend {
display:none;
}
@@ -214,6 +216,9 @@ margin-right:0;
address .fn {
font-weight:bold;
}
+address img + .fn {
+display:none;
+}
#header {
width:100%;
@@ -419,6 +424,7 @@ padding:0;
display:none;
}
#form_notice textarea {
+float:left;
border-radius:7px;
-moz-border-radius:7px;
-webkit-border-radius:7px;
@@ -429,30 +435,19 @@ padding:7px 7px 16px 7px;
}
#form_notice label {
display:block;
+float:left;
font-size:1.3em;
margin-bottom:7px;
}
-#form_notice .form_data li {
-float:left;
-}
-
-#form_notice #notice_attach_file label,
#form_notice #notice_submit label {
display:none;
}
-
-#form_notice #notice_attachment {
-margin-top:25px;
-margin-left:4px;
-}
-
#form_notice .form_note {
position:absolute;
top:99px;
right:98px;
z-index:9;
}
-
#form_notice .form_note dt {
font-weight:bold;
display:none;
@@ -462,42 +457,19 @@ font-weight:bold;
line-height:1.15;
padding:1px 2px;
}
-
-#form_notice #notice_data-attach_view {
-position:absolute;
-top:25px;
-right:30px;
-margin-left:4px;
-padding:0;
-width:16px;
-height:16px;
-border:0;
-text-indent:-9999px;
-}
-#form_notice .form_actions {
+#form_notice #notice_action-submit {
+width:60px;
+padding:8px;
position:absolute;
bottom:0;
right:0;
}
-#form_notice .form_actions input.submit {
-width:60px;
-padding:8px;
-}
-
-#form_notice li {
-margin-bottom:0;
-}
-
-#form_notice #notice_to {
-margin-bottom:7px;
-}
-
-#notice_to label {
-float:left;
-margin-right:18px;
+#form_notice label[for=to] {
margin-top:11px;
}
-#notice_to select {
+#form_notice select[id=to] {
+margin-bottom:7px;
+margin-left:18px;
float:left;
}
/*end FORM NOTICE*/
diff --git a/theme/base/css/ie6.css b/theme/base/css/ie6.css
index 10b31cbcb..fa6ec92d2 100644
--- a/theme/base/css/ie6.css
+++ b/theme/base/css/ie6.css
@@ -9,3 +9,6 @@ margin-left:0;
.entity_profile .entity_depiction {
margin-bottom:123px;
}
+.notice div.entry-content {
+width:63%;
+}
diff --git a/theme/base/images/icons/icon_processing.gif b/theme/base/images/icons/icon_processing.gif
new file mode 100644
index 000000000..d0bce1542
--- /dev/null
+++ b/theme/base/images/icons/icon_processing.gif
Binary files differ
diff --git a/theme/default/css/display.css b/theme/default/css/display.css
index 85b5aa13e..12303dd68 100644
--- a/theme/default/css/display.css
+++ b/theme/default/css/display.css
@@ -19,9 +19,6 @@ font-size:1em;
address {
margin-right:71px;
}
-address .fn {
-display:none;
-}
input, textarea, select, option {
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
@@ -94,6 +91,11 @@ color:#333;
#form_notice.warning #notice_text-count {
color:#000;
}
+#form_notice.processing #notice_action-submit {
+background:#fff url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%;
+cursor:wait;
+text-indent:-9999px;
+}
#nav_register a {
diff --git a/theme/identica/css/display.css b/theme/identica/css/display.css
index 576a2e14b..5235c34a4 100644
--- a/theme/identica/css/display.css
+++ b/theme/identica/css/display.css
@@ -19,9 +19,6 @@ font-size:1em;
address {
margin-right:71px;
}
-address .fn {
-display:none;
-}
input, textarea, select, option {
font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
@@ -94,7 +91,11 @@ color:#333;
#form_notice.warning #notice_text-count {
color:#000;
}
-
+#form_notice.processing #notice_action-submit {
+background:#fff url(../../base/images/icons/icon_processing.gif) no-repeat 47% 47%;
+cursor:wait;
+text-indent:-9999px;
+}
#nav_register a {
text-decoration:none;