diff options
115 files changed, 6408 insertions, 981 deletions
diff --git a/Zotlabs/ActivityStreams/ASObject.php b/Zotlabs/ActivityStreams/ASObject.php new file mode 100644 index 000000000..1006943af --- /dev/null +++ b/Zotlabs/ActivityStreams/ASObject.php @@ -0,0 +1,776 @@ +<?php + +namespace Zotlabs\ActivityStreams; + + +use Zotlabs\Lib\BaseObject; + +class ASObject extends BaseObject +{ + public $id; + public $type; + public $attachment; + public $attributedTo; + public $audience; + public $content; + public $context; + public $name; + public $endTime; + public $generator; + public $icon; + public $image; + public $inReplyTo; + public $location; + public $preview; + public $published; + public $replies; + public $startTime; + public $summary; + public $tag; + public $updated; + public $url; + public $to; + public $bto; + public $cc; + public $bcc; + public $mediaType; + public $duration; + public $source; + + + // Extension properties + + public $signature; + public $proof; + public $sensitive; + public $replyTo; + public $wall; + public $isContainedConversation; + public $expires; + public $canReply; + public $canSearch; + public $directMessage; + public $commentPolicy; + + /** + * @return mixed + */ + public function getDirectMessage() + { + return $this->directMessage; + } + + /** + * @param mixed $directMessage + * @return ASObject + */ + public function setDirectMessage($directMessage) + { + $this->directMessage = $directMessage; + return $this; + } + + /** + * @return mixed + */ + public function getSignature() + { + return $this->signature; + } + + /** + * @param mixed $signature + * @return ASObject + */ + public function setSignature($signature) + { + $this->signature = $signature; + return $this; + } + + /** + * @return mixed + */ + public function getProof() + { + return $this->proof; + } + + /** + * @param mixed $proof + * @return ASObject + */ + public function setProof($proof) + { + $this->proof = $proof; + return $this; + } + + + /** + * @return mixed + */ + public function getSensitive() + { + return $this->sensitive; + } + + /** + * @param mixed $sensitive + * @return ASObject + */ + public function setSensitive($sensitive) + { + $this->sensitive = $sensitive; + return $this; + } + + /** + * @return mixed + */ + public function getReplyTo() + { + return $this->replyTo; + } + + /** + * @param mixed $replyTo + * @return ASObject + */ + public function setReplyTo($replyTo) + { + $this->replyTo = $replyTo; + return $this; + } + + /** + * @return mixed + */ + public function getWall() + { + return $this->wall; + } + + /** + * @param mixed $wall + * @return ASObject + */ + public function setWall($wall) + { + $this->wall = $wall; + return $this; + } + + /** + * @return mixed + */ + public function getIsContainedConversation() + { + return $this->isContainedConversation; + } + + /** + * @param mixed $isContainedConversation + * @return ASObject + */ + public function setIsContainedConversation($isContainedConversation) + { + $this->isContainedConversation = $isContainedConversation; + return $this; + } + + /** + * @return mixed + */ + public function getExpires() + { + return $this->expires; + } + + /** + * @param mixed $expires + * @return ASObject + */ + public function setExpires($expires) + { + $this->expires = $expires; + return $this; + } + + /** + * @return mixed + */ + public function getCanReply() + { + return $this->canReply; + } + + /** + * @param mixed $canReply + * @return ASObject + */ + public function setCanReply($canReply) + { + $this->canReply = $canReply; + return $this; + } + + /** + * @return mixed + */ + public function getCanSearch() + { + return $this->canSearch; + } + + /** + * @param mixed $canSearch + * @return ASObject + */ + public function setCanSearch($canSearch) + { + $this->canSearch = $canSearch; + return $this; + } + + /** + * @return mixed + */ + public function getCommentPolicy() + { + return $this->commentPolicy; + } + + /** + * @param mixed $commentPolicy + * @return ASObject + */ + public function setCommentPolicy($commentPolicy) + { + $this->commentPolicy = $commentPolicy; + return $this; + } + + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + + /** + * @param mixed $id + * @return ASObject + */ + public function setId($id) + { + $this->id = $id; + return $this; + } + + /** + * @return mixed + */ + public function getType() + { + return $this->type; + } + + /** + * @param mixed $type + * @return ASObject + */ + public function setType($type) + { + $this->type = $type; + return $this; + } + + /** + * @return mixed + */ + public function getAttachment() + { + return $this->attachment; + } + + /** + * @param mixed $attachment + * @return ASObject + */ + public function setAttachment($attachment) + { + $this->attachment = $attachment; + return $this; + } + + /** + * @return mixed + */ + public function getAttributedTo() + { + return $this->attributedTo; + } + + /** + * @param mixed $attributedTo + * @return ASObject + */ + public function setAttributedTo($attributedTo) + { + $this->attributedTo = $attributedTo; + return $this; + } + + /** + * @return mixed + */ + public function getAudience() + { + return $this->audience; + } + + /** + * @param mixed $audience + * @return ASObject + */ + public function setAudience($audience) + { + $this->audience = $audience; + return $this; + } + + /** + * @return mixed + */ + public function getContent() + { + return $this->content; + } + + /** + * @param mixed $content + * @return ASObject + */ + public function setContent($content) + { + $this->content = $content; + return $this; + } + + /** + * @return mixed + */ + public function getContext() + { + return $this->context; + } + + /** + * @param mixed $context + * @return ASObject + */ + public function setContext($context) + { + $this->context = $context; + return $this; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->name; + } + + /** + * @param mixed $name + * @return ASObject + */ + public function setName($name) + { + $this->name = $name; + return $this; + } + + /** + * @return mixed + */ + public function getEndTime() + { + return $this->endTime; + } + + /** + * @param mixed $endTime + * @return ASObject + */ + public function setEndTime($endTime) + { + $this->endTime = $endTime; + return $this; + } + + /** + * @return mixed + */ + public function getGenerator() + { + return $this->generator; + } + + /** + * @param mixed $generator + * @return ASObject + */ + public function setGenerator($generator) + { + $this->generator = $generator; + return $this; + } + + /** + * @return mixed + */ + public function getIcon() + { + return $this->icon; + } + + /** + * @param mixed $icon + * @return ASObject + */ + public function setIcon($icon) + { + $this->icon = $icon; + return $this; + } + + /** + * @return mixed + */ + public function getImage() + { + return $this->image; + } + + /** + * @param mixed $image + * @return ASObject + */ + public function setImage($image) + { + $this->image = $image; + return $this; + } + + /** + * @return mixed + */ + public function getInReplyTo() + { + return $this->inReplyTo; + } + + /** + * @param mixed $inReplyTo + * @return ASObject + */ + public function setInReplyTo($inReplyTo) + { + $this->inReplyTo = $inReplyTo; + return $this; + } + + /** + * @return mixed + */ + public function getLocation() + { + return $this->location; + } + + /** + * @param mixed $location + * @return ASObject + */ + public function setLocation($location) + { + $this->location = $location; + return $this; + } + + /** + * @return mixed + */ + public function getPreview() + { + return $this->preview; + } + + /** + * @param mixed $preview + * @return ASObject + */ + public function setPreview($preview) + { + $this->preview = $preview; + return $this; + } + + /** + * @return mixed + */ + public function getPublished() + { + return $this->published; + } + + /** + * @param mixed $published + * @return ASObject + */ + public function setPublished($published) + { + $this->published = $published; + return $this; + } + + /** + * @return mixed + */ + public function getReplies() + { + return $this->replies; + } + + /** + * @param mixed $replies + * @return ASObject + */ + public function setReplies($replies) + { + $this->replies = $replies; + return $this; + } + + /** + * @return mixed + */ + public function getStartTime() + { + return $this->startTime; + } + + /** + * @param mixed $startTime + * @return ASObject + */ + public function setStartTime($startTime) + { + $this->startTime = $startTime; + return $this; + } + + /** + * @return mixed + */ + public function getSummary() + { + return $this->summary; + } + + /** + * @param mixed $summary + * @return ASObject + */ + public function setSummary($summary) + { + $this->summary = $summary; + return $this; + } + + /** + * @return mixed + */ + public function getTag() + { + return $this->tag; + } + + /** + * @param mixed $tag + * @return ASObject + */ + public function setTag($tag) + { + $this->tag = $tag; + return $this; + } + + /** + * @return mixed + */ + public function getUpdated() + { + return $this->updated; + } + + /** + * @param mixed $updated + * @return ASObject + */ + public function setUpdated($updated) + { + $this->updated = $updated; + return $this; + } + + /** + * @return mixed + */ + public function getUrl() + { + return $this->url; + } + + /** + * @param mixed $url + * @return ASObject + */ + public function setUrl($url) + { + $this->url = $url; + return $this; + } + + /** + * @return mixed + */ + public function getTo() + { + return $this->to; + } + + /** + * @param mixed $to + * @return ASObject + */ + public function setTo($to) + { + $this->to = $to; + return $this; + } + + /** + * @return mixed + */ + public function getBto() + { + return $this->bto; + } + + /** + * @param mixed $bto + * @return ASObject + */ + public function setBto($bto) + { + $this->bto = $bto; + return $this; + } + + /** + * @return mixed + */ + public function getCc() + { + return $this->cc; + } + + /** + * @param mixed $cc + * @return ASObject + */ + public function setCc($cc) + { + $this->cc = $cc; + return $this; + } + + /** + * @return mixed + */ + public function getBcc() + { + return $this->bcc; + } + + /** + * @param mixed $bcc + * @return ASObject + */ + public function setBcc($bcc) + { + $this->bcc = $bcc; + return $this; + } + + /** + * @return mixed + */ + public function getMediaType() + { + return $this->mediaType; + } + + /** + * @param mixed $mediaType + * @return ASObject + */ + public function setMediaType($mediaType) + { + $this->mediaType = $mediaType; + return $this; + } + + /** + * @return mixed + */ + public function getDuration() + { + return $this->duration; + } + + /** + * @param mixed $duration + * @return ASObject + */ + public function setDuration($duration) + { + $this->duration = $duration; + return $this; + } + + /** + * @return mixed + */ + public function getSource() + { + return $this->source; + } + + /** + * @param mixed $source + * @return ASObject + */ + public function setSource($source) + { + $this->source = $source; + return $this; + } + +} diff --git a/Zotlabs/ActivityStreams/Activity.php b/Zotlabs/ActivityStreams/Activity.php new file mode 100644 index 000000000..3fccfb964 --- /dev/null +++ b/Zotlabs/ActivityStreams/Activity.php @@ -0,0 +1,122 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Activity extends ASObject +{ + public $actor; + public $object; + public $target; + public $result; + public $origin; + public $instrument; + + /** + * @return mixed + */ + public function getActor() + { + return $this->actor; + } + + /** + * @param mixed $actor + * @return Activity + */ + public function setActor($actor) + { + $this->actor = $actor; + return $this; + } + + /** + * @return mixed + */ + public function getObject() + { + return $this->object; + } + + /** + * @param mixed $object + * @return Activity + */ + public function setObject($object) + { + $this->object = $object; + return $this; + } + + /** + * @return mixed + */ + public function getTarget() + { + return $this->target; + } + + /** + * @param mixed $target + * @return Activity + */ + public function setTarget($target) + { + $this->target = $target; + return $this; + } + + /** + * @return mixed + */ + public function getResult() + { + return $this->result; + } + + /** + * @param mixed $result + * @return Activity + */ + public function setResult($result) + { + $this->result = $result; + return $this; + } + + /** + * @return mixed + */ + public function getOrigin() + { + return $this->origin; + } + + /** + * @param mixed $origin + * @return Activity + */ + public function setOrigin($origin) + { + $this->origin = $origin; + return $this; + } + + /** + * @return mixed + */ + public function getInstrument() + { + return $this->instrument; + } + + /** + * @param mixed $instrument + * @return Activity + */ + public function setInstrument($instrument) + { + $this->instrument = $instrument; + return $this; + } + +} diff --git a/Zotlabs/ActivityStreams/Actor.php b/Zotlabs/ActivityStreams/Actor.php new file mode 100644 index 000000000..4efa2f6b1 --- /dev/null +++ b/Zotlabs/ActivityStreams/Actor.php @@ -0,0 +1,428 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Actor extends ASObject +{ + public $inbox; + public $outbox; + public $followers; + public $following; + public $permissions; /* extension property */ + public $endpoints; + public $publicKey; + public $preferredUsername; + public $alsoKnownAs; + + // Extension properties + + public $movedTo; + public $copiedTo; + public $discoverable; + public $manuallyApprovesFollowers; + public $webfinger; + public $canSearch; + public $indexable; + public $assertionMethod; + public $gateways; + public $openwebauth; + public $authredirect; + + /** + * @return mixed + */ + public function getAlsoKnownAs() + { + return $this->alsoKnownAs; + } + + /** + * @param mixed $alsoKnownAs + * @return Actor + */ + public function setAlsoKnownAs($alsoKnownAs) + { + $this->alsoKnownAs = $alsoKnownAs; + return $this; + } + + /** + * @return mixed + */ + public function getMovedTo() + { + return $this->movedTo; + } + + /** + * @return mixed + */ + public function getCopiedTo() + { + return $this->copiedTo; + } + + /** + * @param mixed $copiedTo + * @return Actor + */ + public function setCopiedTo($copiedTo) + { + $this->copiedTo = $copiedTo; + return $this; + } + + /** + * @param mixed $movedTo + * @return Actor + */ + public function setMovedTo($movedTo) + { + $this->movedTo = $movedTo; + return $this; + } + + /** + * @return mixed + */ + public function getDiscoverable() + { + return $this->discoverable; + } + + /** + * @param mixed $discoverable + * @return Actor + */ + public function setDiscoverable($discoverable) + { + $this->discoverable = $discoverable; + return $this; + } + + /** + * @return mixed + */ + public function getManuallyApprovesFollowers() + { + return $this->manuallyApprovesFollowers; + } + + /** + * @param mixed $manuallyApprovesFollowers + * @return Actor + */ + public function setManuallyApprovesFollowers($manuallyApprovesFollowers) + { + $this->manuallyApprovesFollowers = $manuallyApprovesFollowers; + return $this; + } + + /** + * @return mixed + */ + public function getPreferredUsername() + { + return $this->preferredUsername; + } + + /** + * @param mixed $preferredUsername + * @return Actor + */ + public function setPreferredUsername($preferredUsername) + { + $this->preferredUsername = $preferredUsername; + return $this; + } + + + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + + /** + * @param mixed $id + * @return Actor + */ + public function setId($id) + { + $this->id = $id; + return $this; + } + + /** + * @return mixed + */ + public function getType() + { + return $this->type; + } + + /** + * @param mixed $type + * @return Actor + */ + public function setType($type) + { + $this->type = $type; + return $this; + } + + /** + * @return mixed + */ + public function getInbox() + { + return $this->inbox; + } + + /** + * @param mixed $inbox + * @return Actor + */ + public function setInbox($inbox) + { + $this->inbox = $inbox; + return $this; + } + + /** + * @return mixed + */ + public function getOutbox() + { + return $this->outbox; + } + + /** + * @param mixed $outbox + * @return Actor + */ + public function setOutbox($outbox) + { + $this->outbox = $outbox; + return $this; + } + + /** + * @return mixed + */ + public function getFollowers() + { + return $this->followers; + } + + /** + * @param mixed $followers + * @return Actor + */ + public function setFollowers($followers) + { + $this->followers = $followers; + return $this; + } + + /** + * @return mixed + */ + public function getFollowing() + { + return $this->following; + } + + /** + * @param mixed $following + * @return Actor + */ + public function setFollowing($following) + { + $this->following = $following; + return $this; + } + + /** + * @return mixed + */ + public function getEndpoints() + { + return $this->endpoints; + } + + /** + * @param mixed $endpoints + * @return Actor + */ + public function setEndpoints($endpoints) + { + $this->endpoints = $endpoints; + return $this; + } + + /** + * @return mixed + */ + public function getPublicKey() + { + return $this->publicKey; + } + + /** + * @param mixed $publicKey + * @return Actor + */ + public function setPublicKey($publicKey) + { + $this->publicKey = $publicKey; + return $this; + } + + /** + * @return mixed + */ + public function getWebfinger() + { + return $this->webfinger; + } + + /** + * @param mixed $webfinger + * @return Actor + */ + public function setWebfinger($webfinger) + { + $this->webfinger = $webfinger; + return $this; + } + + /** + * @return mixed + */ + public function getCanSearch() + { + return $this->canSearch; + } + + /** + * @param mixed $canSearch + * @return Actor + */ + public function setCanSearch($canSearch) + { + $this->canSearch = $canSearch; + return $this; + } + + /** + * @return mixed + */ + public function getIndexable() + { + return $this->indexable; + } + + /** + * @param mixed $indexable + * @return Actor + */ + public function setIndexable($indexable) + { + $this->indexable = $indexable; + return $this; + } + + /** + * @return mixed + */ + public function getAssertionMethod() + { + return $this->assertionMethod; + } + + /** + * @param mixed $assertionMethod + * @return Actor + */ + public function setAssertionMethod($assertionMethod) + { + $this->assertionMethod = $assertionMethod; + return $this; + } + + /** + * @return mixed + */ + public function getGateways() + { + return $this->gateways; + } + + /** + * @param mixed $gateways + * @return Actor + */ + public function setGateways($gateways) + { + $this->gateways = $gateways; + return $this; + } + + /** + * @return mixed + */ + public function getPermissions() + { + return $this->permissions; + } + + /** + * @param mixed $permissions + * @return Actor + */ + public function setPermissions($permissions) + { + $this->permissions = $permissions; + return $this; + } + + /** + * @return mixed + */ + public function getOpenwebauth() + { + return $this->openwebauth; + } + + /** + * @param mixed $openwebauth + * @return Actor + */ + public function setOpenwebauth($openwebauth) + { + $this->openwebauth = $openwebauth; + return $this; + } + + /** + * @return mixed + */ + public function getAuthredirect() + { + return $this->authredirect; + } + + /** + * @param mixed $authredirect + * @return Actor + */ + public function setAuthredirect($authredirect) + { + $this->authredirect = $authredirect; + return $this; + } + +} diff --git a/Zotlabs/ActivityStreams/AssertionMethod.php b/Zotlabs/ActivityStreams/AssertionMethod.php new file mode 100644 index 000000000..d34f0332c --- /dev/null +++ b/Zotlabs/ActivityStreams/AssertionMethod.php @@ -0,0 +1,87 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class AssertionMethod extends ASObject +{ + public $id; + public $type; + public $controller; + public $publicKeyMultibase; + + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + + /** + * @param mixed $id + * @return AssertionMethod + */ + public function setId($id) + { + $this->id = $id; + return $this; + } + + /** + * @return mixed + */ + public function getType() + { + return $this->type; + } + + /** + * @param mixed $type + * @return AssertionMethod + */ + public function setType($type) + { + $this->type = $type; + return $this; + } + + /** + * @return mixed + */ + public function getController() + { + return $this->controller; + } + + /** + * @param mixed $controller + * @return AssertionMethod + */ + public function setController($controller) + { + $this->controller = $controller; + return $this; + } + + /** + * @return mixed + */ + public function getPublicKeyMultibase() + { + return $this->publicKeyMultibase; + } + + /** + * @param mixed $publicKeyMultibase + * @return AssertionMethod + */ + public function setPublicKeyMultibase($publicKeyMultibase) + { + $this->publicKeyMultibase = $publicKeyMultibase; + return $this; + } + + + + +} diff --git a/Zotlabs/ActivityStreams/Collection.php b/Zotlabs/ActivityStreams/Collection.php new file mode 100644 index 000000000..f005166a8 --- /dev/null +++ b/Zotlabs/ActivityStreams/Collection.php @@ -0,0 +1,124 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Collection extends ASObject +{ + public int $totalItems; + public string $current; + public string $first; + public string $last; + public array $items; + + public mixed $collectionOf; + + /** + * @return int + */ + public function getTotalItems(): int + { + return $this->totalItems; + } + + /** + * @param mixed $totalItems + * @return Collection + */ + public function setTotalItems(mixed $totalItems): static + { + $this->totalItems = $totalItems; + return $this; + } + + /** + * @return string + */ + public function getCurrent(): string + { + return $this->current; + } + + /** + * @param mixed $current + * @return Collection + */ + public function setCurrent(mixed $current): static + { + $this->current = $current; + return $this; + } + + /** + * @return string + */ + public function getFirst(): string + { + return $this->first; + } + + /** + * @param mixed $first + * @return Collection + */ + public function setFirst(mixed $first): static + { + $this->first = $first; + return $this; + } + + /** + * @return string + */ + public function getLast(): string + { + return $this->last; + } + + /** + * @param mixed $last + * @return Collection + */ + public function setLast(mixed $last): static + { + $this->last = $last; + return $this; + } + + /** + * @return array + */ + public function getItems(): array + { + return $this->items; + } + + /** + * @param mixed $items + * @return Collection + */ + public function setItems(mixed $items): static + { + $this->items = $items; + return $this; + } + + /** + * @return mixed + */ + public function getCollectionOf(): mixed + { + return $this->collectionOf; + } + + /** + * @param mixed $collectionOf + * @return Collection + */ + public function setCollectionOf(mixed $collectionOf): static + { + $this->collectionOf = $collectionOf; + return $this; + } + + +} diff --git a/Zotlabs/ActivityStreams/CollectionPage.php b/Zotlabs/ActivityStreams/CollectionPage.php new file mode 100644 index 000000000..4bdedc93e --- /dev/null +++ b/Zotlabs/ActivityStreams/CollectionPage.php @@ -0,0 +1,73 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class CollectionPage extends Collection +{ + public $partOf; + public $next; + public $prev; + + // startIndex only applies for OrderedCollectionPage. See + // https://www.w3.org/ns/activitystreams#OrderedCollectionPage + // It is provided here to avoid multiple inheritance + + public $startIndex; + + /** + * @return mixed + */ + public function getPartOf() + { + return $this->partOf; + } + + /** + * @param mixed $partOf + * @return CollectionPage + */ + public function setPartOf($partOf) + { + $this->partOf = $partOf; + return $this; + } + + /** + * @return mixed + */ + public function getNext() + { + return $this->next; + } + + /** + * @param mixed $next + * @return CollectionPage + */ + public function setNext($next) + { + $this->next = $next; + return $this; + } + + /** + * @return mixed + */ + public function getPrev() + { + return $this->prev; + } + + /** + * @param mixed $prev + * @return CollectionPage + */ + public function setPrev($prev) + { + $this->prev = $prev; + return $this; + } + + + +} diff --git a/Zotlabs/ActivityStreams/IntransitiveActivity.php b/Zotlabs/ActivityStreams/IntransitiveActivity.php new file mode 100644 index 000000000..62e83f63c --- /dev/null +++ b/Zotlabs/ActivityStreams/IntransitiveActivity.php @@ -0,0 +1,104 @@ +<?php + +namespace Zotlabs\ActivityStreams; + + +class IntransitiveActivity extends ASObject +{ + public $actor; + public $target; + public $result; + public $origin; + public $instrument; + + /** + * @return mixed + */ + public function getActor() + { + return $this->actor; + } + + /** + * @param mixed $actor + * @return IntransitiveActivity + */ + public function setActor($actor) + { + $this->actor = $actor; + return $this; + } + + /** + * @return mixed + */ + public function getTarget() + { + return $this->target; + } + + /** + * @param mixed $target + * @return IntransitiveActivity + */ + public function setTarget($target) + { + $this->target = $target; + return $this; + } + + /** + * @return mixed + */ + public function getResult() + { + return $this->result; + } + + /** + * @param mixed $result + * @return IntransitiveActivity + */ + public function setResult($result) + { + $this->result = $result; + return $this; + } + + /** + * @return mixed + */ + public function getOrigin() + { + return $this->origin; + } + + /** + * @param mixed $origin + * @return IntransitiveActivity + */ + public function setOrigin($origin) + { + $this->origin = $origin; + return $this; + } + + /** + * @return mixed + */ + public function getInstrument() + { + return $this->instrument; + } + + /** + * @param mixed $instrument + * @return IntransitiveActivity + */ + public function setInstrument($instrument) + { + $this->instrument = $instrument; + return $this; + } + +} diff --git a/Zotlabs/ActivityStreams/Link.php b/Zotlabs/ActivityStreams/Link.php new file mode 100644 index 000000000..904b354da --- /dev/null +++ b/Zotlabs/ActivityStreams/Link.php @@ -0,0 +1,183 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +use Zotlabs\Lib\BaseObject; + +class Link extends BaseObject +{ + public $type; + public $href; + public $rel; + public $mediaType; + public $name; + public $hreflang; + public $height; + public $width; + public $preview; + + + + /** + * @return mixed + */ + public function getType() + { + return $this->type; + } + + /** + * @param mixed $type + * @return Link + */ + public function setType($type) + { + $this->type = $type; + return $this; + } + + /** + * @return mixed + */ + public function getHref() + { + return $this->href; + } + + /** + * @param mixed $href + * @return Link + */ + public function setHref($href) + { + $this->href = $href; + return $this; + } + + /** + * @return mixed + */ + public function getRel() + { + return $this->rel; + } + + /** + * @param mixed $rel + * @return Link + */ + public function setRel($rel) + { + $this->rel = $rel; + return $this; + } + + /** + * @return mixed + */ + public function getMediaType() + { + return $this->mediaType; + } + + /** + * @param mixed $mediaType + * @return Link + */ + public function setMediaType($mediaType) + { + $this->mediaType = $mediaType; + return $this; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->name; + } + + /** + * @param mixed $name + * @return Link + */ + public function setName($name) + { + $this->name = $name; + return $this; + } + + /** + * @return mixed + */ + public function getHreflang() + { + return $this->hreflang; + } + + /** + * @param mixed $hreflang + * @return Link + */ + public function setHreflang($hreflang) + { + $this->hreflang = $hreflang; + return $this; + } + + /** + * @return mixed + */ + public function getHeight() + { + return $this->height; + } + + /** + * @param mixed $height + * @return Link + */ + public function setHeight($height) + { + $this->height = $height; + return $this; + } + + /** + * @return mixed + */ + public function getWidth() + { + return $this->width; + } + + /** + * @param mixed $width + * @return Link + */ + public function setWidth($width) + { + $this->width = $width; + return $this; + } + + /** + * @return mixed + */ + public function getPreview() + { + return $this->preview; + } + + /** + * @param mixed $preview + * @return Link + */ + public function setPreview($preview) + { + $this->preview = $preview; + return $this; + } + +} diff --git a/Zotlabs/ActivityStreams/OrderedCollection.php b/Zotlabs/ActivityStreams/OrderedCollection.php new file mode 100644 index 000000000..95f5036f7 --- /dev/null +++ b/Zotlabs/ActivityStreams/OrderedCollection.php @@ -0,0 +1,8 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class OrderedCollection extends Collection +{ + +} diff --git a/Zotlabs/ActivityStreams/OrderedCollectionPage.php b/Zotlabs/ActivityStreams/OrderedCollectionPage.php new file mode 100644 index 000000000..664802eff --- /dev/null +++ b/Zotlabs/ActivityStreams/OrderedCollectionPage.php @@ -0,0 +1,92 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +/** + * According to the specification, OrderedCollectionPage extends + * both OrderedCollection and CollectionPage, but PHP is still a bit awkward + * when it comes to multiple inheritance. Rather than try and do this with + * traits, we'll just include the CollectionPage elements here - as this only + * consists of three properties. + */ + +class OrderedCollectionPage extends OrderedCollection +{ + public $partOf; + public $next; + public $prev; + public $startIndex; + + /** + * @return mixed + */ + public function getPartOf() + { + return $this->partOf; + } + + /** + * @param mixed $partOf + * @return OrderedCollectionPage + */ + public function setPartOf($partOf) + { + $this->partOf = $partOf; + return $this; + } + + /** + * @return mixed + */ + public function getNext() + { + return $this->next; + } + + /** + * @param mixed $next + * @return OrderedCollectionPage + */ + public function setNext($next) + { + $this->next = $next; + return $this; + } + + /** + * @return mixed + */ + public function getPrev() + { + return $this->prev; + } + + /** + * @param mixed $prev + * @return OrderedCollectionPage + */ + public function setPrev($prev) + { + $this->prev = $prev; + return $this; + } + + /** + * @return mixed + */ + public function getStartIndex() + { + return $this->startIndex; + } + + /** + * @param mixed $startIndex + * @return OrderedCollectionPage + */ + public function setStartIndex($startIndex) + { + $this->startIndex = $startIndex; + return $this; + } + +} diff --git a/Zotlabs/ActivityStreams/Place.php b/Zotlabs/ActivityStreams/Place.php new file mode 100644 index 000000000..5aadc1c73 --- /dev/null +++ b/Zotlabs/ActivityStreams/Place.php @@ -0,0 +1,125 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Place extends ASObject +{ + + public $accuracy; + public $altitude; + public $latitude; + public $longitude; + public $radius; + public $units; + + /** + * @return mixed + */ + public function getAccuracy() + { + return $this->accuracy; + } + + /** + * @param mixed $accuracy + * @return Place + */ + public function setAccuracy($accuracy) + { + $this->accuracy = $accuracy; + return $this; + } + + /** + * @return mixed + */ + public function getAltitude() + { + return $this->altitude; + } + + /** + * @param mixed $altitude + * @return Place + */ + public function setAltitude($altitude) + { + $this->altitude = $altitude; + return $this; + } + + /** + * @return mixed + */ + public function getLatitude() + { + return $this->latitude; + } + + /** + * @param mixed $latitude + * @return Place + */ + public function setLatitude($latitude) + { + $this->latitude = $latitude; + return $this; + } + + /** + * @return mixed + */ + public function getLongitude() + { + return $this->longitude; + } + + /** + * @param mixed $longitude + * @return Place + */ + public function setLongitude($longitude) + { + $this->longitude = $longitude; + return $this; + } + + /** + * @return mixed + */ + public function getRadius() + { + return $this->radius; + } + + /** + * @param mixed $radius + * @return Place + */ + public function setRadius($radius) + { + $this->radius = $radius; + return $this; + } + + /** + * @return mixed + */ + public function getUnits() + { + return $this->units; + } + + /** + * @param mixed $units + * @return Place + */ + public function setUnits($units) + { + $this->units = $units; + return $this; + } + + + +} diff --git a/Zotlabs/ActivityStreams/Profile.php b/Zotlabs/ActivityStreams/Profile.php new file mode 100644 index 000000000..817f4a817 --- /dev/null +++ b/Zotlabs/ActivityStreams/Profile.php @@ -0,0 +1,29 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Profile extends ASObject +{ + + public $describes; + + /** + * @return mixed + */ + public function getDescribes() + { + return $this->describes; + } + + /** + * @param mixed $describes + * @return Profile + */ + public function setDescribes($describes) + { + $this->describes = $describes; + return $this; + } + + +} diff --git a/Zotlabs/ActivityStreams/PublicKey.php b/Zotlabs/ActivityStreams/PublicKey.php new file mode 100644 index 000000000..d5e7b9522 --- /dev/null +++ b/Zotlabs/ActivityStreams/PublicKey.php @@ -0,0 +1,68 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class PublicKey extends ASObject +{ + public $owner; + public $signatureAlgorithm; + public $publicKeyPem; + + /** + * @return mixed + */ + public function getOwner() + { + return $this->owner; + } + + /** + * @param mixed $owner + * @return PublicKey + */ + public function setOwner($owner) + { + $this->owner = $owner; + return $this; + } + + /** + * @return mixed + */ + public function getSignatureAlgorithm() + { + return $this->signatureAlgorithm; + } + + /** + * @param mixed $signatureAlgorithm + * @return PublicKey + */ + public function setSignatureAlgorithm($signatureAlgorithm) + { + $this->signatureAlgorithm = $signatureAlgorithm; + return $this; + } + + /** + * @return mixed + */ + public function getPublicKeyPem() + { + return $this->publicKeyPem; + } + + /** + * @param mixed $publicKeyPem + * @return PublicKey + */ + public function setPublicKeyPem($publicKeyPem) + { + $this->publicKeyPem = $publicKeyPem; + return $this; + } + + + + +} diff --git a/Zotlabs/ActivityStreams/Question.php b/Zotlabs/ActivityStreams/Question.php new file mode 100644 index 000000000..63f642eaa --- /dev/null +++ b/Zotlabs/ActivityStreams/Question.php @@ -0,0 +1,67 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Question extends ASObject +{ + public $oneOf; + public $anyOf; + public $closed; + + /** + * @return mixed + */ + public function getOneOf() + { + return $this->oneOf; + } + + /** + * @param mixed $oneOf + * @return Question + */ + public function setOneOf($oneOf) + { + $this->oneOf = $oneOf; + return $this; + } + + /** + * @return mixed + */ + public function getAnyOf() + { + return $this->anyOf; + } + + /** + * @param mixed $anyOf + * @return Question + */ + public function setAnyOf($anyOf) + { + $this->anyOf = $anyOf; + return $this; + } + + /** + * @return mixed + */ + public function getClosed() + { + return $this->closed; + } + + /** + * @param mixed $closed + * @return Question + */ + public function setClosed($closed) + { + $this->closed = $closed; + return $this; + } + + + +} diff --git a/Zotlabs/ActivityStreams/Relationship.php b/Zotlabs/ActivityStreams/Relationship.php new file mode 100644 index 000000000..29669a200 --- /dev/null +++ b/Zotlabs/ActivityStreams/Relationship.php @@ -0,0 +1,67 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Relationship extends ASObject +{ + public $subject; + public $object; + public $relationship; + + /** + * @return mixed + */ + public function getSubject() + { + return $this->subject; + } + + /** + * @param mixed $subject + * @return Relationship + */ + public function setSubject($subject) + { + $this->subject = $subject; + return $this; + } + + /** + * @return mixed + */ + public function getObject() + { + return $this->object; + } + + /** + * @param mixed $object + * @return Relationship + */ + public function setObject($object) + { + $this->object = $object; + return $this; + } + + /** + * @return mixed + */ + public function getRelationship() + { + return $this->relationship; + } + + /** + * @param mixed $relationship + * @return Relationship + */ + public function setRelationship($relationship) + { + $this->relationship = $relationship; + return $this; + } + + + +} diff --git a/Zotlabs/ActivityStreams/Signature.php b/Zotlabs/ActivityStreams/Signature.php new file mode 100644 index 000000000..e115dd331 --- /dev/null +++ b/Zotlabs/ActivityStreams/Signature.php @@ -0,0 +1,65 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Signature extends ASObject +{ + public $nonce; + public $creator; + public $signatureValue; + + /** + * @return mixed + */ + public function getCreator() + { + return $this->creator; + } + + /** + * @param mixed $creator + * @return Signature + */ + public function setCreator($creator) + { + $this->creator = $creator; + return $this; + } + + /** + * @return mixed + */ + public function getSignatureValue() + { + return $this->signatureValue; + } + + /** + * @param mixed $signatureValue + * @return Signature + */ + public function setSignatureValue($signatureValue) + { + $this->signatureValue = $signatureValue; + return $this; + } + + /** + * @return mixed + */ + public function getNonce() + { + return $this->nonce; + } + + /** + * @param mixed $nonce + * @return Signature + */ + public function setNonce($nonce) + { + $this->nonce = $nonce; + return $this; + } + +} diff --git a/Zotlabs/ActivityStreams/Tombstone.php b/Zotlabs/ActivityStreams/Tombstone.php new file mode 100644 index 000000000..54a6ab76c --- /dev/null +++ b/Zotlabs/ActivityStreams/Tombstone.php @@ -0,0 +1,48 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class Tombstone extends ASObject +{ + public $formerType; + public $deleted; + + /** + * @return mixed + */ + public function getFormerType() + { + return $this->formerType; + } + + /** + * @param mixed $formerType + * @return Tombstone + */ + public function setFormerType($formerType) + { + $this->formerType = $formerType; + return $this; + } + + /** + * @return mixed + */ + public function getDeleted() + { + return $this->deleted; + } + + /** + * @param mixed $deleted + * @return Tombstone + */ + public function setDeleted($deleted) + { + $this->deleted = $deleted; + return $this; + } + + + +} diff --git a/Zotlabs/ActivityStreams/UnhandledElementException.php b/Zotlabs/ActivityStreams/UnhandledElementException.php new file mode 100644 index 000000000..f8b71693d --- /dev/null +++ b/Zotlabs/ActivityStreams/UnhandledElementException.php @@ -0,0 +1,8 @@ +<?php + +namespace Zotlabs\ActivityStreams; + +class UnhandledElementException extends \Exception +{ + +} diff --git a/Zotlabs/Daemon/Channel_purge.php b/Zotlabs/Daemon/Channel_purge.php index 9fceb0fb9..d25edf8ba 100644 --- a/Zotlabs/Daemon/Channel_purge.php +++ b/Zotlabs/Daemon/Channel_purge.php @@ -24,7 +24,7 @@ class Channel_purge { ); if ($r) { foreach ($r as $rv) { - drop_item($rv['id'], false); + drop_item($rv['id']); } } } while ($r); diff --git a/Zotlabs/Daemon/Content_importer.php b/Zotlabs/Daemon/Content_importer.php index 67f1c8e80..b98a1f10d 100644 --- a/Zotlabs/Daemon/Content_importer.php +++ b/Zotlabs/Daemon/Content_importer.php @@ -38,7 +38,13 @@ class Content_importer { $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512'); - $x = z_fetch_url($hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page,false,$redirects,[ 'headers' => $headers ]); + $redirects = 0; + $x = z_fetch_url( + $hz_server . '/api/z/1.0/item/export_page?f=&since=' . urlencode($since) . '&until=' . urlencode($until) . '&page=' . $page, + false, + $redirects, + [ 'headers' => $headers ] + ); // logger('item fetch: ' . print_r($x,true)); @@ -47,9 +53,9 @@ class Content_importer { killme(); } - $j = json_decode($x['body'],true); + $j = json_decode($x['body'], true); - if(! is_array($j['item']) || ! count($j['item'])) { + if($j && empty($j['item'])) { PConfig::Set($channel['channel_id'], 'import', 'content_completed', 1); return; } diff --git a/Zotlabs/Daemon/Cron.php b/Zotlabs/Daemon/Cron.php index 3f5ce28eb..186f3efcf 100644 --- a/Zotlabs/Daemon/Cron.php +++ b/Zotlabs/Daemon/Cron.php @@ -76,7 +76,8 @@ class Cron { if ($r) { require_once('include/items.php'); foreach ($r as $rr) { - drop_item($rr['id'], false, (($rr['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); + drop_item($rr['id'], (($rr['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL), uid: intval($rr['uid'])); + if ($rr['item_wall']) { // The notifier isn't normally invoked unless item_drop is interactive. Master::Summon(['Notifier', 'drop', $rr['id']]); diff --git a/Zotlabs/Daemon/Expire.php b/Zotlabs/Daemon/Expire.php index ad52a6b71..3ac3dee3a 100644 --- a/Zotlabs/Daemon/Expire.php +++ b/Zotlabs/Daemon/Expire.php @@ -29,7 +29,7 @@ class Expire { ); if ($r) { foreach ($r as $rr) { - drop_item($rr['id'], false, DROPITEM_PHASE2); + drop_item($rr['id'], DROPITEM_PHASE2); } } diff --git a/Zotlabs/Daemon/File_importer.php b/Zotlabs/Daemon/File_importer.php index 7067e152d..1ddab60f0 100644 --- a/Zotlabs/Daemon/File_importer.php +++ b/Zotlabs/Daemon/File_importer.php @@ -38,7 +38,13 @@ class File_importer { $headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),true,'sha512'); // TODO: implement total count - $x = z_fetch_url($hz_server . '/api/z/1.0/file/export_page?f=records=1&page=' . $page, false, $redirects, [ 'headers' => $headers ]); + $redirects = 0; + $x = z_fetch_url( + $hz_server . '/api/z/1.0/file/export_page?f=records=1&page=' . $page, + false, + $redirects, + [ 'headers' => $headers ] + ); // logger('file fetch: ' . print_r($x,true)); if(! $x['success']) { diff --git a/Zotlabs/Daemon/Importdoc.php b/Zotlabs/Daemon/Importdoc.php index c5a81e50c..8f04e05f8 100644 --- a/Zotlabs/Daemon/Importdoc.php +++ b/Zotlabs/Daemon/Importdoc.php @@ -18,9 +18,13 @@ class Importdoc { static public function update_docs_dir($s) { $f = basename($s); $d = dirname($s); - if ($s === 'doc/html') + + if ($s === 'doc/html') { return; + } + $files = glob("$d/$f"); + if ($files) { foreach ($files as $fi) { if ($fi === 'doc/html') { @@ -37,6 +41,18 @@ class Importdoc { } } } + + // remove old files that weren't updated (indicates they were most likely deleted). + $i = q("select * from item where item_type = 5 and edited < %s - %s", + db_utcnow(), + db_quoteinterval('14 DAY', true) + ); + + if ($i) { + foreach ($i as $iv) { + drop_item($iv['id'], DROPITEM_NORMAL, true); + } + } } } diff --git a/Zotlabs/Daemon/Notifier.php b/Zotlabs/Daemon/Notifier.php index 20134b8fe..1693f9c9f 100644 --- a/Zotlabs/Daemon/Notifier.php +++ b/Zotlabs/Daemon/Notifier.php @@ -299,7 +299,7 @@ class Notifier { return; } - if ($target_item['verb'] === ACTIVITY_SHARE) { + if (in_array($target_item['verb'], [ACTIVITY_SHARE])) { // Provide correct representation across the wire. Internally this is treated as a comment. $target_item['parent_mid'] = $target_item['thr_parent'] = $target_item['mid']; } @@ -374,7 +374,6 @@ class Notifier { if (($relay_to_owner || $uplink) && ($cmd !== 'relay')) { logger('notifier: followup relay', LOGGER_DEBUG); - // If the Parent item is an Announce the real owner is the parent author $sendto = (($uplink) ? $parent_item['source_xchan'] : $parent_item['owner_xchan']); self::$recipients = [$sendto]; self::$private = true; @@ -589,8 +588,6 @@ class Notifier { foreach ($dhubs as $hub) { - logger('notifier_hub: ' . $hub['hubloc_url'], LOGGER_DEBUG); - if ($hub['hubloc_network'] !== 'zot6') { $narr = [ 'channel' => self::$channel, diff --git a/Zotlabs/Entity/Account.php b/Zotlabs/Entity/Account.php new file mode 100644 index 000000000..2d3af5e4b --- /dev/null +++ b/Zotlabs/Entity/Account.php @@ -0,0 +1,352 @@ +<?php + +namespace Zotlabs\Entity; + +use Zotlabs\Lib\BaseObject; + +class Account extends BaseObject +{ + public $account_id; + public $account_parent; + public $account_default_channel; + public $account_salt; + public $account_password; + public $account_email; + public $account_external; + public $account_language; + public $account_created; + public $account_lastlog; + public $account_flags; + public $account_roles; + public $account_reset; + public $account_expires; + public $account_expire_notified; + public $account_service_class; + public $account_level; + public $account_password_change; + + /** + * @return mixed + */ + public function getId() + { + return $this->account_id; + } + + /** + * @param mixed $account_id + * @return Account + */ + public function setId($account_id) + { + $this->account_id = $account_id; + return $this; + } + + /** + * @return mixed + */ + public function getParent() + { + return $this->account_parent; + } + + /** + * @param mixed $account_parent + * @return Account + */ + public function setParent($account_parent) + { + $this->account_parent = $account_parent; + return $this; + } + + /** + * @return mixed + */ + public function getDefaultChannel() + { + return $this->account_default_channel; + } + + /** + * @param mixed $account_default_channel + * @return Account + */ + public function setDefaultChannel($account_default_channel) + { + $this->account_default_channel = $account_default_channel; + return $this; + } + + /** + * @return mixed + */ + public function getSalt() + { + return $this->account_salt; + } + + /** + * @param mixed $account_salt + * @return Account + */ + public function setSalt($account_salt) + { + $this->account_salt = $account_salt; + return $this; + } + + /** + * @return mixed + */ + public function getPassword() + { + return $this->account_password; + } + + /** + * @param mixed $account_password + * @return Account + */ + public function setPassword($account_password) + { + $this->account_password = $account_password; + return $this; + } + + /** + * @return mixed + */ + public function getEmail() + { + return $this->account_email; + } + + /** + * @param mixed $account_email + * @return Account + */ + public function setEmail($account_email) + { + $this->account_email = $account_email; + return $this; + } + + /** + * @return mixed + */ + public function getExternal() + { + return $this->account_external; + } + + /** + * @param mixed $account_external + * @return Account + */ + public function setExternal($account_external) + { + $this->account_external = $account_external; + return $this; + } + + /** + * @return mixed + */ + public function getLanguage() + { + return $this->account_language; + } + + /** + * @param mixed $account_language + * @return Account + */ + public function setLanguage($account_language) + { + $this->account_language = $account_language; + return $this; + } + + /** + * @return mixed + */ + public function getCreated() + { + return $this->account_created; + } + + /** + * @param mixed $account_created + * @return Account + */ + public function setCreated($account_created) + { + $this->account_created = $account_created; + return $this; + } + + /** + * @return mixed + */ + public function getLastlog() + { + return $this->account_lastlog; + } + + /** + * @param mixed $account_lastlog + * @return Account + */ + public function setLastlog($account_lastlog) + { + $this->account_lastlog = $account_lastlog; + return $this; + } + + /** + * @return mixed + */ + public function getFlags() + { + return $this->account_flags; + } + + /** + * @param mixed $account_flags + * @return Account + */ + public function setFlags($account_flags) + { + $this->account_flags = $account_flags; + return $this; + } + + /** + * @return mixed + */ + public function getRoles() + { + return $this->account_roles; + } + + /** + * @param mixed $account_roles + * @return Account + */ + public function setRoles($account_roles) + { + $this->account_roles = $account_roles; + return $this; + } + + /** + * @return mixed + */ + public function getReset() + { + return $this->account_reset; + } + + /** + * @param mixed $account_reset + * @return Account + */ + public function setReset($account_reset) + { + $this->account_reset = $account_reset; + return $this; + } + + /** + * @return mixed + */ + public function getExpires() + { + return $this->account_expires; + } + + /** + * @param mixed $account_expires + * @return Account + */ + public function setExpires($account_expires) + { + $this->account_expires = $account_expires; + return $this; + } + + /** + * @return mixed + */ + public function getExpireNotified() + { + return $this->account_expire_notified; + } + + /** + * @param mixed $account_expire_notified + * @return Account + */ + public function setExpireNotified($account_expire_notified) + { + $this->account_expire_notified = $account_expire_notified; + return $this; + } + + /** + * @return mixed + */ + public function getServiceClass() + { + return $this->account_service_class; + } + + /** + * @param mixed $account_service_class + * @return Account + */ + public function setServiceClass($account_service_class) + { + $this->account_service_class = $account_service_class; + return $this; + } + + /** + * @return mixed + */ + public function getLevel() + { + return $this->account_level; + } + + /** + * @param mixed $account_level + * @return Account + */ + public function setLevel($account_level) + { + $this->account_level = $account_level; + return $this; + } + + /** + * @return mixed + */ + public function getPasswordChange() + { + return $this->account_password_change; + } + + /** + * @param mixed $account_password_change + * @return Account + */ + public function setPasswordChange($account_password_change) + { + $this->account_password_change = $account_password_change; + return $this; + } + +} diff --git a/Zotlabs/Entity/Channel.php b/Zotlabs/Entity/Channel.php new file mode 100644 index 000000000..e9f7dc14f --- /dev/null +++ b/Zotlabs/Entity/Channel.php @@ -0,0 +1,714 @@ +<?php + +namespace Zotlabs\Entity; + +use Zotlabs\Lib\BaseObject; + +class Channel extends BaseObject +{ + public $channel_id; + public $channel_account_id; + public $channel_primary; + public $channel_name; + public $channel_parent; + public $channel_address; + public $channel_guid; + public $channel_guid_sig; + public $channel_hash; + public $channel_timezone; + public $channel_location; + public $channel_theme; + public $channel_startpage; + public $channel_pubkey; + public $channel_prvkey; + public $channel_epubkey; + public $channel_eprvkey; + public $channel_notifyflags; + public $channel_pageflags; + public $channel_dirdate; + public $channel_lastpost; + public $channel_deleted; + public $channel_active; + public $channel_max_anon_mail; + public $channel_max_friend_req; + public $channel_expire_days; + public $channel_passwd_reset; + public $channel_default_group; + public $channel_allow_cid; + public $channel_allow_gid; + public $channel_deny_cid; + public $channel_deny_gid; + public $channel_removed; + public $channel_system; + public $channel_moved; + public $channel_password; + public $channel_salt; + + /** + * @return mixed + */ + public function getId() + { + return $this->channel_id; + } + + /** + * @param mixed $channel_id + * @return Channel + */ + public function setId($channel_id) + { + $this->channel_id = $channel_id; + return $this; + } + + /** + * @return mixed + */ + public function getAccountId() + { + return $this->channel_account_id; + } + + /** + * @param mixed $channel_account_id + * @return Channel + */ + public function setAccountId($channel_account_id) + { + $this->channel_account_id = $channel_account_id; + return $this; + } + + /** + * @return mixed + */ + public function getPrimary() + { + return $this->channel_primary; + } + + /** + * @param mixed $channel_primary + * @return Channel + */ + public function setPrimary($channel_primary) + { + $this->channel_primary = $channel_primary; + return $this; + } + + /** + * @return mixed + */ + public function getName() + { + return $this->channel_name; + } + + /** + * @param mixed $channel_name + * @return Channel + */ + public function setName($channel_name) + { + $this->channel_name = $channel_name; + return $this; + } + + /** + * @return mixed + */ + public function getParent() + { + return $this->channel_parent; + } + + /** + * @param mixed $channel_parent + * @return Channel + */ + public function setParent($channel_parent) + { + $this->channel_parent = $channel_parent; + return $this; + } + + /** + * @return mixed + */ + public function getAddress() + { + return $this->channel_address; + } + + /** + * @param mixed $channel_address + * @return Channel + */ + public function setAddress($channel_address) + { + $this->channel_address = $channel_address; + return $this; + } + + /** + * @return mixed + */ + public function getGuid() + { + return $this->channel_guid; + } + + /** + * @param mixed $channel_guid + * @return Channel + */ + public function setGuid($channel_guid) + { + $this->channel_guid = $channel_guid; + return $this; + } + + /** + * @return mixed + */ + public function getGuidSig() + { + return $this->channel_guid_sig; + } + + /** + * @param mixed $channel_guid_sig + * @return Channel + */ + public function setGuidSig($channel_guid_sig) + { + $this->channel_guid_sig = $channel_guid_sig; + return $this; + } + + /** + * @return mixed + */ + public function getHash() + { + return $this->channel_hash; + } + + /** + * @param mixed $channel_hash + * @return Channel + */ + public function setHash($channel_hash) + { + $this->channel_hash = $channel_hash; + return $this; + } + + /** + * @return mixed + */ + public function getTimezone() + { + return $this->channel_timezone; + } + + /** + * @param mixed $channel_timezone + * @return Channel + */ + public function setTimezone($channel_timezone) + { + $this->channel_timezone = $channel_timezone; + return $this; + } + + /** + * @return mixed + */ + public function getLocation() + { + return $this->channel_location; + } + + /** + * @param mixed $channel_location + * @return Channel + */ + public function setLocation($channel_location) + { + $this->channel_location = $channel_location; + return $this; + } + + /** + * @return mixed + */ + public function getTheme() + { + return $this->channel_theme; + } + + /** + * @param mixed $channel_theme + * @return Channel + */ + public function setTheme($channel_theme) + { + $this->channel_theme = $channel_theme; + return $this; + } + + /** + * @return mixed + */ + public function getStartpage() + { + return $this->channel_startpage; + } + + /** + * @param mixed $channel_startpage + * @return Channel + */ + public function setStartpage($channel_startpage) + { + $this->channel_startpage = $channel_startpage; + return $this; + } + + /** + * @return mixed + */ + public function getPubkey() + { + return $this->channel_pubkey; + } + + /** + * @param mixed $channel_pubkey + * @return Channel + */ + public function setPubkey($channel_pubkey) + { + $this->channel_pubkey = $channel_pubkey; + return $this; + } + + /** + * @return mixed + */ + public function getPrvkey() + { + return $this->channel_prvkey; + } + + /** + * @param mixed $channel_prvkey + * @return Channel + */ + public function setPrvkey($channel_prvkey) + { + $this->channel_prvkey = $channel_prvkey; + return $this; + } + + /** + * @return mixed + */ + public function getEpubkey() + { + return $this->channel_epubkey; + } + + /** + * @param mixed $channel_epubkey + * @return Channel + */ + public function setEpubkey($channel_epubkey) + { + $this->channel_epubkey = $channel_epubkey; + return $this; + } + + /** + * @return mixed + */ + public function getEprvkey() + { + return $this->channel_eprvkey; + } + + /** + * @param mixed $channel_eprvkey + * @return Channel + */ + public function setEprvkey($channel_eprvkey) + { + $this->channel_eprvkey = $channel_eprvkey; + return $this; + } + + + /** + * @return mixed + */ + public function getNotifyflags() + { + return $this->channel_notifyflags; + } + + /** + * @param mixed $channel_notifyflags + * @return Channel + */ + public function setNotifyflags($channel_notifyflags) + { + $this->channel_notifyflags = $channel_notifyflags; + return $this; + } + + /** + * @return mixed + */ + public function getPageflags() + { + return $this->channel_pageflags; + } + + /** + * @param mixed $channel_pageflags + * @return Channel + */ + public function setPageflags($channel_pageflags) + { + $this->channel_pageflags = $channel_pageflags; + return $this; + } + + /** + * @return mixed + */ + public function getDirdate() + { + return $this->channel_dirdate; + } + + /** + * @param mixed $channel_dirdate + * @return Channel + */ + public function setDirdate($channel_dirdate) + { + $this->channel_dirdate = $channel_dirdate; + return $this; + } + + /** + * @return mixed + */ + public function getLastpost() + { + return $this->channel_lastpost; + } + + /** + * @param mixed $channel_lastpost + * @return Channel + */ + public function setLastpost($channel_lastpost) + { + $this->channel_lastpost = $channel_lastpost; + return $this; + } + + /** + * @return mixed + */ + public function getDeleted() + { + return $this->channel_deleted; + } + + /** + * @param mixed $channel_deleted + * @return Channel + */ + public function setDeleted($channel_deleted) + { + $this->channel_deleted = $channel_deleted; + return $this; + } + + /** + * @return mixed + */ + public function getActive() + { + return $this->channel_active; + } + + /** + * @param mixed $channel_active + * @return Channel + */ + public function setActive($channel_active) + { + $this->channel_active = $channel_active; + return $this; + } + + /** + * @return mixed + */ + public function getMaxAnonMail() + { + return $this->channel_max_anon_mail; + } + + /** + * @param mixed $channel_max_anon_mail + * @return Channel + */ + public function setMaxAnonMail($channel_max_anon_mail) + { + $this->channel_max_anon_mail = $channel_max_anon_mail; + return $this; + } + + /** + * @return mixed + */ + public function getMaxFriendReq() + { + return $this->channel_max_friend_req; + } + + /** + * @param mixed $channel_max_friend_req + * @return Channel + */ + public function setMaxFriendReq($channel_max_friend_req) + { + $this->channel_max_friend_req = $channel_max_friend_req; + return $this; + } + + /** + * @return mixed + */ + public function getExpireDays() + { + return $this->channel_expire_days; + } + + /** + * @param mixed $channel_expire_days + * @return Channel + */ + public function setExpireDays($channel_expire_days) + { + $this->channel_expire_days = $channel_expire_days; + return $this; + } + + /** + * @return mixed + */ + public function getPasswdReset() + { + return $this->channel_passwd_reset; + } + + /** + * @param mixed $channel_passwd_reset + * @return Channel + */ + public function setPasswdReset($channel_passwd_reset) + { + $this->channel_passwd_reset = $channel_passwd_reset; + return $this; + } + + /** + * @return mixed + */ + public function getDefaultGroup() + { + return $this->channel_default_group; + } + + /** + * @param mixed $channel_default_group + * @return Channel + */ + public function setDefaultGroup($channel_default_group) + { + $this->channel_default_group = $channel_default_group; + return $this; + } + + /** + * @return mixed + */ + public function getAllowCid() + { + return $this->channel_allow_cid; + } + + /** + * @param mixed $channel_allow_cid + * @return Channel + */ + public function setAllowCid($channel_allow_cid) + { + $this->channel_allow_cid = $channel_allow_cid; + return $this; + } + + /** + * @return mixed + */ + public function getAllowGid() + { + return $this->channel_allow_gid; + } + + /** + * @param mixed $channel_allow_gid + * @return Channel + */ + public function setAllowGid($channel_allow_gid) + { + $this->channel_allow_gid = $channel_allow_gid; + return $this; + } + + /** + * @return mixed + */ + public function getDenyCid() + { + return $this->channel_deny_cid; + } + + /** + * @param mixed $channel_deny_cid + * @return Channel + */ + public function setDenyCid($channel_deny_cid) + { + $this->channel_deny_cid = $channel_deny_cid; + return $this; + } + + /** + * @return mixed + */ + public function getDenyGid() + { + return $this->channel_deny_gid; + } + + /** + * @param mixed $channel_deny_gid + * @return Channel + */ + public function setDenyGid($channel_deny_gid) + { + $this->channel_deny_gid = $channel_deny_gid; + return $this; + } + + /** + * @return mixed + */ + public function getRemoved() + { + return $this->channel_removed; + } + + /** + * @param mixed $channel_removed + * @return Channel + */ + public function setRemoved($channel_removed) + { + $this->channel_removed = $channel_removed; + return $this; + } + + /** + * @return mixed + */ + public function getSystem() + { + return $this->channel_system; + } + + /** + * @param mixed $channel_system + * @return Channel + */ + public function setSystem($channel_system) + { + $this->channel_system = $channel_system; + return $this; + } + + /** + * @return mixed + */ + public function getMoved() + { + return $this->channel_moved; + } + + /** + * @param mixed $channel_moved + * @return Channel + */ + public function setMoved($channel_moved) + { + $this->channel_moved = $channel_moved; + return $this; + } + + /** + * @return mixed + */ + public function getPassword() + { + return $this->channel_password; + } + + /** + * @param mixed $channel_password + * @return Channel + */ + public function setPassword($channel_password) + { + $this->channel_password = $channel_password; + return $this; + } + + /** + * @return mixed + */ + public function getSalt() + { + return $this->channel_salt; + } + + /** + * @param mixed $channel_salt + * @return Channel + */ + public function setSalt($channel_salt) + { + $this->channel_salt = $channel_salt; + return $this; + } + +} diff --git a/Zotlabs/Entity/Item.php b/Zotlabs/Entity/Item.php new file mode 100644 index 000000000..9e4bb5ee8 --- /dev/null +++ b/Zotlabs/Entity/Item.php @@ -0,0 +1,1534 @@ +<?php + +namespace Zotlabs\Entity; + +use Zotlabs\Lib\BaseObject; + +class Item extends BaseObject +{ + // primary index auto-increment + public $id; + // id of the thread top-level parent + public $parent; + + // account id of the owner of this record + public $aid; + // channel id of the owner of this record + public $uid; + + // UUID-V4 // If no UUID is provided UUID-V5 of the message id + public $uuid; + + // message id + public $mid; + + // message id of top-level parent + public $parent_mid; + // message id of immediate parent + public $thr_parent; + + // int thread depth + public $item_level; + + // url pointing to the local copy of this item + public $llink; + + // url pointing to permalink or this item origin + public $plink; + + // UTC datetime the item was created + public $created; + // UTC datetime the item was changed + public $edited; + // UTC datetime the item will self-destruct + public $expires; + // UTC datetime last comment + public $commented; + // UTC datetime received here + public $received; + // UTC datetime this record last modified + public $changed; + // UTC datetime comments will be refused + public $comments_closed; + + // portable id of channel that initiated this conversation thread + public $owner_xchan; + // portable id of item creator + public $author_xchan; + // portable id of real (upstream) author if relayed + public $source_xchan; + // MIME type of item body + public $mimetype; + + // ISO language string + public $lang; + // Name of publishing software + public $app; + // Title of item + public $title; + // Sommary of item + public $summary; + // body of item + public $body; + // html representation + public $html; + // Activity type + public $verb; + // Activity object type + public $obj_type; + // Activity object content JSON + public $obj; + // Activity target type + public $tgt_type; + // Activity target content JSON + public $target; + // attachments + public $attach; + // signature information + public $sig; + + // version of this item + public $revision; + // message id of controlling layout (CMS use) + public $layout_mid; + // shared storage for delivery addons + public $postopts; + // delivery relay tracking + public $route; + // UUID of attached resource + public $resource_id; + // table type of attacched resource + public $resource_type; + + // free-form text location + public $location; + // combined coordinates (text) + public $coord; + // string public policy + public $public_policy; + // string comment policy + public $comment_policy; + // string encoded array of portable ids + public $allow_cid; + // string encoded array of access group UUIDs + public $allow_gid; + // string encoded array blocked portable ids + public $deny_cid; + // string encoded array blocked access group UUIDs + public $deny_gid; + public $item_restrict; + public $item_flags; + public $item_private; + public $item_origin; + public $item_unseen; + public $item_starred; + public $item_uplink; + public $item_consensus; + public $item_wall; + public $item_thread_top; + public $item_notshown; + public $item_nsfw; + public $item_relay; + public $item_mentionsme; + public $item_nocomment; + public $item_obscured; + public $item_verified; + public $item_retained; + public $item_rss; + public $item_deleted; + public $item_type; + public $item_hidden; + public $item_unpublished; + public $item_delayed; + public $item_pending_remove; + public $item_blocked; + + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + + /** + * @param mixed $id + * @return Item + */ + public function setId($id) + { + $this->id = $id; + return $this; + } + + /** + * @return mixed + */ + public function getMid() + { + return $this->mid; + } + + /** + * @param mixed $mid + * @return Item + */ + public function setMid($mid) + { + $this->mid = $mid; + return $this; + } + + /** + * @return mixed + */ + public function getUuid() + { + return $this->uuid; + } + + /** + * @param mixed $uuid + * @return Item + */ + public function setUuid($uuid) + { + $this->uuid = $uuid; + return $this; + } + + /** + * @return mixed + */ + public function getAid() + { + return $this->aid; + } + + /** + * @param mixed $aid + * @return Item + */ + public function setAid($aid) + { + $this->aid = $aid; + return $this; + } + + /** + * @return mixed + */ + public function getUid() + { + return $this->uid; + } + + /** + * @param mixed $uid + * @return Item + */ + public function setUid($uid) + { + $this->uid = $uid; + return $this; + } + + /** + * @return mixed + */ + public function getParent() + { + return $this->parent; + } + + /** + * @param mixed $parent + * @return Item + */ + public function setParent($parent) + { + $this->parent = $parent; + return $this; + } + + /** + * @return mixed + */ + public function getParentMid() + { + return $this->parent_mid; + } + + /** + * @param mixed $parent_mid + * @return Item + */ + public function setParentMid($parent_mid) + { + $this->parent_mid = $parent_mid; + return $this; + } + + /** + * @return mixed + */ + public function getThrParent() + { + return $this->thr_parent; + } + + /** + * @param mixed $thr_parent + * @return Item + */ + public function setThrParent($thr_parent) + { + $this->thr_parent = $thr_parent; + return $this; + } + + /** + * @return mixed + */ + public function getLevel() + { + return $this->item_level; + } + + /** + * @param mixed $item_level + * @return Item + */ + public function setLevel($item_level) + { + $this->item_level = $item_level; + return $this; + } + + /** + * @return mixed + */ + public function getCreated() + { + return $this->created; + } + + /** + * @param mixed $created + * @return Item + */ + public function setCreated($created) + { + $this->created = $created; + return $this; + } + + /** + * @return mixed + */ + public function getEdited() + { + return $this->edited; + } + + /** + * @param mixed $edited + * @return Item + */ + public function setEdited($edited) + { + $this->edited = $edited; + return $this; + } + + /** + * @return mixed + */ + public function getExpires() + { + return $this->expires; + } + + /** + * @param mixed $expires + * @return Item + */ + public function setExpires($expires) + { + $this->expires = $expires; + return $this; + } + + /** + * @return mixed + */ + public function getCommented() + { + return $this->commented; + } + + /** + * @param mixed $commented + * @return Item + */ + public function setCommented($commented) + { + $this->commented = $commented; + return $this; + } + + /** + * @return mixed + */ + public function getReceived() + { + return $this->received; + } + + /** + * @param mixed $received + * @return Item + */ + public function setReceived($received) + { + $this->received = $received; + return $this; + } + + /** + * @return mixed + */ + public function getChanged() + { + return $this->changed; + } + + /** + * @param mixed $changed + * @return Item + */ + public function setChanged($changed) + { + $this->changed = $changed; + return $this; + } + + /** + * @return mixed + */ + public function getCommentsClosed() + { + return $this->comments_closed; + } + + /** + * @param mixed $comments_closed + * @return Item + */ + public function setCommentsClosed($comments_closed) + { + $this->comments_closed = $comments_closed; + return $this; + } + + /** + * @return mixed + */ + public function getOwnerXchan() + { + return $this->owner_xchan; + } + + /** + * @param mixed $owner_xchan + * @return Item + */ + public function setOwnerXchan($owner_xchan) + { + $this->owner_xchan = $owner_xchan; + return $this; + } + + /** + * @return mixed + */ + public function getAuthorXchan() + { + return $this->author_xchan; + } + + /** + * @param mixed $author_xchan + * @return Item + */ + public function setAuthorXchan($author_xchan) + { + $this->author_xchan = $author_xchan; + return $this; + } + + /** + * @return mixed + */ + public function getSourceXchan() + { + return $this->source_xchan; + } + + /** + * @param mixed $source_xchan + * @return Item + */ + public function setSourceXchan($source_xchan) + { + $this->source_xchan = $source_xchan; + return $this; + } + + /** + * @return mixed + */ + public function getApproved() + { + return $this->approved; + } + + /** + * @param mixed $approved + * @return Item + */ + public function setApproved($approved) + { + $this->approved = $approved; + return $this; + } + + /** + * @return mixed + */ + public function getMimetype() + { + return $this->mimetype; + } + + /** + * @param mixed $mimetype + * @return Item + */ + public function setMimetype($mimetype) + { + $this->mimetype = $mimetype; + return $this; + } + + /** + * @return mixed + */ + public function getReplyto() + { + return $this->replyto; + } + + /** + * @param mixed $replyto + * @return Item + */ + public function setReplyto($replyto) + { + $this->replyto = $replyto; + return $this; + } + + /** + * @return mixed + */ + public function getTitle() + { + return $this->title; + } + + /** + * @param mixed $title + * @return Item + */ + public function setTitle($title) + { + $this->title = $title; + return $this; + } + + /** + * @return mixed + */ + public function getSummary() + { + return $this->summary; + } + + /** + * @param mixed $summary + * @return Item + */ + public function setSummary($summary) + { + $this->summary = $summary; + return $this; + } + + /** + * @return mixed + */ + public function getBody() + { + return $this->body; + } + + /** + * @param mixed $body + * @return Item + */ + public function setBody($body) + { + $this->body = $body; + return $this; + } + + /** + * @return mixed + */ + public function getHtml() + { + return $this->html; + } + + /** + * @param mixed $html + * @return Item + */ + public function setHtml($html) + { + $this->html = $html; + return $this; + } + + /** + * @return mixed + */ + public function getApp() + { + return $this->app; + } + + /** + * @param mixed $app + * @return Item + */ + public function setApp($app) + { + $this->app = $app; + return $this; + } + + /** + * @return mixed + */ + public function getLang() + { + return $this->lang; + } + + /** + * @param mixed $lang + * @return Item + */ + public function setLang($lang) + { + $this->lang = $lang; + return $this; + } + + /** + * @return mixed + */ + public function getRevision() + { + return $this->revision; + } + + /** + * @param mixed $revision + * @return Item + */ + public function setRevision($revision) + { + $this->revision = $revision; + return $this; + } + + /** + * @return mixed + */ + public function getVerb() + { + return $this->verb; + } + + /** + * @param mixed $verb + * @return Item + */ + public function setVerb($verb) + { + $this->verb = $verb; + return $this; + } + + /** + * @return mixed + */ + public function getObjType() + { + return $this->obj_type; + } + + /** + * @param mixed $obj_type + * @return Item + */ + public function setObjType($obj_type) + { + $this->obj_type = $obj_type; + return $this; + } + + /** + * @return mixed + */ + public function getObj() + { + return $this->obj; + } + + /** + * @param mixed $obj + * @return Item + */ + public function setObj($obj) + { + $this->obj = $obj; + return $this; + } + + /** + * @return mixed + */ + public function getTgtType() + { + return $this->tgt_type; + } + + /** + * @param mixed $tgt_type + * @return Item + */ + public function setTgtType($tgt_type) + { + $this->tgt_type = $tgt_type; + return $this; + } + + /** + * @return mixed + */ + public function getTarget() + { + return $this->target; + } + + /** + * @param mixed $target + * @return Item + */ + public function setTarget($target) + { + $this->target = $target; + return $this; + } + + /** + * @return mixed + */ + public function getLayoutMid() + { + return $this->layout_mid; + } + + /** + * @param mixed $layout_mid + * @return Item + */ + public function setLayoutMid($layout_mid) + { + $this->layout_mid = $layout_mid; + return $this; + } + + /** + * @return mixed + */ + public function getPostopts() + { + return $this->postopts; + } + + /** + * @param mixed $postopts + * @return Item + */ + public function setPostopts($postopts) + { + $this->postopts = $postopts; + return $this; + } + + /** + * @return mixed + */ + public function getRoute() + { + return $this->route; + } + + /** + * @param mixed $route + * @return Item + */ + public function setRoute($route) + { + $this->route = $route; + return $this; + } + + /** + * @return mixed + */ + public function getLlink() + { + return $this->llink; + } + + /** + * @param mixed $llink + * @return Item + */ + public function setLlink($llink) + { + $this->llink = $llink; + return $this; + } + + /** + * @return mixed + */ + public function getPlink() + { + return $this->plink; + } + + /** + * @param mixed $plink + * @return Item + */ + public function setPlink($plink) + { + $this->plink = $plink; + return $this; + } + + /** + * @return mixed + */ + public function getResourceId() + { + return $this->resource_id; + } + + /** + * @param mixed $resource_id + * @return Item + */ + public function setResourceId($resource_id) + { + $this->resource_id = $resource_id; + return $this; + } + + /** + * @return mixed + */ + public function getResourceType() + { + return $this->resource_type; + } + + /** + * @param mixed $resource_type + * @return Item + */ + public function setResourceType($resource_type) + { + $this->resource_type = $resource_type; + return $this; + } + + /** + * @return mixed + */ + public function getAttach() + { + return $this->attach; + } + + /** + * @param mixed $attach + * @return Item + */ + public function setAttach($attach) + { + $this->attach = $attach; + return $this; + } + + /** + * @return mixed + */ + public function getSig() + { + return $this->sig; + } + + /** + * @param mixed $sig + * @return Item + */ + public function setSig($sig) + { + $this->sig = $sig; + return $this; + } + + /** + * @return mixed + */ + public function getLocation() + { + return $this->location; + } + + /** + * @param mixed $location + * @return Item + */ + public function setLocation($location) + { + $this->location = $location; + return $this; + } + + /** + * @return mixed + */ + public function getCoord() + { + return $this->coord; + } + + /** + * @param mixed $coord + * @return Item + */ + public function setCoord($coord) + { + $this->coord = $coord; + return $this; + } + + /** + * @return mixed + */ + public function getPublicPolicy() + { + return $this->public_policy; + } + + /** + * @param mixed $public_policy + * @return Item + */ + public function setPublicPolicy($public_policy) + { + $this->public_policy = $public_policy; + return $this; + } + + /** + * @return mixed + */ + public function getCommentPolicy() + { + return $this->comment_policy; + } + + /** + * @param mixed $comment_policy + * @return Item + */ + public function setCommentPolicy($comment_policy) + { + $this->comment_policy = $comment_policy; + return $this; + } + + /** + * @return mixed + */ + public function getAllowCid() + { + return $this->allow_cid; + } + + /** + * @param mixed $allow_cid + * @return Item + */ + public function setAllowCid($allow_cid) + { + $this->allow_cid = $allow_cid; + return $this; + } + + /** + * @return mixed + */ + public function getAllowGid() + { + return $this->allow_gid; + } + + /** + * @param mixed $allow_gid + * @return Item + */ + public function setAllowGid($allow_gid) + { + $this->allow_gid = $allow_gid; + return $this; + } + + /** + * @return mixed + */ + public function getDenyCid() + { + return $this->deny_cid; + } + + /** + * @param mixed $deny_cid + * @return Item + */ + public function setDenyCid($deny_cid) + { + $this->deny_cid = $deny_cid; + return $this; + } + + /** + * @return mixed + */ + public function getDenyGid() + { + return $this->deny_gid; + } + + /** + * @param mixed $deny_gid + * @return Item + */ + public function setDenyGid($deny_gid) + { + $this->deny_gid = $deny_gid; + return $this; + } + + /** + * @return mixed + */ + public function getRestrict() + { + return $this->item_restrict; + } + + /** + * @param mixed $item_restrict + * @return Item + */ + public function setRestrict($item_restrict) + { + $this->item_restrict = $item_restrict; + return $this; + } + + /** + * @return mixed + */ + public function getFlags() + { + return $this->item_flags; + } + + /** + * @param mixed $item_flags + * @return Item + */ + public function setFlags($item_flags) + { + $this->item_flags = $item_flags; + return $this; + } + + /** + * @return mixed + */ + public function getPrivate() + { + return $this->item_private; + } + + /** + * @param mixed $item_private + * @return Item + */ + public function setPrivate($item_private) + { + $this->item_private = $item_private; + return $this; + } + + /** + * @return mixed + */ + public function getOrigin() + { + return $this->item_origin; + } + + /** + * @param mixed $item_origin + * @return Item + */ + public function setOrigin($item_origin) + { + $this->item_origin = $item_origin; + return $this; + } + + /** + * @return mixed + */ + public function getUnseen() + { + return $this->item_unseen; + } + + /** + * @param mixed $item_unseen + * @return Item + */ + public function setUnseen($item_unseen) + { + $this->item_unseen = $item_unseen; + return $this; + } + + /** + * @return mixed + */ + public function getStarred() + { + return $this->item_starred; + } + + /** + * @param mixed $item_starred + * @return Item + */ + public function setStarred($item_starred) + { + $this->item_starred = $item_starred; + return $this; + } + + /** + * @return mixed + */ + public function getUplink() + { + return $this->item_uplink; + } + + /** + * @param mixed $item_uplink + * @return Item + */ + public function setUplink($item_uplink) + { + $this->item_uplink = $item_uplink; + return $this; + } + + /** + * @return mixed + */ + public function getConsensus() + { + return $this->item_consensus; + } + + /** + * @param mixed $item_consensus + * @return Item + */ + public function setConsensus($item_consensus) + { + $this->item_consensus = $item_consensus; + return $this; + } + + /** + * @return mixed + */ + public function getWall() + { + return $this->item_wall; + } + + /** + * @param mixed $item_wall + * @return Item + */ + public function setWall($item_wall) + { + $this->item_wall = $item_wall; + return $this; + } + + /** + * @return mixed + */ + public function getThreadTop() + { + return $this->item_thread_top; + } + + /** + * @param mixed $item_thread_top + * @return Item + */ + public function setThreadTop($item_thread_top) + { + $this->item_thread_top = $item_thread_top; + return $this; + } + + /** + * @return mixed + */ + public function getNotshown() + { + return $this->item_notshown; + } + + /** + * @param mixed $item_notshown + * @return Item + */ + public function setNotshown($item_notshown) + { + $this->item_notshown = $item_notshown; + return $this; + } + + /** + * @return mixed + */ + public function getNsfw() + { + return $this->item_nsfw; + } + + /** + * @param mixed $item_nsfw + * @return Item + */ + public function setNsfw($item_nsfw) + { + $this->item_nsfw = $item_nsfw; + return $this; + } + + /** + * @return mixed + */ + public function getRelay() + { + return $this->item_relay; + } + + /** + * @param mixed $item_relay + * @return Item + */ + public function setRelay($item_relay) + { + $this->item_relay = $item_relay; + return $this; + } + + /** + * @return mixed + */ + public function getMentionsme() + { + return $this->item_mentionsme; + } + + /** + * @param mixed $item_mentionsme + * @return Item + */ + public function setMentionsme($item_mentionsme) + { + $this->item_mentionsme = $item_mentionsme; + return $this; + } + + /** + * @return mixed + */ + public function getNocomment() + { + return $this->item_nocomment; + } + + /** + * @param mixed $item_nocomment + * @return Item + */ + public function setNocomment($item_nocomment) + { + $this->item_nocomment = $item_nocomment; + return $this; + } + + /** + * @return mixed + */ + public function getObscured() + { + return $this->item_obscured; + } + + /** + * @param mixed $item_obscured + * @return Item + */ + public function setObscured($item_obscured) + { + $this->item_obscured = $item_obscured; + return $this; + } + + /** + * @return mixed + */ + public function getVerified() + { + return $this->item_verified; + } + + /** + * @param mixed $item_verified + * @return Item + */ + public function setVerified($item_verified) + { + $this->item_verified = $item_verified; + return $this; + } + + /** + * @return mixed + */ + public function getRetained() + { + return $this->item_retained; + } + + /** + * @param mixed $item_retained + * @return Item + */ + public function setRetained($item_retained) + { + $this->item_retained = $item_retained; + return $this; + } + + /** + * @return mixed + */ + public function getRss() + { + return $this->item_rss; + } + + /** + * @param mixed $item_rss + * @return Item + */ + public function setRss($item_rss) + { + $this->item_rss = $item_rss; + return $this; + } + + /** + * @return mixed + */ + public function getDeleted() + { + return $this->item_deleted; + } + + /** + * @param mixed $item_deleted + * @return Item + */ + public function setDeleted($item_deleted) + { + $this->item_deleted = $item_deleted; + return $this; + } + + /** + * @return mixed + */ + public function getType() + { + return $this->item_type; + } + + /** + * @param mixed $item_type + * @return Item + */ + public function setType($item_type) + { + $this->item_type = $item_type; + return $this; + } + + /** + * @return mixed + */ + public function getHidden() + { + return $this->item_hidden; + } + + /** + * @param mixed $item_hidden + * @return Item + */ + public function setHidden($item_hidden) + { + $this->item_hidden = $item_hidden; + return $this; + } + + /** + * @return mixed + */ + public function getUnpublished() + { + return $this->item_unpublished; + } + + /** + * @param mixed $item_unpublished + * @return Item + */ + public function setUnpublished($item_unpublished) + { + $this->item_unpublished = $item_unpublished; + return $this; + } + + /** + * @return mixed + */ + public function getDelayed() + { + return $this->item_delayed; + } + + /** + * @param mixed $item_delayed + * @return Item + */ + public function setDelayed($item_delayed) + { + $this->item_delayed = $item_delayed; + return $this; + } + + /** + * @return mixed + */ + public function getPendingRemove() + { + return $this->item_pending_remove; + } + + /** + * @param mixed $item_pending_remove + * @return Item + */ + public function setPendingRemove($item_pending_remove) + { + $this->item_pending_remove = $item_pending_remove; + return $this; + } + + /** + * @return mixed + */ + public function getBlocked() + { + return $this->item_blocked; + } + + /** + * @param mixed $item_blocked + * @return Item + */ + public function setBlocked($item_blocked) + { + $this->item_blocked = $item_blocked; + return $this; + } + + + +} diff --git a/Zotlabs/Lib/Activity.php b/Zotlabs/Lib/Activity.php index 9a8ac4a39..54a1b8d2a 100644 --- a/Zotlabs/Lib/Activity.php +++ b/Zotlabs/Lib/Activity.php @@ -8,6 +8,7 @@ use Zotlabs\Access\PermissionRoles; use Zotlabs\Access\Permissions; use Zotlabs\Daemon\Master; use Zotlabs\Web\HTTPSig; +use Zotlabs\Entity\Item; require_once('include/event.php'); require_once('include/html2plain.php'); @@ -598,6 +599,25 @@ class Activity { if ($i['mid'] !== $i['parent_mid']) { $ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); + + $cnv = IConfig::Get($i['parent'], 'activitypub', 'context'); + if (!$cnv) { + $cnv = $i['parent_mid']; + } + } + + if (empty($cnv)) { + $cnv = IConfig::Get($i, 'activitypub', 'context'); + if (!$cnv) { + $cnv = $i['parent_mid']; + } + } + + if (!empty($cnv)) { + if (is_string($cnv) && str_starts_with($cnv, z_root())) { + $cnv = str_replace(['/item/', '/activity/'], ['/conversation/', '/conversation/'], $cnv); + } + $ret['context'] = $cnv; } if ($i['mimetype'] === 'text/bbcode') { @@ -617,6 +637,12 @@ class Activity { $t = self::encode_taxonomy($i); if ($t) { + foreach($t as $tag) { + if (strcasecmp($tag['name'], '#nsfw') === 0 || strcasecmp($tag['name'], '#sensitive') === 0) { + $ret['sensitive'] = true; + } + } + $ret['tag'] = $t; } @@ -624,7 +650,20 @@ class Activity { if ($a) { $ret['attachment'] = $a; } - +/* + if ($i['target']) { + if (is_string($i['target'])) { + $tmp = json_decode($i['target'], true); + if ($tmp !== null) { + $i['target'] = $tmp; + } + } + $tgt = self::encode_object($i['target']); + if ($tgt) { + $ret['target'] = $tgt; + } + } +*/ if (intval($i['item_private']) === 0) { $ret['to'] = [ACTIVITY_PUBLIC_INBOX]; } @@ -843,12 +882,32 @@ class Activity { $ret['type'] = self::activity_mapper($i['verb']); if ((isset($i['item_deleted']) && intval($i['item_deleted'])) && !$recurse) { - $is_response = false; - if (ActivityStreams::is_response_activity($ret['type'])) { + if ($i['verb'] === 'Add' && str_contains($i['tgt_type'], 'Collection')) { + $ret['id'] = str_replace('/item/', '/activity/', $i['mid']) . '#Remove'; + $ret['type'] = 'Remove'; + if (is_string($i['obj'])) { + $obj = json_decode($i['obj'], true); + } + elseif(is_array($i['obj'])) { + $obj = $i['obj']; + } + if (isset($obj['id'])) { + $ret['object'] = $obj['id']; + } + else { + $ret['object'] = str_replace('/item/', '/activity/', $i['mid']); + } + $ret['target'] = is_array($i['target']) ? $i['target'] : json_decode($i['target'], true); + + return $ret; + } + + $is_response = ActivityStreams::is_response_activity($ret['type']); + + if ($is_response) { $ret['type'] = 'Undo'; $fragment = 'undo'; - $is_response = true; } else { $ret['type'] = 'Delete'; @@ -971,9 +1030,28 @@ class Activity { // inReplyTo needs to be set in the activity for followup actions (Like, Dislike, Announce, etc.), // but *not* for comments and RSVPs, where it should only be present in the object - if (!in_array($ret['type'], ['Create', 'Update', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject'])) { + if (!in_array($ret['type'], ['Create', 'Update', 'Add', 'Remove', 'Accept', 'Reject', 'TentativeAccept', 'TentativeReject'])) { $ret['inReplyTo'] = ((strpos($i['thr_parent'], 'http') === 0) ? $i['thr_parent'] : z_root() . '/item/' . urlencode($i['thr_parent'])); } + + $cnv = IConfig::Get($i['parent'], 'activitypub', 'context'); + if (!$cnv) { + $cnv = $i['parent_mid']; + } + } + + if (empty($cnv)) { + $cnv = IConfig::Get($i, 'activitypub', 'context'); + if (!$cnv) { + $cnv = $i['parent_mid']; + } + } + + if (!empty($cnv)) { + if (is_string($cnv) && str_starts_with($cnv, z_root())) { + $cnv = str_replace(['/item/', '/activity/'], ['/conversation/', '/conversation/'], $cnv); + } + $ret['context'] = $cnv; } $actor = self::encode_person($i['author'], false); @@ -1046,6 +1124,7 @@ class Activity { call_hooks('encode_activity', $hookinfo); return $hookinfo['encoded']; + } // Returns an array of URLS for any mention tags found in the item array $i. @@ -1289,81 +1368,6 @@ class Activity { // return false; } - static function activity_decode_mapper($verb) { - - $acts = [ - 'http://activitystrea.ms/schema/1.0/post' => 'Create', - // 'http://activitystrea.ms/schema/1.0/share' => 'Announce', - 'http://activitystrea.ms/schema/1.0/update' => 'Update', - 'http://activitystrea.ms/schema/1.0/like' => 'Like', - 'http://activitystrea.ms/schema/1.0/favorite' => 'Like', - 'http://purl.org/zot/activity/dislike' => 'Dislike', - // 'http://activitystrea.ms/schema/1.0/tag' => 'Add', - 'http://activitystrea.ms/schema/1.0/follow' => 'Follow', - 'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow', - 'http://activitystrea.ms/schema/1.0/stop-following' => 'Unfollow', - 'http://purl.org/zot/activity/attendyes' => 'Accept', - 'http://purl.org/zot/activity/attendno' => 'Reject', - 'http://purl.org/zot/activity/attendmaybe' => 'TentativeAccept', - 'Announce' => 'Announce', - 'Invite' => 'Invite', - 'Delete' => 'Delete', - 'Undo' => 'Undo', - 'Add' => 'Add', - 'Remove' => 'Remove' - ]; - - call_hooks('activity_decode_mapper', $acts); - - foreach ($acts as $k => $v) { - if ($verb === $v) { - return $k; - } - } - - logger('Unmapped activity: ' . $verb); - return 'Create'; - - } - - static function activity_obj_decode_mapper($obj) { - - $objs = [ - 'http://activitystrea.ms/schema/1.0/note' => 'Note', - 'http://activitystrea.ms/schema/1.0/note' => 'Article', - 'http://activitystrea.ms/schema/1.0/comment' => 'Note', - 'http://activitystrea.ms/schema/1.0/person' => 'Person', - 'http://purl.org/zot/activity/profile' => 'Profile', - 'http://activitystrea.ms/schema/1.0/photo' => 'Image', - 'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon', - 'http://activitystrea.ms/schema/1.0/event' => 'Event', - 'http://purl.org/zot/activity/location' => 'Place', - 'http://purl.org/zot/activity/chessgame' => 'Game', - 'http://purl.org/zot/activity/tagterm' => 'zot:Tag', - 'http://purl.org/zot/activity/thing' => 'Object', - 'http://purl.org/zot/activity/file' => 'zot:File', - 'http://purl.org/zot/activity/mood' => 'zot:Mood', - 'Invite' => 'Invite', - 'Question' => 'Question', - 'Document' => 'Document', - 'Audio' => 'Audio', - 'Video' => 'Video', - 'Delete' => 'Delete', - 'Undo' => 'Undo' - ]; - - call_hooks('activity_obj_decode_mapper', $objs); - - foreach ($objs as $k => $v) { - if ($obj === $v) { - return $k; - } - } - - logger('Unmapped activity object: ' . $obj); - return 'Note'; - } - static function activity_obj_mapper($obj) { $objs = [ @@ -1642,9 +1646,9 @@ class Activity { } if (in_array($observer, [$r[0]['author_xchan'], $r[0]['owner_xchan']])) { - drop_item($r[0]['id'], false, (($r[0]['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); + drop_item($r[0]['id'], (($r[0]['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL), observer_hash: $observer); } elseif (in_array($act->actor['id'], [$r[0]['author_xchan'], $r[0]['owner_xchan']])) { - drop_item($r[0]['id'], false, (($r[0]['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); + drop_item($r[0]['id'], (($r[0]['item_wall']) ? DROPITEM_PHASE1 : DROPITEM_NORMAL)); } sync_an_item($channel['channel_id'], $r[0]['id']); @@ -1942,129 +1946,170 @@ class Activity { } - static function update_poll($item_id, $post) { + static function update_poll($pollItem, $response) { + + logger('updating poll'); + + $multi = false; - $multi = false; - $mid = $post['mid']; - $content = $post['title']; + if (!$pollItem) { + logger('no item'); + return false; + } - if (!$item_id) { + if (intval($pollItem['item_blocked']) === ITEM_MODERATED) { + logger('item blocked'); return false; } - if (intval($post['item_blocked']) === ITEM_MODERATED) { + $channel = channelx_by_n($pollItem['uid']); + if (!$channel) { + logger('no channel'); return false; } + $relatedItem = find_related($pollItem); + + $ids = (($relatedItem) ? $pollItem['id'] . ',' . $relatedItem['id'] : $pollItem['id']); + dbq("START TRANSACTION"); + // Using the provided items as is will produce desastrous race conditions + // in case of multiple choice polls - hence: - $item = q("SELECT * FROM item WHERE id = %d FOR UPDATE", - intval($item_id) - ); + $items = dbq("SELECT * FROM item WHERE id in ($ids) FOR UPDATE"); - if (!$item) { - dbq("COMMIT"); - return false; + foreach ($items as $item) { + if ($item['id'] === $pollItem['id']) { + $pollItem = $item; + } + if (!empty($relatedItem['id']) && $item['id'] === $relatedItem['id']) { + $relatedItem = $item; + } } - $item = $item[0]; + $o = json_decode($pollItem['obj'], true); - $o = json_decode($item['obj'], true); if ($o && array_key_exists('anyOf', $o)) { $multi = true; } - $r = q("select mid, title from item where parent_mid = '%s' and author_xchan = '%s'", - dbesc($item['mid']), - dbesc($post['author_xchan']) - ); + if ($response) { + $mid = $response['mid']; + $content = trim($response['title']); - // prevent any duplicate votes by same author for oneOf and duplicate votes with same author and same answer for anyOf + $r = q("select mid, title from item where parent_mid = '%s' and author_xchan = '%s' and mid != parent_mid ", + dbesc($pollItem['mid']), + dbesc($response['author_xchan']) + ); - if ($r) { - if ($multi) { - foreach ($r as $rv) { - if ($rv['title'] === $content && $rv['mid'] !== $mid) { - return false; + // prevent any duplicate votes by same author for oneOf and duplicate votes with same author and same answer for anyOf + + if ($r) { + if ($multi) { + foreach ($r as $rv) { + if (trim($rv['title']) === $content && $rv['mid'] !== $mid) { + logger('already voted multi'); + return false; + } } - } - } - else { - foreach ($r as $rv) { - if ($rv['mid'] !== $mid) { - return false; + } else { + foreach ($r as $rv) { + if ($rv['mid'] !== $mid && $content) { + logger('already voted'); + return false; + } } } } - } - $answer_found = false; - $found = false; - if ($multi) { - for ($c = 0; $c < count($o['anyOf']); $c++) { - if ($o['anyOf'][$c]['name'] === $content) { - $answer_found = true; - if (is_array($o['anyOf'][$c]['replies'])) { - foreach ($o['anyOf'][$c]['replies'] as $reply) { - if (is_array($reply) && array_key_exists('id', $reply) && $reply['id'] === $mid) { - $found = true; + $answer_found = false; + $foundPrevious = false; + if ($multi) { + for ($c = 0; $c < count($o['anyOf']); $c++) { + if (trim($o['anyOf'][$c]['name']) === $content) { + $answer_found = true; + + + if (is_array($o['anyOf'][$c]['replies'])) { + foreach ($o['anyOf'][$c]['replies'] as $reply) { + if (is_array($reply) && array_key_exists('id', $reply) && $reply['id'] === $mid) { + $foundPrevious = true; + } } } - } - if (!$found) { - $o['anyOf'][$c]['replies']['totalItems']++; - $o['anyOf'][$c]['replies']['items'][] = ['id' => $mid, 'type' => 'Note']; + if (!$foundPrevious) { + $o['anyOf'][$c]['replies']['totalItems']++; + $o['anyOf'][$c]['replies']['items'][] = ['id' => $mid, 'type' => 'Note']; + } } } - } - } - else { - for ($c = 0; $c < count($o['oneOf']); $c++) { - if ($o['oneOf'][$c]['name'] === $content) { - $answer_found = true; - if (is_array($o['oneOf'][$c]['replies'])) { - foreach ($o['oneOf'][$c]['replies'] as $reply) { - if (is_array($reply) && array_key_exists('id', $reply) && $reply['id'] === $mid) { - $found = true; + } else { + for ($c = 0; $c < count($o['oneOf']); $c++) { + if (trim($o['oneOf'][$c]['name']) === $content) { + $answer_found = true; + if (is_array($o['oneOf'][$c]['replies'])) { + foreach ($o['oneOf'][$c]['replies'] as $reply) { + if (is_array($reply) && array_key_exists('id', $reply) && $reply['id'] === $mid) { + $foundPrevious = true; + } } } - } - if (!$found) { - $o['oneOf'][$c]['replies']['totalItems']++; - $o['oneOf'][$c]['replies']['items'][] = ['id' => $mid, 'type' => 'Note']; + if (!$foundPrevious) { + $o['oneOf'][$c]['replies']['totalItems']++; + $o['oneOf'][$c]['replies']['items'][] = ['id' => $mid, 'type' => 'Note']; + } } } } } - logger('updated_poll: ' . print_r($o, true), LOGGER_DATA); - if ($answer_found && !$found) { - $u = q("update item set obj = '%s', edited = '%s' where id = %d", - dbesc(json_encode($o)), - dbesc(datetime_convert()), - intval($item['id']) - ); + if ($pollItem['comments_closed'] > NULL_DATE) { + if ($pollItem['comments_closed'] > datetime_convert()) { + $o['closed'] = datetime_convert('UTC', 'UTC', $pollItem['comments_closed'], ATOM_TIME); + // set this to force an update + $answer_found = true; + } + } - if ($u) { - dbq("COMMIT"); + // A change was made locally + if ($response && $answer_found && !$foundPrevious) { - if ($multi) { - // wait some seconds for possible multiple answers to be processed - // before calling the notifier - sleep(3); - } + // update this copy + $i = [$pollItem]; + xchan_query($i, true); + $i = fetch_post_tags($i); + $i[0]['obj'] = $o; - Master::Summon(['Notifier', 'wall-new', $item['id']]); - return true; - } + // create the new object + $newObj = self::build_packet(self::encode_activity($i[0]), $channel, true); - dbq("ROLLBACK"); + // and immediately update the db + $u = q("UPDATE item + SET obj = ( + CASE + WHEN item.id = %d THEN '%s' + WHEN item.id = %d THEN '%s' + END + ), + edited = '%s' + WHERE id IN ($ids)", + intval($pollItem['id']), + dbesc(json_encode($o)), + intval($relatedItem['id']), + dbesc($newObj), + dbesc(datetime_convert()) + ); + + dbq("COMMIT"); + Master::Summon(['Notifier', 'edit_post', $pollItem['id'], $response['mid']]); + if (!empty($relatedItem['id'])) { + Master::Summon(['Notifier', 'edit_post', $relatedItem['id'], $response['mid']]); + } } - dbq("COMMIT"); - return false; + return true; } static function decode_note($act) { @@ -2320,6 +2365,16 @@ class Activity { $s['obj']['actor'] = $s['obj']['actor']['id']; } + if (is_array($act->tgt) && $act->tgt) { + if (array_key_exists('type', $act->tgt)) { + $s['tgt_type'] = self::activity_obj_mapper($act->tgt['type']); + } + // We shouldn't need to store collection contents which could be large. We will often only require the meta-data + if (isset($s['tgt_type']) && str_contains($s['tgt_type'], 'Collection')) { + $s['target'] = ['id' => $act->tgt['id'], 'type' => $s['tgt_type'], 'attributedTo' => $act->tgt['attributedTo'] ?? $act->tgt['actor']]; + } + } + $generator = $act->get_property_obj('generator'); if ((!$generator) && (!$response_activity)) { $generator = $act->get_property_obj('generator', $act->obj); @@ -2903,6 +2958,10 @@ class Activity { // This isn't perfect but the best we can do for now. $item['comment_policy'] = ((isset($act->data['commentPolicy'])) ? $act->data['commentPolicy'] : 'authenticated'); + if (!empty($act->obj['context'])) { + IConfig::Set($item, 'activitypub', 'context', $act->obj['context'], 1); + } + IConfig::Set($item, 'activitypub', 'recips', $act->raw_recips); if (intval($act->sigok)) { @@ -3090,24 +3149,6 @@ class Activity { } $a = new ActivityStreams($n); - - logger($a->debug(), LOGGER_DATA); - - if (!$a->is_valid()) { - logger('not a valid activity'); - break; - } - - if (in_array($a->type, ['Add', 'Remove']) - && is_array($a->obj) - && array_key_exists('object', $a->obj) - && array_key_exists('actor', $a->obj) - && !empty($a->tgt)) { - - logger('unsupported collection operation', LOGGER_DEBUG); - return; - } - if ($a->type === 'Announce' && is_array($a->obj) && array_key_exists('object', $a->obj) && array_key_exists('actor', $a->obj)) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) @@ -3116,6 +3157,13 @@ class Activity { $a = new ActivityStreams($a->obj); } + logger($a->debug(), LOGGER_DATA); + + if (!$a->is_valid()) { + logger('not a valid activity'); + break; + } + $item = Activity::decode_note($a); if (!$item) { @@ -3723,5 +3771,72 @@ class Activity { } } + public static function addToCollection($channel, $object, $target, $sourceItem = null, $deliver = true) { + if (!isset($channel['xchan_hash'])) { + $channel = channelx_by_hash($channel['channel_hash']); + } + + $item = ((new Item()) + ->setUid($channel['channel_id']) + ->setVerb('Add') + ->setAuthorXchan($channel['channel_hash']) + ->setOwnerXchan($channel['channel_hash']) + ->setObj($object) + ->setObjType($object['type']) + ->setParentMid(str_replace('/conversation/','/item/', $target)) + ->setThrParent(str_replace('/conversation/','/item/', $target)) + // ->setApproved($object['object']['id'] ?? '') + // ->setReplyto(z_root() . '/channel/' . $channel['channel_address']) + ->setTgtType('Collection') + ->setTarget([ + 'id' => str_replace('/item/','/conversation/', $target), + 'type' => 'Collection', + 'attributedTo' => z_root() . '/channel/' . $channel['channel_address'], + ]) + ); + if ($sourceItem) { + $item->setSourceXchan($sourceItem['source_xchan']) + ->setAllowCid($sourceItem['allow_cid']) + ->setAllowGid($sourceItem['allow_gid']) + ->setDenyCid($sourceItem['deny_cid']) + ->setDenyGid($sourceItem['deny_gid']) + ->setPrivate($sourceItem['item_private']) + ->setNocomment($sourceItem['item_nocomment']) + ->setCommentPolicy($sourceItem['comment_policy']) + ->setPublicPolicy($sourceItem['public_policy']) + ->setPostopts($sourceItem['postopts']); + } + $result = post_activity_item($item->toArray(), deliver: $deliver, channel: $channel, observer: $channel, addAndSync: false); + logger('addToCollection: ' . print_r($result, true)); + return $result; + } + + public static function removeFromCollection($channel, $object, $target, $deliver = true) { + if (!isset($channel['xchan_hash'])) { + $channel = channelx_by_hash($channel['channel_hash']); + } + + $item = ((new Item()) + ->setUid($channel['channel_id']) + ->setVerb('Remove') + ->setAuthorXchan($channel['channel_hash']) + ->setOwnerXchan($channel['channel_hash']) + ->setObj($object) + ->setObjType($object['type']) + ->setParentMid(str_replace('/conversation/','/item/', $target)) + ->setThrParent(str_replace('/conversation/','/item/', $target)) + ->setReplyto(z_root() . '/channel/' . $channel['channel_address']) + ->setTgtType('Collection') + ->setTarget([ + 'id' => str_replace('/item/','/conversation/', $target), + 'type' => 'Collection', + 'attributedTo' => z_root() . '/channel/' . $channel['channel_address'] + ]) + ); + + $result = post_activity_item($item->toArray(), deliver: $deliver, channel: $channel, observer: $channel, addAndSync: false); + logger('removeFromCollection: ' . print_r($result, true)); + return $result; + } } diff --git a/Zotlabs/Lib/BaseObject.php b/Zotlabs/Lib/BaseObject.php new file mode 100644 index 000000000..7125d34cb --- /dev/null +++ b/Zotlabs/Lib/BaseObject.php @@ -0,0 +1,80 @@ +<?php + +namespace Zotlabs\Lib; + +use Zotlabs\ActivityStreams\UnhandledElementException; + +class BaseObject +{ + + public $string; + public $ldContext; + + /** + * @param $input + * @param $strict + * @throws UnhandledElementException if $strict + */ + + public function __construct($input = null, $strict = false) + { + if (isset($input)) { + if (is_string($input)) { + $this->string = $input; + } + elseif(is_array($input)) { + foreach ($input as $key => $value) { + $key = ($key === '@context') ? 'ldContext' : $key; + if ($strict && !property_exists($this, $key)) { + throw new UnhandledElementException("Unhandled element: $key"); + } + $this->{$key} = $value; + } + } + } + return $this; + } + + public function getDataType($element, $object = null) + { + $object = $object ?? $this; + $type = gettype($object[$element]); + if ($type === 'array' && array_is_list($object[$element])) { + return 'list'; + } + return $type; + } + + public function toArray() + { + if ($this->string) { + return $this->string; + } + $returnValue = []; + foreach ((array) $this as $key => $value) { + if (isset($value)) { + $key = ($key === 'ldContext') ? '@context' : $key; + $returnValue[$key] = (($value instanceof BaseObject) ? $value->toArray() : $value); + } + } + return $returnValue; + } + + /** + * @return mixed + */ + public function getLdContext() + { + return $this->ldContext; + } + + /** + * @param mixed $ldContext + * @return BaseObject + */ + public function setLdContext($ldContext) + { + $this->ldContext = $ldContext; + return $this; + } +} diff --git a/Zotlabs/Lib/Chatroom.php b/Zotlabs/Lib/Chatroom.php index 34853b6ab..ee16d0002 100644 --- a/Zotlabs/Lib/Chatroom.php +++ b/Zotlabs/Lib/Chatroom.php @@ -181,7 +181,7 @@ class Chatroom { } - function leave($observer_xchan, $room_id, $client) { + public static function leave($observer_xchan, $room_id, $client) { if(! $room_id || ! $observer_xchan) return; diff --git a/Zotlabs/Lib/Enotify.php b/Zotlabs/Lib/Enotify.php index 121ad9b09..245d137fb 100644 --- a/Zotlabs/Lib/Enotify.php +++ b/Zotlabs/Lib/Enotify.php @@ -406,6 +406,7 @@ class Enotify { } elseif (isset($params['type']) && $params['type'] === NOTIFY_TAGSHARE) { + $itemlink = $params['link']; $subject = sprintf( t('[$Projectname:Notify] %s tagged your post') , $sender['xchan_name']); $preamble = sprintf( t('%1$s tagged your post at %2$s'),$sender['xchan_name'], $sitename); $epreamble = sprintf( t('%1$s tagged [zrl=%2$s]your post[/zrl]') , @@ -415,7 +416,6 @@ class Enotify { $sitelink = t('Please visit %s to view and/or reply to the conversation.'); $tsitelink = sprintf( $sitelink, $siteurl ); $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>'); - $itemlink = $params['link']; } elseif (isset($params['type']) && $params['type'] === NOTIFY_INTRO) { @@ -433,6 +433,7 @@ class Enotify { } elseif (isset($params['type']) && $params['type'] === NOTIFY_SUGGEST) { + $itemlink = $params['link']; $subject = sprintf( t('[$Projectname:Notify] Friend suggestion received')); $preamble = sprintf( t('You\'ve received a friend suggestion from \'%1$s\' at %2$s'), $sender['xchan_name'], $sitename); $epreamble = sprintf( t('You\'ve received [zrl=%1$s]a friend suggestion[/zrl] for %2$s from %3$s.'), @@ -447,7 +448,6 @@ class Enotify { $sitelink = t('Please visit %s to approve or reject the suggestion.'); $tsitelink = sprintf( $sitelink, $siteurl ); $hsitelink = sprintf( $sitelink, '<a href="' . $siteurl . '">' . $sitename . '</a>'); - $itemlink = $params['link']; } elseif (isset($params['type']) && $params['type'] === NOTIFY_CONFIRM) { diff --git a/Zotlabs/Lib/Libzot.php b/Zotlabs/Lib/Libzot.php index 05134f433..be2305c04 100644 --- a/Zotlabs/Lib/Libzot.php +++ b/Zotlabs/Lib/Libzot.php @@ -1134,6 +1134,7 @@ class Libzot { } $message_request = false; + $is_collection_operation = false; $has_data = array_key_exists('data', $env) && $env['data']; @@ -1141,26 +1142,37 @@ class Libzot { $AS = null; + if ($env['encoding'] === 'activitystreams') { $AS = new ActivityStreams($data); - if (!$AS->is_valid()) { - logger('Activity rejected: ' . print_r($data, true)); - return; - } + // process add/remove from collection separately, as it requires a target. + // use the raw object, as it will not include actor expansion if (in_array($AS->type, ['Add', 'Remove']) && is_array($AS->obj) && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj) && !empty($AS->tgt)) { - logger('unsupported collection operation', LOGGER_DEBUG); - return; + logger('relayed collection operation', LOGGER_DEBUG); + $is_collection_operation = true; + + $original_id = $AS->id; + $original_type = $AS->type; + + $raw_activity = $AS->data; + + $AS = new ActivityStreams($raw_activity['object'], portable_id: $env['sender']); + + // Store the original activity id and type for later usage + $AS->meta['original_id'] = $original_id; + $AS->meta['original_type'] = $original_type; } if (is_array($AS->obj)) { $item = Activity::decode_note($AS); + if (!$item) { logger('Could not decode activity: ' . print_r($AS, true)); return; @@ -1170,6 +1182,11 @@ class Libzot { $item = []; } + if (!$AS->is_valid()) { + logger('Activity rejected: ' . print_r($data, true)); + return; + } + logger($AS->debug(), LOGGER_DATA); } @@ -1313,7 +1330,7 @@ class Libzot { $relay = (($env['type'] === 'response') ? true : false); - $result = self::process_delivery($env['sender'], $AS, $item, $deliveries, $relay, false, $message_request); + $result = self::process_delivery($env['sender'], $AS, $item, $deliveries, $relay, false, $message_request, false, $is_collection_operation); Activity::init_background_fetch($env['sender']); } @@ -1529,7 +1546,7 @@ class Libzot { * @return array */ - static function process_delivery($sender, $act, $arr, $deliveries, $relay, $public = false, $request = false, $force = false) { + static function process_delivery($sender, $act, $arr, $deliveries, $relay, $public = false, $request = false, $force = false, $is_collection_operation = false) { $result = []; // We've validated the sender. Now make sure that the sender is the owner or author @@ -1557,6 +1574,14 @@ class Libzot { $DR->set_name($channel['channel_name'] . ' <' . channel_reddress($channel) . '>'); + $conversation_operation = $is_collection_operation && isset($arr['target']['attributedTo']); + + if (str_contains($arr['tgt_type'], 'Collection') && !$relay && !$conversation_operation) { + $DR->update('not a collection activity'); + $result[] = $DR->get(); + continue; + } + if (($act) && ($act->obj) && (!is_array($act->obj))) { // The initial object fetch failed using the sys channel credentials. // Try again using the delivery channel credentials. @@ -1590,6 +1615,8 @@ class Libzot { * */ + + if ($sender === $channel['channel_hash'] && $arr['author_xchan'] === $channel['channel_hash'] && !str_starts_with($arr['mid'], z_root())) { $DR->update('self delivery ignored'); $result[] = $DR->get(); @@ -1838,11 +1865,19 @@ class Libzot { dbesc($arr['author_xchan']) ); - // reactions such as like and dislike could have an mid with /activity/ in it. + // If we import an add/remove activity ($is_collection_operation) we strip off the + // add/remove part and only process the object. + // When looking up the item to pass it to the notifier for relay, we need to look up + // the original (stripped off) message id which we stored in $act->meta. + + $sql_mid = (($is_collection_operation && $relay && $channel['channel_hash'] === $arr['owner_xchan']) ? $act->meta['original_id'] : $arr['mid']); + + // Reactions such as like and dislike could have an mid with /activity/ in it. // Check for both forms in order to prevent duplicates. - $r = q("select * from item where mid in ('%s','%s') and uid = %d limit 1", - dbesc($arr['mid']), - dbesc(str_replace(z_root() . '/activity/', z_root() . '/item/', $arr['mid'])), + + $r = q("select * from item where mid in ('%s', '%s') and uid = %d limit 1", + dbesc($sql_mid), + dbesc(reverse_activity_mid($sql_mid)), intval($channel['channel_id']) ); @@ -1871,21 +1906,29 @@ class Libzot { $DR->update('update ignored'); $result[] = $DR->get(); } + + if ($relay && $channel['channel_hash'] === $item_result['item']['owner_xchan'] && $item_result['item']['verb'] !== 'Add' && !$is_collection_operation) { + $approval = Activity::addToCollection($channel, $act->data, $item_result['item']['parent_mid'], $item_result['item'], deliver: false); + } + } else { $DR->update('update ignored'); $result[] = $DR->get(); - // We need this line to ensure wall-to-wall comments are relayed (by falling through to the relay bit), + // We need this line to ensure wall-to-wall comments and add/remove activities are relayed (by falling through to the relay bit), // and at the same time not relay any other relayable posts more than once, because to do so is very wasteful. if (!intval($r[0]['item_origin'])) continue; } + + } else { $arr['aid'] = $channel['channel_account_id']; $arr['uid'] = $channel['channel_id']; + // if it's a sourced post, call the post_local hooks as if it were // posted locally so that crosspost connectors will be triggered. $item_source = check_item_source($arr['uid'], $arr); @@ -1914,10 +1957,15 @@ class Libzot { } if (post_is_importable($arr['uid'], $arr, $abook)) { - $item_result = item_store($arr); + $item_result = item_store($arr, addAndSync: false); + if ($item_result['success']) { $item_id = $item_result['item_id']; + if ($relay && $channel['channel_hash'] === $item_result['item']['owner_xchan'] && $item_result['item']['verb'] !== 'Add' && !$is_collection_operation) { + $approval = Activity::addToCollection($channel, $act->data, $item_result['item']['parent_mid'], $item_result['item'], deliver: false); + } + if ($item_source && in_array($item_result['item']['obj_type'], ['Event', ACTIVITY_OBJ_EVENT])) { event_addtocal($item_id, $channel['channel_id']); } @@ -1966,6 +2014,10 @@ class Libzot { if ($relay && $item_id && $stored['item_blocked'] !== ITEM_MODERATED) { logger('Invoking relay'); Master::Summon(['Notifier', 'relay', intval($item_id)]); + if (!empty($approval) && $approval['item_id']) { + Master::Summon(['Notifier', 'relay', intval($approval['item_id'])]); + } + $DR->addto_update('relayed'); $result[] = $DR->get(); } @@ -2019,12 +2071,7 @@ class Libzot { $AS = new ActivityStreams($activity); - if (!$AS->is_valid()) { - logger('Fetched activity rejected: ' . print_r($activity, true)); - continue; - } - - if ($AS->type === 'Announce' && is_array($AS->obj) + if ($AS->is_valid() && $AS->type === 'Announce' && is_array($AS->obj) && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj)) { // This is a relayed/forwarded Activity (as opposed to a shared/boosted object) // Reparse the encapsulated Activity and use that instead @@ -2032,14 +2079,33 @@ class Libzot { $AS = new ActivityStreams($AS->obj); } + // process add/remove from collection separately, as it requires a target. + // use the raw object, as it will not include actor expansion if (in_array($AS->type, ['Add', 'Remove']) && is_array($AS->obj) && array_key_exists('object', $AS->obj) && array_key_exists('actor', $AS->obj) && !empty($AS->tgt)) { - logger('unsupported collection operation', LOGGER_DEBUG); - return; + logger('relayed collection operation', LOGGER_DEBUG); + + $is_collection_operation = true; + + $original_id = $AS->id; + $original_type = $AS->type; + + $raw_activity = $AS->data; + + $AS = new ActivityStreams($raw_activity['object'], portable_id: $env['sender']); + + // Store the original activity id and type for later usage + $AS->meta['original_id'] = $original_id; + $AS->meta['original_type'] = $original_type; + } + + if (!$AS->is_valid()) { + logger('Fetched activity rejected: ' . print_r($activity, true)); + continue; } // logger($AS->debug()); @@ -2230,7 +2296,7 @@ class Libzot { } - $x = item_store_update($item); + $x = item_store_update($item, addAndSync: false); // If we're updating an event that we've saved locally, we store the item info first // because event_addtocal will parse the body to get the 'new' event details @@ -2346,21 +2412,20 @@ class Libzot { ); } } else { - if ($stored['id'] !== $stored['parent']) { - q( - "update item set commented = '%s', changed = '%s' where id = %d", - dbesc(datetime_convert()), - dbesc(datetime_convert()), - intval($stored['parent']) - ); - } - } + if ($stored['id'] !== $stored['parent']) { + q("update item set commented = '%s', changed = '%s' where id = %d", + dbesc(datetime_convert()), + dbesc(datetime_convert()), + intval($stored['parent']) + ); + } + } // Use phased deletion to set the deleted flag, call both tag_deliver and the notifier to notify downstream channels // and then clean up after ourselves with a cron job after several days to do the delete_item_lowlevel() (DROPITEM_PHASE2). - drop_item($post_id, false, DROPITEM_PHASE1); + drop_item($post_id, DROPITEM_PHASE1, uid: $uid); tag_deliver($uid, $post_id); } diff --git a/Zotlabs/Lib/SuperCurl.php b/Zotlabs/Lib/SuperCurl.php deleted file mode 100644 index 462a62b36..000000000 --- a/Zotlabs/Lib/SuperCurl.php +++ /dev/null @@ -1,127 +0,0 @@ -<?php - -namespace Zotlabs\Lib; - -/** - * @brief wrapper for z_fetch_url() which can be instantiated with several built-in parameters and - * these can be modified and re-used. Useful for CalDAV and other processes which need to authenticate - * and set lots of CURL options (many of which stay the same from one call to the next). - */ - - - - -class SuperCurl { - - - private $auth; - private $url; - - private $curlopt = array(); - - private $headers = null; - public $filepos = 0; - public $filehandle = 0; - public $request_data = ''; - - private $request_method = 'GET'; - private $upload = false; - private $cookies = false; - - - private function set_data($s) { - $this->request_data = $s; - $this->filepos = 0; - } - - public function curl_read($ch,$fh,$size) { - - if($this->filepos < 0) { - unset($fh); - return ''; - } - - $s = substr($this->request_data,$this->filepos,$size); - - if(strlen($s) < $size) - $this->filepos = (-1); - else - $this->filepos = $this->filepos + $size; - - return $s; - } - - - public function __construct($opts = array()) { - $this->set($opts); - } - - private function set($opts = array()) { - if($opts) { - foreach($opts as $k => $v) { - switch($k) { - case 'http_auth': - $this->auth = $v; - break; - case 'magicauth': - // currently experimental - $this->magicauth = $v; - \Zotlabs\Daemon\Master::Summon([ 'CurlAuth', $v ]); - break; - case 'custom': - $this->request_method = $v; - break; - case 'url': - $this->url = $v; - break; - case 'data': - $this->set_data($v); - if($v) { - $this->upload = true; - } - else { - $this->upload = false; - } - break; - case 'headers': - $this->headers = $v; - break; - default: - $this->curlopts[$k] = $v; - break; - } - } - } - } - - function exec() { - $opts = $this->curlopts; - $url = $this->url; - if($this->auth) - $opts['http_auth'] = $this->auth; - if($this->magicauth) { - $opts['cookiejar'] = 'store/[data]/cookie_' . $this->magicauth; - $opts['cookiefile'] = 'store/[data]/cookie_' . $this->magicauth; - $opts['cookie'] = 'PHPSESSID=' . trim(file_get_contents('store/[data]/cookien_' . $this->magicauth)); - $c = channelx_by_n($this->magicauth); - if($c) - $url = zid($this->url,channel_reddress($c)); - } - if($this->custom) - $opts['custom'] = $this->custom; - if($this->headers) - $opts['headers'] = $this->headers; - if($this->upload) { - $opts['upload'] = true; - $opts['infile'] = $this->filehandle; - $opts['infilesize'] = strlen($this->request_data); - $opts['readfunc'] = [ $this, 'curl_read' ] ; - } - - $recurse = 0; - return z_fetch_url($this->url,true,$recurse,(($opts) ? $opts : null)); - - } - - -} diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php index d21d85105..90a3d3fc8 100644 --- a/Zotlabs/Lib/ThreadItem.php +++ b/Zotlabs/Lib/ThreadItem.php @@ -544,7 +544,8 @@ class ThreadItem { 'moderate_delete' => t('Delete'), 'rtl' => in_array($item['lang'], rtl_languages()), 'reactions_allowed' => $reactions_allowed, - 'reaction_str' => [t('Add yours'), t('Remove yours')] + 'reaction_str' => [t('Add yours'), t('Remove yours')], + 'is_contained' => $this->is_toplevel() && str_contains($item['tgt_type'], 'Collection') ); $arr = array('item' => $item, 'output' => $tmp_item); diff --git a/Zotlabs/Module/Achievements.php b/Zotlabs/Module/Achievements.php index 1529448d3..a16294039 100644 --- a/Zotlabs/Module/Achievements.php +++ b/Zotlabs/Module/Achievements.php @@ -8,25 +8,25 @@ class Achievements extends \Zotlabs\Web\Controller { // This doesn't work, so if (! is_developer()) return; - + if(argc() > 1) $which = argv(1); else { notice( t('Requested profile is not available.') . EOL ); return; } - + $profile = 0; - $profile = argv(1); + $profile = argv(1); profile_load($which,$profile); - + $r = q("select channel_id from channel where channel_address = '%s'", dbesc($which) ); if($r) { $owner = intval($r[0]['channel_id']); } - + $observer = \App::get_observer(); $ob_hash = (($observer) ? $observer['xchan_hash'] : ''); $perms = get_all_perms($owner,$ob_hash); @@ -34,60 +34,60 @@ class Achievements extends \Zotlabs\Web\Controller { notice( t('Permission denied.') . EOL); return; } - + $newmembertext = t('Some blurb about what to do when you\'re new here'); - - + + // By default, all badges are false $contactbadge = false; $profilebadge = false; $keywordsbadge = false; - + // Check number of contacts. Award a badge if over 10 - // We'll figure these out on each page load instead of + // We'll figure these out on each page load instead of // writing them to the DB because that will mean one needs // to retain their achievements - eg, you can't add // a bunch of channels just to get your badge, and then // delete them all again. If these become popular or // used in profiles or something, we may need to reconsider // and add a table for this - because this won't scale. - + $r = q("select * from abook where abook_channel = %d", intval($owner) ); - + if (count($r)) $contacts = count($r); // We're checking for 11 to adjust for the abook record for self if ($contacts >= 11) $contactbadge = true; - + // Check if an about field in the profile has been created. - + $r = q("select * from profile where uid = %d and about <> ''", intval($owner) ); - + if ($r) $profilebadge = 1; - + // Check if keywords have been set - + $r = q("select * from profile where uid = %d and keywords <> ''", intval($owner) ); - + if($r) $keywordsbadge = 1; - + return replace_macros(get_markup_template("achievements.tpl"), array( '$newmembertext' => $newmembertext, '$profilebadge' => $profilebadge, '$contactbadge' => $contactbadge, '$keywordsbadge' => $keywordsbadge, - '$channelsbadge' => $channelsbadge + '$channelsbadge' => null, )); - + } - + } diff --git a/Zotlabs/Module/Admin/Features.php b/Zotlabs/Module/Admin/Features.php index e0b3a3fd4..eb82ae1ff 100644 --- a/Zotlabs/Module/Admin/Features.php +++ b/Zotlabs/Module/Admin/Features.php @@ -59,14 +59,13 @@ class Features { } $tpl = get_markup_template("admin_settings_features.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("admin_manage_features"), '$title' => t('Manage Additional Features'), '$features' => $arr, '$submit' => t('Submit'), )); - - return $o; } } diff --git a/Zotlabs/Module/Admin/Site.php b/Zotlabs/Module/Admin/Site.php index abc56d298..9ef5dc20f 100644 --- a/Zotlabs/Module/Admin/Site.php +++ b/Zotlabs/Module/Admin/Site.php @@ -6,6 +6,8 @@ use Zotlabs\Lib\Config; class Site { + private string $eol; + private string $joo; /** * @brief POST handler for Admin Site Page. @@ -208,7 +210,6 @@ class Site { //Config::Set('system','force_queue_threshold', $force_queue); Config::Set('system','no_community_page', $no_community_page); - Config::Set('system','no_utf', $no_utf); Config::Set('system','sse_enabled', $sse_enabled); diff --git a/Zotlabs/Module/Authorize.php b/Zotlabs/Module/Authorize.php index c6709f602..b015c3284 100644 --- a/Zotlabs/Module/Authorize.php +++ b/Zotlabs/Module/Authorize.php @@ -9,7 +9,7 @@ class Authorize extends \Zotlabs\Web\Controller { function get() { if (! local_channel()) { return login(); - } + } else { $name = $_REQUEST['client_name']; @@ -25,7 +25,7 @@ class Authorize extends \Zotlabs\Web\Controller { $link = (($app['url']) ? '<a style="float: none;" href="' . $app['url'] . '">' . $app['name'] . '</a> ' : $app['name']); - $o .= replace_macros(get_markup_template('oauth_authorize.tpl'), [ + return replace_macros(get_markup_template('oauth_authorize.tpl'), [ '$title' => t('Authorize'), '$authorize' => sprintf( t('Do you authorize the app %s to access your channel data?'), $link ), '$app' => $app, @@ -35,7 +35,6 @@ class Authorize extends \Zotlabs\Web\Controller { '$redirect_uri' => (x($_REQUEST, 'redirect_uri') ? $_REQUEST['redirect_uri'] : ''), '$state' => (x($_REQUEST, 'state') ? $_REQUEST['state'] : ''), ]); - return $o; } } @@ -50,7 +49,7 @@ class Authorize extends \Zotlabs\Web\Controller { // TODO: The automatic client registration protocol below should adhere more // closely to "OAuth 2.0 Dynamic Client Registration Protocol" defined // at https://tools.ietf.org/html/rfc7591 - + // If no client_id was provided, generate a new one. if (x($_POST, 'client_id')) { $client_id = $_POST['client_id']; @@ -67,7 +66,7 @@ class Authorize extends \Zotlabs\Web\Controller { $request = \OAuth2\Request::createFromGlobals(); $response = new \OAuth2\Response(); - // Note, "sub" field must match type and content. $user_id is used to populate - make sure it's a string. + // Note, "sub" field must match type and content. $user_id is used to populate - make sure it's a string. $channel = channelx_by_n(local_channel()); $user_id = $channel['channel_id']; diff --git a/Zotlabs/Module/Authtest.php b/Zotlabs/Module/Authtest.php index d85af09dc..bf199ccf6 100644 --- a/Zotlabs/Module/Authtest.php +++ b/Zotlabs/Module/Authtest.php @@ -7,7 +7,7 @@ class Authtest extends \Zotlabs\Web\Controller { $auth_success = false; - $o .= '<h3>Magic-Auth Diagnostic</h3>'; + $o = '<h3>Magic-Auth Diagnostic</h3>'; if(! local_channel()) { notice( t('Permission denied.') . EOL); @@ -27,7 +27,7 @@ class Authtest extends \Zotlabs\Web\Controller { $_REQUEST['test'] = 1; $mod = new Magic(); - $x = $mod->init($a); + $x = $mod->init(); $o .= 'Local Setup returns: ' . print_r($x,true); diff --git a/Zotlabs/Module/Changeaddr.php b/Zotlabs/Module/Changeaddr.php index ed139c9f9..f8a045727 100644 --- a/Zotlabs/Module/Changeaddr.php +++ b/Zotlabs/Module/Changeaddr.php @@ -5,30 +5,30 @@ namespace Zotlabs\Module; class Changeaddr extends \Zotlabs\Web\Controller { function post() { - + if(! local_channel()) return; - + if($_SESSION['delegate']) return; - + if((! x($_POST,'qxz_password')) || (! strlen(trim($_POST['qxz_password'])))) return; - + if((! x($_POST,'verify')) || (! strlen(trim($_POST['verify'])))) return; - + if($_POST['verify'] !== $_SESSION['remove_account_verify']) return; - - + + $account = \App::get_account(); $channel = \App::get_channel(); - + $x = account_verify_password($account['account_email'],$_POST['qxz_password']); if(! ($x && $x['account'])) return; - + if($account['account_password_changed'] > NULL_DATE) { $d1 = datetime_convert('UTC','UTC','now - 48 hours'); if($account['account_password_changed'] > $d1) { @@ -36,7 +36,7 @@ class Changeaddr extends \Zotlabs\Web\Controller { return; } } - + $new_address = trim($_POST['newname']); if($new_address === $channel['channel_address']) @@ -55,23 +55,23 @@ class Changeaddr extends \Zotlabs\Web\Controller { channel_change_address($channel,$new_address); goaway(z_root() . '/changeaddr'); - + } - - + + function get() { - + if(! local_channel()) goaway(z_root()); - + $channel = \App::get_channel(); $hash = random_string(); - + $_SESSION['remove_account_verify'] = $hash; - + $tpl = get_markup_template('channel_rename.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$basedir' => z_root(), '$hash' => $hash, '$title' => t('Change channel nickname/address'), @@ -80,9 +80,5 @@ class Changeaddr extends \Zotlabs\Web\Controller { '$newname' => array('newname', t('New channel address'),$channel['channel_address'], ''), '$submit' => t('Rename Channel') )); - - return $o; - } - } diff --git a/Zotlabs/Module/Channel_calendar.php b/Zotlabs/Module/Channel_calendar.php index 289e3a734..30683404b 100644 --- a/Zotlabs/Module/Channel_calendar.php +++ b/Zotlabs/Module/Channel_calendar.php @@ -179,26 +179,14 @@ class Channel_calendar extends Controller { if ($post_tags) $datarray['term'] = $post_tags; - $item_id = event_store_item($datarray, $event); + $post = event_store_item($datarray, $event); - if ($item_id) { - $r = q("select * from item where id = %d", - intval($item_id) - ); - if ($r) { - xchan_query($r); - $sync_item = fetch_post_tags($r); - $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", - dbesc($r[0]['resource_id']), - intval($channel['channel_id']) - ); - if ($z) { - Libsync::build_sync_packet($channel['channel_id'], array('event_item' => array(encode_item($sync_item[0], true)), 'event' => $z)); - } - } + if (!empty($post['item_id'])) { + Master::Summon(['Notifier', 'event', $post['item_id']]); + } + if (!empty($post['approval_id'])) { + Master::Summon(['Notifier', 'event', $post['approval_id']]); } - - Master::Summon(array('Notifier', 'event', $item_id)); killme(); @@ -470,13 +458,14 @@ class Channel_calendar extends Controller { } else { // complex deletion that needs to propagate and be performed in phases - drop_item($i[0]['id'], true, DROPITEM_PHASE1); + drop_item($i[0]['id'], DROPITEM_PHASE1); $complex = true; } $ii = q("select * from item where id = %d", intval($i[0]['id']) ); + if ($ii) { xchan_query($ii); $sync_item = fetch_post_tags($ii); @@ -485,6 +474,9 @@ class Channel_calendar extends Controller { if ($complex) { tag_deliver($i[0]['uid'], $i[0]['id']); + if (intval($i[0]['item_wall'])) { + Master::Summon(['Notifier', 'drop', $i[0]['id']]); + } } } } diff --git a/Zotlabs/Module/Conversation.php b/Zotlabs/Module/Conversation.php index aa8349f55..c3e6ae5ec 100644 --- a/Zotlabs/Module/Conversation.php +++ b/Zotlabs/Module/Conversation.php @@ -16,7 +16,7 @@ class Conversation extends Controller { public function init() { - if (ActivityStreams::is_as_request()) { + if (ActivityStreams::is_as_request() || Libzot::is_zot_request()) { $item_id = argv(1); if (!$item_id) { @@ -77,7 +77,7 @@ class Conversation extends Controller { } } } - elseif (Config::get('system', 'require_authenticated_fetch', false)) { + elseif (Config::Get('system', 'require_authenticated_fetch', false)) { http_status_exit(403, 'Permission denied'); } diff --git a/Zotlabs/Module/Cover_photo.php b/Zotlabs/Module/Cover_photo.php index aa2464ac2..2d2ffd52d 100644 --- a/Zotlabs/Module/Cover_photo.php +++ b/Zotlabs/Module/Cover_photo.php @@ -371,7 +371,7 @@ class Cover_photo extends \Zotlabs\Web\Controller { $tpl = get_markup_template('cover_photo.tpl'); - $o .= replace_macros($tpl,array( + $output = replace_macros($tpl,array( '$user' => \App::$channel['channel_address'], '$info' => t('Your cover photo may be visible to anybody on the internet'), '$existing' => get_cover_photo(local_channel(),'array',PHOTO_RES_COVER_850), @@ -397,15 +397,15 @@ class Cover_photo extends \Zotlabs\Web\Controller { )); - call_hooks('cover_photo_content_end', $o); + call_hooks('cover_photo_content_end', $output); - return $o; + return $output; } else { $filename = \App::$data['imagecrop'] . '-3'; $resolution = 3; $tpl = get_markup_template("cropcover.tpl"); - $o .= replace_macros($tpl,array( + return replace_macros($tpl,array( '$filename' => $filename, '$profile' => intval($_REQUEST['profile']), '$resource' => \App::$data['imagecrop'] . '-3', @@ -415,7 +415,6 @@ class Cover_photo extends \Zotlabs\Web\Controller { '$form_security_token' => get_form_security_token("cover_photo"), '$done' => t('Done Editing') )); - return $o; } } diff --git a/Zotlabs/Module/Dav.php b/Zotlabs/Module/Dav.php index 96fe2c898..5254d436d 100644 --- a/Zotlabs/Module/Dav.php +++ b/Zotlabs/Module/Dav.php @@ -9,6 +9,7 @@ namespace Zotlabs\Module; use Sabre\DAV as SDAV; +use Zotlabs\Lib\Libzot; use Zotlabs\Storage; use Zotlabs\Web\HTTPSig; diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php index 451ddeb1f..090e0c92e 100644 --- a/Zotlabs/Module/Display.php +++ b/Zotlabs/Module/Display.php @@ -344,7 +344,12 @@ class Display extends Controller { '$profile_page' => xmlify(z_root() . '/display/' . gen_link_id($target_item['mid'])), )); - $x = [ 'xml' => $atom, 'channel' => $channel, 'observer_hash' => $observer_hash, 'params' => $params ]; + $x = [ + 'xml' => $atom, + 'channel' => $channel, + 'observer_hash' => $observer_hash, + 'params' => [], + ]; call_hooks('atom_feed_top',$x); $atom = $x['xml']; diff --git a/Zotlabs/Module/Fbrowser.php b/Zotlabs/Module/Fbrowser.php index 3bac81c5a..e8517e095 100644 --- a/Zotlabs/Module/Fbrowser.php +++ b/Zotlabs/Module/Fbrowser.php @@ -6,6 +6,8 @@ namespace Zotlabs\Module; * @author Fabio Comuni <fabrixxm@kirgroup.com> */ +use function Zotlabs\Render\template_escape; + require_once('include/photo/photo_driver.php'); /** diff --git a/Zotlabs/Module/Go.php b/Zotlabs/Module/Go.php index ec528fb1a..77a3ffac6 100644 --- a/Zotlabs/Module/Go.php +++ b/Zotlabs/Module/Go.php @@ -2,7 +2,7 @@ namespace Zotlabs\Module; -use Zorlabs\Lib\Config; +use Zotlabs\Lib\Config; class Go extends \Zotlabs\Web\Controller { @@ -19,7 +19,7 @@ class Go extends \Zotlabs\Web\Controller { function get() { if(! local_channel()) { - notify( t('This page is available only to site members') . EOL); + notice( t('This page is available only to site members') . EOL); } $channel = \App::get_channel(); diff --git a/Zotlabs/Module/Impel.php b/Zotlabs/Module/Impel.php index 869de2669..0e07ab71c 100644 --- a/Zotlabs/Module/Impel.php +++ b/Zotlabs/Module/Impel.php @@ -164,7 +164,7 @@ class Impel extends \Zotlabs\Web\Controller { $arr['id'] = $i[0]['id']; // don't update if it has the same timestamp as the original if($arr['edited'] > $i[0]['edited']) - $x = item_store_update($arr,$execflag); + $x = item_store_update($arr, $execflag , deliver: false, addAndSync: false); } else { if(($i) && (intval($i[0]['item_deleted']))) { @@ -175,7 +175,7 @@ class Impel extends \Zotlabs\Web\Controller { ); } else - $x = item_store($arr,$execflag); + $x = item_store($arr, $execflag, deliver: false, addAndSync: false); } if($x && $x['success']) { diff --git a/Zotlabs/Module/Import.php b/Zotlabs/Module/Import.php index 5ace4e72d..7aed6469e 100644 --- a/Zotlabs/Module/Import.php +++ b/Zotlabs/Module/Import.php @@ -534,6 +534,7 @@ class Import extends Controller { if ($api_path) { $parsed = parse_url($api_path); unset($parsed['path']); + unset($parsed['query']); // store the import host so we can manually kick off item/file sync later in case anything did not work out set_pconfig($channel['channel_id'], 'import', 'host', $parsed['host']); @@ -551,7 +552,7 @@ class Import extends Controller { $until = datetime_convert(date_default_timezone_get(), date_default_timezone_get(), 'now + 1 day'); //$poll_interval = Config::Get('system', 'poll_interval', 3); - $page = 0; + $page = 0; Master::Summon(['Content_importer', sprintf('%d', $page), $since, $until, $channel['channel_address'], urlencode($hz_server)]); Master::Summon(['File_importer', sprintf('%d', $page), $channel['channel_address'], urlencode($hz_server)]); diff --git a/Zotlabs/Module/Import_progress.php b/Zotlabs/Module/Import_progress.php index d9b13e8a8..0afb6faed 100644 --- a/Zotlabs/Module/Import_progress.php +++ b/Zotlabs/Module/Import_progress.php @@ -29,14 +29,14 @@ class Import_progress extends \Zotlabs\Web\Controller { $c = PConfig::Get(local_channel(), 'import', 'content_progress'); if ($c) { - $total_cpages = floor(intval($c['items_total']) / intval($c['items_page'])); + $total_cpages = round(intval($c['items_total']) / intval($c['items_page'])); if(!$total_cpages) { - $total_cpages = 1; // because of floor + $total_cpages = 1; // because of round } $cpage = $c['last_page'] + 1; // because page count start at 0 - $cprogress = intval(floor((intval($cpage) * 100) / $total_cpages)); + $cprogress = intval(round((intval($cpage) * 100) / $total_cpages)); $ccompleted_str = t('Item sync completed!'); if(argv(1) === 'resume_itemsync' && $cprogress < 100) { @@ -50,6 +50,7 @@ class Import_progress extends \Zotlabs\Web\Controller { if ($alive) { $parsed = parse_url($alive); unset($parsed['path']); + unset($parsed['query']); $hz_server = unparse_url($parsed); $since = datetime_convert(date_default_timezone_get(), date_default_timezone_get(), '0001-01-01 00:00'); @@ -79,14 +80,14 @@ class Import_progress extends \Zotlabs\Web\Controller { $f = PConfig::Get(local_channel(), 'import', 'files_progress'); if ($f) { - $total_fpages = floor(intval($f['files_total']) / intval($f['files_page'])); + $total_fpages = round(intval($f['files_total']) / intval($f['files_page'])); if(!$total_fpages) { $total_fpages = 1; } $fpage = $f['last_page'] + 1; - $fprogress = intval(floor((intval($fpage) * 100) / $total_fpages)); + $fprogress = intval(round((intval($fpage) * 100) / $total_fpages)); $fcompleted_str = t('File sync completed!'); if(argv(1) === 'resume_filesync' && $fprogress < 100) { @@ -120,6 +121,7 @@ class Import_progress extends \Zotlabs\Web\Controller { } $fcompleted_str = t('File sync completed but no files were found!'); + } $fprogress_str = ((intval($fprogress)) ? $fprogress . '%' : $fprogress); @@ -127,13 +129,15 @@ class Import_progress extends \Zotlabs\Web\Controller { if(is_ajax()) { $ret = [ 'cprogress' => $cprogress, - 'fprogress' => $fprogress + 'ccompleted_str' => $ccompleted_str, + 'fprogress' => $fprogress, + 'fcompleted_str' => $fcompleted_str ]; json_return_and_die($ret); } - $o = replace_macros(get_markup_template("import_progress.tpl"), [ + return replace_macros(get_markup_template('import_progress.tpl'), [ '$chtitle_str' => t('Channel clone status'), '$ctitle_str' => t('Item sync status'), '$ftitle_str' => t('File sync status'), @@ -147,8 +151,6 @@ class Import_progress extends \Zotlabs\Web\Controller { '$resume_str' => t('Resume'), '$resume_helper_str' => t('Only resume if sync stalled!') ]); - - return $o; } } diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php index fba16fbe1..8ded7c1d7 100644 --- a/Zotlabs/Module/Item.php +++ b/Zotlabs/Module/Item.php @@ -807,18 +807,44 @@ class Item extends Controller { } - if ($moderated) + if ($moderated) { $item_blocked = ITEM_MODERATED; + } - if (!strlen($verb)) + if (!strlen($verb)) { $verb = 'Create'; + } $notify_type = (($parent) ? 'comment-new' : 'wall-new'); $uuid = $uuid ?? $message_id ?? item_message_id(); $mid = $mid ?? z_root() . '/item/' . $uuid; + + // Set the conversation target. + if (empty($owner_hash)) { + $owner_hash = $owner_xchan['xchan_hash']; + } + + if ($owner_hash === $channel['channel_hash']) { + $attributedTo = z_root() . '/channel/' . $channel['channel_address']; + + $conversation = isset($parent_item) ? $parent_item['mid'] : $mid; + $datarray['target'] = [ + 'id' => str_replace('/item/', '/conversation/', $conversation), + 'type' => 'Collection', + 'attributedTo' => $attributedTo, + ]; + $datarray['tgt_type'] = 'Collection'; + } + elseif (!empty($parent_item['target'])) { + $datarray['target'] = $parent_item['target']; + $datarray['tgt_type'] = $parent_item['tgt_type']; + } + + + if ($is_poll) { $poll = [ 'question' => $body, @@ -1023,6 +1049,7 @@ class Item extends Controller { $this->add_listeners($datarray); } + /* sync this is done in item_store_update() if (!$parent) { $r = q("select * from item where id = %d", intval($post_id) @@ -1033,9 +1060,14 @@ class Item extends Controller { Libsync::build_sync_packet($profile_uid, ['item' => [encode_item($sync_item[0], true)]]); } } - if (!$nopush) - Master::Summon(['Notifier', 'edit_post', $post_id]); + */ + if (!$nopush) { + Master::Summon(['Notifier', 'edit_post', $post_id]); + if (intval($x['approval_id'])) { + Master::Summon(['Notifier', 'edit_post', $x['approval_id']]); + } + } if ($api_source) return ($x); @@ -1059,6 +1091,7 @@ class Item extends Controller { } $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; $datarray = $post['item']; @@ -1133,6 +1166,7 @@ class Item extends Controller { killme(); } + /* sync this is done in item_store_update() if ($parent || $datarray['item_private'] == 1) { $r = q("select * from item where id = %d", intval($post_id) @@ -1143,6 +1177,7 @@ class Item extends Controller { Libsync::build_sync_packet($profile_uid, ['item' => [encode_item($sync_item[0], true)]]); } } + */ $datarray['id'] = $post_id; $datarray['llink'] = z_root() . '/display/' . $datarray['uuid']; @@ -1153,8 +1188,12 @@ class Item extends Controller { $nopush = false; } - if (!$nopush) + if (!$nopush) { Master::Summon(['Notifier', $notify_type, $post_id]); + if ($approval_id) { + Master::Summon(['Notifier', $notify_type, $approval_id]); + } + } logger('post_complete'); @@ -1209,7 +1248,7 @@ class Item extends Controller { require_once('include/items.php'); - $i = q("select id, uid, item_origin, author_xchan, owner_xchan, source_xchan, item_type from item where id = %d limit 1", + $i = q("select * from item where id = %d limit 1", intval(argv(2)) ); @@ -1236,7 +1275,6 @@ class Item extends Controller { $can_delete = true; } - if (!($can_delete || $local_delete)) { notice(t('Permission denied.') . EOL); return; @@ -1252,13 +1290,14 @@ class Item extends Controller { } else { // complex deletion that needs to propagate and be performed in phases - drop_item($i[0]['id'], true, DROPITEM_PHASE1); + drop_item($i[0]['id'], DROPITEM_PHASE1); $complex = true; } $r = q("select * from item where id = %d", intval($i[0]['id']) ); + if ($r) { xchan_query($r); $sync_item = fetch_post_tags($r); @@ -1267,6 +1306,9 @@ class Item extends Controller { if ($complex) { tag_deliver($i[0]['uid'], $i[0]['id']); + if (intval($i[0]['item_wall']) || $i[0]['mid'] !== $i[0]['parent_mid']) { + Master::Summon(['Notifier', 'drop', $i[0]['id']]); + } } } diff --git a/Zotlabs/Module/Like.php b/Zotlabs/Module/Like.php index d493742e7..2fb3fab83 100644 --- a/Zotlabs/Module/Like.php +++ b/Zotlabs/Module/Like.php @@ -284,7 +284,7 @@ class Like extends Controller { intval($ch[0]['channel_id']) ); if ($r) - drop_item($r[0]['id'], false); + drop_item($r[0]['id']); if ($interactive) { notice(t('Previous action reversed.') . EOL); return $o; @@ -387,17 +387,20 @@ class Like extends Controller { // already liked it. Drop that item. require_once('include/items.php'); foreach ($r as $rr) { - drop_item($rr['id'], false, DROPITEM_PHASE1); + drop_item($rr['id'], DROPITEM_PHASE1); + // set the changed timestamp on the parent so we'll see the update without a page reload q("update item set changed = '%s' where id = %d and uid = %d", dbesc(datetime_convert()), intval($rr['parent']), intval($rr['uid']) ); + // Prior activity was a duplicate of the one we're submitting, just undo it; // don't fall through and create another - if (activity_match($rr['verb'], $activity)) + if (activity_match($rr['verb'], $activity)) { $multi_undo = false; + } $d = q("select * from item where id = %d", intval($rr['id']) @@ -559,6 +562,7 @@ class Like extends Controller { $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; // save the conversation from expiration @@ -574,6 +578,7 @@ class Like extends Controller { } +/* Item sync is now done in item_store() $r = q("select * from item where id = %d", intval($post_id) ); @@ -582,7 +587,7 @@ class Like extends Controller { $sync_item = fetch_post_tags($r); Libsync::build_sync_packet($profile_uid, ['item' => [encode_item($sync_item[0], true)]]); } - +*/ if ($extended_like) { $r = q("insert into likes (channel_id,liker,likee,iid,i_mid,verb,target_type,target_id,target) values (%d,'%s','%s',%d,'%s','%s','%s','%s','%s')", @@ -609,7 +614,10 @@ class Like extends Controller { } - Master::Summon(array('Notifier', 'like', $post_id)); + Master::Summon(['Notifier', 'like', $post_id]); + if ($approval_id) { + Master::Summon(['Notifier', 'like', $approval_id]); + } if ($interactive) { notice(t('Action completed.') . EOL); diff --git a/Zotlabs/Module/Mitem.php b/Zotlabs/Module/Mitem.php index ac7470e13..81787f8c4 100644 --- a/Zotlabs/Module/Mitem.php +++ b/Zotlabs/Module/Mitem.php @@ -184,8 +184,8 @@ class Mitem extends \Zotlabs\Web\Controller { '$nick' => $which, '$sys' => \App::$is_sys )); - - $o .= replace_macros(get_markup_template('mitemlist.tpl'),array( + + return replace_macros(get_markup_template('mitemlist.tpl'),array( '$title' => t('Menu:'), '$create' => $create, '$nametitle' => t('Link Name'), @@ -204,29 +204,27 @@ class Mitem extends \Zotlabs\Web\Controller { '$hintedit' => t('Edit this menu item'), '$nick' => $which, )); - - return $o; } - - + + if(argc() > 3) { if(intval(argv(3))) { - + $m = q("select * from menu_item where mitem_id = %d and mitem_channel_id = %d limit 1", intval(argv(3)), intval($owner) ); - + if(! $m) { notice( t('Menu item not found.') . EOL); goaway(z_root() . '/menu/'. $which . ((\App::$is_sys) ? '?f=&sys=1' : '')); } - + $mitem = $m[0]; - + $lockstate = (($mitem['allow_cid'] || $mitem['allow_gid'] || $mitem['deny_cid'] || $mitem['deny_gid']) ? 'lock' : 'unlock'); - + if(argc() == 5 && argv(4) == 'drop') { menu_sync_packet($owner,get_observer_hash(),$mitem['mitem_menu_id']); $r = menu_del_item($mitem['mitem_menu_id'], $owner, intval(argv(3))); @@ -235,12 +233,12 @@ class Mitem extends \Zotlabs\Web\Controller { info( t('Menu item deleted.') . EOL); else notice( t('Menu item could not be deleted.'). EOL); - + goaway(z_root() . '/mitem/' . $which . '/' . $mitem['mitem_menu_id'] . ((\App::$is_sys) ? '?f=&sys=1' : '')); } - + // edit menu item - $o = replace_macros(get_markup_template('mitemedit.tpl'), array( + return replace_macros(get_markup_template('mitemedit.tpl'), array( '$header' => t('Edit Menu Element'), '$menu_id' => \App::$data['menu']['menu_id'], '$permissions' => t('Menu Item Permissions'), @@ -261,10 +259,8 @@ class Mitem extends \Zotlabs\Web\Controller { '$menu_names' => $menu_names, '$nick' => $which )); - - return $o; } } } - + } diff --git a/Zotlabs/Module/Moderate.php b/Zotlabs/Module/Moderate.php index ed2a1e4f9..2103684ab 100644 --- a/Zotlabs/Module/Moderate.php +++ b/Zotlabs/Module/Moderate.php @@ -74,7 +74,7 @@ class Moderate extends \Zotlabs\Web\Controller { // let the sender know we received their comment but we don't permit spam here. // Activity::send_rejection_activity(App::get_channel(), $item['author_xchan'], $item); - drop_item($post_id,false); + drop_item($post_id); notice( t('Item deleted') . EOL); } diff --git a/Zotlabs/Module/OAuth2TestVehicle.php b/Zotlabs/Module/OAuth2TestVehicle.php index 5ae278e8c..57cda3c28 100644 --- a/Zotlabs/Module/OAuth2TestVehicle.php +++ b/Zotlabs/Module/OAuth2TestVehicle.php @@ -31,8 +31,8 @@ class OAuth2TestVehicle extends \Zotlabs\Web\Controller { $_SESSION['api_response'] = (x($_SESSION, 'api_response') ? $_SESSION['api_response'] : ''); } function get() { - - $o .= replace_macros(get_markup_template('oauth2testvehicle.tpl'), array( + + $output = replace_macros(get_markup_template('oauth2testvehicle.tpl'), array( '$baseurl' => z_root(), '$api_response' => $_SESSION['api_response'], /* @@ -97,8 +97,10 @@ class OAuth2TestVehicle extends \Zotlabs\Web\Controller { ) ) )); + $_SESSION['success'] = ''; - return $o; + + return $output; } function post() { diff --git a/Zotlabs/Module/Oauth.php b/Zotlabs/Module/Oauth.php index 061296257..6063c7738 100644 --- a/Zotlabs/Module/Oauth.php +++ b/Zotlabs/Module/Oauth.php @@ -103,7 +103,8 @@ class Oauth extends Controller { if((argc() > 1) && (argv(1) === 'add')) { $tpl = get_markup_template("oauth_edit.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth"), '$title' => t('Add application'), '$submit' => t('Submit'), @@ -114,7 +115,6 @@ class Oauth extends Controller { '$redirect' => array('redirect', t('Redirect'), '', t('Redirect URI - leave blank unless your application specifically requires this')), '$icon' => array('icon', t('Icon url'), '', t('Optional')), )); - return $o; } if((argc() > 2) && (argv(1) === 'edit')) { @@ -129,7 +129,7 @@ class Oauth extends Controller { $app = $r[0]; $tpl = get_markup_template("oauth_edit.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth"), '$title' => t('Add application'), '$submit' => t('Update'), @@ -140,7 +140,6 @@ class Oauth extends Controller { '$redirect' => array('redirect', t('Redirect'), $app['redirect_uri'], ''), '$icon' => array('icon', t('Icon url'), $app['icon'], ''), )); - return $o; } if((argc() > 2) && (argv(1) === 'delete')) { @@ -163,7 +162,8 @@ class Oauth extends Controller { $tpl = get_markup_template("oauth.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth"), '$baseurl' => z_root(), '$title' => t('Connected OAuth Apps'), @@ -175,8 +175,6 @@ class Oauth extends Controller { '$remove' => t('Remove authorization'), '$apps' => $r, )); - return $o; - } } diff --git a/Zotlabs/Module/Oauth2.php b/Zotlabs/Module/Oauth2.php index 4b0b1991e..7aadd91bc 100644 --- a/Zotlabs/Module/Oauth2.php +++ b/Zotlabs/Module/Oauth2.php @@ -108,7 +108,8 @@ class Oauth2 extends Controller { if((argc() > 1) && (argv(1) === 'add')) { $tpl = get_markup_template("oauth2_edit.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth2"), '$title' => t('Add OAuth2 application'), '$submit' => t('Submit'), @@ -119,7 +120,6 @@ class Oauth2 extends Controller { '$grant' => array('grant', t('Grant Types'), '', t('leave blank unless your application sepcifically requires this')), '$scope' => array('scope', t('Authorization scope'), '', t('leave blank unless your application sepcifically requires this')), )); - return $o; } if((argc() > 2) && (argv(1) === 'edit')) { @@ -136,7 +136,7 @@ class Oauth2 extends Controller { $app = $r[0]; $tpl = get_markup_template("oauth2_edit.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth2"), '$title' => t('Add application'), '$submit' => t('Update'), @@ -147,7 +147,6 @@ class Oauth2 extends Controller { '$grant' => array('grant', t('Grant Types'), $app['grant_types'], t('leave blank unless your application specifically requires this')), '$scope' => array('scope', t('Authorization scope'), $app['scope'], t('leave blank unless your application specifically requires this')), )); - return $o; } if((argc() > 2) && (argv(1) === 'delete')) { @@ -184,7 +183,8 @@ class Oauth2 extends Controller { ); $tpl = get_markup_template("oauth2.tpl"); - $o .= replace_macros($tpl, array( + + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("oauth2"), '$baseurl' => z_root(), '$title' => t('Connected OAuth2 Apps'), @@ -196,8 +196,6 @@ class Oauth2 extends Controller { '$remove' => t('Remove authorization'), '$apps' => $r, )); - return $o; - } } diff --git a/Zotlabs/Module/Page.php b/Zotlabs/Module/Page.php index 8a698005a..a4ee5eaa2 100644 --- a/Zotlabs/Module/Page.php +++ b/Zotlabs/Module/Page.php @@ -183,9 +183,7 @@ class Page extends \Zotlabs\Web\Controller { if($r[0]['mimetype'] === 'application/x-pdl') \App::$page['pdl_content'] = true; - $o .= prepare_page($r[0]); - return $o; - + return prepare_page($r[0]); } } diff --git a/Zotlabs/Module/Pdledit.php b/Zotlabs/Module/Pdledit.php index e0bbc31d0..aa512e6da 100644 --- a/Zotlabs/Module/Pdledit.php +++ b/Zotlabs/Module/Pdledit.php @@ -51,7 +51,7 @@ class Pdledit extends Controller { if(argc() > 1) $module = 'mod_' . argv(1) . '.pdl'; else { - $o .= '<div class="generic-content-wrapper-styled">'; + $o = '<div class="generic-content-wrapper-styled">'; $o .= '<h1>' . t('Edit System Page Description') . '</h1>'; $edited = []; diff --git a/Zotlabs/Module/Profperm.php b/Zotlabs/Module/Profperm.php index 842197415..4594728b1 100644 --- a/Zotlabs/Module/Profperm.php +++ b/Zotlabs/Module/Profperm.php @@ -55,6 +55,8 @@ class Profperm extends \Zotlabs\Web\Controller { } + $o = ''; + if((argc() > 1) && (intval(argv(1)))) { $r = q("SELECT * FROM profile WHERE id = %d AND uid = %d AND is_default = 0 LIMIT 1", intval(argv(1)), diff --git a/Zotlabs/Module/React.php b/Zotlabs/Module/React.php index e04b9b257..e1abd242e 100644 --- a/Zotlabs/Module/React.php +++ b/Zotlabs/Module/React.php @@ -91,6 +91,9 @@ class React extends Controller { if ($x['success']) { $nid = $x['item_id']; Master::Summon(['Notifier', 'like', $nid]); + if (!empty($x['approval_id'])) { + Master::Summon(['Notifier', 'like', $x['approval_id']]); + } } } diff --git a/Zotlabs/Module/Removeaccount.php b/Zotlabs/Module/Removeaccount.php index cd18b79c0..b41acb8b0 100644 --- a/Zotlabs/Module/Removeaccount.php +++ b/Zotlabs/Module/Removeaccount.php @@ -36,22 +36,22 @@ class Removeaccount extends \Zotlabs\Web\Controller { return; } } - + $global_remove = 0; //intval($_POST['global']); - - account_remove($account_id, 1 - $global_remove); + + account_remove($account_id, 1 - $global_remove); } - + function get() { - + if(! local_channel()) goaway(z_root()); - + $hash = random_string(); - + $_SESSION['remove_account_verify'] = $hash; $tpl = get_markup_template('removeaccount.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$basedir' => z_root(), '$hash' => $hash, '$title' => t('Remove This Account'), @@ -60,9 +60,5 @@ class Removeaccount extends \Zotlabs\Web\Controller { // '$global' => array('global', t('Remove this account, all its channels and all its channel clones from the network'), false, t('By default only the instances of the channels located on this hub will be removed from the network')), '$submit' => t('Remove Account') )); - - return $o; - } - } diff --git a/Zotlabs/Module/Removeme.php b/Zotlabs/Module/Removeme.php index 4d475ead6..d71f8d4ab 100644 --- a/Zotlabs/Module/Removeme.php +++ b/Zotlabs/Module/Removeme.php @@ -54,7 +54,7 @@ class Removeme extends \Zotlabs\Web\Controller { $_SESSION['remove_account_verify'] = $hash; $tpl = get_markup_template('removeme.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$basedir' => z_root(), '$hash' => $hash, '$title' => t('Remove Channel'), @@ -63,9 +63,5 @@ class Removeme extends \Zotlabs\Web\Controller { // '$global' => [ 'global', t('Remove this channel and all its clones from the network'), false, t('By default only the instance of the channel located on this hub will be removed from the network'), [ t('No'),t('Yes') ] ], '$submit' => t('Remove Channel') )); - - return $o; - } - } diff --git a/Zotlabs/Module/Search_ac.php b/Zotlabs/Module/Search_ac.php index 24b724c5d..cd0960859 100644 --- a/Zotlabs/Module/Search_ac.php +++ b/Zotlabs/Module/Search_ac.php @@ -90,12 +90,7 @@ class Search_ac extends \Zotlabs\Web\Controller { 'items' => $results, ); echo json_encode($o); - - logger('search_ac: ' . print_r($x,true),LOGGER_DATA,LOG_INFO); - + killme(); } - - - } diff --git a/Zotlabs/Module/Settings/Account.php b/Zotlabs/Module/Settings/Account.php index 0266cee12..7f0d11069 100644 --- a/Zotlabs/Module/Settings/Account.php +++ b/Zotlabs/Module/Settings/Account.php @@ -100,7 +100,7 @@ class Account { $attremail = ((!strpos($email, '@')) ? 'disabled="disabled"' : ''); $tpl = get_markup_template("settings_account.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_account"), '$title' => t('Account Settings'), '$origpass' => array('origpass', t('Current Password'), ' ',''), @@ -114,7 +114,5 @@ class Account { '$removeaccount' => t('Remove this account including all its channels'), '$account_settings' => $account_settings )); - return $o; } - } diff --git a/Zotlabs/Module/Settings/Calendar.php b/Zotlabs/Module/Settings/Calendar.php index 65240c635..3b15f4aa6 100644 --- a/Zotlabs/Module/Settings/Calendar.php +++ b/Zotlabs/Module/Settings/Calendar.php @@ -33,7 +33,7 @@ class Calendar { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Calendar { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Channel_home.php b/Zotlabs/Module/Settings/Channel_home.php index 470dbe4c3..388b70942 100644 --- a/Zotlabs/Module/Settings/Channel_home.php +++ b/Zotlabs/Module/Settings/Channel_home.php @@ -81,7 +81,7 @@ class Channel_home { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -90,8 +90,5 @@ class Channel_home { '$extra_settings_html' => $extra_settings_html, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Connections.php b/Zotlabs/Module/Settings/Connections.php index 52a95a3d1..9d1069cf3 100644 --- a/Zotlabs/Module/Settings/Connections.php +++ b/Zotlabs/Module/Settings/Connections.php @@ -33,7 +33,7 @@ class Connections { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Connections { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Conversation.php b/Zotlabs/Module/Settings/Conversation.php index 5f3d903a8..51ee2c83a 100644 --- a/Zotlabs/Module/Settings/Conversation.php +++ b/Zotlabs/Module/Settings/Conversation.php @@ -36,7 +36,7 @@ class Conversation { $tpl = (($aj) ? get_markup_template("settings_module_ajax.tpl") : get_markup_template("settings_module.tpl")); - $o .= replace_macros($tpl, array( + $o = replace_macros($tpl, array( '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), '$title' => t('Conversation Settings'), diff --git a/Zotlabs/Module/Settings/Directory.php b/Zotlabs/Module/Settings/Directory.php index 09ea61f60..e1957d2fa 100644 --- a/Zotlabs/Module/Settings/Directory.php +++ b/Zotlabs/Module/Settings/Directory.php @@ -33,7 +33,7 @@ class Directory { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Directory { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Editor.php b/Zotlabs/Module/Settings/Editor.php index 85c3e69ae..50bd2b2ad 100644 --- a/Zotlabs/Module/Settings/Editor.php +++ b/Zotlabs/Module/Settings/Editor.php @@ -33,7 +33,7 @@ class Editor { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Editor { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Events.php b/Zotlabs/Module/Settings/Events.php index 0a0e3516c..3a7faa8b4 100644 --- a/Zotlabs/Module/Settings/Events.php +++ b/Zotlabs/Module/Settings/Events.php @@ -33,7 +33,7 @@ class Events { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Events { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Features.php b/Zotlabs/Module/Settings/Features.php index 553ff0836..84c868e48 100644 --- a/Zotlabs/Module/Settings/Features.php +++ b/Zotlabs/Module/Settings/Features.php @@ -38,17 +38,14 @@ class Features { $arr[$fname][1][] = array('feature_' . $f[0],$f[1],((intval(feature_enabled(local_channel(),$f[0]))) ? "1" : ''),$f[2],array(t('Off'),t('On'))); } } - + $tpl = get_markup_template("settings_features.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$form_security_token' => get_form_security_token("settings_features"), '$title' => t('Additional Features'), '$features' => $arr, '$baseurl' => z_root(), '$submit' => t('Submit'), )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Manage.php b/Zotlabs/Module/Settings/Manage.php index 6fb57eafb..6e47cfcc7 100644 --- a/Zotlabs/Module/Settings/Manage.php +++ b/Zotlabs/Module/Settings/Manage.php @@ -34,7 +34,7 @@ class Manage { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -42,8 +42,5 @@ class Manage { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Network.php b/Zotlabs/Module/Settings/Network.php index eae963a25..39c66622e 100644 --- a/Zotlabs/Module/Settings/Network.php +++ b/Zotlabs/Module/Settings/Network.php @@ -52,7 +52,7 @@ class Network { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -61,8 +61,5 @@ class Network { '$extra_settings_html' => $extra_settings_html, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Photos.php b/Zotlabs/Module/Settings/Photos.php index f68c8847b..05c380850 100644 --- a/Zotlabs/Module/Settings/Photos.php +++ b/Zotlabs/Module/Settings/Photos.php @@ -33,7 +33,7 @@ class Photos { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -41,8 +41,5 @@ class Photos { '$features' => process_module_features_get(local_channel(), $features), '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Settings/Profiles.php b/Zotlabs/Module/Settings/Profiles.php index 0ff2dfb6d..5052385a8 100644 --- a/Zotlabs/Module/Settings/Profiles.php +++ b/Zotlabs/Module/Settings/Profiles.php @@ -42,7 +42,7 @@ class Profiles { $tpl = get_markup_template("settings_module.tpl"); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$rpath' => escape_url($rpath), '$action_url' => 'settings/' . $module, '$form_security_token' => get_form_security_token('settings_' . $module), @@ -51,8 +51,5 @@ class Profiles { '$extra_settings_html' => $extra_settings_html, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Share.php b/Zotlabs/Module/Share.php index db0acb6f5..4fefdb4ef 100644 --- a/Zotlabs/Module/Share.php +++ b/Zotlabs/Module/Share.php @@ -136,6 +136,7 @@ class Share extends \Zotlabs\Web\Controller { $post = item_store($arr); $post_id = $post['item_id']; + $approval_id = $post['approval_id'] ?? 0; $arr['id'] = $post_id; @@ -143,6 +144,7 @@ class Share extends \Zotlabs\Web\Controller { // info( t('Post repeated') . EOL); +/* $r = q("select * from item where id = %d", intval($post_id) ); @@ -151,8 +153,12 @@ class Share extends \Zotlabs\Web\Controller { $sync_item = fetch_post_tags($r); Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); } +*/ Master::Summon([ 'Notifier', 'like', $post_id ]); + if ($approval_id) { + Master::Summon(['Notifier', 'like', $approval_id]); + } killme(); diff --git a/Zotlabs/Module/Subthread.php b/Zotlabs/Module/Subthread.php index b927ee480..baabee78f 100644 --- a/Zotlabs/Module/Subthread.php +++ b/Zotlabs/Module/Subthread.php @@ -159,7 +159,7 @@ class Subthread extends \Zotlabs\Web\Controller { $arr['deny_cid'] = $item['deny_cid']; $arr['deny_gid'] = $item['deny_gid']; - $post = item_store($arr); + $post = item_store($arr, deliver: false, addAndSync: false); $post_id = $post['item_id']; $arr['id'] = $post_id; diff --git a/Zotlabs/Module/Tagrm.php b/Zotlabs/Module/Tagrm.php index a6dc21798..34eaf85b2 100644 --- a/Zotlabs/Module/Tagrm.php +++ b/Zotlabs/Module/Tagrm.php @@ -7,141 +7,141 @@ require_once('include/bbcode.php'); class Tagrm extends \Zotlabs\Web\Controller { function post() { - + if(! local_channel()) goaway(z_root() . '/' . $_SESSION['photo_return']); - - + + if((x($_POST,'submit')) && ($_POST['submit'] === t('Cancel'))) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $tag = ((x($_POST,'tag')) ? trim($_POST['tag']) : ''); $item = ((x($_POST,'item')) ? intval($_POST['item']) : 0 ); - + $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", intval($item), intval(local_channel()) ); - + if(! $r) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $r = fetch_post_tags($r,true); - + $item = $r[0]; $new_tags = array(); - + if($item['term']) { for($x = 0; $x < count($item['term']); $x ++) { if($item['term'][$x]['term'] !== hex2bin($tag)) $new_tags[] = $item['term'][$x]; } } - + if($new_tags) $item['term'] = $new_tags; else unset($item['term']); - - item_store_update($item); - + + item_store_update($item, deliver: false, addAndSync: false); + info( t('Tag removed') . EOL ); goaway(z_root() . '/' . $_SESSION['photo_return']); - + // NOTREACHED - + } - - - + + + function get() { - + if(! local_channel()) { goaway(z_root() . '/' . $_SESSION['photo_return']); // NOTREACHED } - + // remove tag on the fly if item and tag are provided if((argc() == 4) && (argv(1) === 'drop') && intval(argv(2))) { - + $item = intval(argv(2)); $tag = argv(3); - + $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", intval($item), intval(local_channel()) ); - + if(! $r) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $r = fetch_post_tags($r,true); - + $item = $r[0]; - + $new_tags = array(); - + if($item['term']) { for($x = 0; $x < count($item['term']); $x ++) { if($item['term'][$x]['term'] !== hex2bin($tag)) $new_tags[] = $item['term'][$x]; } } - + if($new_tags) $item['term'] = $new_tags; else unset($item['term']); - - item_store_update($item); - + + item_store_update($item, deliver: false, addAndSync: false); + info( t('Tag removed') . EOL ); goaway(z_root() . '/' . $_SESSION['photo_return']); - + } - + //if we got only the item print a list of tags to select if((argc() == 3) && (argv(1) === 'drop') && intval(argv(2))) { - + $o = ''; - + $item = intval(argv(2)); - + $r = q("SELECT * FROM item WHERE id = %d AND uid = %d LIMIT 1", intval($item), intval(local_channel()) ); - + if(! $r) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $r = fetch_post_tags($r,true); - + if(! count($r[0]['term'])) goaway(z_root() . '/' . $_SESSION['photo_return']); - + $o .= '<h3>' . t('Remove Item Tag') . '</h3>'; - + $o .= '<p id="tag-remove-desc">' . t('Select a tag to remove: ') . '</p>'; - + $o .= '<form id="tagrm" action="tagrm" method="post" >'; $o .= '<input type="hidden" name="item" value="' . $item . '" />'; $o .= '<ul>'; - - + + foreach($r[0]['term'] as $x) { $o .= '<li><input type="checkbox" name="tag" value="' . bin2hex($x['term']) . '" >' . bbcode($x['term']) . '</input></li>'; } - + $o .= '</ul>'; $o .= '<input id="tagrm-submit" type="submit" name="submit" value="' . t('Remove') .'" />'; $o .= '<input id="tagrm-cancel" type="submit" name="submit" value="' . t('Cancel') .'" />'; $o .= '</form>'; - + return $o; - + } - + } - + } diff --git a/Zotlabs/Module/Thing.php b/Zotlabs/Module/Thing.php index a77081741..aef494e13 100644 --- a/Zotlabs/Module/Thing.php +++ b/Zotlabs/Module/Thing.php @@ -339,7 +339,7 @@ class Thing extends \Zotlabs\Web\Controller { return ''; } - $o .= replace_macros(get_markup_template('thing_edit.tpl'),array( + return replace_macros(get_markup_template('thing_edit.tpl'),array( '$thing_hdr' => t('Edit Thing'), '$multiprof' => feature_enabled(local_channel(),'multi_profiles'), '$profile_lbl' => t('Select a profile'), @@ -363,8 +363,6 @@ class Thing extends \Zotlabs\Web\Controller { '$lockstate' => $lockstate, '$submit' => t('Submit') )); - - return $o; } if(argc() == 3 && argv(1) === 'drop') { @@ -392,10 +390,10 @@ class Thing extends \Zotlabs\Web\Controller { Libsync::build_sync_packet(0,array('obj' => $r)); - return $o; + return ''; } - $o .= replace_macros(get_markup_template('thing_input.tpl'),array( + return replace_macros(get_markup_template('thing_input.tpl'),array( '$thing_hdr' => t('Add Thing to your Profile'), '$multiprof' => feature_enabled(local_channel(),'multi_profiles'), '$profile_lbl' => t('Select a profile'), @@ -415,8 +413,5 @@ class Thing extends \Zotlabs\Web\Controller { '$lockstate' => $lockstate, '$submit' => t('Submit') )); - - return $o; } - } diff --git a/Zotlabs/Module/Vote.php b/Zotlabs/Module/Vote.php index 06c47f91f..5192e3043 100644 --- a/Zotlabs/Module/Vote.php +++ b/Zotlabs/Module/Vote.php @@ -107,10 +107,12 @@ class Vote extends Controller { retain_item($fetch[0]['id']); if($x['success']) { - $itemid = $x['item_id']; - Master::Summon( [ 'Notifier', 'like', $itemid ] ); + Master::Summon(['Notifier', 'like', $x['item_id']]); + if (!empty($x['approval_id'])) { + Master::Summon(['Notifier', 'like', $x['approval_id']]); + } } - +/* $r = q("select * from item where id = %d", intval($itemid) ); @@ -119,6 +121,7 @@ class Vote extends Controller { $sync_item = fetch_post_tags($r); Libsync::build_sync_packet($channel['channel_id'], [ 'item' => [ encode_item($sync_item[0],true) ] ]); } +*/ } $ret['success'] = true; diff --git a/Zotlabs/Module/Webfinger.php b/Zotlabs/Module/Webfinger.php index 0dafae23c..ba0dca9e7 100644 --- a/Zotlabs/Module/Webfinger.php +++ b/Zotlabs/Module/Webfinger.php @@ -7,16 +7,16 @@ namespace Zotlabs\Module; class Webfinger extends \Zotlabs\Web\Controller { function get() { - - - $o .= '<h3>Webfinger Diagnostic</h3>'; - + + + $o = '<h3>Webfinger Diagnostic</h3>'; + $o .= '<form action="webfinger" method="get">'; $o .= 'Lookup address: <input type="text" style="width: 250px;" name="addr" value="' . $_GET['addr'] .'" />'; - $o .= '<input type="submit" name="submit" value="Submit" /></form>'; - + $o .= '<input type="submit" name="submit" value="Submit" /></form>'; + $o .= '<br /><br />'; - + if(x($_GET,'addr')) { $addr = trim($_GET['addr']); diff --git a/Zotlabs/Module/Webpages.php b/Zotlabs/Module/Webpages.php index ffb0d94ea..ca15c0b3a 100644 --- a/Zotlabs/Module/Webpages.php +++ b/Zotlabs/Module/Webpages.php @@ -63,7 +63,7 @@ class Webpages extends Controller { switch ($_SESSION['action']) { case 'import': $_SESSION['action'] = null; - $o .= replace_macros(get_markup_template('webpage_import.tpl'), array( + return replace_macros(get_markup_template('webpage_import.tpl'), array( '$title' => t('Import Webpage Elements'), '$importbtn' => t('Import selected'), '$action' => 'import', @@ -71,7 +71,6 @@ class Webpages extends Controller { '$layouts' => $_SESSION['layouts'], '$blocks' => $_SESSION['blocks'], )); - return $o; case 'importselected': $_SESSION['action'] = null; @@ -87,7 +86,7 @@ class Webpages extends Controller { $pages = get_webpage_elements($channel, 'pages'); $layouts = get_webpage_elements($channel, 'layouts'); $blocks = get_webpage_elements($channel, 'blocks'); - $o .= replace_macros(get_markup_template('webpage_export_list.tpl'), array( + $o = replace_macros(get_markup_template('webpage_export_list.tpl'), array( '$title' => t('Export Webpage Elements'), '$exportbtn' => t('Export selected'), '$action' => $_SESSION['export'], // value should be 'zipfile' or 'cloud' diff --git a/Zotlabs/Storage/Browser.php b/Zotlabs/Storage/Browser.php index e7f71c8c8..6a9cd61ef 100644 --- a/Zotlabs/Storage/Browser.php +++ b/Zotlabs/Storage/Browser.php @@ -399,7 +399,6 @@ class Browser extends DAV\Browser\Plugin { '$allow_gid' => ((isset($channel_acl['allow_gid'])) ? acl2json($channel_acl['allow_gid']) : ''), '$deny_cid' => ((isset($channel_acl['deny_cid'])) ? acl2json($channel_acl['deny_cid']) : ''), '$deny_gid' => ((isset($channel_acl['deny_gid'])) ? acl2json($channel_acl['deny_gid']) : ''), - '$is_owner' => $is_owner, '$select_all_label' => t('Select All'), '$bulk_actions_label' => t('Bulk Actions'), '$adjust_permissions_label' => t('Adjust Permissions'), diff --git a/Zotlabs/Update/_1007.php b/Zotlabs/Update/_1007.php index eb52c5bc5..74e1bb310 100644 --- a/Zotlabs/Update/_1007.php +++ b/Zotlabs/Update/_1007.php @@ -6,10 +6,10 @@ class _1007 { function run() { $r = q("ALTER TABLE `channel` ADD `channel_r_storage` INT UNSIGNED NOT NULL DEFAULT '128', ADD `channel_w_storage` INT UNSIGNED NOT NULL DEFAULT '128', add index ( channel_r_storage ), add index ( channel_w_storage )"); - if($r && $r2) + if($r) return UPDATE_SUCCESS; return UPDATE_FAILED; } -}
\ No newline at end of file +} diff --git a/Zotlabs/Update/_1151.php b/Zotlabs/Update/_1151.php index d14baabb1..20f3180a0 100644 --- a/Zotlabs/Update/_1151.php +++ b/Zotlabs/Update/_1151.php @@ -8,7 +8,7 @@ function run() { $r3 = q("select likes.*, item.mid from likes left join item on likes.iid = item.id"); if($r3) { foreach($r3 as $rr) { - q("update likes set i_mid = '%s' where id = $d", + q("update likes set i_mid = '%s' where id = %d", dbesc($rr['mid']), intval($rr['id']) ); @@ -21,4 +21,4 @@ function run() { } -}
\ No newline at end of file +} diff --git a/Zotlabs/Widget/Activity.php b/Zotlabs/Widget/Activity.php index 34e0f67dc..19f7acadb 100644 --- a/Zotlabs/Widget/Activity.php +++ b/Zotlabs/Widget/Activity.php @@ -17,7 +17,7 @@ class Activity { $o = ''; if(is_array($arr) && array_key_exists('limit',$arr)) - $limit = " limit " . intval($limit) . " "; + $limit = " limit " . intval($arr['limit']) . " "; else $limit = ''; diff --git a/Zotlabs/Widget/Album.php b/Zotlabs/Widget/Album.php index 003f6f49d..f1fa69182 100644 --- a/Zotlabs/Widget/Album.php +++ b/Zotlabs/Widget/Album.php @@ -94,7 +94,7 @@ class Album { $tpl = get_markup_template('photo_album.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$photos' => $photos, '$album' => (($title) ? $title : $album), '$album_id' => rand(), @@ -102,11 +102,9 @@ class Album { '$can_post' => false, '$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)), '$order' => false, - '$upload_form' => $upload_form, - '$usage' => $usage_message + '$upload_form' => '', // $upload_form, + '$usage' => '', // $usage_message )); - - return $o; } } diff --git a/Zotlabs/Widget/Item.php b/Zotlabs/Widget/Item.php index 6f943ffdf..3de135cb9 100644 --- a/Zotlabs/Widget/Item.php +++ b/Zotlabs/Widget/Item.php @@ -34,7 +34,7 @@ class Item { if($arr['title']) { $r = q("select item.* from item left join iconfig on item.id = iconfig.iid where item.uid = %d and iconfig.cat = 'system' and iconfig.v = '%s' - and iconfig.k = 'WEBPAGE' and item_type = %d $sql_extra $revision limit 1", + and iconfig.k = 'WEBPAGE' and item_type = %d $sql_extra limit 1", intval($channel_id), dbesc($arr['title']), intval(ITEM_TYPE_WEBPAGE) diff --git a/Zotlabs/Widget/Pinned.php b/Zotlabs/Widget/Pinned.php index 2ba170fe8..be6b98434 100644 --- a/Zotlabs/Widget/Pinned.php +++ b/Zotlabs/Widget/Pinned.php @@ -112,8 +112,7 @@ class Pinned { 'mids' => json_encode([ $midb64 ]), 'isevent' => $isevent, 'attend' => $attend, - 'consensus' => $consensus, - 'conlabels' => ($canvote ? $conlabels : []), + 'conlabels' => [], 'canvote' => $canvote, 'linktitle' => sprintf( t('View %s\'s profile - %s'), $profile_name, ($author['xchan_addr'] ? $author['xchan_addr'] : $author['xchan_url']) ), 'olinktitle' => sprintf( t('View %s\'s profile - %s'), $owner['xchan_name'], ($owner['xchan_addr'] ? $owner['xchan_addr'] : $owner['xchan_url']) ), diff --git a/Zotlabs/Widget/Portfolio.php b/Zotlabs/Widget/Portfolio.php index a06f56e30..bde1c7d6a 100644 --- a/Zotlabs/Widget/Portfolio.php +++ b/Zotlabs/Widget/Portfolio.php @@ -103,7 +103,7 @@ class Portfolio { $tpl = get_markup_template('photo_album_portfolio.tpl'); - $o .= replace_macros($tpl, array( + return replace_macros($tpl, array( '$photos' => $photos, '$mode' => $mode, '$count' => $count, @@ -113,11 +113,7 @@ class Portfolio { '$can_post' => false, '$upload' => array(t('Upload'), z_root() . '/photos/' . \App::$profile['channel_address'] . '/upload/' . bin2hex($album)), '$order' => false, - '$upload_form' => $upload_form, - '$usage' => $usage_message )); - - return $o; } } diff --git a/Zotlabs/Widget/Tagcloud.php b/Zotlabs/Widget/Tagcloud.php index 00456f24f..efd571576 100644 --- a/Zotlabs/Widget/Tagcloud.php +++ b/Zotlabs/Widget/Tagcloud.php @@ -18,8 +18,7 @@ class Tagcloud { $flags = 0; $type = TERM_HASHTAG; - // @FIXME there exists no $authors variable - $r = tagadelic($uid, $count, $authors, $owner, $flags, 0, $type); + $r = tagadelic($uid, $count, '', '', $flags, 0, $type); // @FIXME this should use a template diff --git a/Zotlabs/Widget/Tasklist.php b/Zotlabs/Widget/Tasklist.php index 96b70af15..9271269cf 100644 --- a/Zotlabs/Widget/Tasklist.php +++ b/Zotlabs/Widget/Tasklist.php @@ -19,7 +19,7 @@ class Tasklist { if(App::$profile_uid !== local_channel()) return EMPTY_STR; - $o .= '<script>var tasksShowAll = 0; $(document).ready(function() { tasksFetch(); $("#tasklist-new-form").submit(function(event) { event.preventDefault(); $.post( "tasks/new", $("#tasklist-new-form").serialize(), function(data) { tasksFetch(); $("#tasklist-new-summary").val(""); } ); return false; } )});</script>'; + $o = '<script>var tasksShowAll = 0; $(document).ready(function() { tasksFetch(); $("#tasklist-new-form").submit(function(event) { event.preventDefault(); $.post( "tasks/new", $("#tasklist-new-form").serialize(), function(data) { tasksFetch(); $("#tasklist-new-summary").val(""); } ); return false; } )});</script>'; $o .= '<script>function taskComplete(id) { $.post("tasks/complete/"+id, function(data) { tasksFetch();}); } function tasksFetch() { $.get("tasks/fetch" + ((tasksShowAll) ? "/all" : ""), function(data) { @@ -66,7 +66,7 @@ require_once('include/security.php'); define('PLATFORM_NAME', 'hubzilla'); -define('STD_VERSION', '9.5.1'); +define('STD_VERSION', '9.5.2'); define('ZOT_REVISION', '6.0'); define('DB_UPDATE_VERSION', 1263); @@ -1538,7 +1538,7 @@ function check_config() { App::set_baseurl(z_root()); - new DB_Upgrade(DB_UPDATE_VERSION); + DB_Upgrade::run(DB_UPDATE_VERSION); plugins_sync(); diff --git a/include/attach.php b/include/attach.php index 2ee3401f6..02b94ddb6 100644 --- a/include/attach.php +++ b/include/attach.php @@ -1606,8 +1606,7 @@ function attach_drop_photo($channel_id,$resource) { if($x) { $stage = (($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1); - $interactive = (($x[0]['item_hidden']) ? false : true); - drop_item($x[0]['id'], $interactive, $stage); + drop_item($x[0]['id'], $stage); } $r = q("SELECT content FROM photo WHERE resource_id = '%s' AND uid = %d AND os_storage = 1", @@ -1636,8 +1635,7 @@ function attach_drop_item($channel_id,$resource) { if($x) { $stage = (($x[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1); - $interactive = (($x[0]['item_hidden']) ? false : true); - drop_item($x[0]['id'], $interactive, $stage); + drop_item($x[0]['id'], $stage); } } @@ -1855,8 +1853,6 @@ function pipe_streams($in, $out, $bufsize = 16384) { } function attach_store_item($channel, $observer, $file) { - - if(is_string($file)) { $r = q("SELECT * FROM attach WHERE uid = %d AND hash = '%s' LIMIT 1", intval($channel['channel_id']), @@ -1906,10 +1902,11 @@ function attach_store_item($channel, $observer, $file) { $post = item_store($arr); - $item_id = $post['item_id']; - - if($item_id) { - Master::Summon(['Notifier', 'activity', $item_id]); + if ($post['success']) { + Master::Summon(['Notifier', 'activity', $post['item_id']]); + if (!empty($post['approval_id'])) { + Master::Summon(['Notifier', 'activity', $post['approval_id']]); + } } */ @@ -1919,8 +1916,11 @@ function attach_store_item($channel, $observer, $file) { } $stage = (($r[0]['item_hidden']) ? DROPITEM_NORMAL : DROPITEM_PHASE1); - $interactive = (($r[0]['item_hidden']) ? false : true); - drop_item($r[0]['id'], $interactive, $stage); + drop_item($r[0]['id'], $stage); + + if (empty($r[0]['item_hidden'])) { + Master::Summon(['Notifier', 'drop', $i[0]['id']]); + } } @@ -1945,6 +1945,12 @@ function attach_store_item($channel, $observer, $file) { $mid = z_root() . '/item/' . $uuid; + $target = [ + 'id' => z_root() . '/conversation/' . $uuid, + 'type' => 'Collection', + 'attributedTo' => channel_url($channel), + ]; + $arr = []; // Initialize the array of parameters for the post $arr['aid'] = $channel['channel_account_id']; $arr['uuid'] = $uuid; @@ -1965,6 +1971,8 @@ function attach_store_item($channel, $observer, $file) { $arr['item_thread_top'] = 1; $arr['item_private'] = (($file['allow_cid'] || $file['allow_gid'] || $file['deny_cid'] || $file['deny_gid']) ? 1 : 0); $arr['verb'] = 'Create'; + $arr['target'] = $target; + $arr['target_type'] = 'Collection'; $arr['obj_type'] = $type; $arr['title'] = $file['filename']; @@ -1982,14 +1990,13 @@ function attach_store_item($channel, $observer, $file) { } $body_str = sprintf((($type === 'Image') ? t('%s shared an %s with you') : t('%s shared a %s with you')), '[zrl=' . $observer['xchan_url'] . ']' . $observer['xchan_name'] . '[/zrl]', '[zrl=' . $path . ']' . (($type === 'Image') ? t('image') : t('file')) . '[/zrl]'); - $arr['body'] .= $body_str; + $arr['body'] .= "\r\n" . $body_str; $meta = [ 'name' => $file['filename'], 'type' => $file['filetype'], 'size' => $file['filesize'], 'revision' => $file['revision'], - 'size' => $file['filesize'], 'created' => $file['created'], 'edited' => $file['edited'], 'path' => $path @@ -1999,10 +2006,11 @@ function attach_store_item($channel, $observer, $file) { $post = item_store($arr); - $item_id = $post['item_id']; - - if($item_id) { - Master::Summon(['Notifier', 'activity', $item_id]); + if ($post['success']) { + Master::Summon(['Notifier', 'activity', $post['item_id']]); + if (!empty($post['approval_id'])) { + Master::Summon(['Notifier', 'activity', $post['approval_id']]); + } } } diff --git a/include/channel.php b/include/channel.php index 0ece3be74..a3ba1a765 100644 --- a/include/channel.php +++ b/include/channel.php @@ -96,6 +96,8 @@ function validate_channelname($name) { if (x($arr, 'message')) return $arr['message']; + + return null; } @@ -2428,7 +2430,7 @@ function get_zcard($channel, $observer_hash = '', $args = array()) { $cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.png' ]; } - $o .= replace_macros(get_markup_template('zcard.tpl'), array( + return replace_macros(get_markup_template('zcard.tpl'), array( '$maxwidth' => $maxwidth, '$scale' => $scale, '$translate' => $translate, @@ -2437,8 +2439,6 @@ function get_zcard($channel, $observer_hash = '', $args = array()) { '$pphoto' => $pphoto, '$zcard' => $zcard )); - - return $o; } @@ -2505,17 +2505,13 @@ function get_zcard_embed($channel, $observer_hash = '', $args = array()) { $cover = [ 'href' => z_root() . '/images/default_cover_photos/' . $default_cover . '/' . $cover_width . '.png' ]; } - $o .= replace_macros(get_markup_template('zcard_embed.tpl'),array( + return replace_macros(get_markup_template('zcard_embed.tpl'),array( '$maxwidth' => $maxwidth, - '$scale' => $scale, - '$translate' => $translate, '$size' => $size, '$cover' => $cover, '$pphoto' => $pphoto, '$zcard' => $zcard )); - - return $o; } /** diff --git a/include/config.php b/include/config.php index 4dd40eccf..50fe60eb0 100644 --- a/include/config.php +++ b/include/config.php @@ -39,8 +39,6 @@ use Zotlabs\Lib as Zlib; * * @param string $family The category of the configuration value * - * @return Nothing - * * @deprecated * This function is deprecated, use Zotlabs\Lib\Config::Load * instead. diff --git a/include/connections.php b/include/connections.php index efc531171..7500647b4 100644 --- a/include/connections.php +++ b/include/connections.php @@ -342,7 +342,7 @@ function remove_all_xchan_resources($xchan, $channel_id = 0) { if($r) { foreach($r as $rr) { - drop_item($rr['id'],false); + drop_item($rr['id']); } } @@ -513,7 +513,7 @@ function remove_abook_items($channel_id, $xchan_hash) { continue; } - drop_item($rr['id'],false); + drop_item($rr['id']); } } diff --git a/include/datetime.php b/include/datetime.php index 4c7105138..2182d7c43 100644 --- a/include/datetime.php +++ b/include/datetime.php @@ -264,6 +264,8 @@ function relative_date($posted_date, $format = null) { return sprintf($format, $r, plural_dates($str,$r)); } } + + return $abs; } function plural_dates($k,$n) { @@ -525,7 +527,7 @@ function update_birthdays() { $z = event_store_event($ev); if ($z) { - $item_id = event_store_item($ev, $z); + event_store_item($ev, $z, false); q("update abook set abook_dob = '%s' where abook_id = %d", dbesc(intval($rr['abook_dob']) + 1 . substr($rr['abook_dob'], 4)), intval($rr['abook_id']) diff --git a/include/event.php b/include/event.php index af27c45b0..2fa1cc4f1 100644 --- a/include/event.php +++ b/include/event.php @@ -235,7 +235,7 @@ function ical_wrapper($ev) { if(! ((is_array($ev)) && count($ev))) return ''; - $o .= "BEGIN:VCALENDAR"; + $o = "BEGIN:VCALENDAR"; $o .= "\r\nVERSION:2.0"; $o .= "\r\nMETHOD:PUBLISH"; $o .= "\r\nPRODID:-//" . Config::Get('system','sitename') . "//" . Zotlabs\Lib\System::get_platform_name() . "//" . strtoupper(App::$language). "\r\n"; @@ -1070,7 +1070,7 @@ function event_import_ical($ical, $uid) { logger('storing event: ' . print_r($ev,true), LOGGER_ALL); $event = event_store_event($ev); if($event) { - $item_id = event_store_item($ev,$event); + event_store_item($ev, $event, false); return true; } } @@ -1205,7 +1205,7 @@ function event_import_ical_task($ical, $uid) { logger('storing event: ' . print_r($ev,true), LOGGER_ALL); $event = event_store_event($ev); if($event) { - $item_id = event_store_item($ev,$event); + event_store_item($ev, $event, false); return true; } } @@ -1214,8 +1214,7 @@ function event_import_ical_task($ical, $uid) { } - -function event_store_item($arr, $event) { +function event_store_item($arr, $event, $deliver = true) { require_once('include/datetime.php'); require_once('include/items.php'); @@ -1234,7 +1233,7 @@ function event_store_item($arr, $event) { } - $item_arr = array(); + $item_arr = []; $prefix = ''; // $birthday = false; @@ -1255,7 +1254,7 @@ function event_store_item($arr, $event) { $item_arr['comment_policy'] = 'none'; } - $r = q("SELECT * FROM item WHERE resource_id = '%s' AND resource_type = 'event' and uid = %d LIMIT 1", + $r = q("SELECT * FROM item left join xchan on author_xchan = xchan_hash WHERE resource_id = '%s' AND resource_type = 'event' and uid = %d LIMIT 1", dbesc($event['event_hash']), intval($arr['uid']) ); @@ -1292,51 +1291,21 @@ function event_store_item($arr, $event) { $object = json_encode($x); - $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); - - /** - * @FIXME can only update sig if we have the author's channel on this site - * Until fixed, set it to nothing so it won't give us signature errors. - */ - $sig = ''; - - q("UPDATE item SET title = '%s', body = '%s', obj = '%s', allow_cid = '%s', allow_gid = '%s', deny_cid = '%s', deny_gid = '%s', edited = '%s', sig = '%s', item_flags = %d, item_private = %d, obj_type = '%s' WHERE id = %d AND uid = %d", - dbesc($arr['summary']), - dbesc($prefix . format_event_bbcode($arr)), - dbesc($object), - dbesc($arr['allow_cid']), - dbesc($arr['allow_gid']), - dbesc($arr['deny_cid']), - dbesc($arr['deny_gid']), - dbesc($arr['edited']), - dbesc($sig), - intval($r[0]['item_flags']), - intval($private), - dbesc('Event'), - intval($r[0]['id']), - intval($arr['uid']) - ); - - q("delete from term where oid = %d and otype = %d", - intval($r[0]['id']), - intval(TERM_OBJ_POST) - ); - - if(($arr['term']) && (is_array($arr['term']))) { - foreach($arr['term'] as $t) { - q("insert into term (uid,oid,otype,ttype,term,url) - values(%d,%d,%d,%d,'%s','%s') ", - intval($arr['uid']), - intval($r[0]['id']), - intval(TERM_OBJ_POST), - intval($t['ttype']), - dbesc($t['term']), - dbesc($t['url']) - ); - } - } - - $item_id = $r[0]['id']; + $item_arr['id'] = $r[0]['id']; + $item_arr['uid'] = $arr['uid']; + $item_arr['obj'] = $object; + $item_arr['edited'] = $arr['edited']; + $item_arr['allow_cid'] = $arr['allow_cid']; + $item_arr['allow_gid'] = $arr['allow_gid']; + $item_arr['deny_cid'] = $arr['deny_cid']; + $item_arr['deny_gid'] = $arr['deny_gid']; + $item_arr['item_private'] = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); + $item_arr['title'] = $arr['summary']; + $item_arr['sig'] = ''; + $item_arr['body'] = $prefix . format_event_bbcode($arr); + $item_arr['term'] = $arr['term']; + + $post = item_store_update($item_arr, deliver: $deliver); /** * @hooks event_updated @@ -1344,14 +1313,10 @@ function event_store_item($arr, $event) { */ call_hooks('event_updated', $event['id']); - return $item_id; + return $post; } else { - $z = q("select * from channel where channel_id = %d limit 1", - intval($arr['uid']) - ); - - $private = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); + $z = channelx_by_n($arr['uid']); $item_wall = 0; $item_origin = 0; @@ -1361,7 +1326,7 @@ function event_store_item($arr, $event) { $item_arr['id'] = $item['id']; } else { - $wall = (($z[0]['channel_hash'] == $event['event_xchan']) ? true : false); + $wall = (($z['channel_hash'] == $event['event_xchan']) ? true : false); $item_thread_top = 1; if($wall) { $item_wall = 1; @@ -1374,20 +1339,20 @@ function event_store_item($arr, $event) { $arr['mid'] = z_root() . '/activity/' . $event['event_hash']; } - $item_arr['aid'] = $z[0]['channel_account_id']; + $item_arr['aid'] = $z['channel_account_id']; $item_arr['uid'] = $arr['uid']; $item_arr['uuid'] = $arr['uuid']; $item_arr['author_xchan'] = $arr['event_xchan']; $item_arr['mid'] = $arr['mid']; $item_arr['parent_mid'] = $arr['mid']; - $item_arr['owner_xchan'] = (($wall) ? $z[0]['channel_hash'] : $arr['event_xchan']); + $item_arr['owner_xchan'] = (($wall) ? $z['channel_hash'] : $arr['event_xchan']); $item_arr['author_xchan'] = $arr['event_xchan']; $item_arr['title'] = $arr['summary']; $item_arr['allow_cid'] = $arr['allow_cid']; $item_arr['allow_gid'] = $arr['allow_gid']; $item_arr['deny_cid'] = $arr['deny_cid']; $item_arr['deny_gid'] = $arr['deny_gid']; - $item_arr['item_private'] = $private; + $item_arr['item_private'] = (($arr['allow_cid'] || $arr['allow_gid'] || $arr['deny_cid'] || $arr['deny_gid']) ? 1 : 0); $item_arr['verb'] = 'Invite'; $item_arr['item_wall'] = $item_wall; $item_arr['item_origin'] = $item_origin; @@ -1452,16 +1417,21 @@ function event_store_item($arr, $event) { $item_arr['obj'] = json_encode($y); } + $item_arr['target'] = [ + 'id' => str_replace('/item/', '/conversation/', $item_arr['parent_mid']), + 'type' => 'Collection', + 'attributedTo' => z_root() . '/channel/' . $z['channel_address'], + ]; + $item_arr['tgt_type'] = 'Collection'; + // propagate the event resource_id so that posts containing it are easily searchable in downstream copies // of the item which have not stored the actual event. Required for Diaspora event federation as Diaspora // event_participation messages refer to the event resource_id as a parent, while out own event attendance // activities refer to the item message_id as the parent. - set_iconfig($item_arr, 'system','event_id',$event['event_hash'],true); - - $res = item_store($item_arr); + set_iconfig($item_arr, 'system', 'event_id', $event['event_hash'], true); - $item_id = $res['item_id']; + $post = item_store($item_arr, deliver: $deliver); /** * @hooks event_created @@ -1469,7 +1439,7 @@ function event_store_item($arr, $event) { */ call_hooks('event_created', $event['id']); - return $item_id; + return $post; } } diff --git a/include/feedutils.php b/include/feedutils.php index a50214746..cc57d106c 100644 --- a/include/feedutils.php +++ b/include/feedutils.php @@ -998,7 +998,7 @@ function process_feed_tombstones($feed,$importer,$contact,$pass) { if(! intval($item['item_deleted'])) { logger('deleting item ' . $item['id'] . ' mid=' . $item['mid'], LOGGER_DEBUG); - drop_item($item['id'],false); + drop_item($item['id']); } } } @@ -1181,7 +1181,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { && $datarray['author_xchan'] === $r[0]['author_xchan']) { if(! intval($r[0]['item_deleted'])) { logger('deleting item ' . $r[0]['id'] . ' mid=' . $datarray['mid'], LOGGER_DEBUG); - drop_item($r[0]['id'],false); + drop_item($r[0]['id']); } continue; } @@ -1449,7 +1449,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) { && isset($datarray['author_xchan']) && $datarray['author_xchan'] === $r[0]['author_xchan']) { if(! intval($r[0]['item_deleted'])) { logger('deleting item ' . $r[0]['id'] . ' mid=' . $datarray['mid'], LOGGER_DEBUG); - drop_item($r[0]['id'],false); + drop_item($r[0]['id']); } continue; } diff --git a/include/help.php b/include/help.php index 0efe90a9f..2358f1289 100644 --- a/include/help.php +++ b/include/help.php @@ -156,12 +156,12 @@ function store_doc_file($s) { if($r) { $item['id'] = $r[0]['id']; $item['mid'] = $item['parent_mid'] = $r[0]['mid']; - $x = item_store_update($item); + $x = item_store_update($item, deliver: false, addAndSync: false); } else { $item['uuid'] = item_message_id(); $item['mid'] = $item['parent_mid'] = z_root() . '/item/' . $item['uuid']; - $x = item_store($item); + $x = item_store($item, deliver: false, addAndSync: false); } return $x; diff --git a/include/html2bbcode.php b/include/html2bbcode.php index 277b0e640..b799a0c28 100644 --- a/include/html2bbcode.php +++ b/include/html2bbcode.php @@ -29,9 +29,6 @@ function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb) foreach ($list as $oldNode) { - if ($oldnode == 'li') - hz_syslog(print_r($oldNode,true)); - $attr = array(); if ($oldNode->attributes->length) foreach ($oldNode->attributes as $attribute) diff --git a/include/import.php b/include/import.php index 479c2c255..77d35a3e7 100644 --- a/include/import.php +++ b/include/import.php @@ -825,13 +825,13 @@ function import_items($channel, $items, $sync = false, $relocate = null) { if($item['edited'] >= $r[0]['edited']) { $item['id'] = $r[0]['id']; $item['uid'] = $channel['channel_id']; - $item_result = item_store_update($item,$allow_code,$deliver); + $item_result = item_store_update($item, $allow_code, $deliver, addAndSync: false); } } else { $item['aid'] = $channel['channel_account_id']; $item['uid'] = $channel['channel_id']; - $item_result = item_store($item,$allow_code,$deliver); + $item_result = item_store($item, $allow_code, $deliver, addAndSync: false); } // preserve conversations you've been involved in from being expired @@ -1886,7 +1886,7 @@ function import_webpage_element($element, $channel, $type) { $arr['id'] = $i[0]['id']; // don't update if it has the same timestamp as the original if($arr['edited'] > $i[0]['edited']) - $x = item_store_update($arr,$execflag); + $x = item_store_update($arr, $execflag, deliver: false, addAndSync: false); } else { if(($i) && (intval($i[0]['item_deleted']))) { @@ -1897,7 +1897,7 @@ function import_webpage_element($element, $channel, $type) { ); } else - $x = item_store($arr,$execflag); + $x = item_store($arr, $execflag, deliver: false, addAndSync: false); } if($x && $x['success']) { diff --git a/include/items.php b/include/items.php index 423d626ad..9ef44e147 100644 --- a/include/items.php +++ b/include/items.php @@ -361,7 +361,7 @@ function can_comment_on_post($observer_xchan, $item) { case 'specific': case 'contacts': case '': - if(local_channel() && get_abconfig(local_channel(), (($item['verb'] === ACTIVITY_SHARE) ? $item['source_xchan'] : $item['owner_xchan']), 'their_perms', 'post_comments')) { + if(local_channel() && get_abconfig(local_channel(), $item['owner_xchan'], 'their_perms', 'post_comments')) { return true; } if(intval($item['item_wall']) && perm_is_allowed($item['uid'],$observer_xchan,'post_comments')) { @@ -431,8 +431,9 @@ function add_source_route($iid, $hash) { * * \e boolean \b success true or false * * \e array \b activity the resulting activity if successful */ -function post_activity_item($arr, $allow_code = false, $deliver = true) { + +function post_activity_item($arr, $allow_code = false, $deliver = true, $channel = null, $observer = null, $addAndSync = true) { $ret = array('success' => false); $is_comment = false; @@ -446,8 +447,13 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) { if(! array_key_exists('item_thread_top',$arr) && (! $is_comment)) $arr['item_thread_top'] = 1; - $channel = App::get_channel(); - $observer = App::get_observer(); + if (!$channel) { + $channel = App::get_channel(); + } + + if (!$observer) { + $observer = App::get_observer(); + } $arr['aid'] = ((x($arr,'aid')) ? $arr['aid'] : $channel['channel_account_id']); $arr['uid'] = ((x($arr,'uid')) ? $arr['uid'] : $channel['channel_id']); @@ -493,6 +499,14 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) { $arr['plink'] = $arr['mid']; } + if (!$arr['target']) { + $arr['target'] = [ + 'id' => str_replace('/item/', '/conversation/', $arr['parent_mid']), + 'type' => 'Collection', + 'attributedTo' => z_root() . '/channel/' . $channel['channel_address'], + ]; + $arr['tgt_type'] = 'Collection'; + } // for the benefit of plugins, we will behave as if this is an API call rather than a normal online post @@ -509,29 +523,30 @@ function post_activity_item($arr, $allow_code = false, $deliver = true) { return $ret; } - $post = item_store($arr,$allow_code,$deliver); - - if($post['success']) { - $post_id = $post['item_id']; - $ret['success'] = true; - $ret['item_id'] = $post_id; - $ret['activity'] = $post['item']; + $post = item_store($arr, $allow_code, $deliver, $addAndSync); - /** - * @hooks post_local_end - * Called after a local post operation has completed. - * * \e array - the item returned from item_store() - */ - call_hooks('post_local_end', $ret['activity']); - } - else + if (!$post['success']) { return $ret; - - if($post_id && $deliver) { - Master::Summon(['Notifier','activity', $post_id]); } + $post_id = $post['item_id']; $ret['success'] = true; + $ret['item_id'] = $post_id; + $ret['activity'] = $post['item']; + + /** + * @hooks post_local_end + * Called after a local post operation has completed. + * * \e array - the item returned from item_store() + */ + call_hooks('post_local_end', $ret['activity']); + + if($post_id && $deliver) { + Master::Summon(['Notifier', 'activity', $post_id]); + if (!empty($post['approval_id'])) { + Master::Summon(['Notifier', 'activity', $post['approval_id']]); + } + } return $ret; } @@ -1594,7 +1609,7 @@ function item_json_encapsulate($arr, $k) { * * \e boolean \b success * * \e int \b item_id */ -function item_store($arr, $allow_exec = false, $deliver = true) { +function item_store($arr, $allow_exec = false, $deliver = true, $addAndSync = true) { $d = [ 'item' => $arr, @@ -1882,7 +1897,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) { $arr['item_private'] = 0; if(in_array($arr['obj_type'], ['Note','Answer']) && $r[0]['obj_type'] === 'Question' && intval($r[0]['item_wall'])) { - Activity::update_poll($r[0]['id'], $arr); + Activity::update_poll($r[0], $arr); } } @@ -2052,6 +2067,13 @@ function item_store($arr, $allow_exec = false, $deliver = true) { Master::Summon([ 'Cache_embeds', $current_post ]); } + $ret['success'] = true; + $ret['item_id'] = $current_post; + + if ($addAndSync) { + $ret = addToCollectionAndSync($ret); + } + // If _creating_ a deleted item, don't propagate it further or send out notifications. // We need to store the item details just in case the delete came in before the original post, // so that we have an item in the DB that's marked deleted and won't store a fresh post @@ -2062,9 +2084,6 @@ function item_store($arr, $allow_exec = false, $deliver = true) { tag_deliver($arr['uid'],$current_post); } - $ret['success'] = true; - $ret['item_id'] = $current_post; - return $ret; } @@ -2077,7 +2096,7 @@ function item_store($arr, $allow_exec = false, $deliver = true) { * @param boolean $deliver (optional) default true * @return array */ -function item_store_update($arr, $allow_exec = false, $deliver = true) { +function item_store_update($arr, $allow_exec = false, $deliver = true, $addAndSync = true) { $d = [ 'item' => $arr, @@ -2390,17 +2409,19 @@ function item_store_update($arr, $allow_exec = false, $deliver = true) { Master::Summon([ 'Cache_embeds', $orig_post_id ]); } + $ret['success'] = true; + $ret['item_id'] = $orig_post_id; - + if ($addAndSync) { + $ret = addToCollectionAndSync($ret); + } if($deliver) { - send_status_notifications($orig_post_id,$arr); + // don't send notify_comment for edits + // send_status_notifications($orig_post_id,$arr); tag_deliver($uid,$orig_post_id); } - $ret['success'] = true; - $ret['item_id'] = $orig_post_id; - return $ret; } @@ -3101,6 +3122,11 @@ function i_am_mentioned($channel, $item, $check_groups = false) { */ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false, $edit = false) { + if ($item['author_xchan'] === $channel['channel_hash'] && in_array($item['verb'], ['Add', 'Remove'])) { + logger('delivery chain already started'); + return; + } + $sourced = check_item_source($channel['channel_id'],$item); if($sourced) { @@ -3147,7 +3173,7 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $item['thr_parent'] = $item['mid']; $item['llink'] = z_root() . '/display/' . $item['uuid']; } - +/* $r = q("UPDATE item SET author_xchan = '%s', mid = '%s', parent_mid = '%s', thr_parent = '%s', llink = '%s' WHERE id = %d", dbesc($item['author_xchan']), dbesc($item['mid']), @@ -3156,7 +3182,108 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false dbesc($item['llink']), intval($item_id) ); +*/ + } + + hz_syslog('gothere'); + // sourced + + $private = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] + || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); + + $new_public_policy = map_scope(PermissionLimits::Get($channel['channel_id'],'view_stream'),true); + + if((! $private) && $new_public_policy) + $private = 1; + + $item_wall = 1; + $item_origin = (($item['item_deleted']) ? 0 : 1); // item_origin for deleted items is set to 0 in delete_imported_item() to prevent looping. In this case we probably should not set it back to 1 here. + $item_uplink = 0; + $item_nocomment = 0; + + $flag_bits = $item['item_flags']; + + // maintain the original source, which will be the original item owner and was stored in source_xchan + // when we created the delivery fork + + if($parent) { + $r = q("update item set source_xchan = '%s' where id = %d", + dbesc($parent['source_xchan']), + intval($item_id) + ); + } + else { + $item_uplink = (($item['item_rss']) ? 0 : 1); // Do not set item_uplink for rss items - we can not send anything to them. + + // if this is an edit, item_store_update() will have already updated the item + // with the correct value for source_xchan (by ignoring it). We cannot set to owner_xchan + // in this case because owner_xchan will point to the parent of this chain + // and not the original sender. + + if(!$edit) { + $r = q("update item set source_xchan = owner_xchan where id = %d", + intval($item_id) + ); + } + } + + // this will not work with item_store_update() + + $r = q("update item set item_uplink = %d, item_nocomment = %d, item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s', + deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s', item_wall = %d, item_origin = %d, + author_xchan = '%s', mid = '%s', parent_mid = '%s', thr_parent = '%s', llink = '%s' where id = %d", + intval($item_uplink), + intval($item_nocomment), + intval($flag_bits), + dbesc($channel['channel_hash']), + dbesc($channel['channel_allow_cid']), + dbesc($channel['channel_allow_gid']), + dbesc($channel['channel_deny_cid']), + dbesc($channel['channel_deny_gid']), + intval($private), + dbesc($new_public_policy), + dbesc(map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'))), + dbesc($item['title']), + dbesc($item['body']), + intval($item_wall), + intval($item_origin), + dbesc($item['author_xchan']), + dbesc($item['mid']), + dbesc($item['parent_mid']), + dbesc($item['thr_parent']), + dbesc($item['llink']), + intval($item_id) + ); + + if($r) { + $rr = q("select * from item where id = %d", + intval($item_id) + ); + + if ($rr) { + + // this is hackish but since we can not use item_store_update() here, + // we will prepare a similar output to feed to addToCollectionAndSync() + $ret['success'] = 1; + $ret['item_id'] = $rr[0]['id']; + $ret['item'] = $rr[0]; + + $result = addToCollectionAndSync($ret); + + Master::Summon(['Notifier', 'tgroup', $result['item_id']]); + if ($result['approval_id']) { + Master::Summon(['Notifier', 'tgroup', $result['approval_id']]); + } + } + } + else { + logger('start_delivery_chain: failed to update item'); + // reset the source xchan to prevent loops + $r = q("update item set source_xchan = '' where id = %d", + intval($item_id) + ); } + return; } if ($group && (! $parent)) { @@ -3178,8 +3305,8 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false if ($r) { if (intval($item['item_deleted'])) { - drop_item($r[0]['id'], false, DROPITEM_PHASE1); - Master::Summon([ 'Notifier', 'drop', $r[0]['id'] ]); + drop_item($r[0]['id'], DROPITEM_PHASE1, uid: $r[0]['uid']); + Master::Summon(['Notifier', 'drop' ,$r[0]['id']]); return; } $arr['id'] = intval($r[0]['id']); @@ -3261,8 +3388,15 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false } $arr['title'] = $item['title']; - $arr['tgt_type'] = $item['tgt_type']; - $arr['target'] = $item['target']; +// $arr['tgt_type'] = $item['tgt_type']; +// $arr['target'] = $item['target']; + + $arr['tgt_type'] = 'Collection'; + $arr['target'] = [ + 'id' => str_replace('/item/', '/conversation/', $arr['parent_mid']), + 'type' => 'Collection', + 'attributedTo' => channel_url($channel['channel_address']) + ]; $arr['term'] = $item['term']; @@ -3285,10 +3419,14 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $post = item_store($arr); } - $post_id = $post['item_id']; + $post_id = $post['item_id'] ?? 0; + $approval_id = $post['approval_id'] ?? 0; if($post_id) { Master::Summon([ 'Notifier','tgroup',$post_id ]); + if ($approval_id) { + Master::Summon(['Notifier', 'tgroup', $approval_id]); + } } return; } @@ -3313,14 +3451,14 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false if ($edit) { if (intval($item['item_deleted'])) { - drop_item($item['id'],false,DROPITEM_PHASE1); - Master::Summon([ 'Notifier','drop',$item['id'] ]); + drop_item($item['id'], DROPITEM_PHASE1, uid: $item['uid']); + Master::Summon(['Notifier', 'drop', $item['id']]); return; } return; } else { - $arr['uuid'] = item_message_id(); + $arr['uuid'] = uuid_from_url($item['mid']); $arr['mid'] = z_root() . '/activity/' . $arr['uuid']; $arr['parent_mid'] = $item['parent_mid']; //IConfig::Set($arr,'activitypub','context', str_replace('/item/','/conversation/',$item['parent_mid'])); @@ -3364,12 +3502,12 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false $arr['deny_gid'] = $channel['channel_deny_gid']; $arr['comment_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments')); - $post = item_store($arr); - $post_id = $post['item_id']; + $post = item_store($arr, deliver: false, addAndSync: false); + $post_id = $post['item_id'] ?? 0; - if ($post_id) { - Master::Summon([ 'Notifier','tgroup',$post_id ]); - } + if ($post_id) { + Master::Summon(['Notifier', 'tgroup', $post_id]); + } q("update channel set channel_lastpost = '%s' where channel_id = %d", dbesc(datetime_convert()), @@ -3379,81 +3517,6 @@ function start_delivery_chain($channel, $item, $item_id, $parent, $group = false return; } - - // Change this copy of the post to a forum head message and deliver to all the tgroup members - // also reset all the privacy bits to the forum default permissions - - $private = (($channel['channel_allow_cid'] || $channel['channel_allow_gid'] - || $channel['channel_deny_cid'] || $channel['channel_deny_gid']) ? 1 : 0); - - $new_public_policy = map_scope(PermissionLimits::Get($channel['channel_id'],'view_stream'),true); - - if((! $private) && $new_public_policy) - $private = 1; - - $item_wall = 1; - $item_origin = (($item['item_deleted']) ? 0 : 1); // item_origin for deleted items is set to 0 in delete_imported_item() to prevent looping. In this case we probably should not set it back to 1 here. - $item_uplink = 0; - $item_nocomment = 0; - - $flag_bits = $item['item_flags']; - - // maintain the original source, which will be the original item owner and was stored in source_xchan - // when we created the delivery fork - - if($parent) { - $r = q("update item set source_xchan = '%s' where id = %d", - dbesc($parent['source_xchan']), - intval($item_id) - ); - } - else { - $item_uplink = (($item['item_rss']) ? 0 : 1); // Do not set item_uplink for rss items - we can not send anything to them. - - // if this is an edit, item_store_update() will have already updated the item - // with the correct value for source_xchan (by ignoring it). We cannot set to owner_xchan - // in this case because owner_xchan will point to the parent of this chain - // and not the original sender. - - if(! $edit) { - $r = q("update item set source_xchan = owner_xchan where id = %d", - intval($item_id) - ); - } - } - - $title = $item['title']; - $body = $item['body']; - - $r = q("update item set item_uplink = %d, item_nocomment = %d, item_flags = %d, owner_xchan = '%s', allow_cid = '%s', allow_gid = '%s', - deny_cid = '%s', deny_gid = '%s', item_private = %d, public_policy = '%s', comment_policy = '%s', title = '%s', body = '%s', item_wall = %d, item_origin = %d where id = %d", - intval($item_uplink), - intval($item_nocomment), - intval($flag_bits), - dbesc($channel['channel_hash']), - dbesc($channel['channel_allow_cid']), - dbesc($channel['channel_allow_gid']), - dbesc($channel['channel_deny_cid']), - dbesc($channel['channel_deny_gid']), - intval($private), - dbesc($new_public_policy), - dbesc(map_scope(PermissionLimits::Get($channel['channel_id'],'post_comments'))), - dbesc($title), - dbesc($body), - intval($item_wall), - intval($item_origin), - intval($item_id) - ); - - if($r) - Master::Summon([ 'Notifier','tgroup',$item_id ]); - else { - logger('start_delivery_chain: failed to update item'); - // reset the source xchan to prevent loops - $r = q("update item set source_xchan = '' where id = %d", - intval($item_id) - ); - } } /** @@ -3792,7 +3855,7 @@ function item_expire($uid,$days,$comment_days = 7) { if ($r) { foreach ($r as $item) { - drop_item($item['id'], false); + drop_item($item['id'], expire: true); } } @@ -3805,25 +3868,12 @@ function retain_item($id) { ); } -function drop_items($items,$interactive = false,$stage = DROPITEM_NORMAL) { - $uid = 0; - - if(! local_channel() && ! remote_channel()) - return; - - if(count($items)) { +function drop_items($items, $stage = DROPITEM_NORMAL, $force = false, $expire = false) { + if ($items) { foreach($items as $item) { - $owner = drop_item($item,$interactive,$stage); - if($owner && ! $uid) - $uid = $owner; + drop_item($item, $stage, $force, expire: $expire); } } - - // multiple threads may have been deleted, send an expire notification - - if($uid) { - Master::Summon([ 'Notifier','expire',$uid ]); - } } @@ -3836,7 +3886,7 @@ function drop_items($items,$interactive = false,$stage = DROPITEM_NORMAL) { // $stage = 1 => set deleted flag on the item and perform intial notifications // $stage = 2 => perform low level delete at a later stage -function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { +function drop_item($id, $stage = DROPITEM_NORMAL, $force = false, $uid = 0, $observer_hash = '', $expire = false, $recurse = false) { // locate item to be deleted @@ -3844,33 +3894,48 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { intval($id) ); - if((! $r) || (intval($r[0]['item_deleted']) && ($stage === DROPITEM_NORMAL))) { - if(! $interactive) - return 0; - notice( t('Item not found.') . EOL); - //goaway(z_root() . '/' . $_SESSION['return_url']); + if(!$r || (intval($r[0]['item_deleted']) && $stage === DROPITEM_NORMAL)) { + return false; } $item = $r[0]; - $ok_to_delete = false; + if(!$recurse) { + drop_related($item, $stage, $force, $uid, $observer_hash, $expire); + } - // system deletion - if(! $interactive) - $ok_to_delete = true; + $ok_to_delete = false; // admin deletion - if(is_site_admin()) + if(is_site_admin()) { $ok_to_delete = true; + } // owner deletion - if(local_channel() && local_channel() == $item['uid']) + if(local_channel() && local_channel() == $item['uid']) { $ok_to_delete = true; + } + + // remote delete when nobody is authenticated (called from Libzot) + if ($uid && intval($uid) === intval($item['uid'])) { + $ok_to_delete = true; + } // author deletion - $observer = App::get_observer(); - if($observer && $observer['xchan_hash'] && ($observer['xchan_hash'] === $item['author_xchan'])) + if ($observer_hash) { + $observer = ['xchan_hash' => $observer_hash]; + } + else { + $observer = App::get_observer(); + } + + if (isset($observer['xchan_hash']) && $observer['xchan_hash'] === $item['author_xchan']) { $ok_to_delete = true; + } + + if (isset($observer['xchan_hash']) && $observer['xchan_hash'] === $item['owner_xchan']) { + $ok_to_delete = true; + } if($ok_to_delete) { @@ -3883,9 +3948,9 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { $arr = [ 'item' => $item, - 'interactive' => $interactive, 'stage' => $stage ]; + /** * @hooks drop_item * Called when an 'item' is removed. @@ -3908,30 +3973,95 @@ function drop_item($id,$interactive = true,$stage = DROPITEM_NORMAL) { delete_item_lowlevel($item, $stage); } - if(! $interactive) - return 1; + return true; + } + else { + return false; + } +} - // send the notification upstream/downstream as the case may be - // only send notifications to others if this is the owner's wall item. - // This isn't optimal. We somehow need to pass to this function whether or not - // to call the notifier, or we need to call the notifier from the calling function. - // We'll rely on the undocumented behaviour that DROPITEM_PHASE1 is (hopefully) only - // set if we know we're going to send delete notifications out to others. +// If somebody deletes a 'Create' activity, find any associated 'Add/Collection' +// activity and delete it. And vice versa. - if((intval($item['item_wall']) && ($stage != DROPITEM_PHASE2)) || ($stage == DROPITEM_PHASE1)) { - Master::Summon([ 'Notifier','drop',$notify_id ]); +function drop_related($item, $stage = DROPITEM_NORMAL, $force = false, $uid = 0, $observer_hash = '', $expire = false, $recurse = false) { + $allRelated = q("select * from item where parent_mid = '%s' and uid = %d", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + if (! $allRelated) { + return; + } + if ($item['verb'] === 'Add' && $item['tgt_type'] === 'Collection') { + if (is_array($item['obj'])) { + $thisItem = $item['obj']; + } + else { + $thisItem = json_decode($item['obj'], true); + } + if (isset($thisItem['object']['id'])) { + $targetMid = $thisItem['object']['id']; + } + if (!$targetMid) { + return; + } + foreach ($allRelated as $related) { + if ($related['mid'] === $targetMid) { + drop_item($related['id'], $stage, $force, $uid, $observer_hash, $expire, recurse: true); + break; + } } - //goaway(z_root() . '/' . $_SESSION['return_url']); } else { - if(! $interactive) - return 0; - notice( t('Permission denied.') . EOL); - //goaway(z_root() . '/' . $_SESSION['return_url']); + foreach ($allRelated as $related) { + if ($related['verb'] === 'Add' && str_contains($related['tgt_type'], 'Collection')) { + $thisItem = json_decode($related['obj'], true); + if (isset($thisItem['id']) && $thisItem['id'] === str_replace('/item/', '/activity/', $item['mid'])) { + drop_item($related['id'], $stage, $force, $uid, $observer_hash, $expire, recurse: true); + break; + } + } + } } } + +function find_related($item) { + $allRelated = q("select * from item where parent_mid = '%s' and uid = %d", + dbesc($item['parent_mid']), + intval($item['uid']) + ); + if (! $allRelated) { + return false; + } + if ($item['verb'] === 'Add' && $item['tgt_type'] === 'Collection') { + $thisItem = json_decode($item['obj'],true); + if (is_array($thisItem)) { + $targetMid = $thisItem['object']['id']; + } + if (!$targetMid) { + return false; + } + foreach ($allRelated as $related) { + if ($related['mid'] === $targetMid) { + return $related; + } + } + } + else { + foreach ($allRelated as $related) { + if ($related['verb'] === 'Add' && str_contains($related['tgt_type'], 'Collection')) { + $thisItem = json_decode($related['obj'], true); + if (isset($thisItem['object']['id']) && $thisItem['object']['id'] === $item['mid']) { + return $related; + } + } + } + } + return false; +} + + /** * @warning This function does not check for permission and does not send * notifications and does not check recursion. @@ -5094,7 +5224,7 @@ function fix_attached_permissions($uid, $body, $str_contact_allow, $str_group_al * which will allow you to interact with it. */ -function copy_of_pubitem($channel,$mid) { +function copy_of_pubitem($channel, $mid) { $result = null; $syschan = get_sys_channel(); @@ -5130,9 +5260,10 @@ function copy_of_pubitem($channel,$mid) { $rv['item_wall'] = 0; $rv['item_origin'] = 0; - $x = item_store($rv); + $x = item_store($rv, deliver: false, addAndSync: false); if($x['item_id'] && $x['item']['mid'] === $mid) { $result = $x['item']; + sync_an_item($channel['channel_id'], $x['item_id']); } } @@ -5140,3 +5271,69 @@ function copy_of_pubitem($channel,$mid) { return $result; } + +function addToCollectionAndSync($ret) { + if (!$ret['success']) { + return $ret; + } + + $channel = channelx_by_n($ret['item']['uid']); + if ($channel && $channel['channel_hash'] === $ret['item']['owner_xchan']) { + $items = [$ret['item']]; + + if ((int)$items[0]['item_blocked'] === ITEM_MODERATED + || (int)$items[0]['item_unpublished'] || (int)$items[0]['item_delayed']) { + return $ret; + } + + xchan_query($items); + $items = fetch_post_tags($items); + $sync_items = []; + $sync_items[] = encode_item($items[0], true); + + if (!in_array($ret['item']['verb'], ['Add', 'Remove'])) { + + $new_obj = Activity::build_packet(Activity::encode_activity($items[0]), $channel, false); + $approval = Activity::addToCollection($channel, $new_obj, $ret['item']['parent_mid'], $ret['item'], deliver: false); + + if ($approval['success']) { + $ret['approval_id'] = $approval['item_id']; + $ret['approval'] = $approval['activity']; + $add_items = [$approval['activity']]; + xchan_query($add_items); + $add_items = fetch_post_tags($add_items); + $sync_items[] = encode_item($add_items[0], true); + } + } + + $resource_type = $ret['item']['resource_type']; + + if ($resource_type === 'event') { + $z = q("select * from event where event_hash = '%s' and uid = %d limit 1", + dbesc($ret['item']['resource_id']), + intval($channel['channel_id']) + ); + + if ($z) { + Libsync::build_sync_packet($channel['channel_id'], ['event_item' => $sync_items, 'event' => $z]); + } + } + elseif ($resource_type === 'photo') { + // reserved for future use, currently handled in the photo upload workflow + } + else { + Libsync::build_sync_packet($ret['item']['uid'], ['item' => $sync_items]); + } + } + + return $ret; +} + +function reverse_activity_mid($string) { + return str_replace(z_root() . '/activity/', z_root() . '/item/', $string); +} + +function set_activity_mid($string) { + return str_replace(z_root() . '/item/', z_root() . '/activity/', $string); +} + diff --git a/include/network.php b/include/network.php index b3a3d715c..0a78c144b 100644 --- a/include/network.php +++ b/include/network.php @@ -1488,7 +1488,7 @@ function do_delivery($deliveries, $force = false) { $interval = Config::Get('queueworker', 'queue_interval', 500000); - $deliveries_per_process = intval(Config::Get('system','delivery_batch_count')); +// $deliveries_per_process = intval(Config::Get('system','delivery_batch_count')); if($deliveries_per_process <= 0) $deliveries_per_process = 1; diff --git a/include/permissions.php b/include/permissions.php index be6fc8594..29d242537 100644 --- a/include/permissions.php +++ b/include/permissions.php @@ -408,7 +408,7 @@ function get_all_api_perms($uid,$api) { $arr = array( 'channel_id' => $uid, - 'observer_hash' => $observer_xchan, + 'observer_hash' => null, //$observer_xchan, 'permissions' => $ret); call_hooks('get_all_api_perms',$arr); @@ -422,7 +422,7 @@ function api_perm_is_allowed($uid,$api,$permission) { $arr = array( 'channel_id' => $uid, - 'observer_hash' => $observer_xchan, + 'observer_hash' => null, //$observer_xchan, 'permission' => $permission, 'result' => false ); diff --git a/include/photos.php b/include/photos.php index 85c97d1fd..390754f39 100644 --- a/include/photos.php +++ b/include/photos.php @@ -7,6 +7,7 @@ use Zotlabs\Access\PermissionLimits; use Zotlabs\Lib\Activity; use Zotlabs\Lib\Config; +use Zotlabs\Daemon\Master; require_once('include/permissions.php'); require_once('include/items.php'); @@ -405,7 +406,7 @@ function photo_upload($channel, $observer, $args) { } } - $attribution = (($visitor) ? $visitor : $channel['xchan_url']); + $attribution = (($visitor) ? $visitor : channel_url($channel)); //// Create item object $object = [ @@ -438,13 +439,13 @@ function photo_upload($channel, $observer, $args) { else { $object['to'] = Activity::map_acl(array_merge($ac, ['item_private' => 1 - intval($public)])); } - +/* $target = [ 'type' => 'orderedCollection', 'name' => ((strlen($album)) ? $album : '/'), 'id' => z_root() . '/album/' . $channel['channel_address'] . ((isset($args['directory']['hash'])) ? '/' . $args['directory']['hash'] : EMPTY_STR) ]; - +*/ // Create item container if (isset($args['item'])) { foreach ($args['item'] as $i) { @@ -453,6 +454,11 @@ function photo_upload($channel, $observer, $args) { $force = false; if ($item['mid'] === $item['parent_mid']) { + $target = [ + 'id' => str_replace('/item/', '/conversation/', $item['mid']), + 'type' => 'Collection', + 'attributedTo' => $attribution, + ]; $item['body'] = $summary; $item['mimetype'] = 'text/bbcode'; @@ -460,10 +466,10 @@ function photo_upload($channel, $observer, $args) { $object['id'] = $item['mid']; $object['diaspora:guid'] = $item['uuid']; - $item['obj'] = json_encode($object); + $item['obj'] = $object; - $item['tgt_type'] = 'orderedCollection'; - $item['target'] = json_encode($target); + $item['tgt_type'] = 'Collection'; + $item['target'] = $target; if ($post_tags) { $arr['term'] = $post_tags; } @@ -477,15 +483,23 @@ function photo_upload($channel, $observer, $args) { if (($item['edited'] > $r[0]['edited']) || $force) { $item['id'] = $r[0]['id']; $item['uid'] = $channel['channel_id']; - item_store_update($item, false, $deliver); + $result = item_store_update($item, deliver: $deliver); continue; } } else { $item['aid'] = $channel['channel_account_id']; $item['uid'] = $channel['channel_id']; - item_store($item, false, $deliver); + $result = item_store($item, deliver: $deliver); } + + if ($result['success'] && $visible && $deliver) { + Master::Summon(['Notifier', 'wall-new', $result['item_id']]); + if (!empty($result['approval_id'])) { + Master::Summon(['Notifier', 'wall-new', $result['approval_id']]); + } + } + } } else { @@ -496,6 +510,12 @@ function photo_upload($channel, $observer, $args) { $object['id'] = $mid; $object['diaspora:guid'] = $uuid; + $target = [ + 'id' => z_root() . '/conversation/' . $uuid, + 'type' => 'Collection', + 'attributedTo' => $attribution, + ]; + $arr = [ 'aid' => $account_id, 'uid' => $channel_id, @@ -514,9 +534,9 @@ function photo_upload($channel, $observer, $args) { 'deny_gid' => $ac['deny_gid'], 'verb' => 'Create', 'obj_type' => 'Image', - 'obj' => json_encode($object), - 'tgt_type' => 'orderedCollection', - 'target' => json_encode($target), + 'obj' => $object, + 'tgt_type' => 'Collection', + 'target' => $target, 'item_wall' => $visible, 'item_origin' => 1, 'item_thread_top' => 1, @@ -541,14 +561,19 @@ function photo_upload($channel, $observer, $args) { // linked item from leaking into the feed when somebody has a channel with read_stream restrictions. $arr['public_policy'] = map_scope(PermissionLimits::Get($channel['channel_id'], 'view_stream'), true); - if ($arr['public_policy']) + + if ($arr['public_policy']) { $arr['item_private'] = 1; + } - $result = item_store($arr, false, $deliver); - $item_id = $result['item_id']; + $result = item_store($arr, deliver: $deliver); - if ($visible && $deliver) - Zotlabs\Daemon\Master::Summon(['Notifier', 'wall-new', $item_id]); + if ($result['success'] && $visible && $deliver) { + Master::Summon(['Notifier', 'wall-new', $result['item_id']]); + if (!empty($result['approval_id'])) { + Master::Summon(['Notifier', 'wall-new', $result['approval_id']]); + } + } } $ret['success'] = true; @@ -911,7 +936,7 @@ function photos_create_item($channel, $creator_hash, $photo, $visible = false) { . '[zmg]' . z_root() . '/photo/' . $photo['resource_id'] . '-' . $photo['imgscale'] . '[/zmg]' . '[/zrl]'; - $result = item_store($arr); + $result = item_store($arr, deliver: false, addAndSync: true); $item_id = $result['item_id']; return $item_id; diff --git a/view/css/conversation.css b/view/css/conversation.css index 491cee92e..fb26c7e3f 100644 --- a/view/css/conversation.css +++ b/view/css/conversation.css @@ -96,10 +96,6 @@ /* conv_item */ -.wall-item-head-new { - border-top: 0.2rem solid var(--bs-primary); -} - .wall-item-wrapper { margin-left: .75rem; } diff --git a/view/js/mod_import_progress.js b/view/js/mod_import_progress.js index 7aed56365..11b324862 100644 --- a/view/js/mod_import_progress.js +++ b/view/js/mod_import_progress.js @@ -30,6 +30,9 @@ $(document).ready(function() { $('#cprogress-bar').css('width', '0%'); } + $('#cprogress-completed span').html(data.ccompleted_str); + + // files if (typeof data.fprogress == 'number') { $('#fprogress-label').html(data.fprogress + '%'); @@ -50,5 +53,8 @@ $(document).ready(function() { $('#fprogress-label').html(data.fprogress); $('#fprogress-bar').css('width', '0%'); } + + $('#fprogress-completed span').html(data.fcompleted_str); + } }); diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css index 12f5e1bad..85f5939f8 100644 --- a/view/theme/redbasic/css/style.css +++ b/view/theme/redbasic/css/style.css @@ -1144,12 +1144,20 @@ a .drop-icons:hover { .generic-content-wrapper { background-color: var(--bs-body-bg); - border: 1px solid var(--bs-border-color); + border: 1px solid var(--bs-light-border-subtle); border-radius: var(--bs-border-radius); margin-bottom: 1.5rem; font-size: 1.1rem; } +.generic-content-wrapper.is-contained { + border: 1px solid var(--bs-primary-border-subtle); +} + +.generic-content-wrapper.is-new { + border-top: 2px solid var(--bs-primary); +} + .section-title-wrapper { padding: 7px 10px; background-color: var(--bs-tertiary-bg); diff --git a/view/tpl/conv_item.tpl b/view/tpl/conv_item.tpl index c646387d7..74e06d6ac 100644 --- a/view/tpl/conv_item.tpl +++ b/view/tpl/conv_item.tpl @@ -4,7 +4,7 @@ </div> <div id="collapsed-comments-{{$item.id}}" class="collapsed-comments" style="display: none;"> {{/if}} - <div id="thread-wrapper-{{$item.id}}" class="thread-wrapper{{if $item.toplevel}} {{$item.toplevel}} generic-content-wrapper h-entry {{else}} u-comment h-cite{{/if}} clearfix" data-b64mids='{{$item.mids}}'> + <div id="thread-wrapper-{{$item.id}}" class="thread-wrapper{{if $item.toplevel}} {{$item.toplevel}} generic-content-wrapper h-entry {{else}} u-comment h-cite{{/if}} clearfix{{if $item.is_contained}} is-contained{{/if}}{{if $item.is_new && !$item.event && !$item.photo && !$item.title && !$item.is_comment}} is-new{{/if}}" data-b64mids='{{$item.mids}}'> <a name="item_{{$item.id}}" ></a> <div class="wall-item-outside-wrapper{{if $item.is_comment}} comment{{/if}}{{if $item.previewing}} preview{{/if}}" id="wall-item-outside-wrapper-{{$item.id}}" > <div class="rounded wall-item-content-wrapper{{if $item.is_comment}} comment{{/if}}" id="wall-item-content-wrapper-{{$item.id}}"> @@ -26,7 +26,7 @@ <hr class="m-0"> {{/if}} {{/if}} - <div class="p-2 wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}}{{if $item.is_new && !$item.event && !$item.is_comment}} wall-item-head-new{{/if}} clearfix"> + <div class="p-2 wall-item-head{{if !$item.title && !$item.event && !$item.photo}} rounded-top{{/if}} clearfix"> <div class="lh-sm text-end float-end"> <div class="wall-item-ago opacity-75" id="wall-item-ago-{{$item.id}}"> {{if $item.location}} @@ -255,7 +255,7 @@ {{/foreach}} {{/if}} {{if $item.comment}} - <div id="wall-item-comment-wrapper-{{$item.id}}" class="p-2 wall-item-comment-wrapper{{if $item.children}} wall-item-comment-wrapper-wc{{/if}}" > + <div id="wall-item-comment-wrapper-{{$item.id}}" class="p-2 rounded wall-item-comment-wrapper{{if $item.children}} wall-item-comment-wrapper-wc{{/if}}"> {{$item.comment}} </div> {{/if}} diff --git a/view/tpl/conv_list.tpl b/view/tpl/conv_list.tpl index a54a52369..41880029f 100644 --- a/view/tpl/conv_list.tpl +++ b/view/tpl/conv_list.tpl @@ -1,7 +1,7 @@ - <div id="thread-wrapper-{{$item.id}}" class="thread-wrapper{{if $item.toplevel}} {{$item.toplevel}} generic-content-wrapper h-entry {{else}} u-comment h-cite {{/if}}" data-b64mids='{{$item.mids}}'> + <div id="thread-wrapper-{{$item.id}}" class="thread-wrapper{{if $item.toplevel}} {{$item.toplevel}} generic-content-wrapper h-entry {{else}} u-comment h-cite{{/if}} clearfix{{if $item.is_contained}} is-contained{{/if}}{{if $item.is_new && !$item.event && !$item.title && !$item.is_comment}} is-new{{/if}}" data-b64mids='{{$item.mids}}'> <a name="item_{{$item.id}}" ></a> <div class="wall-item-outside-wrapper{{if $item.is_comment}} comment{{/if}}{{if $item.previewing}} preview{{/if}}" id="wall-item-outside-wrapper-{{$item.id}}" > - <div class="clearfix wall-item-content-wrapper{{if $item.is_comment}} comment{{/if}}" id="wall-item-content-wrapper-{{$item.id}}"> + <div class="rounded clearfix wall-item-content-wrapper{{if $item.is_comment}} comment{{/if}}" id="wall-item-content-wrapper-{{$item.id}}"> {{if $item.photo}} <div class="wall-photo-item" id="wall-photo-item-{{$item.id}}"> {{$item.photo}} |