PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.7.7
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.7.7
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.7.7, at Modules/Migrations/Http/Controllers/BPMigrationController.php

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