从虚线路径生成QueryBuilder

时间:2016-07-06 14:35:17

标签: php doctrine-orm symfony

我即将根据潜在的虚线路径字段创建QueryBuilder生成器。

想象一下3个实体:Site链接到与Customer相关联的Address

我需要获取给定网站客户地址的城市:

  

site.customer.address.city

会生成此查询:

$qb = $em->getRepository(Site::class)->createQueryBuilder()
$qb
    ->select('address.city')
    ->join('customer', 'customer')
    ->join('customer.address', 'address')
;

我想创建递归函数来生成对join => alias数组

我可以使用一些工具来重新发明轮子吗?

否则我会在这里用我的解决方案回答。

1 个答案:

答案 0 :(得分:0)

这是我的转储解决方案

/**
 * @param string|array $dottedParts
 * @param string $parent
 * @return array
 */
public function getJoinsFromDottedPath($dottedParts, $parent = 'entity')
{
    if (!is_array($dottedParts)) {
        // Assuming the $dottedParts is a string
        if (!strstr($dottedParts, '.')) {
            // Exiting if this string does not contain any dot
            return array();
        }
        // Converting into array
        $dottedParts = explode('.', $dottedParts);
    }
    $joins = array();
    // Adding the current join
    $joins[$parent.'.'.$dottedParts[0]] = $dottedParts[0];
    if (count($dottedParts) > 2) {
        // There are children
        $parent = array_shift($dottedParts);
        $children = $this->getJoinsFromDottedPath($dottedParts, $parent);
        // They are part of the family
        $joins = array_merge($joins, $children);
    }

    return $joins;
}

他的考试

function testGetJoinsFromDottedPath()
{
    $joins = $this->admin->getJoinsFromDottedPath('site.customer');
    $this->assertCount(1, $joins);
    $this->assertEquals('entity.site', array_keys($joins)[0]);
    $this->assertEquals('site', array_values($joins)[0]);

    $joins = $this->admin->getJoinsFromDottedPath('site.customer.address.city');
    $this->assertCount(3, $joins);
    $this->assertEquals('entity.site', array_keys($joins)[0]);
    $this->assertEquals('site', array_values($joins)[0]);
    $this->assertEquals('site.customer', array_keys($joins)[1]);
    $this->assertEquals('customer', array_values($joins)[1]);
    $this->assertEquals('customer.address', array_keys($joins)[2]);
    $this->assertEquals('address', array_values($joins)[2]);
}

随意改进相关的gist和/或建议任何更好的解决方案