Merge branch 'nightly'
This commit is contained in:
commit
d448275713
@ -563,6 +563,11 @@ sslserver: if specified, this server will be used when creating HTTPS
|
|||||||
sslpath: if this and the sslserver are specified, this path will be used
|
sslpath: if this and the sslserver are specified, this path will be used
|
||||||
when creating HTTPS URLs. Otherwise, the attachments|path value
|
when creating HTTPS URLs. Otherwise, the attachments|path value
|
||||||
will be used.
|
will be used.
|
||||||
|
show_thumbs: show thumbnails in notice lists for uploaded images, and photos
|
||||||
|
and videos linked remotely that provide oEmbed info. Defaults to true.
|
||||||
|
show_html: show (filtered) text/html attachments (and oEmbed HTML etc.).
|
||||||
|
Doesn't affect AJAX calls. Defaults to false.
|
||||||
|
filename_base: for new files, choose one: 'upload', 'hash'. Defaults to hash.
|
||||||
|
|
||||||
group
|
group
|
||||||
-----
|
-----
|
||||||
|
@ -615,12 +615,12 @@ EndCheckPassword: After checking a username/password pair
|
|||||||
- $authenticatedUser: User object if credentials match a user, else null.
|
- $authenticatedUser: User object if credentials match a user, else null.
|
||||||
|
|
||||||
StartChangePassword: Before changing a password
|
StartChangePassword: Before changing a password
|
||||||
- $user: user
|
- Profile $target: The profile of the User that is changing password
|
||||||
- $oldpassword: the user's old password
|
- $oldpassword: the user's old password
|
||||||
- $newpassword: the desired new password
|
- $newpassword: the desired new password
|
||||||
|
|
||||||
EndChangePassword: After changing a password
|
EndChangePassword: After changing a password
|
||||||
- $user: user
|
- Profile $target: The profile of the User that just changed its password
|
||||||
|
|
||||||
StartHashPassword: Generate a hashed version of the password (like a salted crypt)
|
StartHashPassword: Generate a hashed version of the password (like a salted crypt)
|
||||||
- &$hashed: Hashed version of the password, later put in the database
|
- &$hashed: Hashed version of the password, later put in the database
|
||||||
|
4
INSTALL
4
INSTALL
@ -196,7 +196,9 @@ your server (like lighttpd or nginx).
|
|||||||
file is well commented.
|
file is well commented.
|
||||||
* For lighttpd, inspect the lighttpd.conf.example file and apply the
|
* For lighttpd, inspect the lighttpd.conf.example file and apply the
|
||||||
appropriate changes in your virtualhost configuration for lighttpd.
|
appropriate changes in your virtualhost configuration for lighttpd.
|
||||||
* For nginx and other webservers, we gladly accept contributions of
|
* For nginx, inspect the nginx.conf.sample file and apply the appropriate
|
||||||
|
changes.
|
||||||
|
* For other webservers, we gladly accept contributions of
|
||||||
server configuration examples.
|
server configuration examples.
|
||||||
|
|
||||||
2. Assuming your webserver is properly configured and have its settings
|
2. Assuming your webserver is properly configured and have its settings
|
||||||
|
@ -39,8 +39,6 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
|||||||
|
|
||||||
class AllAction extends ShowstreamAction
|
class AllAction extends ShowstreamAction
|
||||||
{
|
{
|
||||||
var $notice;
|
|
||||||
|
|
||||||
public function getStream()
|
public function getStream()
|
||||||
{
|
{
|
||||||
if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
|
if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
|
||||||
@ -54,7 +52,7 @@ class AllAction extends ShowstreamAction
|
|||||||
|
|
||||||
function title()
|
function title()
|
||||||
{
|
{
|
||||||
if (!empty($this->scoped) && $this->scoped->id == $this->target->id) {
|
if (!empty($this->scoped) && $this->scoped->sameAs($this->target)) {
|
||||||
// TRANS: Title of a user's own start page.
|
// TRANS: Title of a user's own start page.
|
||||||
return _('Home timeline');
|
return _('Home timeline');
|
||||||
} else {
|
} else {
|
||||||
@ -71,44 +69,44 @@ class AllAction extends ShowstreamAction
|
|||||||
common_local_url(
|
common_local_url(
|
||||||
'ApiTimelineFriends', array(
|
'ApiTimelineFriends', array(
|
||||||
'format' => 'as',
|
'format' => 'as',
|
||||||
'id' => $this->target->nickname
|
'id' => $this->target->getNickname()
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
// TRANS: %s is user nickname.
|
// TRANS: %s is user nickname.
|
||||||
sprintf(_('Feed for friends of %s (Activity Streams JSON)'), $this->target->nickname)),
|
sprintf(_('Feed for friends of %s (Activity Streams JSON)'), $this->target->getNickname())),
|
||||||
new Feed(Feed::RSS1,
|
new Feed(Feed::RSS1,
|
||||||
common_local_url(
|
common_local_url(
|
||||||
'allrss', array(
|
'allrss', array(
|
||||||
'nickname' =>
|
'nickname' =>
|
||||||
$this->target->nickname)
|
$this->target->getNickname())
|
||||||
),
|
),
|
||||||
// TRANS: %s is user nickname.
|
// TRANS: %s is user nickname.
|
||||||
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->target->nickname)),
|
sprintf(_('Feed for friends of %s (RSS 1.0)'), $this->target->getNickname())),
|
||||||
new Feed(Feed::RSS2,
|
new Feed(Feed::RSS2,
|
||||||
common_local_url(
|
common_local_url(
|
||||||
'ApiTimelineFriends', array(
|
'ApiTimelineFriends', array(
|
||||||
'format' => 'rss',
|
'format' => 'rss',
|
||||||
'id' => $this->target->nickname
|
'id' => $this->target->getNickname()
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
// TRANS: %s is user nickname.
|
// TRANS: %s is user nickname.
|
||||||
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->target->nickname)),
|
sprintf(_('Feed for friends of %s (RSS 2.0)'), $this->target->getNickname())),
|
||||||
new Feed(Feed::ATOM,
|
new Feed(Feed::ATOM,
|
||||||
common_local_url(
|
common_local_url(
|
||||||
'ApiTimelineFriends', array(
|
'ApiTimelineFriends', array(
|
||||||
'format' => 'atom',
|
'format' => 'atom',
|
||||||
'id' => $this->target->nickname
|
'id' => $this->target->getNickname()
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
// TRANS: %s is user nickname.
|
// TRANS: %s is user nickname.
|
||||||
sprintf(_('Feed for friends of %s (Atom)'), $this->target->nickname))
|
sprintf(_('Feed for friends of %s (Atom)'), $this->target->getNickname()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showEmptyListMessage()
|
function showEmptyListMessage()
|
||||||
{
|
{
|
||||||
// TRANS: Empty list message. %s is a user nickname.
|
// TRANS: Empty list message. %s is a user nickname.
|
||||||
$message = sprintf(_('This is the timeline for %s and friends but no one has posted anything yet.'), $this->target->nickname) . ' ';
|
$message = sprintf(_('This is the timeline for %s and friends but no one has posted anything yet.'), $this->target->getNickname()) . ' ';
|
||||||
|
|
||||||
if (common_logged_in()) {
|
if (common_logged_in()) {
|
||||||
if ($this->target->id === $this->scoped->id) {
|
if ($this->target->id === $this->scoped->id) {
|
||||||
@ -118,12 +116,12 @@ class AllAction extends ShowstreamAction
|
|||||||
} else {
|
} else {
|
||||||
// TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@".
|
// TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@".
|
||||||
// TRANS: This message contains Markdown links. Keep "](" together.
|
// TRANS: This message contains Markdown links. Keep "](" together.
|
||||||
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->target->nickname, $this->target->nickname, '@' . $this->target->nickname);
|
$message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to them](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->target->getNickname(), $this->target->getNickname(), '@' . $this->target->getNickname());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TRANS: Encouragement displayed on empty timeline user pages for anonymous users.
|
// TRANS: Encouragement displayed on empty timeline user pages for anonymous users.
|
||||||
// TRANS: %s is a user nickname. This message contains Markdown links. Keep "](" together.
|
// TRANS: %s is a user nickname. This message contains Markdown links. Keep "](" together.
|
||||||
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->target->nickname);
|
$message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to them.'), $this->target->getNickname());
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
@ -134,19 +132,10 @@ class AllAction extends ShowstreamAction
|
|||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
if (Event::handle('StartShowAllContent', array($this))) {
|
if (Event::handle('StartShowAllContent', array($this))) {
|
||||||
|
if ($this->scoped instanceof Profile && $this->scoped->isLocal() && $this->scoped->getUser()->streamModeOnly()) {
|
||||||
$profile = null;
|
|
||||||
|
|
||||||
$current_user = common_current_user();
|
|
||||||
|
|
||||||
if (!empty($current_user)) {
|
|
||||||
$profile = $current_user->getProfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($current_user) && $current_user->streamModeOnly()) {
|
|
||||||
$nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));
|
$nl = new PrimaryNoticeList($this->notice, $this, array('show_n'=>NOTICES_PER_PAGE));
|
||||||
} else {
|
} else {
|
||||||
$nl = new ThreadedNoticeList($this->notice, $this, $profile);
|
$nl = new ThreadedNoticeList($this->notice, $this, $this->scoped);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cnt = $nl->show();
|
$cnt = $nl->show();
|
||||||
@ -157,7 +146,7 @@ class AllAction extends ShowstreamAction
|
|||||||
|
|
||||||
$this->pagination(
|
$this->pagination(
|
||||||
$this->page > 1, $cnt > NOTICES_PER_PAGE,
|
$this->page > 1, $cnt > NOTICES_PER_PAGE,
|
||||||
$this->page, 'all', array('nickname' => $this->target->nickname)
|
$this->page, 'all', array('nickname' => $this->target->getNickname())
|
||||||
);
|
);
|
||||||
|
|
||||||
Event::handle('EndShowAllContent', array($this));
|
Event::handle('EndShowAllContent', array($this));
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/rssaction.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSS feed for user and friends timeline.
|
* RSS feed for user and friends timeline.
|
||||||
@ -46,52 +42,12 @@ require_once INSTALLDIR.'/lib/rssaction.php';
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class AllrssAction extends Rss10Action
|
class AllrssAction extends TargetedRss10Action
|
||||||
{
|
{
|
||||||
var $user = null;
|
protected function getNotices()
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization.
|
|
||||||
*
|
|
||||||
* @param array $args Web and URL arguments
|
|
||||||
*
|
|
||||||
* @return boolean false if user doesn't exist
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function prepare($args)
|
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
$stream = new InboxNoticeStream($this->target);
|
||||||
$nickname = $this->trimmed('nickname');
|
return $stream->getNotices(0, $this->limit)->fetchAll();
|
||||||
$this->user = User::getKV('nickname', $nickname);
|
|
||||||
|
|
||||||
if (!$this->user) {
|
|
||||||
// TRANS: Client error when user not found for an rss related action.
|
|
||||||
$this->clientError(_('No such user.'));
|
|
||||||
} else {
|
|
||||||
$this->notices = $this->getNotices($this->limit);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get notices
|
|
||||||
*
|
|
||||||
* @param integer $limit max number of notices to return
|
|
||||||
*
|
|
||||||
* @return array notices
|
|
||||||
*/
|
|
||||||
function getNotices($limit=0)
|
|
||||||
{
|
|
||||||
$stream = new InboxNoticeStream($this->user->getProfile());
|
|
||||||
$notice = $stream->getNotices(0, $limit, null, null);
|
|
||||||
|
|
||||||
$notices = array();
|
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $notices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,33 +57,17 @@ class AllrssAction extends Rss10Action
|
|||||||
*/
|
*/
|
||||||
function getChannel()
|
function getChannel()
|
||||||
{
|
{
|
||||||
$user = $this->user;
|
|
||||||
$c = array('url' => common_local_url('allrss',
|
$c = array('url' => common_local_url('allrss',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$user->nickname)),
|
$this->target->getNickname())),
|
||||||
// TRANS: Message is used as link title. %s is a user nickname.
|
// TRANS: Message is used as link title. %s is a user nickname.
|
||||||
'title' => sprintf(_('%s and friends'), $user->nickname),
|
'title' => sprintf(_('%s and friends'), $this->target->getNickname()),
|
||||||
'link' => common_local_url('all',
|
'link' => common_local_url('all',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$user->nickname)),
|
$this->target->getNickname())),
|
||||||
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
|
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
|
||||||
'description' => sprintf(_('Updates from %1$s and friends on %2$s!'),
|
'description' => sprintf(_('Updates from %1$s and friends on %2$s!'),
|
||||||
$user->nickname, common_config('site', 'name')));
|
$this->target->getNickname(), common_config('site', 'name')));
|
||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get image.
|
|
||||||
*
|
|
||||||
* @return string user avatar URL or null
|
|
||||||
*/
|
|
||||||
function getImage()
|
|
||||||
{
|
|
||||||
$user = $this->user;
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
if (!$profile) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return $profile->avatarUrl(AVATAR_PROFILE_SIZE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -96,21 +96,12 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
|||||||
|
|
||||||
$original = clone($profile);
|
$original = clone($profile);
|
||||||
|
|
||||||
if (!empty($this->name)) {
|
$profile->fullname = $this->name;
|
||||||
$profile->fullname = $this->name;
|
$profile->homepage = $this->url;
|
||||||
}
|
$profile->bio = $this->description;
|
||||||
|
$profile->location = $this->location;
|
||||||
if (!empty($this->url)) {
|
|
||||||
$profile->homepage = $this->url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->description)) {
|
|
||||||
$profile->bio = $this->description;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->location)) {
|
if (!empty($this->location)) {
|
||||||
$profile->location = $this->location;
|
|
||||||
|
|
||||||
$loc = Location::fromName($this->location);
|
$loc = Location::fromName($this->location);
|
||||||
|
|
||||||
if (!empty($loc)) {
|
if (!empty($loc)) {
|
||||||
@ -119,6 +110,12 @@ class ApiAccountUpdateProfileAction extends ApiAuthAction
|
|||||||
$profile->location_id = $loc->location_id;
|
$profile->location_id = $loc->location_id;
|
||||||
$profile->location_ns = $loc->location_ns;
|
$profile->location_ns = $loc->location_ns;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// location is empty so reset the extrapolated information too
|
||||||
|
$profile->lat = '';
|
||||||
|
$profile->lon = '';
|
||||||
|
$profile->location_id = '';
|
||||||
|
$profile->location_ns = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $profile->update($original);
|
$result = $profile->update($original);
|
||||||
|
@ -51,10 +51,14 @@ class ApiTimelineTagAction extends ApiPrivateAuthAction
|
|||||||
{
|
{
|
||||||
var $notices = null;
|
var $notices = null;
|
||||||
|
|
||||||
protected function doPreparation()
|
protected function prepare(array $args=array())
|
||||||
{
|
{
|
||||||
|
parent::prepare($args);
|
||||||
|
|
||||||
$this->tag = $this->arg('tag');
|
$this->tag = $this->arg('tag');
|
||||||
$this->notices = $this->getNotices();
|
$this->notices = $this->getNotices();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,11 +76,11 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
/**
|
/**
|
||||||
* Content area of the page
|
* Content area of the page
|
||||||
*
|
*
|
||||||
* Shows a form for uploading an avatar.
|
* Shows a form for uploading an avatar. Currently overrides FormAction's showContent
|
||||||
|
* since we haven't made classes out of AvatarCropForm and AvatarUploadForm.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
if ($this->mode == 'crop') {
|
if ($this->mode == 'crop') {
|
||||||
@ -243,52 +243,19 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
$this->elementEnd('form');
|
$this->elementEnd('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPost()
|
||||||
* Handle a post
|
|
||||||
*
|
|
||||||
* We mux on the button name to figure out what the user actually wanted.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handlePost()
|
|
||||||
{
|
{
|
||||||
// Workaround for PHP returning empty $_POST and $_FILES when POST
|
|
||||||
// length > post_max_size in php.ini
|
|
||||||
|
|
||||||
if (empty($_FILES)
|
|
||||||
&& empty($_POST)
|
|
||||||
&& ($_SERVER['CONTENT_LENGTH'] > 0)
|
|
||||||
) {
|
|
||||||
// TRANS: Client error displayed when the number of bytes in a POST request exceeds a limit.
|
|
||||||
// TRANS: %s is the number of bytes of the CONTENT_LENGTH.
|
|
||||||
$msg = _m('The server was unable to handle that much POST data (%s byte) due to its current configuration.',
|
|
||||||
'The server was unable to handle that much POST data (%s bytes) due to its current configuration.',
|
|
||||||
intval($_SERVER['CONTENT_LENGTH']));
|
|
||||||
$this->showForm(sprintf($msg, $_SERVER['CONTENT_LENGTH']));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CSRF protection
|
|
||||||
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Event::handle('StartAvatarSaveForm', array($this))) {
|
if (Event::handle('StartAvatarSaveForm', array($this))) {
|
||||||
if ($this->arg('upload')) {
|
if ($this->trimmed('upload')) {
|
||||||
$this->uploadAvatar();
|
return $this->uploadAvatar();
|
||||||
} else if ($this->arg('crop')) {
|
} else if ($this->trimmed('crop')) {
|
||||||
$this->cropAvatar();
|
return $this->cropAvatar();
|
||||||
} else if ($this->arg('delete')) {
|
} else if ($this->trimmed('delete')) {
|
||||||
$this->deleteAvatar();
|
return $this->deleteAvatar();
|
||||||
} else {
|
} else {
|
||||||
// TRANS: Unexpected validation error on avatar upload form.
|
// TRANS: Unexpected validation error on avatar upload form.
|
||||||
$this->showForm(_('Unexpected form submission.'));
|
throw new ClientException(_('Unexpected form submission.'));
|
||||||
}
|
}
|
||||||
Event::handle('EndAvatarSaveForm', array($this));
|
Event::handle('EndAvatarSaveForm', array($this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,21 +270,12 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function uploadAvatar()
|
function uploadAvatar()
|
||||||
{
|
{
|
||||||
try {
|
// ImageFile throws exception if something goes wrong, which we'll
|
||||||
$imagefile = ImageFile::fromUpload('avatarfile');
|
// pick up and show as an error message above the form.
|
||||||
} catch (Exception $e) {
|
$imagefile = ImageFile::fromUpload('avatarfile');
|
||||||
$this->showForm($e->getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($imagefile === null) {
|
|
||||||
// TRANS: Validation error on avatar upload form when no file was uploaded.
|
|
||||||
$this->showForm(_('No file uploaded.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$cur = common_current_user();
|
|
||||||
$type = $imagefile->preferredType();
|
$type = $imagefile->preferredType();
|
||||||
$filename = Avatar::filename($cur->id,
|
$filename = Avatar::filename($this->scoped->getID(),
|
||||||
image_type_to_extension($type),
|
image_type_to_extension($type),
|
||||||
null,
|
null,
|
||||||
'tmp'.common_timestamp());
|
'tmp'.common_timestamp());
|
||||||
@ -338,8 +296,7 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
$this->mode = 'crop';
|
$this->mode = 'crop';
|
||||||
|
|
||||||
// TRANS: Avatar upload form instruction after uploading a file.
|
// TRANS: Avatar upload form instruction after uploading a file.
|
||||||
$this->showForm(_('Pick a square area of the image to be your avatar.'),
|
return _('Pick a square area of the image to be your avatar.');
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -351,13 +308,12 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
{
|
{
|
||||||
$filedata = $_SESSION['FILEDATA'];
|
$filedata = $_SESSION['FILEDATA'];
|
||||||
|
|
||||||
if (!$filedata) {
|
if (empty($filedata)) {
|
||||||
// TRANS: Server error displayed if an avatar upload went wrong somehow server side.
|
// TRANS: Server error displayed if an avatar upload went wrong somehow server side.
|
||||||
$this->serverError(_('Lost our file data.'));
|
throw new ServerException(_('Lost our file data.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$file_d = ($filedata['width'] > $filedata['height'])
|
$file_d = min($filedata['width'], $filedata['height']);
|
||||||
? $filedata['height'] : $filedata['width'];
|
|
||||||
|
|
||||||
$dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
|
$dest_x = $this->arg('avatar_crop_x') ? $this->arg('avatar_crop_x'):0;
|
||||||
$dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
|
$dest_y = $this->arg('avatar_crop_y') ? $this->arg('avatar_crop_y'):0;
|
||||||
@ -369,11 +325,8 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
'x' => $dest_x, 'y' => $dest_y,
|
'x' => $dest_x, 'y' => $dest_y,
|
||||||
'w' => $dest_w, 'h' => $dest_h);
|
'w' => $dest_w, 'h' => $dest_h);
|
||||||
|
|
||||||
$user = common_current_user();
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
|
|
||||||
$imagefile = new ImageFile(null, $filedata['filepath']);
|
$imagefile = new ImageFile(null, $filedata['filepath']);
|
||||||
$filename = Avatar::filename($profile->getID(), image_type_to_extension($imagefile->preferredType()),
|
$filename = Avatar::filename($this->scoped->getID(), image_type_to_extension($imagefile->preferredType()),
|
||||||
$size, common_timestamp());
|
$size, common_timestamp());
|
||||||
try {
|
try {
|
||||||
$imagefile->resizeTo(Avatar::path($filename), $box);
|
$imagefile->resizeTo(Avatar::path($filename), $box);
|
||||||
@ -385,16 +338,16 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($profile->setOriginal($filename)) {
|
if ($this->scoped->setOriginal($filename)) {
|
||||||
@unlink($filedata['filepath']);
|
@unlink($filedata['filepath']);
|
||||||
unset($_SESSION['FILEDATA']);
|
unset($_SESSION['FILEDATA']);
|
||||||
$this->mode = 'upload';
|
$this->mode = 'upload';
|
||||||
// TRANS: Success message for having updated a user avatar.
|
// TRANS: Success message for having updated a user avatar.
|
||||||
$this->showForm(_('Avatar updated.'), true);
|
return _('Avatar updated.');
|
||||||
} else {
|
|
||||||
// TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason.
|
|
||||||
$this->showForm(_('Failed updating avatar.'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TRANS: Error displayed on the avatar upload page if the avatar could not be updated for an unknown reason.
|
||||||
|
throw new ServerException(_('Failed updating avatar.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -404,13 +357,10 @@ class AvatarsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function deleteAvatar()
|
function deleteAvatar()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
Avatar::deleteFromProfile($this->scoped);
|
||||||
$profile = $user->getProfile();
|
|
||||||
|
|
||||||
Avatar::deleteFromProfile($profile);
|
|
||||||
|
|
||||||
// TRANS: Success message for deleting a user avatar.
|
// TRANS: Success message for deleting a user avatar.
|
||||||
$this->showForm(_('Avatar deleted.'), true);
|
return _('Avatar deleted.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,80 +28,24 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @todo FIXME: documentation needed.
|
// @todo FIXME: documentation needed.
|
||||||
class DeletenoticeAction extends Action
|
class DeletenoticeAction extends FormAction
|
||||||
{
|
{
|
||||||
var $error = null;
|
protected $notice = null;
|
||||||
var $user = null;
|
|
||||||
var $notice = null;
|
|
||||||
var $profile = null;
|
|
||||||
var $user_profile = null;
|
|
||||||
|
|
||||||
function prepare($args)
|
protected function doPreparation()
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
$this->notice = Notice::getByID($this->trimmed('notice'));
|
||||||
|
|
||||||
$this->user = common_current_user();
|
if (!$this->scoped->sameAs($this->notice->getProfile()) &&
|
||||||
|
!$this->scoped->hasRight(Right::DELETEOTHERSNOTICE)) {
|
||||||
if (!$this->user) {
|
|
||||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
|
||||||
common_user_error(_('Not logged in.'));
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$notice_id = $this->trimmed('notice');
|
|
||||||
$this->notice = Notice::getKV($notice_id);
|
|
||||||
|
|
||||||
if (!$this->notice) {
|
|
||||||
// TRANS: Error message displayed trying to delete a non-existing notice.
|
|
||||||
common_user_error(_('No such notice.'));
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->profile = $this->notice->getProfile();
|
|
||||||
$this->user_profile = $this->user->getProfile();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handle($args)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
if ($this->notice->profile_id != $this->user_profile->id &&
|
|
||||||
!$this->user->hasRight(Right::DELETEOTHERSNOTICE)) {
|
|
||||||
// TRANS: Error message displayed trying to delete a notice that was not made by the current user.
|
// TRANS: Error message displayed trying to delete a notice that was not made by the current user.
|
||||||
common_user_error(_('Cannot delete this notice.'));
|
$this->clientError(_('Cannot delete this notice.'));
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
// XXX: Ajax!
|
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
$this->formOpts['notice'] = $this->notice;
|
||||||
$this->deleteNotice();
|
|
||||||
} else if ($_SERVER['REQUEST_METHOD'] == 'GET') {
|
|
||||||
$this->showForm();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the page notice
|
|
||||||
*
|
|
||||||
* Shows instructions for the page
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function showPageNotice()
|
|
||||||
{
|
|
||||||
$instr = $this->getInstructions();
|
|
||||||
$output = common_markup_to_html($instr);
|
|
||||||
|
|
||||||
$this->elementStart('div', 'instructions');
|
|
||||||
$this->raw($output);
|
|
||||||
$this->elementEnd('div');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInstructions()
|
function getInstructions()
|
||||||
@ -117,84 +61,17 @@ class DeletenoticeAction extends Action
|
|||||||
return _('Delete notice');
|
return _('Delete notice');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPost()
|
||||||
* Wrapper for showing a page
|
|
||||||
*
|
|
||||||
* Stores an error and shows the page
|
|
||||||
*
|
|
||||||
* @param string $error Error, if any
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function showForm($error = null)
|
|
||||||
{
|
{
|
||||||
$this->error = $error;
|
|
||||||
$this->showPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Insert delete notice form into the content
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function showContent()
|
|
||||||
{
|
|
||||||
$this->elementStart('form', array('id' => 'form_notice_delete',
|
|
||||||
'class' => 'form_settings',
|
|
||||||
'method' => 'post',
|
|
||||||
'action' => common_local_url('deletenotice')));
|
|
||||||
$this->elementStart('fieldset');
|
|
||||||
// TRANS: Fieldset legend for the delete notice form.
|
|
||||||
$this->element('legend', null, _('Delete notice'));
|
|
||||||
$this->hidden('token', common_session_token());
|
|
||||||
$this->hidden('notice', $this->trimmed('notice'));
|
|
||||||
// TRANS: Message for the delete notice form.
|
|
||||||
$this->element('p', null, _('Are you sure you want to delete this notice?'));
|
|
||||||
$this->submit('form_action-no',
|
|
||||||
// TRANS: Button label on the delete notice form.
|
|
||||||
_m('BUTTON','No'),
|
|
||||||
'submit form_action-primary',
|
|
||||||
'no',
|
|
||||||
// TRANS: Submit button title for 'No' when deleting a notice.
|
|
||||||
_('Do not delete this notice.'));
|
|
||||||
$this->submit('form_action-yes',
|
|
||||||
// TRANS: Button label on the delete notice form.
|
|
||||||
_m('BUTTON','Yes'),
|
|
||||||
'submit form_action-secondary',
|
|
||||||
'yes',
|
|
||||||
// TRANS: Submit button title for 'Yes' when deleting a notice.
|
|
||||||
_('Delete this notice.'));
|
|
||||||
$this->elementEnd('fieldset');
|
|
||||||
$this->elementEnd('form');
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteNotice()
|
|
||||||
{
|
|
||||||
// CSRF protection
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
||||||
$this->showForm(_('There was a problem with your session token. ' .
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->arg('yes')) {
|
if ($this->arg('yes')) {
|
||||||
if (Event::handle('StartDeleteOwnNotice', array($this->user, $this->notice))) {
|
if (Event::handle('StartDeleteOwnNotice', array($this->scoped->getUser(), $this->notice))) {
|
||||||
$this->notice->delete();
|
$this->notice->delete();
|
||||||
Event::handle('EndDeleteOwnNotice', array($this->user, $this->notice));
|
Event::handle('EndDeleteOwnNotice', array($this->scoped->getUser(), $this->notice));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$url = common_get_returnto();
|
|
||||||
|
|
||||||
if ($url) {
|
|
||||||
common_set_returnto(null);
|
|
||||||
} else {
|
} else {
|
||||||
$url = common_local_url('public');
|
common_redirect(common_get_returnto(), 303);
|
||||||
}
|
}
|
||||||
|
|
||||||
common_redirect($url, 303);
|
common_redirect(common_local_url('top'), 303);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for email
|
* Settings for email
|
||||||
@ -112,8 +108,8 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
// TRANS: Button label to remove a confirmed e-mail address.
|
// TRANS: Button label to remove a confirmed e-mail address.
|
||||||
$this->submit('remove', _m('BUTTON','Remove'));
|
$this->submit('remove', _m('BUTTON','Remove'));
|
||||||
} else {
|
} else {
|
||||||
$confirm = $this->getConfirmation();
|
try {
|
||||||
if ($confirm) {
|
$confirm = $this->getConfirmation();
|
||||||
$this->element('p', array('id' => 'form_unconfirmed'), $confirm->address);
|
$this->element('p', array('id' => 'form_unconfirmed'), $confirm->address);
|
||||||
$this->element('p', array('class' => 'form_note'),
|
$this->element('p', array('class' => 'form_note'),
|
||||||
// TRANS: Form note in e-mail settings form.
|
// TRANS: Form note in e-mail settings form.
|
||||||
@ -123,12 +119,12 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
$this->hidden('email', $confirm->address);
|
$this->hidden('email', $confirm->address);
|
||||||
// TRANS: Button label to cancel an e-mail address confirmation procedure.
|
// TRANS: Button label to cancel an e-mail address confirmation procedure.
|
||||||
$this->submit('cancel', _m('BUTTON','Cancel'));
|
$this->submit('cancel', _m('BUTTON','Cancel'));
|
||||||
} else {
|
} catch (NoResultException $e) {
|
||||||
$this->elementStart('ul', 'form_data');
|
$this->elementStart('ul', 'form_data');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label for e-mail address input in e-mail settings form.
|
// TRANS: Field label for e-mail address input in e-mail settings form.
|
||||||
$this->input('email', _('Email address'),
|
$this->input('email', _('Email address'),
|
||||||
($this->arg('email')) ? $this->arg('email') : null,
|
$this->trimmed('email') ?: null,
|
||||||
// TRANS: Instructions for e-mail address input form. Do not translate
|
// TRANS: Instructions for e-mail address input form. Do not translate
|
||||||
// TRANS: "example.org". It is one of the domain names reserved for
|
// TRANS: "example.org". It is one of the domain names reserved for
|
||||||
// TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
|
// TRANS: use in examples by http://www.rfc-editor.org/rfc/rfc2606.txt.
|
||||||
@ -231,12 +227,6 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
_('Allow friends to nudge me and send me an email.'),
|
_('Allow friends to nudge me and send me an email.'),
|
||||||
$user->emailnotifynudge);
|
$user->emailnotifynudge);
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
$this->elementStart('li');
|
|
||||||
$this->checkbox('emailmicroid',
|
|
||||||
// TRANS: Checkbox label in e-mail preferences form.
|
|
||||||
_('Publish a MicroID for my email address.'),
|
|
||||||
$user->emailmicroid);
|
|
||||||
$this->elementEnd('li');
|
|
||||||
Event::handle('EndEmailFormData', array($this, $this->scoped));
|
Event::handle('EndEmailFormData', array($this, $this->scoped));
|
||||||
}
|
}
|
||||||
$this->elementEnd('ul');
|
$this->elementEnd('ul');
|
||||||
@ -254,56 +244,36 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function getConfirmation()
|
function getConfirmation()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$confirm = new Confirm_address();
|
$confirm = new Confirm_address();
|
||||||
|
|
||||||
$confirm->user_id = $user->id;
|
$confirm->user_id = $this->scoped->getID();
|
||||||
$confirm->address_type = 'email';
|
$confirm->address_type = 'email';
|
||||||
|
|
||||||
if ($confirm->find(true)) {
|
if ($confirm->find(true)) {
|
||||||
return $confirm;
|
return $confirm;
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new NoResultException($confirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPost()
|
||||||
* Handle posts
|
|
||||||
*
|
|
||||||
* Since there are a lot of different options on the page, we
|
|
||||||
* figure out what we're supposed to do based on which button was
|
|
||||||
* pushed
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handlePost()
|
|
||||||
{
|
{
|
||||||
// CSRF protection
|
if ($this->arg('save')) {
|
||||||
$token = $this->trimmed('token');
|
return $this->savePreferences();
|
||||||
if (!$token || $token != common_session_token()) {
|
} else if ($this->arg('add')) {
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
return $this->addAddress();
|
||||||
$this->show_form(_('There was a problem with your session token. '.
|
} else if ($this->arg('cancel')) {
|
||||||
'Try again, please.'));
|
return $this->cancelConfirmation();
|
||||||
return;
|
} else if ($this->arg('remove')) {
|
||||||
|
return $this->removeAddress();
|
||||||
|
} else if ($this->arg('removeincoming')) {
|
||||||
|
return $this->removeIncoming();
|
||||||
|
} else if ($this->arg('newincoming')) {
|
||||||
|
return $this->newIncoming();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->arg('save')) {
|
// TRANS: Message given submitting a form with an unknown action in e-mail settings.
|
||||||
$this->savePreferences();
|
throw new ClientException(_('Unexpected form submission.'));
|
||||||
} else if ($this->arg('add')) {
|
|
||||||
$this->addAddress();
|
|
||||||
} else if ($this->arg('cancel')) {
|
|
||||||
$this->cancelConfirmation();
|
|
||||||
} else if ($this->arg('remove')) {
|
|
||||||
$this->removeAddress();
|
|
||||||
} else if ($this->arg('removeincoming')) {
|
|
||||||
$this->removeIncoming();
|
|
||||||
} else if ($this->arg('newincoming')) {
|
|
||||||
$this->newIncoming();
|
|
||||||
} else {
|
|
||||||
// TRANS: Message given submitting a form with an unknown action in e-mail settings.
|
|
||||||
$this->showForm(_('Unexpected form submission.'));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,25 +283,21 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function savePreferences()
|
function savePreferences()
|
||||||
{
|
{
|
||||||
$user = $this->scoped->getUser();
|
|
||||||
|
|
||||||
if (Event::handle('StartEmailSaveForm', array($this, $this->scoped))) {
|
if (Event::handle('StartEmailSaveForm', array($this, $this->scoped))) {
|
||||||
$emailnotifysub = $this->booleanintstring('emailnotifysub');
|
$emailnotifysub = $this->booleanintstring('emailnotifysub');
|
||||||
$emailnotifymsg = $this->booleanintstring('emailnotifymsg');
|
$emailnotifymsg = $this->booleanintstring('emailnotifymsg');
|
||||||
$emailnotifynudge = $this->booleanintstring('emailnotifynudge');
|
$emailnotifynudge = $this->booleanintstring('emailnotifynudge');
|
||||||
$emailnotifyattn = $this->booleanintstring('emailnotifyattn');
|
$emailnotifyattn = $this->booleanintstring('emailnotifyattn');
|
||||||
$emailmicroid = $this->booleanintstring('emailmicroid');
|
|
||||||
$emailpost = $this->booleanintstring('emailpost');
|
$emailpost = $this->booleanintstring('emailpost');
|
||||||
|
|
||||||
|
$user = $this->scoped->getUser();
|
||||||
$user->query('BEGIN');
|
$user->query('BEGIN');
|
||||||
|
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
|
|
||||||
$user->emailnotifysub = $emailnotifysub;
|
$user->emailnotifysub = $emailnotifysub;
|
||||||
$user->emailnotifymsg = $emailnotifymsg;
|
$user->emailnotifymsg = $emailnotifymsg;
|
||||||
$user->emailnotifynudge = $emailnotifynudge;
|
$user->emailnotifynudge = $emailnotifynudge;
|
||||||
$user->emailnotifyattn = $emailnotifyattn;
|
$user->emailnotifyattn = $emailnotifyattn;
|
||||||
$user->emailmicroid = $emailmicroid;
|
|
||||||
$user->emailpost = $emailpost;
|
$user->emailpost = $emailpost;
|
||||||
|
|
||||||
$result = $user->update($original);
|
$result = $user->update($original);
|
||||||
@ -340,16 +306,15 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||||
$user->query('ROLLBACK');
|
$user->query('ROLLBACK');
|
||||||
// TRANS: Server error thrown on database error updating e-mail preferences.
|
// TRANS: Server error thrown on database error updating e-mail preferences.
|
||||||
$this->serverError(_('Could not update user.'));
|
throw new ServerException(_('Could not update user.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->query('COMMIT');
|
$user->query('COMMIT');
|
||||||
|
|
||||||
Event::handle('EndEmailSaveForm', array($this, $this->scoped));
|
Event::handle('EndEmailSaveForm', array($this, $this->scoped));
|
||||||
|
|
||||||
// TRANS: Confirmation message for successful e-mail preferences save.
|
|
||||||
$this->showForm(_('Email preferences saved.'), true);
|
|
||||||
}
|
}
|
||||||
|
// TRANS: Confirmation message for successful e-mail preferences save.
|
||||||
|
return _('Email preferences saved.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -359,38 +324,32 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function addAddress()
|
function addAddress()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = $this->scoped->getUser();
|
||||||
|
|
||||||
$email = $this->trimmed('email');
|
$email = $this->trimmed('email');
|
||||||
|
|
||||||
// Some validation
|
// Some validation
|
||||||
|
|
||||||
if (!$email) {
|
if (empty($email)) {
|
||||||
// TRANS: Message given saving e-mail address without having provided one.
|
// TRANS: Message given saving e-mail address without having provided one.
|
||||||
$this->showForm(_('No email address.'));
|
throw new ClientException(_('No email address.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$email = common_canonical_email($email);
|
$email = common_canonical_email($email);
|
||||||
|
|
||||||
if (!$email) {
|
if (empty($email)) {
|
||||||
// TRANS: Message given saving e-mail address that cannot be normalised.
|
// TRANS: Message given saving e-mail address that cannot be normalised.
|
||||||
$this->showForm(_('Cannot normalize that email address.'));
|
throw new ClientException(_('Cannot normalize that email address.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!Validate::email($email, common_config('email', 'check_domain'))) {
|
if (!Validate::email($email, common_config('email', 'check_domain'))) {
|
||||||
// TRANS: Message given saving e-mail address that not valid.
|
// TRANS: Message given saving e-mail address that not valid.
|
||||||
$this->showForm(_('Not a valid email address.'));
|
throw new ClientException(_('Not a valid email address.'));
|
||||||
return;
|
|
||||||
} else if ($user->email == $email) {
|
} else if ($user->email == $email) {
|
||||||
// TRANS: Message given saving e-mail address that is already set.
|
// TRANS: Message given saving e-mail address that is already set.
|
||||||
$this->showForm(_('That is already your email address.'));
|
throw new ClientException(_('That is already your email address.'));
|
||||||
return;
|
|
||||||
} else if ($this->emailExists($email)) {
|
} else if ($this->emailExists($email)) {
|
||||||
// TRANS: Message given saving e-mail address that is already set for another user.
|
// TRANS: Message given saving e-mail address that is already set for another user.
|
||||||
$this->showForm(_('That email address already belongs '.
|
throw new ClientException(_('That email address already belongs to another user.'));
|
||||||
'to another user.'));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Event::handle('StartAddEmailAddress', array($user, $email))) {
|
if (Event::handle('StartAddEmailAddress', array($user, $email))) {
|
||||||
@ -399,7 +358,7 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
|
|
||||||
$confirm->address = $email;
|
$confirm->address = $email;
|
||||||
$confirm->address_type = 'email';
|
$confirm->address_type = 'email';
|
||||||
$confirm->user_id = $user->id;
|
$confirm->user_id = $user->getID();
|
||||||
$confirm->code = common_confirmation_code(64);
|
$confirm->code = common_confirmation_code(64);
|
||||||
|
|
||||||
$result = $confirm->insert();
|
$result = $confirm->insert();
|
||||||
@ -407,21 +366,19 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
common_log_db_error($confirm, 'INSERT', __FILE__);
|
common_log_db_error($confirm, 'INSERT', __FILE__);
|
||||||
// TRANS: Server error thrown on database error adding e-mail confirmation code.
|
// TRANS: Server error thrown on database error adding e-mail confirmation code.
|
||||||
$this->serverError(_('Could not insert confirmation code.'));
|
throw new ServerException(_('Could not insert confirmation code.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
common_debug('Sending confirmation address for user '.$user->id.' to email '.$email);
|
common_debug('Sending confirmation address for user '.$user->getID().' to email '.$email);
|
||||||
mail_confirm_address($user, $confirm->code, $user->nickname, $email);
|
mail_confirm_address($user, $confirm->code, $user->getNickname(), $email);
|
||||||
|
|
||||||
Event::handle('EndAddEmailAddress', array($user, $email));
|
Event::handle('EndAddEmailAddress', array($user, $email));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRANS: Message given saving valid e-mail address that is to be confirmed.
|
// TRANS: Message given saving valid e-mail address that is to be confirmed.
|
||||||
$msg = _('A confirmation code was sent to the email address you added. '.
|
return _('A confirmation code was sent to the email address you added. '.
|
||||||
'Check your inbox (and spam box!) for the code and instructions '.
|
'Check your inbox (and spam box!) for the code and instructions '.
|
||||||
'on how to use it.');
|
'on how to use it.');
|
||||||
|
|
||||||
$this->showForm($msg, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -431,31 +388,29 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function cancelConfirmation()
|
function cancelConfirmation()
|
||||||
{
|
{
|
||||||
$email = $this->arg('email');
|
$email = $this->trimmed('email');
|
||||||
|
|
||||||
$confirm = $this->getConfirmation();
|
try {
|
||||||
|
$confirm = $this->getConfirmation();
|
||||||
if (!$confirm) {
|
if ($confirm->address !== $email) {
|
||||||
|
// TRANS: Message given canceling e-mail address confirmation for the wrong e-mail address.
|
||||||
|
throw new ClientException(_('That is the wrong email address.'));
|
||||||
|
}
|
||||||
|
} catch (NoResultException $e) {
|
||||||
// TRANS: Message given canceling e-mail address confirmation that is not pending.
|
// TRANS: Message given canceling e-mail address confirmation that is not pending.
|
||||||
$this->showForm(_('No pending confirmation to cancel.'));
|
throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($confirm->address != $email) {
|
|
||||||
// TRANS: Message given canceling e-mail address confirmation for the wrong e-mail address.
|
|
||||||
$this->showForm(_('That is the wrong email address.'));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $confirm->delete();
|
$result = $confirm->delete();
|
||||||
|
|
||||||
if (!$result) {
|
if ($result === false) {
|
||||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||||
// TRANS: Server error thrown on database error canceling e-mail address confirmation.
|
// TRANS: Server error thrown on database error canceling e-mail address confirmation.
|
||||||
$this->serverError(_('Could not delete email confirmation.'));
|
throw new ServerException(_('Could not delete email confirmation.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRANS: Message given after successfully canceling e-mail address confirmation.
|
// TRANS: Message given after successfully canceling e-mail address confirmation.
|
||||||
$this->showForm(_('Email confirmation cancelled.'), true);
|
return _('Email confirmation cancelled.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -467,26 +422,22 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
$email = $this->arg('email');
|
$email = $this->trimmed('email');
|
||||||
|
|
||||||
// Maybe an old tab open...?
|
// Maybe an old tab open...?
|
||||||
|
if ($user->email !== $email) {
|
||||||
if ($user->email != $email) {
|
|
||||||
// TRANS: Message given trying to remove an e-mail address that is not
|
// TRANS: Message given trying to remove an e-mail address that is not
|
||||||
// TRANS: registered for the active user.
|
// TRANS: registered for the active user.
|
||||||
$this->showForm(_('That is not your email address.'));
|
throw new ClientException(_('That is not your email address.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
|
|
||||||
$user->email = null;
|
$user->email = null;
|
||||||
|
|
||||||
// Throws exception on failure. Also performs it within a transaction.
|
// Throws exception on failure. Also performs it within a transaction.
|
||||||
$user->updateWithKeys($original);
|
$user->updateWithKeys($original);
|
||||||
|
|
||||||
// TRANS: Message given after successfully removing a registered e-mail address.
|
// TRANS: Message given after successfully removing a registered e-mail address.
|
||||||
$this->showForm(_('The email address was removed.'), true);
|
return _('The email address was removed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -498,22 +449,19 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
if (!$user->incomingemail) {
|
if (empty($user->incomingemail)) {
|
||||||
// TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set.
|
// TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set.
|
||||||
$this->showForm(_('No incoming email address.'));
|
throw new AlreadyFulfilledException(_('No incoming email address.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$orig = clone($user);
|
$orig = clone($user);
|
||||||
|
|
||||||
$user->incomingemail = null;
|
$user->incomingemail = null;
|
||||||
$user->emailpost = 0;
|
$user->emailpost = 0;
|
||||||
|
|
||||||
// Throws exception on failure. Also performs it within a transaction.
|
// Throws exception on failure. Also performs it within a transaction.
|
||||||
$user->updateWithKeys($orig);
|
$user->updateWithKeys($orig);
|
||||||
|
|
||||||
// TRANS: Message given after successfully removing an incoming e-mail address.
|
// TRANS: Message given after successfully removing an incoming e-mail address.
|
||||||
$this->showForm(_('Incoming email address removed.'), true);
|
return _('Incoming email address removed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -524,17 +472,14 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
function newIncoming()
|
function newIncoming()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = common_current_user();
|
||||||
|
|
||||||
$orig = clone($user);
|
$orig = clone($user);
|
||||||
|
|
||||||
$user->incomingemail = mail_new_incoming_address();
|
$user->incomingemail = mail_new_incoming_address();
|
||||||
$user->emailpost = 1;
|
$user->emailpost = 1;
|
||||||
|
|
||||||
// Throws exception on failure. Also performs it within a transaction.
|
// Throws exception on failure. Also performs it within a transaction.
|
||||||
$user->updateWithKeys($orig);
|
$user->updateWithKeys($orig);
|
||||||
|
|
||||||
// TRANS: Message given after successfully adding an incoming e-mail address.
|
// TRANS: Message given after successfully adding an incoming e-mail address.
|
||||||
$this->showForm(_('New incoming email address added.'), true);
|
return _('New incoming email address added.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -553,10 +498,10 @@ class EmailsettingsAction extends SettingsAction
|
|||||||
|
|
||||||
$other = User::getKV('email', $email);
|
$other = User::getKV('email', $email);
|
||||||
|
|
||||||
if (!$other) {
|
if (!$other instanceof User) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
return $other->id != $user->id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $other->id != $user->id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,24 +17,22 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
define('LISTENER', 1);
|
define('LISTENER', 1);
|
||||||
define('LISTENEE', -1);
|
define('LISTENEE', -1);
|
||||||
define('BOTH', 0);
|
define('BOTH', 0);
|
||||||
|
|
||||||
// @todo XXX: Documentation missing.
|
// @todo XXX: Documentation missing.
|
||||||
class FoafAction extends Action
|
class FoafAction extends ManagedAction
|
||||||
{
|
{
|
||||||
function isReadOnly($args)
|
function isReadOnly($args)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepare($args)
|
protected function doPreparation()
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
|
||||||
|
|
||||||
$nickname_arg = $this->arg('nickname');
|
$nickname_arg = $this->arg('nickname');
|
||||||
|
|
||||||
if (empty($nickname_arg)) {
|
if (empty($nickname_arg)) {
|
||||||
@ -69,10 +67,8 @@ class FoafAction extends Action
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle($args)
|
public function showPage()
|
||||||
{
|
{
|
||||||
parent::handle($args);
|
|
||||||
|
|
||||||
header('Content-Type: application/rdf+xml');
|
header('Content-Type: application/rdf+xml');
|
||||||
|
|
||||||
$this->startXML();
|
$this->startXML();
|
||||||
|
@ -28,12 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/noticelist.php';
|
|
||||||
require_once INSTALLDIR.'/lib/feedlist.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permalink for a group
|
* Permalink for a group
|
||||||
@ -47,53 +42,22 @@ require_once INSTALLDIR.'/lib/feedlist.php';
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class GroupbyidAction extends Action
|
class GroupbyidAction extends ManagedAction
|
||||||
{
|
{
|
||||||
/** group we're viewing. */
|
/** group we're viewing. */
|
||||||
var $group = null;
|
protected $group = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* Is this page read-only?
|
|
||||||
*
|
|
||||||
* @return boolean true
|
|
||||||
*/
|
|
||||||
function isReadOnly($args)
|
function isReadOnly($args)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepare($args)
|
protected function doPreparation()
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
$this->group = User_group::getByID($this->arg('id'));
|
||||||
|
|
||||||
$id = $this->arg('id');
|
|
||||||
|
|
||||||
if (!$id) {
|
|
||||||
// TRANS: Client error displayed referring to a group's permalink without providing a group ID.
|
|
||||||
$this->clientError(_('No ID.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
common_debug("Got ID $id");
|
|
||||||
|
|
||||||
$this->group = User_group::getKV('id', $id);
|
|
||||||
|
|
||||||
if (!$this->group) {
|
|
||||||
// TRANS: Client error displayed referring to a group's permalink for a non-existing group ID.
|
|
||||||
$this->clientError(_('No such group.'), 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function showPage()
|
||||||
* Handle the request
|
|
||||||
*
|
|
||||||
* Shows a profile for the group, some controls, and a list of
|
|
||||||
* group notices.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handle($args)
|
|
||||||
{
|
{
|
||||||
common_redirect($this->group->homeUrl(), 303);
|
common_redirect($this->group->homeUrl(), 303);
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/rssaction.php';
|
|
||||||
|
|
||||||
define('MEMBERS_PER_SECTION', 27);
|
define('MEMBERS_PER_SECTION', 27);
|
||||||
|
|
||||||
@ -45,10 +41,10 @@ define('MEMBERS_PER_SECTION', 27);
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class groupRssAction extends Rss10Action
|
class GroupRssAction extends TargetedRss10Action
|
||||||
{
|
{
|
||||||
/** group we're viewing. */
|
/** group we're viewing. */
|
||||||
var $group = null;
|
protected $group = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this page read-only?
|
* Is this page read-only?
|
||||||
@ -60,18 +56,8 @@ class groupRssAction extends Rss10Action
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doStreamPreparation()
|
||||||
* Prepare the action
|
|
||||||
*
|
|
||||||
* Reads and validates arguments and instantiates the attributes.
|
|
||||||
*
|
|
||||||
* @param array $args $_REQUEST args
|
|
||||||
*
|
|
||||||
* @return boolean success flag
|
|
||||||
*/
|
|
||||||
function prepare($args)
|
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
|
||||||
|
|
||||||
$nickname_arg = $this->arg('nickname');
|
$nickname_arg = $this->arg('nickname');
|
||||||
$nickname = common_canonical_nickname($nickname_arg);
|
$nickname = common_canonical_nickname($nickname_arg);
|
||||||
@ -90,52 +76,32 @@ class groupRssAction extends Rss10Action
|
|||||||
|
|
||||||
$local = Local_group::getKV('nickname', $nickname);
|
$local = Local_group::getKV('nickname', $nickname);
|
||||||
|
|
||||||
if (!$local) {
|
if (!$local instanceof Local_group) {
|
||||||
// TRANS: Client error displayed when requesting a group RSS feed for group that does not exist.
|
// TRANS: Client error displayed when requesting a group RSS feed for group that does not exist.
|
||||||
$this->clientError(_('No such group.'), 404);
|
$this->clientError(_('No such group.'), 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->group = User_group::getKV('id', $local->group_id);
|
$this->group = $local->getGroup();
|
||||||
|
$this->target = $this->group->getProfile();
|
||||||
if (!$this->group) {
|
|
||||||
// TRANS: Client error displayed when requesting a group RSS feed for an object that is not a group.
|
|
||||||
$this->clientError(_('No such group.'), 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->notices = $this->getNotices($this->limit);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNotices($limit=0)
|
protected function getNotices()
|
||||||
{
|
{
|
||||||
$group = $this->group;
|
$stream = $this->group->getNotices(0, $this->limit);
|
||||||
|
return $stream->fetchAll();
|
||||||
if (is_null($group)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$notices = array();
|
|
||||||
$notice = $group->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
|
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $notices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannel()
|
function getChannel()
|
||||||
{
|
{
|
||||||
$group = $this->group;
|
|
||||||
$c = array('url' => common_local_url('grouprss',
|
$c = array('url' => common_local_url('grouprss',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$group->nickname)),
|
$this->target->getNickname())),
|
||||||
// TRANS: Message is used as link title. %s is a user nickname.
|
// TRANS: Message is used as link title. %s is a user nickname.
|
||||||
'title' => sprintf(_('%s timeline'), $group->nickname),
|
'title' => sprintf(_('%s timeline'), $this->target->getNickname()),
|
||||||
'link' => common_local_url('showgroup', array('nickname' => $group->nickname)),
|
'link' => common_local_url('showgroup', array('nickname' => $this->target->getNickname())),
|
||||||
// TRANS: Message is used as link description. %1$s is a group name, %2$s is a site name.
|
// TRANS: Message is used as link description. %1$s is a group name, %2$s is a site name.
|
||||||
'description' => sprintf(_('Updates from members of %1$s on %2$s!'),
|
'description' => sprintf(_('Updates from members of %1$s on %2$s!'),
|
||||||
$group->nickname, common_config('site', 'name')));
|
$this->target->getNickname(), common_config('site', 'name')));
|
||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for Jabber/XMPP integration
|
* Settings for Jabber/XMPP integration
|
||||||
@ -118,8 +116,8 @@ class ImsettingsAction extends SettingsAction
|
|||||||
// TRANS: Button label to remove a confirmed IM address.
|
// TRANS: Button label to remove a confirmed IM address.
|
||||||
$this->submit('remove', _m('BUTTON','Remove'));
|
$this->submit('remove', _m('BUTTON','Remove'));
|
||||||
} else {
|
} else {
|
||||||
$confirm = $this->getConfirmation($transport);
|
try {
|
||||||
if ($confirm) {
|
$confirm = $this->getConfirmation($transport);
|
||||||
$this->element('p', 'form_unconfirmed', $confirm->address);
|
$this->element('p', 'form_unconfirmed', $confirm->address);
|
||||||
// TRANS: Form note in IM settings form.
|
// TRANS: Form note in IM settings form.
|
||||||
$this->element('p', 'form_note',
|
$this->element('p', 'form_note',
|
||||||
@ -134,7 +132,7 @@ class ImsettingsAction extends SettingsAction
|
|||||||
$this->hidden('screenname', $confirm->address);
|
$this->hidden('screenname', $confirm->address);
|
||||||
// TRANS: Button label to cancel an IM address confirmation procedure.
|
// TRANS: Button label to cancel an IM address confirmation procedure.
|
||||||
$this->submit('cancel', _m('BUTTON','Cancel'));
|
$this->submit('cancel', _m('BUTTON','Cancel'));
|
||||||
} else {
|
} catch (NoResultException $e) {
|
||||||
$this->elementStart('ul', 'form_data');
|
$this->elementStart('ul', 'form_data');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label for IM address.
|
// TRANS: Field label for IM address.
|
||||||
@ -179,8 +177,6 @@ class ImsettingsAction extends SettingsAction
|
|||||||
// TRANS: Checkbox label in IM preferences form.
|
// TRANS: Checkbox label in IM preferences form.
|
||||||
array('name'=>'replies', 'description'=>_('Send me replies '.
|
array('name'=>'replies', 'description'=>_('Send me replies '.
|
||||||
'from people I\'m not subscribed to.')),
|
'from people I\'m not subscribed to.')),
|
||||||
// TRANS: Checkbox label in IM preferences form.
|
|
||||||
array('name'=>'microid', 'description'=>_('Publish a MicroID'))
|
|
||||||
);
|
);
|
||||||
foreach($preferences as $preference)
|
foreach($preferences as $preference)
|
||||||
{
|
{
|
||||||
@ -211,57 +207,35 @@ class ImsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function getConfirmation($transport)
|
function getConfirmation($transport)
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$confirm = new Confirm_address();
|
$confirm = new Confirm_address();
|
||||||
|
|
||||||
$confirm->user_id = $user->id;
|
$confirm->user_id = $this->scoped->getID();
|
||||||
$confirm->address_type = $transport;
|
$confirm->address_type = $transport;
|
||||||
|
|
||||||
if ($confirm->find(true)) {
|
if ($confirm->find(true)) {
|
||||||
return $confirm;
|
return $confirm;
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new NoResultException($confirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPost()
|
||||||
* Handle posts to this form
|
|
||||||
*
|
|
||||||
* Based on the button that was pressed, muxes out to other functions
|
|
||||||
* to do the actual task requested.
|
|
||||||
*
|
|
||||||
* All sub-functions reload the form with a message -- success or failure.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handlePost()
|
|
||||||
{
|
{
|
||||||
// CSRF protection
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->arg('save')) {
|
if ($this->arg('save')) {
|
||||||
$this->savePreferences();
|
return $this->savePreferences();
|
||||||
} else if ($this->arg('add')) {
|
} else if ($this->arg('add')) {
|
||||||
$this->addAddress();
|
return $this->addAddress();
|
||||||
} else if ($this->arg('cancel')) {
|
} else if ($this->arg('cancel')) {
|
||||||
$this->cancelConfirmation();
|
return $this->cancelConfirmation();
|
||||||
} else if ($this->arg('remove')) {
|
} else if ($this->arg('remove')) {
|
||||||
$this->removeAddress();
|
return $this->removeAddress();
|
||||||
} else {
|
|
||||||
// TRANS: Message given submitting a form with an unknown action in Instant Messaging settings.
|
|
||||||
$this->showForm(_('Unexpected form submission.'));
|
|
||||||
}
|
}
|
||||||
|
// TRANS: Message given submitting a form with an unknown action in Instant Messaging settings.
|
||||||
|
throw new ClientException(_('Unexpected form submission.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save user's Jabber preferences
|
* Save user's XMPP preferences
|
||||||
*
|
*
|
||||||
* These are the checkboxes at the bottom of the page. They're used to
|
* These are the checkboxes at the bottom of the page. They're used to
|
||||||
* set different settings
|
* set different settings
|
||||||
@ -270,14 +244,12 @@ class ImsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function savePreferences()
|
function savePreferences()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$user_im_prefs = new User_im_prefs();
|
$user_im_prefs = new User_im_prefs();
|
||||||
$user_im_prefs->query('BEGIN');
|
$user_im_prefs->query('BEGIN');
|
||||||
$user_im_prefs->user_id = $user->id;
|
$user_im_prefs->user_id = $this->scoped->getID();
|
||||||
if($user_im_prefs->find() && $user_im_prefs->fetch())
|
if($user_im_prefs->find() && $user_im_prefs->fetch())
|
||||||
{
|
{
|
||||||
$preferences = array('notify', 'updatefrompresence', 'replies', 'microid');
|
$preferences = array('notify', 'updatefrompresence', 'replies');
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
$original = clone($user_im_prefs);
|
$original = clone($user_im_prefs);
|
||||||
@ -289,15 +261,15 @@ class ImsettingsAction extends SettingsAction
|
|||||||
$result = $new->update($original);
|
$result = $new->update($original);
|
||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user_im_prefs, 'UPDATE', __FILE__);
|
||||||
// TRANS: Server error thrown on database error updating IM preferences.
|
// TRANS: Server error thrown on database error updating IM preferences.
|
||||||
$this->serverError(_('Could not update IM preferences.'));
|
throw new ServerException(_('Could not update IM preferences.'));
|
||||||
}
|
}
|
||||||
}while($user_im_prefs->fetch());
|
}while($user_im_prefs->fetch());
|
||||||
}
|
}
|
||||||
$user_im_prefs->query('COMMIT');
|
$user_im_prefs->query('COMMIT');
|
||||||
// TRANS: Confirmation message for successful IM preferences save.
|
// TRANS: Confirmation message for successful IM preferences save.
|
||||||
$this->showForm(_('Preferences saved.'), true);
|
return _('Preferences saved.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -310,49 +282,42 @@ class ImsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function addAddress()
|
function addAddress()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$screenname = $this->trimmed('screenname');
|
$screenname = $this->trimmed('screenname');
|
||||||
$transport = $this->trimmed('transport');
|
$transport = $this->trimmed('transport');
|
||||||
|
|
||||||
// Some validation
|
// Some validation
|
||||||
|
|
||||||
if (!$screenname) {
|
if (empty($screenname)) {
|
||||||
// TRANS: Message given saving IM address without having provided one.
|
// TRANS: Message given saving IM address without having provided one.
|
||||||
$this->showForm(_('No screenname.'));
|
throw new ClientException(_('No screenname.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$transport) {
|
if (empty($transport)) {
|
||||||
// TRANS: Form validation error when no transport is available setting an IM address.
|
// TRANS: Form validation error when no transport is available setting an IM address.
|
||||||
$this->showForm(_('No transport.'));
|
throw new ClientException(_('No transport.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::handle('NormalizeImScreenname', array($transport, &$screenname));
|
Event::handle('NormalizeImScreenname', array($transport, &$screenname));
|
||||||
|
|
||||||
if (!$screenname) {
|
if (empty($screenname)) {
|
||||||
// TRANS: Message given saving IM address that cannot be normalised.
|
// TRANS: Message given saving IM address that cannot be normalised.
|
||||||
$this->showForm(_('Cannot normalize that screenname.'));
|
throw new ClientException(_('Cannot normalize that screenname.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
$valid = false;
|
$valid = false;
|
||||||
Event::handle('ValidateImScreenname', array($transport, $screenname, &$valid));
|
Event::handle('ValidateImScreenname', array($transport, $screenname, &$valid));
|
||||||
if (!$valid) {
|
if (!$valid) {
|
||||||
// TRANS: Message given saving IM address that not valid.
|
// TRANS: Message given saving IM address that not valid.
|
||||||
$this->showForm(_('Not a valid screenname.'));
|
throw new ClientException(_('Not a valid screenname.'));
|
||||||
return;
|
|
||||||
} else if ($this->screennameExists($transport, $screenname)) {
|
} else if ($this->screennameExists($transport, $screenname)) {
|
||||||
// TRANS: Message given saving IM address that is already set for another user.
|
// TRANS: Message given saving IM address that is already set for another user.
|
||||||
$this->showForm(_('Screenname already belongs to another user.'));
|
throw new ClientException(_('Screenname already belongs to another user.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$confirm = new Confirm_address();
|
$confirm = new Confirm_address();
|
||||||
|
|
||||||
$confirm->address = $screenname;
|
$confirm->address = $screenname;
|
||||||
$confirm->address_type = $transport;
|
$confirm->address_type = $transport;
|
||||||
$confirm->user_id = $user->id;
|
$confirm->user_id = $this->scoped->getID();
|
||||||
$confirm->code = common_confirmation_code(64);
|
$confirm->code = common_confirmation_code(64);
|
||||||
$confirm->sent = common_sql_now();
|
$confirm->sent = common_sql_now();
|
||||||
$confirm->claimed = common_sql_now();
|
$confirm->claimed = common_sql_now();
|
||||||
@ -365,13 +330,10 @@ class ImsettingsAction extends SettingsAction
|
|||||||
$this->serverError(_('Could not insert confirmation code.'));
|
$this->serverError(_('Could not insert confirmation code.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::handle('SendImConfirmationCode', array($transport, $screenname, $confirm->code, $user));
|
Event::handle('SendImConfirmationCode', array($transport, $screenname, $confirm->code, $this->scoped));
|
||||||
|
|
||||||
// TRANS: Message given saving valid IM address that is to be confirmed.
|
// TRANS: Message given saving valid IM address that is to be confirmed.
|
||||||
$msg = _('A confirmation code was sent '.
|
return _('A confirmation code was sent to the IM address you added.');
|
||||||
'to the IM address you added.');
|
|
||||||
|
|
||||||
$this->showForm($msg, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -386,29 +348,27 @@ class ImsettingsAction extends SettingsAction
|
|||||||
$screenname = $this->trimmed('screenname');
|
$screenname = $this->trimmed('screenname');
|
||||||
$transport = $this->trimmed('transport');
|
$transport = $this->trimmed('transport');
|
||||||
|
|
||||||
$confirm = $this->getConfirmation($transport);
|
try {
|
||||||
|
$confirm = $this->getConfirmation($transport);
|
||||||
if (!$confirm) {
|
if ($confirm->address != $screenname) {
|
||||||
|
// TRANS: Message given canceling IM address confirmation for the wrong IM address.
|
||||||
|
throw new ClientException(_('That is the wrong IM address.'));
|
||||||
|
}
|
||||||
|
} catch (NoResultException $e) {
|
||||||
// TRANS: Message given canceling Instant Messaging address confirmation that is not pending.
|
// TRANS: Message given canceling Instant Messaging address confirmation that is not pending.
|
||||||
$this->showForm(_('No pending confirmation to cancel.'));
|
throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($confirm->address != $screenname) {
|
|
||||||
// TRANS: Message given canceling IM address confirmation for the wrong IM address.
|
|
||||||
$this->showForm(_('That is the wrong IM address.'));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $confirm->delete();
|
$result = $confirm->delete();
|
||||||
|
|
||||||
if (!$result) {
|
if ($result === false) {
|
||||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||||
// TRANS: Server error thrown on database error canceling IM address confirmation.
|
// TRANS: Server error thrown on database error canceling IM address confirmation.
|
||||||
$this->serverError(_('Could not delete confirmation.'));
|
throw new ServerException(_('Could not delete confirmation.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRANS: Message given after successfully canceling IM address confirmation.
|
// TRANS: Message given after successfully canceling IM address confirmation.
|
||||||
$this->showForm(_('IM confirmation cancelled.'), true);
|
return _('IM confirmation cancelled.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -420,34 +380,32 @@ class ImsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function removeAddress()
|
function removeAddress()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$screenname = $this->trimmed('screenname');
|
$screenname = $this->trimmed('screenname');
|
||||||
$transport = $this->trimmed('transport');
|
$transport = $this->trimmed('transport');
|
||||||
|
|
||||||
// Maybe an old tab open...?
|
// Maybe an old tab open...?
|
||||||
|
|
||||||
$user_im_prefs = new User_im_prefs();
|
$user_im_prefs = new User_im_prefs();
|
||||||
$user_im_prefs->user_id = $user->id;
|
$user_im_prefs->user_id = $this->scoped->getID();
|
||||||
if(! ($user_im_prefs->find() && $user_im_prefs->fetch())) {
|
$user_im_prefs->transport = $transport;
|
||||||
|
if (!$user_im_prefs->find(true)) {
|
||||||
// TRANS: Message given trying to remove an IM address that is not
|
// TRANS: Message given trying to remove an IM address that is not
|
||||||
// TRANS: registered for the active user.
|
// TRANS: registered for the active user.
|
||||||
$this->showForm(_('That is not your screenname.'));
|
throw new AlreadyFulfilledException(_('There were no preferences stored for this transport.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $user_im_prefs->delete();
|
$result = $user_im_prefs->delete();
|
||||||
|
|
||||||
if (!$result) {
|
if ($result === false) {
|
||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user_im_prefs, 'UPDATE', __FILE__);
|
||||||
// TRANS: Server error thrown on database error removing a registered IM address.
|
// TRANS: Server error thrown on database error removing a registered IM address.
|
||||||
$this->serverError(_('Could not update user IM preferences.'));
|
throw new ServerException(_('Could not update user IM preferences.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: unsubscribe to the old address
|
// XXX: unsubscribe to the old address
|
||||||
|
|
||||||
// TRANS: Message given after successfully removing a registered Instant Messaging address.
|
// TRANS: Message given after successfully removing a registered Instant Messaging address.
|
||||||
$this->showForm(_('The IM address was removed.'), true);
|
return _('The IM address was removed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -463,15 +421,9 @@ class ImsettingsAction extends SettingsAction
|
|||||||
|
|
||||||
function screennameExists($transport, $screenname)
|
function screennameExists($transport, $screenname)
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$user_im_prefs = new User_im_prefs();
|
$user_im_prefs = new User_im_prefs();
|
||||||
$user_im_prefs->transport = $transport;
|
$user_im_prefs->transport = $transport;
|
||||||
$user_im_prefs->screenname = $screenname;
|
$user_im_prefs->screenname = $screenname;
|
||||||
if($user_im_prefs->find() && $user_im_prefs->fetch()){
|
return $user_im_prefs->find(true) ? true : false;
|
||||||
return true;
|
|
||||||
}else{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ class LogoutAction extends ManagedAction
|
|||||||
}
|
}
|
||||||
Event::handle('EndLogout', array($this));
|
Event::handle('EndLogout', array($this));
|
||||||
|
|
||||||
common_redirect(common_local_url('startpage'));
|
common_redirect(common_local_url('top'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accessed through the action on events
|
// Accessed through the action on events
|
||||||
|
@ -41,7 +41,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class NewApplicationAction extends FormAction
|
class NewApplicationAction extends SettingsAction
|
||||||
{
|
{
|
||||||
function title()
|
function title()
|
||||||
{
|
{
|
||||||
@ -54,6 +54,7 @@ class NewApplicationAction extends FormAction
|
|||||||
if ($this->arg('cancel')) {
|
if ($this->arg('cancel')) {
|
||||||
common_redirect(common_local_url('oauthappssettings'), 303);
|
common_redirect(common_local_url('oauthappssettings'), 303);
|
||||||
} elseif ($this->arg('save')) {
|
} elseif ($this->arg('save')) {
|
||||||
|
//trySave will never return, just throw exception or redirect
|
||||||
$this->trySave();
|
$this->trySave();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ class NewApplicationAction extends FormAction
|
|||||||
return _('Use this form to register a new application.');
|
return _('Use this form to register a new application.');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function trySave()
|
protected function trySave()
|
||||||
{
|
{
|
||||||
$name = $this->trimmed('name');
|
$name = $this->trimmed('name');
|
||||||
$description = $this->trimmed('description');
|
$description = $this->trimmed('description');
|
||||||
@ -137,7 +138,7 @@ class NewApplicationAction extends FormAction
|
|||||||
$app->query('BEGIN');
|
$app->query('BEGIN');
|
||||||
|
|
||||||
$app->name = $name;
|
$app->name = $name;
|
||||||
$app->owner = $this->scoped->id;
|
$app->owner = $this->scoped->getID();
|
||||||
$app->description = $description;
|
$app->description = $description;
|
||||||
$app->source_url = $source_url;
|
$app->source_url = $source_url;
|
||||||
$app->organization = $organization;
|
$app->organization = $organization;
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/rssaction.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSS feed for notice search action class.
|
* RSS feed for notice search action class.
|
||||||
@ -48,19 +44,7 @@ require_once INSTALLDIR.'/lib/rssaction.php';
|
|||||||
*/
|
*/
|
||||||
class NoticesearchrssAction extends Rss10Action
|
class NoticesearchrssAction extends Rss10Action
|
||||||
{
|
{
|
||||||
function init()
|
protected function getNotices()
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepare($args)
|
|
||||||
{
|
|
||||||
parent::prepare($args);
|
|
||||||
$this->notices = $this->getNotices();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNotices($limit=0)
|
|
||||||
{
|
{
|
||||||
$q = $this->trimmed('q');
|
$q = $this->trimmed('q');
|
||||||
$notices = array();
|
$notices = array();
|
||||||
@ -70,8 +54,7 @@ class NoticesearchrssAction extends Rss10Action
|
|||||||
$search_engine = $notice->getSearchEngine('notice');
|
$search_engine = $notice->getSearchEngine('notice');
|
||||||
$search_engine->set_sort_mode('chron');
|
$search_engine->set_sort_mode('chron');
|
||||||
|
|
||||||
if (!$limit) $limit = 20;
|
$search_engine->limit(0, $this->limit, true);
|
||||||
$search_engine->limit(0, $limit, true);
|
|
||||||
if (false === $search_engine->query($q)) {
|
if (false === $search_engine->query($q)) {
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,11 +27,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR . '/lib/applicationlist.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a user's registered OAuth applications
|
* Show a user's registered OAuth applications
|
||||||
@ -47,19 +43,11 @@ require_once INSTALLDIR . '/lib/applicationlist.php';
|
|||||||
|
|
||||||
class OauthappssettingsAction extends SettingsAction
|
class OauthappssettingsAction extends SettingsAction
|
||||||
{
|
{
|
||||||
var $page = 0;
|
protected $page = null;
|
||||||
|
|
||||||
function prepare($args)
|
protected function doPreparation()
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
$this->page = $this->int('page') ?: 1;
|
||||||
$this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
|
|
||||||
|
|
||||||
if (!common_logged_in()) {
|
|
||||||
// TRANS: Message displayed to an anonymous user trying to view OAuth application list.
|
|
||||||
$this->clientError(_('You must be logged in to list your applications.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,21 +74,13 @@ class OauthappssettingsAction extends SettingsAction
|
|||||||
return _('Applications you have registered');
|
return _('Applications you have registered');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Content area of the page
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$offset = ($this->page - 1) * APPS_PER_PAGE;
|
$offset = ($this->page - 1) * APPS_PER_PAGE;
|
||||||
$limit = APPS_PER_PAGE + 1;
|
$limit = APPS_PER_PAGE + 1;
|
||||||
|
|
||||||
$application = new Oauth_application();
|
$application = new Oauth_application();
|
||||||
$application->owner = $user->id;
|
$application->owner = $this->scoped->getID();
|
||||||
$application->whereAdd("name != 'anonymous'");
|
$application->whereAdd("name != 'anonymous'");
|
||||||
$application->limit($offset, $limit);
|
$application->limit($offset, $limit);
|
||||||
$application->orderBy('created DESC');
|
$application->orderBy('created DESC');
|
||||||
@ -109,7 +89,7 @@ class OauthappssettingsAction extends SettingsAction
|
|||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
|
|
||||||
if ($application) {
|
if ($application) {
|
||||||
$al = new ApplicationList($application, $user, $this);
|
$al = new ApplicationList($application, $this->scoped, $this);
|
||||||
$cnt = $al->show();
|
$cnt = $al->show();
|
||||||
if (0 == $cnt) {
|
if (0 == $cnt) {
|
||||||
$this->showEmptyListMessage();
|
$this->showEmptyListMessage();
|
||||||
@ -135,34 +115,11 @@ class OauthappssettingsAction extends SettingsAction
|
|||||||
|
|
||||||
function showEmptyListMessage()
|
function showEmptyListMessage()
|
||||||
{
|
{
|
||||||
// TRANS: Empty list message on page with OAuth applications.
|
// TRANS: Empty list message on page with OAuth applications. Markup allowed
|
||||||
$message = sprintf(_('You have not registered any applications yet.'));
|
$message = sprintf(_('You have not registered any applications yet.'));
|
||||||
|
|
||||||
$this->elementStart('div', 'guide');
|
$this->elementStart('div', 'guide');
|
||||||
$this->raw(common_markup_to_html($message));
|
$this->raw(common_markup_to_html($message));
|
||||||
$this->elementEnd('div');
|
$this->elementEnd('div');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle posts to this form
|
|
||||||
*
|
|
||||||
* Based on the button that was pressed, muxes out to other functions
|
|
||||||
* to do the actual task requested.
|
|
||||||
*
|
|
||||||
* All sub-functions reload the form with a message -- success or failure.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function handlePost()
|
|
||||||
{
|
|
||||||
// CSRF protection
|
|
||||||
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR . '/lib/applicationlist.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show connected OAuth applications
|
* Show connected OAuth applications
|
||||||
@ -46,15 +42,14 @@ require_once INSTALLDIR . '/lib/applicationlist.php';
|
|||||||
*/
|
*/
|
||||||
class OauthconnectionssettingsAction extends SettingsAction
|
class OauthconnectionssettingsAction extends SettingsAction
|
||||||
{
|
{
|
||||||
var $page = null;
|
var $page = null;
|
||||||
var $oauth_token = null;
|
|
||||||
|
|
||||||
function prepare($args)
|
protected $oauth_token = null;
|
||||||
|
|
||||||
|
protected function doPreparation()
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
|
||||||
$this->oauth_token = $this->arg('oauth_token');
|
$this->oauth_token = $this->arg('oauth_token');
|
||||||
$this->page = ($this->arg('page')) ? ($this->arg('page') + 0) : 1;
|
$this->page = $this->int('page') ?: 1;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,18 +82,15 @@ class OauthconnectionssettingsAction extends SettingsAction
|
|||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
|
|
||||||
$offset = ($this->page - 1) * APPS_PER_PAGE;
|
$offset = ($this->page - 1) * APPS_PER_PAGE;
|
||||||
$limit = APPS_PER_PAGE + 1;
|
$limit = APPS_PER_PAGE + 1;
|
||||||
|
|
||||||
$connection = $user->getConnectedApps($offset, $limit);
|
$connection = $this->scoped->getConnectedApps($offset, $limit);
|
||||||
|
|
||||||
$cnt = 0;
|
$cnt = 0;
|
||||||
|
|
||||||
if (!empty($connection)) {
|
if (!empty($connection)) {
|
||||||
$cal = new ConnectedAppsList($connection, $user, $this);
|
$cal = new ConnectedAppsList($connection, $this->scoped, $this);
|
||||||
$cnt = $cal->show();
|
$cnt = $cal->show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +103,7 @@ class OauthconnectionssettingsAction extends SettingsAction
|
|||||||
$cnt > APPS_PER_PAGE,
|
$cnt > APPS_PER_PAGE,
|
||||||
$this->page,
|
$this->page,
|
||||||
'connectionssettings',
|
'connectionssettings',
|
||||||
array('nickname' => $user->nickname)
|
array('nickname' => $this->scoped->getNickname())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,24 +117,14 @@ class OauthconnectionssettingsAction extends SettingsAction
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function handlePost()
|
protected function doPost()
|
||||||
{
|
{
|
||||||
// CSRF protection
|
|
||||||
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->arg('revoke')) {
|
if ($this->arg('revoke')) {
|
||||||
$this->revokeAccess($this->oauth_token);
|
return $this->revokeAccess($this->oauth_token);
|
||||||
} else {
|
|
||||||
// TRANS: Client error when submitting a form with unexpected information.
|
|
||||||
$this->clientError(_('Unexpected form submission.'), 401);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TRANS: Client error when submitting a form with unexpected information.
|
||||||
|
throw new ClientException(_('Unexpected form submission.'), 401);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
// This check helps protect against security problems;
|
|
||||||
// your code file can't be executed directly from the web.
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Old-school settings
|
* Old-school settings
|
||||||
@ -77,35 +73,23 @@ class OldschoolsettingsAction extends SettingsAction
|
|||||||
* @return boolean true
|
* @return boolean true
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function prepare($argarray)
|
protected function doPreparation()
|
||||||
{
|
{
|
||||||
if (!common_config('oldschool', 'enabled')) {
|
if (!common_config('oldschool', 'enabled')) {
|
||||||
throw new ClientException("Old-school settings not enabled.");
|
throw new ClientException("Old-school settings not enabled.");
|
||||||
}
|
}
|
||||||
parent::prepare($argarray);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function doPost()
|
||||||
* Handler method
|
|
||||||
*
|
|
||||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function handlePost()
|
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$osp = Old_school_prefs::getKV('user_id', $this->scoped->getID());
|
||||||
|
|
||||||
$osp = Old_school_prefs::getKV('user_id', $user->id);
|
|
||||||
$orig = null;
|
$orig = null;
|
||||||
|
|
||||||
if (!empty($osp)) {
|
if (!empty($osp)) {
|
||||||
$orig = clone($osp);
|
$orig = clone($osp);
|
||||||
} else {
|
} else {
|
||||||
$osp = new Old_school_prefs();
|
$osp = new Old_school_prefs();
|
||||||
$osp->user_id = $user->id;
|
$osp->user_id = $this->scoped->getID();
|
||||||
$osp->created = common_sql_now();
|
$osp->created = common_sql_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,34 +97,25 @@ class OldschoolsettingsAction extends SettingsAction
|
|||||||
$osp->stream_nicknames = $this->boolean('stream_nicknames');
|
$osp->stream_nicknames = $this->boolean('stream_nicknames');
|
||||||
$osp->modified = common_sql_now();
|
$osp->modified = common_sql_now();
|
||||||
|
|
||||||
if (!empty($orig)) {
|
if ($orig instanceof Old_school_prefs) {
|
||||||
$osp->update($orig);
|
$osp->update($orig);
|
||||||
} else {
|
} else {
|
||||||
$osp->insert();
|
$osp->insert();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRANS: Confirmation shown when user profile settings are saved.
|
// TRANS: Confirmation shown when user profile settings are saved.
|
||||||
$this->showForm(_('Settings saved.'), true);
|
return _('Settings saved.');
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showContent()
|
|
||||||
{
|
|
||||||
$user = common_current_user();
|
|
||||||
$form = new OldSchoolForm($this, $user);
|
|
||||||
$form->show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class OldSchoolForm extends Form
|
class OldSchoolSettingsForm extends Form
|
||||||
{
|
{
|
||||||
var $user;
|
var $user;
|
||||||
|
|
||||||
function __construct($out, $user)
|
function __construct(Action $out)
|
||||||
{
|
{
|
||||||
parent::__construct($out);
|
parent::__construct($out);
|
||||||
$this->user = $user;
|
$this->user = $out->getScoped()->getUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('STATUSNET')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change password
|
* Change password
|
||||||
@ -77,18 +73,8 @@ class PasswordsettingsAction extends SettingsAction
|
|||||||
$this->autofocus('oldpassword');
|
$this->autofocus('oldpassword');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Content area of the page
|
|
||||||
*
|
|
||||||
* Shows a form for changing the password
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$this->elementStart('form', array('method' => 'POST',
|
$this->elementStart('form', array('method' => 'POST',
|
||||||
'id' => 'form_password',
|
'id' => 'form_password',
|
||||||
'class' => 'form_settings',
|
'class' => 'form_settings',
|
||||||
@ -102,7 +88,7 @@ class PasswordsettingsAction extends SettingsAction
|
|||||||
|
|
||||||
$this->elementStart('ul', 'form_data');
|
$this->elementStart('ul', 'form_data');
|
||||||
// Users who logged in with OpenID won't have a pwd
|
// Users who logged in with OpenID won't have a pwd
|
||||||
if ($user->password) {
|
if ($this->scoped->hasPassword()) {
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label on page where to change password.
|
// TRANS: Field label on page where to change password.
|
||||||
$this->password('oldpassword', _('Old password'));
|
$this->password('oldpassword', _('Old password'));
|
||||||
@ -129,29 +115,8 @@ class PasswordsettingsAction extends SettingsAction
|
|||||||
$this->elementEnd('form');
|
$this->elementEnd('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPost()
|
||||||
* Handle a post
|
|
||||||
*
|
|
||||||
* Validate input and save changes. Reload the form with a success
|
|
||||||
* or error message.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handlePost()
|
|
||||||
{
|
{
|
||||||
// CSRF protection
|
|
||||||
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = common_current_user();
|
|
||||||
assert(!is_null($user)); // should already be checked
|
|
||||||
|
|
||||||
// FIXME: scrub input
|
// FIXME: scrub input
|
||||||
|
|
||||||
$newpassword = $this->arg('newpassword');
|
$newpassword = $this->arg('newpassword');
|
||||||
@ -161,49 +126,44 @@ class PasswordsettingsAction extends SettingsAction
|
|||||||
|
|
||||||
if (strlen($newpassword) < 6) {
|
if (strlen($newpassword) < 6) {
|
||||||
// TRANS: Form validation error on page where to change password.
|
// TRANS: Form validation error on page where to change password.
|
||||||
$this->showForm(_('Password must be 6 or more characters.'));
|
throw new ClientException(_('Password must be 6 or more characters.'));
|
||||||
return;
|
|
||||||
} else if (0 != strcmp($newpassword, $confirm)) {
|
} else if (0 != strcmp($newpassword, $confirm)) {
|
||||||
// TRANS: Form validation error on password change when password confirmation does not match.
|
// TRANS: Form validation error on password change when password confirmation does not match.
|
||||||
$this->showForm(_('Passwords do not match.'));
|
throw new ClientException(_('Passwords do not match.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($user->password) {
|
$oldpassword = null;
|
||||||
|
if ($this->scoped->hasPassword()) {
|
||||||
$oldpassword = $this->arg('oldpassword');
|
$oldpassword = $this->arg('oldpassword');
|
||||||
|
|
||||||
if (!common_check_user($user->nickname, $oldpassword)) {
|
if (!common_check_user($this->scoped->getNickname(), $oldpassword)) {
|
||||||
// TRANS: Form validation error on page where to change password.
|
// TRANS: Form validation error on page where to change password.
|
||||||
$this->showForm(_('Incorrect old password.'));
|
throw new ClientException(_('Incorrect old password.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
$oldpassword = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$success = false;
|
if (Event::handle('StartChangePassword', array($this->scoped, $oldpassword, $newpassword))) {
|
||||||
if(Event::handle('StartChangePassword', array($user, $oldpassword, $newpassword))){
|
|
||||||
//no handler changed the password, so change the password internally
|
//no handler changed the password, so change the password internally
|
||||||
|
$user = $this->scoped->getUser();
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
|
|
||||||
$user->password = common_munge_password($newpassword, $user->id);
|
$user->password = common_munge_password($newpassword, $this->scoped);
|
||||||
|
|
||||||
$val = $user->validate();
|
$val = $user->validate();
|
||||||
if ($val !== true) {
|
if ($val !== true) {
|
||||||
// TRANS: Form validation error on page where to change password.
|
// TRANS: Form validation error on page where to change password.
|
||||||
$this->showForm(_('Error saving user; invalid.'));
|
throw new ServerException(_('Error saving user; invalid.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$user->update($original)) {
|
if (!$user->update($original)) {
|
||||||
// TRANS: Server error displayed on page where to change password when password change
|
// TRANS: Server error displayed on page where to change password when password change
|
||||||
// TRANS: could not be made because of a server error.
|
// TRANS: could not be made because of a server error.
|
||||||
$this->serverError(_('Cannot save new password.'));
|
throw new ServerException(_('Cannot save new password.'));
|
||||||
}
|
}
|
||||||
Event::handle('EndChangePassword', array($user));
|
Event::handle('EndChangePassword', array($this->scoped));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRANS: Form validation notice on page where to change password.
|
// TRANS: Form validation notice on page where to change password.
|
||||||
$this->showForm(_('Password saved.'), true);
|
return _('Password saved.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,6 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$profile = $this->scoped;
|
|
||||||
$user = $this->scoped->getUser();
|
$user = $this->scoped->getUser();
|
||||||
|
|
||||||
$this->elementStart('form', array('method' => 'post',
|
$this->elementStart('form', array('method' => 'post',
|
||||||
@ -100,7 +99,7 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label in form for profile settings.
|
// TRANS: Field label in form for profile settings.
|
||||||
$this->input('nickname', _('Nickname'),
|
$this->input('nickname', _('Nickname'),
|
||||||
$this->arg('nickname') ?: $profile->nickname,
|
$this->trimmed('nickname') ?: $this->scoped->getNickname(),
|
||||||
// TRANS: Tooltip for field label in form for profile settings.
|
// TRANS: Tooltip for field label in form for profile settings.
|
||||||
_('1-64 lowercase letters or numbers, no punctuation or spaces.'),
|
_('1-64 lowercase letters or numbers, no punctuation or spaces.'),
|
||||||
null, false, // "name" (will be set to id), then "required"
|
null, false, // "name" (will be set to id), then "required"
|
||||||
@ -111,12 +110,12 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label in form for profile settings.
|
// TRANS: Field label in form for profile settings.
|
||||||
$this->input('fullname', _('Full name'),
|
$this->input('fullname', _('Full name'),
|
||||||
($this->arg('fullname')) ? $this->arg('fullname') : $profile->fullname);
|
$this->trimmed('fullname') ?: $this->scoped->getFullname());
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label in form for profile settings.
|
// TRANS: Field label in form for profile settings.
|
||||||
$this->input('homepage', _('Homepage'),
|
$this->input('homepage', _('Homepage'),
|
||||||
($this->arg('homepage')) ? $this->arg('homepage') : $profile->homepage,
|
$this->trimmed('homepage') ?: $this->scoped->getHomepage(),
|
||||||
// TRANS: Tooltip for field label in form for profile settings.
|
// TRANS: Tooltip for field label in form for profile settings.
|
||||||
_('URL of your homepage, blog, or profile on another site.'));
|
_('URL of your homepage, blog, or profile on another site.'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
@ -137,13 +136,13 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
// TRANS: Text area label in form for profile settings where users can provide
|
// TRANS: Text area label in form for profile settings where users can provide
|
||||||
// TRANS: their biography.
|
// TRANS: their biography.
|
||||||
$this->textarea('bio', _('Bio'),
|
$this->textarea('bio', _('Bio'),
|
||||||
($this->arg('bio')) ? $this->arg('bio') : $profile->bio,
|
$this->trimmed('bio') ?: $this->scoped->getDescription(),
|
||||||
$bioInstr);
|
$bioInstr);
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label in form for profile settings.
|
// TRANS: Field label in form for profile settings.
|
||||||
$this->input('location', _('Location'),
|
$this->input('location', _('Location'),
|
||||||
($this->arg('location')) ? $this->arg('location') : $profile->location,
|
$this->trimmed('location') ?: $this->scoped->location,
|
||||||
// TRANS: Tooltip for field label in form for profile settings.
|
// TRANS: Tooltip for field label in form for profile settings.
|
||||||
_('Where you are, like "City, State (or Region), Country".'));
|
_('Where you are, like "City, State (or Region), Country".'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
@ -152,14 +151,14 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
// TRANS: Checkbox label in form for profile settings.
|
// TRANS: Checkbox label in form for profile settings.
|
||||||
$this->checkbox('sharelocation', _('Share my current location when posting notices'),
|
$this->checkbox('sharelocation', _('Share my current location when posting notices'),
|
||||||
($this->arg('sharelocation')) ?
|
($this->arg('sharelocation')) ?
|
||||||
$this->arg('sharelocation') : $this->scoped->shareLocation());
|
$this->boolean('sharelocation') : $this->scoped->shareLocation());
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
}
|
}
|
||||||
Event::handle('EndProfileFormData', array($this));
|
Event::handle('EndProfileFormData', array($this));
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label in form for profile settings.
|
// TRANS: Field label in form for profile settings.
|
||||||
$this->input('tags', _('Tags'),
|
$this->input('tags', _('Tags'),
|
||||||
($this->arg('tags')) ? $this->arg('tags') : implode(' ', $user->getSelfTags()),
|
$this->trimmed('tags') ?: implode(' ', Profile_tag::getSelfTagsArray($this->scoped)),
|
||||||
// TRANS: Tooltip for field label in form for profile settings.
|
// TRANS: Tooltip for field label in form for profile settings.
|
||||||
_('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated.'));
|
_('Tags for yourself (letters, numbers, -, ., and _), comma- or space- separated.'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
@ -228,17 +227,8 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function handlePost()
|
protected function doPost()
|
||||||
{
|
{
|
||||||
// CSRF protection
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Form validation error.
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Event::handle('StartProfileSaveForm', array($this))) {
|
if (Event::handle('StartProfileSaveForm', array($this))) {
|
||||||
|
|
||||||
// $nickname will only be set if this changenick value is true.
|
// $nickname will only be set if this changenick value is true.
|
||||||
@ -246,15 +236,13 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
try {
|
try {
|
||||||
$nickname = Nickname::normalize($this->trimmed('nickname'), true);
|
$nickname = Nickname::normalize($this->trimmed('nickname'), true);
|
||||||
} catch (NicknameTakenException $e) {
|
} catch (NicknameTakenException $e) {
|
||||||
// Abort only if the nickname is occupied by another local profile
|
// Abort only if the nickname is occupied by _another_ local user profile
|
||||||
if ($e->profile->id != $this->scoped->id) {
|
if (!$this->scoped->sameAs($e->profile)) {
|
||||||
$this->showForm($e->getMessage());
|
throw $e;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
$nickname = Nickname::normalize($this->trimmed('nickname')); // without in-use check this time
|
// Since the variable wasn't set before the exception was thrown, let's run
|
||||||
} catch (NicknameException $e) {
|
// the normalize sequence again, but without in-use check this time.
|
||||||
$this->showForm($e->getMessage());
|
$nickname = Nickname::normalize($this->trimmed('nickname'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,33 +261,27 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
if (!is_null($homepage) && (strlen($homepage) > 0) &&
|
if (!is_null($homepage) && (strlen($homepage) > 0) &&
|
||||||
!common_valid_http_url($homepage)) {
|
!common_valid_http_url($homepage)) {
|
||||||
// TRANS: Validation error in form for profile settings.
|
// TRANS: Validation error in form for profile settings.
|
||||||
$this->showForm(_('Homepage is not a valid URL.'));
|
throw new ClientException(_('Homepage is not a valid URL.'));
|
||||||
return;
|
} else if (!is_null($fullname) && mb_strlen($fullname) > 191) {
|
||||||
} else if (!is_null($fullname) && mb_strlen($fullname) > 255) {
|
|
||||||
// TRANS: Validation error in form for profile settings.
|
// TRANS: Validation error in form for profile settings.
|
||||||
$this->showForm(_('Full name is too long (maximum 255 characters).'));
|
throw new ClientException(_('Full name is too long (maximum 191 characters).'));
|
||||||
return;
|
|
||||||
} else if (Profile::bioTooLong($bio)) {
|
} else if (Profile::bioTooLong($bio)) {
|
||||||
// TRANS: Validation error in form for profile settings.
|
// TRANS: Validation error in form for profile settings.
|
||||||
// TRANS: Plural form is used based on the maximum number of allowed
|
// TRANS: Plural form is used based on the maximum number of allowed
|
||||||
// TRANS: characters for the biography (%d).
|
// TRANS: characters for the biography (%d).
|
||||||
$this->showForm(sprintf(_m('Bio is too long (maximum %d character).',
|
throw new ClientException(sprintf(_m('Bio is too long (maximum %d character).',
|
||||||
'Bio is too long (maximum %d characters).',
|
'Bio is too long (maximum %d characters).',
|
||||||
Profile::maxBio()),
|
Profile::maxBio()),
|
||||||
Profile::maxBio()));
|
Profile::maxBio()));
|
||||||
return;
|
} else if (!is_null($location) && mb_strlen($location) > 191) {
|
||||||
} else if (!is_null($location) && mb_strlen($location) > 255) {
|
|
||||||
// TRANS: Validation error in form for profile settings.
|
// TRANS: Validation error in form for profile settings.
|
||||||
$this->showForm(_('Location is too long (maximum 255 characters).'));
|
throw new ClientException(_('Location is too long (maximum 191 characters).'));
|
||||||
return;
|
|
||||||
} else if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) {
|
} else if (is_null($timezone) || !in_array($timezone, DateTimeZone::listIdentifiers())) {
|
||||||
// TRANS: Validation error in form for profile settings.
|
// TRANS: Validation error in form for profile settings.
|
||||||
$this->showForm(_('Timezone not selected.'));
|
throw new ClientException(_('Timezone not selected.'));
|
||||||
return;
|
|
||||||
} else if (!is_null($language) && strlen($language) > 50) {
|
} else if (!is_null($language) && strlen($language) > 50) {
|
||||||
// TRANS: Validation error in form for profile settings.
|
// TRANS: Validation error in form for profile settings.
|
||||||
$this->showForm(_('Language is too long (maximum 50 characters).'));
|
throw new ClientException(_('Language is too long (maximum 50 characters).'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tags = array();
|
$tags = array();
|
||||||
@ -315,15 +297,14 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
if (!common_valid_profile_tag($tag)) {
|
if (!common_valid_profile_tag($tag)) {
|
||||||
// TRANS: Validation error in form for profile settings.
|
// TRANS: Validation error in form for profile settings.
|
||||||
// TRANS: %s is an invalid tag.
|
// TRANS: %s is an invalid tag.
|
||||||
$this->showForm(sprintf(_('Invalid tag: "%s".'), $tag));
|
throw new ClientException(sprintf(_('Invalid tag: "%s".'), $tag));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tag_priv[$tag] = $private;
|
$tag_priv[$tag] = $private;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = common_current_user();
|
$user = $this->scoped->getUser();
|
||||||
$user->query('BEGIN');
|
$user->query('BEGIN');
|
||||||
|
|
||||||
// $user->nickname is updated through Profile->update();
|
// $user->nickname is updated through Profile->update();
|
||||||
@ -346,54 +327,53 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
$result = $user->update($original);
|
$result = $user->update($original);
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||||
|
$user->query('ROLLBACK');
|
||||||
// TRANS: Server error thrown when user profile settings could not be updated to
|
// TRANS: Server error thrown when user profile settings could not be updated to
|
||||||
// TRANS: automatically subscribe to any subscriber.
|
// TRANS: automatically subscribe to any subscriber.
|
||||||
$this->serverError(_('Could not update user for autosubscribe or subscribe_policy.'));
|
throw new ServerException(_('Could not update user for autosubscribe or subscribe_policy.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-initialize language environment if it changed
|
// Re-initialize language environment if it changed
|
||||||
common_init_language();
|
common_init_language();
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile = $user->getProfile();
|
$original = clone($this->scoped);
|
||||||
|
|
||||||
$orig_profile = clone($profile);
|
if (common_config('profile', 'changenick') == true && $this->scoped->getNickname() !== $nickname) {
|
||||||
|
|
||||||
if (common_config('profile', 'changenick') == true && $profile->nickname !== $nickname) {
|
|
||||||
assert(Nickname::normalize($nickname)===$nickname);
|
assert(Nickname::normalize($nickname)===$nickname);
|
||||||
common_debug("Changing user nickname from '{$profile->nickname}' to '{$nickname}'.");
|
common_debug("Changing user nickname from '{$this->scoped->getNickname()}' to '{$nickname}'.");
|
||||||
$profile->nickname = $nickname;
|
$this->scoped->nickname = $nickname;
|
||||||
$profile->profileurl = common_profile_url($profile->nickname);
|
$this->scoped->profileurl = common_profile_url($this->scoped->getNickname());
|
||||||
}
|
}
|
||||||
$profile->fullname = $fullname;
|
$this->scoped->fullname = $fullname;
|
||||||
$profile->homepage = $homepage;
|
$this->scoped->homepage = $homepage;
|
||||||
$profile->bio = $bio;
|
$this->scoped->bio = $bio;
|
||||||
$profile->location = $location;
|
$this->scoped->location = $location;
|
||||||
|
|
||||||
$loc = Location::fromName($location);
|
$loc = Location::fromName($location);
|
||||||
|
|
||||||
if (empty($loc)) {
|
if (empty($loc)) {
|
||||||
$profile->lat = null;
|
$this->scoped->lat = null;
|
||||||
$profile->lon = null;
|
$this->scoped->lon = null;
|
||||||
$profile->location_id = null;
|
$this->scoped->location_id = null;
|
||||||
$profile->location_ns = null;
|
$this->scoped->location_ns = null;
|
||||||
} else {
|
} else {
|
||||||
$profile->lat = $loc->lat;
|
$this->scoped->lat = $loc->lat;
|
||||||
$profile->lon = $loc->lon;
|
$this->scoped->lon = $loc->lon;
|
||||||
$profile->location_id = $loc->location_id;
|
$this->scoped->location_id = $loc->location_id;
|
||||||
$profile->location_ns = $loc->location_ns;
|
$this->scoped->location_ns = $loc->location_ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common_config('location', 'share') == 'user') {
|
if (common_config('location', 'share') == 'user') {
|
||||||
|
|
||||||
$exists = false;
|
$exists = false;
|
||||||
|
|
||||||
$prefs = User_location_prefs::getKV('user_id', $user->id);
|
$prefs = User_location_prefs::getKV('user_id', $this->scoped->getID());
|
||||||
|
|
||||||
if (empty($prefs)) {
|
if (empty($prefs)) {
|
||||||
$prefs = new User_location_prefs();
|
$prefs = new User_location_prefs();
|
||||||
|
|
||||||
$prefs->user_id = $user->id;
|
$prefs->user_id = $this->scoped->getID();
|
||||||
$prefs->created = common_sql_now();
|
$prefs->created = common_sql_now();
|
||||||
} else {
|
} else {
|
||||||
$exists = true;
|
$exists = true;
|
||||||
@ -410,42 +390,37 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
common_log_db_error($prefs, ($exists) ? 'UPDATE' : 'INSERT', __FILE__);
|
common_log_db_error($prefs, ($exists) ? 'UPDATE' : 'INSERT', __FILE__);
|
||||||
|
$user->query('ROLLBACK');
|
||||||
// TRANS: Server error thrown when user profile location preference settings could not be updated.
|
// TRANS: Server error thrown when user profile location preference settings could not be updated.
|
||||||
$this->serverError(_('Could not save location prefs.'));
|
throw new ServerException(_('Could not save location prefs.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
common_debug('Old profile: ' . common_log_objstring($orig_profile), __FILE__);
|
common_debug('Old profile: ' . common_log_objstring($original), __FILE__);
|
||||||
common_debug('New profile: ' . common_log_objstring($profile), __FILE__);
|
common_debug('New profile: ' . common_log_objstring($this->scoped), __FILE__);
|
||||||
|
|
||||||
$result = $profile->update($orig_profile);
|
$result = $this->scoped->update($original);
|
||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
common_log_db_error($profile, 'UPDATE', __FILE__);
|
common_log_db_error($this->scoped, 'UPDATE', __FILE__);
|
||||||
|
$user->query('ROLLBACK');
|
||||||
// TRANS: Server error thrown when user profile settings could not be saved.
|
// TRANS: Server error thrown when user profile settings could not be saved.
|
||||||
$this->serverError(_('Could not save profile.'));
|
throw new ServerException(_('Could not save profile.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the user tags
|
// Set the user tags
|
||||||
$result = $user->setSelfTags($tags, $tag_priv);
|
$result = Profile_tag::setSelfTags($this->scoped, $tags, $tag_priv);
|
||||||
|
|
||||||
if (!$result) {
|
|
||||||
// TRANS: Server error thrown when user profile settings tags could not be saved.
|
|
||||||
$this->serverError(_('Could not save tags.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$user->query('COMMIT');
|
$user->query('COMMIT');
|
||||||
Event::handle('EndProfileSaveForm', array($this));
|
Event::handle('EndProfileSaveForm', array($this));
|
||||||
|
|
||||||
// TRANS: Confirmation shown when user profile settings are saved.
|
// TRANS: Confirmation shown when user profile settings are saved.
|
||||||
$this->showForm(_('Settings saved.'), true);
|
return _('Settings saved.');
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAside() {
|
function showAside() {
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$this->elementStart('div', array('id' => 'aside_primary',
|
$this->elementStart('div', array('id' => 'aside_primary',
|
||||||
'class' => 'aside'));
|
'class' => 'aside'));
|
||||||
|
|
||||||
@ -453,7 +428,7 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
'class' => 'section'));
|
'class' => 'section'));
|
||||||
$this->elementStart('ul');
|
$this->elementStart('ul');
|
||||||
if (Event::handle('StartProfileSettingsActions', array($this))) {
|
if (Event::handle('StartProfileSettingsActions', array($this))) {
|
||||||
if ($user->hasRight(Right::BACKUPACCOUNT)) {
|
if ($this->scoped->hasRight(Right::BACKUPACCOUNT)) {
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->element('a',
|
$this->element('a',
|
||||||
array('href' => common_local_url('backupaccount')),
|
array('href' => common_local_url('backupaccount')),
|
||||||
@ -461,7 +436,7 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
_('Backup account'));
|
_('Backup account'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
}
|
}
|
||||||
if ($user->hasRight(Right::DELETEACCOUNT)) {
|
if ($this->scoped->hasRight(Right::DELETEACCOUNT)) {
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->element('a',
|
$this->element('a',
|
||||||
array('href' => common_local_url('deleteaccount')),
|
array('href' => common_local_url('deleteaccount')),
|
||||||
@ -469,7 +444,7 @@ class ProfilesettingsAction extends SettingsAction
|
|||||||
_('Delete account'));
|
_('Delete account'));
|
||||||
$this->elementEnd('li');
|
$this->elementEnd('li');
|
||||||
}
|
}
|
||||||
if ($user->hasRight(Right::RESTOREACCOUNT)) {
|
if ($this->scoped->hasRight(Right::RESTOREACCOUNT)) {
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
$this->element('a',
|
$this->element('a',
|
||||||
array('href' => common_local_url('restoreaccount')),
|
array('href' => common_local_url('restoreaccount')),
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/rssaction.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSS feed for public timeline.
|
* RSS feed for public timeline.
|
||||||
@ -48,29 +44,6 @@ require_once INSTALLDIR.'/lib/rssaction.php';
|
|||||||
*/
|
*/
|
||||||
class PublicrssAction extends Rss10Action
|
class PublicrssAction extends Rss10Action
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Read arguments and initialize members
|
|
||||||
*
|
|
||||||
* @param array $args Arguments from $_REQUEST
|
|
||||||
* @return boolean success
|
|
||||||
*/
|
|
||||||
function prepare($args)
|
|
||||||
{
|
|
||||||
parent::prepare($args);
|
|
||||||
$this->notices = $this->getNotices($this->limit);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialization.
|
|
||||||
*
|
|
||||||
* @return boolean true
|
|
||||||
*/
|
|
||||||
function init()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get notices
|
* Get notices
|
||||||
*
|
*
|
||||||
@ -78,15 +51,10 @@ class PublicrssAction extends Rss10Action
|
|||||||
*
|
*
|
||||||
* @return array notices
|
* @return array notices
|
||||||
*/
|
*/
|
||||||
function getNotices($limit=0)
|
protected function getNotices()
|
||||||
{
|
{
|
||||||
$notices = array();
|
$stream = Notice::publicStream(0, $this->limit);
|
||||||
$notice = Notice::publicStream(0, ($limit == 0) ? 48 : $limit);
|
return $stream->fetchAll();
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $notices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -325,7 +325,7 @@ class RecoverpasswordAction extends Action
|
|||||||
|
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
|
|
||||||
$user->password = common_munge_password($newpassword, $user->id);
|
$user->password = common_munge_password($newpassword, $user->getProfile());
|
||||||
|
|
||||||
if (!$user->update($original)) {
|
if (!$user->update($original)) {
|
||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
// This check helps protect against security problems;
|
|
||||||
// your code file can't be executed directly from the web.
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redirect to a given URL
|
* Redirect to a given URL
|
||||||
@ -47,75 +43,27 @@ if (!defined('STATUSNET')) {
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class RedirecturlAction extends Action
|
class RedirecturlAction extends ManagedAction
|
||||||
{
|
{
|
||||||
protected $id = null;
|
|
||||||
protected $file = null;
|
protected $file = null;
|
||||||
|
|
||||||
/**
|
protected function doPreparation()
|
||||||
* For initializing members of the class.
|
|
||||||
*
|
|
||||||
* @param array $argarray misc. arguments
|
|
||||||
*
|
|
||||||
* @return boolean true
|
|
||||||
*/
|
|
||||||
function prepare($argarray)
|
|
||||||
{
|
{
|
||||||
parent::prepare($argarray);
|
$this->file = File::getByID($this->int('id'));
|
||||||
|
|
||||||
$this->id = $this->trimmed('id');
|
|
||||||
|
|
||||||
if (empty($this->id)) {
|
|
||||||
// TRANS: Client exception thrown when no ID parameter was provided.
|
|
||||||
throw new ClientException(_('No id parameter.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->file = File::getKV('id', $this->id);
|
|
||||||
|
|
||||||
if (empty($this->file)) {
|
|
||||||
// TRANS: Client exception thrown when an invalid ID parameter was provided for a file.
|
|
||||||
// TRANS: %d is the provided ID for which the file is not present (number).
|
|
||||||
throw new ClientException(sprintf(_('No such file "%d".'),
|
|
||||||
$this->id),
|
|
||||||
404);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function showPage()
|
||||||
* Handler method
|
|
||||||
*
|
|
||||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handle($argarray=null)
|
|
||||||
{
|
{
|
||||||
common_redirect($this->file->url, 307);
|
common_redirect($this->file->url, 307);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if read only.
|
|
||||||
*
|
|
||||||
* MAY override
|
|
||||||
*
|
|
||||||
* @param array $args other arguments
|
|
||||||
*
|
|
||||||
* @return boolean is read only action?
|
|
||||||
*/
|
|
||||||
function isReadOnly($args)
|
function isReadOnly($args)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return last modified, if applicable.
|
|
||||||
*
|
|
||||||
* MAY override
|
|
||||||
*
|
|
||||||
* @return string last modified http header
|
|
||||||
*/
|
|
||||||
function lastModified()
|
function lastModified()
|
||||||
{
|
{
|
||||||
// For comparison with If-Last-Modified
|
// For comparison with If-Last-Modified
|
||||||
@ -133,9 +81,9 @@ class RedirecturlAction extends Action
|
|||||||
*/
|
*/
|
||||||
function etag()
|
function etag()
|
||||||
{
|
{
|
||||||
return 'W/"' . implode(':', array($this->arg('action'),
|
return 'W/"' . implode(':', array($this->getActionName(),
|
||||||
common_user_cache_hash(),
|
common_user_cache_hash(),
|
||||||
common_language(),
|
common_language(),
|
||||||
$this->file->id)) . '"';
|
$this->file->getID())) . '"';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,6 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
|||||||
*/
|
*/
|
||||||
class RepliesAction extends ShowstreamAction
|
class RepliesAction extends ShowstreamAction
|
||||||
{
|
{
|
||||||
var $page = null;
|
|
||||||
var $notice;
|
|
||||||
|
|
||||||
public function getStream()
|
public function getStream()
|
||||||
{
|
{
|
||||||
return new ReplyNoticeStream($this->target->getID(), $this->scoped);
|
return new ReplyNoticeStream($this->target->getID(), $this->scoped);
|
||||||
@ -85,7 +82,7 @@ class RepliesAction extends ShowstreamAction
|
|||||||
// TRANS: Link for feed with replies for a user.
|
// TRANS: Link for feed with replies for a user.
|
||||||
// TRANS: %s is a user nickname.
|
// TRANS: %s is a user nickname.
|
||||||
sprintf(_('Replies feed for %s (Activity Streams JSON)'),
|
sprintf(_('Replies feed for %s (Activity Streams JSON)'),
|
||||||
$this->user->nickname)),
|
$this->target->getNickname())),
|
||||||
new Feed(Feed::RSS1,
|
new Feed(Feed::RSS1,
|
||||||
common_local_url('repliesrss',
|
common_local_url('repliesrss',
|
||||||
array('nickname' => $this->target->getNickname())),
|
array('nickname' => $this->target->getNickname())),
|
||||||
|
@ -17,70 +17,34 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/lib/rssaction.php');
|
|
||||||
|
|
||||||
// Formatting of RSS handled by Rss10Action
|
// Formatting of RSS handled by Rss10Action
|
||||||
|
|
||||||
class RepliesrssAction extends Rss10Action
|
class RepliesrssAction extends TargetedRss10Action
|
||||||
{
|
{
|
||||||
var $user = null;
|
protected function getNotices()
|
||||||
|
|
||||||
function prepare($args)
|
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
$stream = $this->target->getReplies(0, $this->limit);
|
||||||
$nickname = $this->trimmed('nickname');
|
return $stream->fetchAll();
|
||||||
$this->user = User::getKV('nickname', $nickname);
|
|
||||||
|
|
||||||
if (!$this->user) {
|
|
||||||
// TRANS: Client error displayed when providing a non-existing nickname in a RSS 1.0 action.
|
|
||||||
$this->clientError(_('No such user.'));
|
|
||||||
} else {
|
|
||||||
$this->notices = $this->getNotices($this->limit);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNotices($limit=0)
|
|
||||||
{
|
|
||||||
$user = $this->user;
|
|
||||||
|
|
||||||
$notice = $user->getReplies(0, ($limit == 0) ? 48 : $limit);
|
|
||||||
|
|
||||||
$notices = array();
|
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $notices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannel()
|
function getChannel()
|
||||||
{
|
{
|
||||||
$user = $this->user;
|
|
||||||
$c = array('url' => common_local_url('repliesrss',
|
$c = array('url' => common_local_url('repliesrss',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$user->nickname)),
|
$this->target->getNickname())),
|
||||||
// TRANS: RSS reply feed title. %s is a user nickname.
|
// TRANS: RSS reply feed title. %s is a user nickname.
|
||||||
'title' => sprintf(_("Replies to %s"), $user->nickname),
|
'title' => sprintf(_("Replies to %s"), $this->target->getNickname()),
|
||||||
'link' => common_local_url('replies',
|
'link' => common_local_url('replies',
|
||||||
array('nickname' =>
|
array('nickname' => $this->target->getNickname())),
|
||||||
$user->nickname)),
|
|
||||||
// TRANS: RSS reply feed description.
|
// TRANS: RSS reply feed description.
|
||||||
// TRANS: %1$s is a user nickname, %2$s is the StatusNet site name.
|
// TRANS: %1$s is a user nickname, %2$s is the StatusNet site name.
|
||||||
'description' => sprintf(_('Replies to %1$s on %2$s.'),
|
'description' => sprintf(_('Replies to %1$s on %2$s.'),
|
||||||
$user->nickname, common_config('site', 'name')));
|
$this->target->getNickname(), common_config('site', 'name')));
|
||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImage()
|
|
||||||
{
|
|
||||||
$profile = $this->user->getProfile();
|
|
||||||
return $profile->avatarUrl(AVATAR_PROFILE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isReadOnly($args)
|
function isReadOnly($args)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -27,9 +27,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints out a static robots.txt
|
* Prints out a static robots.txt
|
||||||
@ -40,19 +38,9 @@ if (!defined('STATUSNET')) {
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class RobotstxtAction extends Action
|
class RobotstxtAction extends ManagedAction
|
||||||
{
|
{
|
||||||
/**
|
public function showPage()
|
||||||
* Handles requests
|
|
||||||
*
|
|
||||||
* Since this is a relatively static document, we
|
|
||||||
* don't do a prepare()
|
|
||||||
*
|
|
||||||
* @param array $args GET, POST, and URL params; unused.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handle($args)
|
|
||||||
{
|
{
|
||||||
if (Event::handle('StartRobotsTxt', array($this))) {
|
if (Event::handle('StartRobotsTxt', array($this))) {
|
||||||
|
|
||||||
|
@ -222,25 +222,12 @@ class ShownoticeAction extends ManagedAction
|
|||||||
/**
|
/**
|
||||||
* Extra <head> content
|
* Extra <head> content
|
||||||
*
|
*
|
||||||
* We show the microid(s) for the author, if any.
|
* Facebook OpenGraph metadata.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function extraHead()
|
function extraHead()
|
||||||
{
|
{
|
||||||
$user = User::getKV($this->profile->id);
|
|
||||||
|
|
||||||
if (!$user instanceof User) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($user->emailmicroid && $user->email && $this->notice->uri) {
|
|
||||||
$id = new Microid('mailto:'. $user->email,
|
|
||||||
$this->notice->uri);
|
|
||||||
$this->element('meta', array('name' => 'microid',
|
|
||||||
'content' => $id->toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extras to aid in sharing notices to Facebook
|
// Extras to aid in sharing notices to Facebook
|
||||||
$avatarUrl = $this->profile->avatarUrl(AVATAR_PROFILE_SIZE);
|
$avatarUrl = $this->profile->avatarUrl(AVATAR_PROFILE_SIZE);
|
||||||
$this->element('meta', array('property' => 'og:image',
|
$this->element('meta', array('property' => 'og:image',
|
||||||
|
@ -47,37 +47,6 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
|||||||
*/
|
*/
|
||||||
class ShowstreamAction extends NoticestreamAction
|
class ShowstreamAction extends NoticestreamAction
|
||||||
{
|
{
|
||||||
var $notice;
|
|
||||||
|
|
||||||
protected function doPreparation()
|
|
||||||
{
|
|
||||||
// showstream requires a nickname
|
|
||||||
$nickname_arg = $this->arg('nickname');
|
|
||||||
$nickname = common_canonical_nickname($nickname_arg);
|
|
||||||
|
|
||||||
// Permanent redirect on non-canonical nickname
|
|
||||||
|
|
||||||
if ($nickname_arg != $nickname) {
|
|
||||||
$args = array('nickname' => $nickname);
|
|
||||||
if ($this->arg('page') && $this->arg('page') != 1) {
|
|
||||||
$args['page'] = $this->arg['page'];
|
|
||||||
}
|
|
||||||
common_redirect(common_local_url($this->getActionName(), $args), 301);
|
|
||||||
}
|
|
||||||
$this->user = User::getKV('nickname', $nickname);
|
|
||||||
|
|
||||||
if (!$this->user) {
|
|
||||||
$group = Local_group::getKV('nickname', $nickname);
|
|
||||||
if ($group instanceof Local_group) {
|
|
||||||
common_redirect($group->getProfile()->getUrl());
|
|
||||||
}
|
|
||||||
// TRANS: Client error displayed when calling a profile action without specifying a user.
|
|
||||||
$this->clientError(_('No such user.'), 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->target = $this->user->getProfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getStream()
|
public function getStream()
|
||||||
{
|
{
|
||||||
if (empty($this->tag)) {
|
if (empty($this->tag)) {
|
||||||
@ -194,13 +163,6 @@ class ShowstreamAction extends NoticestreamAction
|
|||||||
'content' => $this->target->getDescription()));
|
'content' => $this->target->getDescription()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->target->isLocal() && $this->target->getUser()->emailmicroid && $this->target->getUser()->email && $this->target->getUrl()) {
|
|
||||||
$id = new Microid('mailto:'.$this->target->getUser()->email,
|
|
||||||
$this->selfUrl());
|
|
||||||
$this->element('meta', array('name' => 'microid',
|
|
||||||
'content' => $id->toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// See https://wiki.mozilla.org/Microsummaries
|
// See https://wiki.mozilla.org/Microsummaries
|
||||||
|
|
||||||
$this->element('link', array('rel' => 'microsummary',
|
$this->element('link', array('rel' => 'microsummary',
|
||||||
@ -289,7 +251,7 @@ class ShowstreamAction extends NoticestreamAction
|
|||||||
{
|
{
|
||||||
parent::showSections();
|
parent::showSections();
|
||||||
if (!common_config('performance', 'high')) {
|
if (!common_config('performance', 'high')) {
|
||||||
$cloud = new PersonalTagCloudSection($this, $this->user);
|
$cloud = new PersonalTagCloudSection($this->target, $this);
|
||||||
$cloud->show();
|
$cloud->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,7 +260,7 @@ class ShowstreamAction extends NoticestreamAction
|
|||||||
{
|
{
|
||||||
$options = parent::noticeFormOptions();
|
$options = parent::noticeFormOptions();
|
||||||
|
|
||||||
if (!$this->scoped instanceof Profile || $this->scoped->id != $this->target->id) {
|
if (!$this->scoped instanceof Profile || !$this->scoped->sameAs($this->target)) {
|
||||||
$options['to_profile'] = $this->target;
|
$options['to_profile'] = $this->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,9 +27,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings for SMS
|
* Settings for SMS
|
||||||
@ -45,6 +43,14 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
|
|
||||||
class SmssettingsAction extends SettingsAction
|
class SmssettingsAction extends SettingsAction
|
||||||
{
|
{
|
||||||
|
protected function doPreparation()
|
||||||
|
{
|
||||||
|
if (!common_config('sms', 'enabled')) {
|
||||||
|
// TRANS: Message given in the SMS settings if SMS is not enabled on the site.
|
||||||
|
throw new ServerException(_('SMS is not available.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Title of the page
|
* Title of the page
|
||||||
*
|
*
|
||||||
@ -86,14 +92,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
if (!common_config('sms', 'enabled')) {
|
$user = $this->scoped->getUser();
|
||||||
$this->element('div', array('class' => 'error'),
|
|
||||||
// TRANS: Message given in the SMS settings if SMS is not enabled on the site.
|
|
||||||
_('SMS is not available.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$this->elementStart('form', array('method' => 'post',
|
$this->elementStart('form', array('method' => 'post',
|
||||||
'id' => 'form_settings_sms',
|
'id' => 'form_settings_sms',
|
||||||
@ -118,8 +117,8 @@ class SmssettingsAction extends SettingsAction
|
|||||||
// TRANS: Button label to remove a confirmed SMS address.
|
// TRANS: Button label to remove a confirmed SMS address.
|
||||||
$this->submit('remove', _m('BUTTON','Remove'));
|
$this->submit('remove', _m('BUTTON','Remove'));
|
||||||
} else {
|
} else {
|
||||||
$confirm = $this->getConfirmation();
|
try {
|
||||||
if ($confirm) {
|
$confirm = $this->getConfirmation();
|
||||||
$carrier = Sms_carrier::getKV($confirm->address_extra);
|
$carrier = Sms_carrier::getKV($confirm->address_extra);
|
||||||
$this->element('p', 'form_unconfirmed',
|
$this->element('p', 'form_unconfirmed',
|
||||||
$confirm->address . ' (' . $carrier->name . ')');
|
$confirm->address . ' (' . $carrier->name . ')');
|
||||||
@ -141,7 +140,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
$this->elementEnd('ul');
|
$this->elementEnd('ul');
|
||||||
// TRANS: Button label to confirm SMS confirmation code in SMS settings.
|
// TRANS: Button label to confirm SMS confirmation code in SMS settings.
|
||||||
$this->submit('confirm', _m('BUTTON','Confirm'));
|
$this->submit('confirm', _m('BUTTON','Confirm'));
|
||||||
} else {
|
} catch (NoResultException $e) {
|
||||||
$this->elementStart('ul', 'form_data');
|
$this->elementStart('ul', 'form_data');
|
||||||
$this->elementStart('li');
|
$this->elementStart('li');
|
||||||
// TRANS: Field label for SMS phone number input in SMS settings form.
|
// TRANS: Field label for SMS phone number input in SMS settings form.
|
||||||
@ -216,60 +215,38 @@ class SmssettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function getConfirmation()
|
function getConfirmation()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$confirm = new Confirm_address();
|
$confirm = new Confirm_address();
|
||||||
|
|
||||||
$confirm->user_id = $user->id;
|
$confirm->user_id = $this->scoped->getID();
|
||||||
$confirm->address_type = 'sms';
|
$confirm->address_type = 'sms';
|
||||||
|
|
||||||
if ($confirm->find(true)) {
|
if ($confirm->find(true)) {
|
||||||
return $confirm;
|
return $confirm;
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new NoResultException($confirm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPost()
|
||||||
* Handle posts to this form
|
|
||||||
*
|
|
||||||
* Based on the button that was pressed, muxes out to other functions
|
|
||||||
* to do the actual task requested.
|
|
||||||
*
|
|
||||||
* All sub-functions reload the form with a message -- success or failure.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handlePost()
|
|
||||||
{
|
{
|
||||||
// CSRF protection
|
|
||||||
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->arg('save')) {
|
if ($this->arg('save')) {
|
||||||
$this->savePreferences();
|
return $this->savePreferences();
|
||||||
} else if ($this->arg('add')) {
|
} else if ($this->arg('add')) {
|
||||||
$this->addAddress();
|
return $this->addAddress();
|
||||||
} else if ($this->arg('cancel')) {
|
} else if ($this->arg('cancel')) {
|
||||||
$this->cancelConfirmation();
|
return $this->cancelConfirmation();
|
||||||
} else if ($this->arg('remove')) {
|
} else if ($this->arg('remove')) {
|
||||||
$this->removeAddress();
|
return $this->removeAddress();
|
||||||
} else if ($this->arg('removeincoming')) {
|
} else if ($this->arg('removeincoming')) {
|
||||||
$this->removeIncoming();
|
return $this->removeIncoming();
|
||||||
} else if ($this->arg('newincoming')) {
|
} else if ($this->arg('newincoming')) {
|
||||||
$this->newIncoming();
|
return $this->newIncoming();
|
||||||
} else if ($this->arg('confirm')) {
|
} else if ($this->arg('confirm')) {
|
||||||
$this->confirmCode();
|
return $this->confirmCode();
|
||||||
} else {
|
|
||||||
// TRANS: Message given submitting a form with an unknown action in SMS settings.
|
|
||||||
$this->showForm(_('Unexpected form submission.'));
|
|
||||||
}
|
}
|
||||||
|
// TRANS: Message given submitting a form with an unknown action in SMS settings.
|
||||||
|
throw new ClientException(_('Unexpected form submission.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -281,30 +258,26 @@ class SmssettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function savePreferences()
|
function savePreferences()
|
||||||
{
|
{
|
||||||
$smsnotify = $this->boolean('smsnotify');
|
$user = $this->scoped->getUser();
|
||||||
|
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
assert(!is_null($user)); // should already be checked
|
|
||||||
|
|
||||||
$user->query('BEGIN');
|
$user->query('BEGIN');
|
||||||
|
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
|
|
||||||
$user->smsnotify = $smsnotify;
|
$user->smsnotify = $this->boolean('smsnotify');
|
||||||
|
|
||||||
$result = $user->update($original);
|
$result = $user->update($original);
|
||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||||
// TRANS: Server error thrown on database error updating SMS preferences.
|
// TRANS: Server error thrown on database error updating SMS preferences.
|
||||||
$this->serverError(_('Could not update user.'));
|
throw new ServerException(_('Could not update user.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->query('COMMIT');
|
$user->query('COMMIT');
|
||||||
|
|
||||||
// TRANS: Confirmation message for successful SMS preferences save.
|
// TRANS: Confirmation message for successful SMS preferences save.
|
||||||
$this->showForm(_('SMS preferences saved.'), true);
|
return _('SMS preferences saved.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -324,28 +297,24 @@ class SmssettingsAction extends SettingsAction
|
|||||||
|
|
||||||
// Some validation
|
// Some validation
|
||||||
|
|
||||||
if (!$sms) {
|
if (empty($sms)) {
|
||||||
// TRANS: Message given saving SMS phone number without having provided one.
|
// TRANS: Message given saving SMS phone number without having provided one.
|
||||||
$this->showForm(_('No phone number.'));
|
throw new ClientException(_('No phone number.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$carrier_id) {
|
if (empty($carrier_id)) {
|
||||||
// TRANS: Message given saving SMS phone number without having selected a carrier.
|
// TRANS: Message given saving SMS phone number without having selected a carrier.
|
||||||
$this->showForm(_('No carrier selected.'));
|
throw new ClientException(_('No carrier selected.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$sms = common_canonical_sms($sms);
|
$sms = common_canonical_sms($sms);
|
||||||
|
|
||||||
if ($user->sms == $sms) {
|
if ($user->sms === $sms) {
|
||||||
// TRANS: Message given saving SMS phone number that is already set.
|
// TRANS: Message given saving SMS phone number that is already set.
|
||||||
$this->showForm(_('That is already your phone number.'));
|
throw new AlreadyFulfilledException(_('That is already your phone number.'));
|
||||||
return;
|
|
||||||
} else if ($this->smsExists($sms)) {
|
} else if ($this->smsExists($sms)) {
|
||||||
// TRANS: Message given saving SMS phone number that is already set for another user.
|
// TRANS: Message given saving SMS phone number that is already set for another user.
|
||||||
$this->showForm(_('That phone number already belongs to another user.'));
|
throw new ClientException(_('That phone number already belongs to another user.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$confirm = new Confirm_address();
|
$confirm = new Confirm_address();
|
||||||
@ -353,7 +322,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
$confirm->address = $sms;
|
$confirm->address = $sms;
|
||||||
$confirm->address_extra = $carrier_id;
|
$confirm->address_extra = $carrier_id;
|
||||||
$confirm->address_type = 'sms';
|
$confirm->address_type = 'sms';
|
||||||
$confirm->user_id = $user->id;
|
$confirm->user_id = $this->scoped->getID();
|
||||||
$confirm->code = common_confirmation_code(40);
|
$confirm->code = common_confirmation_code(40);
|
||||||
|
|
||||||
$result = $confirm->insert();
|
$result = $confirm->insert();
|
||||||
@ -371,11 +340,9 @@ class SmssettingsAction extends SettingsAction
|
|||||||
$carrier->toEmailAddress($sms));
|
$carrier->toEmailAddress($sms));
|
||||||
|
|
||||||
// TRANS: Message given saving valid SMS phone number that is to be confirmed.
|
// TRANS: Message given saving valid SMS phone number that is to be confirmed.
|
||||||
$msg = _('A confirmation code was sent to the phone number you added. '.
|
return _('A confirmation code was sent to the phone number you added. '.
|
||||||
'Check your phone for the code and instructions '.
|
'Check your phone for the code and instructions '.
|
||||||
'on how to use it.');
|
'on how to use it.');
|
||||||
|
|
||||||
$this->showForm($msg, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -390,29 +357,27 @@ class SmssettingsAction extends SettingsAction
|
|||||||
$sms = $this->trimmed('sms');
|
$sms = $this->trimmed('sms');
|
||||||
$carrier = $this->trimmed('carrier');
|
$carrier = $this->trimmed('carrier');
|
||||||
|
|
||||||
$confirm = $this->getConfirmation();
|
try {
|
||||||
|
$confirm = $this->getConfirmation();
|
||||||
if (!$confirm) {
|
if ($confirm->address != $sms) {
|
||||||
|
// TRANS: Message given canceling SMS phone number confirmation for the wrong phone number.
|
||||||
|
throw new ClientException(_('That is the wrong confirmation number.'));
|
||||||
|
}
|
||||||
|
} catch (NoResultException $e) {
|
||||||
// TRANS: Message given canceling SMS phone number confirmation that is not pending.
|
// TRANS: Message given canceling SMS phone number confirmation that is not pending.
|
||||||
$this->showForm(_('No pending confirmation to cancel.'));
|
throw new AlreadyFulfilledException(_('No pending confirmation to cancel.'));
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($confirm->address != $sms) {
|
|
||||||
// TRANS: Message given canceling SMS phone number confirmation for the wrong phone number.
|
|
||||||
$this->showForm(_('That is the wrong confirmation number.'));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $confirm->delete();
|
$result = $confirm->delete();
|
||||||
|
|
||||||
if (!$result) {
|
if ($result === false) {
|
||||||
common_log_db_error($confirm, 'DELETE', __FILE__);
|
common_log_db_error($confirm, 'DELETE', __FILE__);
|
||||||
// TRANS: Server error thrown on database error canceling SMS phone number confirmation.
|
// TRANS: Server error thrown on database error canceling SMS phone number confirmation.
|
||||||
$this->serverError(_('Could not delete SMS confirmation.'));
|
throw new ServerException(_('Could not delete SMS confirmation.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TRANS: Message given after successfully canceling SMS phone number confirmation.
|
// TRANS: Message given after successfully canceling SMS phone number confirmation.
|
||||||
$this->showForm(_('SMS confirmation cancelled.'), true);
|
return _('SMS confirmation cancelled.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -422,7 +387,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function removeAddress()
|
function removeAddress()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = $this->scoped->getUser();
|
||||||
|
|
||||||
$sms = $this->arg('sms');
|
$sms = $this->arg('sms');
|
||||||
$carrier = $this->arg('carrier');
|
$carrier = $this->arg('carrier');
|
||||||
@ -432,8 +397,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
if ($user->sms != $sms) {
|
if ($user->sms != $sms) {
|
||||||
// TRANS: Message given trying to remove an SMS phone number that is not
|
// TRANS: Message given trying to remove an SMS phone number that is not
|
||||||
// TRANS: registered for the active user.
|
// TRANS: registered for the active user.
|
||||||
$this->showForm(_('That is not your phone number.'));
|
throw new ClientException(_('That is not your phone number.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$original = clone($user);
|
$original = clone($user);
|
||||||
@ -446,7 +410,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
$user->updateWithKeys($original);
|
$user->updateWithKeys($original);
|
||||||
|
|
||||||
// TRANS: Message given after successfully removing a registered SMS phone number.
|
// TRANS: Message given after successfully removing a registered SMS phone number.
|
||||||
$this->showForm(_('The SMS phone number was removed.'), true);
|
return _('The SMS phone number was removed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -460,15 +424,13 @@ class SmssettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function smsExists($sms)
|
function smsExists($sms)
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$other = User::getKV('sms', $sms);
|
$other = User::getKV('sms', $sms);
|
||||||
|
|
||||||
if (!$other) {
|
if (!$other instanceof User) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
|
||||||
return $other->id != $user->id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return !$this->scoped->sameAs($other->getProfile());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -519,15 +481,12 @@ class SmssettingsAction extends SettingsAction
|
|||||||
{
|
{
|
||||||
$code = $this->trimmed('code');
|
$code = $this->trimmed('code');
|
||||||
|
|
||||||
if (!$code) {
|
if (empty($code)) {
|
||||||
// TRANS: Message given saving SMS phone number confirmation code without having provided one.
|
// TRANS: Message given saving SMS phone number confirmation code without having provided one.
|
||||||
$this->showForm(_('No code entered.'));
|
throw new ClientException(_('No code entered.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
common_redirect(common_local_url('confirmaddress',
|
common_redirect(common_local_url('confirmaddress', array('code' => $code)), 303);
|
||||||
array('code' => $code)),
|
|
||||||
303);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -541,8 +500,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
|
|
||||||
if (!$user->incomingemail) {
|
if (!$user->incomingemail) {
|
||||||
// TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set.
|
// TRANS: Form validation error displayed when trying to remove an incoming e-mail address while no address has been set.
|
||||||
$this->showForm(_('No incoming email address.'));
|
throw new ClientException(_('No incoming email address.'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$orig = clone($user);
|
$orig = clone($user);
|
||||||
@ -553,7 +511,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
$user->updateWithKeys($orig);
|
$user->updateWithKeys($orig);
|
||||||
|
|
||||||
// TRANS: Confirmation text after updating SMS settings.
|
// TRANS: Confirmation text after updating SMS settings.
|
||||||
$this->showForm(_('Incoming email address removed.'), true);
|
return _('Incoming email address removed.');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -565,7 +523,7 @@ class SmssettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function newIncoming()
|
function newIncoming()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = $this->scoped->getUser();
|
||||||
|
|
||||||
$orig = clone($user);
|
$orig = clone($user);
|
||||||
|
|
||||||
@ -575,6 +533,6 @@ class SmssettingsAction extends SettingsAction
|
|||||||
$user->updateWithKeys($orig);
|
$user->updateWithKeys($orig);
|
||||||
|
|
||||||
// TRANS: Confirmation text after updating SMS settings.
|
// TRANS: Confirmation text after updating SMS settings.
|
||||||
$this->showForm(_('New incoming email address added.'), true);
|
return _('New incoming email address added.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Startpage action. Decides what to show on the first page.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!defined('GNUSOCIAL')) { exit(1); }
|
|
||||||
|
|
||||||
class StartpageAction extends ManagedAction
|
|
||||||
{
|
|
||||||
function isReadOnly($args)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showPage()
|
|
||||||
{
|
|
||||||
if (common_config('singleuser', 'enabled')) {
|
|
||||||
$user = User::singleUser();
|
|
||||||
common_redirect(common_local_url('showstream', array('nickname' => $user->nickname)), 303);
|
|
||||||
} elseif (common_config('public', 'localonly')) {
|
|
||||||
common_redirect(common_local_url('public'), 303);
|
|
||||||
} else {
|
|
||||||
common_redirect(common_local_url('networkpublic'), 303);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,9 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of the user's subscriptions
|
* A list of the user's subscriptions
|
||||||
@ -60,7 +58,7 @@ class SubscriptionsAction extends GalleryAction
|
|||||||
|
|
||||||
function showPageNotice()
|
function showPageNotice()
|
||||||
{
|
{
|
||||||
if ($this->scoped instanceof Profile && $this->scoped->id === $this->target->id) {
|
if ($this->scoped instanceof Profile && $this->scoped->sameAs($this->getTarget())) {
|
||||||
$this->element('p', null,
|
$this->element('p', null,
|
||||||
// TRANS: Page notice for page with an overview of all subscriptions
|
// TRANS: Page notice for page with an overview of all subscriptions
|
||||||
// TRANS: of the logged in user's own profile.
|
// TRANS: of the logged in user's own profile.
|
||||||
|
@ -17,38 +17,28 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/lib/rssaction.php');
|
|
||||||
|
|
||||||
// Formatting of RSS handled by Rss10Action
|
// Formatting of RSS handled by Rss10Action
|
||||||
|
|
||||||
class TagrssAction extends Rss10Action
|
class TagrssAction extends Rss10Action
|
||||||
{
|
{
|
||||||
var $tag;
|
protected $tag;
|
||||||
|
|
||||||
function prepare($args) {
|
protected function doStreamPreparation()
|
||||||
parent::prepare($args);
|
{
|
||||||
$tag = common_canonical_tag($this->trimmed('tag'));
|
$tag = common_canonical_tag($this->trimmed('tag'));
|
||||||
$this->tag = Notice_tag::getKV('tag', $tag);
|
$this->tag = Notice_tag::getKV('tag', $tag);
|
||||||
if (!$this->tag) {
|
if (!$this->tag instanceof Notice_tag) {
|
||||||
// TRANS: Client error when requesting a tag feed for a non-existing tag.
|
// TRANS: Client error when requesting a tag feed for a non-existing tag.
|
||||||
$this->clientError(_('No such tag.'));
|
$this->clientError(_('No such tag.'));
|
||||||
} else {
|
|
||||||
$this->notices = $this->getNotices($this->limit);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNotices($limit=0)
|
protected function getNotices()
|
||||||
{
|
{
|
||||||
$tag = $this->tag;
|
$stream = Notice_tag::getStream($this->tag->tag)->getNotices(0, $this->limit);
|
||||||
|
return $stream->fetchAll();
|
||||||
if (is_null($tag)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$notice = Notice_tag::getStream($tag->tag)->getNotices(0, ($limit == 0) ? NOTICES_PER_PAGE : $limit);
|
|
||||||
return $notice->fetchAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannel()
|
function getChannel()
|
||||||
|
@ -20,67 +20,29 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
* @category Top
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
|
||||||
* @copyright 2010 StatusNet, Inc.
|
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!defined('STATUSNET')) {
|
|
||||||
// This check helps protect against security problems;
|
|
||||||
// your code file can't be executed directly from the web.
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An action to redirect to the top of the site
|
|
||||||
*
|
|
||||||
* @category Action
|
* @category Action
|
||||||
* @package StatusNet
|
* @package GNUsocial
|
||||||
* @author Evan Prodromou <evan@status.net>
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Mikael Nordfeldth <mmn@hethane.se>
|
||||||
* @copyright 2010 StatusNet, Inc.
|
* @copyright 2010 StatusNet, Inc.
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0
|
* @copyright 2015 Free Software Foundation, Inc.
|
||||||
* @link http://status.net/
|
* @license https://www.gnu.org/licenses/agpl-3.0.html AGPL 3.0
|
||||||
|
* @link https://gnu.io/social
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class TopAction extends Action
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
|
class TopAction extends ManagedAction
|
||||||
{
|
{
|
||||||
/**
|
public function showPage()
|
||||||
* For initializing members of the class.
|
|
||||||
*
|
|
||||||
* @param array $argarray misc. arguments
|
|
||||||
*
|
|
||||||
* @return boolean true
|
|
||||||
*/
|
|
||||||
|
|
||||||
function prepare($argarray)
|
|
||||||
{
|
|
||||||
parent::prepare($argarray);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler method
|
|
||||||
*
|
|
||||||
* @param array $argarray is ignored since it's now passed in in prepare()
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function handle($argarray=null)
|
|
||||||
{
|
{
|
||||||
if (common_config('singleuser', 'enabled')) {
|
if (common_config('singleuser', 'enabled')) {
|
||||||
$url = common_local_url('showstream', array('nickname' => User::singleUserNickname()));
|
$user = User::singleUser();
|
||||||
|
common_redirect(common_local_url('showstream', array('nickname' => $user->getNickname())), 303);
|
||||||
|
} elseif (common_config('public', 'localonly')) {
|
||||||
|
common_redirect(common_local_url('public'), 303);
|
||||||
} else {
|
} else {
|
||||||
$url = common_local_url('public');
|
common_redirect(common_local_url('networkpublic'), 303);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: Permanent? I think so.
|
|
||||||
|
|
||||||
common_redirect($url, 301);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Miscellaneous settings actions
|
* Miscellaneous settings actions
|
||||||
@ -83,7 +81,7 @@ class UrlsettingsAction extends SettingsAction
|
|||||||
*/
|
*/
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
$user = $this->scoped->getUser();
|
||||||
|
|
||||||
$this->elementStart('form', array('method' => 'post',
|
$this->elementStart('form', array('method' => 'post',
|
||||||
'id' => 'form_settings_other',
|
'id' => 'form_settings_other',
|
||||||
@ -154,31 +152,13 @@ class UrlsettingsAction extends SettingsAction
|
|||||||
$this->elementEnd('form');
|
$this->elementEnd('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPost()
|
||||||
* Handle a post
|
|
||||||
*
|
|
||||||
* Saves the changes to url-shortening prefs and shows a success or failure
|
|
||||||
* message.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function handlePost()
|
|
||||||
{
|
{
|
||||||
// CSRF protection
|
|
||||||
$token = $this->trimmed('token');
|
|
||||||
if (!$token || $token != common_session_token()) {
|
|
||||||
// TRANS: Client error displayed when the session token does not match or is not given.
|
|
||||||
$this->showForm(_('There was a problem with your session token. '.
|
|
||||||
'Try again, please.'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$urlshorteningservice = $this->trimmed('urlshorteningservice');
|
$urlshorteningservice = $this->trimmed('urlshorteningservice');
|
||||||
|
|
||||||
if (!is_null($urlshorteningservice) && strlen($urlshorteningservice) > 50) {
|
if (!is_null($urlshorteningservice) && strlen($urlshorteningservice) > 50) {
|
||||||
// TRANS: Form validation error for form "Other settings" in user profile.
|
// TRANS: Form validation error for form "Other settings" in user profile.
|
||||||
$this->showForm(_('URL shortening service is too long (maximum 50 characters).'));
|
throw new ClientException(_('URL shortening service is too long (maximum 50 characters).'));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$maxurllength = $this->trimmed('maxurllength');
|
$maxurllength = $this->trimmed('maxurllength');
|
||||||
@ -195,9 +175,7 @@ class UrlsettingsAction extends SettingsAction
|
|||||||
throw new ClientException(_('Invalid number for maximum notice length.'));
|
throw new ClientException(_('Invalid number for maximum notice length.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$user = common_current_user();
|
$user = $this->scoped->getUser();
|
||||||
|
|
||||||
assert(!is_null($user)); // should already be checked
|
|
||||||
|
|
||||||
$user->query('BEGIN');
|
$user->query('BEGIN');
|
||||||
|
|
||||||
@ -209,14 +187,15 @@ class UrlsettingsAction extends SettingsAction
|
|||||||
|
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
common_log_db_error($user, 'UPDATE', __FILE__);
|
common_log_db_error($user, 'UPDATE', __FILE__);
|
||||||
|
$user->query('ROLLBACK');
|
||||||
// TRANS: Server error displayed when "Other" settings in user profile could not be updated on the server.
|
// TRANS: Server error displayed when "Other" settings in user profile could not be updated on the server.
|
||||||
$this->serverError(_('Could not update user.'));
|
throw new ServerException(_('Could not update user.'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$prefs = User_urlshortener_prefs::getPrefs($user);
|
$prefs = User_urlshortener_prefs::getPrefs($user);
|
||||||
$orig = null;
|
$orig = null;
|
||||||
|
|
||||||
if (empty($prefs)) {
|
if (!$prefs instanceof User_urlshortener_prefs) {
|
||||||
$prefs = new User_urlshortener_prefs();
|
$prefs = new User_urlshortener_prefs();
|
||||||
|
|
||||||
$prefs->user_id = $user->id;
|
$prefs->user_id = $user->id;
|
||||||
@ -229,13 +208,14 @@ class UrlsettingsAction extends SettingsAction
|
|||||||
$prefs->maxurllength = $maxurllength;
|
$prefs->maxurllength = $maxurllength;
|
||||||
$prefs->maxnoticelength = $maxnoticelength;
|
$prefs->maxnoticelength = $maxnoticelength;
|
||||||
|
|
||||||
if (!empty($orig)) {
|
if ($orig instanceof User_urlshortener_prefs) {
|
||||||
$result = $prefs->update($orig);
|
$result = $prefs->update($orig);
|
||||||
} else {
|
} else {
|
||||||
$result = $prefs->insert();
|
$result = $prefs->insert();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$result) {
|
if ($result === null) {
|
||||||
|
$user->query('ROLLBACK');
|
||||||
// TRANS: Server exception thrown in profile URL settings when preferences could not be saved.
|
// TRANS: Server exception thrown in profile URL settings when preferences could not be saved.
|
||||||
throw new ServerException(_('Error saving user URL shortening preferences.'));
|
throw new ServerException(_('Error saving user URL shortening preferences.'));
|
||||||
}
|
}
|
||||||
@ -243,6 +223,6 @@ class UrlsettingsAction extends SettingsAction
|
|||||||
$user->query('COMMIT');
|
$user->query('COMMIT');
|
||||||
|
|
||||||
// TRANS: Confirmation message after saving preferences.
|
// TRANS: Confirmation message after saving preferences.
|
||||||
$this->showForm(_('Preferences saved.'), true);
|
return _('Preferences saved.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,12 +52,12 @@ class UsergroupsAction extends GalleryAction
|
|||||||
if ($this->page == 1) {
|
if ($this->page == 1) {
|
||||||
// TRANS: Page title for first page of groups for a user.
|
// TRANS: Page title for first page of groups for a user.
|
||||||
// TRANS: %s is a nickname.
|
// TRANS: %s is a nickname.
|
||||||
return sprintf(_('%s groups'), $this->user->nickname);
|
return sprintf(_('%s groups'), $this->getTarget()->getNickname());
|
||||||
} else {
|
} else {
|
||||||
// TRANS: Page title for all but the first page of groups for a user.
|
// TRANS: Page title for all but the first page of groups for a user.
|
||||||
// TRANS: %1$s is a nickname, %2$d is a page number.
|
// TRANS: %1$s is a nickname, %2$d is a page number.
|
||||||
return sprintf(_('%1$s groups, page %2$d'),
|
return sprintf(_('%1$s groups, page %2$d'),
|
||||||
$this->user->nickname,
|
$this->getTarget()->getNickname(),
|
||||||
$this->page);
|
$this->page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,14 +82,14 @@ class UsergroupsAction extends GalleryAction
|
|||||||
$offset = ($this->page-1) * GROUPS_PER_PAGE;
|
$offset = ($this->page-1) * GROUPS_PER_PAGE;
|
||||||
$limit = GROUPS_PER_PAGE + 1;
|
$limit = GROUPS_PER_PAGE + 1;
|
||||||
|
|
||||||
$groups = $this->user->getGroups($offset, $limit);
|
$groups = $this->getTarget()->getGroups($offset, $limit);
|
||||||
|
|
||||||
if ($groups instanceof User_group) {
|
if ($groups instanceof User_group) {
|
||||||
$gl = new GroupList($groups, $this->user, $this);
|
$gl = new GroupList($groups, $this->getTarget(), $this);
|
||||||
$cnt = $gl->show();
|
$cnt = $gl->show();
|
||||||
$this->pagination($this->page > 1, $cnt > GROUPS_PER_PAGE,
|
$this->pagination($this->page > 1, $cnt > GROUPS_PER_PAGE,
|
||||||
$this->page, 'usergroups',
|
$this->page, 'usergroups',
|
||||||
array('nickname' => $this->user->nickname));
|
array('nickname' => $this->getTarget()->getNickname()));
|
||||||
} else {
|
} else {
|
||||||
$this->showEmptyListMessage();
|
$this->showEmptyListMessage();
|
||||||
}
|
}
|
||||||
@ -102,11 +102,11 @@ class UsergroupsAction extends GalleryAction
|
|||||||
{
|
{
|
||||||
// TRANS: Text on group page for a user that is not a member of any group.
|
// TRANS: Text on group page for a user that is not a member of any group.
|
||||||
// TRANS: %s is a user nickname.
|
// TRANS: %s is a user nickname.
|
||||||
$message = sprintf(_('%s is not a member of any group.'), $this->user->nickname) . ' ';
|
$message = sprintf(_('%s is not a member of any group.'), $this->getTarget()->getNickname()) . ' ';
|
||||||
|
|
||||||
if (common_logged_in()) {
|
if (common_logged_in()) {
|
||||||
$current_user = common_current_user();
|
$current_user = common_current_user();
|
||||||
if ($this->user->id === $current_user->id) {
|
if ($this->scoped->sameAs($this->getTarget())) {
|
||||||
// TRANS: Text on group page for a user that is not a member of any group. This message contains
|
// TRANS: Text on group page for a user that is not a member of any group. This message contains
|
||||||
// TRANS: a Markdown link in the form [link text](link) and a variable that should not be changed.
|
// TRANS: a Markdown link in the form [link text](link) and a variable that should not be changed.
|
||||||
$message .= _('Try [searching for groups](%%action.groupsearch%%) and joining them.');
|
$message .= _('Try [searching for groups](%%action.groupsearch%%) and joining them.');
|
||||||
@ -119,7 +119,7 @@ class UsergroupsAction extends GalleryAction
|
|||||||
|
|
||||||
function showProfileBlock()
|
function showProfileBlock()
|
||||||
{
|
{
|
||||||
$block = new AccountProfileBlock($this, $this->profile);
|
$block = new AccountProfileBlock($this, $this->getTarget());
|
||||||
$block->show();
|
$block->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,100 +17,54 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
require_once(INSTALLDIR.'/lib/rssaction.php');
|
|
||||||
|
|
||||||
// Formatting of RSS handled by Rss10Action
|
// Formatting of RSS handled by Rss10Action
|
||||||
|
|
||||||
class UserrssAction extends Rss10Action
|
class UserrssAction extends TargetedRss10Action
|
||||||
{
|
{
|
||||||
var $tag = null;
|
protected $tag = null;
|
||||||
|
|
||||||
function prepare($args)
|
protected function doStreamPreparation()
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
parent::doStreamPreparation();
|
||||||
$nickname = $this->trimmed('nickname');
|
|
||||||
$this->user = User::getKV('nickname', $nickname);
|
|
||||||
$this->tag = $this->trimmed('tag');
|
$this->tag = $this->trimmed('tag');
|
||||||
|
}
|
||||||
|
|
||||||
if (!$this->user) {
|
protected function getNotices()
|
||||||
// TRANS: Client error displayed when user not found for an action.
|
{
|
||||||
$this->clientError(_('No such user.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty($this->tag)) {
|
if (!empty($this->tag)) {
|
||||||
$this->notices = $this->getTaggedNotices();
|
$stream = $this->getTarget()->getTaggedNotices($this->tag, 0, $this->limit);
|
||||||
} else {
|
return $stream->fetchAll();
|
||||||
$this->notices = $this->getNotices();
|
|
||||||
}
|
}
|
||||||
|
// otherwise we fetch a normal user stream
|
||||||
|
|
||||||
return true;
|
$stream = $this->getTarget()->getNotices(0, $this->limit);
|
||||||
}
|
return $stream->fetchAll();
|
||||||
|
|
||||||
function getTaggedNotices()
|
|
||||||
{
|
|
||||||
$notice = $this->user->getTaggedNotices(
|
|
||||||
$this->tag,
|
|
||||||
0,
|
|
||||||
($this->limit == 0) ? NOTICES_PER_PAGE : $this->limit,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
|
|
||||||
$notices = array();
|
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $notices;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function getNotices()
|
|
||||||
{
|
|
||||||
$notice = $this->user->getNotices(
|
|
||||||
0,
|
|
||||||
($this->limit == 0) ? NOTICES_PER_PAGE : $this->limit
|
|
||||||
);
|
|
||||||
|
|
||||||
$notices = array();
|
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $notices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChannel()
|
function getChannel()
|
||||||
{
|
{
|
||||||
$user = $this->user;
|
|
||||||
$profile = $user->getProfile();
|
|
||||||
$c = array('url' => common_local_url('userrss',
|
$c = array('url' => common_local_url('userrss',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$user->nickname)),
|
$this->target->getNickname())),
|
||||||
// TRANS: Message is used as link title. %s is a user nickname.
|
// TRANS: Message is used as link title. %s is a user nickname.
|
||||||
'title' => sprintf(_('%s timeline'), $user->nickname),
|
'title' => sprintf(_('%s timeline'), $this->target->getNickname()),
|
||||||
'link' => $profile->profileurl,
|
'link' => $this->target->getUrl(),
|
||||||
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
|
// TRANS: Message is used as link description. %1$s is a username, %2$s is a site name.
|
||||||
'description' => sprintf(_('Updates from %1$s on %2$s!'),
|
'description' => sprintf(_('Updates from %1$s on %2$s!'),
|
||||||
$user->nickname, common_config('site', 'name')));
|
$this->target->getNickname(), common_config('site', 'name')));
|
||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImage()
|
|
||||||
{
|
|
||||||
$profile = $this->user->getProfile();
|
|
||||||
return $profile->avatarUrl(AVATAR_PROFILE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// override parent to add X-SUP-ID URL
|
// override parent to add X-SUP-ID URL
|
||||||
|
|
||||||
function initRss($limit=0)
|
function initRss()
|
||||||
{
|
{
|
||||||
$url = common_local_url('sup', null, null, $this->user->id);
|
$url = common_local_url('sup', null, null, $this->target->getID());
|
||||||
header('X-SUP-ID: '.$url);
|
header('X-SUP-ID: '.$url);
|
||||||
parent::initRss($limit);
|
parent::initRss();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isReadOnly($args)
|
function isReadOnly($args)
|
||||||
|
0
avatar/.gitignore
vendored
0
avatar/.gitignore
vendored
0
background/.gitignore
vendored
0
background/.gitignore
vendored
@ -110,8 +110,7 @@ class Conversation extends Managed_DataObject
|
|||||||
{
|
{
|
||||||
$conv = new Conversation();
|
$conv = new Conversation();
|
||||||
$conv->id = $notice->conversation;
|
$conv->id = $notice->conversation;
|
||||||
$conv->find(true);
|
if (!$conv->find(true)) {
|
||||||
if (!$conv instanceof Conversation) {
|
|
||||||
common_debug('Conversation does not exist for notice ID: '.$notice->id);
|
common_debug('Conversation does not exist for notice ID: '.$notice->id);
|
||||||
throw new NoResultException($conv);
|
throw new NoResultException($conv);
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ class File_redirection extends Managed_DataObject
|
|||||||
* size (optional): byte size from Content-Length header
|
* size (optional): byte size from Content-Length header
|
||||||
* time (optional): timestamp from Last-Modified header
|
* time (optional): timestamp from Last-Modified header
|
||||||
*/
|
*/
|
||||||
public function where($in_url, $discover=true) {
|
static function where($in_url, $discover=true) {
|
||||||
// let's see if we know this...
|
// let's see if we know this...
|
||||||
try {
|
try {
|
||||||
$a = File::getByUrl($in_url);
|
$a = File::getByUrl($in_url);
|
||||||
@ -176,7 +176,7 @@ class File_redirection extends Managed_DataObject
|
|||||||
try {
|
try {
|
||||||
$b = File_redirection::getByUrl($in_url);
|
$b = File_redirection::getByUrl($in_url);
|
||||||
// this is a redirect to $b->file_id
|
// this is a redirect to $b->file_id
|
||||||
$a = File::getKV('id', $b->file_id);
|
$a = File::getByID($b->file_id);
|
||||||
return $a->url;
|
return $a->url;
|
||||||
} catch (NoResultException $e) {
|
} catch (NoResultException $e) {
|
||||||
// Oh well, let's keep going
|
// Oh well, let's keep going
|
||||||
@ -186,10 +186,10 @@ class File_redirection extends Managed_DataObject
|
|||||||
if ($discover) {
|
if ($discover) {
|
||||||
$ret = File_redirection::lookupWhere($in_url);
|
$ret = File_redirection::lookupWhere($in_url);
|
||||||
return $ret;
|
return $ret;
|
||||||
} else {
|
|
||||||
// No manual dereferencing; leave the unknown URL as is.
|
|
||||||
return $in_url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// No manual dereferencing; leave the unknown URL as is.
|
||||||
|
return $in_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -206,7 +206,7 @@ class File_redirection extends Managed_DataObject
|
|||||||
* @param User $user whose shortening options to use; defaults to the current web session user
|
* @param User $user whose shortening options to use; defaults to the current web session user
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function makeShort($long_url, $user=null)
|
static function makeShort($long_url, $user=null)
|
||||||
{
|
{
|
||||||
$canon = File_redirection::_canonUrl($long_url);
|
$canon = File_redirection::_canonUrl($long_url);
|
||||||
|
|
||||||
@ -214,11 +214,7 @@ class File_redirection extends Managed_DataObject
|
|||||||
|
|
||||||
// Did we get one? Is it shorter?
|
// Did we get one? Is it shorter?
|
||||||
|
|
||||||
if (!empty($short_url)) {
|
return !empty($short_url) ? $short_url : $long_url;
|
||||||
return $short_url;
|
|
||||||
} else {
|
|
||||||
return $long_url;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,18 +231,14 @@ class File_redirection extends Managed_DataObject
|
|||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function forceShort($long_url, $user)
|
static function forceShort($long_url, $user)
|
||||||
{
|
{
|
||||||
$canon = File_redirection::_canonUrl($long_url);
|
$canon = File_redirection::_canonUrl($long_url);
|
||||||
|
|
||||||
$short_url = File_redirection::_userMakeShort($canon, $user, true);
|
$short_url = File_redirection::_userMakeShort($canon, $user, true);
|
||||||
|
|
||||||
// Did we get one? Is it shorter?
|
// Did we get one? Is it shorter?
|
||||||
if (!empty($short_url)) {
|
return !empty($short_url) ? $short_url : $long_url;
|
||||||
return $short_url;
|
|
||||||
} else {
|
|
||||||
return $long_url;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static function _userMakeShort($long_url, User $user=null, $force = false) {
|
static function _userMakeShort($long_url, User $user=null, $force = false) {
|
||||||
|
@ -56,34 +56,37 @@ class Foreign_link extends Managed_DataObject
|
|||||||
static function getByUserID($user_id, $service)
|
static function getByUserID($user_id, $service)
|
||||||
{
|
{
|
||||||
if (empty($user_id) || empty($service)) {
|
if (empty($user_id) || empty($service)) {
|
||||||
return null;
|
throw new ServerException('Empty user_id or service for Foreign_link::getByUserID');
|
||||||
}
|
}
|
||||||
|
|
||||||
$flink = new Foreign_link();
|
$flink = new Foreign_link();
|
||||||
|
|
||||||
$flink->service = $service;
|
$flink->service = $service;
|
||||||
$flink->user_id = $user_id;
|
$flink->user_id = $user_id;
|
||||||
$flink->limit(1);
|
$flink->limit(1);
|
||||||
|
|
||||||
$result = $flink->find(true);
|
if (!$flink->find(true)) {
|
||||||
|
throw new NoResultException($flink);
|
||||||
|
}
|
||||||
|
|
||||||
return empty($result) ? null : $flink;
|
return $flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getByForeignID($foreign_id, $service)
|
static function getByForeignID($foreign_id, $service)
|
||||||
{
|
{
|
||||||
if (empty($foreign_id) || empty($service)) {
|
if (empty($foreign_id) || empty($service)) {
|
||||||
return null;
|
throw new ServerException('Empty foreign_id or service for Foreign_link::getByForeignID');
|
||||||
} else {
|
|
||||||
$flink = new Foreign_link();
|
|
||||||
$flink->service = $service;
|
|
||||||
$flink->foreign_id = $foreign_id;
|
|
||||||
$flink->limit(1);
|
|
||||||
|
|
||||||
$result = $flink->find(true);
|
|
||||||
|
|
||||||
return empty($result) ? null : $flink;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$flink = new Foreign_link();
|
||||||
|
$flink->service = $service;
|
||||||
|
$flink->foreign_id = $foreign_id;
|
||||||
|
$flink->limit(1);
|
||||||
|
|
||||||
|
if (!$flink->find(true)) {
|
||||||
|
throw new NoResultException($flink);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
function set_flags($noticesend, $noticerecv, $replysync, $friendsync)
|
function set_flags($noticesend, $noticerecv, $replysync, $friendsync)
|
||||||
@ -124,21 +127,21 @@ class Foreign_link extends Managed_DataObject
|
|||||||
|
|
||||||
$fuser->limit(1);
|
$fuser->limit(1);
|
||||||
|
|
||||||
if ($fuser->find(true)) {
|
if (!$fuser->find(true)) {
|
||||||
return $fuser;
|
throw new NoResultException($fuser);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return $fuser;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUser()
|
function getUser()
|
||||||
{
|
{
|
||||||
return User::getKV($this->user_id);
|
return Profile::getByID($this->user_id)->getUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProfile()
|
function getProfile()
|
||||||
{
|
{
|
||||||
return Profile::getKV('id', $this->user_id);
|
return Profile::getByID($this->user_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we only ever delete one record at a time
|
// Make sure we only ever delete one record at a time
|
||||||
|
@ -41,33 +41,39 @@ class Foreign_user extends Managed_DataObject
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getForeignUser($id, $service) {
|
static function getForeignUser($id, $service)
|
||||||
|
{
|
||||||
|
if (empty($id) || empty($service)) {
|
||||||
|
throw new ServerException('Empty foreign user id or service for Foreign_user::getForeignUser');
|
||||||
|
}
|
||||||
|
|
||||||
$fuser = new Foreign_user();
|
$fuser = new Foreign_user();
|
||||||
|
|
||||||
$fuser->id = $id;
|
$fuser->id = $id;
|
||||||
$fuser->service = $service;
|
$fuser->service = $service;
|
||||||
|
|
||||||
$fuser->limit(1);
|
$fuser->limit(1);
|
||||||
|
|
||||||
$result = $fuser->find(true);
|
if (!$fuser->find(true)) {
|
||||||
|
throw new NoResultException($fuser);
|
||||||
|
}
|
||||||
|
|
||||||
return empty($result) ? null : $fuser;
|
return $fuser;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getByNickname($nickname, $service)
|
static function getByNickname($nickname, $service)
|
||||||
{
|
{
|
||||||
if (empty($nickname) || empty($service)) {
|
if (empty($nickname) || empty($service)) {
|
||||||
return null;
|
throw new ServerException('Empty nickname or service for Foreign_user::getByNickname');
|
||||||
} else {
|
|
||||||
$fuser = new Foreign_user();
|
|
||||||
$fuser->service = $service;
|
|
||||||
$fuser->nickname = $nickname;
|
|
||||||
$fuser->limit(1);
|
|
||||||
|
|
||||||
$result = $fuser->find(true);
|
|
||||||
|
|
||||||
return empty($result) ? null : $fuser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$fuser = new Foreign_user();
|
||||||
|
$fuser->service = $service;
|
||||||
|
$fuser->nickname = $nickname;
|
||||||
|
$fuser->limit(1);
|
||||||
|
|
||||||
|
if (!$fuser->find(true)) {
|
||||||
|
throw new NoResultException($fuser);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fuser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class Local_group extends Managed_DataObject
|
|||||||
$group->find(true);
|
$group->find(true);
|
||||||
if (!$group instanceof User_group) {
|
if (!$group instanceof User_group) {
|
||||||
common_log(LOG_ERR, 'User_group does not exist for Local_group: '.$this->group_id);
|
common_log(LOG_ERR, 'User_group does not exist for Local_group: '.$this->group_id);
|
||||||
throw new NoResultException($group);
|
throw new NoSuchGroupException(array('id' => $this->group_id));
|
||||||
}
|
}
|
||||||
return $group;
|
return $group;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ class Memcached_DataObject extends Safe_DataObject
|
|||||||
{
|
{
|
||||||
$obj = new $cls;
|
$obj = new $cls;
|
||||||
|
|
||||||
// php-compatible, for settype(), datatype
|
// PHP compatible datatype for settype() below
|
||||||
$colType = $obj->columnType($keyCol);
|
$colType = $obj->columnType($keyCol);
|
||||||
|
|
||||||
if (!in_array($colType, array('integer', 'int'))) {
|
if (!in_array($colType, array('integer', 'int'))) {
|
||||||
|
@ -65,10 +65,6 @@ class Notice extends Managed_DataObject
|
|||||||
public $is_local; // int(4)
|
public $is_local; // int(4)
|
||||||
public $source; // varchar(32)
|
public $source; // varchar(32)
|
||||||
public $conversation; // int(4)
|
public $conversation; // int(4)
|
||||||
public $lat; // decimal(10,7)
|
|
||||||
public $lon; // decimal(10,7)
|
|
||||||
public $location_id; // int(4)
|
|
||||||
public $location_ns; // int(4)
|
|
||||||
public $repeat_of; // int(4)
|
public $repeat_of; // int(4)
|
||||||
public $verb; // varchar(191) not 255 because utf8mb4 takes more space
|
public $verb; // varchar(191) not 255 because utf8mb4 takes more space
|
||||||
public $object_type; // varchar(191) not 255 because utf8mb4 takes more space
|
public $object_type; // varchar(191) not 255 because utf8mb4 takes more space
|
||||||
@ -93,10 +89,6 @@ class Notice extends Managed_DataObject
|
|||||||
'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'),
|
'is_local' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'notice was generated by a user'),
|
||||||
'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'),
|
'source' => array('type' => 'varchar', 'length' => 32, 'description' => 'source of comment, like "web", "im", or "clientname"'),
|
||||||
'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'),
|
'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'),
|
||||||
'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'),
|
|
||||||
'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'),
|
|
||||||
'location_id' => array('type' => 'int', 'description' => 'location id if possible'),
|
|
||||||
'location_ns' => array('type' => 'int', 'description' => 'namespace for location'),
|
|
||||||
'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'),
|
'repeat_of' => array('type' => 'int', 'description' => 'notice this is a repeat of'),
|
||||||
'object_type' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'),
|
'object_type' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams object type', 'default' => 'http://activitystrea.ms/schema/1.0/note'),
|
||||||
'verb' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'),
|
'verb' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'),
|
||||||
@ -196,6 +188,7 @@ class Notice extends Managed_DataObject
|
|||||||
// Clear related records
|
// Clear related records
|
||||||
|
|
||||||
$this->clearReplies();
|
$this->clearReplies();
|
||||||
|
$this->clearLocation();
|
||||||
$this->clearRepeats();
|
$this->clearRepeats();
|
||||||
$this->clearTags();
|
$this->clearTags();
|
||||||
$this->clearGroupInboxes();
|
$this->clearGroupInboxes();
|
||||||
@ -523,18 +516,13 @@ class Notice extends Managed_DataObject
|
|||||||
|
|
||||||
// Handle repeat case
|
// Handle repeat case
|
||||||
|
|
||||||
if (isset($repeat_of)) {
|
if (!empty($options['repeat_of'])) {
|
||||||
|
|
||||||
// Check for a private one
|
// Check for a private one
|
||||||
|
|
||||||
$repeat = Notice::getKV('id', $repeat_of);
|
$repeat = Notice::getByID($options['repeat_of']);
|
||||||
|
|
||||||
if (!($repeat instanceof Notice)) {
|
if ($profile->sameAs($repeat->getProfile())) {
|
||||||
// TRANS: Client exception thrown in notice when trying to repeat a missing or deleted notice.
|
|
||||||
throw new ClientException(_('Cannot repeat; original notice is missing or deleted.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($profile->id == $repeat->profile_id) {
|
|
||||||
// TRANS: Client error displayed when trying to repeat an own notice.
|
// TRANS: Client error displayed when trying to repeat an own notice.
|
||||||
throw new ClientException(_('You cannot repeat your own notice.'));
|
throw new ClientException(_('You cannot repeat your own notice.'));
|
||||||
}
|
}
|
||||||
@ -610,12 +598,13 @@ class Notice extends Managed_DataObject
|
|||||||
if (empty($notice->conversation) and !empty($options['conversation'])) {
|
if (empty($notice->conversation) and !empty($options['conversation'])) {
|
||||||
$conv = Conversation::getKV('uri', $options['conversation']);
|
$conv = Conversation::getKV('uri', $options['conversation']);
|
||||||
if ($conv instanceof Conversation) {
|
if ($conv instanceof Conversation) {
|
||||||
common_debug('Conversation stitched together from (probably) reply to unknown remote user. Activity creation time ('.$notice->created.') should maybe be compared to conversation creation time ('.$conv->created.').');
|
common_debug('Conversation stitched together from (probably) a reply to unknown remote user. Activity creation time ('.$notice->created.') should maybe be compared to conversation creation time ('.$conv->created.').');
|
||||||
$notice->conversation = $conv->id;
|
$notice->conversation = $conv->id;
|
||||||
} else {
|
} else {
|
||||||
// Conversation URI was not found, so we must create it. But we can't create it
|
// Conversation URI was not found, so we must create it. But we can't create it
|
||||||
// until we have a Notice ID because of the database layout...
|
// until we have a Notice ID because of the database layout...
|
||||||
$notice->tmp_conv_uri = $options['conversation'];
|
// $options['conversation'] will be used later after the $notice->insert();
|
||||||
|
common_debug('Conversation URI not found, so we have to create it after inserting this Notice: '.$options['conversation']);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we're not using the attached conversation URI let's remove it
|
// If we're not using the attached conversation URI let's remove it
|
||||||
@ -625,14 +614,15 @@ class Notice extends Managed_DataObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$notloc = new Notice_location();
|
||||||
if (!empty($lat) && !empty($lon)) {
|
if (!empty($lat) && !empty($lon)) {
|
||||||
$notice->lat = $lat;
|
$notloc->lat = $lat;
|
||||||
$notice->lon = $lon;
|
$notloc->lon = $lon;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($location_ns) && !empty($location_id)) {
|
if (!empty($location_ns) && !empty($location_id)) {
|
||||||
$notice->location_id = $location_id;
|
$notloc->location_id = $location_id;
|
||||||
$notice->location_ns = $location_ns;
|
$notloc->location_ns = $location_ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($rendered)) {
|
if (!empty($rendered)) {
|
||||||
@ -671,12 +661,19 @@ class Notice extends Managed_DataObject
|
|||||||
// XXX: some of these functions write to the DB
|
// XXX: some of these functions write to the DB
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$notice->insert(); // throws exception on failure
|
$notice->insert(); // throws exception on failure, if successful we have an ->id
|
||||||
|
|
||||||
|
if (($notloc->lat && $notloc->lon) || ($notloc->location_id && $notloc->location_ns)) {
|
||||||
|
$notloc->notice_id = $notice->getID();
|
||||||
|
$notloc->insert(); // store the notice location if it had any information
|
||||||
|
}
|
||||||
|
|
||||||
// If it's not part of a conversation, it's
|
// If it's not part of a conversation, it's
|
||||||
// the beginning of a new conversation.
|
// the beginning of a new conversation.
|
||||||
if (empty($notice->conversation)) {
|
if (empty($notice->conversation)) {
|
||||||
$orig = clone($notice);
|
$orig = clone($notice);
|
||||||
// $act->context->conversation will be null if it was not provided
|
// $act->context->conversation will be null if it was not provided
|
||||||
|
|
||||||
$conv = Conversation::create($notice, $options['conversation']);
|
$conv = Conversation::create($notice, $options['conversation']);
|
||||||
$notice->conversation = $conv->id;
|
$notice->conversation = $conv->id;
|
||||||
$notice->update($orig);
|
$notice->update($orig);
|
||||||
@ -853,17 +850,28 @@ class Notice extends Managed_DataObject
|
|||||||
if (is_null($scope)) {
|
if (is_null($scope)) {
|
||||||
$scope = $reply->scope;
|
$scope = $reply->scope;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// If we don't know the reply, we might know the conversation!
|
||||||
|
// This will happen if a known remote user replies to an
|
||||||
|
// unknown remote user - within a known conversation.
|
||||||
|
if (empty($stored->conversation) and !empty($act->context->conversation)) {
|
||||||
|
$conv = Conversation::getKV('uri', $act->context->conversation);
|
||||||
|
if ($conv instanceof Conversation) {
|
||||||
|
common_debug('Conversation stitched together from (probably) a reply activity to unknown remote user. Activity creation time ('.$stored->created.') should maybe be compared to conversation creation time ('.$conv->created.').');
|
||||||
|
$stored->conversation = $conv->id;
|
||||||
|
} else {
|
||||||
|
// Conversation URI was not found, so we must create it. But we can't create it
|
||||||
|
// until we have a Notice ID because of the database layout...
|
||||||
|
// $options['conversation'] will be used later after the $stored->insert();
|
||||||
|
common_debug('Conversation URI from activity context not found, so we have to create it after inserting this Notice: '.$act->context->conversation);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$notloc = null;
|
||||||
if ($act->context instanceof ActivityContext) {
|
if ($act->context instanceof ActivityContext) {
|
||||||
$location = $act->context->location;
|
if ($act->context->location instanceof Location) {
|
||||||
if ($location) {
|
$notloc = Notice_location::fromLocation($act->context->location);
|
||||||
$stored->lat = $location->lat;
|
|
||||||
$stored->lon = $location->lon;
|
|
||||||
if ($location->location_id) {
|
|
||||||
$stored->location_ns = $location->location_ns;
|
|
||||||
$stored->location_id = $location->location_id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$act->context = new ActivityContext();
|
$act->context = new ActivityContext();
|
||||||
@ -890,6 +898,12 @@ class Notice extends Managed_DataObject
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$stored->insert(); // throws exception on error
|
$stored->insert(); // throws exception on error
|
||||||
|
|
||||||
|
if ($notloc instanceof Notice_location) {
|
||||||
|
$notloc->notice_id = $stored->getID();
|
||||||
|
$notloc->insert();
|
||||||
|
}
|
||||||
|
|
||||||
$orig = clone($stored); // for updating later in this try clause
|
$orig = clone($stored); // for updating later in this try clause
|
||||||
|
|
||||||
$object = null;
|
$object = null;
|
||||||
@ -898,10 +912,11 @@ class Notice extends Managed_DataObject
|
|||||||
throw new ServerException('Unsuccessful call to StoreActivityObject '.$stored->uri . ': '.$act->asString());
|
throw new ServerException('Unsuccessful call to StoreActivityObject '.$stored->uri . ': '.$act->asString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not part of a conversation, it's
|
// If it's not part of a conversation, it's the beginning
|
||||||
// the beginning of a new conversation.
|
// of a new one (or belongs to a previously unknown URI).
|
||||||
if (empty($stored->conversation)) {
|
if (empty($stored->conversation)) {
|
||||||
// $act->context->conversation will be null if it was not provided
|
// $act->context->conversation will be null if it was not provided
|
||||||
|
common_debug('Creating a new conversation for stored notice ID='.$stored->getID().' with URI: '.$act->context->conversation);
|
||||||
$conv = Conversation::create($stored, $act->context->conversation);
|
$conv = Conversation::create($stored, $act->context->conversation);
|
||||||
$stored->conversation = $conv->id;
|
$stored->conversation = $conv->id;
|
||||||
}
|
}
|
||||||
@ -1203,17 +1218,15 @@ class Notice extends Managed_DataObject
|
|||||||
$this->_attachments[$this->id] = $attachments;
|
$this->_attachments[$this->id] = $attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
function publicStream($offset=0, $limit=20, $since_id=0, $max_id=0)
|
static function publicStream($offset=0, $limit=20, $since_id=null, $max_id=null)
|
||||||
{
|
{
|
||||||
$stream = new PublicNoticeStream();
|
$stream = new PublicNoticeStream();
|
||||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function conversationStream($id, $offset=0, $limit=20, $since_id=null, $max_id=null)
|
||||||
function conversationStream($id, $offset=0, $limit=20, $since_id=0, $max_id=0)
|
|
||||||
{
|
{
|
||||||
$stream = new ConversationNoticeStream($id);
|
$stream = new ConversationNoticeStream($id);
|
||||||
|
|
||||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1225,18 +1238,17 @@ class Notice extends Managed_DataObject
|
|||||||
*/
|
*/
|
||||||
function hasConversation()
|
function hasConversation()
|
||||||
{
|
{
|
||||||
if (!empty($this->conversation)) {
|
if (empty($this->conversation)) {
|
||||||
$conversation = Notice::conversationStream(
|
// this notice is not part of a conversation apparently
|
||||||
$this->conversation,
|
// FIXME: all notices should have a conversation value, right?
|
||||||
1,
|
return false;
|
||||||
1
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($conversation->N > 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
$stream = new ConversationNoticeStream($this->conversation);
|
||||||
|
$notice = $stream->getNotices(/*offset*/ 1, /*limit*/ 1);
|
||||||
|
|
||||||
|
// if our "offset 1, limit 1" query got a result, return true else false
|
||||||
|
return $notice->N > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1271,8 +1283,7 @@ class Notice extends Managed_DataObject
|
|||||||
$root = new Notice;
|
$root = new Notice;
|
||||||
$root->conversation = $this->conversation;
|
$root->conversation = $this->conversation;
|
||||||
$root->orderBy('notice.created ASC');
|
$root->orderBy('notice.created ASC');
|
||||||
$root->find();
|
$root->find(true); // true means "fetch first result"
|
||||||
$root->fetch();
|
|
||||||
$root->free();
|
$root->free();
|
||||||
return $root;
|
return $root;
|
||||||
}
|
}
|
||||||
@ -1660,32 +1671,22 @@ class Notice extends Managed_DataObject
|
|||||||
protected $_replies = array();
|
protected $_replies = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pull the complete list of @-reply targets for this notice.
|
* Pull the complete list of @-mentioned profile IDs for this notice.
|
||||||
*
|
*
|
||||||
* @return array of integer profile ids
|
* @return array of integer profile ids
|
||||||
*/
|
*/
|
||||||
function getReplies()
|
function getReplies()
|
||||||
{
|
{
|
||||||
if (isset($this->_replies[$this->id])) {
|
if (!isset($this->_replies[$this->getID()])) {
|
||||||
return $this->_replies[$this->id];
|
$mentions = Reply::multiGet('notice_id', array($this->getID()));
|
||||||
|
$this->_replies[$this->getID()] = $mentions->fetchAll('profile_id');
|
||||||
}
|
}
|
||||||
|
return $this->_replies[$this->getID()];
|
||||||
$replyMap = Reply::listGet('notice_id', array($this->id));
|
|
||||||
|
|
||||||
$ids = array();
|
|
||||||
|
|
||||||
foreach ($replyMap[$this->id] as $reply) {
|
|
||||||
$ids[] = $reply->profile_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_replies[$this->id] = $ids;
|
|
||||||
|
|
||||||
return $ids;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _setReplies($replies)
|
function _setReplies($replies)
|
||||||
{
|
{
|
||||||
$this->_replies[$this->id] = $replies;
|
$this->_replies[$this->getID()] = $replies;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1844,7 +1845,11 @@ class Notice extends Managed_DataObject
|
|||||||
// This is not a reply to something
|
// This is not a reply to something
|
||||||
}
|
}
|
||||||
|
|
||||||
$ctx->location = $this->getLocation();
|
try {
|
||||||
|
$ctx->location = Notice_location::locFromStored($this);
|
||||||
|
} catch (ServerException $e) {
|
||||||
|
$ctx->location = null;
|
||||||
|
}
|
||||||
|
|
||||||
$conv = null;
|
$conv = null;
|
||||||
|
|
||||||
@ -2090,23 +2095,6 @@ class Notice extends Managed_DataObject
|
|||||||
return ($contentlimit > 0 && !empty($content) && (mb_strlen($content) > $contentlimit));
|
return ($contentlimit > 0 && !empty($content) && (mb_strlen($content) > $contentlimit));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLocation()
|
|
||||||
{
|
|
||||||
$location = null;
|
|
||||||
|
|
||||||
if (!empty($this->location_id) && !empty($this->location_ns)) {
|
|
||||||
$location = Location::fromId($this->location_id, $this->location_ns);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_null($location)) { // no ID, or Location::fromId() failed
|
|
||||||
if (!empty($this->lat) && !empty($this->lon)) {
|
|
||||||
$location = Location::fromLatLon($this->lat, $this->lon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $location;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience function for posting a repeat of an existing message.
|
* Convenience function for posting a repeat of an existing message.
|
||||||
*
|
*
|
||||||
@ -2193,7 +2181,7 @@ class Notice extends Managed_DataObject
|
|||||||
return $notice->fetchAll('id');
|
return $notice->fetchAll('id');
|
||||||
}
|
}
|
||||||
|
|
||||||
function locationOptions($lat, $lon, $location_id, $location_ns, $profile = null)
|
static function locationOptions($lat, $lon, $location_id, $location_ns, $profile = null)
|
||||||
{
|
{
|
||||||
$options = array();
|
$options = array();
|
||||||
|
|
||||||
@ -2277,6 +2265,16 @@ class Notice extends Managed_DataObject
|
|||||||
$reply->free();
|
$reply->free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearLocation()
|
||||||
|
{
|
||||||
|
$loc = new Notice_location();
|
||||||
|
$loc->notice_id = $this->id;
|
||||||
|
|
||||||
|
if ($loc->find()) {
|
||||||
|
$loc->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function clearFiles()
|
function clearFiles()
|
||||||
{
|
{
|
||||||
$f2p = new File_to_post();
|
$f2p = new File_to_post();
|
||||||
@ -2885,4 +2883,51 @@ class Notice extends Managed_DataObject
|
|||||||
$notice->_setReplies($ids);
|
$notice->_setReplies($ids);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function beforeSchemaUpdate()
|
||||||
|
{
|
||||||
|
$table = strtolower(get_called_class());
|
||||||
|
$schema = Schema::get();
|
||||||
|
$schemadef = $schema->getTableDef($table);
|
||||||
|
|
||||||
|
// 2015-09-04 We move Notice location data to Notice_location
|
||||||
|
// First we see if we have to do this at all
|
||||||
|
if (!isset($schemadef['fields']['lat'])
|
||||||
|
&& !isset($schemadef['fields']['lon'])
|
||||||
|
&& !isset($schemadef['fields']['location_id'])
|
||||||
|
&& !isset($schemadef['fields']['location_ns'])) {
|
||||||
|
// We have already removed the location fields, so no need to migrate.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Then we make sure the Notice_location table is created!
|
||||||
|
$schema->ensureTable('notice_location', Notice_location::schemaDef());
|
||||||
|
|
||||||
|
// Then we continue on our road to migration!
|
||||||
|
echo "\nFound old $table table, moving location data to 'notice_location' table... (this will probably take a LONG time, but can be aborted and continued)";
|
||||||
|
|
||||||
|
$notice = new Notice();
|
||||||
|
$notice->query(sprintf('SELECT id, lat, lon, location_id, location_ns FROM %1$s ' .
|
||||||
|
'WHERE lat IS NOT NULL ' .
|
||||||
|
'OR lon IS NOT NULL ' .
|
||||||
|
'OR location_id IS NOT NULL ' .
|
||||||
|
'OR location_ns IS NOT NULL',
|
||||||
|
$schema->quoteIdentifier($table)));
|
||||||
|
print "\nFound {$notice->N} notices with location data, inserting";
|
||||||
|
while ($notice->fetch()) {
|
||||||
|
$notloc = Notice_location::getKV('notice_id', $notice->id);
|
||||||
|
if ($notloc instanceof Notice_location) {
|
||||||
|
print "-";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$notloc = new Notice_location();
|
||||||
|
$notloc->notice_id = $notice->id;
|
||||||
|
$notloc->lat= $notice->lat;
|
||||||
|
$notloc->lon= $notice->lon;
|
||||||
|
$notloc->location_id= $notice->location_id;
|
||||||
|
$notloc->location_ns= $notice->location_ns;
|
||||||
|
$notloc->insert();
|
||||||
|
print ".";
|
||||||
|
}
|
||||||
|
print "\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
75
classes/Notice_location.php
Normal file
75
classes/Notice_location.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Table Definition for notice_location
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Notice_location extends Managed_DataObject
|
||||||
|
{
|
||||||
|
public $__table = 'notice_location'; // table name
|
||||||
|
public $notice_id; // int(4) primary_key not_null
|
||||||
|
public $lat; // decimal(10,7)
|
||||||
|
public $lon; // decimal(10,7)
|
||||||
|
public $location_id; // int(4)
|
||||||
|
public $location_ns; // int(4)
|
||||||
|
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
|
||||||
|
|
||||||
|
public static function schemaDef()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'fields' => array(
|
||||||
|
'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice that is the reply'),
|
||||||
|
'lat' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'latitude'),
|
||||||
|
'lon' => array('type' => 'numeric', 'precision' => 10, 'scale' => 7, 'description' => 'longitude'),
|
||||||
|
'location_id' => array('type' => 'int', 'description' => 'location id if possible'),
|
||||||
|
'location_ns' => array('type' => 'int', 'description' => 'namespace for location'),
|
||||||
|
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
|
||||||
|
),
|
||||||
|
'primary key' => array('notice_id'),
|
||||||
|
'foreign keys' => array(
|
||||||
|
'notice_location_notice_id_fkey' => array('notice', array('notice_id' => 'id')),
|
||||||
|
),
|
||||||
|
'indexes' => array(
|
||||||
|
'notice_location_location_id_idx' => array('location_id'),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function locFromStored(Notice $stored)
|
||||||
|
{
|
||||||
|
$loc = new Notice_location();
|
||||||
|
$loc->notice_id = $stored->getID();
|
||||||
|
if (!$loc->find(true)) {
|
||||||
|
throw new NoResultException($loc);
|
||||||
|
}
|
||||||
|
return $loc->asLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
static function fromLocation(Location $location)
|
||||||
|
{
|
||||||
|
$notloc = new Notice_location();
|
||||||
|
$notloc->lat = $location->lat;
|
||||||
|
$notloc->lon = $location->lon;
|
||||||
|
$notloc->location_ns = $location->location_ns;
|
||||||
|
$notloc->location_id = $location->location_id;
|
||||||
|
return $notloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function asLocation()
|
||||||
|
{
|
||||||
|
$location = null;
|
||||||
|
|
||||||
|
if (!empty($this->location_id) && !empty($this->location_ns)) {
|
||||||
|
$location = Location::fromId($this->location_id, $this->location_ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($location)) { // no ID, or Location::fromId() failed
|
||||||
|
$location = Location::fromLatLon($this->lat, $this->lon);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($location)) {
|
||||||
|
throw new ServerException('Location could not be looked up from existing data.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $location;
|
||||||
|
}
|
||||||
|
}
|
@ -138,6 +138,18 @@ class Profile extends Managed_DataObject
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns false if the user has no password (which will always
|
||||||
|
// be the case for remote users). This can be the case for OpenID
|
||||||
|
// logins or other mechanisms which don't store a password hash.
|
||||||
|
public function hasPassword()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return !empty($this->getUser()->hasPassword());
|
||||||
|
} catch (NoSuchUserException $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getObjectType()
|
public function getObjectType()
|
||||||
{
|
{
|
||||||
// FIXME: More types... like peopletags and whatever
|
// FIXME: More types... like peopletags and whatever
|
||||||
@ -242,6 +254,11 @@ class Profile extends Managed_DataObject
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
|
||||||
|
{
|
||||||
|
return Reply::stream($this->getID(), $offset, $limit, $since_id, $before_id);
|
||||||
|
}
|
||||||
|
|
||||||
function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
||||||
{
|
{
|
||||||
$stream = new TaggedProfileNoticeStream($this, $tag);
|
$stream = new TaggedProfileNoticeStream($this, $tag);
|
||||||
@ -860,6 +877,11 @@ class Profile extends Managed_DataObject
|
|||||||
|
|
||||||
function delete($useWhere=false)
|
function delete($useWhere=false)
|
||||||
{
|
{
|
||||||
|
// just in case it hadn't been done before... (usually set before adding deluser to queue handling!)
|
||||||
|
if (!$this->hasRole(Profile_role::DELETED)) {
|
||||||
|
$this->grantRole(Profile_role::DELETED);
|
||||||
|
}
|
||||||
|
|
||||||
$this->_deleteNotices();
|
$this->_deleteNotices();
|
||||||
$this->_deleteSubscriptions();
|
$this->_deleteSubscriptions();
|
||||||
$this->_deleteTags();
|
$this->_deleteTags();
|
||||||
@ -1390,6 +1412,11 @@ class Profile extends Managed_DataObject
|
|||||||
return $this->fullname;
|
return $this->fullname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getHomepage()
|
||||||
|
{
|
||||||
|
return $this->homepage;
|
||||||
|
}
|
||||||
|
|
||||||
public function getDescription()
|
public function getDescription()
|
||||||
{
|
{
|
||||||
return $this->bio;
|
return $this->bio;
|
||||||
@ -1566,6 +1593,11 @@ class Profile extends Managed_DataObject
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sameAs(Profile $other)
|
||||||
|
{
|
||||||
|
return $this->getID() === $other->getID();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This will perform shortenLinks with the connected User object.
|
* This will perform shortenLinks with the connected User object.
|
||||||
*
|
*
|
||||||
@ -1613,4 +1645,9 @@ class Profile extends Managed_DataObject
|
|||||||
public function setPref($namespace, $topic, $data) {
|
public function setPref($namespace, $topic, $data) {
|
||||||
return Profile_prefs::setData($this, $namespace, $topic, $data);
|
return Profile_prefs::setData($this, $namespace, $topic, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getConnectedApps($offset=0, $limit=null)
|
||||||
|
{
|
||||||
|
return $this->getUser()->getConnectedApps($offset, $limit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,15 @@
|
|||||||
/**
|
/**
|
||||||
* Table Definition for profile_tag
|
* Table Definition for profile_tag
|
||||||
*/
|
*/
|
||||||
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
|
|
||||||
|
|
||||||
class Profile_tag extends Managed_DataObject
|
class Profile_tag extends Managed_DataObject
|
||||||
{
|
{
|
||||||
###START_AUTOCODE
|
|
||||||
/* the code below is auto generated do not remove the above tag */
|
|
||||||
|
|
||||||
public $__table = 'profile_tag'; // table name
|
public $__table = 'profile_tag'; // table name
|
||||||
public $tagger; // int(4) primary_key not_null
|
public $tagger; // int(4) primary_key not_null
|
||||||
public $tagged; // int(4) primary_key not_null
|
public $tagged; // int(4) primary_key not_null
|
||||||
public $tag; // varchar(64) primary_key not_null
|
public $tag; // varchar(64) primary_key not_null
|
||||||
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
|
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
|
||||||
|
|
||||||
/* the code above is auto generated do not remove the tag below */
|
|
||||||
###END_AUTOCODE
|
|
||||||
|
|
||||||
public static function schemaDef()
|
public static function schemaDef()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
@ -52,6 +45,16 @@ class Profile_tag extends Managed_DataObject
|
|||||||
return Profile_list::pkeyGet(array('tagger' => $this->tagger, 'tag' => $this->tag));
|
return Profile_list::pkeyGet(array('tagger' => $this->tagger, 'tag' => $this->tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function getSelfTagsArray(Profile $target)
|
||||||
|
{
|
||||||
|
return self::getTagsArray($target->getID(), $target->getID(), $target);
|
||||||
|
}
|
||||||
|
|
||||||
|
static function setSelfTags(Profile $target, array $newtags, array $privacy=array())
|
||||||
|
{
|
||||||
|
return self::setTags($target->getID(), $target->getID(), $newtags, $privacy);
|
||||||
|
}
|
||||||
|
|
||||||
static function getTags($tagger, $tagged, $auth_user=null) {
|
static function getTags($tagger, $tagged, $auth_user=null) {
|
||||||
|
|
||||||
$profile_list = new Profile_list();
|
$profile_list = new Profile_list();
|
||||||
@ -88,7 +91,7 @@ class Profile_tag extends Managed_DataObject
|
|||||||
return $profile_list;
|
return $profile_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function getTagsArray($tagger, $tagged, $auth_user_id=null)
|
static function getTagsArray($tagger, $tagged, Profile $scoped=null)
|
||||||
{
|
{
|
||||||
$ptag = new Profile_tag();
|
$ptag = new Profile_tag();
|
||||||
|
|
||||||
@ -100,7 +103,7 @@ class Profile_tag extends Managed_DataObject
|
|||||||
'and profile_tag.tagged = %d ',
|
'and profile_tag.tagged = %d ',
|
||||||
$tagger, $tagged);
|
$tagger, $tagged);
|
||||||
|
|
||||||
if ($auth_user_id != $tagger) {
|
if (!$scoped instanceof Profile || $scoped->getID() !== $tagger) {
|
||||||
$qry .= 'and profile_list.private = 0';
|
$qry .= 'and profile_list.private = 0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,10 +118,10 @@ class Profile_tag extends Managed_DataObject
|
|||||||
return $tags;
|
return $tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function setTags($tagger, $tagged, $newtags, $privacy=array()) {
|
static function setTags($tagger, $tagged, array $newtags, array $privacy=array()) {
|
||||||
|
|
||||||
$newtags = array_unique($newtags);
|
$newtags = array_unique($newtags);
|
||||||
$oldtags = self::getTagsArray($tagger, $tagged, $tagger);
|
$oldtags = self::getTagsArray($tagger, $tagged, Profile::getByID($tagger));
|
||||||
|
|
||||||
$ptag = new Profile_tag();
|
$ptag = new Profile_tag();
|
||||||
|
|
||||||
@ -149,19 +152,18 @@ class Profile_tag extends Managed_DataObject
|
|||||||
'tag' => $tag));
|
'tag' => $tag));
|
||||||
|
|
||||||
# if tag already exists, return it
|
# if tag already exists, return it
|
||||||
if(!empty($ptag)) {
|
if ($ptag instanceof Profile_tag) {
|
||||||
return $ptag;
|
return $ptag;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tagger_profile = Profile::getKV('id', $tagger);
|
$tagger_profile = Profile::getByID($tagger);
|
||||||
$tagged_profile = Profile::getKV('id', $tagged);
|
$tagged_profile = Profile::getByID($tagged);
|
||||||
|
|
||||||
if (Event::handle('StartTagProfile', array($tagger_profile, $tagged_profile, $tag))) {
|
if (Event::handle('StartTagProfile', array($tagger_profile, $tagged_profile, $tag))) {
|
||||||
|
|
||||||
if (!$tagger_profile->canTag($tagged_profile)) {
|
if (!$tagger_profile->canTag($tagged_profile)) {
|
||||||
// TRANS: Client exception thrown trying to set a tag for a user that cannot be tagged.
|
// TRANS: Client exception thrown trying to set a tag for a user that cannot be tagged.
|
||||||
throw new ClientException(_('You cannot tag this user.'));
|
throw new ClientException(_('You cannot tag this user.'));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$tags = new Profile_list();
|
$tags = new Profile_list();
|
||||||
@ -174,7 +176,6 @@ class Profile_tag extends Managed_DataObject
|
|||||||
'which is the maximum allowed number of tags. ' .
|
'which is the maximum allowed number of tags. ' .
|
||||||
'Try using or deleting some existing tags.'),
|
'Try using or deleting some existing tags.'),
|
||||||
common_config('peopletag', 'maxtags')));
|
common_config('peopletag', 'maxtags')));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$plist = new Profile_list();
|
$plist = new Profile_list();
|
||||||
@ -188,7 +189,6 @@ class Profile_tag extends Managed_DataObject
|
|||||||
'which is the maximum allowed number. ' .
|
'which is the maximum allowed number. ' .
|
||||||
'Try unlisting others first.'),
|
'Try unlisting others first.'),
|
||||||
common_config('peopletag', 'maxpeople'), $tag));
|
common_config('peopletag', 'maxpeople'), $tag));
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$newtag = new Profile_tag();
|
$newtag = new Profile_tag();
|
||||||
@ -199,9 +199,9 @@ class Profile_tag extends Managed_DataObject
|
|||||||
|
|
||||||
$result = $newtag->insert();
|
$result = $newtag->insert();
|
||||||
|
|
||||||
|
|
||||||
if (!$result) {
|
if (!$result) {
|
||||||
common_log_db_error($newtag, 'INSERT', __FILE__);
|
common_log_db_error($newtag, 'INSERT', __FILE__);
|
||||||
|
$plist->query('ROLLBACK');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,7 +212,6 @@ class Profile_tag extends Managed_DataObject
|
|||||||
$newtag->delete();
|
$newtag->delete();
|
||||||
$profile_list->delete();
|
$profile_list->delete();
|
||||||
throw $e;
|
throw $e;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile_list->taggedCount(true);
|
$profile_list->taggedCount(true);
|
||||||
@ -233,20 +232,17 @@ class Profile_tag extends Managed_DataObject
|
|||||||
if (Event::handle('StartUntagProfile', array($ptag))) {
|
if (Event::handle('StartUntagProfile', array($ptag))) {
|
||||||
$orig = clone($ptag);
|
$orig = clone($ptag);
|
||||||
$result = $ptag->delete();
|
$result = $ptag->delete();
|
||||||
if (!$result) {
|
if ($result === false) {
|
||||||
common_log_db_error($this, 'DELETE', __FILE__);
|
common_log_db_error($this, 'DELETE', __FILE__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Event::handle('EndUntagProfile', array($orig));
|
Event::handle('EndUntagProfile', array($orig));
|
||||||
if ($result) {
|
$profile_list = Profile_list::pkeyGet(array('tag' => $tag, 'tagger' => $tagger));
|
||||||
$profile_list = Profile_list::pkeyGet(array('tag' => $tag, 'tagger' => $tagger));
|
if (!empty($profile_list)) {
|
||||||
if (!empty($profile_list)) {
|
$profile_list->taggedCount(true);
|
||||||
$profile_list->taggedCount(true);
|
|
||||||
}
|
|
||||||
self::blowCaches($tagger, $tagged);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
self::blowCaches($tagger, $tagged);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ class Queue_item extends Managed_DataObject
|
|||||||
* @param mixed $transports name of a single queue or array of queues to pull from
|
* @param mixed $transports name of a single queue or array of queues to pull from
|
||||||
* If not specified, checks all queues in the system.
|
* If not specified, checks all queues in the system.
|
||||||
*/
|
*/
|
||||||
static function top($transports=null) {
|
static function top($transports=null, array $ignored_transports=array()) {
|
||||||
|
|
||||||
$qi = new Queue_item();
|
$qi = new Queue_item();
|
||||||
if ($transports) {
|
if ($transports) {
|
||||||
@ -52,6 +52,11 @@ class Queue_item extends Managed_DataObject
|
|||||||
$qi->transport = $transports;
|
$qi->transport = $transports;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!empty($ignored_transports)) {
|
||||||
|
// @fixme use safer escaping
|
||||||
|
$list = implode("','", array_map(array($qi, 'escape'), $ignored_transports));
|
||||||
|
$qi->whereAdd("transport NOT IN ('$list')");
|
||||||
|
}
|
||||||
$qi->orderBy('created');
|
$qi->orderBy('created');
|
||||||
$qi->whereAdd('claimed is null');
|
$qi->whereAdd('claimed is null');
|
||||||
|
|
||||||
|
@ -55,10 +55,9 @@ class Reply extends Managed_DataObject
|
|||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
static function stream($user_id, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $max_id=0)
|
||||||
{
|
{
|
||||||
$stream = new ReplyNoticeStream($user_id);
|
$stream = new ReplyNoticeStream($user_id);
|
||||||
|
|
||||||
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
return $stream->getNotices($offset, $limit, $since_id, $max_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,10 @@ class Subscription_queue extends Managed_DataObject
|
|||||||
return $rq;
|
return $rq;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exists(Profile $subscriber, Profile $other)
|
static function exists(Profile $subscriber, Profile $other)
|
||||||
{
|
{
|
||||||
$sub = Subscription_queue::pkeyGet(array('subscriber' => $subscriber->id,
|
$sub = Subscription_queue::pkeyGet(array('subscriber' => $subscriber->getID(),
|
||||||
'subscribed' => $other->id));
|
'subscribed' => $other->getID()));
|
||||||
return ($sub instanceof Subscription_queue);
|
return ($sub instanceof Subscription_queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ class User extends Managed_DataObject
|
|||||||
public $emailnotifynudge; // tinyint(1) default_1
|
public $emailnotifynudge; // tinyint(1) default_1
|
||||||
public $emailnotifymsg; // tinyint(1) default_1
|
public $emailnotifymsg; // tinyint(1) default_1
|
||||||
public $emailnotifyattn; // tinyint(1) default_1
|
public $emailnotifyattn; // tinyint(1) default_1
|
||||||
public $emailmicroid; // tinyint(1) default_1
|
|
||||||
public $language; // varchar(50)
|
public $language; // varchar(50)
|
||||||
public $timezone; // varchar(50)
|
public $timezone; // varchar(50)
|
||||||
public $emailpost; // tinyint(1) default_1
|
public $emailpost; // tinyint(1) default_1
|
||||||
@ -77,7 +76,6 @@ class User extends Managed_DataObject
|
|||||||
'emailnotifynudge' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of nudges'),
|
'emailnotifynudge' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of nudges'),
|
||||||
'emailnotifymsg' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of direct messages'),
|
'emailnotifymsg' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of direct messages'),
|
||||||
'emailnotifyattn' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of @-replies'),
|
'emailnotifyattn' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Notify by email of @-replies'),
|
||||||
'emailmicroid' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'whether to publish email microid'),
|
|
||||||
'language' => array('type' => 'varchar', 'length' => 50, 'description' => 'preferred language'),
|
'language' => array('type' => 'varchar', 'length' => 50, 'description' => 'preferred language'),
|
||||||
'timezone' => array('type' => 'varchar', 'length' => 50, 'description' => 'timezone'),
|
'timezone' => array('type' => 'varchar', 'length' => 50, 'description' => 'timezone'),
|
||||||
'emailpost' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Post by email'),
|
'emailpost' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Post by email'),
|
||||||
@ -132,6 +130,11 @@ class User extends Managed_DataObject
|
|||||||
return $this->_profile[$this->id];
|
return $this->_profile[$this->id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function sameAs(Profile $other)
|
||||||
|
{
|
||||||
|
return $this->getProfile()->sameAs($other);
|
||||||
|
}
|
||||||
|
|
||||||
public function getUri()
|
public function getUri()
|
||||||
{
|
{
|
||||||
return $this->uri;
|
return $this->uri;
|
||||||
@ -142,6 +145,16 @@ class User extends Managed_DataObject
|
|||||||
return $this->getProfile()->getNickname();
|
return $this->getProfile()->getNickname();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static function getByNickname($nickname)
|
||||||
|
{
|
||||||
|
$user = User::getKV('nickname', $nickname);
|
||||||
|
if (!$user instanceof User) {
|
||||||
|
throw new NoSuchUserException(array('nickname' => $nickname));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
function isSubscribed(Profile $other)
|
function isSubscribed(Profile $other)
|
||||||
{
|
{
|
||||||
return $this->getProfile()->isSubscribed($other);
|
return $this->getProfile()->isSubscribed($other);
|
||||||
@ -261,9 +274,7 @@ class User extends Managed_DataObject
|
|||||||
$user->emailnotifynudge = 1;
|
$user->emailnotifynudge = 1;
|
||||||
$user->emailnotifymsg = 1;
|
$user->emailnotifymsg = 1;
|
||||||
$user->emailnotifyattn = 1;
|
$user->emailnotifyattn = 1;
|
||||||
$user->emailmicroid = 1;
|
|
||||||
$user->emailpost = 1;
|
$user->emailpost = 1;
|
||||||
$user->jabbermicroid = 1;
|
|
||||||
|
|
||||||
$user->created = common_sql_now();
|
$user->created = common_sql_now();
|
||||||
|
|
||||||
@ -288,7 +299,7 @@ class User extends Managed_DataObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
$user->password = common_munge_password($password);
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = $user->insert();
|
$result = $user->insert();
|
||||||
@ -439,7 +450,7 @@ class User extends Managed_DataObject
|
|||||||
|
|
||||||
function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
|
function getReplies($offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0)
|
||||||
{
|
{
|
||||||
return Reply::stream($this->id, $offset, $limit, $since_id, $before_id);
|
return $this->getProfile()->getReplies($offset, $limit, $since_id, $before_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) {
|
function getTaggedNotices($tag, $offset=0, $limit=NOTICES_PER_PAGE, $since_id=0, $before_id=0) {
|
||||||
@ -451,16 +462,6 @@ class User extends Managed_DataObject
|
|||||||
return $this->getProfile()->getNotices($offset, $limit, $since_id, $before_id);
|
return $this->getProfile()->getNotices($offset, $limit, $since_id, $before_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSelfTags()
|
|
||||||
{
|
|
||||||
return Profile_tag::getTagsArray($this->id, $this->id, $this->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelfTags($newtags, $privacy)
|
|
||||||
{
|
|
||||||
return Profile_tag::setTags($this->id, $this->id, $newtags, $privacy);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block(Profile $other)
|
function block(Profile $other)
|
||||||
{
|
{
|
||||||
// Add a new block record
|
// Add a new block record
|
||||||
@ -597,8 +598,10 @@ class User extends Managed_DataObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$profile = $this->getProfile();
|
if (!$this->hasRole(Profile_role::DELETED)) {
|
||||||
$profile->delete();
|
$profile = $this->getProfile();
|
||||||
|
$profile->delete();
|
||||||
|
}
|
||||||
} catch (UserNoProfileException $unp) {
|
} catch (UserNoProfileException $unp) {
|
||||||
common_log(LOG_INFO, "User {$this->nickname} has no profile; continuing deletion.");
|
common_log(LOG_INFO, "User {$this->nickname} has no profile; continuing deletion.");
|
||||||
}
|
}
|
||||||
@ -1004,6 +1007,11 @@ class User extends Managed_DataObject
|
|||||||
return $this->getProfile()->isPrivateStream();
|
return $this->getProfile()->isPrivateStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasPassword()
|
||||||
|
{
|
||||||
|
return !empty($this->password);
|
||||||
|
}
|
||||||
|
|
||||||
public function delPref($namespace, $topic)
|
public function delPref($namespace, $topic)
|
||||||
{
|
{
|
||||||
return $this->getProfile()->delPref($namespace, $topic);
|
return $this->getProfile()->delPref($namespace, $topic);
|
||||||
|
@ -40,7 +40,6 @@ class User_im_prefs extends Managed_DataObject
|
|||||||
public $transport; // varchar(191) not_null not 255 because utf8mb4 takes more space
|
public $transport; // varchar(191) not_null not 255 because utf8mb4 takes more space
|
||||||
public $notify; // tinyint(1)
|
public $notify; // tinyint(1)
|
||||||
public $replies; // tinyint(1)
|
public $replies; // tinyint(1)
|
||||||
public $microid; // tinyint(1)
|
|
||||||
public $updatefrompresence; // tinyint(1)
|
public $updatefrompresence; // tinyint(1)
|
||||||
public $created; // datetime not_null default_0000-00-00%2000%3A00%3A00
|
public $created; // datetime not_null default_0000-00-00%2000%3A00%3A00
|
||||||
public $modified; // timestamp not_null default_CURRENT_TIMESTAMP
|
public $modified; // timestamp not_null default_CURRENT_TIMESTAMP
|
||||||
@ -57,7 +56,6 @@ class User_im_prefs extends Managed_DataObject
|
|||||||
'transport' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'transport (ex xmpp, aim)'),
|
'transport' => array('type' => 'varchar', 'length' => 191, 'not null' => true, 'description' => 'transport (ex xmpp, aim)'),
|
||||||
'notify' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Notify when a new notice is sent'),
|
'notify' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Notify when a new notice is sent'),
|
||||||
'replies' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to'),
|
'replies' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to'),
|
||||||
'microid' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'Publish a MicroID'),
|
|
||||||
'updatefrompresence' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to.'),
|
'updatefrompresence' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to.'),
|
||||||
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
|
'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'),
|
||||||
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
|
'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'),
|
||||||
|
@ -39,6 +39,7 @@ $classes = array('Schema_version',
|
|||||||
'Subscription_queue',
|
'Subscription_queue',
|
||||||
'Oauth_token_association',
|
'Oauth_token_association',
|
||||||
'Notice',
|
'Notice',
|
||||||
|
'Notice_location',
|
||||||
'Notice_source',
|
'Notice_source',
|
||||||
'Reply',
|
'Reply',
|
||||||
'Consumer',
|
'Consumer',
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
* @author Sean Coates <sean@php.net>
|
* @author Sean Coates <sean@php.net>
|
||||||
* @copyright 2003-2006 PEAR <pear-group@php.net>
|
* @copyright 2003-2006 PEAR <pear-group@php.net>
|
||||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||||
* @version CVS: $Id: mimeDecode.php,v 1.48 2006/12/03 13:43:33 cipri Exp $
|
* @version CVS: $Id: mimeDecode.php 305875 2010-12-01 07:17:10Z alan_k $
|
||||||
* @link http://pear.php.net/package/Mail_mime
|
* @link http://pear.php.net/package/Mail_mime
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -147,6 +147,15 @@ class Mail_mimeDecode extends PEAR
|
|||||||
*/
|
*/
|
||||||
var $_decode_headers;
|
var $_decode_headers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag to determine whether to include attached messages
|
||||||
|
* as body in the returned object. Depends on $_include_bodies
|
||||||
|
*
|
||||||
|
* @var boolean
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
var $_rfc822_bodies;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@ -165,6 +174,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
$this->_body = $body;
|
$this->_body = $body;
|
||||||
$this->_decode_bodies = false;
|
$this->_decode_bodies = false;
|
||||||
$this->_include_bodies = true;
|
$this->_include_bodies = true;
|
||||||
|
$this->_rfc822_bodies = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,7 +197,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
function decode($params = null)
|
function decode($params = null)
|
||||||
{
|
{
|
||||||
// determine if this method has been called statically
|
// determine if this method has been called statically
|
||||||
$isStatic = !(isset($this) && get_class($this) == __CLASS__);
|
$isStatic = empty($this) || !is_a($this, __CLASS__);
|
||||||
|
|
||||||
// Have we been called statically?
|
// Have we been called statically?
|
||||||
// If so, create an object and pass details to that.
|
// If so, create an object and pass details to that.
|
||||||
@ -208,6 +218,8 @@ class Mail_mimeDecode extends PEAR
|
|||||||
$params['decode_bodies'] : false;
|
$params['decode_bodies'] : false;
|
||||||
$this->_decode_headers = isset($params['decode_headers']) ?
|
$this->_decode_headers = isset($params['decode_headers']) ?
|
||||||
$params['decode_headers'] : false;
|
$params['decode_headers'] : false;
|
||||||
|
$this->_rfc822_bodies = isset($params['rfc_822bodies']) ?
|
||||||
|
$params['rfc_822bodies'] : false;
|
||||||
|
|
||||||
$structure = $this->_decode($this->_header, $this->_body);
|
$structure = $this->_decode($this->_header, $this->_body);
|
||||||
if ($structure === false) {
|
if ($structure === false) {
|
||||||
@ -235,6 +247,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
$headers = $this->_parseHeaders($headers);
|
$headers = $this->_parseHeaders($headers);
|
||||||
|
|
||||||
foreach ($headers as $value) {
|
foreach ($headers as $value) {
|
||||||
|
$value['value'] = $this->_decode_headers ? $this->_decodeHeader($value['value']) : $value['value'];
|
||||||
if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {
|
if (isset($return->headers[strtolower($value['name'])]) AND !is_array($return->headers[strtolower($value['name'])])) {
|
||||||
$return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]);
|
$return->headers[strtolower($value['name'])] = array($return->headers[strtolower($value['name'])]);
|
||||||
$return->headers[strtolower($value['name'])][] = $value['value'];
|
$return->headers[strtolower($value['name'])][] = $value['value'];
|
||||||
@ -247,8 +260,8 @@ class Mail_mimeDecode extends PEAR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reset($headers);
|
|
||||||
while (list($key, $value) = each($headers)) {
|
foreach ($headers as $key => $value) {
|
||||||
$headers[$key]['name'] = strtolower($headers[$key]['name']);
|
$headers[$key]['name'] = strtolower($headers[$key]['name']);
|
||||||
switch ($headers[$key]['name']) {
|
switch ($headers[$key]['name']) {
|
||||||
|
|
||||||
@ -261,7 +274,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isset($content_type['other'])) {
|
if (isset($content_type['other'])) {
|
||||||
while (list($p_name, $p_value) = each($content_type['other'])) {
|
foreach($content_type['other'] as $p_name => $p_value) {
|
||||||
$return->ctype_parameters[$p_name] = $p_value;
|
$return->ctype_parameters[$p_name] = $p_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,7 +284,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
$content_disposition = $this->_parseHeaderValue($headers[$key]['value']);
|
$content_disposition = $this->_parseHeaderValue($headers[$key]['value']);
|
||||||
$return->disposition = $content_disposition['value'];
|
$return->disposition = $content_disposition['value'];
|
||||||
if (isset($content_disposition['other'])) {
|
if (isset($content_disposition['other'])) {
|
||||||
while (list($p_name, $p_value) = each($content_disposition['other'])) {
|
foreach($content_disposition['other'] as $p_name => $p_value) {
|
||||||
$return->d_parameters[$p_name] = $p_value;
|
$return->d_parameters[$p_name] = $p_value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,6 +316,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
case 'multipart/alternative':
|
case 'multipart/alternative':
|
||||||
case 'multipart/related':
|
case 'multipart/related':
|
||||||
case 'multipart/mixed':
|
case 'multipart/mixed':
|
||||||
|
case 'application/vnd.wap.multipart.related':
|
||||||
if(!isset($content_type['other']['boundary'])){
|
if(!isset($content_type['other']['boundary'])){
|
||||||
$this->_error = 'No boundary found for ' . $content_type['value'] . ' part';
|
$this->_error = 'No boundary found for ' . $content_type['value'] . ' part';
|
||||||
return false;
|
return false;
|
||||||
@ -321,7 +335,11 @@ class Mail_mimeDecode extends PEAR
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'message/rfc822':
|
case 'message/rfc822':
|
||||||
$obj = &new Mail_mimeDecode($body);
|
if ($this->_rfc822_bodies) {
|
||||||
|
$encoding = isset($content_transfer_encoding) ? $content_transfer_encoding['value'] : '7bit';
|
||||||
|
$return->body = ($this->_decode_bodies ? $this->_decodeBody($body, $encoding) : $body);
|
||||||
|
}
|
||||||
|
$obj = new Mail_mimeDecode($body);
|
||||||
$return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies,
|
$return->parts[] = $obj->decode(array('include_bodies' => $this->_include_bodies,
|
||||||
'decode_bodies' => $this->_decode_bodies,
|
'decode_bodies' => $this->_decode_bodies,
|
||||||
'decode_headers' => $this->_decode_headers));
|
'decode_headers' => $this->_decode_headers));
|
||||||
@ -401,6 +419,11 @@ class Mail_mimeDecode extends PEAR
|
|||||||
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
|
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $input, $match)) {
|
||||||
return array($match[1], $match[2]);
|
return array($match[1], $match[2]);
|
||||||
}
|
}
|
||||||
|
// bug #17325 - empty bodies are allowed. - we just check that at least one line
|
||||||
|
// of headers exist..
|
||||||
|
if (count(explode("\n",$input))) {
|
||||||
|
return array($input, '');
|
||||||
|
}
|
||||||
$this->_error = 'Could not split header and body';
|
$this->_error = 'Could not split header and body';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -419,7 +442,12 @@ class Mail_mimeDecode extends PEAR
|
|||||||
if ($input !== '') {
|
if ($input !== '') {
|
||||||
// Unfold the input
|
// Unfold the input
|
||||||
$input = preg_replace("/\r?\n/", "\r\n", $input);
|
$input = preg_replace("/\r?\n/", "\r\n", $input);
|
||||||
|
//#7065 - wrapping.. with encoded stuff.. - probably not needed,
|
||||||
|
// wrapping space should only get removed if the trailing item on previous line is a
|
||||||
|
// encoded character
|
||||||
|
$input = preg_replace("/=\r\n(\t| )+/", '=', $input);
|
||||||
$input = preg_replace("/\r\n(\t| )+/", ' ', $input);
|
$input = preg_replace("/\r\n(\t| )+/", ' ', $input);
|
||||||
|
|
||||||
$headers = explode("\r\n", trim($input));
|
$headers = explode("\r\n", trim($input));
|
||||||
|
|
||||||
foreach ($headers as $value) {
|
foreach ($headers as $value) {
|
||||||
@ -430,7 +458,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
|
|
||||||
$return[] = array(
|
$return[] = array(
|
||||||
'name' => $hdr_name,
|
'name' => $hdr_name,
|
||||||
'value' => $this->_decode_headers ? $this->_decodeHeader($hdr_value) : $hdr_value
|
'value' => $hdr_value
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -454,41 +482,161 @@ class Mail_mimeDecode extends PEAR
|
|||||||
function _parseHeaderValue($input)
|
function _parseHeaderValue($input)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (($pos = strpos($input, ';')) !== false) {
|
if (($pos = strpos($input, ';')) === false) {
|
||||||
|
$input = $this->_decode_headers ? $this->_decodeHeader($input) : $input;
|
||||||
$return['value'] = trim(substr($input, 0, $pos));
|
|
||||||
$input = trim(substr($input, $pos+1));
|
|
||||||
|
|
||||||
if (strlen($input) > 0) {
|
|
||||||
|
|
||||||
// This splits on a semi-colon, if there's no preceeding backslash
|
|
||||||
// Now works with quoted values; had to glue the \; breaks in PHP
|
|
||||||
// the regex is already bordering on incomprehensible
|
|
||||||
$splitRegex = '/([^;\'"]*[\'"]([^\'"]*([^\'"]*)*)[\'"][^;\'"]*|([^;]+))(;|$)/';
|
|
||||||
preg_match_all($splitRegex, $input, $matches);
|
|
||||||
$parameters = array();
|
|
||||||
for ($i=0; $i<count($matches[0]); $i++) {
|
|
||||||
$param = $matches[0][$i];
|
|
||||||
while (substr($param, -2) == '\;') {
|
|
||||||
$param .= $matches[0][++$i];
|
|
||||||
}
|
|
||||||
$parameters[] = $param;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($i = 0; $i < count($parameters); $i++) {
|
|
||||||
$param_name = trim(substr($parameters[$i], 0, $pos = strpos($parameters[$i], '=')), "'\";\t\\ ");
|
|
||||||
$param_value = trim(str_replace('\;', ';', substr($parameters[$i], $pos + 1)), "'\";\t\\ ");
|
|
||||||
if ($param_value[0] == '"') {
|
|
||||||
$param_value = substr($param_value, 1, -1);
|
|
||||||
}
|
|
||||||
$return['other'][$param_name] = $param_value;
|
|
||||||
$return['other'][strtolower($param_name)] = $param_value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$return['value'] = trim($input);
|
$return['value'] = trim($input);
|
||||||
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$value = substr($input, 0, $pos);
|
||||||
|
$value = $this->_decode_headers ? $this->_decodeHeader($value) : $value;
|
||||||
|
$return['value'] = trim($value);
|
||||||
|
$input = trim(substr($input, $pos+1));
|
||||||
|
|
||||||
|
if (!strlen($input) > 0) {
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
// at this point input contains xxxx=".....";zzzz="...."
|
||||||
|
// since we are dealing with quoted strings, we need to handle this properly..
|
||||||
|
$i = 0;
|
||||||
|
$l = strlen($input);
|
||||||
|
$key = '';
|
||||||
|
$val = false; // our string - including quotes..
|
||||||
|
$q = false; // in quote..
|
||||||
|
$lq = ''; // last quote..
|
||||||
|
|
||||||
|
while ($i < $l) {
|
||||||
|
|
||||||
|
$c = $input[$i];
|
||||||
|
//var_dump(array('i'=>$i,'c'=>$c,'q'=>$q, 'lq'=>$lq, 'key'=>$key, 'val' =>$val));
|
||||||
|
|
||||||
|
$escaped = false;
|
||||||
|
if ($c == '\\') {
|
||||||
|
$i++;
|
||||||
|
if ($i == $l-1) { // end of string.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$escaped = true;
|
||||||
|
$c = $input[$i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// state - in key..
|
||||||
|
if ($val === false) {
|
||||||
|
if (!$escaped && $c == '=') {
|
||||||
|
$val = '';
|
||||||
|
$key = trim($key);
|
||||||
|
$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!$escaped && $c == ';') {
|
||||||
|
if ($key) { // a key without a value..
|
||||||
|
$key= trim($key);
|
||||||
|
$return['other'][$key] = '';
|
||||||
|
$return['other'][strtolower($key)] = '';
|
||||||
|
}
|
||||||
|
$key = '';
|
||||||
|
}
|
||||||
|
$key .= $c;
|
||||||
|
$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// state - in value.. (as $val is set..)
|
||||||
|
|
||||||
|
if ($q === false) {
|
||||||
|
// not in quote yet.
|
||||||
|
if ((!strlen($val) || $lq !== false) && $c == ' ' || $c == "\t") {
|
||||||
|
$i++;
|
||||||
|
continue; // skip leading spaces after '=' or after '"'
|
||||||
|
}
|
||||||
|
if (!$escaped && ($c == '"' || $c == "'")) {
|
||||||
|
// start quoted area..
|
||||||
|
$q = $c;
|
||||||
|
// in theory should not happen raw text in value part..
|
||||||
|
// but we will handle it as a merged part of the string..
|
||||||
|
$val = !strlen(trim($val)) ? '' : trim($val);
|
||||||
|
$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// got end....
|
||||||
|
if (!$escaped && $c == ';') {
|
||||||
|
|
||||||
|
$val = trim($val);
|
||||||
|
$added = false;
|
||||||
|
if (preg_match('/\*[0-9]+$/', $key)) {
|
||||||
|
// this is the extended aaa*0=...;aaa*1=.... code
|
||||||
|
// it assumes the pieces arrive in order, and are valid...
|
||||||
|
$key = preg_replace('/\*[0-9]+$/', '', $key);
|
||||||
|
if (isset($return['other'][$key])) {
|
||||||
|
$return['other'][$key] .= $val;
|
||||||
|
if (strtolower($key) != $key) {
|
||||||
|
$return['other'][strtolower($key)] .= $val;
|
||||||
|
}
|
||||||
|
$added = true;
|
||||||
|
}
|
||||||
|
// continue and use standard setters..
|
||||||
|
}
|
||||||
|
if (!$added) {
|
||||||
|
$return['other'][$key] = $val;
|
||||||
|
$return['other'][strtolower($key)] = $val;
|
||||||
|
}
|
||||||
|
$val = false;
|
||||||
|
$key = '';
|
||||||
|
$lq = false;
|
||||||
|
$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$val .= $c;
|
||||||
|
$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// state - in quote..
|
||||||
|
if (!$escaped && $c == $q) { // potential exit state..
|
||||||
|
|
||||||
|
// end of quoted string..
|
||||||
|
$lq = $q;
|
||||||
|
$q = false;
|
||||||
|
$i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// normal char inside of quoted string..
|
||||||
|
$val.= $c;
|
||||||
|
$i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we have anything left..
|
||||||
|
if (strlen(trim($key)) || $val !== false) {
|
||||||
|
|
||||||
|
$val = trim($val);
|
||||||
|
$added = false;
|
||||||
|
if ($val !== false && preg_match('/\*[0-9]+$/', $key)) {
|
||||||
|
// no dupes due to our crazy regexp.
|
||||||
|
$key = preg_replace('/\*[0-9]+$/', '', $key);
|
||||||
|
if (isset($return['other'][$key])) {
|
||||||
|
$return['other'][$key] .= $val;
|
||||||
|
if (strtolower($key) != $key) {
|
||||||
|
$return['other'][strtolower($key)] .= $val;
|
||||||
|
}
|
||||||
|
$added = true;
|
||||||
|
}
|
||||||
|
// continue and use standard setters..
|
||||||
|
}
|
||||||
|
if (!$added) {
|
||||||
|
$return['other'][$key] = $val;
|
||||||
|
$return['other'][strtolower($key)] = $val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// decode values.
|
||||||
|
foreach($return['other'] as $key =>$val) {
|
||||||
|
$return['other'][$key] = $this->_decode_headers ? $this->_decodeHeader($val) : $val;
|
||||||
|
}
|
||||||
|
//print_r($return);
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,13 +658,19 @@ class Mail_mimeDecode extends PEAR
|
|||||||
if ($boundary == $bs_check) {
|
if ($boundary == $bs_check) {
|
||||||
$boundary = $bs_possible;
|
$boundary = $bs_possible;
|
||||||
}
|
}
|
||||||
|
$tmp = preg_split("/--".preg_quote($boundary, '/')."((?=\s)|--)/", $input);
|
||||||
|
|
||||||
$tmp = explode('--' . $boundary, $input);
|
$len = count($tmp) -1;
|
||||||
|
for ($i = 1; $i < $len; $i++) {
|
||||||
for ($i = 1; $i < count($tmp) - 1; $i++) {
|
if (strlen(trim($tmp[$i]))) {
|
||||||
$parts[] = $tmp[$i];
|
$parts[] = $tmp[$i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the last part on if it does not end with the 'closing indicator'
|
||||||
|
if (!empty($tmp[$len]) && strlen(trim($tmp[$len])) && $tmp[$len][0] != '-') {
|
||||||
|
$parts[] = $tmp[$len];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $parts;
|
return $parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -719,7 +873,7 @@ class Mail_mimeDecode extends PEAR
|
|||||||
case "to":
|
case "to":
|
||||||
case "cc":
|
case "cc":
|
||||||
case "bcc":
|
case "bcc":
|
||||||
$to = ",".$item['value'];
|
$to .= ",".$item['value'];
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,17 @@ use stdClass;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse Microformats2
|
* Parse Microformats2
|
||||||
*
|
*
|
||||||
* Functional shortcut for the commonest cases of parsing microformats2 from HTML.
|
* Functional shortcut for the commonest cases of parsing microformats2 from HTML.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
*
|
||||||
* use Mf2;
|
* use Mf2;
|
||||||
* $output = Mf2\parse('<span class="h-card">Barnaby Walters</span>');
|
* $output = Mf2\parse('<span class="h-card">Barnaby Walters</span>');
|
||||||
* echo json_encode($output, JSON_PRETTY_PRINT);
|
* echo json_encode($output, JSON_PRETTY_PRINT);
|
||||||
*
|
*
|
||||||
* Produces:
|
* Produces:
|
||||||
*
|
*
|
||||||
* {
|
* {
|
||||||
* "items": [
|
* "items": [
|
||||||
* {
|
* {
|
||||||
@ -35,7 +35,7 @@ use stdClass;
|
|||||||
* ],
|
* ],
|
||||||
* "rels": {}
|
* "rels": {}
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @param string|DOMDocument $input The HTML string or DOMDocument object to parse
|
* @param string|DOMDocument $input The HTML string or DOMDocument object to parse
|
||||||
* @param string $url The URL the input document was found at, for relative URL resolution
|
* @param string $url The URL the input document was found at, for relative URL resolution
|
||||||
* @param bool $convertClassic whether or not to convert classic microformats
|
* @param bool $convertClassic whether or not to convert classic microformats
|
||||||
@ -84,7 +84,7 @@ function fetch($url, $convertClassic = true, &$curlInfo=null) {
|
|||||||
/**
|
/**
|
||||||
* Unicode to HTML Entities
|
* Unicode to HTML Entities
|
||||||
* @param string $input String containing characters to convert into HTML entities
|
* @param string $input String containing characters to convert into HTML entities
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
function unicodeToHtmlEntities($input) {
|
function unicodeToHtmlEntities($input) {
|
||||||
return mb_convert_encoding($input, 'HTML-ENTITIES', mb_detect_encoding($input));
|
return mb_convert_encoding($input, 'HTML-ENTITIES', mb_detect_encoding($input));
|
||||||
@ -92,10 +92,10 @@ function unicodeToHtmlEntities($input) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Collapse Whitespace
|
* Collapse Whitespace
|
||||||
*
|
*
|
||||||
* Collapses any sequences of whitespace within a string into a single space
|
* Collapses any sequences of whitespace within a string into a single space
|
||||||
* character.
|
* character.
|
||||||
*
|
*
|
||||||
* @deprecated since v0.2.3
|
* @deprecated since v0.2.3
|
||||||
* @param string $str
|
* @param string $str
|
||||||
* @return string
|
* @return string
|
||||||
@ -113,10 +113,10 @@ function unicodeTrim($str) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Microformat Name From Class string
|
* Microformat Name From Class string
|
||||||
*
|
*
|
||||||
* Given the value of @class, get the relevant mf classnames (e.g. h-card,
|
* Given the value of @class, get the relevant mf classnames (e.g. h-card,
|
||||||
* p-name).
|
* p-name).
|
||||||
*
|
*
|
||||||
* @param string $class A space delimited list of classnames
|
* @param string $class A space delimited list of classnames
|
||||||
* @param string $prefix The prefix to look for
|
* @param string $prefix The prefix to look for
|
||||||
* @return string|array The prefixed name of the first microfomats class found or false
|
* @return string|array The prefixed name of the first microfomats class found or false
|
||||||
@ -127,9 +127,9 @@ function mfNamesFromClass($class, $prefix='h-') {
|
|||||||
$matches = array();
|
$matches = array();
|
||||||
|
|
||||||
foreach ($classes as $classname) {
|
foreach ($classes as $classname) {
|
||||||
$compare_classname = strtolower(' ' . $classname);
|
$compare_classname = ' ' . $classname;
|
||||||
$compare_prefix = strtolower(' ' . $prefix);
|
$compare_prefix = ' ' . $prefix;
|
||||||
if (stristr($compare_classname, $compare_prefix) !== false && ($compare_classname != $compare_prefix)) {
|
if (strstr($compare_classname, $compare_prefix) !== false && ($compare_classname != $compare_prefix)) {
|
||||||
$matches[] = ($prefix === 'h-') ? $classname : substr($classname, strlen($prefix));
|
$matches[] = ($prefix === 'h-') ? $classname : substr($classname, strlen($prefix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,10 +139,10 @@ function mfNamesFromClass($class, $prefix='h-') {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Nested µf Property Name From Class
|
* Get Nested µf Property Name From Class
|
||||||
*
|
*
|
||||||
* Returns all the p-, u-, dt- or e- prefixed classnames it finds in a
|
* Returns all the p-, u-, dt- or e- prefixed classnames it finds in a
|
||||||
* space-separated string.
|
* space-separated string.
|
||||||
*
|
*
|
||||||
* @param string $class
|
* @param string $class
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
@ -153,19 +153,24 @@ function nestedMfPropertyNamesFromClass($class) {
|
|||||||
$class = str_replace(array(' ', ' ', "\n"), ' ', $class);
|
$class = str_replace(array(' ', ' ', "\n"), ' ', $class);
|
||||||
foreach (explode(' ', $class) as $classname) {
|
foreach (explode(' ', $class) as $classname) {
|
||||||
foreach ($prefixes as $prefix) {
|
foreach ($prefixes as $prefix) {
|
||||||
$compare_classname = strtolower(' ' . $classname);
|
// Check if $classname is a valid property classname for $prefix.
|
||||||
if (stristr($compare_classname, $prefix) && ($compare_classname != $prefix)) {
|
if (mb_substr($classname, 0, mb_strlen($prefix)) == $prefix && $classname != $prefix) {
|
||||||
$propertyNames = array_merge($propertyNames, mfNamesFromClass($classname, ltrim($prefix)));
|
$propertyName = mb_substr($classname, mb_strlen($prefix));
|
||||||
|
$propertyNames[$propertyName][] = $prefix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($propertyNames as $property => $prefixes) {
|
||||||
|
$propertyNames[$property] = array_unique($prefixes);
|
||||||
|
}
|
||||||
|
|
||||||
return $propertyNames;
|
return $propertyNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps mfNamesFromClass to handle an element as input (common)
|
* Wraps mfNamesFromClass to handle an element as input (common)
|
||||||
*
|
*
|
||||||
* @param DOMElement $e The element to get the classname for
|
* @param DOMElement $e The element to get the classname for
|
||||||
* @param string $prefix The prefix to look for
|
* @param string $prefix The prefix to look for
|
||||||
* @return mixed See return value of mf2\Parser::mfNameFromClass()
|
* @return mixed See return value of mf2\Parser::mfNameFromClass()
|
||||||
@ -192,28 +197,27 @@ function convertTimeFormat($time) {
|
|||||||
$hh = $mm = $ss = '';
|
$hh = $mm = $ss = '';
|
||||||
preg_match('/(\d{1,2}):?(\d{2})?:?(\d{2})?(a\.?m\.?|p\.?m\.?)?/i', $time, $matches);
|
preg_match('/(\d{1,2}):?(\d{2})?:?(\d{2})?(a\.?m\.?|p\.?m\.?)?/i', $time, $matches);
|
||||||
|
|
||||||
// if no am/pm specified
|
// If no am/pm is specified:
|
||||||
if (empty($matches[4])) {
|
if (empty($matches[4])) {
|
||||||
return $time;
|
return $time;
|
||||||
}
|
} else {
|
||||||
// else am/pm specified
|
// Otherwise, am/pm is specified.
|
||||||
else {
|
|
||||||
$meridiem = strtolower(str_replace('.', '', $matches[4]));
|
$meridiem = strtolower(str_replace('.', '', $matches[4]));
|
||||||
|
|
||||||
// hours
|
// Hours.
|
||||||
$hh = $matches[1];
|
$hh = $matches[1];
|
||||||
|
|
||||||
// add 12 to the pm hours
|
// Add 12 to hours if pm applies.
|
||||||
if ($meridiem == 'pm' && ($hh < 12)) {
|
if ($meridiem == 'pm' && ($hh < 12)) {
|
||||||
$hh += 12;
|
$hh += 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
$hh = str_pad($hh, 2, '0', STR_PAD_LEFT);
|
$hh = str_pad($hh, 2, '0', STR_PAD_LEFT);
|
||||||
|
|
||||||
// minutes
|
// Minutes.
|
||||||
$mm = (empty($matches[2]) ) ? '00' : $matches[2];
|
$mm = (empty($matches[2]) ) ? '00' : $matches[2];
|
||||||
|
|
||||||
// seconds, only if supplied
|
// Seconds, only if supplied.
|
||||||
if (!empty($matches[3])) {
|
if (!empty($matches[3])) {
|
||||||
$ss = $matches[3];
|
$ss = $matches[3];
|
||||||
}
|
}
|
||||||
@ -229,11 +233,11 @@ function convertTimeFormat($time) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Microformats2 Parser
|
* Microformats2 Parser
|
||||||
*
|
*
|
||||||
* A class which holds state for parsing microformats2 from HTML.
|
* A class which holds state for parsing microformats2 from HTML.
|
||||||
*
|
*
|
||||||
* Example usage:
|
* Example usage:
|
||||||
*
|
*
|
||||||
* use Mf2;
|
* use Mf2;
|
||||||
* $parser = new Mf2\Parser('<p class="h-card">Barnaby Walters</p>');
|
* $parser = new Mf2\Parser('<p class="h-card">Barnaby Walters</p>');
|
||||||
* $output = $parser->parse();
|
* $output = $parser->parse();
|
||||||
@ -244,18 +248,18 @@ class Parser {
|
|||||||
|
|
||||||
/** @var DOMXPath object which can be used to query over any fragment*/
|
/** @var DOMXPath object which can be used to query over any fragment*/
|
||||||
public $xpath;
|
public $xpath;
|
||||||
|
|
||||||
/** @var DOMDocument */
|
/** @var DOMDocument */
|
||||||
public $doc;
|
public $doc;
|
||||||
|
|
||||||
/** @var SplObjectStorage */
|
/** @var SplObjectStorage */
|
||||||
protected $parsed;
|
protected $parsed;
|
||||||
|
|
||||||
public $jsonMode;
|
public $jsonMode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param DOMDocument|string $input The data to parse. A string of HTML or a DOMDocument
|
* @param DOMDocument|string $input The data to parse. A string of HTML or a DOMDocument
|
||||||
* @param string $url The URL of the parsed document, for relative URL resolution
|
* @param string $url The URL of the parsed document, for relative URL resolution
|
||||||
* @param boolean $jsonMode Whether or not to use a stdClass instance for an empty `rels` dictionary. This breaks PHP looping over rels, but allows the output to be correctly serialized as JSON.
|
* @param boolean $jsonMode Whether or not to use a stdClass instance for an empty `rels` dictionary. This breaks PHP looping over rels, but allows the output to be correctly serialized as JSON.
|
||||||
@ -271,20 +275,20 @@ class Parser {
|
|||||||
$doc = new DOMDocument();
|
$doc = new DOMDocument();
|
||||||
@$doc->loadHTML('');
|
@$doc->loadHTML('');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->xpath = new DOMXPath($doc);
|
$this->xpath = new DOMXPath($doc);
|
||||||
|
|
||||||
$baseurl = $url;
|
$baseurl = $url;
|
||||||
foreach ($this->xpath->query('//base[@href]') as $base) {
|
foreach ($this->xpath->query('//base[@href]') as $base) {
|
||||||
$baseElementUrl = $base->getAttribute('href');
|
$baseElementUrl = $base->getAttribute('href');
|
||||||
|
|
||||||
if (parse_url($baseElementUrl, PHP_URL_SCHEME) === null) {
|
if (parse_url($baseElementUrl, PHP_URL_SCHEME) === null) {
|
||||||
/* The base element URL is relative to the document URL.
|
/* The base element URL is relative to the document URL.
|
||||||
*
|
*
|
||||||
* :/
|
* :/
|
||||||
*
|
*
|
||||||
* Perhaps the author was high? */
|
* Perhaps the author was high? */
|
||||||
|
|
||||||
$baseurl = resolveUrl($url, $baseElementUrl);
|
$baseurl = resolveUrl($url, $baseElementUrl);
|
||||||
} else {
|
} else {
|
||||||
$baseurl = $baseElementUrl;
|
$baseurl = $baseElementUrl;
|
||||||
@ -296,31 +300,31 @@ class Parser {
|
|||||||
foreach ($this->xpath->query('//template') as $templateEl) {
|
foreach ($this->xpath->query('//template') as $templateEl) {
|
||||||
$templateEl->parentNode->removeChild($templateEl);
|
$templateEl->parentNode->removeChild($templateEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->baseurl = $baseurl;
|
$this->baseurl = $baseurl;
|
||||||
$this->doc = $doc;
|
$this->doc = $doc;
|
||||||
$this->parsed = new SplObjectStorage();
|
$this->parsed = new SplObjectStorage();
|
||||||
$this->jsonMode = $jsonMode;
|
$this->jsonMode = $jsonMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function elementPrefixParsed(\DOMElement $e, $prefix) {
|
private function elementPrefixParsed(\DOMElement $e, $prefix) {
|
||||||
if (!$this->parsed->contains($e))
|
if (!$this->parsed->contains($e))
|
||||||
$this->parsed->attach($e, array());
|
$this->parsed->attach($e, array());
|
||||||
|
|
||||||
$prefixes = $this->parsed[$e];
|
$prefixes = $this->parsed[$e];
|
||||||
$prefixes[] = $prefix;
|
$prefixes[] = $prefix;
|
||||||
$this->parsed[$e] = $prefixes;
|
$this->parsed[$e] = $prefixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isElementParsed(\DOMElement $e, $prefix) {
|
private function isElementParsed(\DOMElement $e, $prefix) {
|
||||||
if (!$this->parsed->contains($e))
|
if (!$this->parsed->contains($e))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
$prefixes = $this->parsed[$e];
|
$prefixes = $this->parsed[$e];
|
||||||
|
|
||||||
if (!in_array($prefix, $prefixes))
|
if (!in_array($prefix, $prefixes))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -352,72 +356,72 @@ class Parser {
|
|||||||
|
|
||||||
// TODO: figure out if this has problems with sms: and geo: URLs
|
// TODO: figure out if this has problems with sms: and geo: URLs
|
||||||
public function resolveUrl($url) {
|
public function resolveUrl($url) {
|
||||||
// If the URL is seriously malformed it’s probably beyond the scope of this
|
// If the URL is seriously malformed it’s probably beyond the scope of this
|
||||||
// parser to try to do anything with it.
|
// parser to try to do anything with it.
|
||||||
if (parse_url($url) === false)
|
if (parse_url($url) === false)
|
||||||
return $url;
|
return $url;
|
||||||
|
|
||||||
$scheme = parse_url($url, PHP_URL_SCHEME);
|
$scheme = parse_url($url, PHP_URL_SCHEME);
|
||||||
|
|
||||||
if (empty($scheme) and !empty($this->baseurl)) {
|
if (empty($scheme) and !empty($this->baseurl)) {
|
||||||
return resolveUrl($this->baseurl, $url);
|
return resolveUrl($this->baseurl, $url);
|
||||||
} else {
|
} else {
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parsing Functions
|
// Parsing Functions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse value-class/value-title on an element, joining with $separator if
|
* Parse value-class/value-title on an element, joining with $separator if
|
||||||
* there are multiple.
|
* there are multiple.
|
||||||
*
|
*
|
||||||
* @param \DOMElement $e
|
* @param \DOMElement $e
|
||||||
* @param string $separator = '' if multiple value-title elements, join with this string
|
* @param string $separator = '' if multiple value-title elements, join with this string
|
||||||
* @return string|null the parsed value or null if value-class or -title aren’t in use
|
* @return string|null the parsed value or null if value-class or -title aren’t in use
|
||||||
*/
|
*/
|
||||||
public function parseValueClassTitle(\DOMElement $e, $separator = '') {
|
public function parseValueClassTitle(\DOMElement $e, $separator = '') {
|
||||||
$valueClassElements = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value ")]', $e);
|
$valueClassElements = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value ")]', $e);
|
||||||
|
|
||||||
if ($valueClassElements->length !== 0) {
|
if ($valueClassElements->length !== 0) {
|
||||||
// Process value-class stuff
|
// Process value-class stuff
|
||||||
$val = '';
|
$val = '';
|
||||||
foreach ($valueClassElements as $el) {
|
foreach ($valueClassElements as $el) {
|
||||||
$val .= $this->textContent($el);
|
$val .= $this->textContent($el);
|
||||||
}
|
}
|
||||||
|
|
||||||
return unicodeTrim($val);
|
return unicodeTrim($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
$valueTitleElements = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value-title ")]', $e);
|
$valueTitleElements = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value-title ")]', $e);
|
||||||
|
|
||||||
if ($valueTitleElements->length !== 0) {
|
if ($valueTitleElements->length !== 0) {
|
||||||
// Process value-title stuff
|
// Process value-title stuff
|
||||||
$val = '';
|
$val = '';
|
||||||
foreach ($valueTitleElements as $el) {
|
foreach ($valueTitleElements as $el) {
|
||||||
$val .= $el->getAttribute('title');
|
$val .= $el->getAttribute('title');
|
||||||
}
|
}
|
||||||
|
|
||||||
return unicodeTrim($val);
|
return unicodeTrim($val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No value-title or -class in this element
|
// No value-title or -class in this element
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an element with class="p-*", get it’s value
|
* Given an element with class="p-*", get it’s value
|
||||||
*
|
*
|
||||||
* @param DOMElement $p The element to parse
|
* @param DOMElement $p The element to parse
|
||||||
* @return string The plaintext value of $p, dependant on type
|
* @return string The plaintext value of $p, dependant on type
|
||||||
* @todo Make this adhere to value-class
|
* @todo Make this adhere to value-class
|
||||||
*/
|
*/
|
||||||
public function parseP(\DOMElement $p) {
|
public function parseP(\DOMElement $p) {
|
||||||
$classTitle = $this->parseValueClassTitle($p, ' ');
|
$classTitle = $this->parseValueClassTitle($p, ' ');
|
||||||
|
|
||||||
if ($classTitle !== null)
|
if ($classTitle !== null)
|
||||||
return $classTitle;
|
return $classTitle;
|
||||||
|
|
||||||
if ($p->tagName == 'img' and $p->getAttribute('alt') !== '') {
|
if ($p->tagName == 'img' and $p->getAttribute('alt') !== '') {
|
||||||
$pValue = $p->getAttribute('alt');
|
$pValue = $p->getAttribute('alt');
|
||||||
} elseif ($p->tagName == 'area' and $p->getAttribute('alt') !== '') {
|
} elseif ($p->tagName == 'area' and $p->getAttribute('alt') !== '') {
|
||||||
@ -429,13 +433,13 @@ class Parser {
|
|||||||
} else {
|
} else {
|
||||||
$pValue = unicodeTrim($this->textContent($p));
|
$pValue = unicodeTrim($this->textContent($p));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $pValue;
|
return $pValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an element with class="u-*", get the value of the URL
|
* Given an element with class="u-*", get the value of the URL
|
||||||
*
|
*
|
||||||
* @param DOMElement $u The element to parse
|
* @param DOMElement $u The element to parse
|
||||||
* @return string The plaintext value of $u, dependant on type
|
* @return string The plaintext value of $u, dependant on type
|
||||||
* @todo make this adhere to value-class
|
* @todo make this adhere to value-class
|
||||||
@ -443,18 +447,18 @@ class Parser {
|
|||||||
public function parseU(\DOMElement $u) {
|
public function parseU(\DOMElement $u) {
|
||||||
if (($u->tagName == 'a' or $u->tagName == 'area') and $u->getAttribute('href') !== null) {
|
if (($u->tagName == 'a' or $u->tagName == 'area') and $u->getAttribute('href') !== null) {
|
||||||
$uValue = $u->getAttribute('href');
|
$uValue = $u->getAttribute('href');
|
||||||
} elseif ($u->tagName == 'img' and $u->getAttribute('src') !== null) {
|
} elseif (in_array($u->tagName, array('img', 'audio', 'video', 'source')) and $u->getAttribute('src') !== null) {
|
||||||
$uValue = $u->getAttribute('src');
|
$uValue = $u->getAttribute('src');
|
||||||
} elseif ($u->tagName == 'object' and $u->getAttribute('data') !== null) {
|
} elseif ($u->tagName == 'object' and $u->getAttribute('data') !== null) {
|
||||||
$uValue = $u->getAttribute('data');
|
$uValue = $u->getAttribute('data');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($uValue)) {
|
if (isset($uValue)) {
|
||||||
return $this->resolveUrl($uValue);
|
return $this->resolveUrl($uValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
$classTitle = $this->parseValueClassTitle($u);
|
$classTitle = $this->parseValueClassTitle($u);
|
||||||
|
|
||||||
if ($classTitle !== null) {
|
if ($classTitle !== null) {
|
||||||
return $classTitle;
|
return $classTitle;
|
||||||
} elseif ($u->tagName == 'abbr' and $u->getAttribute('title') !== null) {
|
} elseif ($u->tagName == 'abbr' and $u->getAttribute('title') !== null) {
|
||||||
@ -468,7 +472,7 @@ class Parser {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an element with class="dt-*", get the value of the datetime as a php date object
|
* Given an element with class="dt-*", get the value of the datetime as a php date object
|
||||||
*
|
*
|
||||||
* @param DOMElement $dt The element to parse
|
* @param DOMElement $dt The element to parse
|
||||||
* @param array $dates Array of dates processed so far
|
* @param array $dates Array of dates processed so far
|
||||||
* @return string The datetime string found
|
* @return string The datetime string found
|
||||||
@ -477,11 +481,11 @@ class Parser {
|
|||||||
// Check for value-class pattern
|
// Check for value-class pattern
|
||||||
$valueClassChildren = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value ") or contains(concat(" ", @class, " "), " value-title ")]', $dt);
|
$valueClassChildren = $this->xpath->query('./*[contains(concat(" ", @class, " "), " value ") or contains(concat(" ", @class, " "), " value-title ")]', $dt);
|
||||||
$dtValue = false;
|
$dtValue = false;
|
||||||
|
|
||||||
if ($valueClassChildren->length > 0) {
|
if ($valueClassChildren->length > 0) {
|
||||||
// They’re using value-class
|
// They’re using value-class
|
||||||
$dateParts = array();
|
$dateParts = array();
|
||||||
|
|
||||||
foreach ($valueClassChildren as $e) {
|
foreach ($valueClassChildren as $e) {
|
||||||
if (strstr(' ' . $e->getAttribute('class') . ' ', ' value-title ')) {
|
if (strstr(' ' . $e->getAttribute('class') . ' ', ' value-title ')) {
|
||||||
$title = $e->getAttribute('title');
|
$title = $e->getAttribute('title');
|
||||||
@ -591,16 +595,16 @@ class Parser {
|
|||||||
$dtValue = $dt->nodeValue;
|
$dtValue = $dt->nodeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( preg_match('/(\d{4}-\d{2}-\d{2})/', $dtValue, $matches) ) {
|
if (preg_match('/(\d{4}-\d{2}-\d{2})/', $dtValue, $matches)) {
|
||||||
$dates[] = $matches[0];
|
$dates[] = $matches[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if $dtValue is only a time and there are recently parsed dates,
|
* if $dtValue is only a time and there are recently parsed dates,
|
||||||
* form the full date-time using the most recnetly parsed dt- value
|
* form the full date-time using the most recently parsed dt- value
|
||||||
*/
|
*/
|
||||||
if ( (preg_match('/^\d{1,2}:\d{1,2}(Z?[+|-]\d{2}:?\d{2})?/', $dtValue) or preg_match('/^\d{1,2}[a|p]m/', $dtValue)) && !empty($dates) ) {
|
if ((preg_match('/^\d{1,2}:\d{1,2}(Z?[+|-]\d{2}:?\d{2})?/', $dtValue) or preg_match('/^\d{1,2}[a|p]m/', $dtValue)) && !empty($dates)) {
|
||||||
$dtValue = convertTimeFormat($dtValue);
|
$dtValue = convertTimeFormat($dtValue);
|
||||||
$dtValue = end($dates) . 'T' . unicodeTrim($dtValue, 'T');
|
$dtValue = end($dates) . 'T' . unicodeTrim($dtValue, 'T');
|
||||||
}
|
}
|
||||||
@ -613,15 +617,15 @@ class Parser {
|
|||||||
*
|
*
|
||||||
* @param DOMElement $e The element to parse
|
* @param DOMElement $e The element to parse
|
||||||
* @return string $e’s innerHTML
|
* @return string $e’s innerHTML
|
||||||
*
|
*
|
||||||
* @todo need to mark this element as e- parsed so it doesn’t get parsed as it’s parent’s e-* too
|
* @todo need to mark this element as e- parsed so it doesn’t get parsed as it’s parent’s e-* too
|
||||||
*/
|
*/
|
||||||
public function parseE(\DOMElement $e) {
|
public function parseE(\DOMElement $e) {
|
||||||
$classTitle = $this->parseValueClassTitle($e);
|
$classTitle = $this->parseValueClassTitle($e);
|
||||||
|
|
||||||
if ($classTitle !== null)
|
if ($classTitle !== null)
|
||||||
return $classTitle;
|
return $classTitle;
|
||||||
|
|
||||||
// Expand relative URLs within children of this element
|
// Expand relative URLs within children of this element
|
||||||
// TODO: as it is this is not relative to only children, make this .// and rerun tests
|
// TODO: as it is this is not relative to only children, make this .// and rerun tests
|
||||||
$this->resolveChildUrls($e);
|
$this->resolveChildUrls($e);
|
||||||
@ -630,7 +634,7 @@ class Parser {
|
|||||||
foreach ($e->childNodes as $node) {
|
foreach ($e->childNodes as $node) {
|
||||||
$html .= $node->C14N();
|
$html .= $node->C14N();
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'html' => $html,
|
'html' => $html,
|
||||||
'value' => unicodeTrim($this->textContent($e))
|
'value' => unicodeTrim($this->textContent($e))
|
||||||
@ -639,7 +643,7 @@ class Parser {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively parse microformats
|
* Recursively parse microformats
|
||||||
*
|
*
|
||||||
* @param DOMElement $e The element to parse
|
* @param DOMElement $e The element to parse
|
||||||
* @return array A representation of the values contained within microformat $e
|
* @return array A representation of the values contained within microformat $e
|
||||||
*/
|
*/
|
||||||
@ -660,26 +664,39 @@ class Parser {
|
|||||||
foreach ($this->xpath->query('.//*[contains(concat(" ", @class)," h-")]', $e) as $subMF) {
|
foreach ($this->xpath->query('.//*[contains(concat(" ", @class)," h-")]', $e) as $subMF) {
|
||||||
// Parse
|
// Parse
|
||||||
$result = $this->parseH($subMF);
|
$result = $this->parseH($subMF);
|
||||||
|
|
||||||
// If result was already parsed, skip it
|
// If result was already parsed, skip it
|
||||||
if (null === $result)
|
if (null === $result)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// In most cases, the value attribute of the nested microformat should be the p- parsed value of the elemnt.
|
||||||
|
// The only times this is different is when the microformat is nested under certain prefixes, which are handled below.
|
||||||
$result['value'] = $this->parseP($subMF);
|
$result['value'] = $this->parseP($subMF);
|
||||||
|
|
||||||
// Does this µf have any property names other than h-*?
|
// Does this µf have any property names other than h-*?
|
||||||
$properties = nestedMfPropertyNamesFromElement($subMF);
|
$properties = nestedMfPropertyNamesFromElement($subMF);
|
||||||
|
|
||||||
if (!empty($properties)) {
|
if (!empty($properties)) {
|
||||||
// Yes! It’s a nested property µf
|
// Yes! It’s a nested property µf
|
||||||
foreach ($properties as $property) {
|
foreach ($properties as $property => $prefixes) {
|
||||||
$return[$property][] = $result;
|
// Note: handling microformat nesting under multiple conflicting prefixes is not currently specified by the mf2 parsing spec.
|
||||||
|
$prefixSpecificResult = $result;
|
||||||
|
if (in_array('p-', $prefixes)) {
|
||||||
|
$prefixSpecificResult['value'] = $prefixSpecificResult['properties']['name'][0];
|
||||||
|
} elseif (in_array('e-', $prefixes)) {
|
||||||
|
$eParsedResult = $this->parseE($subMF);
|
||||||
|
$prefixSpecificResult['html'] = $eParsedResult['html'];
|
||||||
|
$prefixSpecificResult['value'] = $eParsedResult['value'];
|
||||||
|
} elseif (in_array('u-', $prefixes)) {
|
||||||
|
$prefixSpecificResult['value'] = $this->parseU($subMF);
|
||||||
|
}
|
||||||
|
$return[$property][] = $prefixSpecificResult;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No, it’s a child µf
|
// No, it’s a child µf
|
||||||
$children[] = $result;
|
$children[] = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure this sub-mf won’t get parsed as a µf or property
|
// Make sure this sub-mf won’t get parsed as a µf or property
|
||||||
// TODO: Determine if clearing this is required?
|
// TODO: Determine if clearing this is required?
|
||||||
$this->elementPrefixParsed($subMF, 'h');
|
$this->elementPrefixParsed($subMF, 'h');
|
||||||
@ -689,19 +706,24 @@ class Parser {
|
|||||||
$this->elementPrefixParsed($subMF, 'e');
|
$this->elementPrefixParsed($subMF, 'e');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($e->tagName == 'area') {
|
||||||
|
$coords = $e->getAttribute('coords');
|
||||||
|
$shape = $e->getAttribute('shape');
|
||||||
|
}
|
||||||
|
|
||||||
// Handle p-*
|
// Handle p-*
|
||||||
foreach ($this->xpath->query('.//*[contains(concat(" ", @class) ," p-")]', $e) as $p) {
|
foreach ($this->xpath->query('.//*[contains(concat(" ", @class) ," p-")]', $e) as $p) {
|
||||||
if ($this->isElementParsed($p, 'p'))
|
if ($this->isElementParsed($p, 'p'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$pValue = $this->parseP($p);
|
$pValue = $this->parseP($p);
|
||||||
|
|
||||||
// Add the value to the array for it’s p- properties
|
// Add the value to the array for it’s p- properties
|
||||||
foreach (mfNamesFromElement($p, 'p-') as $propName) {
|
foreach (mfNamesFromElement($p, 'p-') as $propName) {
|
||||||
if (!empty($propName))
|
if (!empty($propName))
|
||||||
$return[$propName][] = $pValue;
|
$return[$propName][] = $pValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure this sub-mf won’t get parsed as a top level mf
|
// Make sure this sub-mf won’t get parsed as a top level mf
|
||||||
$this->elementPrefixParsed($p, 'p');
|
$this->elementPrefixParsed($p, 'p');
|
||||||
}
|
}
|
||||||
@ -710,32 +732,32 @@ class Parser {
|
|||||||
foreach ($this->xpath->query('.//*[contains(concat(" ", @class)," u-")]', $e) as $u) {
|
foreach ($this->xpath->query('.//*[contains(concat(" ", @class)," u-")]', $e) as $u) {
|
||||||
if ($this->isElementParsed($u, 'u'))
|
if ($this->isElementParsed($u, 'u'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$uValue = $this->parseU($u);
|
$uValue = $this->parseU($u);
|
||||||
|
|
||||||
// Add the value to the array for it’s property types
|
// Add the value to the array for it’s property types
|
||||||
foreach (mfNamesFromElement($u, 'u-') as $propName) {
|
foreach (mfNamesFromElement($u, 'u-') as $propName) {
|
||||||
$return[$propName][] = $uValue;
|
$return[$propName][] = $uValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure this sub-mf won’t get parsed as a top level mf
|
// Make sure this sub-mf won’t get parsed as a top level mf
|
||||||
$this->elementPrefixParsed($u, 'u');
|
$this->elementPrefixParsed($u, 'u');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle dt-*
|
// Handle dt-*
|
||||||
foreach ($this->xpath->query('.//*[contains(concat(" ", @class), " dt-")]', $e) as $dt) {
|
foreach ($this->xpath->query('.//*[contains(concat(" ", @class), " dt-")]', $e) as $dt) {
|
||||||
if ($this->isElementParsed($dt, 'dt'))
|
if ($this->isElementParsed($dt, 'dt'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
$dtValue = $this->parseDT($dt, $dates);
|
$dtValue = $this->parseDT($dt, $dates);
|
||||||
|
|
||||||
if ($dtValue) {
|
if ($dtValue) {
|
||||||
// Add the value to the array for dt- properties
|
// Add the value to the array for dt- properties
|
||||||
foreach (mfNamesFromElement($dt, 'dt-') as $propName) {
|
foreach (mfNamesFromElement($dt, 'dt-') as $propName) {
|
||||||
$return[$propName][] = $dtValue;
|
$return[$propName][] = $dtValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure this sub-mf won’t get parsed as a top level mf
|
// Make sure this sub-mf won’t get parsed as a top level mf
|
||||||
$this->elementPrefixParsed($dt, 'dt');
|
$this->elementPrefixParsed($dt, 'dt');
|
||||||
}
|
}
|
||||||
@ -762,22 +784,43 @@ class Parser {
|
|||||||
if (!array_key_exists('name', $return)) {
|
if (!array_key_exists('name', $return)) {
|
||||||
try {
|
try {
|
||||||
// Look for img @alt
|
// Look for img @alt
|
||||||
if ($e->tagName == 'img' and $e->getAttribute('alt') != '')
|
if (($e->tagName == 'img' or $e->tagName == 'area') and $e->getAttribute('alt') != '')
|
||||||
throw new Exception($e->getAttribute('alt'));
|
throw new Exception($e->getAttribute('alt'));
|
||||||
|
|
||||||
if ($e->tagName == 'abbr' and $e->hasAttribute('title'))
|
if ($e->tagName == 'abbr' and $e->hasAttribute('title'))
|
||||||
throw new Exception($e->getAttribute('title'));
|
throw new Exception($e->getAttribute('title'));
|
||||||
|
|
||||||
// Look for nested img @alt
|
// Look for nested img @alt
|
||||||
foreach ($this->xpath->query('./img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
|
foreach ($this->xpath->query('./img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
|
||||||
if ($em->getAttribute('alt') != '')
|
$emNames = mfNamesFromElement($em, 'h-');
|
||||||
|
if (empty($emNames) && $em->getAttribute('alt') != '') {
|
||||||
throw new Exception($em->getAttribute('alt'));
|
throw new Exception($em->getAttribute('alt'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for nested area @alt
|
||||||
|
foreach ($this->xpath->query('./area[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
|
||||||
|
$emNames = mfNamesFromElement($em, 'h-');
|
||||||
|
if (empty($emNames) && $em->getAttribute('alt') != '') {
|
||||||
|
throw new Exception($em->getAttribute('alt'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Look for double nested img @alt
|
// Look for double nested img @alt
|
||||||
foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
|
foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/img[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
|
||||||
if ($em->getAttribute('alt') != '')
|
$emNames = mfNamesFromElement($em, 'h-');
|
||||||
|
if (empty($emNames) && $em->getAttribute('alt') != '') {
|
||||||
throw new Exception($em->getAttribute('alt'));
|
throw new Exception($em->getAttribute('alt'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for double nested img @alt
|
||||||
|
foreach ($this->xpath->query('./*[count(preceding-sibling::*)+count(following-sibling::*)=0]/area[count(preceding-sibling::*)+count(following-sibling::*)=0]', $e) as $em) {
|
||||||
|
$emNames = mfNamesFromElement($em, 'h-');
|
||||||
|
if (empty($emNames) && $em->getAttribute('alt') != '') {
|
||||||
|
throw new Exception($em->getAttribute('alt'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Exception($e->nodeValue);
|
throw new Exception($e->nodeValue);
|
||||||
@ -812,36 +855,58 @@ class Parser {
|
|||||||
// Check for u-url
|
// Check for u-url
|
||||||
if (!array_key_exists('url', $return)) {
|
if (!array_key_exists('url', $return)) {
|
||||||
// Look for img @src
|
// Look for img @src
|
||||||
if ($e->tagName == 'a')
|
if ($e->tagName == 'a' or $e->tagName == 'area')
|
||||||
$url = $e->getAttribute('href');
|
$url = $e->getAttribute('href');
|
||||||
|
|
||||||
// Look for nested img @src
|
// Look for nested a @href
|
||||||
foreach ($this->xpath->query('./a[count(preceding-sibling::a)+count(following-sibling::a)=0]', $e) as $em) {
|
foreach ($this->xpath->query('./a[count(preceding-sibling::a)+count(following-sibling::a)=0]', $e) as $em) {
|
||||||
$url = $em->getAttribute('href');
|
$emNames = mfNamesFromElement($em, 'h-');
|
||||||
break;
|
if (empty($emNames)) {
|
||||||
|
$url = $em->getAttribute('href');
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Look for nested area @src
|
||||||
|
foreach ($this->xpath->query('./area[count(preceding-sibling::area)+count(following-sibling::area)=0]', $e) as $em) {
|
||||||
|
$emNames = mfNamesFromElement($em, 'h-');
|
||||||
|
if (empty($emNames)) {
|
||||||
|
$url = $em->getAttribute('href');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty($url))
|
if (!empty($url))
|
||||||
$return['url'][] = $this->resolveUrl($url);
|
$return['url'][] = $this->resolveUrl($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure things are in alphabetical order
|
// Make sure things are in alphabetical order
|
||||||
sort($mfTypes);
|
sort($mfTypes);
|
||||||
|
|
||||||
// Phew. Return the final result.
|
// Phew. Return the final result.
|
||||||
$parsed = array(
|
$parsed = array(
|
||||||
'type' => $mfTypes,
|
'type' => $mfTypes,
|
||||||
'properties' => $return
|
'properties' => $return
|
||||||
);
|
);
|
||||||
if (!empty($children))
|
|
||||||
|
if (!empty($shape)) {
|
||||||
|
$parsed['shape'] = $shape;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($coords)) {
|
||||||
|
$parsed['coords'] = $coords;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($children)) {
|
||||||
$parsed['children'] = array_values(array_filter($children));
|
$parsed['children'] = array_values(array_filter($children));
|
||||||
|
}
|
||||||
return $parsed;
|
return $parsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse Rels and Alternatives
|
* Parse Rels and Alternatives
|
||||||
*
|
*
|
||||||
* Returns [$rels, $alternatives]. If the $rels value is to be empty, i.e. there are no links on the page
|
* Returns [$rels, $alternatives]. If the $rels value is to be empty, i.e. there are no links on the page
|
||||||
* with a rel value *not* containing `alternate`, then the type of $rels depends on $this->jsonMode. If set
|
* with a rel value *not* containing `alternate`, then the type of $rels depends on $this->jsonMode. If set
|
||||||
* to true, it will be a stdClass instance, optimising for JSON serialisation. Otherwise (the default case),
|
* to true, it will be a stdClass instance, optimising for JSON serialisation. Otherwise (the default case),
|
||||||
* it will be an empty array.
|
* it will be an empty array.
|
||||||
@ -849,18 +914,18 @@ class Parser {
|
|||||||
public function parseRelsAndAlternates() {
|
public function parseRelsAndAlternates() {
|
||||||
$rels = array();
|
$rels = array();
|
||||||
$alternates = array();
|
$alternates = array();
|
||||||
|
|
||||||
// Iterate through all a, area and link elements with rel attributes
|
// Iterate through all a, area and link elements with rel attributes
|
||||||
foreach ($this->xpath->query('//*[@rel and @href]') as $hyperlink) {
|
foreach ($this->xpath->query('//*[@rel and @href]') as $hyperlink) {
|
||||||
if ($hyperlink->getAttribute('rel') == '')
|
if ($hyperlink->getAttribute('rel') == '')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Resolve the href
|
// Resolve the href
|
||||||
$href = $this->resolveUrl($hyperlink->getAttribute('href'));
|
$href = $this->resolveUrl($hyperlink->getAttribute('href'));
|
||||||
|
|
||||||
// Split up the rel into space-separated values
|
// Split up the rel into space-separated values
|
||||||
$linkRels = array_filter(explode(' ', $hyperlink->getAttribute('rel')));
|
$linkRels = array_filter(explode(' ', $hyperlink->getAttribute('rel')));
|
||||||
|
|
||||||
// If alternate in rels, create alternate structure, append
|
// If alternate in rels, create alternate structure, append
|
||||||
if (in_array('alternate', $linkRels)) {
|
if (in_array('alternate', $linkRels)) {
|
||||||
$alt = array(
|
$alt = array(
|
||||||
@ -869,10 +934,19 @@ class Parser {
|
|||||||
);
|
);
|
||||||
if ($hyperlink->hasAttribute('media'))
|
if ($hyperlink->hasAttribute('media'))
|
||||||
$alt['media'] = $hyperlink->getAttribute('media');
|
$alt['media'] = $hyperlink->getAttribute('media');
|
||||||
|
|
||||||
if ($hyperlink->hasAttribute('hreflang'))
|
if ($hyperlink->hasAttribute('hreflang'))
|
||||||
$alt['hreflang'] = $hyperlink->getAttribute('hreflang');
|
$alt['hreflang'] = $hyperlink->getAttribute('hreflang');
|
||||||
|
|
||||||
|
if ($hyperlink->hasAttribute('title'))
|
||||||
|
$alt['title'] = $hyperlink->getAttribute('title');
|
||||||
|
|
||||||
|
if ($hyperlink->hasAttribute('type'))
|
||||||
|
$alt['type'] = $hyperlink->getAttribute('type');
|
||||||
|
|
||||||
|
if ($hyperlink->nodeValue)
|
||||||
|
$alt['text'] = $hyperlink->nodeValue;
|
||||||
|
|
||||||
$alternates[] = $alt;
|
$alternates[] = $alt;
|
||||||
} else {
|
} else {
|
||||||
foreach ($linkRels as $rel) {
|
foreach ($linkRels as $rel) {
|
||||||
@ -880,38 +954,38 @@ class Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($rels) and $this->jsonMode) {
|
if (empty($rels) and $this->jsonMode) {
|
||||||
$rels = new stdClass();
|
$rels = new stdClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
return array($rels, $alternates);
|
return array($rels, $alternates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kicks off the parsing routine
|
* Kicks off the parsing routine
|
||||||
*
|
*
|
||||||
* If `$htmlSafe` is set, any angle brackets in the results from non e-* properties
|
* If `$htmlSafe` is set, any angle brackets in the results from non e-* properties
|
||||||
* will be HTML-encoded, bringing all output to the same level of encoding.
|
* will be HTML-encoded, bringing all output to the same level of encoding.
|
||||||
*
|
*
|
||||||
* If a DOMElement is set as the $context, only descendants of that element will
|
* If a DOMElement is set as the $context, only descendants of that element will
|
||||||
* be parsed for microformats.
|
* be parsed for microformats.
|
||||||
*
|
*
|
||||||
* @param bool $htmlSafe whether or not to html-encode non e-* properties. Defaults to false
|
* @param bool $htmlSafe whether or not to html-encode non e-* properties. Defaults to false
|
||||||
* @param DOMElement $context optionally an element from which to parse microformats
|
* @param DOMElement $context optionally an element from which to parse microformats
|
||||||
* @return array An array containing all the µfs found in the current document
|
* @return array An array containing all the µfs found in the current document
|
||||||
*/
|
*/
|
||||||
public function parse($convertClassic = true, DOMElement $context = null) {
|
public function parse($convertClassic = true, DOMElement $context = null) {
|
||||||
$mfs = array();
|
$mfs = array();
|
||||||
|
|
||||||
if ($convertClassic) {
|
if ($convertClassic) {
|
||||||
$this->convertLegacy();
|
$this->convertLegacy();
|
||||||
}
|
}
|
||||||
|
|
||||||
$mfElements = null === $context
|
$mfElements = null === $context
|
||||||
? $this->xpath->query('//*[contains(concat(" ", @class), " h-")]')
|
? $this->xpath->query('//*[contains(concat(" ", @class), " h-")]')
|
||||||
: $this->xpath->query('.//*[contains(concat(" ", @class), " h-")]', $context);
|
: $this->xpath->query('.//*[contains(concat(" ", @class), " h-")]', $context);
|
||||||
|
|
||||||
// Parser microformats
|
// Parser microformats
|
||||||
foreach ($mfElements as $node) {
|
foreach ($mfElements as $node) {
|
||||||
// For each microformat
|
// For each microformat
|
||||||
@ -920,64 +994,64 @@ class Parser {
|
|||||||
// Add the value to the array for this property type
|
// Add the value to the array for this property type
|
||||||
$mfs[] = $result;
|
$mfs[] = $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse rels
|
// Parse rels
|
||||||
list($rels, $alternates) = $this->parseRelsAndAlternates();
|
list($rels, $alternates) = $this->parseRelsAndAlternates();
|
||||||
|
|
||||||
$top = array(
|
$top = array(
|
||||||
'items' => array_values(array_filter($mfs)),
|
'items' => array_values(array_filter($mfs)),
|
||||||
'rels' => $rels
|
'rels' => $rels
|
||||||
);
|
);
|
||||||
|
|
||||||
if (count($alternates))
|
if (count($alternates))
|
||||||
$top['alternates'] = $alternates;
|
$top['alternates'] = $alternates;
|
||||||
|
|
||||||
return $top;
|
return $top;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse From ID
|
* Parse From ID
|
||||||
*
|
*
|
||||||
* Given an ID, parse all microformats which are children of the element with
|
* Given an ID, parse all microformats which are children of the element with
|
||||||
* that ID.
|
* that ID.
|
||||||
*
|
*
|
||||||
* Note that rel values are still document-wide.
|
* Note that rel values are still document-wide.
|
||||||
*
|
*
|
||||||
* If an element with the ID is not found, an empty skeleton mf2 array structure
|
* If an element with the ID is not found, an empty skeleton mf2 array structure
|
||||||
* will be returned.
|
* will be returned.
|
||||||
*
|
*
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @param bool $htmlSafe = false whether or not to HTML-encode angle brackets in non e-* properties
|
* @param bool $htmlSafe = false whether or not to HTML-encode angle brackets in non e-* properties
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function parseFromId($id, $convertClassic=true) {
|
public function parseFromId($id, $convertClassic=true) {
|
||||||
$matches = $this->xpath->query("//*[@id='{$id}']");
|
$matches = $this->xpath->query("//*[@id='{$id}']");
|
||||||
|
|
||||||
if (empty($matches))
|
if (empty($matches))
|
||||||
return array('items' => array(), 'rels' => array(), 'alternates' => array());
|
return array('items' => array(), 'rels' => array(), 'alternates' => array());
|
||||||
|
|
||||||
return $this->parse($convertClassic, $matches->item(0));
|
return $this->parse($convertClassic, $matches->item(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert Legacy Classnames
|
* Convert Legacy Classnames
|
||||||
*
|
*
|
||||||
* Adds microformats2 classnames into a document containing only legacy
|
* Adds microformats2 classnames into a document containing only legacy
|
||||||
* semantic classnames.
|
* semantic classnames.
|
||||||
*
|
*
|
||||||
* @return Parser $this
|
* @return Parser $this
|
||||||
*/
|
*/
|
||||||
public function convertLegacy() {
|
public function convertLegacy() {
|
||||||
$doc = $this->doc;
|
$doc = $this->doc;
|
||||||
$xp = new DOMXPath($doc);
|
$xp = new DOMXPath($doc);
|
||||||
|
|
||||||
// replace all roots
|
// replace all roots
|
||||||
foreach ($this->classicRootMap as $old => $new) {
|
foreach ($this->classicRootMap as $old => $new) {
|
||||||
foreach ($xp->query('//*[contains(concat(" ", @class, " "), " ' . $old . ' ") and not(contains(concat(" ", @class, " "), " ' . $new . ' "))]') as $el) {
|
foreach ($xp->query('//*[contains(concat(" ", @class, " "), " ' . $old . ' ") and not(contains(concat(" ", @class, " "), " ' . $new . ' "))]') as $el) {
|
||||||
$el->setAttribute('class', $el->getAttribute('class') . ' ' . $new);
|
$el->setAttribute('class', $el->getAttribute('class') . ' ' . $new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->classicPropertyMap as $oldRoot => $properties) {
|
foreach ($this->classicPropertyMap as $oldRoot => $properties) {
|
||||||
$newRoot = $this->classicRootMap[$oldRoot];
|
$newRoot = $this->classicRootMap[$oldRoot];
|
||||||
foreach ($properties as $old => $new) {
|
foreach ($properties as $old => $new) {
|
||||||
@ -986,16 +1060,16 @@ class Parser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* XPath Query
|
* XPath Query
|
||||||
*
|
*
|
||||||
* Runs an XPath query over the current document. Works in exactly the same
|
* Runs an XPath query over the current document. Works in exactly the same
|
||||||
* way as DOMXPath::query.
|
* way as DOMXPath::query.
|
||||||
*
|
*
|
||||||
* @param string $expression
|
* @param string $expression
|
||||||
* @param DOMNode $context
|
* @param DOMNode $context
|
||||||
* @return DOMNodeList
|
* @return DOMNodeList
|
||||||
@ -1003,7 +1077,7 @@ class Parser {
|
|||||||
public function query($expression, $context = null) {
|
public function query($expression, $context = null) {
|
||||||
return $this->xpath->query($expression, $context);
|
return $this->xpath->query($expression, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classic Root Classname map
|
* Classic Root Classname map
|
||||||
*/
|
*/
|
||||||
@ -1013,11 +1087,11 @@ class Parser {
|
|||||||
'hentry' => 'h-entry',
|
'hentry' => 'h-entry',
|
||||||
'hrecipe' => 'h-recipe',
|
'hrecipe' => 'h-recipe',
|
||||||
'hresume' => 'h-resume',
|
'hresume' => 'h-resume',
|
||||||
'hevent' => 'h-event',
|
'vevent' => 'h-event',
|
||||||
'hreview' => 'h-review',
|
'hreview' => 'h-review',
|
||||||
'hproduct' => 'h-product'
|
'hproduct' => 'h-product'
|
||||||
);
|
);
|
||||||
|
|
||||||
public $classicPropertyMap = array(
|
public $classicPropertyMap = array(
|
||||||
'vcard' => array(
|
'vcard' => array(
|
||||||
'fn' => 'p-name',
|
'fn' => 'p-name',
|
||||||
@ -1084,7 +1158,7 @@ class Parser {
|
|||||||
'skill' => 'p-skill',
|
'skill' => 'p-skill',
|
||||||
'affiliation' => 'p-affiliation h-card',
|
'affiliation' => 'p-affiliation h-card',
|
||||||
),
|
),
|
||||||
'hevent' => array(
|
'vevent' => array(
|
||||||
'dtstart' => 'dt-start',
|
'dtstart' => 'dt-start',
|
||||||
'dtend' => 'dt-end',
|
'dtend' => 'dt-end',
|
||||||
'duration' => 'dt-duration',
|
'duration' => 'dt-duration',
|
||||||
@ -1246,7 +1320,7 @@ function resolveUrl($baseURI, $referenceURI) {
|
|||||||
# 5.2.3 Merge Paths
|
# 5.2.3 Merge Paths
|
||||||
function mergePaths($base, $reference) {
|
function mergePaths($base, $reference) {
|
||||||
# If the base URI has a defined authority component and an empty
|
# If the base URI has a defined authority component and an empty
|
||||||
# path,
|
# path,
|
||||||
if($base['authority'] && $base['path'] == null) {
|
if($base['authority'] && $base['path'] == null) {
|
||||||
# then return a string consisting of "/" concatenated with the
|
# then return a string consisting of "/" concatenated with the
|
||||||
# reference's path; otherwise,
|
# reference's path; otherwise,
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
<?php
|
|
||||||
if ( !function_exists('sys_get_temp_dir')) {
|
|
||||||
function sys_get_temp_dir() {
|
|
||||||
if (!empty($_ENV['TMP'])) { return realpath($_ENV['TMP']); }
|
|
||||||
if (!empty($_ENV['TMPDIR'])) { return realpath( $_ENV['TMPDIR']); }
|
|
||||||
if (!empty($_ENV['TEMP'])) { return realpath( $_ENV['TEMP']); }
|
|
||||||
$tempfile=tempnam(uniqid(rand(),TRUE),'');
|
|
||||||
if (file_exists($tempfile)) {
|
|
||||||
unlink($tempfile);
|
|
||||||
}
|
|
||||||
return realpath(dirname($tempfile));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
0
file/.gitignore
vendored
0
file/.gitignore
vendored
@ -1081,12 +1081,12 @@ var SN = { // StatusNet
|
|||||||
label.attr('title', label.text());
|
label.attr('title', label.text());
|
||||||
|
|
||||||
check.change(function () {
|
check.change(function () {
|
||||||
if (check.prop('checked') === true || $.cookie(SN.C.S.NoticeDataGeoCookie) === null) {
|
if (check.prop('checked') === true || $.cookie(SN.C.S.NoticeDataGeoCookie) === undefined) {
|
||||||
label
|
label
|
||||||
.attr('title', NoticeDataGeo_text.ShareDisable)
|
.attr('title', NoticeDataGeo_text.ShareDisable)
|
||||||
.addClass('checked');
|
.addClass('checked');
|
||||||
|
|
||||||
if ($.cookie(SN.C.S.NoticeDataGeoCookie) === null || $.cookie(SN.C.S.NoticeDataGeoCookie) == 'disabled') {
|
if ($.cookie(SN.C.S.NoticeDataGeoCookie) === undefined || $.cookie(SN.C.S.NoticeDataGeoCookie) == 'disabled') {
|
||||||
if (navigator.geolocation) {
|
if (navigator.geolocation) {
|
||||||
SN.U.NoticeGeoStatus(form, 'Requesting location from browser...');
|
SN.U.NoticeGeoStatus(form, 'Requesting location from browser...');
|
||||||
navigator.geolocation.getCurrentPosition(
|
navigator.geolocation.getCurrentPosition(
|
||||||
@ -1297,7 +1297,7 @@ var SN = { // StatusNet
|
|||||||
* @fixme what is this?
|
* @fixme what is this?
|
||||||
*/
|
*/
|
||||||
Delete: function () {
|
Delete: function () {
|
||||||
$.cookie(SN.C.S.StatusNetInstance, null);
|
$.removeCookie(SN.C.S.StatusNetInstance);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ class Action extends HTMLOutputter // lawsuit
|
|||||||
*
|
*
|
||||||
* @return nothing
|
* @return nothing
|
||||||
*/
|
*/
|
||||||
function showPage()
|
public function showPage()
|
||||||
{
|
{
|
||||||
if (GNUsocial::isAjax()) {
|
if (GNUsocial::isAjax()) {
|
||||||
self::showAjax();
|
self::showAjax();
|
||||||
|
@ -281,19 +281,20 @@ class ActivityUtils
|
|||||||
static function validateUri($uri)
|
static function validateUri($uri)
|
||||||
{
|
{
|
||||||
// Check mailto: URIs first
|
// Check mailto: URIs first
|
||||||
|
$validate = new Validate();
|
||||||
|
|
||||||
if (preg_match('/^mailto:(.*)$/', $uri, $match)) {
|
if (preg_match('/^mailto:(.*)$/', $uri, $match)) {
|
||||||
return Validate::email($match[1], common_config('email', 'check_domain'));
|
return $validate->email($match[1], common_config('email', 'check_domain'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Validate::uri($uri)) {
|
if ($validate->uri($uri)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possibly an upstream bug; tag: URIs aren't validated properly
|
// Possibly an upstream bug; tag: URIs aren't validated properly
|
||||||
// unless you explicitly ask for them. All other schemes are accepted
|
// unless you explicitly ask for them. All other schemes are accepted
|
||||||
// for basic URI validation without asking.
|
// for basic URI validation without asking.
|
||||||
if (Validate::uri($uri, array('allowed_scheme' => array('tag')))) {
|
if ($validate->uri($uri, array('allowed_scheme' => array('tag')))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ class ApiAction extends Action
|
|||||||
|
|
||||||
$twitter_user['friends_count'] = $profile->subscriptionCount();
|
$twitter_user['friends_count'] = $profile->subscriptionCount();
|
||||||
|
|
||||||
$twitter_user['created_at'] = $this->dateTwitter($profile->created);
|
$twitter_user['created_at'] = self::dateTwitter($profile->created);
|
||||||
|
|
||||||
$timezone = 'UTC';
|
$timezone = 'UTC';
|
||||||
|
|
||||||
@ -322,7 +322,7 @@ class ApiAction extends Action
|
|||||||
$twitter_status = array();
|
$twitter_status = array();
|
||||||
$twitter_status['text'] = $notice->content;
|
$twitter_status['text'] = $notice->content;
|
||||||
$twitter_status['truncated'] = false; # Not possible on StatusNet
|
$twitter_status['truncated'] = false; # Not possible on StatusNet
|
||||||
$twitter_status['created_at'] = $this->dateTwitter($notice->created);
|
$twitter_status['created_at'] = self::dateTwitter($notice->created);
|
||||||
try {
|
try {
|
||||||
// We could just do $notice->reply_to but maybe the future holds a
|
// We could just do $notice->reply_to but maybe the future holds a
|
||||||
// different story for parenting.
|
// different story for parenting.
|
||||||
@ -366,12 +366,13 @@ class ApiAction extends Action
|
|||||||
$twitter_status['in_reply_to_screen_name'] =
|
$twitter_status['in_reply_to_screen_name'] =
|
||||||
($replier_profile) ? $replier_profile->nickname : null;
|
($replier_profile) ? $replier_profile->nickname : null;
|
||||||
|
|
||||||
if (isset($notice->lat) && isset($notice->lon)) {
|
try {
|
||||||
|
$notloc = Notice_location::locFromStored($notice);
|
||||||
// This is the format that GeoJSON expects stuff to be in
|
// This is the format that GeoJSON expects stuff to be in
|
||||||
$twitter_status['geo'] = array('type' => 'Point',
|
$twitter_status['geo'] = array('type' => 'Point',
|
||||||
'coordinates' => array((float) $notice->lat,
|
'coordinates' => array((float) $notloc->lat,
|
||||||
(float) $notice->lon));
|
(float) $notloc->lon));
|
||||||
} else {
|
} catch (ServerException $e) {
|
||||||
$twitter_status['geo'] = null;
|
$twitter_status['geo'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,8 +441,8 @@ class ApiAction extends Action
|
|||||||
$twitter_group['homepage'] = $group->homepage;
|
$twitter_group['homepage'] = $group->homepage;
|
||||||
$twitter_group['description'] = $group->description;
|
$twitter_group['description'] = $group->description;
|
||||||
$twitter_group['location'] = $group->location;
|
$twitter_group['location'] = $group->location;
|
||||||
$twitter_group['created'] = $this->dateTwitter($group->created);
|
$twitter_group['created'] = self::dateTwitter($group->created);
|
||||||
$twitter_group['modified'] = $this->dateTwitter($group->modified);
|
$twitter_group['modified'] = self::dateTwitter($group->modified);
|
||||||
|
|
||||||
return $twitter_group;
|
return $twitter_group;
|
||||||
}
|
}
|
||||||
@ -547,13 +548,14 @@ class ApiAction extends Action
|
|||||||
$entry['pubDate'] = common_date_rfc2822($notice->created);
|
$entry['pubDate'] = common_date_rfc2822($notice->created);
|
||||||
$entry['guid'] = $entry['link'];
|
$entry['guid'] = $entry['link'];
|
||||||
|
|
||||||
if (isset($notice->lat) && isset($notice->lon)) {
|
try {
|
||||||
|
$notloc = Notice_location::locFromStored($notice);
|
||||||
// This is the format that GeoJSON expects stuff to be in.
|
// This is the format that GeoJSON expects stuff to be in.
|
||||||
// showGeoRSS() below uses it for XML output, so we reuse it
|
// showGeoRSS() below uses it for XML output, so we reuse it
|
||||||
$entry['geo'] = array('type' => 'Point',
|
$entry['geo'] = array('type' => 'Point',
|
||||||
'coordinates' => array((float) $notice->lat,
|
'coordinates' => array((float) $notloc->lat,
|
||||||
(float) $notice->lon));
|
(float) $notloc->lon));
|
||||||
} else {
|
} catch (ServerException $e) {
|
||||||
$entry['geo'] = null;
|
$entry['geo'] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,7 +999,13 @@ class ApiAction extends Action
|
|||||||
$statuses = array();
|
$statuses = array();
|
||||||
|
|
||||||
if (is_array($notice)) {
|
if (is_array($notice)) {
|
||||||
$notice = new ArrayWrapper($notice);
|
//FIXME: make everything calling showJsonTimeline use only Notice objects
|
||||||
|
common_debug('ArrayWrapper avoidance in progress! Beep boop, make showJsonTimeline only receive Notice objects!');
|
||||||
|
$ids = array();
|
||||||
|
foreach ($notice as $n) {
|
||||||
|
$ids[] = $n->getID();
|
||||||
|
}
|
||||||
|
$notice = Notice::multiGet('id', $ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ($notice->fetch()) {
|
while ($notice->fetch()) {
|
||||||
@ -1196,7 +1204,7 @@ class ApiAction extends Action
|
|||||||
$this->endDocument('xml');
|
$this->endDocument('xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
function dateTwitter($dt)
|
static function dateTwitter($dt)
|
||||||
{
|
{
|
||||||
$dateStr = date('d F Y H:i:s', strtotime($dt));
|
$dateStr = date('d F Y H:i:s', strtotime($dt));
|
||||||
$d = new DateTime($dateStr, new DateTimeZone('UTC'));
|
$d = new DateTime($dateStr, new DateTimeZone('UTC'));
|
||||||
|
@ -26,20 +26,20 @@ require_once 'OAuth.php';
|
|||||||
*/
|
*/
|
||||||
class ApiGNUsocialOAuthDataStore extends OAuthDataStore
|
class ApiGNUsocialOAuthDataStore extends OAuthDataStore
|
||||||
{
|
{
|
||||||
function lookup_consumer($consumerKey)
|
function lookup_consumer($consumer_key)
|
||||||
{
|
{
|
||||||
$con = Consumer::getKV('consumer_key', $consumerKey);
|
$con = Consumer::getKV('consumer_key', $consumer_key);
|
||||||
|
|
||||||
if (!$con instanceof Consumer) {
|
if (!$con instanceof Consumer) {
|
||||||
|
|
||||||
// Create an anon consumer and anon application if one
|
// Create an anon consumer and anon application if one
|
||||||
// doesn't exist already
|
// doesn't exist already
|
||||||
if ($consumerKey == 'anonymous') {
|
if ($consumer_key == 'anonymous') {
|
||||||
|
|
||||||
common_debug("API OAuth - creating anonymous consumer");
|
common_debug("API OAuth - creating anonymous consumer");
|
||||||
$con = new Consumer();
|
$con = new Consumer();
|
||||||
$con->consumer_key = $consumerKey;
|
$con->consumer_key = $consumer_key;
|
||||||
$con->consumer_secret = $consumerKey;
|
$con->consumer_secret = $consumer_key;
|
||||||
$con->created = common_sql_now();
|
$con->created = common_sql_now();
|
||||||
|
|
||||||
$result = $con->insert();
|
$result = $con->insert();
|
||||||
@ -388,7 +388,7 @@ class ApiGNUsocialOAuthDataStore extends OAuthDataStore
|
|||||||
*
|
*
|
||||||
* @return OAuthToken $token a new unauthorized OAuth request token
|
* @return OAuthToken $token a new unauthorized OAuth request token
|
||||||
*/
|
*/
|
||||||
function new_request_token($consumer, $callback)
|
function new_request_token($consumer, $callback = null)
|
||||||
{
|
{
|
||||||
$t = new Token();
|
$t = new Token();
|
||||||
$t->consumer_key = $consumer->key;
|
$t->consumer_key = $consumer->key;
|
||||||
@ -473,13 +473,13 @@ class ApiGNUsocialOAuthDataStore extends OAuthDataStore
|
|||||||
* @param type $token_key
|
* @param type $token_key
|
||||||
* @return OAuthToken
|
* @return OAuthToken
|
||||||
*/
|
*/
|
||||||
function lookup_token($consumer, $token_type, $token_key)
|
function lookup_token($consumer, $token_type, $token)
|
||||||
{
|
{
|
||||||
$t = new Token();
|
$t = new Token();
|
||||||
if (!is_null($consumer)) {
|
if (!is_null($consumer)) {
|
||||||
$t->consumer_key = $consumer->key;
|
$t->consumer_key = $consumer->key;
|
||||||
}
|
}
|
||||||
$t->tok = $token_key;
|
$t->tok = $token;
|
||||||
$t->type = ($token_type == 'access') ? 1 : 0;
|
$t->type = ($token_type == 'access') ? 1 : 0;
|
||||||
if ($t->find(true)) {
|
if ($t->find(true)) {
|
||||||
return new OAuthToken($t->tok, $t->secret);
|
return new OAuthToken($t->tok, $t->secret);
|
||||||
|
@ -27,13 +27,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR . '/lib/widget.php';
|
|
||||||
|
|
||||||
define('APPS_PER_PAGE', 20);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Widget to show a list of OAuth applications
|
* Widget to show a list of OAuth applications
|
||||||
@ -52,16 +46,12 @@ class ApplicationList extends Widget
|
|||||||
/** Owner of this list */
|
/** Owner of this list */
|
||||||
var $owner = null;
|
var $owner = null;
|
||||||
|
|
||||||
/** Action object using us. */
|
function __construct($application, Profile $owner, Action $out=null)
|
||||||
var $action = null;
|
|
||||||
|
|
||||||
function __construct($application, $owner=null, $action=null)
|
|
||||||
{
|
{
|
||||||
parent::__construct($action);
|
parent::__construct($out);
|
||||||
|
|
||||||
$this->application = $application;
|
$this->application = $application;
|
||||||
$this->owner = $owner;
|
$this->owner = $owner;
|
||||||
$this->action = $action;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function show()
|
function show()
|
||||||
@ -75,7 +65,7 @@ class ApplicationList extends Widget
|
|||||||
if($cnt > APPS_PER_PAGE) {
|
if($cnt > APPS_PER_PAGE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$this->showapplication();
|
$this->showApplication();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->out->elementEnd('ul');
|
$this->out->elementEnd('ul');
|
||||||
@ -85,8 +75,6 @@ class ApplicationList extends Widget
|
|||||||
|
|
||||||
function showApplication()
|
function showApplication()
|
||||||
{
|
{
|
||||||
$user = common_current_user();
|
|
||||||
|
|
||||||
$this->out->elementStart('li', array('class' => 'application h-entry',
|
$this->out->elementStart('li', array('class' => 'application h-entry',
|
||||||
'id' => 'oauthclient-' . $this->application->id));
|
'id' => 'oauthclient-' . $this->application->id));
|
||||||
|
|
||||||
@ -119,140 +107,3 @@ class ApplicationList extends Widget
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Widget to show a list of connected OAuth clients
|
|
||||||
*
|
|
||||||
* @category Application
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Zach Copley <zach@status.net>
|
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
|
||||||
class ConnectedAppsList extends Widget
|
|
||||||
{
|
|
||||||
/** Current connected application query */
|
|
||||||
var $connection = null;
|
|
||||||
|
|
||||||
/** Owner of this list */
|
|
||||||
var $owner = null;
|
|
||||||
|
|
||||||
/** Action object using us. */
|
|
||||||
var $action = null;
|
|
||||||
|
|
||||||
function __construct($connection, $owner=null, $action=null)
|
|
||||||
{
|
|
||||||
parent::__construct($action);
|
|
||||||
|
|
||||||
common_debug("ConnectedAppsList constructor");
|
|
||||||
|
|
||||||
$this->connection = $connection;
|
|
||||||
$this->owner = $owner;
|
|
||||||
$this->action = $action;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Override this in subclasses. */
|
|
||||||
function showOwnerControls()
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
function show()
|
|
||||||
{
|
|
||||||
$this->out->elementStart('ul', 'applications');
|
|
||||||
|
|
||||||
$cnt = 0;
|
|
||||||
|
|
||||||
while ($this->connection->fetch()) {
|
|
||||||
$cnt++;
|
|
||||||
if($cnt > APPS_PER_PAGE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$this->showConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->out->elementEnd('ul');
|
|
||||||
|
|
||||||
return $cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showConnection()
|
|
||||||
{
|
|
||||||
$app = Oauth_application::getKV('id', $this->connection->application_id);
|
|
||||||
|
|
||||||
$this->out->elementStart('li', array('class' => 'application h-entry',
|
|
||||||
'id' => 'oauthclient-' . $app->id));
|
|
||||||
|
|
||||||
$this->out->elementStart('a', array('href' => $app->source_url,
|
|
||||||
'class' => 'h-card p-name'));
|
|
||||||
|
|
||||||
if (!empty($app->icon)) {
|
|
||||||
$this->out->element('img', array('src' => $app->icon,
|
|
||||||
'class' => 'avatar u-photo'));
|
|
||||||
}
|
|
||||||
if ($app->name != 'anonymous') {
|
|
||||||
$this->out->text($app->name);
|
|
||||||
} else {
|
|
||||||
// TRANS: Name for an anonymous application in application list.
|
|
||||||
$this->out->element('span', 'p-name', _('Unknown application'));
|
|
||||||
}
|
|
||||||
$this->out->elementEnd('a');
|
|
||||||
|
|
||||||
if ($app->name != 'anonymous') {
|
|
||||||
// @todo FIXME: i18n trouble.
|
|
||||||
// TRANS: Message has a leading space and a trailing space. Used in application list.
|
|
||||||
// TRANS: Before this message the application name is put, behind it the organisation that manages it.
|
|
||||||
$this->out->raw(_(' by '));
|
|
||||||
|
|
||||||
$this->out->element('a', array('href' => $app->homepage,
|
|
||||||
'class' => 'h-card'),
|
|
||||||
$app->organization);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TRANS: Application access type
|
|
||||||
$readWriteText = _('read-write');
|
|
||||||
// TRANS: Application access type
|
|
||||||
$readOnlyText = _('read-only');
|
|
||||||
|
|
||||||
$access = ($this->connection->access_type & Oauth_application::$writeAccess)
|
|
||||||
? $readWriteText : $readOnlyText;
|
|
||||||
$modifiedDate = common_date_string($this->connection->modified);
|
|
||||||
// TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only")
|
|
||||||
$txt = sprintf(_('Approved %1$s - "%2$s" access.'), $modifiedDate, $access);
|
|
||||||
|
|
||||||
// @todo FIXME: i18n trouble.
|
|
||||||
$this->out->raw(" - $txt");
|
|
||||||
if (!empty($app->description)) {
|
|
||||||
$this->out->element(
|
|
||||||
'p', array('class' => 'application_description'),
|
|
||||||
$app->description
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$this->out->element(
|
|
||||||
'p', array(
|
|
||||||
'class' => 'access_token'),
|
|
||||||
// TRANS: Access token in the application list.
|
|
||||||
// TRANS: %s are the first 7 characters of the access token.
|
|
||||||
sprintf(_('Access token starting with: %s'), substr($this->connection->token, 0, 7))
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->out->elementStart(
|
|
||||||
'form',
|
|
||||||
array(
|
|
||||||
'id' => 'form_revoke_app',
|
|
||||||
'class' => 'form_revoke_app',
|
|
||||||
'method' => 'POST',
|
|
||||||
'action' => common_local_url('oauthconnectionssettings')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
$this->out->elementStart('fieldset');
|
|
||||||
$this->out->hidden('oauth_token', $this->connection->token);
|
|
||||||
$this->out->hidden('token', common_session_token());
|
|
||||||
// TRANS: Button label in application list to revoke access to user data.
|
|
||||||
$this->out->submit('revoke', _m('BUTTON','Revoke'));
|
|
||||||
$this->out->elementEnd('fieldset');
|
|
||||||
$this->out->elementEnd('form');
|
|
||||||
|
|
||||||
$this->out->elementEnd('li');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -113,10 +113,12 @@ class AtomNoticeFeed extends Atom10Feed
|
|||||||
foreach ($notices as $notice) {
|
foreach ($notices as $notice) {
|
||||||
$this->addEntryFromNotice($notice);
|
$this->addEntryFromNotice($notice);
|
||||||
}
|
}
|
||||||
} else {
|
} elseif ($notices instanceof Notice) {
|
||||||
while ($notices->fetch()) {
|
while ($notices->fetch()) {
|
||||||
$this->addEntryFromNotice($notices);
|
$this->addEntryFromNotice($notices);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
throw new ServerException('addEntryFromNotices got neither an array nor a Notice object');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +127,7 @@ class AtomNoticeFeed extends Atom10Feed
|
|||||||
*
|
*
|
||||||
* @param Notice $notice a Notice to add
|
* @param Notice $notice a Notice to add
|
||||||
*/
|
*/
|
||||||
function addEntryFromNotice($notice)
|
function addEntryFromNotice(Notice $notice)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$source = $this->showSource();
|
$source = $this->showSource();
|
||||||
|
@ -201,13 +201,13 @@ abstract class AuthenticationPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStartChangePassword($user,$oldpassword,$newpassword)
|
function onStartChangePassword(Profile $target ,$oldpassword, $newpassword)
|
||||||
{
|
{
|
||||||
if($this->password_changeable){
|
if($this->password_changeable){
|
||||||
$user_username = new User_username();
|
$user_username = new User_username();
|
||||||
$user_username->user_id=$user->id;
|
$user_username->user_id = $target->getID();
|
||||||
$user_username->provider_name=$this->provider_name;
|
$user_username->provider_name=$this->provider_name;
|
||||||
if($user_username->find() && $user_username->fetch()){
|
if ($user_username->find(true)) {
|
||||||
$authenticated = $this->checkPassword($user_username->username, $oldpassword);
|
$authenticated = $this->checkPassword($user_username->username, $oldpassword);
|
||||||
if($authenticated){
|
if($authenticated){
|
||||||
$result = $this->changePassword($user_username->username,$oldpassword,$newpassword);
|
$result = $this->changePassword($user_username->username,$oldpassword,$newpassword);
|
||||||
|
163
lib/connectedappslist.php
Normal file
163
lib/connectedappslist.php
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Widget to show a list of OAuth applications
|
||||||
|
*
|
||||||
|
* 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 Application
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @copyright 2008-2010 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Widget to show a list of connected OAuth clients
|
||||||
|
*
|
||||||
|
* @category Application
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Zach Copley <zach@status.net>
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
class ConnectedAppsList extends Widget
|
||||||
|
{
|
||||||
|
/** Current connected application query */
|
||||||
|
var $connection = null;
|
||||||
|
|
||||||
|
/** Owner of this list */
|
||||||
|
var $owner = null;
|
||||||
|
|
||||||
|
function __construct($connection, Profile $owner, Action $out=null)
|
||||||
|
{
|
||||||
|
parent::__construct($out);
|
||||||
|
|
||||||
|
common_debug("ConnectedAppsList constructor");
|
||||||
|
|
||||||
|
$this->connection = $connection;
|
||||||
|
$this->owner = $owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override this in subclasses. */
|
||||||
|
function showOwnerControls()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function show()
|
||||||
|
{
|
||||||
|
$this->out->elementStart('ul', 'applications');
|
||||||
|
|
||||||
|
$cnt = 0;
|
||||||
|
|
||||||
|
while ($this->connection->fetch()) {
|
||||||
|
$cnt++;
|
||||||
|
if($cnt > APPS_PER_PAGE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$this->showConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->out->elementEnd('ul');
|
||||||
|
|
||||||
|
return $cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
function showConnection()
|
||||||
|
{
|
||||||
|
$app = Oauth_application::getKV('id', $this->connection->application_id);
|
||||||
|
|
||||||
|
$this->out->elementStart('li', array('class' => 'application h-entry',
|
||||||
|
'id' => 'oauthclient-' . $app->id));
|
||||||
|
|
||||||
|
$this->out->elementStart('a', array('href' => $app->source_url,
|
||||||
|
'class' => 'h-card p-name'));
|
||||||
|
|
||||||
|
if (!empty($app->icon)) {
|
||||||
|
$this->out->element('img', array('src' => $app->icon,
|
||||||
|
'class' => 'avatar u-photo'));
|
||||||
|
}
|
||||||
|
if ($app->name != 'anonymous') {
|
||||||
|
$this->out->text($app->name);
|
||||||
|
} else {
|
||||||
|
// TRANS: Name for an anonymous application in application list.
|
||||||
|
$this->out->element('span', 'p-name', _('Unknown application'));
|
||||||
|
}
|
||||||
|
$this->out->elementEnd('a');
|
||||||
|
|
||||||
|
if ($app->name != 'anonymous') {
|
||||||
|
// @todo FIXME: i18n trouble.
|
||||||
|
// TRANS: Message has a leading space and a trailing space. Used in application list.
|
||||||
|
// TRANS: Before this message the application name is put, behind it the organisation that manages it.
|
||||||
|
$this->out->raw(_(' by '));
|
||||||
|
|
||||||
|
$this->out->element('a', array('href' => $app->homepage,
|
||||||
|
'class' => 'h-card'),
|
||||||
|
$app->organization);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TRANS: Application access type
|
||||||
|
$readWriteText = _('read-write');
|
||||||
|
// TRANS: Application access type
|
||||||
|
$readOnlyText = _('read-only');
|
||||||
|
|
||||||
|
$access = ($this->connection->access_type & Oauth_application::$writeAccess)
|
||||||
|
? $readWriteText : $readOnlyText;
|
||||||
|
$modifiedDate = common_date_string($this->connection->modified);
|
||||||
|
// TRANS: Used in application list. %1$s is a modified date, %2$s is access type ("read-write" or "read-only")
|
||||||
|
$txt = sprintf(_('Approved %1$s - "%2$s" access.'), $modifiedDate, $access);
|
||||||
|
|
||||||
|
// @todo FIXME: i18n trouble.
|
||||||
|
$this->out->raw(" - $txt");
|
||||||
|
if (!empty($app->description)) {
|
||||||
|
$this->out->element(
|
||||||
|
'p', array('class' => 'application_description'),
|
||||||
|
$app->description
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$this->out->element(
|
||||||
|
'p', array(
|
||||||
|
'class' => 'access_token'),
|
||||||
|
// TRANS: Access token in the application list.
|
||||||
|
// TRANS: %s are the first 7 characters of the access token.
|
||||||
|
sprintf(_('Access token starting with: %s'), substr($this->connection->token, 0, 7))
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->out->elementStart(
|
||||||
|
'form',
|
||||||
|
array(
|
||||||
|
'id' => 'form_revoke_app',
|
||||||
|
'class' => 'form_revoke_app',
|
||||||
|
'method' => 'POST',
|
||||||
|
'action' => common_local_url('oauthconnectionssettings')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->out->elementStart('fieldset');
|
||||||
|
$this->out->hidden('oauth_token', $this->connection->token);
|
||||||
|
$this->out->hidden('token', common_session_token());
|
||||||
|
// TRANS: Button label in application list to revoke access to user data.
|
||||||
|
$this->out->submit('revoke', _m('BUTTON','Revoke'));
|
||||||
|
$this->out->elementEnd('fieldset');
|
||||||
|
$this->out->elementEnd('form');
|
||||||
|
|
||||||
|
$this->out->elementEnd('li');
|
||||||
|
}
|
||||||
|
}
|
@ -72,7 +72,7 @@ class DBQueueManager extends QueueManager
|
|||||||
public function poll()
|
public function poll()
|
||||||
{
|
{
|
||||||
//$this->_log(LOG_DEBUG, 'Checking for notices...');
|
//$this->_log(LOG_DEBUG, 'Checking for notices...');
|
||||||
$qi = Queue_item::top($this->activeQueues());
|
$qi = Queue_item::top($this->activeQueues(), $this->getIgnoredTransports());
|
||||||
if (!$qi instanceof Queue_item) {
|
if (!$qi instanceof Queue_item) {
|
||||||
//$this->_log(LOG_DEBUG, 'No notices waiting; idling.');
|
//$this->_log(LOG_DEBUG, 'No notices waiting; idling.');
|
||||||
return false;
|
return false;
|
||||||
|
@ -129,7 +129,7 @@ $default =
|
|||||||
'biolimit' => null,
|
'biolimit' => null,
|
||||||
'changenick' => false,
|
'changenick' => false,
|
||||||
'backup' => true,
|
'backup' => true,
|
||||||
'restore' => true,
|
'restore' => false,
|
||||||
'delete' => false,
|
'delete' => false,
|
||||||
'move' => true),
|
'move' => true),
|
||||||
'image' =>
|
'image' =>
|
||||||
|
67
lib/deletenoticeform.php
Normal file
67
lib/deletenoticeform.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
|
class DeletenoticeForm extends Form
|
||||||
|
{
|
||||||
|
protected $notice = null;
|
||||||
|
|
||||||
|
function __construct(HTMLOutputter $out=null, array $formOpts=array())
|
||||||
|
{
|
||||||
|
if (!array_key_exists('notice', $formOpts) || !$formOpts['notice'] instanceof Notice) {
|
||||||
|
throw new ServerException('No notice provided to DeletenoticeForm');
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($out);
|
||||||
|
|
||||||
|
$this->notice = $formOpts['notice'];
|
||||||
|
}
|
||||||
|
|
||||||
|
function id()
|
||||||
|
{
|
||||||
|
return 'form_notice_delete-' . $this->notice->getID();
|
||||||
|
}
|
||||||
|
|
||||||
|
function formClass()
|
||||||
|
{
|
||||||
|
return 'form_settings';
|
||||||
|
}
|
||||||
|
|
||||||
|
function action()
|
||||||
|
{
|
||||||
|
return common_local_url('deletenotice', array('notice' => $this->notice->getID()));
|
||||||
|
}
|
||||||
|
|
||||||
|
function formLegend()
|
||||||
|
{
|
||||||
|
$this->out->element('legend', null, _('Delete notice'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function formData()
|
||||||
|
{
|
||||||
|
$this->out->element('p', null, _('Are you sure you want to delete this notice?'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action elements
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function formActions()
|
||||||
|
{
|
||||||
|
$this->out->submit('form_action-no',
|
||||||
|
// TRANS: Button label on the delete notice form.
|
||||||
|
_m('BUTTON','No'),
|
||||||
|
'submit form_action-primary',
|
||||||
|
'no',
|
||||||
|
// TRANS: Submit button title for 'No' when deleting a notice.
|
||||||
|
_('Do not delete this notice.'));
|
||||||
|
$this->out->submit('form_action-yes',
|
||||||
|
// TRANS: Button label on the delete notice form.
|
||||||
|
_m('BUTTON','Yes'),
|
||||||
|
'submit form_action-secondary',
|
||||||
|
'yes',
|
||||||
|
// TRANS: Submit button title for 'Yes' when deleting a notice.
|
||||||
|
_('Delete this notice.'));
|
||||||
|
}
|
||||||
|
}
|
@ -74,8 +74,13 @@ class DelUserQueueHandler extends QueueHandler
|
|||||||
$qm = QueueManager::get();
|
$qm = QueueManager::get();
|
||||||
$qm->enqueue($user, 'deluser');
|
$qm->enqueue($user, 'deluser');
|
||||||
} else {
|
} else {
|
||||||
// Out of notices? Let's finish deleting this guy!
|
// Out of notices? Let's finish deleting this profile!
|
||||||
$user->delete();
|
try {
|
||||||
|
$user->getProfile()->delete();
|
||||||
|
} catch (UserNoProfileException $e) {
|
||||||
|
// in case a profile didn't exist for some reason, just delete the User directly
|
||||||
|
$user->delete();
|
||||||
|
}
|
||||||
common_log(LOG_INFO, "User $user->id $user->nickname deleted.");
|
common_log(LOG_INFO, "User $user->id $user->nickname deleted.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ class FormAction extends ManagedAction
|
|||||||
protected function prepare(array $args=array()) {
|
protected function prepare(array $args=array()) {
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
|
||||||
$this->form = $this->form ?: $this->action;
|
$this->form = $this->form ?: ucfirst($this->action);
|
||||||
$this->args['form'] = $this->form;
|
$this->args['form'] = $this->form;
|
||||||
|
|
||||||
$this->type = !is_null($this->type) ? $this->type : $this->trimmed('type');
|
$this->type = !is_null($this->type) ? $this->type : $this->trimmed('type');
|
||||||
|
@ -23,7 +23,7 @@ define('GNUSOCIAL_ENGINE', 'GNU social');
|
|||||||
define('GNUSOCIAL_ENGINE_URL', 'https://www.gnu.org/software/social/');
|
define('GNUSOCIAL_ENGINE_URL', 'https://www.gnu.org/software/social/');
|
||||||
|
|
||||||
define('GNUSOCIAL_BASE_VERSION', '1.2.0');
|
define('GNUSOCIAL_BASE_VERSION', '1.2.0');
|
||||||
define('GNUSOCIAL_LIFECYCLE', 'alpha1'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
|
define('GNUSOCIAL_LIFECYCLE', 'alpha2'); // 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release'
|
||||||
|
|
||||||
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
|
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE);
|
||||||
|
|
||||||
@ -37,6 +37,7 @@ define('NOTICES_PER_PAGE', 20);
|
|||||||
define('PROFILES_PER_PAGE', 20);
|
define('PROFILES_PER_PAGE', 20);
|
||||||
define('MESSAGES_PER_PAGE', 20);
|
define('MESSAGES_PER_PAGE', 20);
|
||||||
define('GROUPS_PER_PAGE', 20);
|
define('GROUPS_PER_PAGE', 20);
|
||||||
|
define('APPS_PER_PAGE', 20);
|
||||||
|
|
||||||
define('GROUPS_PER_MINILIST', 8);
|
define('GROUPS_PER_MINILIST', 8);
|
||||||
define('PROFILES_PER_MINILIST', 8);
|
define('PROFILES_PER_MINILIST', 8);
|
||||||
@ -136,9 +137,18 @@ spl_autoload_register('GNUsocial_class_autoload');
|
|||||||
* and is available here: http://www.php-fig.org/psr/psr-0/
|
* and is available here: http://www.php-fig.org/psr/psr-0/
|
||||||
*/
|
*/
|
||||||
spl_autoload_register(function($class){
|
spl_autoload_register(function($class){
|
||||||
$file = INSTALLDIR.'/extlib/'.preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
|
$class_path = preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
|
||||||
|
$file = INSTALLDIR.'/extlib/'.$class_path;
|
||||||
if (file_exists($file)) {
|
if (file_exists($file)) {
|
||||||
require_once $file;
|
require_once $file;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try if the system has this external library
|
||||||
|
$file = '/usr/share/php/'.$class_path;
|
||||||
|
if (file_exists($file)) {
|
||||||
|
require_once $file;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -36,35 +36,6 @@ class GalleryAction extends ProfileAction
|
|||||||
parent::handle();
|
parent::handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doPreparation()
|
|
||||||
{
|
|
||||||
// showstream requires a nickname
|
|
||||||
$nickname_arg = $this->arg('nickname');
|
|
||||||
$nickname = common_canonical_nickname($nickname_arg);
|
|
||||||
|
|
||||||
// Permanent redirect on non-canonical nickname
|
|
||||||
|
|
||||||
if ($nickname_arg != $nickname) {
|
|
||||||
$args = array('nickname' => $nickname);
|
|
||||||
if ($this->arg('page') && $this->arg('page') != 1) {
|
|
||||||
$args['page'] = $this->arg['page'];
|
|
||||||
}
|
|
||||||
common_redirect(common_local_url($this->getActionName(), $args), 301);
|
|
||||||
}
|
|
||||||
$this->user = User::getKV('nickname', $nickname);
|
|
||||||
|
|
||||||
if (!$this->user) {
|
|
||||||
$group = Local_group::getKV('nickname', $nickname);
|
|
||||||
if ($group instanceof Local_group) {
|
|
||||||
common_redirect($group->getProfile()->getUrl());
|
|
||||||
}
|
|
||||||
// TRANS: Client error displayed when calling a profile action without specifying a user.
|
|
||||||
$this->clientError(_('No such user.'), 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->target = $this->user->getProfile();
|
|
||||||
}
|
|
||||||
|
|
||||||
function showContent()
|
function showContent()
|
||||||
{
|
{
|
||||||
$this->showTagsDropdown();
|
$this->showTagsDropdown();
|
||||||
|
@ -189,6 +189,8 @@ class ImageFile
|
|||||||
|
|
||||||
case UPLOAD_ERR_NO_FILE:
|
case UPLOAD_ERR_NO_FILE:
|
||||||
// No file; probably just a non-AJAX submission.
|
// No file; probably just a non-AJAX submission.
|
||||||
|
throw new ClientException(_('No file uploaded.'));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " . $_FILES[$param]['error']);
|
common_log(LOG_ERR, __METHOD__ . ": Unknown upload error " . $_FILES[$param]['error']);
|
||||||
// TRANS: Exception thrown when uploading an image fails for an unknown reason.
|
// TRANS: Exception thrown when uploading an image fails for an unknown reason.
|
||||||
|
@ -126,17 +126,6 @@ abstract class ImPlugin extends Plugin
|
|||||||
*/
|
*/
|
||||||
abstract function daemonScreenname();
|
abstract function daemonScreenname();
|
||||||
|
|
||||||
/**
|
|
||||||
* get the microid uri of a given screenname
|
|
||||||
*
|
|
||||||
* @param string $screenname screenname
|
|
||||||
*
|
|
||||||
* @return string microid uri
|
|
||||||
*/
|
|
||||||
function microiduri($screenname)
|
|
||||||
{
|
|
||||||
return $this->transport . ':' . $screenname;
|
|
||||||
}
|
|
||||||
//========================UTILITY FUNCTIONS USEFUL TO IMPLEMENTATIONS - MISC ========================\
|
//========================UTILITY FUNCTIONS USEFUL TO IMPLEMENTATIONS - MISC ========================\
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -254,11 +243,11 @@ abstract class ImPlugin extends Plugin
|
|||||||
*
|
*
|
||||||
* @param string $screenname screenname sending to
|
* @param string $screenname screenname sending to
|
||||||
* @param string $code the confirmation code
|
* @param string $code the confirmation code
|
||||||
* @param User $user user sending to
|
* @param Profile $target For whom the code is valid for
|
||||||
*
|
*
|
||||||
* @return boolean success value
|
* @return boolean success value
|
||||||
*/
|
*/
|
||||||
function sendConfirmationCode($screenname, $code, $user)
|
function sendConfirmationCode($screenname, $code, Profile $target)
|
||||||
{
|
{
|
||||||
// TRANS: Body text for confirmation code e-mail.
|
// TRANS: Body text for confirmation code e-mail.
|
||||||
// TRANS: %1$s is a user nickname, %2$s is the StatusNet sitename,
|
// TRANS: %1$s is a user nickname, %2$s is the StatusNet sitename,
|
||||||
@ -269,7 +258,7 @@ abstract class ImPlugin extends Plugin
|
|||||||
' . (If you cannot click it, copy-and-paste it into the ' .
|
' . (If you cannot click it, copy-and-paste it into the ' .
|
||||||
'address bar of your browser). If that user is not you, ' .
|
'address bar of your browser). If that user is not you, ' .
|
||||||
'or if you did not request this confirmation, just ignore this message.'),
|
'or if you did not request this confirmation, just ignore this message.'),
|
||||||
$user->nickname, common_config('site', 'name'), $this->getDisplayName(), common_local_url('confirmaddress', null, array('code' => $code)));
|
$target->getNickname(), common_config('site', 'name'), $this->getDisplayName(), common_local_url('confirmaddress', null, array('code' => $code)));
|
||||||
|
|
||||||
return $this->sendMessage($screenname, $body);
|
return $this->sendMessage($screenname, $body);
|
||||||
}
|
}
|
||||||
@ -563,35 +552,20 @@ abstract class ImPlugin extends Plugin
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onEndShowHeadElements($action)
|
function onEndShowHeadElements(Action $action)
|
||||||
{
|
{
|
||||||
$aname = $action->trimmed('action');
|
if ($action instanceof ShownoticeAction) {
|
||||||
|
|
||||||
if ($aname == 'shownotice') {
|
|
||||||
|
|
||||||
$user_im_prefs = new User_im_prefs();
|
$user_im_prefs = new User_im_prefs();
|
||||||
$user_im_prefs->user_id = $action->profile->id;
|
$user_im_prefs->user_id = $action->notice->getProfile()->getID();
|
||||||
$user_im_prefs->transport = $this->transport;
|
$user_im_prefs->transport = $this->transport;
|
||||||
|
|
||||||
if ($user_im_prefs->find() && $user_im_prefs->fetch() && $user_im_prefs->microid && $action->notice->uri) {
|
} elseif ($action instanceof ShowstreamAction) {
|
||||||
$id = new Microid($this->microiduri($user_im_prefs->screenname),
|
|
||||||
$action->notice->uri);
|
|
||||||
$action->element('meta', array('name' => 'microid',
|
|
||||||
'content' => $id->toString()));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if ($aname == 'showstream') {
|
|
||||||
|
|
||||||
$user_im_prefs = new User_im_prefs();
|
$user_im_prefs = new User_im_prefs();
|
||||||
$user_im_prefs->user_id = $action->user->id;
|
$user_im_prefs->user_id = $action->getTarget()->getID();
|
||||||
$user_im_prefs->transport = $this->transport;
|
$user_im_prefs->transport = $this->transport;
|
||||||
|
|
||||||
if ($user_im_prefs->find() && $user_im_prefs->fetch() && $user_im_prefs->microid && $action->profile->profileurl) {
|
|
||||||
$id = new Microid($this->microiduri($user_im_prefs->screenname),
|
|
||||||
$action->selfUrl());
|
|
||||||
$action->element('meta', array('name' => 'microid',
|
|
||||||
'content' => $id->toString()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,11 +594,11 @@ abstract class ImPlugin extends Plugin
|
|||||||
'daemonScreenname' => $this->daemonScreenname());
|
'daemonScreenname' => $this->daemonScreenname());
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSendImConfirmationCode($transport, $screenname, $code, $user)
|
function onSendImConfirmationCode($transport, $screenname, $code, Profile $target)
|
||||||
{
|
{
|
||||||
if($transport == $this->transport)
|
if($transport == $this->transport)
|
||||||
{
|
{
|
||||||
$this->sendConfirmationCode($screenname, $code, $user);
|
$this->sendConfirmationCode($screenname, $code, $target);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -622,7 +622,7 @@ abstract class Installer
|
|||||||
|
|
||||||
$this->updateStatus("GNU social has been installed at $link");
|
$this->updateStatus("GNU social has been installed at $link");
|
||||||
$this->updateStatus(
|
$this->updateStatus(
|
||||||
'<strong>DONE!</strong> You can visit your <a href="'.htmlspecialchars($link).'">new GNU social site</a> (log in as "'.htmlspecialchars($this->adminNick).'"). If this is your first GNU social install, make your experience the best possible by visiting our resource site to join the <a href="https://gnu.io/social/resources/">mailing list or IRC.</a>. <a href="'.htmlspecialchars($link).'/doc/faq/">FAQ is found here</a>.'
|
'<strong>DONE!</strong> You can visit your <a href="'.htmlspecialchars($link).'">new GNU social site</a> (log in as "'.htmlspecialchars($this->adminNick).'"). If this is your first GNU social install, make your experience the best possible by visiting our resource site to join the <a href="https://gnu.io/social/resources/">mailing list or IRC</a>. <a href="'.htmlspecialchars($link).'/doc/faq">FAQ is found here</a>.'
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -47,11 +47,13 @@ require_once 'Mail.php';
|
|||||||
function mail_backend()
|
function mail_backend()
|
||||||
{
|
{
|
||||||
static $backend = null;
|
static $backend = null;
|
||||||
|
global $_PEAR;
|
||||||
|
|
||||||
if (!$backend) {
|
if (!$backend) {
|
||||||
$backend = Mail::factory(common_config('mail', 'backend'),
|
$mail = new Mail();
|
||||||
|
$backend = $mail->factory(common_config('mail', 'backend'),
|
||||||
common_config('mail', 'params') ?: array());
|
common_config('mail', 'params') ?: array());
|
||||||
if (PEAR::isError($backend)) {
|
if ($_PEAR->isError($backend)) {
|
||||||
common_server_error($backend->getMessage(), 500);
|
common_server_error($backend->getMessage(), 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* StatusNet, the distributed open-source microblogging tool
|
|
||||||
*
|
|
||||||
* Microid class
|
|
||||||
*
|
|
||||||
* 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 ID
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
|
||||||
* @copyright 2008 StatusNet, Inc.
|
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
|
||||||
* @link http://status.net/
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class for microids
|
|
||||||
*
|
|
||||||
* @category ID
|
|
||||||
* @package StatusNet
|
|
||||||
* @author Evan Prodromou <evan@status.net>
|
|
||||||
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
|
||||||
* @link http://status.net/
|
|
||||||
* @see http://microid.org/
|
|
||||||
*/
|
|
||||||
|
|
||||||
class Microid
|
|
||||||
{
|
|
||||||
/** Agent part of the ID. */
|
|
||||||
|
|
||||||
var $agent = null;
|
|
||||||
|
|
||||||
/** Resource part of the ID. */
|
|
||||||
|
|
||||||
var $resource = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param string $agent Agent of the ID
|
|
||||||
* @param string $resource Resource part
|
|
||||||
*/
|
|
||||||
|
|
||||||
function __construct($agent, $resource)
|
|
||||||
{
|
|
||||||
$this->agent = $agent;
|
|
||||||
$this->resource = $resource;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate a MicroID string
|
|
||||||
*
|
|
||||||
* @return string MicroID for agent and resource
|
|
||||||
*/
|
|
||||||
|
|
||||||
function toString()
|
|
||||||
{
|
|
||||||
$agent_proto = $this->_getProto($this->agent);
|
|
||||||
$resource_proto = $this->_getProto($this->resource);
|
|
||||||
|
|
||||||
return $agent_proto.'+'.$resource_proto.':sha1:'.
|
|
||||||
sha1(sha1($this->agent).sha1($this->resource));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility for getting the protocol part of a URI
|
|
||||||
*
|
|
||||||
* @param string $uri URI to parse
|
|
||||||
*
|
|
||||||
* @return string scheme part of the URI
|
|
||||||
*/
|
|
||||||
|
|
||||||
function _getProto($uri)
|
|
||||||
{
|
|
||||||
$colon = strpos($uri, ':');
|
|
||||||
return substr($uri, 0, $colon);
|
|
||||||
}
|
|
||||||
}
|
|
@ -368,18 +368,19 @@ class NoticeListItem extends Widget
|
|||||||
*/
|
*/
|
||||||
function showNoticeLocation()
|
function showNoticeLocation()
|
||||||
{
|
{
|
||||||
$id = $this->notice->id;
|
return;
|
||||||
|
try {
|
||||||
$location = $this->notice->getLocation();
|
$location = Notice_location::locFromStored($this->notice);
|
||||||
|
} catch (NoResultException $e) {
|
||||||
if (empty($location)) {
|
return;
|
||||||
|
} catch (ServerException $e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = $location->getName();
|
$name = $location->getName();
|
||||||
|
|
||||||
$lat = $this->notice->lat;
|
$lat = $location->lat;
|
||||||
$lon = $this->notice->lon;
|
$lon = $location->lon;
|
||||||
$latlon = (!empty($lat) && !empty($lon)) ? $lat.';'.$lon : '';
|
$latlon = (!empty($lat) && !empty($lon)) ? $lat.';'.$lon : '';
|
||||||
|
|
||||||
if (empty($name)) {
|
if (empty($name)) {
|
||||||
|
@ -4,6 +4,7 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
|||||||
|
|
||||||
abstract class NoticestreamAction extends ProfileAction
|
abstract class NoticestreamAction extends ProfileAction
|
||||||
{
|
{
|
||||||
|
protected $notice = null; // holds the stream result
|
||||||
|
|
||||||
protected function prepare(array $args=array()) {
|
protected function prepare(array $args=array()) {
|
||||||
parent::prepare($args);
|
parent::prepare($args);
|
||||||
|
@ -27,9 +27,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Personal tag cloud section
|
* Personal tag cloud section
|
||||||
@ -42,12 +40,12 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
*/
|
*/
|
||||||
class PersonalTagCloudSection extends TagCloudSection
|
class PersonalTagCloudSection extends TagCloudSection
|
||||||
{
|
{
|
||||||
var $user = null;
|
protected $profile = null;
|
||||||
|
|
||||||
function __construct($out=null, $user=null)
|
function __construct(Profile $profile, HTMLOutputter $out=null)
|
||||||
{
|
{
|
||||||
parent::__construct($out);
|
parent::__construct($out);
|
||||||
$this->user = $user;
|
$this->profile = $profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
function title()
|
function title()
|
||||||
@ -80,7 +78,7 @@ class PersonalTagCloudSection extends TagCloudSection
|
|||||||
|
|
||||||
$tag = Memcached_DataObject::cachedQuery('Notice_tag',
|
$tag = Memcached_DataObject::cachedQuery('Notice_tag',
|
||||||
sprintf($qry,
|
sprintf($qry,
|
||||||
$this->user->id),
|
$this->profile->getID()),
|
||||||
3600);
|
3600);
|
||||||
return $tag;
|
return $tag;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,36 @@ abstract class ProfileAction extends ManagedAction
|
|||||||
|
|
||||||
protected $target = null; // Profile that we're showing
|
protected $target = null; // Profile that we're showing
|
||||||
|
|
||||||
|
protected function doPreparation()
|
||||||
|
{
|
||||||
|
// showstream requires a nickname
|
||||||
|
$nickname_arg = $this->trimmed('nickname');
|
||||||
|
$nickname = common_canonical_nickname($nickname_arg);
|
||||||
|
|
||||||
|
// Permanent redirect on non-canonical nickname
|
||||||
|
if ($nickname_arg != $nickname) {
|
||||||
|
$args = array('nickname' => $nickname);
|
||||||
|
if ($this->arg('page') && $this->arg('page') != 1) {
|
||||||
|
$args['page'] = $this->arg['page'];
|
||||||
|
}
|
||||||
|
common_redirect(common_local_url($this->getActionName(), $args), 301);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$user = User::getByNickname($nickname);
|
||||||
|
} catch (NoSuchUserException $e) {
|
||||||
|
$group = Local_group::getKV('nickname', $nickname);
|
||||||
|
if ($group instanceof Local_group) {
|
||||||
|
common_redirect($group->getProfile()->getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
// No user nor group found, throw the NoSuchUserException again
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->target = $user->getProfile();
|
||||||
|
}
|
||||||
|
|
||||||
protected function prepare(array $args=array())
|
protected function prepare(array $args=array())
|
||||||
{
|
{
|
||||||
// this will call ->doPreparation() which child classes use to set $this->target
|
// this will call ->doPreparation() which child classes use to set $this->target
|
||||||
@ -58,9 +88,6 @@ abstract class ProfileAction extends ManagedAction
|
|||||||
throw new ClientException(_('This profile has been silenced by site moderators'), 403);
|
throw new ClientException(_('This profile has been silenced by site moderators'), 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
// backwards compatibility until all actions are fixed to use $this->target
|
|
||||||
$this->profile = $this->target;
|
|
||||||
|
|
||||||
$this->tag = $this->trimmed('tag');
|
$this->tag = $this->trimmed('tag');
|
||||||
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
$this->page = ($this->arg('page')) ? ($this->arg('page')+0) : 1;
|
||||||
common_set_returnto($this->selfUrl());
|
common_set_returnto($this->selfUrl());
|
||||||
@ -68,13 +95,11 @@ abstract class ProfileAction extends ManagedAction
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function profileActionPreparation()
|
|
||||||
{
|
|
||||||
// Nothing to do by default.
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTarget()
|
public function getTarget()
|
||||||
{
|
{
|
||||||
|
if (!$this->target instanceof Profile) {
|
||||||
|
throw new ServerException('No target profile in ProfileAction class');
|
||||||
|
}
|
||||||
return $this->target;
|
return $this->target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,18 +32,26 @@ if (!defined('GNUSOCIAL')) { exit(1); }
|
|||||||
class ProfileListItem extends Widget
|
class ProfileListItem extends Widget
|
||||||
{
|
{
|
||||||
/** Current profile. */
|
/** Current profile. */
|
||||||
|
protected $target = null;
|
||||||
var $profile = null;
|
var $profile = null;
|
||||||
/** Action object using us. */
|
/** Action object using us. */
|
||||||
var $action = null;
|
var $action = null;
|
||||||
|
|
||||||
function __construct($profile, $action)
|
// FIXME: Directory plugin sends a User_group here, but should send a Profile and handle User_group specifics itself
|
||||||
|
function __construct($target, HTMLOutputter $action)
|
||||||
{
|
{
|
||||||
parent::__construct($action);
|
parent::__construct($action);
|
||||||
|
|
||||||
$this->profile = $profile;
|
$this->target = $target;
|
||||||
|
$this->profile = $this->target;
|
||||||
$this->action = $action;
|
$this->action = $action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTarget()
|
||||||
|
{
|
||||||
|
return $this->target;
|
||||||
|
}
|
||||||
|
|
||||||
function show()
|
function show()
|
||||||
{
|
{
|
||||||
if (Event::handle('StartProfileListItem', array($this))) {
|
if (Event::handle('StartProfileListItem', array($this))) {
|
||||||
|
@ -43,6 +43,7 @@ abstract class QueueManager extends IoManager
|
|||||||
protected $handlers = array();
|
protected $handlers = array();
|
||||||
protected $groups = array();
|
protected $groups = array();
|
||||||
protected $activeGroups = array();
|
protected $activeGroups = array();
|
||||||
|
protected $ignoredTransports = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory function to pull the appropriate QueueManager object
|
* Factory function to pull the appropriate QueueManager object
|
||||||
@ -255,6 +256,17 @@ abstract class QueueManager extends IoManager
|
|||||||
return array_keys($queues);
|
return array_keys($queues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getIgnoredTransports()
|
||||||
|
{
|
||||||
|
return array_keys($this->ignoredTransports);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ignoreTransport($transport)
|
||||||
|
{
|
||||||
|
// key is used for uniqueness, value doesn't mean anything
|
||||||
|
$this->ignoredTransports[$transport] = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the list of queue handlers for the current site.
|
* Initialize the list of queue handlers for the current site.
|
||||||
*
|
*
|
||||||
|
@ -108,6 +108,11 @@ class Router
|
|||||||
|
|
||||||
if (Event::handle('StartInitializeRouter', array(&$m))) {
|
if (Event::handle('StartInitializeRouter', array(&$m))) {
|
||||||
|
|
||||||
|
// top of the menu hierarchy, sometimes "Home"
|
||||||
|
$m->connect('', array('action' => 'top'));
|
||||||
|
|
||||||
|
// public endpoints
|
||||||
|
|
||||||
$m->connect('robots.txt', array('action' => 'robotstxt'));
|
$m->connect('robots.txt', array('action' => 'robotstxt'));
|
||||||
|
|
||||||
$m->connect('opensearch/people', array('action' => 'opensearch',
|
$m->connect('opensearch/people', array('action' => 'opensearch',
|
||||||
@ -156,13 +161,13 @@ class Router
|
|||||||
'deleteaccount',
|
'deleteaccount',
|
||||||
'restoreaccount',
|
'restoreaccount',
|
||||||
'top',
|
'top',
|
||||||
|
'public',
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($main as $a) {
|
foreach ($main as $a) {
|
||||||
$m->connect('main/'.$a, array('action' => $a));
|
$m->connect('main/'.$a, array('action' => $a));
|
||||||
}
|
}
|
||||||
|
|
||||||
$m->connect('main/public', array('action' => 'public'));
|
|
||||||
$m->connect('main/all', array('action' => 'networkpublic'));
|
$m->connect('main/all', array('action' => 'networkpublic'));
|
||||||
|
|
||||||
$m->connect('main/tagprofile/:id', array('action' => 'tagprofile'),
|
$m->connect('main/tagprofile/:id', array('action' => 'tagprofile'),
|
||||||
@ -239,12 +244,10 @@ class Router
|
|||||||
array('action' => 'shownotice'),
|
array('action' => 'shownotice'),
|
||||||
array('notice' => '[0-9]+'));
|
array('notice' => '[0-9]+'));
|
||||||
|
|
||||||
$m->connect('notice/delete/:notice',
|
$m->connect('notice/:notice/delete',
|
||||||
array('action' => 'deletenotice'),
|
array('action' => 'deletenotice'),
|
||||||
array('notice' => '[0-9]+'));
|
array('notice' => '[0-9]+'));
|
||||||
|
|
||||||
$m->connect('notice/delete', array('action' => 'deletenotice'));
|
|
||||||
|
|
||||||
// conversation
|
// conversation
|
||||||
|
|
||||||
$m->connect('conversation/:id',
|
$m->connect('conversation/:id',
|
||||||
@ -875,9 +878,6 @@ class Router
|
|||||||
array('action' => 'rsd',
|
array('action' => 'rsd',
|
||||||
'nickname' => $nickname));
|
'nickname' => $nickname));
|
||||||
|
|
||||||
$m->connect('',
|
|
||||||
array('action' => 'startpage'));
|
|
||||||
|
|
||||||
// peopletags
|
// peopletags
|
||||||
|
|
||||||
$m->connect('peopletags',
|
$m->connect('peopletags',
|
||||||
@ -930,9 +930,6 @@ class Router
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$m->connect('', array('action' => 'startpage'));
|
|
||||||
$m->connect('main/public', array('action' => 'public'));
|
|
||||||
$m->connect('main/all', array('action' => 'networkpublic'));
|
|
||||||
$m->connect('rss', array('action' => 'publicrss'));
|
$m->connect('rss', array('action' => 'publicrss'));
|
||||||
$m->connect('featuredrss', array('action' => 'featuredrss'));
|
$m->connect('featuredrss', array('action' => 'featuredrss'));
|
||||||
$m->connect('featured/', array('action' => 'featured'));
|
$m->connect('featured/', array('action' => 'featured'));
|
||||||
@ -950,6 +947,13 @@ class Router
|
|||||||
array('action' => 'subqueue'),
|
array('action' => 'subqueue'),
|
||||||
array('nickname' => Nickname::DISPLAY_FMT));
|
array('nickname' => Nickname::DISPLAY_FMT));
|
||||||
|
|
||||||
|
// some targeted RSS 1.0 actions (extends TargetedRss10Action)
|
||||||
|
foreach (array('all', 'replies') as $a) {
|
||||||
|
$m->connect(':nickname/'.$a.'/rss',
|
||||||
|
array('action' => $a.'rss'),
|
||||||
|
array('nickname' => Nickname::DISPLAY_FMT));
|
||||||
|
}
|
||||||
|
|
||||||
// people tags
|
// people tags
|
||||||
|
|
||||||
$m->connect(':nickname/peopletags',
|
$m->connect(':nickname/peopletags',
|
||||||
@ -1017,12 +1021,6 @@ class Router
|
|||||||
array('nickname' => Nickname::DISPLAY_FMT));
|
array('nickname' => Nickname::DISPLAY_FMT));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (array('all', 'replies') as $a) {
|
|
||||||
$m->connect(':nickname/'.$a.'/rss',
|
|
||||||
array('action' => $a.'rss'),
|
|
||||||
array('nickname' => Nickname::DISPLAY_FMT));
|
|
||||||
}
|
|
||||||
|
|
||||||
$m->connect(':nickname/avatar',
|
$m->connect(':nickname/avatar',
|
||||||
array('action' => 'avatarbynickname'),
|
array('action' => 'avatarbynickname'),
|
||||||
array('nickname' => Nickname::DISPLAY_FMT));
|
array('nickname' => Nickname::DISPLAY_FMT));
|
||||||
|
@ -28,11 +28,11 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
define('DEFAULT_RSS_LIMIT', 48);
|
define('DEFAULT_RSS_LIMIT', 48);
|
||||||
|
|
||||||
class Rss10Action extends Action
|
class Rss10Action extends ManagedAction
|
||||||
{
|
{
|
||||||
// This will contain the details of each feed item's author and be used to generate SIOC data.
|
// This will contain the details of each feed item's author and be used to generate SIOC data.
|
||||||
|
|
||||||
@ -41,47 +41,16 @@ class Rss10Action extends Action
|
|||||||
var $notices = null;
|
var $notices = null;
|
||||||
var $tags_already_output = array();
|
var $tags_already_output = array();
|
||||||
|
|
||||||
/**
|
public function isReadOnly($args)
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* Just wraps the Action constructor.
|
|
||||||
*
|
|
||||||
* @param string $output URI to output to, default = stdout
|
|
||||||
* @param boolean $indent Whether to indent output, default true
|
|
||||||
*
|
|
||||||
* @see Action::__construct
|
|
||||||
*/
|
|
||||||
|
|
||||||
function __construct($output='php://output', $indent=null)
|
|
||||||
{
|
|
||||||
parent::__construct($output, $indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Do we need to write to the database?
|
|
||||||
*
|
|
||||||
* @return boolean true
|
|
||||||
*/
|
|
||||||
|
|
||||||
function isReadonly()
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doPreparation()
|
||||||
* Read arguments and initialize members
|
|
||||||
*
|
|
||||||
* @param array $args Arguments from $_REQUEST
|
|
||||||
* @return boolean success
|
|
||||||
*/
|
|
||||||
|
|
||||||
function prepare($args)
|
|
||||||
{
|
{
|
||||||
parent::prepare($args);
|
$this->limit = $this->int('limit');
|
||||||
|
|
||||||
$this->limit = (int) $this->trimmed('limit');
|
if (empty($this->limit)) {
|
||||||
|
|
||||||
if ($this->limit == 0) {
|
|
||||||
$this->limit = DEFAULT_RSS_LIMIT;
|
$this->limit = DEFAULT_RSS_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +62,7 @@ class Rss10Action extends Action
|
|||||||
|
|
||||||
// If the user hits cancel -- bam!
|
// If the user hits cancel -- bam!
|
||||||
$this->show_basic_auth_error();
|
$this->show_basic_auth_error();
|
||||||
return;
|
// the above calls 'exit'
|
||||||
} else {
|
} else {
|
||||||
$nickname = $_SERVER['PHP_AUTH_USER'];
|
$nickname = $_SERVER['PHP_AUTH_USER'];
|
||||||
$password = $_SERVER['PHP_AUTH_PW'];
|
$password = $_SERVER['PHP_AUTH_PW'];
|
||||||
@ -104,27 +73,19 @@ class Rss10Action extends Action
|
|||||||
|
|
||||||
common_log(LOG_WARNING, "Failed RSS auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
|
common_log(LOG_WARNING, "Failed RSS auth attempt, nickname = $nickname, proxy = $proxy, ip = $ip.");
|
||||||
$this->show_basic_auth_error();
|
$this->show_basic_auth_error();
|
||||||
return;
|
// the above calls 'exit'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
$this->doStreamPreparation();
|
||||||
|
|
||||||
|
$this->notices = $this->getNotices($this->limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function doStreamPreparation()
|
||||||
* Handle a request
|
|
||||||
*
|
|
||||||
* @param array $args Arguments from $_REQUEST
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function handle($args)
|
|
||||||
{
|
{
|
||||||
// Parent handling, including cache check
|
// for example if we need to set $this->target or something
|
||||||
parent::handle($args);
|
|
||||||
$this->showRss();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_basic_auth_error()
|
function show_basic_auth_error()
|
||||||
@ -137,6 +98,7 @@ class Rss10Action extends Action
|
|||||||
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
$this->element('request', null, $_SERVER['REQUEST_URI']);
|
||||||
$this->elementEnd('hash');
|
$this->elementEnd('hash');
|
||||||
$this->endXML();
|
$this->endXML();
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,7 +107,7 @@ class Rss10Action extends Action
|
|||||||
* @return array an array of Notice objects sorted in reverse chron
|
* @return array an array of Notice objects sorted in reverse chron
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getNotices()
|
protected function getNotices()
|
||||||
{
|
{
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
@ -170,7 +132,7 @@ class Rss10Action extends Action
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function showRss()
|
function showPage()
|
||||||
{
|
{
|
||||||
$this->initRss();
|
$this->initRss();
|
||||||
$this->showChannel();
|
$this->showChannel();
|
||||||
@ -254,15 +216,19 @@ class Rss10Action extends Action
|
|||||||
$this->element('dc:creator', null, ($profile->fullname) ? $profile->fullname : $profile->nickname);
|
$this->element('dc:creator', null, ($profile->fullname) ? $profile->fullname : $profile->nickname);
|
||||||
$this->element('foaf:maker', array('rdf:resource' => $creator_uri));
|
$this->element('foaf:maker', array('rdf:resource' => $creator_uri));
|
||||||
$this->element('sioc:has_creator', array('rdf:resource' => $creator_uri.'#acct'));
|
$this->element('sioc:has_creator', array('rdf:resource' => $creator_uri.'#acct'));
|
||||||
$location = $notice->getLocation();
|
try {
|
||||||
if ($location && isset($location->lat) && isset($location->lon)) {
|
$location = Notice_location::locFromStored($notice);
|
||||||
$location_uri = $location->getRdfURL();
|
if (isset($location->lat) && isset($location->lon)) {
|
||||||
$attrs = array('geo:lat' => $location->lat,
|
$location_uri = $location->getRdfURL();
|
||||||
'geo:long' => $location->lon);
|
$attrs = array('geo:lat' => $location->lat,
|
||||||
if (strlen($location_uri)) {
|
'geo:long' => $location->lon);
|
||||||
$attrs['rdf:resource'] = $location_uri;
|
if (strlen($location_uri)) {
|
||||||
|
$attrs['rdf:resource'] = $location_uri;
|
||||||
|
}
|
||||||
|
$this->element('statusnet:origin', $attrs);
|
||||||
}
|
}
|
||||||
$this->element('statusnet:origin', $attrs);
|
} catch (ServerException $e) {
|
||||||
|
// No result, so no location data
|
||||||
}
|
}
|
||||||
$this->element('statusnet:postIcon', array('rdf:resource' => $profile->avatarUrl()));
|
$this->element('statusnet:postIcon', array('rdf:resource' => $profile->avatarUrl()));
|
||||||
$this->element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
|
$this->element('cc:licence', array('rdf:resource' => common_config('license', 'url')));
|
@ -27,9 +27,7 @@
|
|||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for settings group of actions
|
* Base class for settings group of actions
|
||||||
@ -43,113 +41,8 @@ if (!defined('STATUSNET') && !defined('LACONICA')) {
|
|||||||
* @see Widget
|
* @see Widget
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class SettingsAction extends Action
|
class SettingsAction extends FormAction
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* A message for the user.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var $msg = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the message is a good one or a bad one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var $success = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle input and output a page
|
|
||||||
*
|
|
||||||
* @param array $args $_REQUEST arguments
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function handle($args)
|
|
||||||
{
|
|
||||||
parent::handle($args);
|
|
||||||
if (!common_logged_in()) {
|
|
||||||
// TRANS: Error message displayed when trying to perform an action that requires a logged in user.
|
|
||||||
$this->clientError(_('Not logged in.'));
|
|
||||||
} else if (!common_is_real_login()) {
|
|
||||||
// Cookie theft means that automatic logins can't
|
|
||||||
// change important settings or see private info, and
|
|
||||||
// _all_ our settings are important
|
|
||||||
common_set_returnto($this->selfUrl());
|
|
||||||
$user = common_current_user();
|
|
||||||
if (Event::handle('RedirectToLogin', array($this, $user))) {
|
|
||||||
common_redirect(common_local_url('login'), 303);
|
|
||||||
}
|
|
||||||
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|
||||||
$this->handlePost();
|
|
||||||
} else {
|
|
||||||
$this->showForm();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a POST request
|
|
||||||
*
|
|
||||||
* @return boolean success flag
|
|
||||||
*/
|
|
||||||
|
|
||||||
function handlePost()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* show the settings form
|
|
||||||
*
|
|
||||||
* @param string $msg an extra message for the user
|
|
||||||
* @param string $success good message or bad message?
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function showForm($msg=null, $success=false)
|
|
||||||
{
|
|
||||||
$this->msg = $msg;
|
|
||||||
$this->success = $success;
|
|
||||||
|
|
||||||
$this->showPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* show human-readable instructions for the page
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
|
|
||||||
function showPageNotice()
|
|
||||||
{
|
|
||||||
if ($this->msg) {
|
|
||||||
$this->element('div', ($this->success) ? 'success' : 'error',
|
|
||||||
$this->msg);
|
|
||||||
} else {
|
|
||||||
$inst = $this->getInstructions();
|
|
||||||
$output = common_markup_to_html($inst);
|
|
||||||
|
|
||||||
$this->elementStart('div', 'instructions');
|
|
||||||
$this->raw($output);
|
|
||||||
$this->elementEnd('div');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* instructions recipe for sub-classes
|
|
||||||
*
|
|
||||||
* Subclasses should override this to return readable instructions. They'll
|
|
||||||
* be processed by common_markup_to_html().
|
|
||||||
*
|
|
||||||
* @return string instructions text
|
|
||||||
*/
|
|
||||||
|
|
||||||
function getInstructions()
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the local navigation menu
|
* Show the local navigation menu
|
||||||
*
|
*
|
||||||
|
@ -110,7 +110,6 @@ class PublicSite extends SiteProfileSettings
|
|||||||
'plugins' => array(
|
'plugins' => array(
|
||||||
'core' => self::corePlugins(),
|
'core' => self::corePlugins(),
|
||||||
'default' => array_merge(self::defaultPlugins(), array(
|
'default' => array_merge(self::defaultPlugins(), array(
|
||||||
'ExtendedProfile' => array(),
|
|
||||||
'RegisterThrottle' => array(),
|
'RegisterThrottle' => array(),
|
||||||
))
|
))
|
||||||
),
|
),
|
||||||
|
@ -115,11 +115,10 @@ class TagCloudSection extends Section
|
|||||||
|
|
||||||
function tagUrl($tag)
|
function tagUrl($tag)
|
||||||
{
|
{
|
||||||
if ('showstream' === $this->out->trimmed('action')) {
|
if ($this->out instanceof ShowstreamAction) {
|
||||||
return common_local_url('showstream', array('nickname' => $this->out->profile->nickname, 'tag' => $tag));
|
return common_local_url('showstream', array('nickname' => $this->out->getTarget()->getNickname(), 'tag' => $tag));
|
||||||
} else {
|
|
||||||
return common_local_url('tag', array('tag' => $tag));
|
|
||||||
}
|
}
|
||||||
|
return common_local_url('tag', array('tag' => $tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
function divId()
|
function divId()
|
||||||
|
51
lib/targetedrss10action.php
Normal file
51
lib/targetedrss10action.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* StatusNet, the distributed open-source microblogging tool
|
||||||
|
*
|
||||||
|
* Base class for RSS 1.0 feed actions
|
||||||
|
*
|
||||||
|
* 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 Mail
|
||||||
|
* @package StatusNet
|
||||||
|
* @author Evan Prodromou <evan@status.net>
|
||||||
|
* @author Earle Martin <earle@downlode.org>
|
||||||
|
* @copyright 2008-9 StatusNet, Inc.
|
||||||
|
* @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
|
||||||
|
* @link http://status.net/
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
|
|
||||||
|
class TargetedRss10Action extends Rss10Action
|
||||||
|
{
|
||||||
|
protected $target = null;
|
||||||
|
|
||||||
|
protected function doStreamPreparation()
|
||||||
|
{
|
||||||
|
$this->target = User::getByNickname($this->trimmed('nickname'))->getProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTarget()
|
||||||
|
{
|
||||||
|
return $this->target;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getImage()
|
||||||
|
{
|
||||||
|
return $this->target->avatarUrl(AVATAR_PROFILE_SIZE);
|
||||||
|
}
|
||||||
|
}
|
@ -195,7 +195,7 @@ class ThreadedNoticeListItem extends NoticeListItem
|
|||||||
function showEnd()
|
function showEnd()
|
||||||
{
|
{
|
||||||
$max = $this->initialItems();
|
$max = $this->initialItems();
|
||||||
if (!$this->repeat) {
|
if (!$this->repeat instanceof Notice) {
|
||||||
$stream = new ConversationNoticeStream($this->notice->conversation, $this->userProfile);
|
$stream = new ConversationNoticeStream($this->notice->conversation, $this->userProfile);
|
||||||
$notice = $stream->getNotices(0, $max + 2);
|
$notice = $stream->getNotices(0, $max + 2);
|
||||||
$notices = array();
|
$notices = array();
|
||||||
|
42
lib/util.php
42
lib/util.php
@ -210,7 +210,7 @@ function common_language()
|
|||||||
/**
|
/**
|
||||||
* Salted, hashed passwords are stored in the DB.
|
* Salted, hashed passwords are stored in the DB.
|
||||||
*/
|
*/
|
||||||
function common_munge_password($password, $id, Profile $profile=null)
|
function common_munge_password($password, Profile $profile=null)
|
||||||
{
|
{
|
||||||
$hashed = null;
|
$hashed = null;
|
||||||
|
|
||||||
@ -245,8 +245,7 @@ function common_check_user($nickname, $password)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($user instanceof User && !empty($password)) {
|
if ($user instanceof User && !empty($password)) {
|
||||||
if (0 == strcmp(common_munge_password($password, $user->id),
|
if (0 == strcmp(common_munge_password($password, $user->getProfile()), $user->password)) {
|
||||||
$user->password)) {
|
|
||||||
//internal checking passed
|
//internal checking passed
|
||||||
$authenticatedUser = $user;
|
$authenticatedUser = $user;
|
||||||
}
|
}
|
||||||
@ -710,26 +709,22 @@ function common_find_mentions($text, Notice $notice)
|
|||||||
|
|
||||||
// Is it a reply?
|
// Is it a reply?
|
||||||
|
|
||||||
if ($notice instanceof Notice) {
|
try {
|
||||||
try {
|
$origNotice = $notice->getParent();
|
||||||
$origNotice = $notice->getParent();
|
$origAuthor = $origNotice->getProfile();
|
||||||
$origAuthor = $origNotice->getProfile();
|
|
||||||
|
|
||||||
$ids = $origNotice->getReplies();
|
$ids = $origNotice->getReplies();
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$repliedTo = Profile::getKV('id', $id);
|
try {
|
||||||
if ($repliedTo instanceof Profile) {
|
$repliedTo = Profile::getByID($id);
|
||||||
$origMentions[$repliedTo->nickname] = $repliedTo;
|
$origMentions[$repliedTo->getNickname()] = $repliedTo;
|
||||||
}
|
} catch (NoResultException $e) {
|
||||||
|
// continue foreach
|
||||||
}
|
}
|
||||||
} catch (NoProfileException $e) {
|
|
||||||
common_log(LOG_WARNING, sprintf('Notice %d author profile id %d does not exist', $origNotice->id, $origNotice->profile_id));
|
|
||||||
} catch (NoParentNoticeException $e) {
|
|
||||||
// This notice is not in reply to anything
|
|
||||||
} catch (Exception $e) {
|
|
||||||
common_log(LOG_WARNING, __METHOD__ . ' got exception ' . get_class($e) . ' : ' . $e->getMessage());
|
|
||||||
}
|
}
|
||||||
|
} catch (NoParentNoticeException $e) {
|
||||||
|
// It wasn't a reply to anything, so we can't harvest nickname-relations.
|
||||||
}
|
}
|
||||||
|
|
||||||
$matches = common_find_mentions_raw($text);
|
$matches = common_find_mentions_raw($text);
|
||||||
@ -2434,3 +2429,12 @@ function common_strip_html($html, $trim=true, $save_whitespace=false)
|
|||||||
$text = html_entity_decode(strip_tags($html), ENT_QUOTES, 'UTF-8');
|
$text = html_entity_decode(strip_tags($html), ENT_QUOTES, 'UTF-8');
|
||||||
return $trim ? trim($text) : $text;
|
return $trim ? trim($text) : $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function html_sprintf()
|
||||||
|
{
|
||||||
|
$args = func_get_args();
|
||||||
|
for ($i=1; $i<count($args); $i++) {
|
||||||
|
$args[$i] = htmlspecialchars($args[$i]);
|
||||||
|
}
|
||||||
|
return call_user_func_array('sprintf', $args);
|
||||||
|
}
|
||||||
|
@ -63,12 +63,15 @@ class XMLOutputter
|
|||||||
*
|
*
|
||||||
* Initializes the wrapped XMLWriter.
|
* Initializes the wrapped XMLWriter.
|
||||||
*
|
*
|
||||||
* @param string $output URL for outputting, defaults to stdout
|
* @param string $output URL for outputting, if null it defaults to stdout ('php://output')
|
||||||
* @param boolean $indent Whether to indent output, default true
|
* @param boolean $indent Whether to indent output, default true
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function __construct($output='php://output', $indent=null)
|
function __construct($output=null, $indent=null)
|
||||||
{
|
{
|
||||||
|
if (is_null($output)) {
|
||||||
|
$output = 'php://output';
|
||||||
|
}
|
||||||
$this->xw = new XMLWriter();
|
$this->xw = new XMLWriter();
|
||||||
$this->xw->openURI($output);
|
$this->xw->openURI($output);
|
||||||
if(is_null($indent)) {
|
if(is_null($indent)) {
|
||||||
|
53
nginx.conf.sample
Normal file
53
nginx.conf.sample
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
server {
|
||||||
|
# Ports
|
||||||
|
listen 80;
|
||||||
|
# Uncomment the following line
|
||||||
|
# to enable HTTPS
|
||||||
|
#listen 443 ssl;
|
||||||
|
|
||||||
|
# Server name
|
||||||
|
# Change "example.org" to your domain name
|
||||||
|
server_name example.org;
|
||||||
|
|
||||||
|
# SSL
|
||||||
|
# Uncomment and change the paths to setup
|
||||||
|
# your SSL key/cert. See https://cipherli.st/
|
||||||
|
# for more information
|
||||||
|
#ssl_certificate /path/to/ssl.cert;
|
||||||
|
#ssl_certificate_key /path/to/ssl.key;
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
# Uncomment and change the paths to setup
|
||||||
|
# logging
|
||||||
|
#access_log /path/to/access.log;
|
||||||
|
#error_log /path/to/error.log;
|
||||||
|
|
||||||
|
# Root
|
||||||
|
# Change the path below to where you installed
|
||||||
|
# GNU social
|
||||||
|
root /path/to/gnusocial/root;
|
||||||
|
|
||||||
|
# Index
|
||||||
|
index index.php;
|
||||||
|
|
||||||
|
# PHP
|
||||||
|
location ~ \.php {
|
||||||
|
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
|
||||||
|
# Remove the "fastcgi_pass" line above and uncomment
|
||||||
|
# the one below to use TCP sockets instead of Unix sockets
|
||||||
|
#fastcgi_pass 127.0.0.1:9000;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
include fastcgi.conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Location
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ @gnusocial;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fancy URLs
|
||||||
|
location @gnusocial {
|
||||||
|
rewrite ^(.*)$ /index.php?p=$1 last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -72,7 +72,7 @@ class ActivityPlugin extends Plugin
|
|||||||
// TRANS: Text for "started following" item in activity plugin.
|
// TRANS: Text for "started following" item in activity plugin.
|
||||||
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
||||||
// TRANS: %3$s is a profile URL, %4$s is a profile name.
|
// TRANS: %3$s is a profile URL, %4$s is a profile name.
|
||||||
$rendered = sprintf(_m('<a href="%1$s">%2$s</a> started following <a href="%3$s">%4$s</a>.'),
|
$rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> started following <a href="%3$s">%4$s</a>.'),
|
||||||
$profile->getUrl(),
|
$profile->getUrl(),
|
||||||
$profile->getBestName(),
|
$profile->getBestName(),
|
||||||
$other->getUrl(),
|
$other->getUrl(),
|
||||||
@ -110,7 +110,7 @@ class ActivityPlugin extends Plugin
|
|||||||
// TRANS: Text for "stopped following" item in activity plugin.
|
// TRANS: Text for "stopped following" item in activity plugin.
|
||||||
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
||||||
// TRANS: %3$s is a profile URL, %4$s is a profile name.
|
// TRANS: %3$s is a profile URL, %4$s is a profile name.
|
||||||
$rendered = sprintf(_m('<a href="%1$s">%2$s</a> stopped following <a href="%3$s">%4$s</a>.'),
|
$rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> stopped following <a href="%3$s">%4$s</a>.'),
|
||||||
$profile->getUrl(),
|
$profile->getUrl(),
|
||||||
$profile->getBestName(),
|
$profile->getBestName(),
|
||||||
$other->getUrl(),
|
$other->getUrl(),
|
||||||
@ -155,7 +155,7 @@ class ActivityPlugin extends Plugin
|
|||||||
// TRANS: Text for "stopped liking" item in activity plugin.
|
// TRANS: Text for "stopped liking" item in activity plugin.
|
||||||
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
||||||
// TRANS: %3$s is a notice URL, %4$s is an author name.
|
// TRANS: %3$s is a notice URL, %4$s is an author name.
|
||||||
$rendered = sprintf(_m('<a href="%1$s">%2$s</a> stopped liking <a href="%3$s">%4$s\'s update</a>.'),
|
$rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> stopped liking <a href="%3$s">%4$s\'s update</a>.'),
|
||||||
$profile->getUrl(),
|
$profile->getUrl(),
|
||||||
$profile->getBestName(),
|
$profile->getBestName(),
|
||||||
$notice->getUrl(),
|
$notice->getUrl(),
|
||||||
@ -200,7 +200,7 @@ class ActivityPlugin extends Plugin
|
|||||||
// TRANS: Text for "joined group" item in activity plugin.
|
// TRANS: Text for "joined group" item in activity plugin.
|
||||||
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
||||||
// TRANS: %3$s is a group URL, %4$s is a group name.
|
// TRANS: %3$s is a group URL, %4$s is a group name.
|
||||||
$rendered = sprintf(_m('<a href="%1$s">%2$s</a> joined the group <a href="%3$s">%4$s</a>.'),
|
$rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> joined the group <a href="%3$s">%4$s</a>.'),
|
||||||
$profile->getUrl(),
|
$profile->getUrl(),
|
||||||
$profile->getBestName(),
|
$profile->getBestName(),
|
||||||
$group->homeUrl(),
|
$group->homeUrl(),
|
||||||
@ -241,7 +241,7 @@ class ActivityPlugin extends Plugin
|
|||||||
// TRANS: Text for "left group" item in activity plugin.
|
// TRANS: Text for "left group" item in activity plugin.
|
||||||
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
// TRANS: %1$s is a profile URL, %2$s is a profile name,
|
||||||
// TRANS: %3$s is a group URL, %4$s is a group name.
|
// TRANS: %3$s is a group URL, %4$s is a group name.
|
||||||
$rendered = sprintf(_m('<a href="%1$s">%2$s</a> left the group <a href="%3$s">%4$s</a>.'),
|
$rendered = html_sprintf(_m('<a href="%1$s">%2$s</a> left the group <a href="%3$s">%4$s</a>.'),
|
||||||
$profile->getUrl(),
|
$profile->getUrl(),
|
||||||
$profile->getBestName(),
|
$profile->getBestName(),
|
||||||
$group->homeUrl(),
|
$group->homeUrl(),
|
||||||
|
@ -110,17 +110,17 @@ class AuthCryptPlugin extends AuthenticationPlugin
|
|||||||
* EVENTS
|
* EVENTS
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public function onStartChangePassword($user, $oldpassword, $newpassword)
|
public function onStartChangePassword(Profile $target, $oldpassword, $newpassword)
|
||||||
{
|
{
|
||||||
if (!$this->checkPassword($user->nickname, $oldpassword)) {
|
if (!$this->checkPassword($target->getNickname(), $oldpassword)) {
|
||||||
// if we ARE in overwrite mode, test password with common_check_user
|
// if we ARE in overwrite mode, test password with common_check_user
|
||||||
if (!$this->overwrite || !common_check_user($user->nickname, $oldpassword)) {
|
if (!$this->overwrite || !common_check_user($target->getNickname(), $oldpassword)) {
|
||||||
// either we're not in overwrite mode, or the password was incorrect
|
// either we're not in overwrite mode, or the password was incorrect
|
||||||
return !$this->authoritative;
|
return !$this->authoritative;
|
||||||
}
|
}
|
||||||
// oldpassword was apparently ok
|
// oldpassword was apparently ok
|
||||||
}
|
}
|
||||||
$changed = $this->changePassword($user->nickname, $oldpassword, $newpassword);
|
$changed = $this->changePassword($target->getNickname(), $oldpassword, $newpassword);
|
||||||
|
|
||||||
return (!$changed && empty($this->authoritative));
|
return (!$changed && empty($this->authoritative));
|
||||||
}
|
}
|
||||||
|
@ -28,11 +28,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!defined('STATUSNET') && !defined('LACONICA')) {
|
if (!defined('GNUSOCIAL')) { exit(1); }
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once INSTALLDIR.'/lib/rssaction.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RSS feed for user bookmarks action class.
|
* RSS feed for user bookmarks action class.
|
||||||
@ -48,54 +44,12 @@ require_once INSTALLDIR.'/lib/rssaction.php';
|
|||||||
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
* @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3
|
||||||
* @link http://status.net/
|
* @link http://status.net/
|
||||||
*/
|
*/
|
||||||
class BookmarksrssAction extends Rss10Action
|
class BookmarksrssAction extends TargetedRss10Action
|
||||||
{
|
{
|
||||||
/** The user whose bookmarks to display */
|
protected function getNotices()
|
||||||
|
|
||||||
var $user = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the user to display by supplied nickname
|
|
||||||
*
|
|
||||||
* @param array $args Arguments from $_REQUEST
|
|
||||||
*
|
|
||||||
* @return boolean success
|
|
||||||
*/
|
|
||||||
function prepare($args)
|
|
||||||
{
|
|
||||||
parent::prepare($args);
|
|
||||||
|
|
||||||
$nickname = $this->trimmed('nickname');
|
|
||||||
$this->user = User::getKV('nickname', $nickname);
|
|
||||||
|
|
||||||
if (!$this->user) {
|
|
||||||
// TRANS: Client error displayed when trying to get the RSS feed with bookmarks of a user that does not exist.
|
|
||||||
$this->clientError(_('No such user.'));
|
|
||||||
} else {
|
|
||||||
$this->notices = $this->getNotices($this->limit);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get notices
|
|
||||||
*
|
|
||||||
* @param integer $limit max number of notices to return
|
|
||||||
*
|
|
||||||
* @return array notices
|
|
||||||
*/
|
|
||||||
function getNotices($limit=0)
|
|
||||||
{
|
{
|
||||||
$user = $this->user;
|
$stream = new BookmarksNoticeStream($this->target->getID(), true);
|
||||||
|
return $stream->getNotices(0, $this->limit)->fetchAll();
|
||||||
$notice = new BookmarksNoticeStream($this->user->id, true);
|
|
||||||
$notice = $notice->getNotices(0, NOTICES_PER_PAGE);
|
|
||||||
|
|
||||||
$notices = array();
|
|
||||||
while ($notice->fetch()) {
|
|
||||||
$notices[] = clone($notice);
|
|
||||||
}
|
|
||||||
return $notices;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,31 +59,19 @@ class BookmarksrssAction extends Rss10Action
|
|||||||
*/
|
*/
|
||||||
function getChannel()
|
function getChannel()
|
||||||
{
|
{
|
||||||
$user = $this->user;
|
|
||||||
$c = array('url' => common_local_url('bookmarksrss',
|
$c = array('url' => common_local_url('bookmarksrss',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$user->nickname)),
|
$this->target->getNickname())),
|
||||||
// TRANS: Title of RSS feed with bookmarks of a user.
|
// TRANS: Title of RSS feed with bookmarks of a user.
|
||||||
// TRANS: %s is a user's nickname.
|
// TRANS: %s is a user's nickname.
|
||||||
'title' => sprintf(_("%s's bookmarks"), $user->nickname),
|
'title' => sprintf(_("%s's bookmarks"), $this->target->getNickname()),
|
||||||
'link' => common_local_url('bookmarks',
|
'link' => common_local_url('bookmarks',
|
||||||
array('nickname' =>
|
array('nickname' =>
|
||||||
$user->nickname)),
|
$this->target->getNickname())),
|
||||||
// TRANS: Desciption of RSS feed with bookmarks of a user.
|
// TRANS: Desciption of RSS feed with bookmarks of a user.
|
||||||
// TRANS: %1$s is a user's nickname, %2$s is the name of the StatusNet site.
|
// TRANS: %1$s is a user's nickname, %2$s is the name of the StatusNet site.
|
||||||
'description' => sprintf(_('Bookmarks posted by %1$s on %2$s!'),
|
'description' => sprintf(_('Bookmarks posted by %1$s on %2$s!'),
|
||||||
$user->nickname, common_config('site', 'name')));
|
$this->target->getNickname(), common_config('site', 'name')));
|
||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get image.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function getImage()
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user