/** * Tests finding objects by various queries. * * @param array $criteria Search criteria. * @param array $params Search params. * @param array $expected Expected results. * * @depends testInsert * @dataProvider provideFindCriteria */ public function testFind(array $criteria, array $params, array $expected) { $this->insertData(); $hobbits = $this->repository->find($criteria, $params); $this->assertCount(count($expected), $hobbits, $this->logger->getLastMessage()); $this->assertEquals($expected, ObjectUtils::pluck($hobbits, 'name'), $this->logger->getLastMessage()); }
/** * Tests finding by multiple id's. * * @depends testInsert */ public function testFindByMultipleIds() { $hobbits = $this->repository->find(); $otherHobbits = $this->repository->find(['id:in' => ObjectUtils::pluck($hobbits, 'id')]); $this->assertEquals($hobbits, $otherHobbits, $this->logger->getLastMessage()); }
/** * Do a programmatic 1:n join between the given objects and objects retrieved from the passed repository. * * Example: * * $productRepository->joinMany($products, $tagsRepository, 'id', 'product_id', 'tags'); * * The above code will query `$tagsRepository` for all tags that have `id`'s of the `$products` in `product_id` * property. Then it will match `$products` and the fetched tags and set all related tags on each product by * calling `::setTags()` with the related tags. * * @param array $objects Objects to which associated objects will be joined. * @param Repository $withRepository Repository from which associated objects should be fetched. * @param string $leftProperty Property of `$objects` under which the relation is stored. * @param string $rightProperty Property on which the fetched objects can be identified. * @param string $targetProperty Property of `$objects` on which the associated object will be set. This is * converted to a camelCase setter. * @param array $criteria [optional] Any additional criteria for finding the associated objects. * @param array $params [optional] Any additional search parameters for finding the associated objects. * @param boolean $excludeEmpty [optional] Should objects that didn't find the match be removed * from the results set? Set as `Knit::EXCLUDE_EMPTY` constant. Default: `false`. * * @return array */ public function joinMany(array $objects, Repository $withRepository, $leftProperty, $rightProperty, $targetProperty, array $criteria = [], array $params = [], $excludeEmpty = false) { // if empty collection then don't even waste time :) if (empty($objects)) { return $objects; } // select all objects for the right side of the join $criteria = array_merge($criteria, [$rightProperty => ObjectUtils::pluck($objects, $leftProperty)]); $withObjects = $withRepository->find($criteria, $params); $withObjects = ObjectUtils::groupBy($withObjects, $rightProperty); // do the programmatic join $getter = ObjectUtils::getter($leftProperty); $setter = ObjectUtils::setter($targetProperty); foreach ($objects as $i => $object) { $match = $object->{$getter}(); if (isset($withObjects[$match])) { $object->{$setter}($withObjects[$match]); } elseif ($excludeEmpty === Knit::EXCLUDE_EMPTY) { unset($objects[$i]); } } return array_values($objects); }
/** * Tests joining many items to a collection of objects. * * @param array $objects Objects. * @param array $criteria Search criteria. * @param array $params Search params. * @param array $withObjects Search results from the other repository. * @param boolean $excludeEmpty Exclude empty? * @param array $expected Expected result. * * @dataProvider provideJoinManyData */ public function testJoinMany(array $objects, array $criteria, array $params, array $withObjects, $excludeEmpty, array $expected) { $hobbitMocks = $this->provideMocks(); $hobbitRepository = $this->provideRepository($hobbitMocks); $giftMocks = $this->provideMocks(); $giftMocks['objectClass'] = Fixtures\ElvenGift::class; $giftRepository = $this->provideRepositoryStub($giftMocks, ['find']); if (!empty($objects)) { $giftRepository->expects($this->once())->method('find')->with(array_merge($criteria, ['owner_name' => ObjectUtils::pluck($objects, 'name')]), $params)->will($this->returnValue($withObjects)); } else { $giftRepository->expects($this->never())->method('find'); } $result = $hobbitRepository->joinMany($objects, $giftRepository, 'name', 'owner_name', 'gifts', $criteria, $params, $excludeEmpty); $this->assertInternalType('array', $result); $this->assertCount(count($expected), $result); foreach ($result as $hobbit) { $gifts = $hobbit->getGifts(); $expectedGifts = $expected[$hobbit->getName()]; $this->assertCount(count($expectedGifts), $gifts); foreach ($gifts as $i => $gift) { $this->assertEquals($expectedGifts[$i], $gift->getName()); } } }