2023-09-01 21:56:59 +00:00
< ? php
/**
* @ copyright Copyright ( C ) 2010 - 2023 , 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 />.
*
*/
namespace Friendica\Model\Post ;
use Friendica\Core\Logger ;
use Friendica\Core\Protocol ;
use Friendica\Database\Database ;
use Friendica\Database\DBA ;
2023-09-01 22:28:25 +00:00
use Friendica\DI ;
2023-09-02 15:52:53 +00:00
use Friendica\Model\Contact ;
2023-09-01 21:56:59 +00:00
use Friendica\Model\Item ;
use Friendica\Model\Post ;
use Friendica\Model\Verb ;
use Friendica\Protocol\Activity ;
use Friendica\Util\DateTimeFormat ;
// Channel
class Engagement
{
2023-09-02 10:21:23 +00:00
/**
* Store engagement data from an item array
*
* @ param array $item
* @ return void
*/
2023-09-01 21:56:59 +00:00
public static function storeFromItem ( array $item )
{
if ( ! in_array ( $item [ 'network' ], Protocol :: FEDERATED )) {
Logger :: debug ( 'No federated network' , [ 'uri-id' => $item [ 'uri-id' ], 'parent-uri-id' => $item [ 'parent-uri-id' ], 'network' => $item [ 'network' ]]);
return ;
}
if (( $item [ 'uid' ] != 0 ) && ( $item [ 'gravity' ] == Item :: GRAVITY_COMMENT )) {
Logger :: debug ( 'Non public comments are not stored' , [ 'uri-id' => $item [ 'uri-id' ], 'parent-uri-id' => $item [ 'parent-uri-id' ], 'uid' => $item [ 'uid' ]]);
return ;
}
if ( in_array ( $item [ 'verb' ], [ Activity :: FOLLOW , Activity :: VIEW , Activity :: READ ])) {
Logger :: debug ( 'Technical activities are not stored' , [ 'uri-id' => $item [ 'uri-id' ], 'parent-uri-id' => $item [ 'parent-uri-id' ], 'verb' => $item [ 'verb' ]]);
return ;
}
2023-09-02 14:19:52 +00:00
$parent = Post :: selectFirst ([ 'created' , 'owner-id' , 'uid' , 'private' , 'contact-contact-type' ], [ 'uri-id' => $item [ 'parent-uri-id' ]]);
2023-09-01 21:56:59 +00:00
if ( $parent [ 'private' ] != Item :: PUBLIC ) {
Logger :: debug ( 'Non public posts are not stored' , [ 'uri-id' => $item [ 'uri-id' ], 'parent-uri-id' => $item [ 'parent-uri-id' ], 'uid' => $parent [ 'uid' ], 'private' => $parent [ 'private' ]]);
return ;
}
2023-09-01 23:47:29 +00:00
if ( $parent [ 'created' ] < DateTimeFormat :: utc ( 'now - ' . DI :: config () -> get ( 'channel' , 'engagement_hours' ) . ' hour' )) {
2023-09-01 21:56:59 +00:00
Logger :: debug ( 'Post is too old' , [ 'uri-id' => $item [ 'uri-id' ], 'parent-uri-id' => $item [ 'parent-uri-id' ], 'created' => $parent [ 'created' ]]);
return ;
}
2023-09-02 15:52:53 +00:00
$store = ( $item [ 'gravity' ] != Item :: GRAVITY_PARENT );
if ( ! $store ) {
$store = Contact :: hasFollowers ( $parent [ 'owner-id' ]);
}
$mediatype = self :: getMediaType ( $item [ 'parent-uri-id' ]);
if ( ! $store ) {
$mediatype = ! empty ( $mediatype );
}
2023-09-01 21:56:59 +00:00
$engagement = [
'uri-id' => $item [ 'parent-uri-id' ],
2023-09-02 14:19:52 +00:00
'owner-id' => $parent [ 'owner-id' ],
2023-09-01 21:56:59 +00:00
'contact-type' => $parent [ 'contact-contact-type' ],
2023-09-02 15:52:53 +00:00
'media-type' => $mediatype ,
2023-09-01 21:56:59 +00:00
'created' => $parent [ 'created' ],
'comments' => DBA :: count ( 'post' , [ 'parent-uri-id' => $item [ 'parent-uri-id' ], 'gravity' => Item :: GRAVITY_COMMENT ]),
'activities' => DBA :: count ( 'post' , [
" `parent-uri-id` = ? AND `gravity` = ? AND NOT `vid` IN (?, ?, ?) " ,
$item [ 'parent-uri-id' ], Item :: GRAVITY_ACTIVITY ,
Verb :: getID ( Activity :: FOLLOW ), Verb :: getID ( Activity :: VIEW ), Verb :: getID ( Activity :: READ )
])
];
2023-09-02 15:52:53 +00:00
if ( ! $store && ( $engagement [ 'comments' ] == 0 ) && ( $engagement [ 'activities' ] == 0 )) {
Logger :: debug ( 'No media, follower, comments or activities. Engagement not stored' , [ 'fields' => $engagement ]);
2023-09-02 05:22:44 +00:00
return ;
}
2023-09-01 21:56:59 +00:00
$ret = DBA :: insert ( 'post-engagement' , $engagement , Database :: INSERT_UPDATE );
Logger :: debug ( 'Engagement stored' , [ 'fields' => $engagement , 'ret' => $ret ]);
}
2023-09-02 15:52:53 +00:00
private static function getMediaType ( int $uri_id ) : int
{
$media = Post\Media :: getByURIId ( $uri_id );
$type = 0 ;
foreach ( $media as $entry ) {
if ( $entry [ 'type' ] == Post\Media :: IMAGE ) {
$type = $type | 1 ;
} elseif ( $entry [ 'type' ] == Post\Media :: VIDEO ) {
$type = $type | 2 ;
} elseif ( $entry [ 'type' ] == Post\Media :: AUDIO ) {
$type = $type | 4 ;
}
}
return $type ;
}
2023-09-02 10:21:23 +00:00
/**
* Expire old engagement data
*
* @ return void
*/
2023-09-01 21:56:59 +00:00
public static function expire ()
{
2023-09-01 23:47:29 +00:00
DBA :: delete ( 'post-engagement' , [ " `created` < ? " , DateTimeFormat :: utc ( 'now - ' . DI :: config () -> get ( 'channel' , 'engagement_hours' ) . ' hour' )]);
2023-09-01 21:56:59 +00:00
Logger :: notice ( 'Cleared expired engagements' , [ 'rows' => DBA :: affectedRows ()]);
}
}