/** * {@inheritdoc} */ public function apply($fromAlias, $fromIdentifier, $resourcePrefix, array $requesterIdentifiers, $mask, array $orX = []) { $this->query->join(['table' => $this->getAclSchema()->getPermissionsTableName(), 'alias' => 'acl_p', 'type' => 'LEFT', 'conditions' => $this->query->newExpr()->eq('acl_p.resource', $this->query->func()->concat([':acl_resource_prefix' => 'literal', $fromAlias . '.' . $fromIdentifier => 'literal']))]); $orX[] = $this->query->newExpr()->and_([$this->query->newExpr()->in('acl_p.requester', $requesterIdentifiers, 'string'), $this->query->newExpr(':acl_mask = (acl_p.mask & :acl_mask)')]); $this->query->andWhere($this->query->newExpr()->or_($orX)); $this->query->bind(':acl_resource_prefix', $resourcePrefix); $this->query->bind(':acl_mask', $mask, 'integer'); return $this->query; }
/** * Append a join to the junction table. * * @param \Cake\ORM\Query $query The query to append. * @param string|array $conditions The query conditions to use. * @return \Cake\ORM\Query The modified query. */ protected function _appendJunctionJoin($query, $conditions) { $name = $this->_junctionAssociationName(); $joins = $query->join(); $matching = [$name => ['table' => $this->junction()->table(), 'conditions' => $conditions, 'type' => 'INNER']]; $assoc = $this->target()->association($name); $query->addDefaultTypes($assoc->target())->join($matching + $joins, [], true); $query->eagerLoader()->addToJoinsMap($name, $assoc); return $query; }
/** * Alters a Query object to include the associated target table data in the final * result * * The options array accept the following keys: * * - includeFields: Whether to include target model fields in the result or not * - foreignKey: The name of the field to use as foreign key, if false none * will be used * - conditions: array with a list of conditions to filter the join with, this * will be merged with any conditions originally configured for this association * - fields: a list of fields in the target table to include in the result * - type: The type of join to be used (e.g. INNER) * the records found on this association * - aliasPath: A dot separated string representing the path of association names * followed from the passed query main table to this association. * - propertyPath: A dot separated string representing the path of association * properties to be followed from the passed query main entity to this * association * - joinType: The SQL join type to use in the query. * - negateMatch: Will append a condition to the passed query for excluding matches. * with this association. * * @param Query $query the query to be altered to include the target table data * @param array $options Any extra options or overrides to be taken in account * @return void * @throws \RuntimeException if the query builder passed does not return a query * object */ public function attachTo(Query $query, array $options = []) { $target = $this->target(); $joinType = empty($options['joinType']) ? $this->joinType() : $options['joinType']; $options += ['includeFields' => true, 'foreignKey' => $this->foreignKey(), 'conditions' => [], 'fields' => [], 'type' => $joinType, 'table' => $target->table(), 'finder' => $this->finder()]; if (!empty($options['foreignKey'])) { $joinCondition = $this->_joinCondition($options); if ($joinCondition) { $options['conditions'][] = $joinCondition; } } list($finder, $opts) = $this->_extractFinder($options['finder']); $dummy = $this->find($finder, $opts)->eagerLoaded(true); if (!empty($options['queryBuilder'])) { $dummy = $options['queryBuilder']($dummy); if (!$dummy instanceof Query) { throw new RuntimeException(sprintf('Query builder for association "%s" did not return a query', $this->name())); } } $dummy->where($options['conditions']); $this->_dispatchBeforeFind($dummy); $joinOptions = ['table' => 1, 'conditions' => 1, 'type' => 1]; $options['conditions'] = $dummy->clause('where'); $query->join([$this->_name => array_intersect_key($options, $joinOptions)]); $this->_appendFields($query, $dummy, $options); $this->_formatAssociationResults($query, $dummy, $options); $this->_bindNewAssociations($query, $dummy, $options); $this->_appendNotMatching($query, $options); }