2020-12-20 07:22:31 +01:00
< ? php
/**
2021-03-29 08:40:20 +02:00
* @ copyright Copyright ( C ) 2010 - 2021 , the Friendica project
2020-12-20 07:22:31 +01:00
*
* @ 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\Worker ;
use Friendica\Core\Logger ;
use Friendica\Core\Worker ;
use Friendica\Database\DBA ;
2021-07-03 22:43:00 +02:00
use Friendica\Model\Contact ;
2020-12-20 07:22:31 +01:00
use Friendica\Model\Photo ;
/**
* Removes cached avatars from public contacts that aren ' t in use
*/
class RemoveUnusedAvatars
{
public static function execute ()
{
$condition = [ " `uid` = ? AND NOT `self` AND NOT `nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` != ?)
2021-02-14 10:43:27 +01:00
AND `id` IN ( SELECT `contact-id` FROM `photo` ) AND NOT `id` IN ( SELECT `author-id` FROM `post-user` )
AND NOT `id` IN ( SELECT `owner-id` FROM `post-user` ) AND NOT `id` IN ( SELECT `causer-id` FROM `post-user` )
AND NOT `id` IN ( SELECT `cid` FROM `post-tag` ) AND NOT `id` IN ( SELECT `contact-id` FROM `post-user` ) " , 0, 0];
2020-12-20 07:22:31 +01:00
$total = DBA :: count ( 'contact' , $condition );
Logger :: notice ( 'Starting removal' , [ 'total' => $total ]);
$count = 0 ;
$contacts = DBA :: select ( 'contact' , [ 'id' ], $condition );
while ( $contact = DBA :: fetch ( $contacts )) {
2021-09-10 20:21:19 +02:00
Contact :: update ([ 'photo' => '' , 'thumb' => '' , 'micro' => '' ], [ 'id' => $contact [ 'id' ]]);
2020-12-20 07:22:31 +01:00
Photo :: delete ([ 'contact-id' => $contact [ 'id' ], 'album' => Photo :: CONTACT_PHOTOS ]);
if (( ++ $count % 1000 ) == 0 ) {
if ( ! Worker :: isInMaintenanceWindow ()) {
Logger :: notice ( 'We are outside of the maintenance window, quitting' );
return ;
}
Logger :: notice ( 'In removal' , [ 'count' => $count , 'total' => $total ]);
}
}
DBA :: close ( $contacts );
Logger :: notice ( 'Removal done' , [ 'count' => $count , 'total' => $total ]);
2021-07-03 22:43:00 +02:00
self :: fixPhotoContacts ();
2021-07-04 12:40:03 +02:00
self :: deleteDuplicates ();
2021-07-03 22:43:00 +02:00
}
private static function fixPhotoContacts ()
{
$total = 0 ;
$deleted = 0 ;
$updated1 = 0 ;
$updated2 = 0 ;
Logger :: notice ( 'Starting contact fix' );
2021-07-04 12:40:03 +02:00
$photos = DBA :: select ( 'photo' , [], [ " `uid` = ? AND `contact-id` IN (SELECT `id` FROM `contact` WHERE `uid` != ?) AND `contact-id` != ? AND `scale` IN (?, ?, ?) " , 0 , 0 , 0 , 4 , 5 , 6 ]);
2021-07-03 22:43:00 +02:00
while ( $photo = DBA :: fetch ( $photos )) {
$total ++ ;
$photo_contact = Contact :: getById ( $photo [ 'contact-id' ]);
$resource = Photo :: ridFromURI ( $photo_contact [ 'photo' ]);
if ( $photo [ 'resource-id' ] == $resource ) {
$contact = DBA :: selectFirst ( 'contact' , [], [ 'nurl' => $photo_contact [ 'nurl' ], 'uid' => 0 ]);
if ( ! empty ( $contact [ 'photo' ]) && ( $contact [ 'photo' ] == $photo_contact [ 'photo' ])) {
Logger :: notice ( 'Photo updated to public user' , [ 'id' => $photo [ 'id' ], 'contact-id' => $contact [ 'id' ]]);
DBA :: update ( 'photo' , [ 'contact-id' => $contact [ 'id' ]], [ 'id' => $photo [ 'id' ]]);
$updated1 ++ ;
}
} else {
$updated = false ;
$contacts = DBA :: select ( 'contact' , [], [ 'nurl' => $photo_contact [ 'nurl' ]]);
while ( $contact = DBA :: fetch ( $contacts )) {
if ( $photo [ 'resource-id' ] == Photo :: ridFromURI ( $contact [ 'photo' ])) {
Logger :: notice ( 'Photo updated to given user' , [ 'id' => $photo [ 'id' ], 'contact-id' => $contact [ 'id' ], 'uid' => $contact [ 'uid' ]]);
DBA :: update ( 'photo' , [ 'contact-id' => $contact [ 'id' ], 'uid' => $contact [ 'uid' ]], [ 'id' => $photo [ 'id' ]]);
$updated = true ;
$updated2 ++ ;
}
}
DBA :: close ( $contacts );
if ( ! $updated ) {
Logger :: notice ( 'Photo deleted' , [ 'id' => $photo [ 'id' ]]);
Photo :: delete ([ 'id' => $photo [ 'id' ]]);
$deleted ++ ;
}
}
}
DBA :: close ( $photos );
Logger :: notice ( 'Contact fix done' , [ 'total' => $total , 'updated1' => $updated1 , 'updated2' => $updated2 , 'deleted' => $deleted ]);
2020-12-20 07:22:31 +01:00
}
2021-07-04 12:40:03 +02:00
2021-07-04 12:59:24 +02:00
private static function deleteDuplicates ()
2021-07-04 12:40:03 +02:00
{
$size = [ 4 => 'photo' , 5 => 'thumb' , 6 => 'micro' ];
$total = 0 ;
$deleted = 0 ;
Logger :: notice ( 'Starting duplicate removal' );
$photos = DBA :: p ( " SELECT `photo`.`id`, `photo`.`uid`, `photo`.`scale`, `photo`.`album`, `photo`.`contact-id`, `photo`.`resource-id`, `contact`.`photo`, `contact`.`thumb`, `contact`.`micro` FROM `photo` INNER JOIN `contact` ON `contact`.`id` = `photo`.`contact-id` and `photo`.`contact-id` != ? AND `photo`.`scale` IN (?, ?, ?) " , 0 , 4 , 5 , 6 );
while ( $photo = DBA :: fetch ( $photos )) {
$resource = Photo :: ridFromURI ( $photo [ $size [ $photo [ 'scale' ]]]);
if ( $resource != $photo [ 'resource-id' ] && ! empty ( $resource )) {
$total ++ ;
if ( DBA :: exists ( 'photo' , [ 'resource-id' => $resource , 'scale' => $photo [ 'scale' ]])) {
Logger :: notice ( 'Photo deleted' , [ 'id' => $photo [ 'id' ]]);
Photo :: delete ([ 'id' => $photo [ 'id' ]]);
$deleted ++ ;
}
}
}
DBA :: close ( $photos );
Logger :: notice ( 'Duplicate removal done' , [ 'total' => $total , 'deleted' => $deleted ]);
}
2020-12-20 07:22:31 +01:00
}