Completed
Pull Request — master (#546)
by Maxence
01:58
created

CoreQueryBuilder::limitToMembership()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 9.344
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Circles - Bring cloud-users closer together.
7
 *
8
 * This file is licensed under the Affero General Public License version 3 or
9
 * later. See the COPYING file.
10
 *
11
 * @author Maxence Lange <[email protected]>
12
 * @copyright 2017
13
 * @license GNU AGPL version 3 or any later version
14
 *
15
 * This program is free software: you can redistribute it and/or modify
16
 * it under the terms of the GNU Affero General Public License as
17
 * published by the Free Software Foundation, either version 3 of the
18
 * License, or (at your option) any later version.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
27
 *
28
 */
29
30
31
namespace OCA\Circles\Db;
32
33
34
use daita\MySmallPhpTools\Db\Nextcloud\nc21\NC21ExtendedQueryBuilder;
35
use Doctrine\DBAL\Query\QueryBuilder;
36
use OCA\Circles\Model\Circle;
37
use OCA\Circles\Model\Member;
38
39
/**
40
 * Class CoreQueryBuilder
41
 *
42
 * @package OCA\Circles\Db
43
 */
44
class CoreQueryBuilder extends NC21ExtendedQueryBuilder {
45
46
47
	/**
48
	 * @param string $id
49
	 */
50
	public function limitToUniqueId(string $id): void {
51
		$this->limitToDBField('unique_id', $id, false);
52
	}
53
54
	/**
55
	 * @param string $id
56
	 */
57
	public function limitToCircleId(string $id): void {
58
		$this->limitToDBField('circle_id', $id, false);
59
	}
60
61
	/**
62
	 * @param string $host
63
	 */
64
	public function limitToInstance(string $host): void {
65
		$this->limitToDBField('instance', $host, false);
66
	}
67
68
69
	public function limitToViewer(Member $viewer): void {
70
		$this->leftJoinViewer($viewer, 'v');
71
		$this->limitVisibility('v');
72
	}
73
74
75
	/**
76
	 * @param Member $member
77
	 */
78
	public function limitToMembership(Member $member): void {
79
		if ($this->getType() !== QueryBuilder::SELECT) {
80
			return;
81
		}
82
83
		$expr = $this->expr();
84
		$pf = $this->getDefaultSelectAlias() . '.';
85
86
		$this->selectAlias('m.user_id', 'member_user_id')
87
			 ->selectAlias('m.user_type', 'member_user_type')
88
			 ->selectAlias('m.member_id', 'member_member_id')
89
			 ->selectAlias('m.circle_id', 'member_circle_id')
90
			 ->selectAlias('m.instance', 'member_instance')
91
			 ->selectAlias('m.cached_name', 'member_cached_name')
92
			 ->selectAlias('m.cached_update', 'member_cached_update')
93
			 ->selectAlias('m.status', 'member_status')
94
			 ->selectAlias('m.level', 'member_level')
95
			 ->selectAlias('m.note', 'member_note')
96
			 ->selectAlias('m.contact_id', 'member_contact_id')
97
			 ->selectAlias('m.contact_meta', 'member_contact_meta')
98
			 ->selectAlias('m.joined', 'member_joined')
99
			 ->leftJoin(
100
				 $this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, 'm',
101
				 $expr->eq('m.circle_id', $pf . 'unique_id')
102
			 );
103
104
		// TODO: Check in big table if it is better to put condition in andWhere() or in LeftJoin()
105
		$this->andWhere(
106
			$expr->andX(
107
				$expr->eq('m.user_id', $this->createNamedParameter($member->getUserId())),
108
				$expr->eq('m.user_type', $this->createNamedParameter($member->getUserType())),
109
				$expr->eq('m.instance', $this->createNamedParameter($member->getInstance())),
110
				$expr->gte('m.level', $this->createNamedParameter($member->getLevel()))
111
			)
112
		);
113
	}
114
115
116
	/**
117
	 *
118
	 */
119
	public function leftJoinOwner() {
120
		if ($this->getType() !== QueryBuilder::SELECT) {
121
			return;
122
		}
123
124
		$expr = $this->expr();
125
		$pf = $this->getDefaultSelectAlias() . '.';
126
127
		$this->selectAlias('o.user_id', 'owner_user_id')
128
			 ->selectAlias('o.user_type', 'owner_user_type')
129
			 ->selectAlias('o.member_id', 'owner_member_id')
130
			 ->selectAlias('o.circle_id', 'owner_circle_id')
131
			 ->selectAlias('o.instance', 'owner_instance')
132
			 ->selectAlias('o.cached_name', 'owner_cached_name')
133
			 ->selectAlias('o.cached_update', 'owner_cached_update')
134
			 ->selectAlias('o.status', 'owner_status')
135
			 ->selectAlias('o.level', 'owner_level')
136
			 ->selectAlias('o.note', 'owner_note')
137
			 ->selectAlias('o.contact_id', 'owner_contact_id')
138
			 ->selectAlias('o.contact_meta', 'owner_contact_meta')
139
			 ->selectAlias('o.joined', 'owner_joined')
140
			 ->leftJoin(
141
				 $this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, 'o',
142
				 $expr->andX(
143
					 $expr->eq('o.circle_id', $pf . 'unique_id'),
144
					 $expr->eq('o.level', $this->createNamedParameter(Member::LEVEL_OWNER))
145
				 )
146
			 );
147
	}
148
149
150
	/**
151
	 * Left join members to filter userId as viewer.
152
	 *
153
	 * @param Member $viewer
154
	 * @param string $alias
155
	 */
156
	public function leftJoinViewer(Member $viewer, string $alias = 'v') {
157
		if ($this->getType() !== QueryBuilder::SELECT) {
158
			return;
159
		}
160
161
		$expr = $this->expr();
162
		$pf = $this->getDefaultSelectAlias() . '.';
163
164
		$this->selectAlias('v.user_id', 'viewer_user_id')
165
			 ->selectAlias('v.user_type', 'viewer_user_type')
166
			 ->selectAlias('v.member_id', 'viewer_member_id')
167
			 ->selectAlias('v.circle_id', 'viewer_circle_id')
168
			 ->selectAlias('v.instance', 'viewer_instance')
169
			 ->selectAlias('v.cached_name', 'viewer_cached_name')
170
			 ->selectAlias('v.cached_update', 'viewer_cached_update')
171
			 ->selectAlias('v.status', 'viewer_status')
172
			 ->selectAlias('v.level', 'viewer_level')
173
			 ->selectAlias('v.note', 'viewer_note')
174
			 ->selectAlias('v.contact_id', 'viewer_contact_id')
175
			 ->selectAlias('v.contact_meta', 'viewer_contact_meta')
176
			 ->selectAlias('v.joined', 'viewer_joined')
177
			 ->leftJoin(
178
				 $this->getDefaultSelectAlias(), CoreRequestBuilder::TABLE_MEMBER, 'v',
179
				 $expr->andX(
180
					 $expr->eq('v.circle_id', $pf . 'unique_id'),
181
					 $expr->eq('v.user_id', $this->createNamedParameter($viewer->getUserId())),
182
					 $expr->eq('v.user_type', $this->createNamedParameter($viewer->getUserType())),
183
					 $expr->eq('v.instance', $this->createNamedParameter($viewer->getInstance()))
184
				 )
185
			 );
186
	}
187
188
189
	/**
190
	 * @param string $alias
191
	 */
192
	protected function limitVisibility(string $alias = 'v') {
193
		$expr = $this->expr();
194
195
		// Visibility to non-member is
196
		// - 2 (Personal), if viewer is owner)
197
		// - 4 (Visible to everyone)
198
		$orX = $expr->orX();
199
		$orX->add(
200
			$expr->andX(
201
				$expr->bitwiseAnd($this->getDefaultSelectAlias() . '.config', Circle::CFG_PERSONAL),
202
				$expr->eq($alias . '.level', $this->createNamedParameter(Member::LEVEL_OWNER))
203
			)
204
		);
205
		$orX->add($expr->bitwiseAnd($this->getDefaultSelectAlias() . '.config', Circle::CFG_VISIBLE));
206
		$this->andWhere($orX);
207
208
		// - 128 means fully hidden, filtering
209
		$bitHidden = $expr->bitwiseAnd($this->getDefaultSelectAlias() . '.config', Circle::CFG_HIDDEN);
210
		$this->andWhere($this->createFunction('NOT') . $bitHidden);
211
212
213
//		$orTypes = $this->generateLimit($qb, $circleUniqueId, $userId, $type, $name, $forceAll);
214
//		if (sizeof($orTypes) === 0) {
215
//			throw new ConfigNoCircleAvailableException(
216
//				$this->l10n->t(
217
//					'You cannot use the Circles Application until your administrator has allowed at least one type of circles'
218
//				)
219
//			);
220
//		}
221
222
//		$orXTypes = $this->expr()
223
//						 ->orX();
224
//		foreach ($orTypes as $orType) {
225
//			$orXTypes->add($orType);
226
//		}
227
//
228
//		$qb->andWhere($orXTypes);
229
	}
230
231
232
	/**
233
	 * @param int $flag
234
	 */
235
	public function filterConfig(int $flag): void {
236
		$this->andWhere($this->expr()->bitwiseAnd($this->getDefaultSelectAlias() . '.config', $flag));
237
	}
238
239
}
240
241