/** * 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 that an exception is thrown when an unrecognized operator is used. * * @expectedException \Knit\Exceptions\InvalidOperatorException */ public function testFindWithInvalidOperator() { $this->insertData(); $this->repository->find(['height:exists' => 142]); }
/** * Tests that an exception is thrown when the find query fails. * * @expectedException \Knit\Exceptions\StoreQueryErrorException */ public function testFindQueryError() { $this->repository->find([], ['orderBy' => 'no_such_column']); }