We are no longer offering accounts on this server. Consider https://gitlab.freedesktop.org/ as a place to host projects.

Commit f47027ab authored by Shashi Gowda's avatar Shashi Gowda

Merge remote-tracking branch 'mainline/1.0.x' into people_tags_rebase

Conflicts:
	lib/profileblock.php
	theme/default/css/display.css
parents a0ac51c2 285c2ee7
......@@ -1297,3 +1297,19 @@ StartDefaultLocalNav: When showing the default local nav
EndDefaultLocalNav: When showing the default local nav
- $menu: the menu
- $user: current user
StartShowAccountProfileBlock: When showing the profile block for an account
- $out: XMLOutputter to append custom output
- $profile: the profile being shown
EndShowAccountProfileBlock: After showing the profile block for an account
- $out: XMLOutputter to append custom output
- $profile: the profile being shown
StartShowGroupProfileBlock: When showing the profile block for a group
- $out: XMLOutputter to append custom output
- $profile: the profile being shown
EndShowGroupProfileBlock: After showing showing the profile block for a group
- $out: XMLOutputter to append custom output
- $group: the group being shown
......@@ -47,8 +47,11 @@ require_once INSTALLDIR.'/lib/noticelist.php';
*/
class ConversationAction extends Action
{
var $id = null;
var $page = null;
var $id = null;
var $page = null;
var $notices = null;
const MAX_NOTICES = 500;
/**
* Initialization.
......@@ -69,6 +72,19 @@ class ConversationAction extends Action
if (empty($this->page)) {
$this->page = 1;
}
$cur = common_current_user();
if (empty($cur)) {
$profile = null;
} else {
$profile = $cur->getProfile();
}
$stream = new ConversationNoticeStream($this->id, $profile);
$this->notices = $stream->getNotices(0, self::MAX_NOTICES, null, null);
return true;
}
......@@ -106,11 +122,9 @@ class ConversationAction extends Action
*/
function showContent()
{
$notices = Notice::conversationStream($this->id, null, null);
$tnl = new ThreadedNoticeList($this->notices, $this);
$ct = new ConversationTree($notices, $this);
$cnt = $ct->show();
$cnt = $tnl->show();
}
function isReadOnly()
......@@ -118,173 +132,3 @@ class ConversationAction extends Action
return true;
}
}
/**
* Conversation tree
*
* The widget class for displaying a hierarchical list of notices.
*
* @category Widget
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*/
class ConversationTree extends NoticeList
{
var $tree = null;
var $table = null;
/**
* Show the tree of notices
*
* @return void
*/
function show()
{
$cnt = $this->_buildTree();
$this->out->elementStart('div', array('id' =>'notices_primary'));
// TRANS: Header on conversation page. Hidden by default (h2).
$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()
{
$cnt = 0;
$this->tree = array();
$this->table = array();
while ($this->notice->fetch()) {
$cnt++;
$id = $this->notice->id;
$notice = clone($this->notice);
$this->table[$id] = $notice;
if (is_null($notice->reply_to)) {
$this->tree['root'] = array($notice->id);
} else if (array_key_exists($notice->reply_to, $this->tree)) {
$this->tree[$notice->reply_to][] = $notice->id;
} else {
$this->tree[$notice->reply_to] = array($notice->id);
}
}
return $cnt;
}
/**
* Shows a notice plus its list of children.
*
* @param integer $id ID of the notice to show
*
* @return void
*/
function showNoticePlus($id)
{
$notice = $this->table[$id];
// We take responsibility for doing the li
$this->out->elementStart('li', array('class' => 'hentry notice',
'id' => 'notice-' . $id));
$item = $this->newListItem($notice);
$item->show();
if (array_key_exists($id, $this->tree)) {
$children = $this->tree[$id];
$this->out->elementStart('ol', array('class' => 'notices'));
sort($children);
foreach ($children as $child) {
$this->showNoticePlus($child);
}
$this->out->elementEnd('ol');
}
$this->out->elementEnd('li');
}
/**
* Override parent class to return our preferred item.
*
* @param Notice $notice Notice to display
*
* @return NoticeListItem a list item to show
*/
function newListItem($notice)
{
return new ConversationTreeItem($notice, $this->out);
}
}
/**
* Conversation tree list item
*
* Special class of NoticeListItem for use inside conversation trees.
*
* @category Widget
* @package StatusNet
* @author Evan Prodromou <evan@status.net>
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
* @link http://status.net/
*/
class ConversationTreeItem extends NoticeListItem
{
/**
* start a single notice.
*
* The default creates the <li>; we skip, since the ConversationTree
* takes care of that.
*
* @return void
*/
function showStart()
{
return;
}
/**
* finish the notice
*
* The default closes the <li>; we skip, since the ConversationTree
* takes care of that.
*
* @return void
*/
function showEnd()
{
return;
}
/**
* show link to notice conversation page
*
* Since we're only used on the conversation page, we skip this
*
* @return void
*/
function showContext()
{
return;
}
}
......@@ -66,9 +66,7 @@ class ConversationRepliesAction extends ConversationAction
*/
function showContent()
{
$notices = Notice::conversationStream($this->id, null, null);
$ct = new FullThreadedNoticeList($notices, $this);
$ct = new FullThreadedNoticeList($this->notices, $this);
$cnt = $ct->show();
}
......
......@@ -96,17 +96,21 @@ class Notice extends Memcached_DataObject
const GROUP_SCOPE = 4;
const FOLLOWER_SCOPE = 8;
protected $_profile = -1;
function getProfile()
{
$profile = Profile::staticGet('id', $this->profile_id);
if ($this->_profile == -1) {
$this->_profile = Profile::staticGet('id', $this->profile_id);
if (empty($profile)) {
// TRANS: Server exception thrown when a user profile for a notice cannot be found.
// TRANS: %1$d is a profile ID (number), %2$d is a notice ID (number).
throw new ServerException(sprintf(_('No such profile (%1$d) for notice (%2$d).'), $this->profile_id, $this->id));
if (empty($this->_profile)) {
// TRANS: Server exception thrown when a user profile for a notice cannot be found.
// TRANS: %1$d is a profile ID (number), %2$d is a notice ID (number).
throw new ServerException(sprintf(_('No such profile (%1$d) for notice (%2$d).'), $this->profile_id, $this->id));
}
}
return $profile;
return $this->_profile;
}
function delete()
......
......@@ -52,9 +52,15 @@ class Profile extends Memcached_DataObject
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
protected $_user = -1; // Uninitialized value distinct from null
function getUser()
{
return User::staticGet('id', $this->id);
if ($this->_user == -1) {
$this->_user = User::staticGet('id', $this->id);
}
return $this->_user;
}
function getAvatar($width, $height=null)
......@@ -667,34 +673,6 @@ class Profile extends Memcached_DataObject
function hasFave($notice)
{
$cache = Cache::instance();
// XXX: Kind of a hack.
if (!empty($cache)) {
// This is the stream of favorite notices, in rev chron
// order. This forces it into cache.
$ids = Fave::idStream($this->id, 0, CachingNoticeStream::CACHE_WINDOW);
// If it's in the list, then it's a fave
if (in_array($notice->id, $ids)) {
return true;
}
// 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 (count($ids) < CachingNoticeStream::CACHE_WINDOW) {
return false;
}
// 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);
......
......@@ -73,16 +73,21 @@ class User extends Memcached_DataObject
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
protected $_profile = -1;
/**
* @return Profile
*/
function getProfile()
{
$profile = Profile::staticGet('id', $this->id);
if (empty($profile)) {
throw new UserNoProfileException($this);
if ($this->_profile == -1) { // invalid but distinct from null
$this->_profile = Profile::staticGet('id', $this->id);
if (empty($this->_profile)) {
throw new UserNoProfileException($this);
}
}
return $profile;
return $this->_profile;
}
function isSubscribed($other)
......
......@@ -307,4 +307,14 @@ class AccountProfileBlock extends ProfileBlock
// TRANS: Link text for link that will subscribe to a remote profile.
_m('BUTTON','Subscribe'));
}
function show()
{
$this->out->elementStart('div', 'account_profile_block section');
if (Event::handle('StartShowAccountProfileBlock', array($this->out, $this->profile))) {
parent::show();
Event::handle('EndShowAccountProfileBlock', array($this->out, $this->profile));
}
$this->out->elementEnd('div');
}
}
......@@ -46,10 +46,11 @@ if (!defined('STATUSNET')) {
*/
class ConversationNoticeStream extends ScopingNoticeStream
{
function __construct($id)
function __construct($id, $profile = null)
{
parent::__construct(new CachingNoticeStream(new RawConversationNoticeStream($id),
'notice:conversation_ids:'.$id));
'notice:conversation_ids:'.$id),
$profile);
}
}
......@@ -98,9 +99,6 @@ class RawConversationNoticeStream extends NoticeStream
}
}
$notice->free();
$notice = NULL;
return $ids;
}
}
\ No newline at end of file
......@@ -317,7 +317,9 @@ $default =
'QnA' => null,
'SearchSub' => null,
'TagSub' => null,
'OpenID' => null),
'OpenID' => null,
'Directory' => null,
'ExtendedProfile' => null),
'locale_path' => false, // Set to a path to use *instead of* each plugin's own locale subdirectories
'server' => null,
'sslserver' => null,
......
......@@ -123,4 +123,14 @@ class GroupProfileBlock extends ProfileBlock
$this->out->elementEnd('ul');
$this->out->elementEnd('div');
}
function show()
{
$this->out->elementStart('div', 'group_profile_block section');
if (Event::handle('StartShowGroupProfileBlock', array($this->out, $this->group))) {
parent::show();
Event::handle('EndShowGroupProfileBlock', array($this->out, $this->group));
}
$this->out->elementEnd('div');
}
}
......@@ -56,16 +56,33 @@ abstract class ProfileBlock extends Widget
function show()
{
$this->out->elementStart('div', 'profile_block section');
$this->showActions();
$this->showAvatar();
$this->showName();
$this->showLocation();
$this->showHomepage();
$this->showDescription();
$this->showTags();
}
function showAvatar()
{
$size = $this->avatarSize();
$this->out->element('img', array('src' => $this->avatar(),
'class' => 'profile_block_avatar',
'alt' => $this->name(),
'width' => $size,
'height' => $size));
$this->out->element(
'img',
array(
'src' => $this->avatar(),
'class' => 'ur_face',
'alt' => $this->name(),
'width' => $size,
'height' => $size
)
);
}
function showName()
{
$name = $this->name();
if (!empty($name)) {
......@@ -79,31 +96,35 @@ abstract class ProfileBlock extends Widget
}
$this->out->elementEnd('p');
}
}
function showDescription()
{
$description = $this->description();
if (!empty($description)) {
$this->out->element(
'p',
'profile_block_description',
$description
);
}
}
function showLocation()
{
$location = $this->location();
if (!empty($location)) {
$this->out->element('p', 'profile_block_location', $location);
}
}
$homepage = $this->homepage();
function showHomepage()
{
if (!empty($homepage)) {
$this->out->element('a', 'profile_block_homepage', $homepage);
}
$description = $this->description();
if (!empty($description)) {
$this->out->element('p',
'profile_block_description',
$description);
}
$this->showTags();
$this->showActions();
$this->out->elementEnd('div');
}
function avatarSize()
......
......@@ -329,6 +329,11 @@ class EventPlugin extends MicroappPlugin
{
$rsvp = RSVP::fromNotice($notice);
if (empty($rsvp)) {
$out->element('p', null, _('Deleted.'));
return;
}
$out->elementStart('div', 'rsvp');
$out->raw($rsvp->asHTML());
$out->elementEnd('div');
......@@ -340,8 +345,10 @@ class EventPlugin extends MicroappPlugin
$profile = $notice->getProfile();
$event = Happening::fromNotice($notice);
assert(!empty($event));
assert(!empty($profile));
if (empty($event)) {
$out->element('p', null, _('Deleted.'));
return;
}
$out->elementStart('div', 'vevent event'); // VEVENT IN
......
......@@ -115,13 +115,12 @@ class ExtendedProfilePlugin extends Plugin
return true;
}
function onStartProfilePageActionsSection(HTMLOutputter $out, Profile $profile) {
function onEndShowAccountProfileBlock(HTMLOutputter $out, Profile $profile) {
$user = User::staticGet('id', $profile->id);
if ($user) {
$url = common_local_url('profiledetail', array('nickname' => $user->nickname));
// TRANS: Link text on user profile page leading to extended profile page.
$out->element('a', array('href' => $url, 'class' => 'profiledetail'), _m('More details...'));
}
return true;
}
}
......@@ -788,16 +788,16 @@ class Facebookclient
$subject = _m('Your Facebook connection has been removed');
// TRANS: E-mail body. %1$s is a username, %2$s is the StatusNet sitename.
$msg = _m('Hi %1$s,\n\n'.
'We are sorry to inform you we are unable to publish your notice to\n'.
'Facebook, and have removed the connection between your %2$s account and\n'.
'Facebook.\n\n'.
'This may have happened because you have removed permission for %2$s\n'.
'to post on your behalf, or perhaps you have deactivated your Facebook\n'.
'account. You can reconnect your %2$s account to Facebook at any time by\n'.
'logging in with Facebook again.\n\n'.
'Sincerely,\n\n'.
'%2$s\n');
$msg = _m("Hi %1\$s,\n\n".
"We are sorry to inform you we are unable to publish your notice to\n".
"Facebook, and have removed the connection between your %2\$s account and\n".
"Facebook.\n\n".
"This may have happened because you have removed permission for %2\$s\n".
"to post on your behalf, or perhaps you have deactivated your Facebook\n".
"account. You can reconnect your %2\$s account to Facebook at any time by\n".
"logging in with Facebook again.\n\n".
"Sincerely,\n\n".
"%2\$s\n");
$body = sprintf(
$msg,
......@@ -845,13 +845,13 @@ class Facebookclient
// TRANS: E-mail body. %1$s is a username,
// TRANS: %2$s is the StatusNet sitename, %3$s is the site contact e-mail address.
$msg = _m('Hi %1$s,\n\n'.
'We have noticed you have deauthorized the Facebook connection for your\n'.
'%2$s account. You have not set a password for your %2$s account yet, so\n'.