From 67de96e11f9d21b26dfa34f3f14ee54fc7b09a40 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Tue, 22 Aug 2017 15:43:03 +1200 Subject: [PATCH 1/8] just started - updated composer dependencies and basic README --- README.md | 7 ++++--- composer.json | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 0920974..3ea126a 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,15 @@ This module is a fork of [SilverStripe's Elastica Module](https://github.com/sil ## Compatibility -This release is compatible with all elasticsearch 2.x releases. +This release is compatible with all elasticsearch 5.x releases. +This release requires SilverStripe 4.x -If you need to work with an earlier version of elasticsearch, please try the 0.0.1 release of this module +If you need to work with an earlier version of elasticsearch (2.x) and SS (3.x), please try the 1.0 release of this module ## Installation ```bash -$ composer require heyday/silverstripe-elastica:~1.0 +$ composer require heyday/silverstripe-elastica:~2.0 ``` ## Usage diff --git a/composer.json b/composer.json index 80bc083..9a56530 100644 --- a/composer.json +++ b/composer.json @@ -27,10 +27,12 @@ "issues": "http://github.com/heyday/silverstripe-elastica/issues" }, "require": { - "ruflin/elastica": "3.1.0", - "symbiote/silverstripe-queuedjobs": "~2.10" + "ruflin/elastica": "~5.3", + "symbiote/silverstripe-queuedjobs": "~4.0" }, "autoload": { "psr-4": { "Heyday\\Elastica\\": "src/" } - } + }, + "minimum-stability": "dev", + "prefer-stable": true } From e2fe0752a8fc118dba82a82482035c62b83389f4 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Tue, 22 Aug 2017 15:50:20 +1200 Subject: [PATCH 2/8] require php 5.6 or higher --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 9a56530..63cde75 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "issues": "http://github.com/heyday/silverstripe-elastica/issues" }, "require": { + "php": ">=5.6.0", "ruflin/elastica": "~5.3", "symbiote/silverstripe-queuedjobs": "~4.0" }, From 7641bbb24e807150ed7f06537f8111f961b00eb7 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Tue, 22 Aug 2017 17:48:40 +1200 Subject: [PATCH 3/8] updated files with SS namespaces --- README.md | 14 ++++----- _config/config.yml | 4 +-- src/ElasticaService.php | 21 ++++++++----- src/Jobs/ReindexAfterWriteJob.php | 36 +++++++++++++--------- src/ManyManyList.php | 20 +++++++----- src/PaginatedList.php | 2 +- src/ReindexTask.php | 6 ++-- src/ResultList.php | 51 ++++++++++++++++++++++++++++--- src/Searchable.php | 29 ++++++++++-------- 9 files changed, 125 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index 3ea126a..030c3a0 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Heyday\Elastica\ElasticaService: # Example of customising the index config on th Only: environment: dev --- -Injector: +SilverStripe\Core\Injector\Injector: Elastica\Client: constructor: - host: localhost # hostname of the elastic search server @@ -75,7 +75,7 @@ mysite/_config/search.yml # PageTypes -Page: +Your\Namespace\Page: extensions: - Heyday\Elastica\Searchable indexed_fields: &page_defaults @@ -84,7 +84,7 @@ Page: - Content - MetaDescription -SpecialPageWithAdditionalFields: +Your\Namespace\SpecialPageWithAdditionalFields: extensions: - Heyday\Elastica\Searchable # only needed if this page does not extend the 'Page' configured above indexed_fields: @@ -93,14 +93,14 @@ SpecialPageWithAdditionalFields: - BannerCopy - SubHeading -SpecialPageWithRelatedDataObject: +Your\Namespace\SpecialPageWithRelatedDataObject: extensions: - Heyday\Elastica\Searchable indexed_fields: <<: *page_defaults - RelatedDataObjects -RelatedDataObject: +Your\Namespace\RelatedDataObject: extensions: - Heyday\Elastica\Searchable indexed_fields: @@ -117,7 +117,7 @@ mysite/_config/search.yml # PageTypes -Page: +Your\Namespace\Page: extensions: - Heyday\Elastica\Searchable indexed_fields: @@ -239,7 +239,7 @@ We use silverstripe-queuedjobs (https://github.com/symbiote/silverstripe-queuedj To turn on queues, you will need the following config: ```yaml -Injector: +SilverStripe\Core\Injector\Injector: Heyday\Elastica\Searchable: properties: Queued: true diff --git a/_config/config.yml b/_config/config.yml index f517389..5103e33 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -1,7 +1,7 @@ --- Name: Heyday Elastica Config --- -Injector: +SilverStripe\Core\Injector\Injector: Heyday\Elastica\ReindexTask: constructor: - %$Heyday\Elastica\ElasticaService @@ -11,5 +11,5 @@ Injector: ManyManyList: class: Heyday\Elastica\ManyManyList -CleanupJob: +Symbiote\QueuedJobs\Jobs\CleanupJob: is_enabled: true \ No newline at end of file diff --git a/src/ElasticaService.php b/src/ElasticaService.php index f0c1de6..87fee5d 100644 --- a/src/ElasticaService.php +++ b/src/ElasticaService.php @@ -6,12 +6,17 @@ use Elastica\Exception\NotFoundException; use Elastica\Query; use Psr\Log\LoggerInterface; +use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\Core\ClassInfo; +use SilverStripe\Core\Config\Configurable; +use SilverStripe\Versioned\Versioned; /** * A service used to interact with elastic search. */ -class ElasticaService extends \Object +class ElasticaService { + use Configurable; /** * @var Client @@ -205,17 +210,17 @@ public function define() */ public function refresh() { - $reading_mode = \Versioned::get_reading_mode(); - \Versioned::set_reading_mode('Stage.Live'); + $reading_mode = Versioned::get_reading_mode(); + Versioned::set_reading_mode('Stage.Live'); foreach ($this->getIndexedClasses() as $class) { foreach ($class::get() as $record) { //Only index records with Show In Search enabled for Site Tree descendants //otherwise index all other data objects - if (($record instanceof \SiteTree && $record->ShowInSearch) || - (!$record instanceof \SiteTree && ($record->hasMethod('getShowInSearch') && $record->getShowInSearch())) || - (!$record instanceof \SiteTree && !$record->hasMethod('getShowInSearch')) + if (($record instanceof SiteTree && $record->ShowInSearch) || + (!$record instanceof SiteTree && ($record->hasMethod('getShowInSearch') && $record->getShowInSearch())) || + (!$record instanceof SiteTree && !$record->hasMethod('getShowInSearch')) ) { $this->index($record); print "INDEXED: " . $record->getTitle() . "
\n"; @@ -225,7 +230,7 @@ public function refresh() } } } - \Versioned::set_reading_mode($reading_mode); + Versioned::set_reading_mode($reading_mode); } /** @@ -237,7 +242,7 @@ public function getIndexedClasses() { $classes = array(); - foreach (\ClassInfo::subclassesFor('DataObject') as $candidate) { + foreach (ClassInfo::subclassesFor('DataObject') as $candidate) { $candidateInstance = singleton($candidate); if ($candidateInstance->hasExtension('Heyday\\Elastica\\Searchable')) { $classes[] = $candidate; diff --git a/src/Jobs/ReindexAfterWriteJob.php b/src/Jobs/ReindexAfterWriteJob.php index 0cd3f37..ecf09c4 100644 --- a/src/Jobs/ReindexAfterWriteJob.php +++ b/src/Jobs/ReindexAfterWriteJob.php @@ -2,6 +2,14 @@ namespace Heyday\Elastica\Jobs; +use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\Core\Injector\Injector; +use SilverStripe\ORM\DataList; +use SilverStripe\ORM\DataObject; +use SilverStripe\Versioned\Versioned; +use Symbiote\QueuedJobs\Services\AbstractQueuedJob; +use Symbiote\QueuedJobs\Services\QueuedJob; + /** * Created by PhpStorm. @@ -9,7 +17,7 @@ * Date: 9/08/17 * Time: 10:06 AM */ -class ReindexAfterWriteJob extends \AbstractQueuedJob implements \QueuedJob +class ReindexAfterWriteJob extends AbstractQueuedJob implements QueuedJob { /** @@ -24,7 +32,7 @@ public function __construct($owner = null) $this->owner = $owner; } - $this->service = \Injector::inst()->get('Heyday\Elastica\ElasticaService'); + $this->service = Injector::inst()->get('Heyday\Elastica\ElasticaService'); } @@ -51,7 +59,7 @@ public function getTitle() public function getJobType() { $this->totalSteps = 'Lots'; - return \QueuedJob::QUEUED; + return QueuedJob::QUEUED; } @@ -61,17 +69,17 @@ public function getJobType() public function process() { if ($this->owner && $this->service) { - $reading_mode = \Versioned::get_reading_mode(); - \Versioned::set_reading_mode('Stage.Live'); + $reading_mode = Versioned::get_reading_mode(); + Versioned::set_reading_mode('Stage.Live'); - $versionToIndex = \DataObject::get($this->owner->ClassName)->byID($this->owner->ID); + $versionToIndex = DataObject::get($this->owner->ClassName)->byID($this->owner->ID); if (is_null($versionToIndex)) { $versionToIndex = $this->owner; } - if (($versionToIndex instanceof \SiteTree && $versionToIndex->ShowInSearch) || - (!$versionToIndex instanceof \SiteTree && ($versionToIndex->hasMethod('getShowInSearch') && $versionToIndex->ShowInSearch)) || - (!$versionToIndex instanceof \SiteTree && !$versionToIndex->hasMethod('getShowInSearch')) + if (($versionToIndex instanceof SiteTree && $versionToIndex->ShowInSearch) || + (!$versionToIndex instanceof SiteTree && ($versionToIndex->hasMethod('getShowInSearch') && $versionToIndex->ShowInSearch)) || + (!$versionToIndex instanceof SiteTree && !$versionToIndex->hasMethod('getShowInSearch')) ) { $this->service->index($versionToIndex); } else { @@ -80,7 +88,7 @@ public function process() $this->updateDependentClasses(); - \Versioned::set_reading_mode($reading_mode); + Versioned::set_reading_mode($reading_mode); $this->isComplete = true; return; } else { @@ -96,15 +104,15 @@ protected function updateDependentClasses() $classes = $this->dependentClasses(); if ($classes) { foreach ($classes as $class) { - $list = \DataList::create($class); + $list = DataList::create($class); foreach ($list as $object) { - if ($object instanceof \DataObject && + if ($object instanceof DataObject && $object->hasExtension('Heyday\\Elastica\\Searchable') ) { - if (($object instanceof \SiteTree && $object->ShowInSearch) || - (!$object instanceof \SiteTree) + if (($object instanceof SiteTree && $object->ShowInSearch) || + (!$object instanceof SiteTree) ) { $this->service->index($object); } else { diff --git a/src/ManyManyList.php b/src/ManyManyList.php index a7f9d52..cbb23e9 100644 --- a/src/ManyManyList.php +++ b/src/ManyManyList.php @@ -2,7 +2,9 @@ namespace Heyday\Elastica; -use \ManyManyList as SilverStripeManyManyList; +use SilverStripe\ORM\DataList; +use SilverStripe\ORM\DataObject; +use SilverStripe\ORM\ManyManyList as SilverStripeManyManyList; /** * A drop in replacement for the default ManyManyList. @@ -20,11 +22,11 @@ public function add($item, $extraFields = null) { parent::add($item, $extraFields); - if (!$item instanceof \DataObject) { - $item = \DataList::create($this->dataClass)->byId($item); + if (!$item instanceof DataObject) { + $item = DataList::create($this->dataClass)->byId($item); } - if ($item instanceof \DataObject) { + if ($item instanceof DataObject) { $item->extend('onAfterManyManyRelationAdd'); } } @@ -36,7 +38,7 @@ public function removeByID($itemID) { $result = parent::removeByID($itemID); - $item = \DataList::create($this->dataClass)->byId($itemID); + $item = DataList::create($this->dataClass)->byId($itemID); if ($item instanceof $this->dataClass) { $item->extend('onAfterManyManyRelationRemove'); @@ -45,14 +47,16 @@ public function removeByID($itemID) return $result; } + /** + * + */ public function removeAll() { parent::removeAll(); - $items = \DataList::create($this->dataClass); + $items = DataList::create($this->dataClass); - foreach ($items as $item) - { + foreach ($items as $item) { $item->extend('onAfterManyManyRelationRemove'); } } diff --git a/src/PaginatedList.php b/src/PaginatedList.php index ff54d64..983893e 100644 --- a/src/PaginatedList.php +++ b/src/PaginatedList.php @@ -2,7 +2,7 @@ namespace Heyday\Elastica; -class PaginatedList extends \PaginatedList +class PaginatedList extends \SilverStripe\ORM\PaginatedList { /** * Returns the total number of items in the unpaginated list. diff --git a/src/ReindexTask.php b/src/ReindexTask.php index a66624e..3b9e6ea 100644 --- a/src/ReindexTask.php +++ b/src/ReindexTask.php @@ -1,11 +1,13 @@ $content

"); + print(Director::is_cli() ? "$content\n" : "

$content

"); }; $message('Defining the mappings'); diff --git a/src/ResultList.php b/src/ResultList.php index 09e2768..0eae926 100644 --- a/src/ResultList.php +++ b/src/ResultList.php @@ -6,14 +6,23 @@ use Elastica\Query; use Elastica\ResultSet; use Psr\Log\LoggerInterface; +use SilverStripe\ORM\ArrayList; +use SilverStripe\Versioned\Versioned; +use SilverStripe\View\ViewableData; /** * A list wrapper around the results from a query. Note that not all operations are implemented. */ -class ResultList extends \ViewableData implements \SS_Limitable +class ResultList extends ViewableData { + /** + * @var Index + */ private $index; + /** + * @var Query + */ private $query; private $logger; private $resultsArray; @@ -32,7 +41,7 @@ public function __construct(Index $index, Query $query, LoggerInterface $logger )); //If we are in live reading mode, only return published documents - if (\Versioned::get_reading_mode() == \Versioned::DEFAULT_MODE) { + if (Versioned::get_reading_mode() == Versioned::DEFAULT_MODE) { $publishedFilter = new Query\BoolQuery(); $publishedFilter->addMust(new Query\Term([Searchable::$published_field => 'true'])); $query->setPostFilter($publishedFilter); @@ -43,6 +52,9 @@ public function __construct(Index $index, Query $query, LoggerInterface $logger $this->logger = $logger; } + /** + * + */ public function __clone() { $this->query = clone $this->query; @@ -113,7 +125,7 @@ public function getIterator() /** * @param $limit * @param int $offset - * @return ResultList|\SS_Limitable + * @return ResultList */ public function limit($limit, $offset = 0) { @@ -186,11 +198,17 @@ public function toArray() return $this->resultsArray; } + /** + * @return ArrayList + */ public function toArrayList() { - return new \ArrayList($this->toArray()); + return new ArrayList($this->toArray()); } + /** + * @return array + */ public function toNestedArray() { $result = array(); @@ -202,22 +220,37 @@ public function toNestedArray() return $result; } + /** + * @return mixed + */ public function first() { return reset($this->toArray()); } + /** + * @return mixed + */ public function last() { return array_pop($this->toArray()); } + /** + * @param string $key + * @param string $title + * @return \SilverStripe\ORM\Map + */ public function map($key = 'ID', $title = 'Title') { return $this->toArrayList()->map($key, $title); } + /** + * @param string $col + * @return array + */ public function column($col = 'ID') { if ($col == 'ID') { @@ -233,16 +266,26 @@ public function column($col = 'ID') } } + /** + * @param $callback + * @return $this + */ public function each($callback) { return $this->toArrayList()->each($callback); } + /** + * @return int + */ public function count() { return count($this->toArray()); } + /** + * @return int + */ public function totalItems() { return $this->getResults()->getTotalHits(); diff --git a/src/Searchable.php b/src/Searchable.php index def9ca0..9ef5ad8 100644 --- a/src/Searchable.php +++ b/src/Searchable.php @@ -6,11 +6,16 @@ use Elastica\Type\Mapping; use Heyday\Elastica\Jobs\ReindexAfterWriteJob; use Psr\Log\LoggerInterface; +use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\ORM\DataExtension; +use SilverStripe\ORM\DataList; +use SilverStripe\ORM\DataObject; +use SilverStripe\Versioned\Versioned; /** * Adds elastic search integration to a data object. */ -class Searchable extends \DataExtension +class Searchable extends DataExtension { public static $published_field = 'SS_Published'; @@ -398,17 +403,17 @@ public function onAfterWrite() */ public function reIndex() { - $reading_mode = \Versioned::get_reading_mode(); - \Versioned::set_reading_mode('Stage.Live'); + $reading_mode = Versioned::get_reading_mode(); + Versioned::set_reading_mode('Stage.Live'); - $versionToIndex = \DataObject::get($this->owner->ClassName)->byID($this->owner->ID); + $versionToIndex = DataObject::get($this->owner->ClassName)->byID($this->owner->ID); if (is_null($versionToIndex)) { $versionToIndex = $this->owner; } - if (($versionToIndex instanceof \SiteTree && $versionToIndex->ShowInSearch) || - (!$versionToIndex instanceof \SiteTree && ($versionToIndex->hasMethod('getShowInSearch') && $versionToIndex->ShowInSearch)) || - (!$versionToIndex instanceof \SiteTree && !$versionToIndex->hasMethod('getShowInSearch')) + if (($versionToIndex instanceof SiteTree && $versionToIndex->ShowInSearch) || + (!$versionToIndex instanceof SiteTree && ($versionToIndex->hasMethod('getShowInSearch') && $versionToIndex->ShowInSearch)) || + (!$versionToIndex instanceof SiteTree && !$versionToIndex->hasMethod('getShowInSearch')) ) { $this->service->index($versionToIndex); } else { @@ -417,7 +422,7 @@ public function reIndex() $this->updateDependentClasses(); - \Versioned::set_reading_mode($reading_mode); + Versioned::set_reading_mode($reading_mode); } /** @@ -453,15 +458,15 @@ protected function updateDependentClasses() $classes = $this->dependentClasses(); if($classes) { foreach ($classes as $class) { - $list = \DataList::create($class); + $list = DataList::create($class); foreach ($list as $object) { - if ($object instanceof \DataObject && + if ($object instanceof DataObject && $object->hasExtension('Heyday\\Elastica\\Searchable') ) { - if (($object instanceof \SiteTree && $object->ShowInSearch) || - (!$object instanceof \SiteTree) + if (($object instanceof SiteTree && $object->ShowInSearch) || + (!$object instanceof SiteTree) ) { $this->service->index($object); } else { From 9d95f95b5c8ed40186cc2a35468866f40b3adb25 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Wed, 23 Aug 2017 11:29:09 +1200 Subject: [PATCH 4/8] finished upgrading the mapping and indexing --- src/ElasticaService.php | 20 ++++++++++----- src/ReindexTask.php | 7 +++++ src/Searchable.php | 57 +++++++++++++++++++++++++---------------- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/src/ElasticaService.php b/src/ElasticaService.php index 87fee5d..ffbec0f 100644 --- a/src/ElasticaService.php +++ b/src/ElasticaService.php @@ -7,6 +7,7 @@ use Elastica\Query; use Psr\Log\LoggerInterface; use SilverStripe\CMS\Model\SiteTree; +use SilverStripe\Control\Director; use SilverStripe\Core\ClassInfo; use SilverStripe\Core\Config\Configurable; use SilverStripe\Versioned\Versioned; @@ -223,10 +224,19 @@ public function refresh() (!$record instanceof SiteTree && !$record->hasMethod('getShowInSearch')) ) { $this->index($record); - print "INDEXED: " . $record->getTitle() . "
\n"; + if (Director::is_cli()) { + print "INDEXED: Document Type \"" . $record->getClassName() . "\" - " . $record->getTitle() . " - ID " . $record->ID . "\n"; + } else { + print "INDEXED: Document Type \"" . $record->getClassName() . "\" - " . $record->getTitle() . " - ID " . $record->ID . "
"; + } + } else { $this->remove($record); - print "REMOVED: " . $record->getTitle() . "
\n"; + if (Director::is_cli()) { + print "REMOVED: Document Type \"" . $record->getClassName() . "\" - " . $record->getTitle() . " - ID " . $record->ID . "\n"; + } else { + print "REMOVED: Document Type \"" . $record->getClassName() . "\" - " . $record->getTitle() . " - ID " . $record->ID . "
"; + } } } } @@ -241,14 +251,12 @@ public function refresh() public function getIndexedClasses() { $classes = array(); - - foreach (ClassInfo::subclassesFor('DataObject') as $candidate) { + foreach (ClassInfo::subclassesFor('SilverStripe\ORM\DataObject') as $candidate) { $candidateInstance = singleton($candidate); - if ($candidateInstance->hasExtension('Heyday\\Elastica\\Searchable')) { + if ($candidateInstance->hasExtension('Heyday\\Elastica\\Searchable') && $candidate != 'Page') { $classes[] = $candidate; } } - return $classes; } diff --git a/src/ReindexTask.php b/src/ReindexTask.php index 3b9e6ea..5973c80 100644 --- a/src/ReindexTask.php +++ b/src/ReindexTask.php @@ -19,11 +19,18 @@ class ReindexTask extends BuildTask */ private $service; + /** + * ReindexTask constructor. + * @param ElasticaService $service + */ public function __construct(ElasticaService $service) { $this->service = $service; } + /** + * @param \SilverStripe\Control\HTTPRequest $request + */ public function run($request) { $message = function ($content) { diff --git a/src/Searchable.php b/src/Searchable.php index 9ef5ad8..9af465f 100644 --- a/src/Searchable.php +++ b/src/Searchable.php @@ -6,6 +6,7 @@ use Elastica\Type\Mapping; use Heyday\Elastica\Jobs\ReindexAfterWriteJob; use Psr\Log\LoggerInterface; +use SilverStripe\Assets\File; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\ORM\DataExtension; use SilverStripe\ORM\DataList; @@ -107,6 +108,15 @@ public function getElasticaType() return get_class($this->owner); } + /** + * Replacing the SS3 inheritedDatabaseFields() method + * @return array + */ + public function inheritedDatabaseFields() + { + return $this->owner::getSchema()->fieldSpecs($this->owner->getClassName()); + } + /** * Gets an array of elastic field definitions. * This is also where we set the type of field ($spec['type']) and the analyzer for the field ($spec['analyzer']) if needed. @@ -123,6 +133,7 @@ protected function getElasticaFields() ); } + /** * Get the searchable fields for the owner data object * @return array @@ -135,7 +146,7 @@ protected function getSearchableFields() foreach ($this->owner->indexedFields() as $fieldName => $params) { - if (isset($params['type'])) { + if (isset($params['type'])) { // check if data type is manually set $result[$fieldName] = $params; @@ -143,7 +154,7 @@ protected function getSearchableFields() $fieldName = $params; - if (array_key_exists($fieldName, $fields)) { + if (array_key_exists($fieldName, $fields)) { // otherwise get it from $db $dataType = $this->stripDataTypeParameters($fields[$fieldName]); @@ -161,37 +172,38 @@ protected function getSearchableFields() /** * Get the searchable fields for the relationships of the owner data object + * Note we currently only go one layer down eg the property of the document can be Relation_RelationField * @return array */ protected function getReferenceSearchableFields() { $result = array(); - - $relations = array_merge($this->owner->has_many(), $this->owner->has_one(), $this->owner->many_many()); + $config = $this->owner->config(); + $relations = array_merge($config->get('has_one'), $config->get('has_many'), $config->get('many_many')); foreach ($this->owner->indexedFields() as $fieldName => $params) { - if (is_int($fieldName)) { + if (is_int($fieldName)) { // if non-associative array, use the key as fieldName $fieldName = $params; } - if (array_key_exists($fieldName, $relations)) { + if (array_key_exists($fieldName, $relations)) { // we have an indexed field that's a relationship. $className = $relations[$fieldName]; $related = singleton($className); - $fields = $related->inheritedDatabaseFields(); + $fields = $related::getSchema()->fieldSpecs($related); if ($related->hasExtension('Heyday\\Elastica\\Searchable')) { foreach ($related->indexedFields() as $relatedFieldName => $relatedParams) { - if (is_int($relatedFieldName)) { + if (is_int($relatedFieldName)) { // if non-associative array, use the key as fieldName $relatedFieldName = $relatedParams; } - $concatenatedFieldName = "{$fieldName}_{$relatedFieldName}"; + $concatenatedFieldName = "{$fieldName}_{$relatedFieldName}"; // eg. Book_Title - if (isset($params[$relatedFieldName]['type'])) { + if (isset($params[$relatedFieldName]['type'])) { //check if the data type is manually set $result[$concatenatedFieldName] = $params[$relatedFieldName]; @@ -203,7 +215,7 @@ protected function getReferenceSearchableFields() $result[$concatenatedFieldName] = $relatedParams; - } else if (array_key_exists($relatedFieldName, $fields)) { + } else if (array_key_exists($relatedFieldName, $fields)) { //if not get the type from $db $dataType = $this->stripDataTypeParameters($fields[$relatedFieldName]); @@ -222,6 +234,7 @@ protected function getReferenceSearchableFields() } /** + * Clean up the data type name * @param $dataType * @return string */ @@ -267,12 +280,12 @@ protected function setPublishedStatus($document) { $isLive = true; if ($this->owner->hasExtension('Versioned')) { - if ($this->owner instanceof \SiteTree) { + if ($this->owner instanceof SiteTree) { $isLive = $this->owner->isPublished(); } } - $document->set(self::$published_field, (bool) $isLive); + $document->set(self::$published_field, (bool)$isLive); } /** @@ -297,8 +310,8 @@ public function getElasticaDocument() $this->setValue($config, $field, $document, $this->owner->$field); } else { - - $possibleRelations = array_merge($this->owner->has_many(), $this->owner->has_one(), $this->owner->many_many()); + $ownerConfig = $this->owner->config(); + $possibleRelations = array_merge($ownerConfig->get('has_one'), $ownerConfig->get('has_many'), $ownerConfig->get('many_many')); list($relation, $fieldName) = explode('_', $field); @@ -306,9 +319,9 @@ public function getElasticaDocument() $related = $this->owner->$relation(); - if ($related instanceof \DataObject && $related->exists()) { + if ($related instanceof DataObject && $related->exists()) { - $possibleFields = $related->inheritedDatabaseFields(); + $possibleFields = $related::getSchema()->fieldSpecs($related); if (array_key_exists($fieldName, $possibleFields)) { @@ -327,19 +340,19 @@ public function getElasticaDocument() $file = $related->$fieldName(); - if ($file instanceof \File && $file->exists()) { + if ($file instanceof File && $file->exists()) { $document->addFile($field, $file->getFullPath()); } } - } else if ($related instanceof \DataList && $related->count()) { + } else if ($related instanceof DataList && $related->count()) { $relatedData = []; foreach ($related as $relatedItem) { $data = null; - $possibleFields = $relatedItem->inheritedDatabaseFields(); + $possibleFields = $relatedItem::getSchema()->fieldSpecs($relatedItem); if (array_key_exists($fieldName, $possibleFields) || $related->hasMethod('get' . $fieldName) @@ -362,7 +375,7 @@ public function getElasticaDocument() } else { $file = $relatedItem->$fieldName(); - if ($file instanceof \File && $file->exists()) { + if ($file instanceof File && $file->exists()) { $data = base64_encode(file_get_contents($file->getFullPath())); } @@ -456,7 +469,7 @@ public function onAfterManyManyRelationAdd() protected function updateDependentClasses() { $classes = $this->dependentClasses(); - if($classes) { + if ($classes) { foreach ($classes as $class) { $list = DataList::create($class); From 9a1e8130645d8fa2b6a321284090e5a995748e50 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Wed, 30 Aug 2017 09:45:19 +1200 Subject: [PATCH 5/8] fixed namespace bug and updated requirements for queuejobs module --- composer.json | 8 +++++++- src/Searchable.php | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 63cde75..a9da195 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,10 @@ { + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/heyday/silverstripe-queuedjobs/" + } + ], "name": "heyday/silverstripe-elastica", "description": "Provides Elastic Search integration for SilverStripe DataObjects using Elastica", "type": "silverstripe-module", @@ -29,7 +35,7 @@ "require": { "php": ">=5.6.0", "ruflin/elastica": "~5.3", - "symbiote/silverstripe-queuedjobs": "~4.0" + "symbiote/silverstripe-queuedjobs": "dev-softer-silverstripe-admin-reqs" }, "autoload": { "psr-4": { "Heyday\\Elastica\\": "src/" } diff --git a/src/Searchable.php b/src/Searchable.php index 9af465f..74b5b38 100644 --- a/src/Searchable.php +++ b/src/Searchable.php @@ -405,7 +405,7 @@ public function onAfterWrite() { if ($this->queued) { $reindex = new ReindexAfterWriteJob($this->owner); - singleton('QueuedJobService')->queueJob($reindex); + singleton('Symbiote\QueuedJobs\Services\QueuedJobService')->queueJob($reindex); } else { $this->reIndex(); } From 7d83975f65729d4524c44abe82358061ebe8bcc8 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Wed, 30 Aug 2017 09:56:56 +1200 Subject: [PATCH 6/8] updated composer.json --- composer.json | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/composer.json b/composer.json index a9da195..63cde75 100644 --- a/composer.json +++ b/composer.json @@ -1,10 +1,4 @@ { - "repositories": [ - { - "type": "vcs", - "url": "https://github.com/heyday/silverstripe-queuedjobs/" - } - ], "name": "heyday/silverstripe-elastica", "description": "Provides Elastic Search integration for SilverStripe DataObjects using Elastica", "type": "silverstripe-module", @@ -35,7 +29,7 @@ "require": { "php": ">=5.6.0", "ruflin/elastica": "~5.3", - "symbiote/silverstripe-queuedjobs": "dev-softer-silverstripe-admin-reqs" + "symbiote/silverstripe-queuedjobs": "~4.0" }, "autoload": { "psr-4": { "Heyday\\Elastica\\": "src/" } From 84ba6f86c04e5d84e9e9aadc2af450deddf2cb66 Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Thu, 31 Aug 2017 10:27:45 +1200 Subject: [PATCH 7/8] fixed the resultList class --- src/ElasticaService.php | 2 +- src/ResultList.php | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ElasticaService.php b/src/ElasticaService.php index ffbec0f..6e9efa2 100644 --- a/src/ElasticaService.php +++ b/src/ElasticaService.php @@ -93,7 +93,7 @@ protected function getIndexConfig() * @param \Elastica\Query|string|array $query * @param array $options Options defined in \Elastica\Search * @param bool $returnResultList - * @return ResultList + * @return ResultList | \Elastica\ResultSet */ public function search($query, $options = null, $returnResultList = true) { diff --git a/src/ResultList.php b/src/ResultList.php index 0eae926..a178198 100644 --- a/src/ResultList.php +++ b/src/ResultList.php @@ -7,13 +7,14 @@ use Elastica\ResultSet; use Psr\Log\LoggerInterface; use SilverStripe\ORM\ArrayList; +use SilverStripe\ORM\SS_List; use SilverStripe\Versioned\Versioned; use SilverStripe\View\ViewableData; /** * A list wrapper around the results from a query. Note that not all operations are implemented. */ -class ResultList extends ViewableData +class ResultList extends ViewableData implements SS_List { /** @@ -35,7 +36,7 @@ class ResultList extends ViewableData public function __construct(Index $index, Query $query, LoggerInterface $logger = null) { //Optimise the query by just getting back the ids and types - $query->setFields(array( + $query->setStoredFields(array( '_id', '_type' )); From e2c81cc79bf4dd56e48834151a86e4bb4a71e0ff Mon Sep 17 00:00:00 2001 From: Ben Dubuisson Date: Thu, 31 Aug 2017 13:29:20 +1200 Subject: [PATCH 8/8] fix queuing --- README.md | 2 +- src/Jobs/ReindexAfterWriteJob.php | 43 ++++++++++++++++--------------- src/Searchable.php | 2 +- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 030c3a0..88c8dda 100644 --- a/README.md +++ b/README.md @@ -253,7 +253,7 @@ Every minute to run the jobs in the queue ``` and to clean up the jobs, add the cleanup job once by running (it then gets automatically added to run once a day): ``` -framework/sake dev/tasks/CreateQueuedJobTask?name=CleanupJob +framework/sake dev/tasks/CreateQueuedJobTask?name=Symbiote\QueuedJobs\Jobs\CleanupJob ``` ## License diff --git a/src/Jobs/ReindexAfterWriteJob.php b/src/Jobs/ReindexAfterWriteJob.php index ecf09c4..9c5b853 100644 --- a/src/Jobs/ReindexAfterWriteJob.php +++ b/src/Jobs/ReindexAfterWriteJob.php @@ -24,15 +24,17 @@ class ReindexAfterWriteJob extends AbstractQueuedJob implements QueuedJob * * get the instance to reindex and the service * ReindexAfterWriteJob constructor. - * @param null $owner + * @param null $id + * @param null $class */ - public function __construct($owner = null) + public function __construct($id = null, $class = null) { - if ($owner) { - $this->owner = $owner; + if ($id) { + $this->id = $id; + } + if ($class) { + $this->class = $class; } - - $this->service = Injector::inst()->get('Heyday\Elastica\ElasticaService'); } @@ -43,7 +45,7 @@ public function __construct($owner = null) */ public function getTitle() { - return "Reindexing " . $this->owner->ClassName . " ID " . $this->owner->ID; + return "Reindexing " . $this->class . " ID " . $this->id; } /** @@ -68,25 +70,24 @@ public function getJobType() */ public function process() { - if ($this->owner && $this->service) { + if ($this->id && $this->class) { + + $service = Injector::inst()->get('Heyday\Elastica\ElasticaService'); $reading_mode = Versioned::get_reading_mode(); Versioned::set_reading_mode('Stage.Live'); - $versionToIndex = DataObject::get($this->owner->ClassName)->byID($this->owner->ID); - if (is_null($versionToIndex)) { - $versionToIndex = $this->owner; - } + $versionToIndex = DataObject::get($this->class)->byID($this->id); if (($versionToIndex instanceof SiteTree && $versionToIndex->ShowInSearch) || (!$versionToIndex instanceof SiteTree && ($versionToIndex->hasMethod('getShowInSearch') && $versionToIndex->ShowInSearch)) || (!$versionToIndex instanceof SiteTree && !$versionToIndex->hasMethod('getShowInSearch')) ) { - $this->service->index($versionToIndex); + $service->index($versionToIndex); } else { - $this->service->remove($versionToIndex); + $service->remove($versionToIndex); } - $this->updateDependentClasses(); + $this->updateDependentClasses($versionToIndex, $service); Versioned::set_reading_mode($reading_mode); $this->isComplete = true; @@ -99,9 +100,9 @@ public function process() /** * Updates the records of all instances of dependent classes. */ - protected function updateDependentClasses() + protected function updateDependentClasses($versionToIndex, $service) { - $classes = $this->dependentClasses(); + $classes = $this->dependentClasses($versionToIndex); if ($classes) { foreach ($classes as $class) { $list = DataList::create($class); @@ -114,9 +115,9 @@ protected function updateDependentClasses() if (($object instanceof SiteTree && $object->ShowInSearch) || (!$object instanceof SiteTree) ) { - $this->service->index($object); + $service->index($object); } else { - $this->service->remove($object); + $service->remove($object); } } } @@ -129,8 +130,8 @@ protected function updateDependentClasses() * extended class is updated or when a relationship to it changes. * @return array|\scalar */ - public function dependentClasses() + public function dependentClasses($versionToIndex) { - return $this->owner->stat('dependent_classes'); + return $versionToIndex->stat('dependent_classes'); } } diff --git a/src/Searchable.php b/src/Searchable.php index 74b5b38..52c97a7 100644 --- a/src/Searchable.php +++ b/src/Searchable.php @@ -404,7 +404,7 @@ public function getElasticaDocument() public function onAfterWrite() { if ($this->queued) { - $reindex = new ReindexAfterWriteJob($this->owner); + $reindex = new ReindexAfterWriteJob($this->owner->ID, $this->owner->ClassName); singleton('Symbiote\QueuedJobs\Services\QueuedJobService')->queueJob($reindex); } else { $this->reIndex();