Completed
Pull Request — master (#64)
by Joas
04:34 queued 01:46
created

ImportOwncloudCustomGroups::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2017 Joas Schilling <[email protected]>
4
 *
5
 * @author Joas Schilling <[email protected]>
6
 *
7
 * @license GNU AGPL version 3 or any later version
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License as
11
 * published by the Free Software Foundation, either version 3 of the
12
 * License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU Affero General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Affero General Public License
20
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 */
23
24
namespace OCA\Circles\Migration;
25
26
use OCA\Circles\Model\Circle;
27
use OCA\Circles\Model\Member;
28
use OCP\IConfig;
29
use OCP\IDBConnection;
30
use OCP\Migration\IOutput;
31
use OCP\Migration\IRepairStep;
32
use OCP\Share;
33
34
/**
35
 * Class ImportOwncloudCustomGroups
36
 *
37
 * @package OCA\Circles\Migration
38
 */
39
class ImportOwncloudCustomGroups implements IRepairStep {
40
41
	/** @var IDBConnection */
42
	protected $connection;
43
44
	/** @var  IConfig */
45
	protected $config;
46
47
	/** @var array */
48
	protected $circlesById = [];
49
	/** @var array */
50
	protected $circlesByUri = [];
51
	/** @var array */
52
	protected $circleHasAdmin = [];
53
54
	public function __construct(IDBConnection $connection, IConfig $config) {
55
		$this->connection = $connection;
56
		$this->config = $config;
57
	}
58
59
	/**
60
	 * Returns the step's name
61
	 *
62
	 * @return string
63
	 * @since 9.1.0
64
	 */
65
	public function getName() {
66
		return 'Fix the share type of guest shares when migrating from ownCloud';
67
	}
68
69
	/**
70
	 * @param IOutput $output
71
	 */
72
	public function run(IOutput $output) {
73
		if (!$this->shouldRun()) {
74
			return;
75
		}
76
77
		$this->createCircles($output);
78
		$this->createMemberships($output);
79
		$this->updateShares($output);
80
81
		$this->config->setAppValue('circles', 'imported_custom_groups', 'true');
82
	}
83
84
	/**
85
	 * @param IOutput $output
86
	 */
87
	public function createCircles(IOutput $output) {
88
		$output->info('Creating circles');
89
90
		$select = $this->connection->getQueryBuilder();
91
		$select->select('*')
92
			->from('custom_group')
93
			->orderBy('group_id');
94
95
		$insert = $this->connection->getQueryBuilder();
96
		$insert->insert('circles_circles')
97
			->values([
98
				'name' => $insert->createParameter('name'),
99
				'type' => $insert->createParameter('type'),
100
				'creation' => $insert->createFunction('NOW()'),
101
			]);
102
103
		$output->startProgress();
104
		$result = $select->execute();
105
106
		while ($row = $result->fetch()) {
107
			$insert->setParameter('name', $row['display_name'])
108
				->setParameter('type', Circle::CIRCLES_PERSONAL);
109
110
			$insert->execute();
111
			$output->advance();
112
113
			$this->circlesById[$row['groud_id']] = $insert->getLastInsertId();
114
			$this->circlesByUri[$row['uri']] = $this->circlesById[$row['groud_id']];
115
		}
116
117
		$result->closeCursor();
118
		$output->finishProgress();
119
	}
120
121
	/**
122
	 * @param IOutput $output
123
	 */
124
	public function createMemberships(IOutput $output) {
125
		$output->info('Creating memberships');
126
127
		$select = $this->connection->getQueryBuilder();
128
		$select->select('*')
129
			->from('custom_group_member')
130
			->orderBy('group_id');
131
132
		$insert = $this->connection->getQueryBuilder();
133
		$insert->insert('circles_members')
134
			->values([
135
				'circle_id' => $insert->createParameter('circle_id'),
136
				'user_id' => $insert->createParameter('user_id'),
137
				'level' => $insert->createParameter('level'),
138
				'status' => $insert->createParameter('status'),
139
				'joined' => $insert->createFunction('NOW()'),
140
			]);
141
142
		$output->startProgress();
143
		$result = $select->execute();
144
145
		while ($row = $result->fetch()) {
146
			if (!isset($this->circlesById[$row['group_id']])) {
147
				// Stray membership
148
				continue;
149
			}
150
151
			$level = (int) $row['role'] === 1 ? Member::LEVEL_OWNER : Member::LEVEL_MEMBER;
152
153
			if ($level === Member::LEVEL_OWNER) {
154
				if (isset($this->circleHasAdmin[$this->circlesById[$row['group_id']]])) {
155
					$level = Member::LEVEL_MODERATOR;
156
				} else {
157
					$this->circleHasAdmin[$this->circlesById[$row['group_id']]] = $row['user_id'];
158
				}
159
			}
160
161
			$insert->setParameter('circle_id', $this->circlesById[$row['group_id']])
162
				->setParameter('user_id', $row['user_id'])
163
				->setParameter('level', $level)
164
				->setParameter('status', 'Member');
165
166
			$insert->execute();
167
			$output->advance();
168
		}
169
170
		$result->closeCursor();
171
		$output->finishProgress();
172
	}
173
174
	/**
175
	 * Update shares
176
	 * - type 7 instead of 1
177
	 * - with circle ID instead of `customgroup_` + group URI
178
	 *
179
	 * @param IOutput $output
180
	 */
181
	public function updateShares(IOutput $output) {
182
		$output->info('Update shares from custom groups to circles');
183
184
		$select = $this->connection->getQueryBuilder();
185
		$select->select('*')
186
			->from('share')
187
			->where($select->expr()->eq('share_type', $select->createNamedParameter(Share::SHARE_TYPE_GROUP)));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 102 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
188
189
		$update = $this->connection->getQueryBuilder();
190
		$update->update('share')
191
			->set('share_type', $update->createParameter('type'))
192
			->set('share_with', $update->createParameter('with'))
193
			->where($update->expr()->eq('id', $update->createParameter('id')));
194
195
		$output->startProgress();
196
		$result = $select->execute();
197
198
		while ($row = $result->fetch()) {
199
			$with = $row['share_with'];
200
			if (strpos($with, 'customgroup_') !== 0) {
201
				// Stray membership
202
				continue;
203
			}
204
205
			$groupUri = substr($with, strlen('customgroup_'));
206
			if ($groupUri === '' || !isset($this->circlesByUri[$groupUri])) {
207
				// Not a customgroup
208
				continue;
209
			}
210
211
			$update->setParameter('type', Share::SHARE_TYPE_CIRCLE)
212
				->setParameter('with', $this->circlesByUri[$groupUri])
213
				->setParameter('id', $row['id']);
214
215
			$update->execute();
216
			$output->advance();
217
		}
218
219
		$result->closeCursor();
220
		$output->finishProgress();
221
	}
222
223
	protected function shouldRun() {
224
		$alreadyImported = $this->config->getAppValue('circles', 'imported_custom_groups', 'false');
225
		return !$alreadyImported && $this->connection->tableExists('custom_group') && $this->connection->tableExists('custom_group_member');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 134 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
226
	}
227
228
}
229