[BUGFIX] Added handling for array in findOneByXXX result
authorBenjamin Bretz <pleaserebootuniverse@googlemail.com>
Fri, 12 Apr 2013 15:30:45 +0000 (17:30 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sat, 13 Apr 2013 09:47:43 +0000 (11:47 +0200)
If query findOneByXXX is configured to return an array, the first array
element is returned (instead of calling ->getFirst() on a non object).

Fixes: #46035
Releases: 6.1, 6.0, 4.7, 1.3
Change-Id: I2c9d3083ce0eaebd2929ce9f50ec2a7cc36fe222
Reviewed-on: https://review.typo3.org/19855
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Christian Kuhn
Tested-by: Christian Kuhn
typo3/sysext/extbase/Classes/Persistence/Repository.php
typo3/sysext/extbase/Tests/Unit/Persistence/RepositoryTest.php

index 1c8302d..89cc889 100644 (file)
@@ -403,8 +403,14 @@ class Repository implements \TYPO3\CMS\Extbase\Persistence\RepositoryInterface,
                } elseif (substr($methodName, 0, 9) === 'findOneBy' && strlen($methodName) > 10) {
                        $propertyName = lcfirst(substr($methodName, 9));
                        $query = $this->createQuery();
-                       $object = $query->matching($query->equals($propertyName, $arguments[0]))->setLimit(1)->execute()->getFirst();
-                       return $object;
+
+                       $result = $query->matching($query->equals($propertyName, $arguments[0]))->setLimit(1)->execute();
+                       if ($result instanceof \TYPO3\CMS\Extbase\Persistence\QueryResultInterface) {
+                               return $result->getFirst();
+                       } elseif (is_array($result)) {
+                               return isset($result[0]) ? $result[0] : NULL;
+                       }
+
                } elseif (substr($methodName, 0, 7) === 'countBy' && strlen($methodName) > 8) {
                        $propertyName = lcfirst(substr($methodName, 7));
                        $query = $this->createQuery();
index 1e4b95e..be0626d 100644 (file)
@@ -379,6 +379,34 @@ class RepositoryTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
        /**
         * @test
         */
+       public function magicCallMethodReturnsFirstArrayKeyInFindOneBySomethingIfQueryReturnsRawResult() {
+               $queryResultArray = array(
+                       0 => array(
+                               'foo' => 'bar',
+                       ),
+               );
+               $this->mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
+               $this->mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($this->mockQuery));
+               $this->mockQuery->expects($this->once())->method('setLimit')->with(1)->will($this->returnValue($this->mockQuery));
+               $this->mockQuery->expects($this->once())->method('execute')->will($this->returnValue($queryResultArray));
+               $this->assertSame(array('foo' => 'bar'), $this->repository->findOneByFoo('bar'));
+       }
+
+       /**
+        * @test
+        */
+       public function magicCallMethodReturnsNullInFindOneBySomethingIfQueryReturnsEmptyRawResult() {
+               $queryResultArray = array();
+               $this->mockQuery->expects($this->once())->method('equals')->with('foo', 'bar')->will($this->returnValue('matchCriteria'));
+               $this->mockQuery->expects($this->once())->method('matching')->with('matchCriteria')->will($this->returnValue($this->mockQuery));
+               $this->mockQuery->expects($this->once())->method('setLimit')->with(1)->will($this->returnValue($this->mockQuery));
+               $this->mockQuery->expects($this->once())->method('execute')->will($this->returnValue($queryResultArray));
+               $this->assertNull($this->repository->findOneByFoo('bar'));
+       }
+
+       /**
+        * @test
+        */
        public function magicCallMethodAcceptsCountBySomethingCallsAndExecutesAQueryWithThatCriteria() {
                $mockQueryResult = $this->getMock('TYPO3\\CMS\\Extbase\\Persistence\\QueryResultInterface');
                $mockQueryResult->expects($this->once())->method('count')->will($this->returnValue(2));