summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/SemanticMediaWiki/src/Maintenance/DuplicateEntitiesDisposer.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/SemanticMediaWiki/src/Maintenance/DuplicateEntitiesDisposer.php')
-rw-r--r--www/wiki/extensions/SemanticMediaWiki/src/Maintenance/DuplicateEntitiesDisposer.php138
1 files changed, 138 insertions, 0 deletions
diff --git a/www/wiki/extensions/SemanticMediaWiki/src/Maintenance/DuplicateEntitiesDisposer.php b/www/wiki/extensions/SemanticMediaWiki/src/Maintenance/DuplicateEntitiesDisposer.php
new file mode 100644
index 00000000..33afcb1e
--- /dev/null
+++ b/www/wiki/extensions/SemanticMediaWiki/src/Maintenance/DuplicateEntitiesDisposer.php
@@ -0,0 +1,138 @@
+<?php
+
+namespace SMW\Maintenance;
+
+use Onoi\Cache\Cache;
+use Onoi\MessageReporter\MessageReporterAwareTrait;
+use SMW\SQLStore\PropertyTableIdReferenceDisposer;
+use SMW\SQLStore\SQLStore;
+use SMW\Store;
+
+/**
+ * @license GNU GPL v2+
+ * @since 3.0
+ *
+ * @author mwjames
+ */
+class DuplicateEntitiesDisposer {
+
+ use MessageReporterAwareTrait;
+
+ /**
+ * @var Store
+ */
+ private $store;
+
+ /**
+ * @var Store
+ */
+ private $cache;
+
+ /**
+ * @since 3.0
+ *
+ * @param Store $store
+ * @param Cache|null $cache
+ */
+ public function __construct( Store $store, Cache $cache = null ) {
+ $this->store = $store;
+ $this->cache = $cache;
+ }
+
+ /**
+ * @since 3.0
+ */
+ public function findDuplicates() {
+ return $this->store->getObjectIds()->findDuplicates();
+ }
+
+ /**
+ * @since 3.0
+ *
+ * @param Iterator|array $duplicates
+ */
+ public function verifyAndDispose( $duplicates ) {
+
+ if ( !$this->is_iterable( $duplicates ) ) {
+ return;
+ }
+
+ $count = count( $duplicates );
+ $this->messageReporter->reportMessage( "Found: $count duplicates\n" );
+
+ if ( $count > 0 ) {
+ $this->doDispose( $duplicates );
+ }
+
+ if ( $this->cache !== null ) {
+ $this->cache->delete( \SMW\MediaWiki\Api\Task::makeCacheKey( 'duplookup' ) );
+ }
+ }
+
+ private function doDispose( $duplicates ) {
+
+ $propertyTableIdReferenceDisposer = new PropertyTableIdReferenceDisposer(
+ $this->store
+ );
+
+ $propertyTableIdReferenceDisposer->setRedirectRemoval( true );
+ $connection = $this->store->getConnection( 'mw.db' );
+
+ $log = [
+ 'disposed' => [],
+ 'untouched' => []
+ ];
+
+ $i = 0;
+ foreach ( $duplicates as $duplicate ) {
+ unset( $duplicate['count'] );
+
+ if ( ( $i ) % 60 === 0 ) {
+ $this->messageReporter->reportMessage( "\n" );
+ }
+
+ $this->messageReporter->reportMessage( '.' );
+
+ $res = $connection->select(
+ SQLStore::ID_TABLE,
+ [
+ 'smw_id',
+ ],
+ [
+ 'smw_title'=> $duplicate['smw_title'],
+ 'smw_namespace'=> $duplicate['smw_namespace'],
+ 'smw_iw'=> $duplicate['smw_iw'],
+ 'smw_subobject'=> $duplicate['smw_subobject']
+ ],
+ __METHOD__
+ );
+
+ foreach ( $res as $row ) {
+ if ( $propertyTableIdReferenceDisposer->isDisposable( $row->smw_id ) ) {
+ $propertyTableIdReferenceDisposer->cleanUpTableEntriesById( $row->smw_id );
+ $log['disposed'][$row->smw_id] = $duplicate;
+ } else {
+ $log['untouched'][$row->smw_id] = $duplicate;
+ }
+ }
+
+ $i++;
+ }
+
+ $this->messageReporter->reportMessage(
+ "\n\nLog\n\n" . json_encode( $log, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . "\n"
+ );
+ }
+
+ /**
+ * Polyfill for PHP 7.0-
+ *
+ * @see http://php.net/manual/en/function.is-iterable.php
+ *
+ * @since 3.0
+ */
+ private function is_iterable( $obj ) {
+ return is_array( $obj ) || ( is_object( $obj ) && ( $obj instanceof \Traversable ) );
+ }
+
+}