array('id' => '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'));
$m->connect('main/event/updatetimes',
array('action' => 'timelist'));
+
+ $m->connect(':nickname/events',
+ array('action' => 'events'),
+ array('nickname' => Nickname::DISPLAY_FMT));
return true;
}
$out->raw($rsvp->asHTML());
$out->elementEnd('div');
}
+
+ function onEndPersonalGroupNav(Menu $menu, Profile $target, Profile $scoped=null)
+ {
+ $menu->menuItem(common_local_url('events', array('nickname' => $target->getNickname())),
+ // TRANS: Menu item in sample plugin.
+ _m('Happenings'),
+ // TRANS: Menu item title in sample plugin.
+ _m('A list of your events'), false, 'nav_timeline_events');
+ return true;
+ }
}
--- /dev/null
+<?php
+/**
+ * List events
+ */
+
+if (!defined('GNUSOCIAL')) { exit(1); }
+
+class EventsAction extends ShowstreamAction
+{
+ public function getStream()
+ {
+ /* whose events */ /* are these the user's own events? */
+ $stream = new EventsNoticeStream($this->target, $this->scoped);
+ return $stream;
+ }
+
+ function title()
+ {
+ // TRANS: Page title for sample plugin. %s is a user nickname.
+ return sprintf(_m('%s\'s happenings'), $this->target->getNickname());
+ }
+
+ function getFeeds()
+ {
+ return array(
+ );
+ }
+
+ function showEmptyList() {
+ $message = sprintf(_('This is %1$s\'s event stream, but %1$s hasn\'t received any events yet.'), $this->target->getNickname()) . ' ';
+
+ $this->elementStart('div', 'guide');
+ $this->raw(common_markup_to_html($message));
+ $this->elementEnd('div');
+ }
+
+ /**
+ * Return true if read only.
+ *
+ * Some actions only read from the database; others read and write.
+ * The simple database load-balancer built into StatusNet will
+ * direct read-only actions to database mirrors (if they are configured),
+ * and read-write actions to the master database.
+ *
+ * This defaults to false to avoid data integrity issues, but you
+ * should make sure to overload it for performance gains.
+ *
+ * @param array $args other arguments, if RO/RW status depends on them.
+ *
+ * @return boolean is read only action?
+ */
+ function isReadOnly($args)
+ {
+ return true;
+ }
+}
--- /dev/null
+<?php
+
+class RawEventsNoticeStream extends NoticeStream
+{
+ protected $target;
+ protected $own;
+
+ function __construct(Profile $target)
+ {
+ $this->target = $target;
+ }
+
+ function getNoticeIds($offset, $limit, $since_id, $max_id)
+ {
+ $notice = new Notice();
+ $qry = null;
+
+ $qry = 'SELECT notice.* FROM notice ';
+ $qry .= 'INNER JOIN happening ON happening.uri = notice.uri ';
+ $qry .= 'WHERE happening.profile_id = ' . $this->target->getID() . ' ';
+ $qry .= 'AND notice.is_local != ' . Notice::GATEWAY . ' ';
+
+ if ($since_id != 0) {
+ $qry .= 'AND notice.id > ' . $since_id . ' ';
+ }
+
+ if ($max_id != 0) {
+ $qry .= 'AND notice.id <= ' . $max_id . ' ';
+ }
+
+ // NOTE: we sort by bookmark time, not by notice time!
+ $qry .= 'ORDER BY created DESC ';
+ if (!is_null($offset)) {
+ $qry .= "LIMIT $limit OFFSET $offset";
+ }
+
+ $notice->query($qry);
+ $ids = array();
+ while ($notice->fetch()) {
+ $ids[] = $notice->id;
+ }
+
+ $notice->free();
+ unset($notice);
+ return $ids;
+ }
+}
+
+class EventsNoticeStream extends ScopingNoticeStream
+{
+ function __construct(Profile $target, Profile $scoped=null)
+ {
+ $stream = new RawEventsNoticeStream($target);
+
+ if ($target->sameAs($scoped)) {
+ $key = 'bookmark:ids_by_user_own:'.$target->getID();
+ } else {
+ $key = 'bookmark:ids_by_user:'.$target->getID();
+ }
+
+ parent::__construct(new CachingNoticeStream($stream, $key), $scoped);
+ }
+}