From 9a15f89355acd095e858e1687ca91efe9a002d1f Mon Sep 17 00:00:00 2001 From: Yannick ROGER Date: Thu, 27 Nov 2014 15:29:46 +0100 Subject: [PATCH] Fix EZP-23681: Delayed indexing of subtree on move --- cronjobs/indexcontent.php | 57 ++++++++++++++++++- .../ezcontentobjecttreenodeoperations.php | 4 +- kernel/classes/ezsearch.php | 5 +- .../content/ezcontentoperationcollection.php | 8 ++- .../ezcontentoperationdelete_regression.php | 1 + 5 files changed, 67 insertions(+), 8 deletions(-) diff --git a/cronjobs/indexcontent.php b/cronjobs/indexcontent.php index 69736a21a89..9e02074a257 100644 --- a/cronjobs/indexcontent.php +++ b/cronjobs/indexcontent.php @@ -29,7 +29,7 @@ while( true ) { $entries = $db->arrayQuery( - "SELECT param FROM ezpending_actions WHERE action = 'index_object' GROUP BY param ORDER BY min(created)", + "SELECT param, action FROM ezpending_actions WHERE action = 'index_object' OR action = 'index_moved_node' GROUP BY param ORDER BY min(created)", array( 'limit' => $limit, 'offset' => $offset ) ); @@ -38,6 +38,7 @@ foreach ( $entries as $entry ) { $objectID = (int)$entry['param']; + $action = $entry['action']; $cli->output( "\tIndexing object ID #$objectID" ); $db->begin(); @@ -49,12 +50,64 @@ { $searchEngine->removeObject( $object, false ); } + $removeFromPendingActions = $searchEngine->addObject( $object, false ); + + // When moving content (and only, because of performances), reindex the subtree + if ( $action == 'index_moved_node' ) + { + $nodeId = $object->attribute( 'main_node_id' ); + $node = eZContentObjectTreeNode::fetch( $nodeId ); + + if ( !( $node instanceof eZContentObjectTreeNode ) ) + { + $cli->error( "An error occured while trying fetching node $nodeId" ); + } + + $offset = 0; + $limit = 50; + + $params = array( 'Limitation' => array(), 'MainNodeOnly' => true ); + + $subtreeCount = $node->subTreeCount( $params ); + + while ( $offset < $subtreeCount ) + { + $subTree = $node->subTree( + array_merge( + $params, + array( 'Offset' => $offset, 'Limit' => $limit, 'SortBy' => array() ) + ) + ); + + if ( !empty( $subTree ) ) + { + foreach ( $subTree as $innerNode ) + { + /** @var $innerNode eZContentObjectTreeNode */ + $childObject = $innerNode->attribute( 'object' ); + if ( !$childObject ) + { + continue; + } + + $searchEngine->addObject( $childObject, false ); + } + } + + $offset += $limit; + + if ( $offset >= $subtreeCount ) + { + break; + } + } + } } if ( $removeFromPendingActions ) { - $db->query( "DELETE FROM ezpending_actions WHERE action = 'index_object' AND param = '$objectID'" ); + $db->query( "DELETE FROM ezpending_actions WHERE action = '$action' AND param = '$objectID'" ); } else { diff --git a/kernel/classes/ezcontentobjecttreenodeoperations.php b/kernel/classes/ezcontentobjecttreenodeoperations.php index 173c2593050..78fe1973b9b 100644 --- a/kernel/classes/ezcontentobjecttreenodeoperations.php +++ b/kernel/classes/ezcontentobjecttreenodeoperations.php @@ -109,10 +109,10 @@ static function move( $nodeID, $newParentNodeID ) $nodeAssignment->setAttribute( 'op_code', eZNodeAssignment::OP_CODE_MOVE ); $nodeAssignment->store(); - // update search index + // update search index specifying we are doing a move operation $nodeIDList = array( $nodeID ); eZSearch::removeNodeAssignment( $node->attribute( 'main_node_id' ), $newNode->attribute( 'main_node_id' ), $object->attribute( 'id' ), $nodeIDList ); - eZSearch::addNodeAssignment( $newNode->attribute( 'main_node_id' ), $object->attribute( 'id' ), $nodeIDList ); + eZSearch::addNodeAssignment( $newNode->attribute( 'main_node_id' ), $object->attribute( 'id' ), $nodeIDList, true ); } $result = true; diff --git a/kernel/classes/ezsearch.php b/kernel/classes/ezsearch.php index 6a0ef7056c8..01e8d5737f4 100644 --- a/kernel/classes/ezsearch.php +++ b/kernel/classes/ezsearch.php @@ -563,15 +563,16 @@ public static function updateNodeVisibility( $nodeID, $action ) * @param int $mainNodeID * @param int $objectID * @param array $nodeAssignmentIDList + * @param bool $isMoved true if node is being moved * @return false|mixed False in case method is undefined, otherwise return the result of the search engine call */ - public static function addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList ) + public static function addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList, $isMoved = false ) { $searchEngine = eZSearch::getEngine(); if ( $searchEngine instanceof ezpSearchEngine && method_exists( $searchEngine, 'addNodeAssignment' ) ) { - return $searchEngine->addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList ); + return $searchEngine->addNodeAssignment( $mainNodeID, $objectID, $nodeAssignmentIDList, $isMoved ); } return false; diff --git a/kernel/content/ezcontentoperationcollection.php b/kernel/content/ezcontentoperationcollection.php index 222c82bcd91..b4e5b2f7dcb 100644 --- a/kernel/content/ezcontentoperationcollection.php +++ b/kernel/content/ezcontentoperationcollection.php @@ -565,8 +565,10 @@ static public function resetNodeassignmentOpcodes( $objectID, $versionNum ) * the calls within a db transaction; thus within db->begin and db->commit. * * @param int $objectID Id of the object. + * @param int $version Operation collection passes this default param. Not used in the method + * @param bool $isMoved true if node is being moved */ - static public function registerSearchObject( $objectID ) + static public function registerSearchObject( $objectID, $version = null, $isMoved = false ) { $objectID = (int)$objectID; eZDebug::createAccumulatorGroup( 'search_total', 'Search Total' ); @@ -591,7 +593,9 @@ static public function registerSearchObject( $objectID ) if ( $insertPendingAction ) { - eZDB::instance()->query( "INSERT INTO ezpending_actions( action, param ) VALUES ( 'index_object', '$objectID' )" ); + $action = $isMoved ? 'index_moved_node' : 'index_object'; + + eZDB::instance()->query( "INSERT INTO ezpending_actions( action, param ) VALUES ( '$action', '$objectID' )" ); return; } diff --git a/tests/tests/kernel/content/ezcontentoperationdelete_regression.php b/tests/tests/kernel/content/ezcontentoperationdelete_regression.php index 273d2ba3f8e..815a2893902 100644 --- a/tests/tests/kernel/content/ezcontentoperationdelete_regression.php +++ b/tests/tests/kernel/content/ezcontentoperationdelete_regression.php @@ -53,6 +53,7 @@ public function tearDown() $this->folder->remove(); $this->article->remove(); eZPendingActions::removeByAction( 'index_object' ); + eZPendingActions::removeByAction( 'index_moved_node' ); $this->nodeIds = array(); $this->objectIds = array();