4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC. All rights reserved. |
7 | This work is published under the GNU AGPLv3 license with some |
8 | permitted exceptions and without any warranty. For full license |
9 | and copyright information, see https://civicrm.org/licensing |
10 +--------------------------------------------------------------------+
16 * @copyright CiviCRM LLC https://civicrm.org/licensing
22 namespace Civi\Api4\Service\Schema
;
24 use Civi\Api4\Query\Api4SelectQuery
;
33 * @var \Civi\Api4\Service\Schema\Joinable\Joinable[][]
35 protected $cache = [];
38 * @param SchemaMap $schemaMap
40 public function __construct(SchemaMap
$schemaMap) {
41 $this->schemaMap
= $schemaMap;
45 * @param \Civi\Api4\Query\Api4SelectQuery $query
46 * The query object to do the joins on
47 * @param string $joinPath
48 * A path of aliases in dot notation, e.g. contact.phone
50 * Can be LEFT or INNER
53 * @return \Civi\Api4\Service\Schema\Joinable\Joinable[]
54 * The path used to make the join
56 public function join(Api4SelectQuery
$query, $joinPath, $side = 'LEFT') {
57 $fullPath = $this->getPath($query->getFrom(), $joinPath);
58 $baseTable = $query::MAIN_TABLE_ALIAS
;
60 foreach ($fullPath as $link) {
61 $target = $link->getTargetTable();
62 $alias = $link->getAlias();
63 $bao = \CRM_Core_DAO_AllCoreTables
::getBAOClassName(\CRM_Core_DAO_AllCoreTables
::getClassForTable($target));
64 $conditions = array_merge(
65 $link->getConditionsForJoin($baseTable),
66 $query->getAclClause($alias, $bao, explode('.', $joinPath))
69 $query->join($side, $target, $alias, $conditions);
71 $baseTable = $link->getAlias();
78 * Determines if path string points to a simple n-1 join that can be automatically added
80 * @param string $baseTable
85 public function canAutoJoin($baseTable, $joinPath) {
87 $path = $this->getPath($baseTable, $joinPath);
88 foreach ($path as $joinable) {
89 if ($joinable->getJoinType() === $joinable::JOIN_TYPE_ONE_TO_MANY
) {
95 catch (\Exception
$e) {
101 * @param string $baseTable
102 * @param string $joinPath
104 * @return \Civi\Api4\Service\Schema\Joinable\Joinable[]
107 protected function getPath($baseTable, $joinPath) {
108 $cacheKey = sprintf('%s.%s', $baseTable, $joinPath);
109 if (!isset($this->cache
[$cacheKey])) {
110 $stack = explode('.', $joinPath);
113 foreach ($stack as $key => $targetAlias) {
114 $links = $this->schemaMap
->getPath($baseTable, $targetAlias);
117 throw new \
Exception(sprintf('Cannot join %s to %s', $baseTable, $targetAlias));
120 $fullPath = array_merge($fullPath, $links);
121 $lastLink = end($links);
122 $baseTable = $lastLink->getTargetTable();
126 $this->cache
[$cacheKey] = $fullPath;
129 return $this->cache
[$cacheKey];