BUG Fix delete / unpublish

Split SearchUpdater classes into separate files
Fixes #134
This commit is contained in:
Damian Mooyman 2017-03-09 11:40:13 +13:00
parent 203f931961
commit bbaf4276af
No known key found for this signature in database
GPG Key ID: 78B823A10DE27D1A
4 changed files with 113 additions and 78 deletions

View File

@ -97,6 +97,7 @@ class SearchUpdater extends Object
$id = $details['id'];
$state = $details['state'];
$class = $details['class'];
$command = $details['command'];
$fields = isset($details['fields']) ? $details['fields'] : array();
$base = ClassInfo::baseDataClass($class);
@ -111,6 +112,7 @@ class SearchUpdater extends Object
'class' => $class,
'id' => $id,
'statefulids' => $statefulids,
'command' => $command,
'fields' => array()
);
}
@ -125,9 +127,9 @@ class SearchUpdater extends Object
}
}
// Trim records without fields
foreach(array_keys($writes) as $key) {
if(empty($writes[$key]['fields'])) {
// Trim non-delete records without fields
foreach (array_keys($writes) as $key) {
if ($writes[$key]['command'] !== 'delete' && empty($writes[$key]['fields'])) {
unset($writes[$key]);
}
}
@ -203,78 +205,3 @@ class SearchUpdater extends Object
self::$processor = null;
}
}
class SearchUpdater_BindManipulationCaptureFilter implements RequestFilter
{
public function preRequest(SS_HTTPRequest $request, Session $session, DataModel $model)
{
SearchUpdater::bind_manipulation_capture();
}
public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model)
{
/* NOP */
}
}
/**
* Delete operations do not use database manipulations.
*
* If a delete has been requested, force a write on objects that should be
* indexed. This causes the object to be marked for deletion from the index.
*/
class SearchUpdater_ObjectHandler extends DataExtension
{
public function onAfterDelete()
{
// Calling delete() on empty objects does nothing
if (!$this->owner->ID) {
return;
}
// Force SearchUpdater to mark this record as dirty
$manipulation = array(
$this->owner->ClassName => array(
'fields' => array(),
'id' => $this->owner->ID,
'command' => 'update'
)
);
$this->owner->extend('augmentWrite', $manipulation);
SearchUpdater::handle_manipulation($manipulation);
}
/**
* Forces this object to trigger a re-index in the current state
*/
public function triggerReindex()
{
if (!$this->owner->ID) {
return;
}
$id = $this->owner->ID;
$class = $this->owner->ClassName;
$state = SearchVariant::current_state($class);
$base = ClassInfo::baseDataClass($class);
$key = "$id:$base:".serialize($state);
$statefulids = array(array(
'id' => $id,
'state' => $state
));
$writes = array(
$key => array(
'base' => $base,
'class' => $class,
'id' => $id,
'statefulids' => $statefulids,
'fields' => array()
)
);
SearchUpdater::process_writes($writes);
}
}

View File

@ -0,0 +1,15 @@
<?php
class SearchUpdater_BindManipulationCaptureFilter implements RequestFilter
{
public function preRequest(SS_HTTPRequest $request, Session $session, DataModel $model)
{
SearchUpdater::bind_manipulation_capture();
}
public function postRequest(SS_HTTPRequest $request, SS_HTTPResponse $response, DataModel $model)
{
/* NOP */
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* Delete operations do not use database manipulations.
*
* If a delete has been requested, force a write on objects that should be
* indexed. This causes the object to be marked for deletion from the index.
*/
class SearchUpdater_ObjectHandler extends DataExtension
{
public function onAfterDelete()
{
// Calling delete() on empty objects does nothing
if (!$this->owner->ID) {
return;
}
// Force SearchUpdater to mark this record as dirty
// Note: Some extensions require entire hierarchy passed to augmentWrite()
$manipulation = array();
foreach (ClassInfo::ancestry($this->owner) as $class) {
if (!is_subclass_of($class, 'DataObject')) {
continue;
}
$manipulation[$class] = array(
'fields' => array(),
'id' => $this->owner->ID,
// Note: 'delete' command not actually handled by manipulations,
// but added so that SearchUpdater can detect the deletion
'command' => 'delete'
);
}
$this->owner->extend('augmentWrite', $manipulation);
SearchUpdater::handle_manipulation($manipulation);
}
/**
* Forces this object to trigger a re-index in the current state
*/
public function triggerReindex()
{
if (!$this->owner->ID) {
return;
}
$id = $this->owner->ID;
$class = $this->owner->ClassName;
$state = SearchVariant::current_state($class);
$base = ClassInfo::baseDataClass($class);
$key = "$id:$base:" . serialize($state);
$statefulids = array(
array(
'id' => $id,
'state' => $state
)
);
$writes = array(
$key => array(
'base' => $base,
'class' => $class,
'id' => $id,
'statefulids' => $statefulids,
'fields' => array()
)
);
SearchUpdater::process_writes($writes);
}
}

View File

@ -72,6 +72,28 @@ class SearchVariantVersionedTest extends SapphireTest
));
$added = self::$index->getAdded(array('ID', '_versionedstage'));
$this->assertEquals($expected, $added);
// Test unpublish
self::$index->reset();
$item->deleteFromStage('Live');
SearchUpdater::flush_dirty_indexes();
$this->assertEquals(1, count(self::$index->deleted));
$this->assertEquals(
'SiteTree',
self::$index->deleted[0]['base']
);
$this->assertEquals(
$item->ID,
self::$index->deleted[0]['id']
);
$this->assertEquals(
'Live',
self::$index->deleted[0]['state']['SearchVariantVersioned']
);
}
public function testExcludeVariantState()