Deprecate MWFunction::newObj() in favor of ObjectFactory
authorKunal Mehta <legoktm@gmail.com>
Wed, 5 Nov 2014 22:29:43 +0000 (14:29 -0800)
committerBryan Davis <bd808@wikimedia.org>
Thu, 6 Nov 2014 20:41:18 +0000 (13:41 -0700)
Change-Id: Iaa803311409cf7b649f64f69bafe2935a418d31c

includes/StubObject.php
includes/libs/ObjectFactory.php
includes/specialpage/SpecialPageFactory.php
includes/utils/MWFunction.php
tests/phpunit/includes/MWFunctionTest.php
tests/phpunit/includes/libs/ObjectFactoryTest.php [new file with mode: 0644]

index 8878660..7f12c16 100644 (file)
@@ -110,7 +110,11 @@ class StubObject {
         * @return object
         */
        public function _newObject() {
-               return MWFunction::newObj( $this->class, $this->params );
+               return ObjectFactory::getObjectFromSpec( array(
+                       'class' => $this->class,
+                       'args' => $this->params,
+                       'closure_expansion' => false,
+               ) );
        }
 
        /**
index ee696c3..73e76f7 100644 (file)
@@ -47,7 +47,8 @@ class ObjectFactory {
         * expanded by invoking them with no arguments before passing the
         * resulting value on to the constructor/callable. This can be used to
         * pass DatabaseBase instances or other live objects to the
-        * constructor/callable.
+        * constructor/callable. This behavior can be suppressed by adding
+        * closure_expansion => false to the specification.
         *
         * @param array $spec Object specification
         * @return object
@@ -59,14 +60,18 @@ class ObjectFactory {
        public static function getObjectFromSpec( $spec ) {
                $args = isset( $spec['args'] ) ? $spec['args'] : array();
 
-               $args = array_map( function ( $value ) {
-                       if ( is_object( $value ) && $value instanceof Closure ) {
-                               // If an argument is a Closure, call it.
-                               return $value();
-                       } else {
-                               return $value;
-                       }
-               }, $args );
+               if ( !isset( $spec['closure_expansion'] ) ||
+                       $spec['closure_expansion'] === true
+               ) {
+                       $args = array_map( function ( $value ) {
+                               if ( is_object( $value ) && $value instanceof Closure ) {
+                                       // If an argument is a Closure, call it.
+                                       return $value();
+                               } else {
+                                       return $value;
+                               }
+                       }, $args );
+               }
 
                if ( isset( $spec['class'] ) ) {
                        $clazz = $spec['class'];
index b110bda..1531f69 100644 (file)
@@ -414,7 +414,11 @@ class SpecialPageFactory {
                                // @deprecated, officially since 1.18, unofficially since forever
                                wfDeprecated( "Array syntax for \$wgSpecialPages is deprecated ($className), " .
                                        "define a subclass of SpecialPage instead.", '1.18' );
-                               $page = MWFunction::newObj( $className, $rec );
+                               $page = ObjectFactory::getObjectFromSpec( array(
+                                       'class' => $className,
+                                       'args' => $rec,
+                                       'closure_expansion' => false,
+                               ) );
                        } elseif ( $rec instanceof SpecialPage ) {
                                $page = $rec; //XXX: we should deep clone here
                        } else {
index 9fb4c19..fa7eebe 100644 (file)
@@ -26,14 +26,15 @@ class MWFunction {
         * @param string $class
         * @param array $args
         * @return object
+        * @deprecated 1.25 Use ObjectFactory::getObjectFromSpec() instead
         */
        public static function newObj( $class, $args = array() ) {
-               if ( !count( $args ) ) {
-                       return new $class;
-               }
+               wfDeprecated( __METHOD__, '1.25' );
 
-               $ref = new ReflectionClass( $class );
-
-               return $ref->newInstanceArgs( $args );
+               return ObjectFactory::getObjectFromSpec( array(
+                       'class' => $class,
+                       'args' => $args,
+                       'closure_expansion' => false,
+               ) );
        }
 }
index f2a720e..f4d1799 100644 (file)
@@ -13,6 +13,7 @@ class MWFunctionTest extends MediaWikiTestCase {
                $args = array( $arg1, $arg2, $arg3, $arg4 );
 
                $newObject = new MWBlankClass( $arg1, $arg2, $arg3, $arg4 );
+               $this->hideDeprecated( 'MWFunction::newObj' );
                $this->assertEquals(
                        MWFunction::newObj( 'MWBlankClass', $args )->args,
                        $newObject->args
diff --git a/tests/phpunit/includes/libs/ObjectFactoryTest.php b/tests/phpunit/includes/libs/ObjectFactoryTest.php
new file mode 100644 (file)
index 0000000..1f88b12
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+/**
+ * @section LICENSE
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+class ObjectFactoryTest extends PHPUnit_Framework_TestCase {
+
+       public function testClosureExpansionDisabled() {
+               $obj = ObjectFactory::getObjectFromSpec( array(
+                       'class' => 'ObjectFactoryTest_Fixture',
+                       'args' => array( function (){ return 'unwrapped'; }, ),
+                       'closure_expansion' => false,
+               ) );
+               $this->assertInstanceOf( 'Closure', $obj->args[0] );
+               $this->assertSame( 'unwrapped', $obj->args[0]() );
+       }
+
+       public function testClosureExpansionEnabled() {
+               $obj = ObjectFactory::getObjectFromSpec( array(
+                       'class' => 'ObjectFactoryTest_Fixture',
+                       'args' => array( function (){ return 'unwrapped'; }, ),
+                       'closure_expansion' => true,
+               ) );
+               $this->assertInternalType( 'string', $obj->args[0] );
+               $this->assertSame( 'unwrapped', $obj->args[0] );
+
+               $obj = ObjectFactory::getObjectFromSpec( array(
+                       'class' => 'ObjectFactoryTest_Fixture',
+                       'args' => array( function (){ return 'unwrapped'; }, ),
+               ) );
+               $this->assertInternalType( 'string', $obj->args[0] );
+               $this->assertSame( 'unwrapped', $obj->args[0] );
+       }
+}
+
+class ObjectFactoryTest_Fixture {
+       public $args;
+       public function __construct( /*...*/ ) { $this->args = func_get_args(); }
+}