Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions lib/Db/CircleRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,9 @@ public function getCircles(
$qb->setOptions(
[CoreQueryBuilder::CIRCLE],
[
'getData' => true,
'mustBeMember' => $params->gBool('mustBeMember')
'getData' => true,
'mustBeMember' => $params->gBool('mustBeMember'),
'initiatorDirectMember' => true
]
);

Expand Down Expand Up @@ -239,7 +240,14 @@ public function getCircle(
int $filter = Circle::CFG_BACKEND | Circle::CFG_SINGLE | Circle::CFG_HIDDEN
): Circle {
$qb = $this->getCircleSelectSql();
$qb->setOptions([CoreQueryBuilder::CIRCLE], ['getData' => true, 'canBeVisitor' => true]);
$qb->setOptions(
[CoreQueryBuilder::CIRCLE],
[
'getData' => true,
'canBeVisitor' => true,
'initiatorDirectMember' => true
]
);

$qb->limitToUniqueId($id);
$qb->filterCircles(CoreQueryBuilder::CIRCLE, $filter);
Expand Down
66 changes: 56 additions & 10 deletions lib/Db/CoreQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
const REMOTE = 'remote';
const BASED_ON = 'basedon';
const INITIATOR = 'initiator';
const DIRECT_INITIATOR = 'initiatordirect';
const MEMBERSHIPS = 'memberships';
const CONFIG = 'config';
const UPSTREAM_MEMBERSHIPS = 'upstreammemberships';
Expand All @@ -88,23 +89,26 @@ class CoreQueryBuilder extends NC22ExtendedQueryBuilder {
self::MEMBER
],
self::CIRCLE => [
self::OPTIONS => [
self::OPTIONS => [
],
self::MEMBER,
self::MEMBER_COUNT,
self::OWNER => [
self::OWNER => [
self::BASED_ON
],
self::MEMBERSHIPS => [
self::MEMBERSHIPS => [
self::CONFIG
],
self::INITIATOR => [
self::DIRECT_INITIATOR => [
self::BASED_ON
],
self::INITIATOR => [
self::BASED_ON,
self::INHERITED_BY => [
self::MEMBERSHIPS
]
],
self::REMOTE => [
self::REMOTE => [
self::MEMBER,
self::CIRCLE => [
self::OWNER
Expand Down Expand Up @@ -1135,6 +1139,26 @@ public function leftJoinInitiator(
return;
}

// bypass memberships
if ($this->getBool('initiatorDirectMember', $options, false)) {
try {
$aliasDirectInitiator = $this->generateAlias($alias, self::DIRECT_INITIATOR, $options);

$this->generateMemberSelectAlias($aliasDirectInitiator)
->leftJoin(
$helperAlias,
CoreRequestBuilder::TABLE_MEMBER,
$aliasDirectInitiator,
$expr->andX(
$this->exprLimit('single_id', $initiator->getSingleId(), $aliasDirectInitiator),
$expr->eq($aliasDirectInitiator . '.circle_id', $helperAlias . '.' . $field)
)
);
} catch (RequestBuilderException $e) {
}
}


try {
$aliasInitiator = $this->generateAlias($alias, self::INITIATOR, $options);
$this->leftJoin(
Expand Down Expand Up @@ -1164,11 +1188,10 @@ public function leftJoinInitiator(
'instance' => $initiator->getInstance()
];
}
$this->generateMemberSelectAlias($aliasInitiator, $default);

$this->generateMemberSelectAlias($aliasInheritedBy);
$aliasInheritedByMembership = $this->generateAlias($aliasInheritedBy, self::MEMBERSHIPS);
$this->generateMembershipSelectAlias($aliasMembership, $aliasInheritedByMembership);
$this->generateMemberSelectAlias($aliasInitiator, $default)
->generateMemberSelectAlias($aliasInheritedBy)
->generateMembershipSelectAlias($aliasMembership, $aliasInheritedByMembership);
} catch (RequestBuilderException $e) {
}
}
Expand All @@ -1183,6 +1206,11 @@ public function leftJoinInitiator(
protected function limitInitiatorVisibility(string $alias): ICompositeExpression {
$aliasMembership = $this->generateAlias($alias, self::MEMBERSHIPS, $options);
$aliasMembershipCircle = $this->generateAlias($aliasMembership, self::CONFIG, $options);
$levelCheck = [$aliasMembership];

if ($this->getBool('initiatorDirectMember', $options, false)) {
array_push($levelCheck, $this->generateAlias($alias, self::DIRECT_INITIATOR, $options));
}

$filterPersonalCircle = $this->getBool('filterPersonalCircle', $options, true);

Expand All @@ -1193,6 +1221,7 @@ protected function limitInitiatorVisibility(string $alias): ICompositeExpression
// - 2 (Personal), if initiator is owner)
// - 4 (Visible to everyone)
$orX = $expr->orX();

if ($filterPersonalCircle) {
$orX->add(
$expr->andX(
Expand All @@ -1204,7 +1233,7 @@ protected function limitInitiatorVisibility(string $alias): ICompositeExpression

$andXMember = $expr->andX();
$andXMember->add(
$expr->gte($aliasMembership . '.level', $this->createNamedParameter(Member::LEVEL_MEMBER))
$this->orXCheckLevel($levelCheck, Member::LEVEL_MEMBER),
);
if ($filterPersonalCircle) {
$andXMember->add(
Expand Down Expand Up @@ -1570,5 +1599,22 @@ public function getAvailablePath(string $prefix): array {
return $path;
}


/**
* @param array $aliases
* @param int $level
*
* @return ICompositeExpression
*/
private function orXCheckLevel(array $aliases, int $level): ICompositeExpression {
$expr = $this->expr();
$orX = $expr->orX();
foreach ($aliases as $alias) {
$orX->add($expr->gte($alias . '.level', $this->createNamedParameter($level)));
}

return $orX;
}

}

24 changes: 23 additions & 1 deletion lib/Model/Circle.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ class Circle extends ManagedModel implements IMemberships, IDeserializable, INC2
/** @var Member */
private $initiator;

/** @var Member */
private $directInitiator;

/** @var array */
private $settings = [];

Expand Down Expand Up @@ -516,16 +519,35 @@ public function setInitiator(?Member $initiator): self {
* @return Member
*/
public function getInitiator(): Member {
if (is_null($this->initiator)
|| ($this->initiator->getId() === ''
&& !is_null($this->directInitiator)
&& $this->directInitiator->getId() !== '')) {
return $this->directInitiator;
}

return $this->initiator;
}

/**
* @return bool
*/
public function hasInitiator(): bool {
return ($this->initiator !== null);
return (!is_null($this->initiator) || !is_null($this->directInitiator));
}

/**
* @param Member|null $directInitiator
*
* @return $this
*/
public function setDirectInitiator(?Member $directInitiator): self {
$this->directInitiator = $directInitiator;

return $this;
}


/**
* @param string $instance
*
Expand Down
9 changes: 9 additions & 0 deletions lib/Model/ModelManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@ private function importIntoCircle(Circle $circle, array $data, string $path, str
} catch (MemberNotFoundException $e) {
}
break;

case CoreQueryBuilder::DIRECT_INITIATOR;
try {
$directInitiator = new Member();
$directInitiator->importFromDatabase($data, $prefix);
$circle->setDirectInitiator($directInitiator);
} catch (MemberNotFoundException $e) {
}
break;
}
}

Expand Down