X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=classes%2FNotice.php;h=c56d68578debef875a7d38bd1579c101bdc571a5;hb=4d17d9533552ea620b83109c550e250a5c236291;hp=b7378711f5d03382347eced4569a237cc17f8517;hpb=c3c5a9974d6959cf92bc501ebe6b37860a57694a;p=quix0rs-gnu-social.git diff --git a/classes/Notice.php b/classes/Notice.php index b7378711f5..c56d68578d 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -88,7 +88,7 @@ class Notice extends Managed_DataObject 'reply_to' => array('type' => 'int', 'description' => 'notice replied to (usually a guess)'), '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"'), - 'conversation' => array('type' => 'int', 'description' => 'id of root notice in this conversation'), + 'conversation' => array('type' => 'int', 'description' => 'the local numerical conversation id'), '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' => null), 'verb' => array('type' => 'varchar', 'length' => 191, 'description' => 'URI representing activity streams verb', 'default' => 'http://activitystrea.ms/schema/1.0/post'), @@ -260,7 +260,8 @@ class Notice extends Managed_DataObject 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); @@ -272,6 +273,21 @@ class Notice extends Managed_DataObject 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. * @@ -298,9 +314,21 @@ class Notice extends Managed_DataObject } 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(); @@ -749,7 +777,7 @@ class Notice extends Managed_DataObject $options['uri'] = $act->id; $options['url'] = $act->link; } 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) { @@ -821,15 +849,17 @@ class Notice extends Managed_DataObject $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)) { @@ -950,7 +980,7 @@ class Notice extends Managed_DataObject $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 @@ -1579,14 +1609,27 @@ class Notice extends Managed_DataObject continue; } - $this->saveAttention($target); + try { + $this->saveAttention($target); + } catch (AlreadyFulfilledException $e) { + common_debug('Attention already exists: '.var_export($e->getMessage(),true)); + } catch (Exception $e) { + common_log(LOG_ERR, "Could not save notice id=={$this->getID()} attention for profile id=={$target->getID()}: {$e->getMessage()}"); + } } } + /** + * Saves an attention for a profile (user or group) which means + * it shows up in their home feed and such. + */ function saveAttention(Profile $target, $reason=null) { if ($target->isGroup()) { - // FIXME: Make sure we check that users are in the groups they send to! + // FIXME: Make sure we check (for both local and remote) users are in the groups they send to! + + // legacy notification method, will still be in use for quite a while I think + $this->addToGroupInbox($target->getGroup()); } else { if ($target->hasBlocked($this->getProfile())) { common_log(LOG_INFO, "Not saving reply to profile {$target->id} ($uri) from sender {$sender->id} because of a block."); @@ -1595,17 +1638,11 @@ class Notice extends Managed_DataObject } if ($target->isLocal()) { - // is local user - $this->saveReply($target->getID()); // since we still have the Reply table which some apparently use! + // legacy notification method, will still be in use for quite a while I think + $this->saveReply($target->getID()); } - try { - $att = Attention::saveNew($this, $target, $reason); - } catch (AlreadyFulfilledException $e) { - common_debug('Could not save Attention: '.$e->getMessage()); - } catch (Exception $e) { - common_log(LOG_ERR, 'Could not save Attention: '.$e->getMessage()); - } + $att = Attention::saveNew($this, $target, $reason); self::blow('reply:stream:%d', $target->getID()); return true; @@ -1952,19 +1989,11 @@ class Notice extends Managed_DataObject } } - $reply_ids = $this->getReplies(); - - foreach ($reply_ids as $id) { - $rprofile = Profile::getKV('id', $id); - if ($rprofile instanceof Profile) { - $ctx->attention[$rprofile->getUri()] = ActivityObject::PERSON; - } - } - - $groups = $this->getGroups(); - - foreach ($groups as $group) { - $ctx->attention[$group->getUri()] = ActivityObject::GROUP; + // This covers the legacy getReplies and getGroups too which get their data + // from entries stored via Notice::saveNew (which we want to move away from)... + foreach ($this->getAttentionProfiles() as $target) { + // User and group profiles which get the attention of this notice + $ctx->attention[$target->getUri()] = $target->getObjectType(); } switch ($this->scope) { @@ -2129,6 +2158,11 @@ class Notice extends Managed_DataObject 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; } @@ -2616,21 +2650,21 @@ class Notice extends Managed_DataObject */ public static function getAsTimestamp($id) { - if (!$id) { - return false; + if (empty($id)) { + throw new EmptyIdException('Notice'); } - $notice = Notice::getKV('id', $id); - if ($notice) { - return $notice->created; + $timestamp = null; + if (Event::handle('GetNoticeSqlTimestamp', array($id, &$timestamp))) { + // getByID throws exception if $id isn't found + $notice = Notice::getByID($id); + $timestamp = $notice->created; } - $deleted = Deleted_notice::getKV('id', $id); - if ($deleted) { - return $deleted->created; + if (empty($timestamp)) { + throw new ServerException('No timestamp found for Notice with id=='._ve($id)); } - - return false; + return $timestamp; } /** @@ -2646,11 +2680,12 @@ class Notice extends Managed_DataObject */ public static function whereSinceId($id, $idField='id', $createdField='created') { - $since = Notice::getAsTimestamp($id); - if ($since) { - return sprintf("($createdField = '%s' and $idField > %d) or ($createdField > '%s')", $since, $id, $since); + try { + $since = Notice::getAsTimestamp($id); + } catch (Exception $e) { + return false; } - return false; + return sprintf("($createdField = '%s' and $idField > %d) or ($createdField > '%s')", $since, $id, $since); } /** @@ -2685,11 +2720,12 @@ class Notice extends Managed_DataObject */ public static function whereMaxId($id, $idField='id', $createdField='created') { - $max = Notice::getAsTimestamp($id); - if ($max) { - return sprintf("($createdField < '%s') or ($createdField = '%s' and $idField <= %d)", $max, $max, $id); + try { + $max = Notice::getAsTimestamp($id); + } catch (Exception $e) { + return false; } - return false; + return sprintf("($createdField < '%s') or ($createdField = '%s' and $idField <= %d)", $max, $max, $id); } /**