protected function doPost() { try { $request = Subscription_queue::pkeyGet(array('subscriber' => $this->scoped->id, 'subscribed' => $this->target->id)); if ($request instanceof Subscription_queue) { $request->abort(); } } catch (AlreadyFulfilledException $e) { common_debug('Tried to cancel a non-existing pending subscription'); } if (GNUsocial::isAjax()) { $this->startHTML('text/xml;charset=utf-8'); $this->elementStart('head'); // TRANS: Title after unsubscribing from a group. $this->element('title', null, _m('TITLE', 'Unsubscribed')); $this->elementEnd('head'); $this->elementStart('body'); $subscribe = new SubscribeForm($this, $this->target); $subscribe->show(); $this->elementEnd('body'); $this->endHTML(); exit; } common_redirect(common_local_url('subscriptions', array('nickname' => $this->scoped->getNickname())), 303); }
protected function showActionContent(ManagedAction $action, $verb, Notice $target, Profile $scoped) { if (!GNUsocial::isAjax()) { $nl = new NoticeListItem($target, $action, array('options' => false, 'attachments' => false, 'item_tag' => 'div', 'id_prefix' => 'fave')); $nl->show(); } $form = $this->getActivityForm($action, $verb, $target, $scoped); $form->show(); return false; }
/** * Show the form for OpenID management * * We have one form with a few different submit buttons to do different things. * * @return void */ function showContent() { $provider = $this->trimmed('provider'); if (!empty($provider) || GNUsocial::isAjax()) { $this->showAddFeedForm($provider); } else { $this->elementStart('div', array('id' => 'add-mirror')); $this->showAddWizard(); $this->elementEnd('div'); $mirror = new SubMirror(); $mirror->subscriber = $this->scoped->getID(); if ($mirror->find()) { while ($mirror->fetch()) { $this->showFeedForm($mirror); } } } }
function showPage() { if (GNUsocial::isAjax()) { $this->extraHeaders(); $this->ajaxErrorMsg(); exit; } if ($this->minimal) { // Even more minimal -- we're in a machine API // and don't want to flood the output. $this->extraHeaders(); $this->showContent(); } else { parent::showPage(); } // We don't want to have any more output after this exit; }
function showRepresentation() { if (Event::handle('StartShowAttachmentRepresentation', array($this->out, $this->attachment))) { if (!empty($this->attachment->mimetype)) { $mediatype = common_get_mime_media($this->attachment->mimetype); // FIXME: Get proper mime recognition of Ogg files! If system has 'mediainfo', this should do it: // $ mediainfo --inform='General;%InternetMediaType%' if ($this->attachment->mimetype === 'application/ogg') { $mediatype = 'video'; // because this element can handle Ogg/Vorbis etc. on its own } switch ($mediatype) { // Anything we understand as an image, if we need special treatment, do it in StartShowAttachmentRepresentation case 'image': try { // Tell getThumbnail that we can show an animated image if it has one (4th arg, "force_still") $thumb = $this->attachment->getThumbnail(null, null, false, false); $this->out->element('img', array('class' => 'u-photo', 'src' => $thumb->getUrl(), 'alt' => '')); } catch (UseFileAsThumbnailException $e) { $this->out->element('img', array('class' => 'u-photo', 'src' => $e->file->getUrl(), 'alt' => $e->file->title)); } catch (UnsupportedMediaException $e) { // FIXME: Show a good representation of unsupported/unshowable images } break; // HTML5 media elements // HTML5 media elements case 'audio': case 'video': try { $thumb = $this->attachment->getThumbnail(); $poster = $thumb->getUrl(); unset($thumb); } catch (Exception $e) { $poster = null; } $this->out->elementStart($mediatype, array('class' => "attachment_player u-{$mediatype}", 'poster' => $poster, 'controls' => 'controls')); $this->out->element('source', array('src' => $this->attachment->getUrl(), 'type' => $this->attachment->mimetype)); $this->out->elementEnd($mediatype); break; default: switch ($this->attachment->mimetype) { case 'text/html': if (!empty($this->attachment->filename) && (GNUsocial::isAjax() || common_config('attachments', 'show_html'))) { // Locally-uploaded HTML. Scrub and display inline. $this->showHtmlFile($this->attachment); break; } // Fall through to default if it wasn't a _local_ text/html File object // Fall through to default if it wasn't a _local_ text/html File object default: Event::handle('ShowUnsupportedAttachmentRepresentation', array($this->out, $this->attachment)); } } } else { Event::handle('ShowUnsupportedAttachmentRepresentation', array($this->out, $this->attachment)); } } Event::handle('EndShowAttachmentRepresentation', array($this->out, $this->attachment)); }
public function onStartShowAttachmentRepresentation(HTMLOutputter $out, File $file) { $oembed = File_oembed::getKV('file_id', $file->id); if (empty($oembed->type)) { return true; } switch ($oembed->type) { case 'rich': case 'video': case 'link': if (!empty($oembed->html) && (GNUsocial::isAjax() || common_config('attachments', 'show_html'))) { require_once INSTALLDIR . '/extlib/htmLawed/htmLawed.php'; $config = array('safe' => 1, 'elements' => '*+object+embed'); $out->raw(htmLawed($oembed->html, $config)); } break; case 'photo': $out->element('img', array('src' => $oembed->url, 'width' => $oembed->width, 'height' => $oembed->height, 'alt' => 'alt')); break; default: Event::handle('ShowUnsupportedAttachmentRepresentation', array($out, $file)); } }
/** * This doPost saves a new notice, based on arguments * * If successful, will show the notice, or return an Ajax-y result. * If not, it will show an error message -- possibly Ajax-y. * * Also, if the notice input looks like a command, it will run the * command and show the results -- again, possibly ajaxy. * * @return void */ protected function doPost() { assert($this->scoped instanceof Profile); // XXX: maybe an error instead... $user = $this->scoped->getUser(); $content = $this->trimmed('status_textarea'); $options = array(); Event::handle('StartSaveNewNoticeWeb', array($this, $user, &$content, &$options)); if (empty($content)) { // TRANS: Client error displayed trying to send a notice without content. $this->clientError(_('No content!')); } $inter = new CommandInterpreter(); $cmd = $inter->handle_command($user, $content); if ($cmd) { if (GNUsocial::isAjax()) { $cmd->execute(new AjaxWebChannel($this)); } else { $cmd->execute(new WebChannel($this)); } return; } $content_shortened = $user->shortenLinks($content); if (Notice::contentTooLong($content_shortened)) { // TRANS: Client error displayed when the parameter "status" is missing. // TRANS: %d is the maximum number of character for a notice. $this->clientError(sprintf(_m('That\'s too long. Maximum notice size is %d character.', 'That\'s too long. Maximum notice size is %d characters.', Notice::maxContent()), Notice::maxContent())); } $replyto = $this->int('inreplyto'); if ($replyto) { $options['reply_to'] = $replyto; } $upload = null; try { // throws exception on failure $upload = MediaFile::fromUpload('attach', $this->scoped); if (Event::handle('StartSaveNewNoticeAppendAttachment', array($this, $upload, &$content_shortened, &$options))) { $content_shortened .= ' ' . $upload->shortUrl(); } Event::handle('EndSaveNewNoticeAppendAttachment', array($this, $upload, &$content_shortened, &$options)); if (Notice::contentTooLong($content_shortened)) { $upload->delete(); // TRANS: Client error displayed exceeding the maximum notice length. // TRANS: %d is the maximum length for a notice. $this->clientError(sprintf(_m('Maximum notice size is %d character, including attachment URL.', 'Maximum notice size is %d characters, including attachment URL.', Notice::maxContent()), Notice::maxContent())); } } catch (NoUploadedMediaException $e) { // simply no attached media to the new notice } if ($this->scoped->shareLocation()) { // use browser data if checked; otherwise profile data if ($this->arg('notice_data-geo')) { $locOptions = Notice::locationOptions($this->trimmed('lat'), $this->trimmed('lon'), $this->trimmed('location_id'), $this->trimmed('location_ns'), $this->scoped); } else { $locOptions = Notice::locationOptions(null, null, null, null, $this->scoped); } $options = array_merge($options, $locOptions); } $author_id = $this->scoped->id; $text = $content_shortened; // Does the heavy-lifting for getting "To:" information ToSelector::fillOptions($this, $options); if (Event::handle('StartNoticeSaveWeb', array($this, &$author_id, &$text, &$options))) { $this->stored = Notice::saveNew($this->scoped->id, $content_shortened, 'web', $options); if ($upload instanceof MediaFile) { $upload->attachToNotice($this->stored); } Event::handle('EndNoticeSaveWeb', array($this, $this->stored)); } Event::handle('EndSaveNewNoticeWeb', array($this, $user, &$content_shortened, &$options)); if (!GNUsocial::isAjax()) { $url = common_local_url('shownotice', array('notice' => $this->stored->id)); common_redirect($url, 303); } return _('Saved the notice!'); }
/** * This doPost saves a new notice, based on arguments * * If successful, will show the notice, or return an Ajax-y result. * If not, it will show an error message -- possibly Ajax-y. * * Also, if the notice input looks like a command, it will run the * command and show the results -- again, possibly ajaxy. * * @return void */ protected function doPost() { assert($this->scoped instanceof Profile); // XXX: maybe an error instead... $user = $this->scoped->getUser(); $content = $this->trimmed('status_textarea'); $options = array('source' => 'web'); Event::handle('StartSaveNewNoticeWeb', array($this, $user, &$content, &$options)); if (empty($content)) { // TRANS: Client error displayed trying to send a notice without content. $this->clientError(_('No content!')); } $inter = new CommandInterpreter(); $cmd = $inter->handle_command($user, $content); if ($cmd) { if (GNUsocial::isAjax()) { $cmd->execute(new AjaxWebChannel($this)); } else { $cmd->execute(new WebChannel($this)); } return; } if ($this->int('inreplyto')) { // Throws exception if the inreplyto Notice is given but not found. $parent = Notice::getByID($this->int('inreplyto')); } else { $parent = null; } $act = new Activity(); $act->verb = ActivityVerb::POST; $act->time = time(); $act->actor = $this->scoped->asActivityObject(); $upload = null; try { // throws exception on failure $upload = MediaFile::fromUpload('attach', $this->scoped); if (Event::handle('StartSaveNewNoticeAppendAttachment', array($this, $upload, &$content, &$options))) { $content .= ' ' . $upload->shortUrl(); } Event::handle('EndSaveNewNoticeAppendAttachment', array($this, $upload, &$content, &$options)); // We could check content length here if the URL was added, but I'll just let it slide for now... $act->enclosures[] = $upload->getEnclosure(); } catch (NoUploadedMediaException $e) { // simply no attached media to the new notice } // Reject notice if it is too long (without the HTML) // This is done after MediaFile::fromUpload etc. just to act the same as the ApiStatusesUpdateAction if (Notice::contentTooLong($content)) { // TRANS: Client error displayed when the parameter "status" is missing. // TRANS: %d is the maximum number of character for a notice. throw new ClientException(sprintf(_m('That\'s too long. Maximum notice size is %d character.', 'That\'s too long. Maximum notice size is %d characters.', Notice::maxContent()), Notice::maxContent())); } $act->context = new ActivityContext(); if ($parent instanceof Notice) { $act->context->replyToID = $parent->getUri(); $act->context->replyToUrl = $parent->getUrl(true); // maybe we don't have to send true here to force a URL? } if ($this->scoped->shareLocation()) { // use browser data if checked; otherwise profile data if ($this->arg('notice_data-geo')) { $locOptions = Notice::locationOptions($this->trimmed('lat'), $this->trimmed('lon'), $this->trimmed('location_id'), $this->trimmed('location_ns'), $this->scoped); } else { $locOptions = Notice::locationOptions(null, null, null, null, $this->scoped); } $act->context->location = Location::fromOptions($locOptions); } $content = $this->scoped->shortenLinks($content); // FIXME: Make sure NoticeTitle plugin gets a change to add the title to our activityobject! if (Event::handle('StartNoticeSaveWeb', array($this, $this->scoped, &$content, &$options))) { // FIXME: We should be able to get the attentions from common_render_content! // and maybe even directly save whether they're local or not! $act->context->attention = common_get_attentions($content, $this->scoped, $parent); $actobj = new ActivityObject(); $actobj->type = ActivityObject::NOTE; $actobj->content = common_render_content($content, $this->scoped, $parent); // Finally add the activity object to our activity $act->objects[] = $actobj; $this->stored = Notice::saveActivity($act, $this->scoped, $options); if ($upload instanceof MediaFile) { $upload->attachToNotice($this->stored); } Event::handle('EndNoticeSaveWeb', array($this, $this->stored)); } Event::handle('EndSaveNewNoticeWeb', array($this, $user, &$content, &$options)); if (!GNUsocial::isAjax()) { $url = common_local_url('shownotice', array('notice' => $this->stored->id)); common_redirect($url, 303); } return _('Saved the notice!'); }
protected function doPost() { assert($this->scoped instanceof Profile); // XXX: maybe an error instead... if (empty($this->content)) { // TRANS: Form validator error displayed trying to send a direct message without content. $this->clientError(_('No content!')); } $content_shortened = $this->scoped->shortenLinks($this->content); if (Message::contentTooLong($content_shortened)) { // TRANS: Form validation error displayed when message content is too long. // TRANS: %d is the maximum number of characters for a message. $this->clientError(sprintf(_m('That\'s too long. Maximum message size is %d character.', 'That\'s too long. Maximum message size is %d characters.', Message::maxContent()), Message::maxContent())); } if (!$this->other instanceof Profile) { // TRANS: Form validation error displayed trying to send a direct message without specifying a recipient. $this->clientError(_('No recipient specified.')); } else { if (!$this->scoped->mutuallySubscribed($this->other)) { // TRANS: Client error displayed trying to send a direct message to a user while sender and // TRANS: receiver are not subscribed to each other. $this->clientError(_('You cannot send a message to this user.'), 404); } else { if ($this->scoped->id == $this->other->id) { // TRANS: Client error displayed trying to send a direct message to self. $this->clientError(_('Do not send a message to yourself; ' . 'just say it to yourself quietly instead.'), 403); } } } $message = Message::saveNew($this->scoped->id, $this->other->id, $this->content, 'web'); $message->notify(); if (GNUsocial::isAjax()) { // TRANS: Confirmation text after sending a direct message. // TRANS: %s is the direct message recipient. return sprintf(_('Direct message to %s sent.'), $this->other->getNickname()); } $url = common_local_url('outbox', array('nickname' => $this->scoped->getNickname())); common_redirect($url, 303); }
/** * Show page, a template method. * * @return nothing */ function showPage() { if (GNUsocial::isAjax()) { self::showAjax(); return; } if (Event::handle('StartShowHTML', array($this))) { $this->startHTML(); $this->flush(); Event::handle('EndShowHTML', array($this)); } if (Event::handle('StartShowHead', array($this))) { $this->showHead(); $this->flush(); Event::handle('EndShowHead', array($this)); } if (Event::handle('StartShowBody', array($this))) { $this->showBody(); Event::handle('EndShowBody', array($this)); } if (Event::handle('StartEndHTML', array($this))) { $this->endHTML(); Event::handle('EndEndHTML', array($this)); } }
public function onShowUnsupportedAttachmentRepresentation(HTMLOutputter $out, File $file) { try { $oembed = File_oembed::getByFile($file); } catch (NoResultException $e) { return true; } // the 'photo' type is shown through ordinary means, using StartShowAttachmentRepresentation! switch ($oembed->type) { case 'rich': case 'video': case 'link': if (!empty($oembed->html) && (GNUsocial::isAjax() || common_config('attachments', 'show_html'))) { require_once INSTALLDIR . '/extlib/htmLawed/htmLawed.php'; $config = array('safe' => 1, 'elements' => '*+object+embed'); $out->raw(htmLawed($oembed->html, $config)); } return false; break; } return true; }