public function getRendered()
{
- if (is_null($this->rendered) || $this->rendered === '') {
+ // we test $this->id because if it's not inserted yet, we can't update the field
+ if (!empty($this->id) && (is_null($this->rendered) || $this->rendered === '')) {
// update to include rendered content on-the-fly, so we don't have to have a fix-up script in upgrade.php
common_debug('Rendering notice '.$this->getID().' as it had no rendered HTML content.');
$orig = clone($this);
return $this->rendered;
}
+ public function getCreated()
+ {
+ return $this->created;
+ }
+
+ public function getVerb($make_relative=false)
+ {
+ return ActivityUtils::resolveUri($this->verb, $make_relative);
+ }
+
+ public function isVerb(array $verbs)
+ {
+ return ActivityUtils::compareVerbs($this->getVerb(), $verbs);
+ }
+
/*
* Get the original representation URL of this notice.
*
}
}
+ public function getSelfLink()
+ {
+ if ($this->isLocal()) {
+ return common_local_url('ApiStatusesShow', array('id' => $this->getID(), 'format' => 'atom'));
+ }
+
+ $selfLink = $this->getPref('ostatus', 'self');
+
+ if (!common_valid_http_url($selfLink)) {
+ throw new InvalidUrlException($selfLink);
+ }
+
+ return $selfLink;
+ }
+
public function getObjectType($canonical=false) {
+ if (is_null($this->object_type) || $this->object_type==='') {
+ throw new NoObjectTypeException($this);
+ }
return ActivityUtils::resolveUri($this->object_type, $canonical);
}
+ public function isObjectType(array $types)
+ {
+ try {
+ return ActivityUtils::compareTypes($this->getObjectType(), $types);
+ } catch (NoObjectTypeException $e) {
+ return false;
+ }
+ }
+
public static function getByUri($uri)
{
$notice = new Notice();
static function saveNew($profile_id, $content, $source, array $options=null) {
$defaults = array('uri' => null,
'url' => null,
+ 'self' => null,
'conversation' => null, // URI of conversation
'reply_to' => null, // This will override convo URI if the parent is known
'repeat_of' => null, // This will override convo URI if the repeated notice is known
}
}
+ if ($self && common_valid_http_url($self)) {
+ $notice->setPref('ostatus', 'self', $self);
+ }
+
// Only save 'attention' and metadata stuff (URLs, tags...) stuff if
// the activityverb is a POST (since stuff like repeat, favorite etc.
// reasonably handle notifications themselves.
// implied object
$options['uri'] = $act->id;
$options['url'] = $act->link;
+ if ($act->selfLink) {
+ $options['self'] = $act->selfLink;
+ }
} else {
- $actobj = count($act->objects)==1 ? $act->objects[0] : null;
+ $actobj = count($act->objects)===1 ? $act->objects[0] : null;
if (!is_null($actobj) && !empty($actobj->id)) {
$options['uri'] = $actobj->id;
if ($actobj->link) {
$options['url'] = $actobj->id;
}
}
+ if ($actobj->selfLink) {
+ $options['self'] = $actobj->selfLink;
+ }
}
$defaults = array(
'reply_to' => null,
'repeat_of' => null,
'scope' => null,
+ 'self' => null,
'source' => 'unknown',
'tags' => array(),
'uri' => null,
$stored->url = $url;
$stored->verb = $act->verb;
- // Notice content. We trust local users to provide HTML we like, but of course not remote users.
- // FIXME: What about local users importing feeds? Mirror functions must filter out bad HTML first...
$content = $act->content ?: $act->summary;
if (is_null($content) && !is_null($actobj)) {
$content = $actobj->content ?: $actobj->summary;
}
- $stored->rendered = $actor->isLocal() ? $content : common_purify($content);
- // yeah, just don't use getRendered() here since it's not inserted yet ;)
- $stored->content = common_strip_html($stored->rendered);
+ // Strip out any bad HTML
+ $stored->rendered = common_purify($content);
+ $stored->content = common_strip_html($stored->getRendered(), true, true);
+ if (trim($stored->content) === '') {
+ // TRANS: Error message when the plain text content of a notice has zero length.
+ throw new ClientException(_('Empty notice content, will not save this.'));
+ }
// Maybe a missing act-time should be fatal if the actor is not local?
if (!empty($act->time)) {
$object = null;
Event::handle('StoreActivityObject', array($act, $stored, $options, &$object));
if (empty($object)) {
- throw new ServerException('Unsuccessful call to StoreActivityObject '.$stored->getUri() . ': '.$act->asString());
+ throw new NoticeSaveException('Unsuccessful call to StoreActivityObject '._ve($stored->getUri()) . ': '._ve($act->asString()));
}
// If something changed in the Notice during StoreActivityObject
throw new ServerException('StartNoticeSave did not give back a Notice');
}
+ if ($self && common_valid_http_url($self)) {
+ $stored->setPref('ostatus', 'self', $self);
+ }
+
// Only save 'attention' and metadata stuff (URLs, tags...) stuff if
// the activityverb is a POST (since stuff like repeat, favorite etc.
// reasonably handle notifications themselves.
}
}
+ try {
+ $act->selfLink = $this->getSelfLink();
+ } catch (InvalidUrlException $e) {
+ $act->selfLink = null;
+ }
if ($this->isLocal()) {
- $act->selfLink = common_local_url('ApiStatusesShow', array('id' => $this->id,
- 'format' => 'atom'));
$act->editLink = $act->selfLink;
}
if (!empty($ns->url)) {
$noticeInfoAttr['source_link'] = $ns->url;
if (!empty($ns->name)) {
- $noticeInfoAttr['source'] = '<a href="'
- . htmlspecialchars($ns->url)
- . '" rel="nofollow">'
- . htmlspecialchars($ns->name)
- . '</a>';
+ $noticeInfoAttr['source'] = $ns->name;
}
}
}
$object->title = sprintf('New %1$s by %2$s', ActivityObject::canonicalType($object->type), $this->getProfile()->getNickname());
$object->content = $this->getRendered();
$object->link = $this->getUrl();
+ try {
+ $object->selfLink = $this->getSelfLink();
+ } catch (InvalidUrlException $e) {
+ $object->selfLink = null;
+ }
$object->extra[] = array('status_net', array('notice_id' => $this->id));
Event::handle('EndActivityObjectFromNotice', array($this, &$object));
}
+ if (!$object instanceof ActivityObject) {
+ common_log(LOG_ERR, 'Notice asActivityObject created something else for uri=='._ve($this->getUri()).': '._ve($object));
+ throw new ServerException('Notice asActivityObject created something else.');
+ }
+
return $object;
}
}
print "\n";
}
+
+ public function delPref($namespace, $topic) {
+ return Notice_prefs::setData($this, $namespace, $topic, null);
+ }
+
+ public function getPref($namespace, $topic, $default=null) {
+ // If you want an exception to be thrown, call Notice_prefs::getData directly
+ try {
+ return Notice_prefs::getData($this, $namespace, $topic, $default);
+ } catch (NoResultException $e) {
+ return null;
+ }
+ }
+
+ // The same as getPref but will fall back to common_config value for the same namespace/topic
+ public function getConfigPref($namespace, $topic)
+ {
+ return Notice_prefs::getConfigData($this, $namespace, $topic);
+ }
+
+ public function setPref($namespace, $topic, $data) {
+ return Notice_prefs::setData($this, $namespace, $topic, $data);
+ }
}