/** * Adds a new association to the list that will be used to filter the results of * any given query based on the results of finding records for that association. * You can pass a dot separated path of associations to this method as its first * parameter, this will translate in setting all those associations with the * `matching` option. * * If called with no arguments it will return the current tree of associations to * be matched. * * @param string|null $assoc A single association or a dot separated path of associations. * @param callable|null $builder the callback function to be used for setting extra * options to the filtering query * @return array The resulting containments array */ public function matching($assoc = null, callable $builder = null) { if ($this->_matching === null) { $this->_matching = new self(); } if ($assoc === null) { return $this->_matching->contain(); } $assocs = explode('.', $assoc); $last = array_pop($assocs); $containments = []; $pointer =& $containments; foreach ($assocs as $name) { $pointer[$name] = ['matching' => true]; $pointer =& $pointer[$name]; } $pointer[$last] = ['queryBuilder' => $builder, 'matching' => true]; return $this->_matching->contain($containments); }
/** * Adds a new association to the list that will be used to filter the results of * any given query based on the results of finding records for that association. * You can pass a dot separated path of associations to this method as its first * parameter, this will translate in setting all those associations with the * `matching` option. * * If called with no arguments it will return the current tree of associations to * be matched. * * @param string|null $assoc A single association or a dot separated path of associations. * @param callable|null $builder the callback function to be used for setting extra * options to the filtering query * @param array $options Extra options for the association matching, such as 'joinType' * and 'fields' * @return array The resulting containments array */ public function matching($assoc = null, callable $builder = null, $options = []) { if ($this->_matching === null) { $this->_matching = new self(); } if ($assoc === null) { return $this->_matching->contain(); } $assocs = explode('.', $assoc); $last = array_pop($assocs); $containments = []; $pointer =& $containments; $options += ['joinType' => 'INNER']; $opts = ['matching' => true] + $options; unset($opts['negateMatch']); foreach ($assocs as $name) { $pointer[$name] = $opts; $pointer =& $pointer[$name]; } $pointer[$last] = ['queryBuilder' => $builder, 'matching' => true] + $options; return $this->_matching->contain($containments); }
/** * Tests that the path for gettings to a deep assocition is materialized in an * array key * * @return void */ public function testNormalizedPath() { $contains = ['clients' => ['orders' => ['orderTypes', 'stuff' => ['stuffTypes']], 'companies' => ['categories']]]; $query = $this->getMock('\\Cake\\ORM\\Query', ['join'], [$this->connection, $this->table]); $loader = new EagerLoader(); $loader->contain($contains); $normalized = $loader->normalized($this->table); $this->assertEquals('clients', $normalized['clients']->aliasPath()); $this->assertEquals('client', $normalized['clients']->propertyPath()); $assocs = $normalized['clients']->associations(); $this->assertEquals('clients.orders', $assocs['orders']->aliasPath()); $this->assertEquals('client.order', $assocs['orders']->propertyPath()); $assocs = $assocs['orders']->associations(); $this->assertEquals('clients.orders.orderTypes', $assocs['orderTypes']->aliasPath()); $this->assertEquals('client.order.order_type', $assocs['orderTypes']->propertyPath()); $this->assertEquals('clients.orders.stuff', $assocs['stuff']->aliasPath()); $this->assertEquals('client.order.stuff', $assocs['stuff']->propertyPath()); $assocs = $assocs['stuff']->associations(); $this->assertEquals('clients.orders.stuff.stuffTypes', $assocs['stuffTypes']->aliasPath()); $this->assertEquals('client.order.stuff.stuff_type', $assocs['stuffTypes']->propertyPath()); }
/** * Test clearing containments but not matching joins. * * @return void */ public function testClearContain() { $contains = ['clients' => ['orders' => ['orderTypes', 'stuff' => ['stuffTypes']], 'companies' => ['categories']]]; $loader = new EagerLoader(); $loader->contain($contains); $loader->matching('clients.addresses'); $this->assertNull($loader->clearContain()); $result = $loader->normalized($this->table); $this->assertEquals([], $result); $this->assertArrayHasKey('clients', $loader->matching()); }