Allow fields to define their own merge strategy via callback.
authorStanislav Malyshev <smalyshev@gmail.com>
Thu, 9 Feb 2017 21:30:12 +0000 (13:30 -0800)
committerStanislav Malyshev <smalyshev@gmail.com>
Tue, 7 Mar 2017 18:36:53 +0000 (10:36 -0800)
Change-Id: Ic1cc1581f07381224d3f4fcba4feb1eac7085057

includes/search/SearchIndexFieldDefinition.php
tests/phpunit/includes/search/SearchIndexFieldTest.php

index 910fd77..04344fd 100644 (file)
@@ -33,6 +33,11 @@ abstract class SearchIndexFieldDefinition implements SearchIndexField {
         */
        protected $subfields = [];
 
+       /**
+        * @var callable
+        */
+       private $mergeCallback;
+
        /**
         * SearchIndexFieldDefinition constructor.
         * @param string $name Field name
@@ -91,6 +96,9 @@ abstract class SearchIndexFieldDefinition implements SearchIndexField {
         * @return SearchIndexField|false New definition or false if not mergeable.
         */
        public function merge( SearchIndexField $that ) {
+               if ( !empty( $this->mergeCallback ) ) {
+                       return call_user_func( $this->mergeCallback, $this, $that );
+               }
                // TODO: which definitions may be compatible?
                if ( ( $that instanceof self ) && $this->type === $that->type &&
                        $this->flags === $that->flags && $this->type !== self::INDEX_TYPE_NESTED
@@ -125,4 +133,11 @@ abstract class SearchIndexFieldDefinition implements SearchIndexField {
         */
        abstract public function getMapping( SearchEngine $engine );
 
+       /**
+        * Set field-specific merge strategy.
+        * @param callable $callback
+        */
+       public function setMergeCallback( $callback ) {
+               $this->mergeCallback = $callback;
+       }
 }
index 9c10e49..a5a1b7a 100644 (file)
@@ -18,14 +18,23 @@ class SearchIndexFieldTest extends MediaWikiTestCase {
 
        /**
         * @dataProvider getMergeCases
+        * @param $t1
+        * @param $n1
+        * @param $t2
+        * @param $n2
+        * @param $result
         */
        public function testMerge( $t1, $n1, $t2, $n2, $result ) {
-               $field1 = $this->getMockBuilder( 'SearchIndexFieldDefinition' )
-                       ->setMethods( [ 'getMapping' ] )
-                       ->setConstructorArgs( [ $n1, $t1 ] )->getMock();
-               $field2 = $this->getMockBuilder( 'SearchIndexFieldDefinition' )
-                       ->setMethods( [ 'getMapping' ] )
-                       ->setConstructorArgs( [ $n2, $t2 ] )->getMock();
+               $field1 =
+                       $this->getMockBuilder( SearchIndexFieldDefinition::class )
+                               ->setMethods( [ 'getMapping' ] )
+                               ->setConstructorArgs( [ $n1, $t1 ] )
+                               ->getMock();
+               $field2 =
+                       $this->getMockBuilder( SearchIndexFieldDefinition::class )
+                               ->setMethods( [ 'getMapping' ] )
+                               ->setConstructorArgs( [ $n2, $t2 ] )
+                               ->getMock();
 
                if ( $result ) {
                        $this->assertNotFalse( $field1->merge( $field2 ) );
@@ -35,5 +44,14 @@ class SearchIndexFieldTest extends MediaWikiTestCase {
 
                $field1->setFlag( 0xFF );
                $this->assertFalse( $field1->merge( $field2 ) );
+
+               $field1->setMergeCallback(
+                       function ( $this, $that ) {
+                               return "test";
+                       }
+               );
+               $this->assertEquals( "test", $field1->merge( $field2 ) );
+
        }
+
 }