PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.5.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.5.0
2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 1.1.0 All 77 releases
fluent-community / Modules / Migrations / Http / Controllers / BPMigrationController.php

BPMigrationController.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 2.5.0, at Modules/Migrations/Http/Controllers/BPMigrationController.php

346 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Modules\Migrations\Http\Controllers;
4
5 use FluentCommunity\App\Functions\Utility;
6 use FluentCommunity\App\Http\Controllers\Controller;
7 use FluentCommunity\App\Models\BaseSpace;
8 use FluentCommunity\App\Models\Space;
9 use FluentCommunity\App\Models\SpaceGroup;
10 use FluentCommunity\App\Models\User;
11 use FluentCommunity\App\Services\Helper;
12 use FluentCommunity\Framework\Http\Request\Request;
13 use FluentCommunity\Framework\Support\Arr;
14 use FluentCommunity\Modules\Migrations\Helpers\BPMigratorHelper;
15
16 class BPMigrationController extends Controller
17 {
18 protected $timeLimit = 40;
19
20 protected $startTimeStamp = 0;
21
22 public function getMigrationConfig(Request $request)
23 {
24 $previousConfig = $this->getCurrentStatus();
25
26 $groups = [];
27 $hasGroups = bp_is_active('groups');
28
29 if ($hasGroups) {
30 $groups = fluentCommunityApp('db')->table('bp_groups')->select('id', 'name')->get();
31 foreach ($groups as $group) {
32 $group->members_count = fluentCommunityApp('db')->table('bp_groups_members')->where('group_id', $group->id)->count();
33 $group->is_migrated = isset($previousConfig['migrated_groups'][$group->id]);
34 }
35 }
36
37 $data = [
38 'groupItems' => $groups,
39 'featureConfig' => [
40 'has_groups' => $hasGroups
41 ],
42 'stats' => BPMigratorHelper::getBbDataStats(),
43 'current_status' => $previousConfig,
44 'has_previous' => !empty($previousConfig['migrated_groups']) || !empty($previousConfig['last_migrated_user_id'])
45 ];
46
47 return $data;
48 }
49
50 public function startMigration(Request $request)
51 {
52 if ($request->get('reset_migration') === 'yes') {
53 update_option('_fcom_bp_migrations_status', [], 'no');
54 }
55
56 if ($request->get('delete_current_data') === 'yes') {
57 $this->deleteCurrentData();
58 }
59
60 $configMap = (array)$request->get('config', []);
61 $prevStatus = $this->getCurrentStatus();
62
63 if (bp_is_active('groups')) {
64 $groups = fluentCommunityApp('db')->table('bp_groups')->get();
65 if ($groups) {
66 foreach ($groups as $group) {
67 if (!empty($configMap[$group->id])) {
68 $group->space_menu_id = $configMap[$group->id];
69 }
70 }
71
72 $createdMaps = $this->migrateGroups($groups);
73 $prevStatus['migrated_groups'] = $createdMaps;
74 }
75 $prevStatus['current_stage'] = 'group_members';
76 } else {
77 $prevStatus['current_stage'] = 'posts';
78 }
79
80 BPMigratorHelper::maybeEnableFollowersModule();
81
82 $status = $this->updateCurrentStatus($prevStatus);
83
84 return [
85 'current_status' => $status,
86 'max_ids' => [
87 'group_member_max' => fluentCommunityApp('db')->table('bp_groups_members')->max('id'),
88 'max_user_id' => fluentCommunityApp('db')->table('bp_xprofile_data')->count('user_id'),
89 'max_activity_id' => fluentCommunityApp('db')->table('bp_activity')->max('id')
90 ]
91 ];
92 }
93
94 public function getPollingStatus()
95 {
96 $this->timeLimit = Utility::getMaxRunTime();
97 $this->startTimeStamp = time();
98
99 $status = $this->getCurrentStatus();
100 $currentStep = Arr::get($status, 'current_stage', 'groups');
101
102 $validStages = ['group_members', 'posts', 'users', 'completed'];
103
104 if (!in_array($currentStep, $validStages)) {
105 return $this->sendError([
106 'message' => 'Invalid stage. Please start the migration again.'
107 ]);
108 }
109
110 if ($currentStep == 'group_members') {
111 return $this->syncGroupMembers($status);
112 }
113
114 if ($currentStep == 'posts') {
115 return $this->syncPostsAndComments($status);
116 }
117
118 if ($currentStep == 'users') {
119 return $this->syncUsers($status);
120 }
121
122 return $this->getCurrentStatus();
123 }
124
125 protected function syncUsers($status)
126 {
127 if ($this->isTimeLimitExceeded(10)) {
128 return $this->getCurrentStatus();
129 }
130
131 $lastUserId = Arr::get($status, 'last_migrated_user_id', 0);
132 $usersIds = fluentCommunityApp('db')->table('bp_xprofile_data')
133 ->groupBy('user_id')
134 ->select(['user_id'])
135 ->when($lastUserId, function ($q) use ($lastUserId) {
136 $q->where('user_id', '>', $lastUserId);
137 })
138 ->orderBy('user_id', 'ASC')
139 ->limit(100)
140 ->get()
141 ->pluck('user_id')
142 ->toArray();
143
144 if (!$usersIds) {
145 $status['current_stage'] = 'completed';
146 $this->updateCurrentStatus($status, false);
147 return $this->getCurrentStatus();
148 }
149
150 $users = User::whereIn('id', $usersIds)->get();
151
152 if ($users->isEmpty()) {
153 $status['current_stage'] = 'completed';
154 $this->updateCurrentStatus($status, false);
155 return $this->getCurrentStatus();
156 }
157
158 $lastUserId = null;
159
160 foreach ($users as $user) {
161 $lastUserId = $user->ID;
162 BPMigratorHelper::syncUser($user);
163 }
164
165 do_action('fluent_community/after_sync_bp_users', $users);
166
167 $status['last_migrated_user_id'] = $lastUserId;
168 $this->updateCurrentStatus($status, false);
169
170 return $this->syncUsers($status);
171 }
172
173 protected function syncGroupMembers($status)
174 {
175 if ($this->isTimeLimitExceeded(10)) {
176 return $this->getCurrentStatus();
177 }
178
179 $lastMemberId = Arr::get($status, 'last_migrated_member_id', 0);
180
181 $groupMemberEntries = fluentCommunityApp('db')->table('bp_groups_members')
182 ->when($lastMemberId, function ($q) use ($lastMemberId) {
183 $q->where('id', '>', $lastMemberId);
184 })
185 ->orderBy('id', 'ASC')
186 ->limit(100)
187 ->get();
188
189 if ($groupMemberEntries->isEmpty()) {
190 $status['current_stage'] = 'posts';
191 $this->updateCurrentStatus($status, false);
192 return $this->getCurrentStatus();
193 }
194
195 foreach ($groupMemberEntries as $entry) {
196 $spaceId = Arr::get($status['migrated_groups'], $entry->group_id);
197 if (!$spaceId) {
198 continue;
199 }
200
201 $role = 'member';
202 if ($entry->is_admin == 1) {
203 $role = 'admin';
204 } else if ($entry->is_mod == 1) {
205 $role = 'moderator';
206 }
207
208 $entryData = [
209 'space_id' => $spaceId,
210 'user_id' => $entry->user_id,
211 'status' => 'active',
212 'role' => $role,
213 'created_at' => $entry->date_modified,
214 ];
215
216 if (!Helper::isUserInSpace($entryData['user_id'], $entryData['space_id'])) {
217 fluentCommunityApp('db')->table('fcom_space_user')->insert($entryData);
218 }
219
220 $status['last_migrated_member_id'] = $entry->id;
221 $status = $this->updateCurrentStatus($status, false);
222 }
223
224 return $this->syncGroupMembers($status);
225 }
226
227 protected function syncPostsAndComments($status)
228 {
229 if ($this->isTimeLimitExceeded(10)) {
230 return $this->getCurrentStatus();
231 }
232
233 $lastPostId = Arr::get($status, 'last_activity_id', 0);
234
235 $isBuddyBoss = BPMigratorHelper::isBuddyBoss();
236
237 $posts = fluentCommunityApp('db')->table('bp_activity')
238 ->where('type', 'activity_update')
239 ->when($isBuddyBoss, function ($q) {
240 $q->whereNotIn('privacy', ['media', 'onlyme']);
241 })
242 ->when($lastPostId, function ($q) use ($lastPostId) {
243 $q->where('id', '>', $lastPostId);
244 })
245 ->orderBy('id', 'ASC')
246 ->limit(40)
247 ->get();
248
249 if ($posts->isEmpty()) {
250 $status['current_stage'] = 'users';
251 $this->updateCurrentStatus($status, false);
252 return $this->getCurrentStatus();
253 }
254
255 foreach ($posts as $post) {
256 $status['last_activity_id'] = $post->id;
257 $status = $this->updateCurrentStatus($status, false);
258
259 if (fluentCommunityApp('db')->table('bp_activity_meta')->where('activity_id', $post->id)->where('meta_key', '_fcom_feed_id')->exists()) {
260 continue;
261 }
262
263 $feed = BPMigratorHelper::migratePost($post, Arr::get($status['migrated_groups'], $post->item_id, NULL));
264
265 if ($feed) {
266 fluentCommunityApp('db')->table('bp_activity_meta')
267 ->insert([
268 'activity_id' => $post->id,
269 'meta_key' => '_fcom_feed_id', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
270 'meta_value' => $feed->id // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value
271 ]);
272 }
273 }
274
275 return $this->syncPostsAndComments($status);
276 }
277
278 protected function migrateGroups($groups)
279 {
280 $createdMaps = [];
281 foreach ($groups as $group) {
282 $createdSpace = BPMigratorHelper::migrateGroupData($group);
283 if ($createdSpace) {
284 $createdMaps[$group->id] = $createdSpace->id;
285 }
286 }
287
288 update_option('_bp_fcom_group_maps', $createdMaps);
289
290 return $createdMaps;
291 }
292
293 private function isTimeLimitExceeded($offset = 10)
294 {
295 $timeLimit = $this->timeLimit - $offset;
296 $currentTime = time();
297 $timeElapsed = $currentTime - $this->startTimeStamp;
298
299 return $timeElapsed >= $timeLimit;
300 }
301
302 private function getCurrentStatus()
303 {
304 $defaults = [
305 'migrated_groups' => [],
306 'last_activity_id' => 0,
307 'migrated_posts_count' => 0,
308 'last_migrated_user_id' => 0,
309 'last_migrated_member_id' => 0,
310 'current_stage' => 'groups',
311 ];
312
313 $status = (array)get_option('_fcom_bp_migrations_status', $defaults);
314
315 $status = wp_parse_args($status, $defaults);
316
317 return $status;
318 }
319
320 private function updateCurrentStatus($newData, $resync = true)
321 {
322 if ($resync) {
323 $status = $this->getCurrentStatus();
324 $newData = wp_parse_args($newData, $status);
325 }
326
327 $newData = Arr::only($newData, [
328 'migrated_groups',
329 'last_activity_id',
330 'last_migrated_member_id',
331 'migrated_posts_count',
332 'last_migrated_user_id',
333 'current_stage'
334 ]);
335
336 update_option('_fcom_bp_migrations_status', $newData, 'no');
337
338 return $newData;
339 }
340
341 private function deleteCurrentData()
342 {
343 BPMigratorHelper::deleteCurrentData();
344 }
345 }
346