2018-02-09 03:49:49 +00:00
< ? php
/**
2022-01-02 07:27:47 +00:00
* @ copyright Copyright ( C ) 2010 - 2022 , the Friendica project
2020-02-09 14:45:36 +00: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 />.
*
2018-02-09 03:49:49 +00:00
*/
2020-02-09 14:45:36 +00:00
2018-02-09 03:49:49 +00:00
namespace Friendica\Database ;
2018-10-29 21:20:46 +00:00
use Friendica\Core\Logger ;
2018-08-11 20:40:44 +00:00
use Friendica\Core\Protocol ;
2020-01-19 20:26:42 +00:00
use Friendica\DI ;
2018-02-09 03:49:49 +00:00
use Friendica\Model\Contact ;
2022-02-19 13:31:49 +00:00
use Friendica\Model\Conversation ;
2020-05-22 04:19:32 +00:00
use Friendica\Model\GServer ;
2018-07-01 19:02:29 +00:00
use Friendica\Model\Item ;
2021-02-14 21:57:02 +00:00
use Friendica\Model\ItemURI ;
2020-12-19 22:07:08 +00:00
use Friendica\Model\Photo ;
2021-01-17 20:32:13 +00:00
use Friendica\Model\Post ;
2020-05-03 15:13:40 +00:00
use Friendica\Model\Post\Category ;
2020-04-30 06:09:57 +00:00
use Friendica\Model\Tag ;
2020-05-09 15:38:40 +00:00
use Friendica\Model\Verb ;
2022-02-19 13:31:49 +00:00
use Friendica\Protocol\ActivityPub\Processor ;
use Friendica\Protocol\ActivityPub\Receiver ;
use Friendica\Util\JsonLD ;
2020-04-30 06:09:57 +00:00
use Friendica\Util\Strings ;
2018-02-09 03:49:49 +00:00
/**
2020-01-19 14:24:46 +00:00
* These database - intensive post update routines are meant to be executed in the background by the cronjob .
*
* If there is a need for a intensive migration after a database structure change , update this file
* by adding a new method at the end with the number of the new DB_UPDATE_VERSION .
2018-02-09 03:49:49 +00:00
*/
class PostUpdate
{
2020-05-15 06:50:20 +00:00
// Needed for the helper function to read from the legacy term table
const OBJECT_TYPE_POST = 1 ;
2021-07-11 09:39:34 +00:00
2022-02-19 13:31:49 +00:00
const VERSION = 1452 ;
2020-05-15 06:50:20 +00:00
2018-05-03 20:49:32 +00:00
/**
2020-01-19 06:05:23 +00:00
* Calls the post update functions
2018-05-03 20:49:32 +00:00
*/
public static function update ()
{
2019-01-23 05:02:00 +00:00
if ( ! self :: update1297 ()) {
return false ;
}
2019-08-29 04:06:41 +00:00
if ( ! self :: update1322 ()) {
return false ;
}
2020-01-05 09:10:32 +00:00
if ( ! self :: update1329 ()) {
return false ;
}
2020-04-30 06:09:57 +00:00
if ( ! self :: update1341 ()) {
return false ;
}
if ( ! self :: update1342 ()) {
return false ;
}
2020-05-02 21:27:37 +00:00
if ( ! self :: update1345 ()) {
return false ;
}
2020-05-03 15:13:40 +00:00
if ( ! self :: update1346 ()) {
return false ;
}
2020-05-09 15:38:40 +00:00
if ( ! self :: update1347 ()) {
return false ;
}
2020-05-22 04:19:32 +00:00
if ( ! self :: update1348 ()) {
return false ;
}
if ( ! self :: update1349 ()) {
return false ;
}
2020-12-19 22:07:08 +00:00
if ( ! self :: update1383 ()) {
return false ;
}
2020-12-26 18:51:36 +00:00
if ( ! self :: update1384 ()) {
return false ;
}
2021-02-14 21:57:02 +00:00
if ( ! self :: update1400 ()) {
return false ;
}
2021-07-10 01:41:26 +00:00
if ( ! self :: update1424 ()) {
return false ;
}
if ( ! self :: update1425 ()) {
return false ;
}
if ( ! self :: update1426 ()) {
return false ;
}
2021-07-10 21:08:55 +00:00
if ( ! self :: update1427 ()) {
return false ;
}
2022-02-19 13:31:49 +00:00
if ( ! self :: update1452 ()) {
return false ;
}
2018-08-10 21:20:25 +00:00
return true ;
2018-05-03 20:49:32 +00:00
}
2019-01-23 05:02:00 +00:00
/**
* Set the delivery queue count to a negative value for all items preceding the feature .
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function update1297 ()
{
// Was the script completed?
2020-01-19 20:21:13 +00:00
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1297 ) {
2019-01-23 05:02:00 +00:00
return true ;
}
2020-08-22 05:22:08 +00:00
if ( ! DBStructure :: existsTable ( 'item-delivery-data' )) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1297 );
return true ;
}
2019-01-23 05:02:00 +00:00
$max_item_delivery_data = DBA :: selectFirst ( 'item-delivery-data' , [ 'iid' ], [ 'queue_count > 0 OR queue_done > 0' ], [ 'order' => [ 'iid' ]]);
$max_iid = $max_item_delivery_data [ 'iid' ];
Logger :: info ( 'Start update1297 with max iid: ' . $max_iid );
$condition = [ '`queue_count` = 0 AND `iid` < ?' , $max_iid ];
DBA :: update ( 'item-delivery-data' , [ 'queue_count' => - 1 ], $condition );
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error ' . DBA :: errorNo () . ':' . DBA :: errorMessage ());
return false ;
}
Logger :: info ( 'Processed rows: ' . DBA :: affectedRows ());
2020-01-19 20:21:53 +00:00
DI :: config () -> set ( 'system' , 'post_update_version' , 1297 );
2019-01-23 05:02:00 +00:00
Logger :: info ( 'Done' );
2019-08-29 04:06:41 +00:00
return true ;
}
/**
2019-08-30 05:38:42 +00:00
* Remove contact duplicates
2019-08-29 04:06:41 +00:00
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function update1322 ()
{
// Was the script completed?
2020-01-19 20:21:13 +00:00
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1322 ) {
2019-08-29 04:06:41 +00:00
return true ;
}
Logger :: info ( 'Start' );
2019-08-30 05:52:21 +00:00
$contacts = DBA :: p ( " SELECT `nurl`, `uid` FROM `contact`
2019-08-29 04:06:41 +00:00
WHERE EXISTS ( SELECT `nurl` FROM `contact` AS `c2`
2019-08-29 05:22:29 +00:00
WHERE `c2` . `nurl` = `contact` . `nurl` AND `c2` . `id` != `contact` . `id` AND `c2` . `uid` = `contact` . `uid` AND `c2` . `network` IN ( ? , ? , ? ) AND NOT `deleted` )
AND ( `network` IN ( ? , ? , ? ) OR ( `uid` = ? )) AND NOT `deleted` GROUP BY `nurl` , `uid` " ,
2019-08-29 04:55:36 +00:00
Protocol :: DIASPORA , Protocol :: OSTATUS , Protocol :: ACTIVITYPUB ,
Protocol :: DIASPORA , Protocol :: OSTATUS , Protocol :: ACTIVITYPUB , 0 );
2019-08-29 04:06:41 +00:00
while ( $contact = DBA :: fetch ( $contacts )) {
2019-08-30 05:52:21 +00:00
Logger :: info ( 'Remove duplicates' , [ 'nurl' => $contact [ 'nurl' ], 'uid' => $contact [ 'uid' ]]);
Contact :: removeDuplicates ( $contact [ 'nurl' ], $contact [ 'uid' ]);
2019-08-29 04:06:41 +00:00
}
DBA :: close ( $contact );
2020-01-19 20:21:53 +00:00
DI :: config () -> set ( 'system' , 'post_update_version' , 1322 );
2019-08-29 04:06:41 +00:00
Logger :: info ( 'Done' );
2019-01-23 05:02:00 +00:00
return true ;
}
2020-01-05 09:10:32 +00:00
/**
2021-02-02 05:45:57 +00:00
* update user notification data
2020-01-05 09:10:32 +00:00
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function update1329 ()
{
// Was the script completed?
2020-01-19 20:21:13 +00:00
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1329 ) {
2020-01-05 09:10:32 +00:00
return true ;
}
2021-02-14 18:33:15 +00:00
if ( ! DBStructure :: existsTable ( 'item' )) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1329 );
return true ;
}
2020-01-19 20:21:13 +00:00
$id = DI :: config () -> get ( 'system' , 'post_update_version_1329_id' , 0 );
2020-01-05 09:10:32 +00:00
Logger :: info ( 'Start' , [ 'item' => $id ]);
$start_id = $id ;
$rows = 0 ;
$condition = [ " `id` > ? " , $id ];
$params = [ 'order' => [ 'id' ], 'limit' => 10000 ];
2021-02-02 05:45:57 +00:00
$items = DBA :: select ( 'item' , [ 'id' , 'uri-id' , 'uid' ], $condition , $params );
2020-01-05 09:10:32 +00:00
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $item = DBA :: fetch ( $items )) {
2020-01-05 10:16:01 +00:00
$id = $item [ 'id' ];
2021-02-02 05:45:57 +00:00
Post\UserNotification :: setNotification ( $item [ 'uri-id' ], $item [ 'uid' ]);
2020-01-05 09:10:32 +00:00
++ $rows ;
}
DBA :: close ( $items );
2020-01-19 20:21:53 +00:00
DI :: config () -> set ( 'system' , 'post_update_version_1329_id' , $id );
2020-01-05 09:10:32 +00:00
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
if ( $start_id == $id ) {
2020-01-19 20:21:53 +00:00
DI :: config () -> set ( 'system' , 'post_update_version' , 1329 );
2020-01-05 09:10:32 +00:00
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2020-04-30 06:09:57 +00:00
/**
* Fill the " tag " table with tags and mentions from the body
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function update1341 ()
{
// Was the script completed?
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1341 ) {
return true ;
}
2021-01-30 22:03:53 +00:00
if ( ! DBStructure :: existsTable ( 'item-content' )) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1342 );
return true ;
}
2020-04-30 06:09:57 +00:00
$id = DI :: config () -> get ( 'system' , 'post_update_version_1341_id' , 0 );
Logger :: info ( 'Start' , [ 'item' => $id ]);
$rows = 0 ;
$items = DBA :: p ( " SELECT `uri-id`,`body` FROM `item-content` WHERE
( `body` LIKE ? OR `body` LIKE ? OR `body` LIKE ? ) AND `uri-id` >= ?
ORDER BY `uri-id` LIMIT 100000 " , '%#%', '%@%', '%!%', $id );
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $item = DBA :: fetch ( $items )) {
Tag :: storeFromBody ( $item [ 'uri-id' ], $item [ 'body' ], '#!@' , false );
$id = $item [ 'uri-id' ];
++ $rows ;
if ( $rows % 1000 == 0 ) {
DI :: config () -> set ( 'system' , 'post_update_version_1341_id' , $id );
}
}
DBA :: close ( $items );
DI :: config () -> set ( 'system' , 'post_update_version_1341_id' , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
2020-04-30 12:13:13 +00:00
// When there are less than 1,000 items processed this means that we reached the end
2020-04-30 09:03:05 +00:00
// The other entries will then be processed with the regular functionality
2020-04-30 12:13:13 +00:00
if ( $rows < 1000 ) {
2020-04-30 06:09:57 +00:00
DI :: config () -> set ( 'system' , 'post_update_version' , 1341 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
/**
* Fill the " tag " table with tags and mentions from the " term " table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function update1342 ()
{
// Was the script completed?
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1342 ) {
return true ;
}
2021-01-30 22:03:53 +00:00
if ( ! DBStructure :: existsTable ( 'term' ) || ! DBStructure :: existsTable ( 'item-content' )) {
2020-10-04 19:20:18 +00:00
DI :: config () -> set ( 'system' , 'post_update_version' , 1342 );
return true ;
}
2020-04-30 06:09:57 +00:00
$id = DI :: config () -> get ( 'system' , 'post_update_version_1342_id' , 0 );
Logger :: info ( 'Start' , [ 'item' => $id ]);
$rows = 0 ;
$terms = DBA :: p ( " SELECT `term`.`tid`, `item`.`uri-id`, `term`.`type`, `term`.`term`, `term`.`url`, `item-content`.`body`
FROM `term`
INNER JOIN `item` ON `item` . `id` = `term` . `oid`
INNER JOIN `item-content` ON `item-content` . `uri-id` = `item` . `uri-id`
WHERE term . type IN ( ? , ? , ? , ? ) AND `tid` >= ? ORDER BY `tid` LIMIT 100000 " ,
Tag :: HASHTAG , Tag :: MENTION , Tag :: EXCLUSIVE_MENTION , Tag :: IMPLICIT_MENTION , $id );
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $term = DBA :: fetch ( $terms )) {
if (( $term [ 'type' ] == Tag :: MENTION ) && ! empty ( $term [ 'url' ]) && ! strstr ( $term [ 'body' ], $term [ 'url' ])) {
$condition = [ 'nurl' => Strings :: normaliseLink ( $term [ 'url' ]), 'uid' => 0 , 'deleted' => false ];
$contact = DBA :: selectFirst ( 'contact' , [ 'url' , 'alias' ], $condition , [ 'order' => [ 'id' ]]);
if ( ! DBA :: isResult ( $contact )) {
$ssl_url = str_replace ( 'http://' , 'https://' , $term [ 'url' ]);
$condition = [ '`alias` IN (?, ?, ?) AND `uid` = ? AND NOT `deleted`' , $term [ 'url' ], Strings :: normaliseLink ( $term [ 'url' ]), $ssl_url , 0 ];
$contact = DBA :: selectFirst ( 'contact' , [ 'url' , 'alias' ], $condition , [ 'order' => [ 'id' ]]);
}
if ( DBA :: isResult ( $contact ) && ( ! strstr ( $term [ 'body' ], $contact [ 'url' ]) && ( empty ( $contact [ 'alias' ]) || ! strstr ( $term [ 'body' ], $contact [ 'alias' ])))) {
$term [ 'type' ] = Tag :: IMPLICIT_MENTION ;
}
}
Tag :: store ( $term [ 'uri-id' ], $term [ 'type' ], $term [ 'term' ], $term [ 'url' ], false );
$id = $term [ 'tid' ];
++ $rows ;
if ( $rows % 1000 == 0 ) {
DI :: config () -> set ( 'system' , 'post_update_version_1342_id' , $id );
}
}
DBA :: close ( $terms );
DI :: config () -> set ( 'system' , 'post_update_version_1342_id' , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
2020-04-30 12:13:13 +00:00
// When there are less than 1,000 items processed this means that we reached the end
2020-04-30 09:03:05 +00:00
// The other entries will then be processed with the regular functionality
2020-04-30 12:13:13 +00:00
if ( $rows < 1000 ) {
2020-04-30 06:09:57 +00:00
DI :: config () -> set ( 'system' , 'post_update_version' , 1342 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2020-05-03 15:13:40 +00:00
2020-05-02 21:27:37 +00:00
/**
* Fill the " post-delivery-data " table with data from the " item-delivery-data " table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function update1345 ()
{
// Was the script completed?
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1345 ) {
return true ;
}
2020-08-22 05:22:08 +00:00
if ( ! DBStructure :: existsTable ( 'item-delivery-data' )) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1345 );
return true ;
}
2020-05-02 21:27:37 +00:00
$id = DI :: config () -> get ( 'system' , 'post_update_version_1345_id' , 0 );
2020-05-05 15:47:35 +00:00
2020-05-02 21:27:37 +00:00
Logger :: info ( 'Start' , [ 'item' => $id ]);
$rows = 0 ;
$deliveries = DBA :: p ( " SELECT `uri-id`, `iid`, `item-delivery-data`.`postopts`, `item-delivery-data`.`inform`,
`queue_count` , `queue_done` , `activitypub` , `dfrn` , `diaspora` , `ostatus` , `legacy_dfrn` , `queue_failed`
FROM `item-delivery-data`
INNER JOIN `item` ON `item` . `id` = `item-delivery-data` . `iid`
WHERE `iid` >= ? ORDER BY `iid` LIMIT 10000 " , $id );
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $delivery = DBA :: fetch ( $deliveries )) {
$id = $delivery [ 'iid' ];
unset ( $delivery [ 'iid' ]);
2020-11-19 19:34:48 +00:00
DBA :: insert ( 'post-delivery-data' , $delivery , Database :: INSERT_UPDATE );
2020-05-02 21:27:37 +00:00
++ $rows ;
}
DBA :: close ( $deliveries );
DI :: config () -> set ( 'system' , 'post_update_version_1345_id' , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
// When there are less than 100 items processed this means that we reached the end
// The other entries will then be processed with the regular functionality
if ( $rows < 100 ) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1345 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2020-05-05 15:44:24 +00:00
2020-05-15 06:50:20 +00:00
/**
* Generates the legacy item . file field string from an item ID .
* Includes only file and category terms .
*
* @ param int $item_id
* @ return string
* @ throws \Exception
*/
private static function fileTextFromItemId ( $item_id )
{
$file_text = '' ;
$condition = [ 'otype' => self :: OBJECT_TYPE_POST , 'oid' => $item_id , 'type' => [ Category :: FILE , Category :: CATEGORY ]];
$tags = DBA :: selectToArray ( 'term' , [ 'type' , 'term' , 'url' ], $condition );
foreach ( $tags as $tag ) {
if ( $tag [ 'type' ] == Category :: CATEGORY ) {
$file_text .= '<' . $tag [ 'term' ] . '>' ;
} else {
$file_text .= '[' . $tag [ 'term' ] . ']' ;
}
}
return $file_text ;
}
2020-05-03 15:13:40 +00:00
/**
* Fill the " tag " table with tags and mentions from the " term " table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private static function update1346 ()
{
// Was the script completed?
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1346 ) {
return true ;
}
2020-10-04 19:20:18 +00:00
if ( ! DBStructure :: existsTable ( 'term' )) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1346 );
return true ;
}
2020-05-03 15:13:40 +00:00
$id = DI :: config () -> get ( 'system' , 'post_update_version_1346_id' , 0 );
Logger :: info ( 'Start' , [ 'item' => $id ]);
$rows = 0 ;
$terms = DBA :: select ( 'term' , [ 'oid' ],
[ " `type` IN (?, ?) AND `oid` >= ? " , Category :: CATEGORY , Category :: FILE , $id ],
[ 'order' => [ 'oid' ], 'limit' => 1000 , 'group_by' => [ 'oid' ]]);
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $term = DBA :: fetch ( $terms )) {
2021-01-17 20:32:13 +00:00
$item = Post :: selectFirst ([ 'uri-id' , 'uid' ], [ 'id' => $term [ 'oid' ]]);
2020-05-03 15:13:40 +00:00
if ( ! DBA :: isResult ( $item )) {
continue ;
}
2020-05-15 06:50:20 +00:00
$file = self :: fileTextFromItemId ( $term [ 'oid' ]);
2020-05-03 15:13:40 +00:00
if ( ! empty ( $file )) {
Category :: storeTextByURIId ( $item [ 'uri-id' ], $item [ 'uid' ], $file );
}
$id = $term [ 'oid' ];
++ $rows ;
if ( $rows % 100 == 0 ) {
DI :: config () -> set ( 'system' , 'post_update_version_1346_id' , $id );
}
}
DBA :: close ( $terms );
DI :: config () -> set ( 'system' , 'post_update_version_1346_id' , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
// When there are less than 10 items processed this means that we reached the end
// The other entries will then be processed with the regular functionality
if ( $rows < 10 ) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1346 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
2020-05-09 15:38:40 +00:00
}
/**
2020-05-31 15:48:31 +00:00
* update the " vid " ( verb ) field in the item table
2020-05-09 15:38:40 +00:00
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1347 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1347 ) {
return true ;
}
2021-02-14 18:33:15 +00:00
if ( ! DBStructure :: existsTable ( 'item-activity' ) || ! DBStructure :: existsTable ( 'item' )) {
2021-01-30 22:03:53 +00:00
DI :: config () -> set ( 'system' , 'post_update_version' , 1347 );
return true ;
}
2020-05-09 15:38:40 +00:00
$id = DI :: config () -> get ( " system " , " post_update_version_1347_id " , 0 );
Logger :: info ( 'Start' , [ 'item' => $id ]);
$start_id = $id ;
$rows = 0 ;
2020-05-26 21:45:57 +00:00
2020-05-31 15:48:31 +00:00
$items = DBA :: p ( " SELECT `item`.`id`, `item`.`verb` AS `item-verb`, `item-content`.`verb`, `item-activity`.`activity`
2020-05-26 21:45:57 +00:00
FROM `item` LEFT JOIN `item-content` ON `item-content` . `uri-id` = `item` . `uri-id`
LEFT JOIN `item-activity` ON `item-activity` . `uri-id` = `item` . `uri-id` AND `item` . `gravity` = ?
2020-05-31 15:48:31 +00:00
WHERE `item` . `id` >= ? AND `item` . `vid` IS NULL ORDER BY `item` . `id` LIMIT 10000 " , GRAVITY_ACTIVITY, $id );
2020-05-09 15:38:40 +00:00
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
2020-05-26 21:45:57 +00:00
while ( $item = DBA :: fetch ( $items )) {
2020-05-09 15:38:40 +00:00
$id = $item [ 'id' ];
2020-05-26 21:45:57 +00:00
$verb = $item [ 'item-verb' ];
if ( empty ( $verb )) {
$verb = $item [ 'verb' ];
}
if ( empty ( $verb ) && is_int ( $item [ 'activity' ])) {
$verb = Item :: ACTIVITIES [ $item [ 'activity' ]];
}
if ( empty ( $verb )) {
continue ;
}
2020-05-09 15:38:40 +00:00
2020-05-26 21:45:57 +00:00
DBA :: update ( 'item' , [ 'vid' => Verb :: getID ( $verb )], [ 'id' => $item [ 'id' ]]);
2020-05-09 15:38:40 +00:00
++ $rows ;
}
DBA :: close ( $items );
DI :: config () -> set ( " system " , " post_update_version_1347_id " , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
if ( $start_id == $id ) {
DI :: config () -> set ( " system " , " post_update_version " , 1347 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2020-05-22 04:19:32 +00:00
/**
2020-06-14 16:09:59 +00:00
* update the " gsid " ( global server id ) field in the contact table
2020-05-22 04:19:32 +00:00
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1348 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1348 ) {
return true ;
}
$id = DI :: config () -> get ( " system " , " post_update_version_1348_id " , 0 );
Logger :: info ( 'Start' , [ 'contact' => $id ]);
$start_id = $id ;
$rows = 0 ;
$condition = [ " `id` > ? AND `gsid` IS NULL AND `baseurl` != '' AND NOT `baseurl` IS NULL " , $id ];
$params = [ 'order' => [ 'id' ], 'limit' => 10000 ];
$contacts = DBA :: select ( 'contact' , [ 'id' , 'baseurl' ], $condition , $params );
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $contact = DBA :: fetch ( $contacts )) {
$id = $contact [ 'id' ];
DBA :: update ( 'contact' ,
2020-06-14 16:09:59 +00:00
[ 'gsid' => GServer :: getID ( $contact [ 'baseurl' ], true ), 'baseurl' => GServer :: cleanURL ( $contact [ 'baseurl' ])],
2020-05-22 04:19:32 +00:00
[ 'id' => $contact [ 'id' ]]);
++ $rows ;
}
DBA :: close ( $contacts );
DI :: config () -> set ( " system " , " post_update_version_1348_id " , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
if ( $start_id == $id ) {
DI :: config () -> set ( " system " , " post_update_version " , 1348 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
/**
2020-06-14 16:09:59 +00:00
* update the " gsid " ( global server id ) field in the apcontact table
2020-05-22 04:19:32 +00:00
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1349 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1349 ) {
return true ;
}
2020-06-14 16:09:59 +00:00
$id = DI :: config () -> get ( " system " , " post_update_version_1349_id " , '' );
2020-05-22 04:19:32 +00:00
Logger :: info ( 'Start' , [ 'apcontact' => $id ]);
$start_id = $id ;
$rows = 0 ;
$condition = [ " `url` > ? AND `gsid` IS NULL AND `baseurl` != '' AND NOT `baseurl` IS NULL " , $id ];
$params = [ 'order' => [ 'url' ], 'limit' => 10000 ];
$apcontacts = DBA :: select ( 'apcontact' , [ 'url' , 'baseurl' ], $condition , $params );
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $apcontact = DBA :: fetch ( $apcontacts )) {
$id = $apcontact [ 'url' ];
DBA :: update ( 'apcontact' ,
2020-06-14 16:09:59 +00:00
[ 'gsid' => GServer :: getID ( $apcontact [ 'baseurl' ], true ), 'baseurl' => GServer :: cleanURL ( $apcontact [ 'baseurl' ])],
2020-05-22 04:19:32 +00:00
[ 'url' => $apcontact [ 'url' ]]);
++ $rows ;
}
DBA :: close ( $apcontacts );
DI :: config () -> set ( " system " , " post_update_version_1349_id " , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id ]);
if ( $start_id == $id ) {
DI :: config () -> set ( " system " , " post_update_version " , 1349 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2020-12-26 18:51:36 +00:00
2020-12-19 22:07:08 +00:00
/**
* Remove orphaned photo entries
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1383 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1383 ) {
return true ;
}
Logger :: info ( 'Start' );
$deleted = 0 ;
$avatar = [ 4 => 'photo' , 5 => 'thumb' , 6 => 'micro' ];
$photos = DBA :: select ( 'photo' , [ 'id' , 'contact-id' , 'resource-id' , 'scale' ], [ " `contact-id` != ? AND `album` = ? " , 0 , Photo :: CONTACT_PHOTOS ]);
while ( $photo = DBA :: fetch ( $photos )) {
$delete = ! in_array ( $photo [ 'scale' ], [ 4 , 5 , 6 ]);
if ( ! $delete ) {
// Check if there is a contact entry with that photo
$delete = ! DBA :: exists ( 'contact' , [ " `id` = ? AND ` " . $avatar [ $photo [ 'scale' ]] . " ` LIKE ? " ,
$photo [ 'contact-id' ], '%' . $photo [ 'resource-id' ] . '%' ]);
}
if ( $delete ) {
Photo :: delete ([ 'id' => $photo [ 'id' ]]);
$deleted ++ ;
}
}
DBA :: close ( $photos );
DI :: config () -> set ( " system " , " post_update_version " , 1383 );
Logger :: info ( 'Done' , [ 'deleted' => $deleted ]);
return true ;
}
2020-12-26 18:51:36 +00:00
/**
* update the " hash " field in the photo table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1384 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1384 ) {
return true ;
}
$condition = [ " `hash` IS NULL " ];
Logger :: info ( 'Start' , [ 'rest' => DBA :: count ( 'photo' , $condition )]);
$rows = 0 ;
2021-06-12 18:40:17 +00:00
$photos = DBA :: select ( 'photo' , [], $condition , [ 'limit' => 100 ]);
2020-12-26 18:51:36 +00:00
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $photo = DBA :: fetch ( $photos )) {
$img = Photo :: getImageForPhoto ( $photo );
if ( ! empty ( $img )) {
$md5 = md5 ( $img -> asString ());
} else {
$md5 = '' ;
}
DBA :: update ( 'photo' , [ 'hash' => $md5 ], [ 'id' => $photo [ 'id' ]]);
++ $rows ;
}
DBA :: close ( $photos );
Logger :: info ( 'Processed' , [ 'rows' => $rows ]);
if ( $rows <= 100 ) {
DI :: config () -> set ( " system " , " post_update_version " , 1384 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2021-02-14 21:57:02 +00:00
/**
2021-07-10 01:41:26 +00:00
* update the " external-id " field in the post table
2021-02-14 21:57:02 +00:00
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1400 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1400 ) {
return true ;
}
2021-03-04 00:00:24 +00:00
if ( ! DBStructure :: existsTable ( 'item' )) {
DI :: config () -> set ( " system " , " post_update_version " , 1400 );
return true ;
}
2021-02-14 21:57:02 +00:00
$condition = [ " `extid` != ? AND EXISTS(SELECT `id` FROM `post-user` WHERE `uri-id` = `item`.`uri-id` AND `uid` = `item`.`uid` AND `external-id` IS NULL) " , '' ];
Logger :: info ( 'Start' , [ 'rest' => DBA :: count ( 'item' , $condition )]);
$rows = 0 ;
$items = DBA :: select ( 'item' , [ 'uri-id' , 'uid' , 'extid' ], $condition , [ 'order' => [ 'id' ], 'limit' => 10000 ]);
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $item = DBA :: fetch ( $items )) {
Post :: update ([ 'external-id' => ItemURI :: getIdByURI ( $item [ 'extid' ])], [ 'uri-id' => $item [ 'uri-id' ], 'uid' => $item [ 'uid' ]]);
++ $rows ;
}
DBA :: close ( $items );
Logger :: info ( 'Processed' , [ 'rows' => $rows ]);
if ( $rows <= 100 ) {
2021-02-15 22:22:34 +00:00
DI :: config () -> set ( " system " , " post_update_version " , 1400 );
2021-02-14 21:57:02 +00:00
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2021-07-10 01:41:26 +00:00
/**
* update the " uri-id " field in the contact table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1424 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1424 ) {
return true ;
}
$condition = [ " `uri-id` IS NULL " ];
Logger :: info ( 'Start' , [ 'rest' => DBA :: count ( 'contact' , $condition )]);
$rows = 0 ;
$contacts = DBA :: select ( 'contact' , [ 'id' , 'url' ], $condition , [ 'limit' => 1000 ]);
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $contact = DBA :: fetch ( $contacts )) {
DBA :: update ( 'contact' , [ 'uri-id' => ItemURI :: getIdByURI ( $contact [ 'url' ])], [ 'id' => $contact [ 'id' ]]);
++ $rows ;
}
DBA :: close ( $contacts );
Logger :: info ( 'Processed' , [ 'rows' => $rows ]);
if ( $rows <= 100 ) {
DI :: config () -> set ( " system " , " post_update_version " , 1424 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
/**
* update the " uri-id " field in the fcontact table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1425 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1425 ) {
return true ;
}
$condition = [ " `uri-id` IS NULL " ];
Logger :: info ( 'Start' , [ 'rest' => DBA :: count ( 'fcontact' , $condition )]);
$rows = 0 ;
$fcontacts = DBA :: select ( 'fcontact' , [ 'id' , 'url' , 'guid' ], $condition , [ 'limit' => 1000 ]);
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $fcontact = DBA :: fetch ( $fcontacts )) {
if ( ! empty ( $fcontact [ 'guid' ])) {
$uriid = ItemURI :: insert ([ 'uri' => $fcontact [ 'url' ], 'guid' => $fcontact [ 'guid' ]]);
} else {
$uriid = ItemURI :: getIdByURI ( $fcontact [ 'url' ]);
}
DBA :: update ( 'fcontact' , [ 'uri-id' => $uriid ], [ 'id' => $fcontact [ 'id' ]]);
++ $rows ;
}
DBA :: close ( $fcontacts );
Logger :: info ( 'Processed' , [ 'rows' => $rows ]);
if ( $rows <= 100 ) {
DI :: config () -> set ( " system " , " post_update_version " , 1425 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
/**
* update the " uri-id " field in the apcontact table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1426 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1426 ) {
return true ;
}
$condition = [ " `uri-id` IS NULL " ];
Logger :: info ( 'Start' , [ 'rest' => DBA :: count ( 'apcontact' , $condition )]);
$rows = 0 ;
$apcontacts = DBA :: select ( 'apcontact' , [ 'url' , 'uuid' ], $condition , [ 'limit' => 1000 ]);
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $apcontact = DBA :: fetch ( $apcontacts )) {
if ( ! empty ( $apcontact [ 'uuid' ])) {
$uriid = ItemURI :: insert ([ 'uri' => $apcontact [ 'url' ], 'guid' => $apcontact [ 'uuid' ]]);
} else {
$uriid = ItemURI :: getIdByURI ( $apcontact [ 'url' ]);
}
DBA :: update ( 'apcontact' , [ 'uri-id' => $uriid ], [ 'url' => $apcontact [ 'url' ]]);
++ $rows ;
}
DBA :: close ( $apcontacts );
Logger :: info ( 'Processed' , [ 'rows' => $rows ]);
if ( $rows <= 100 ) {
DI :: config () -> set ( " system " , " post_update_version " , 1426 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2021-07-10 21:08:55 +00:00
/**
* update the " uri-id " field in the event table
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1427 ()
{
// Was the script completed?
if ( DI :: config () -> get ( " system " , " post_update_version " ) >= 1427 ) {
return true ;
}
$condition = [ " `uri-id` IS NULL " ];
Logger :: info ( 'Start' , [ 'rest' => DBA :: count ( 'event' , $condition )]);
$rows = 0 ;
$events = DBA :: select ( 'event' , [ 'id' , 'uri' , 'guid' ], $condition , [ 'limit' => 1000 ]);
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $event = DBA :: fetch ( $events )) {
if ( ! empty ( $event [ 'guid' ])) {
$uriid = ItemURI :: insert ([ 'uri' => $event [ 'uri' ], 'guid' => $event [ 'guid' ]]);
} else {
$uriid = ItemURI :: getIdByURI ( $event [ 'uri' ]);
}
DBA :: update ( 'event' , [ 'uri-id' => $uriid ], [ 'id' => $event [ 'id' ]]);
++ $rows ;
}
DBA :: close ( $events );
Logger :: info ( 'Processed' , [ 'rows' => $rows ]);
if ( $rows <= 100 ) {
DI :: config () -> set ( " system " , " post_update_version " , 1427 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2022-02-19 13:31:49 +00:00
/**
* Fill the receivers of the post via the raw source
*
* @ return bool " true " when the job is done
* @ throws \Friendica\Network\HTTPException\InternalServerErrorException
* @ throws \ImagickException
*/
private static function update1452 ()
{
// Was the script completed?
if ( DI :: config () -> get ( 'system' , 'post_update_version' ) >= 1452 ) {
return true ;
}
$id = DI :: config () -> get ( 'system' , 'post_update_version_1452_id' , 0 );
Logger :: info ( 'Start' , [ 'uri-id' => $id ]);
$start_id = $id ;
2022-02-20 20:47:08 +00:00
$rows = 0 ;
$received = '' ;
2022-02-19 13:31:49 +00:00
$conversations = DBA :: p ( " SELECT `post-view`.`uri-id`, `conversation`.`source`, `conversation`.`received` FROM `conversation`
INNER JOIN `post-view` ON `post-view` . `uri` = `conversation` . `item-uri`
WHERE NOT `source` IS NULL AND `conversation` . `protocol` = ? AND `uri-id` > ? LIMIT ? " ,
Conversation :: PARCEL_ACTIVITYPUB , $id , 1000 );
if ( DBA :: errorNo () != 0 ) {
Logger :: error ( 'Database error' , [ 'no' => DBA :: errorNo (), 'message' => DBA :: errorMessage ()]);
return false ;
}
while ( $conversation = DBA :: fetch ( $conversations )) {
$id = $conversation [ 'uri-id' ];
$received = $conversation [ 'received' ];
$raw = json_decode ( $conversation [ 'source' ], true );
if ( empty ( $raw )) {
continue ;
}
$activity = JsonLD :: compact ( $raw );
$urls = Receiver :: getReceiverURL ( $activity );
Processor :: storeReceivers ( $conversation [ 'uri-id' ], $urls );
if ( ! empty ( $activity [ 'as:object' ])) {
$urls = array_merge ( $urls , Receiver :: getReceiverURL ( $activity [ 'as:object' ]));
Processor :: storeReceivers ( $conversation [ 'uri-id' ], $urls );
}
++ $rows ;
}
DBA :: close ( $conversations );
DI :: config () -> set ( 'system' , 'post_update_version_1452_id' , $id );
Logger :: info ( 'Processed' , [ 'rows' => $rows , 'last' => $id , 'last-received' => $received ]);
if ( $start_id == $id ) {
DI :: config () -> set ( 'system' , 'post_update_version' , 1452 );
Logger :: info ( 'Done' );
return true ;
}
return false ;
}
2018-02-09 03:49:49 +00:00
}