2021-09-18 05:37:41 +02:00
< ? php
2022-01-02 10:49:50 +01:00
/**
* @ copyright Copyright ( C ) 2010 - 2022 , the Friendica project
*
* @ license GNU AGPL version 3 or any later version
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation , either version 3 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*
*/
2021-09-18 05:37:41 +02:00
namespace Friendica\Navigation\Notifications\Factory ;
use Friendica\App\BaseURL ;
use Friendica\BaseFactory ;
use Friendica\Capabilities\ICanCreateFromTableRow ;
2022-03-03 14:49:07 +01:00
use Friendica\Contact\LocalRelationship\Repository\LocalRelationship ;
2022-05-18 22:05:29 +02:00
use Friendica\Content\Text\BBCode ;
2021-09-18 05:37:41 +02:00
use Friendica\Content\Text\Plaintext ;
2022-05-18 22:05:29 +02:00
use Friendica\Core\Cache\Enum\Duration ;
use Friendica\Core\Cache\Capability\ICanCache ;
2021-09-18 05:37:41 +02:00
use Friendica\Core\L10n ;
use Friendica\Model\Contact ;
use Friendica\Model\Post ;
2022-06-04 16:08:11 +02:00
use Friendica\Model\User ;
2021-09-18 05:37:41 +02:00
use Friendica\Model\Verb ;
use Friendica\Navigation\Notifications\Entity ;
2022-03-03 14:49:07 +01:00
use Friendica\Network\HTTPException ;
2021-09-18 05:37:41 +02:00
use Friendica\Protocol\Activity ;
2022-03-03 14:49:07 +01:00
use Psr\Log\LoggerInterface ;
2021-09-18 05:37:41 +02:00
class Notification extends BaseFactory implements ICanCreateFromTableRow
{
2022-03-03 14:49:07 +01:00
/** @var BaseURL */
private $baseUrl ;
/** @var L10n */
private $l10n ;
/** @var LocalRelationship */
private $localRelationshipRepo ;
2022-05-18 22:05:29 +02:00
/** @var ICanCache */
private $cache ;
2022-03-03 14:49:07 +01:00
2022-05-19 11:08:04 +02:00
public function __construct ( \Friendica\App\BaseURL $baseUrl , \Friendica\Core\L10n $l10n , \Friendica\Contact\LocalRelationship\Repository\LocalRelationship $localRelationshipRepo , LoggerInterface $logger , ICanCache $cache )
2022-03-03 14:49:07 +01:00
{
parent :: __construct ( $logger );
$this -> baseUrl = $baseUrl ;
$this -> l10n = $l10n ;
$this -> localRelationshipRepo = $localRelationshipRepo ;
2022-05-19 11:08:04 +02:00
$this -> cache = $cache ;
2022-03-03 14:49:07 +01:00
}
2021-09-18 05:37:41 +02:00
public function createFromTableRow ( array $row ) : Entity\Notification
{
return new Entity\Notification (
$row [ 'uid' ] ? ? 0 ,
Verb :: getByID ( $row [ 'vid' ]),
$row [ 'type' ],
$row [ 'actor-id' ],
$row [ 'target-uri-id' ],
$row [ 'parent-uri-id' ],
new \DateTime ( $row [ 'created' ], new \DateTimeZone ( 'UTC' )),
$row [ 'seen' ],
2022-03-03 14:49:07 +01:00
$row [ 'dismissed' ],
$row [ 'id' ],
2021-09-18 05:37:41 +02:00
);
}
public function createForUser ( int $uid , int $vid , int $type , int $actorId , int $targetUriId , int $parentUriId ) : Entity\Notification
{
return new Entity\Notification (
$uid ,
Verb :: getByID ( $vid ),
$type ,
$actorId ,
$targetUriId ,
$parentUriId
);
}
2022-03-03 14:49:07 +01:00
/**
* @ param int $uid
* @ param int $contactId Public contact id
* @ param string $verb
* @ return Entity\Notification
*/
2021-09-18 05:37:41 +02:00
public function createForRelationship ( int $uid , int $contactId , string $verb ) : Entity\Notification
{
return new Entity\Notification (
$uid ,
$verb ,
Post\UserNotification :: TYPE_NONE ,
$contactId
);
}
/**
* @ param Entity\Notification $Notification
* @ return array
2022-03-03 14:49:07 +01:00
* @ throws HTTPException\InternalServerErrorException
* @ throws HTTPException\NotFoundException
2021-09-18 05:37:41 +02:00
*/
2022-03-03 14:49:07 +01:00
public function getMessageFromNotification ( Entity\Notification $Notification ) : array
2021-09-18 05:37:41 +02:00
{
$message = [];
2022-05-18 22:05:29 +02:00
$cachekey = 'Notification:' . $Notification -> id ;
$result = $this -> cache -> get ( $cachekey );
if ( ! is_null ( $result )) {
return $result ;
}
2022-06-04 16:08:11 +02:00
$user = User :: getById ( $Notification -> uid , [ 'language' ]);
$l10n = $this -> l10n -> withLang ( $user [ 'language' ]);
2022-02-17 22:44:59 +01:00
$causer = $author = Contact :: getById ( $Notification -> actorId , [ 'id' , 'name' , 'url' , 'contact-type' , 'pending' ]);
2021-09-18 05:37:41 +02:00
if ( empty ( $causer )) {
$this -> logger -> info ( 'Causer not found' , [ 'contact' => $Notification -> actorId ]);
return $message ;
}
if ( $Notification -> type === Post\UserNotification :: TYPE_NONE ) {
2022-05-31 16:02:43 +02:00
if ( $causer [ 'pending' ]) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s wants to follow you' );
2021-09-18 05:37:41 +02:00
} else {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s has started following you' );
2021-09-18 05:37:41 +02:00
}
2022-03-03 14:49:07 +01:00
2021-09-18 05:37:41 +02:00
$title = $causer [ 'name' ];
2022-03-03 14:49:07 +01:00
$link = $this -> baseUrl . '/contact/' . $causer [ 'id' ];
2021-09-18 05:37:41 +02:00
} else {
if ( ! $Notification -> targetUriId ) {
return $message ;
}
2022-03-19 10:48:50 +01:00
if ( Post\ThreadUser :: getIgnored ( $Notification -> parentUriId , $Notification -> uid )) {
$this -> logger -> info ( 'Thread is ignored' , [ 'parent-uri-id' => $Notification -> parentUriId , 'type' => $Notification -> type ]);
return $message ;
}
2022-05-18 22:05:29 +02:00
2022-03-19 10:27:49 +01:00
if ( in_array ( $Notification -> type , [ Post\UserNotification :: TYPE_THREAD_COMMENT , Post\UserNotification :: TYPE_COMMENT_PARTICIPATION , Post\UserNotification :: TYPE_ACTIVITY_PARTICIPATION , Post\UserNotification :: TYPE_EXPLICIT_TAGGED ])) {
$item = Post :: selectFirst ([], [ 'uri-id' => $Notification -> parentUriId , 'uid' => [ 0 , $Notification -> uid ]], [ 'order' => [ 'uid' => true ]]);
2021-09-18 05:37:41 +02:00
if ( empty ( $item )) {
2022-03-19 10:27:49 +01:00
$this -> logger -> info ( 'Parent post not found' , [ 'uri-id' => $Notification -> parentUriId ]);
2021-09-18 05:37:41 +02:00
return $message ;
}
2022-03-19 16:25:00 +01:00
$link_item = Post :: selectFirstPost ([ 'guid' ], [ 'uri-id' => $Notification -> targetUriId ]);
2022-03-19 10:27:49 +01:00
} else {
2022-03-20 20:59:35 +01:00
$link_item = $item = Post :: selectFirst ([], [ 'uri-id' => $Notification -> targetUriId , 'uid' => [ 0 , $Notification -> uid ]], [ 'order' => [ 'uid' => true ]]);
2022-03-19 10:27:49 +01:00
if ( empty ( $item )) {
$this -> logger -> info ( 'Post not found' , [ 'uri-id' => $Notification -> targetUriId ]);
2022-03-03 14:49:07 +01:00
return $message ;
2021-09-18 05:37:41 +02:00
}
2022-03-19 10:27:49 +01:00
if (( $Notification -> verb == Activity :: POST ) || ( $Notification -> type === Post\UserNotification :: TYPE_SHARED )) {
$item = Post :: selectFirst ([], [ 'uri-id' => $item [ 'thr-parent-id' ], 'uid' => [ 0 , $Notification -> uid ]], [ 'order' => [ 'uid' => true ]]);
if ( empty ( $item )) {
$this -> logger -> info ( 'Thread parent post not found' , [ 'uri-id' => $item [ 'thr-parent-id' ]]);
return $message ;
}
}
2022-03-20 20:59:35 +01:00
if (( $Notification -> verb != Activity :: POST ) || ! in_array ( $Notification -> type , [ Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT , Post\UserNotification :: TYPE_IMPLICIT_TAGGED ])) {
$link_item = $item ;
}
2021-09-18 05:37:41 +02:00
}
2022-01-24 05:15:36 +01:00
if ( in_array ( $Notification -> type , [ Post\UserNotification :: TYPE_COMMENT_PARTICIPATION , Post\UserNotification :: TYPE_ACTIVITY_PARTICIPATION , Post\UserNotification :: TYPE_SHARED ])) {
2022-02-17 22:44:59 +01:00
$author = Contact :: getById ( $item [ 'author-id' ], [ 'id' , 'name' , 'url' , 'contact-type' ]);
2021-09-18 05:37:41 +02:00
if ( empty ( $author )) {
$this -> logger -> info ( 'Author not found' , [ 'author' => $item [ 'author-id' ]]);
return $message ;
}
}
2022-03-19 16:25:00 +01:00
$link = $this -> baseUrl . '/display/' . urlencode ( $link_item [ 'guid' ]);
2021-09-18 05:37:41 +02:00
2022-05-18 22:05:29 +02:00
$body = BBCode :: toPlaintext ( $item [ 'body' ], false );
$title = Plaintext :: shorten ( $body , 70 );
if ( ! empty ( $title )) {
$title = '"' . trim ( str_replace ( " \n " , " " , $title )) . '"' ;
2021-09-18 05:37:41 +02:00
}
2022-01-28 06:28:13 +01:00
$this -> logger -> debug ( 'Got verb and type' , [ 'verb' => $Notification -> verb , 'type' => $Notification -> type , 'causer' => $causer [ 'id' ], 'author' => $author [ 'id' ], 'item' => $item [ 'id' ], 'uid' => $Notification -> uid ]);
2022-01-23 20:37:52 +01:00
2021-09-18 05:37:41 +02:00
switch ( $Notification -> verb ) {
case Activity :: LIKE :
switch ( $Notification -> type ) {
case Post\UserNotification :: TYPE_DIRECT_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s liked your comment on %2$s' );
2021-09-18 05:37:41 +02:00
break ;
case Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s liked your post %2$s' );
2021-09-18 05:37:41 +02:00
break ;
}
break ;
case Activity :: DISLIKE :
switch ( $Notification -> type ) {
case Post\UserNotification :: TYPE_DIRECT_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s disliked your comment on %2$s' );
2021-09-18 05:37:41 +02:00
break ;
case Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s disliked your post %2$s' );
2021-09-18 05:37:41 +02:00
break ;
}
break ;
case Activity :: ANNOUNCE :
switch ( $Notification -> type ) {
case Post\UserNotification :: TYPE_DIRECT_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared your comment %2$s' );
2021-09-18 05:37:41 +02:00
break ;
case Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared your post %2$s' );
2021-09-18 05:37:41 +02:00
break ;
2022-01-23 20:37:52 +01:00
case Post\UserNotification :: TYPE_SHARED :
if (( $causer [ 'id' ] != $author [ 'id' ]) && ( $title != '' )) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared the post %2$s from %3$s' );
2022-01-23 20:37:52 +01:00
} elseif ( $causer [ 'id' ] != $author [ 'id' ]) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared a post from %3$s' );
2022-01-23 20:37:52 +01:00
} elseif ( $title != '' ) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared the post %2$s' );
2022-01-23 20:37:52 +01:00
} else {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared a post' );
2022-01-23 20:37:52 +01:00
}
break ;
2021-09-18 05:37:41 +02:00
}
break ;
2022-01-24 05:49:13 +01:00
case Activity :: ATTEND :
switch ( $Notification -> type ) {
case Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s wants to attend your event %2$s' );
2022-01-24 05:49:13 +01:00
break ;
}
break ;
case Activity :: ATTENDNO :
switch ( $Notification -> type ) {
case Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s does not want to attend your event %2$s' );
2022-01-24 05:49:13 +01:00
break ;
}
break ;
case Activity :: ATTENDMAYBE :
switch ( $Notification -> type ) {
case Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s maybe wants to attend your event %2$s' );
2022-01-24 05:49:13 +01:00
break ;
}
break ;
2021-09-18 05:37:41 +02:00
case Activity :: POST :
switch ( $Notification -> type ) {
case Post\UserNotification :: TYPE_EXPLICIT_TAGGED :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s tagged you on %2$s' );
2021-09-18 05:37:41 +02:00
break ;
case Post\UserNotification :: TYPE_IMPLICIT_TAGGED :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s replied to you on %2$s' );
2021-09-18 05:37:41 +02:00
break ;
case Post\UserNotification :: TYPE_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s commented in your thread %2$s' );
2021-09-18 05:37:41 +02:00
break ;
case Post\UserNotification :: TYPE_DIRECT_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s commented on your comment %2$s' );
2021-09-18 05:37:41 +02:00
break ;
case Post\UserNotification :: TYPE_COMMENT_PARTICIPATION :
case Post\UserNotification :: TYPE_ACTIVITY_PARTICIPATION :
if (( $causer [ 'id' ] == $author [ 'id' ]) && ( $title != '' )) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s commented in their thread %2$s' );
2021-09-18 05:37:41 +02:00
} elseif ( $causer [ 'id' ] == $author [ 'id' ]) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s commented in their thread' );
2021-09-18 05:37:41 +02:00
} elseif ( $title != '' ) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s commented in the thread %2$s from %3$s' );
2021-09-18 05:37:41 +02:00
} else {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s commented in the thread from %3$s' );
2021-09-18 05:37:41 +02:00
}
break ;
case Post\UserNotification :: TYPE_DIRECT_THREAD_COMMENT :
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s commented on your thread %2$s' );
2021-09-18 05:37:41 +02:00
break ;
2022-01-28 06:28:13 +01:00
case Post\UserNotification :: TYPE_SHARED :
if (( $causer [ 'id' ] != $author [ 'id' ]) && ( $title != '' )) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared the post %2$s from %3$s' );
2022-01-28 06:28:13 +01:00
} elseif ( $causer [ 'id' ] != $author [ 'id' ]) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared a post from %3$s' );
2022-01-28 06:28:13 +01:00
} elseif ( $title != '' ) {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared the post %2$s' );
2022-01-28 06:28:13 +01:00
} else {
2022-06-04 16:08:11 +02:00
$msg = $l10n -> t ( '%1$s shared a post' );
2022-01-28 06:28:13 +01:00
}
break ;
2021-09-18 05:37:41 +02:00
}
break ;
}
}
if ( ! empty ( $msg )) {
// Name of the notification's causer
$message [ 'causer' ] = $causer [ 'name' ];
// Format for the "ping" mechanism
$message [ 'notification' ] = sprintf ( $msg , '{0}' , $title , $author [ 'name' ]);
// Plain text for the web push api
$message [ 'plain' ] = sprintf ( $msg , $causer [ 'name' ], $title , $author [ 'name' ]);
// Rich text for other purposes
$message [ 'rich' ] = sprintf ( $msg ,
'[url=' . $causer [ 'url' ] . ']' . $causer [ 'name' ] . '[/url]' ,
'[url=' . $link . ']' . $title . '[/url]' ,
'[url=' . $author [ 'url' ] . ']' . $author [ 'name' ] . '[/url]' );
2022-03-03 14:49:07 +01:00
$message [ 'link' ] = $link ;
2022-05-18 22:05:29 +02:00
$this -> cache -> set ( $cachekey , $message , Duration :: HOUR );
2022-03-19 10:27:49 +01:00
} else {
$this -> logger -> debug ( 'Unhandled notification' , [ 'notification' => $Notification ]);
2021-09-18 05:37:41 +02:00
}
return $message ;
}
}