• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

waynestate / base-site / 18878507988

28 Oct 2025 02:37PM UTC coverage: 99.083% (+0.2%) from 98.864%
18878507988

push

github

nickdenardis
Merge branch 'release/8.15.0'

113 of 113 new or added lines in 15 files covered. (100.0%)

10 existing lines in 1 file now uncovered.

1081 of 1091 relevant lines covered (99.08%)

7.1 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.59
/app/Repositories/ProfileRepository.php
1
<?php
2

3
namespace App\Repositories;
4

5
use Illuminate\Support\Arr;
6
use Illuminate\Support\Str;
7
use Waynestate\Api\Connector;
8
use Illuminate\Cache\Repository;
9
use Waynestate\Youtube\ParseId;
10
use Waynestate\Api\News;
11
use Waynestate\Promotions\ParsePromos;
12
use Contracts\Repositories\ProfileRepositoryContract;
13
use Illuminate\Support\Facades\Config;
14

15
class ProfileRepository implements ProfileRepositoryContract
16
{
17
    /** @var Connector */
18
    protected $wsuApi;
19

20
    /** @var ParsePromos */
21
    protected $parsePromos;
22

23
    /** @var Repository */
24
    protected $cache;
25

26
    /** @var News */
27
    protected $newsApi;
28

29
    /**
30
     * Construct the repository.
31
     */
32
    public function __construct(Connector $wsuApi, ParsePromos $parsePromos, Repository $cache, News $newsApi)
33
    {
34
        $this->wsuApi = $wsuApi;
25✔
35
        $this->parsePromos = $parsePromos;
25✔
36
        $this->cache = $cache;
25✔
37
        $this->newsApi = $newsApi;
25✔
38
    }
39

40
    /**
41
     * {@inheritdoc}
42
     */
43
    public function getProfiles(int $site_id, ?string $selected_group = null, $subsite_url = null): array
44
    {
45
        $params = [
5✔
46
            'method' => 'profile.users.listing',
5✔
47
            'site_id' => $site_id,
5✔
48
            'groups' => $selected_group,
5✔
49
        ];
5✔
50

51
        $profile_listing = $this->cache->remember($params['method'].md5(serialize($params)), config('cache.ttl'), function () use ($params) {
5✔
52
            $this->wsuApi->nextRequestProduction();
5✔
53

54
            return $this->wsuApi->sendRequest($params['method'], $params);
5✔
55
        });
5✔
56

57
        // Build the link
58
        if (empty($profile_listing['error'])) {
5✔
59
            $profile_listing = collect($profile_listing)->map(function ($item) use ($subsite_url) {
4✔
60
                $item['link'] = '/'.$subsite_url.'profile/'.$item['data']['AccessID'];
4✔
61

62
                $item['full_name'] = $this->getPageTitleFromName(['profile' => $item]);
4✔
63

64
                return $item;
4✔
65
            })->toArray();
4✔
66
        }
67

68
        // Make sure the return is an array
69
        $profiles['profiles'] = empty($profile_listing['error']) ? $profile_listing : [];
5✔
70

71
        return $profiles;
5✔
72
    }
73

74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function getProfilesByGroup($site_id, $subsite_url = null): array
78
    {
79
        // Get the groups for the dropdown
80
        $dropdown_groups = $this->getDropdownOfGroups($site_id);
3✔
81

82
        // Determine which group(s) to filter by
83
        $group_ids = $this->getGroupIds(null, null, $dropdown_groups['dropdown_groups']);
3✔
84

85
        // Get all the profiles
86
        $all_profiles = $this->getProfiles($site_id, $group_ids, $subsite_url);
3✔
87

88
        // Organize profiles by the group they are in keyed by accessid
89
        $grouped = collect($all_profiles['profiles'])->keyBy('data.AccessID')
3✔
90
        ->groupBy([
3✔
91
            function ($profile) {
3✔
92
                return $profile['groups'];
2✔
93
            },
3✔
94
        ], $preserveKeys = true)
3✔
95
        ->toArray();
3✔
96

97
        // Follow the ordering of groups from the CMS
98
        $profiles['profiles'] = $this->sortGroupsByDisplayOrder($grouped, $dropdown_groups['dropdown_groups']);
3✔
99

100
        return $profiles;
3✔
101
    }
102

103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function sortGroupsByDisplayOrder($grouped, $groups)
107
    {
108
        return collect($groups)
1✔
109
            ->reject(function ($item, $key) {
1✔
110
                return $key === '';
1✔
111
            })
1✔
112
            ->reject(function ($item, $key) use ($grouped) {
1✔
113
                // Remove groups that no one is in
114
                return empty($grouped[$item]);
1✔
115
            })
1✔
116
            ->flatMap(function ($item, $key) use ($grouped) {
1✔
117
                return [
1✔
118
                    $item => $grouped[$item],
1✔
119
                ];
1✔
120
            })
1✔
121
            ->toArray();
1✔
122
    }
123

124
    /**
125
     * {@inheritdoc}
126
     */
127
    public function getProfilesByGroupOrder($site_id, $groups, $subsite_url = null): array
128
    {
129
        $profile_listing = $this->getProfiles($site_id, null, $subsite_url);
3✔
130

131
        $group_order = preg_split('/[\s,|]+/', $groups);
3✔
132

133
        $profiles = [];
3✔
134

135
        // Retain the order of the groups as they were piped in
136
        if (!empty($profile_listing)) {
3✔
137
            foreach ($group_order as $group) {
3✔
138
                foreach ($profile_listing['profiles'] as $profile) {
3✔
139
                    if (array_key_exists($group, $profile['groups'])) {
2✔
140
                        $profiles['profiles'][$profile['groups'][$group]][] = $profile;
2✔
141
                        $profiles['anchors'][$profile['groups'][$group]] = Str::slug($profile['groups'][$group]);
2✔
142
                    }
143
                }
144
            }
145
        }
146

147
        return $profiles;
3✔
148
    }
149

150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function getDropdownOptions($selected_group = null, $forced_profile_group_id = null, $profiles = [])
154
    {
155
        // Default Options
156
        $options['selected_group'] = $selected_group;
4✔
157
        $options['hide_filtering'] = false;
4✔
158

159
        // If a data page field was set force that filtering and don't show the dropdown
160
        if ($forced_profile_group_id !== null) {
4✔
161
            $options['selected_group'] = $forced_profile_group_id;
2✔
162
            $options['hide_filtering'] = true;
2✔
163
        }
164

165
        // Hide filtering if all profiles belong to the same group
166
        if (!$options['hide_filtering'] && !empty($profiles['profiles'])) {
4✔
167
            $unique_groups = $this->getUniqueGroupsFromProfiles($profiles['profiles']);
2✔
168
            if (count($unique_groups) <= 1) {
2✔
169
                $options['hide_filtering'] = true;
1✔
170
            }
171
        }
172

173
        return $options;
4✔
174
    }
175

176
    /**
177
     * {@inheritdoc}
178
     */
179
    public function getGroupIds($selected_group, $forced_profile_group_id, $dropdown_groups)
180
    {
181
        // Use the selected group or the forced one from custom page fields
182
        $group_ids = $forced_profile_group_id === null ? $selected_group : $forced_profile_group_id;
4✔
183

184
        // Use all the IDs from the dropdown since the initial selection is "All Profiles"
185
        if ($group_ids === null) {
4✔
186
            $group_ids = ltrim(implode('|', array_keys($dropdown_groups)), '|');
4✔
187
        }
188

189
        return $group_ids;
4✔
190
    }
191

192
    /**
193
     * {@inheritdoc}
194
     */
195
    public function getDropdownOfGroups(int $site_id): array
196
    {
197
        $params = [
3✔
198
            'method' => 'profile.groups.listing',
3✔
199
            'site_id' => $site_id,
3✔
200
        ];
3✔
201

202
        $profile_groups = $this->cache->remember($params['method'].md5(serialize($params)), config('cache.ttl'), function () use ($params) {
3✔
203
            $this->wsuApi->nextRequestProduction();
3✔
204

205
            return $this->wsuApi->sendRequest($params['method'], $params);
3✔
206
        });
3✔
207

208
        // Filter down the groups based on the parent group from the config
209
        $parent_group_id = (config('base.profile_parent_group_id')) ?? config('base.profile.parent_group_id');
3✔
210
        $profile_groups['results'] = collect($profile_groups['results'])
3✔
211
            ->filter(function ($item) use ($parent_group_id) {
3✔
212
                return (int) $item['parent_id'] === $parent_group_id;
3✔
213
            })
3✔
214
            ->toArray();
3✔
215

216
        // Only return the display name ordered by the display order
217
        $groupsArray = collect($profile_groups['results'])
3✔
218
            ->sortBy('display_order')
3✔
219
            ->map(function ($item) {
3✔
220
                return $item['display_name'];
3✔
221
            })->toArray();
3✔
222

223
        if (count($groupsArray) == 1) {
3✔
224
            $groups['single_group'] = key($groupsArray);
1✔
225
        }
226

227
        $groups['dropdown_groups'] = ['' => 'All Profiles'] + $groupsArray;
3✔
228

229
        return $groups;
3✔
230
    }
231

232
    /**
233
     * {@inheritdoc}
234
     */
235
    public function getProfile(int $site_id, string $accessid): array
236
    {
237
        $params = [
4✔
238
            'method' => 'profile.users.view',
4✔
239
            'site_id' => $site_id,
4✔
240
            'accessid' => $accessid,
4✔
241
            'include_courses' => 'true',
4✔
242
        ];
4✔
243

244
        $profiles = $this->cache->remember($params['method'].md5(serialize($params)), config('cache.ttl'), function () use ($params) {
4✔
245
            $this->wsuApi->nextRequestProduction();
4✔
246

247
            return $this->wsuApi->sendRequest($params['method'], $params);
4✔
248
        });
4✔
249

250
        if (!empty($profiles['error'])) {
4✔
251
            return ['profile' => []];
1✔
252
        }
253

254
        if (!empty($profiles['profiles'][$site_id]['data']['Youtube Videos'])) {
3✔
255
            $profiles['profiles'][$site_id]['data']['Youtube Videos'] = collect($profiles['profiles'][$site_id]['data']['Youtube Videos'])->map(function ($video) use ($profiles, $site_id) {
1✔
256
                return [
1✔
257
                    'youtube_id' => ParseId::fromUrl($video['link']),
1✔
258
                    'link' => $video['link'],
1✔
259
                    'filename_alt_text' => $profiles['profiles'][$site_id]['data']['First Name'] . ' ' .
1✔
260
                        $profiles['profiles'][$site_id]['data']['Last Name'] . ' video',
1✔
261
                ];
1✔
262
            })->toArray();
1✔
263
        }
264

265
        if (!empty($profiles['profiles'])) {
3✔
266
            $profiles['profiles']['articles'] = $this->getNewsArticles($accessid, 10);
2✔
267
        }
268

269
        return [
3✔
270
            'profile' =>  Arr::get($profiles['profiles'], $site_id, []),
3✔
271
            'courses' => Arr::get($profiles, 'courses', []),
3✔
272
            'articles' => Arr::get($profiles['profiles'], 'articles', []),
3✔
273
        ];
3✔
274
    }
275

276
    /**
277
     * {@inheritdoc}
278
     */
279
    public function getNewsArticles($accessid, $limit = 10)
280
    {
281
        $params = [
4✔
282
            'perPage' =>  $limit,
4✔
283
            'method' => 'articles/faculty/'.$accessid,
4✔
284
            'env' => config('app.env'),
4✔
285
        ];
4✔
286

287
        $articles = $this->cache->remember($params['method'].md5(serialize($params)), config('cache.ttl'), function () use ($params) {
4✔
288
            try {
289
                $articles = $this->newsApi->request($params['method'], $params);
4✔
290

291
                return $articles['data'] ?? [];
1✔
292
            } catch (\Exception $e) {
3✔
293
                return [];
3✔
294
            }
295
        });
4✔
296

297
        return $articles;
4✔
298
    }
299

300
    /**
301
     * {@inheritdoc}
302
     */
303
    public function getFields()
304
    {
305
        return [
6✔
306
            // Show under the profile image
307
            'contact_fields' => [
6✔
308
                'Curriculum Vitae',
6✔
309
                'Syllabi',
6✔
310
                'Phone',
6✔
311
                'Fax',
6✔
312
                'Email',
6✔
313
                'Office',
6✔
314
                'Website',
6✔
315
            ],
6✔
316
            // Fields that should be displayed as a URL
317
            'url_fields' => [
6✔
318
                'Website',
6✔
319
            ],
6✔
320
            // Show under the profile images contact fields
321
            'file_fields' => [
6✔
322
                'Curriculum Vitae',
6✔
323
                'Syllabi',
6✔
324
                'Youtube Videos',
6✔
325
            ],
6✔
326
            // Hide these in the main tube of content
327
            'hidden_fields' => [
6✔
328
                'Title',
6✔
329
                'AccessID',
6✔
330
                'Suffix',
6✔
331
                'Honorific',
6✔
332
                'First Name',
6✔
333
                'Middle name',
6✔
334
                'Last Name',
6✔
335
                'Picture',
6✔
336
                'Photo Download',
6✔
337
                'Youtube Videos',
6✔
338
            ],
6✔
339
            // Build the users name based on these fields
340
            'name_fields' => [
6✔
341
                'Honorific',
6✔
342
                'First Name',
6✔
343
                'Middle name',
6✔
344
                'Last Name',
6✔
345
                'Suffix',
6✔
346
            ],
6✔
347
        ];
6✔
348
    }
349

350
    /**
351
     * {@inheritdoc}
352
     */
353
    public function getPageTitleFromName($profile)
354
    {
355
        if (empty($profile)) {
6✔
356
            return '';
1✔
357
        }
358

359
        $name_fields = $this->getFields()['name_fields'];
6✔
360

361
        $name = collect($profile['profile']['data'])->filter(function ($value, $key) use ($name_fields) {
6✔
362
            return in_array($key, $name_fields) && $value != '';
6✔
363
        })
6✔
364
            ->map(function ($value, $key) {
6✔
365
                return $key == 'Suffix' ? ', '.$value : $value;
6✔
366
            })
6✔
367
            ->sortBy(function ($value, $key) use ($name_fields) {
6✔
368
                return array_search($key, $name_fields);
6✔
369
            })
6✔
370
            ->implode(' ');
6✔
371

372
        return str_replace(' ,', ',', $name);
6✔
373
    }
374

375
    /**
376
     * {@inheritdoc}
377
     */
378
    public function getBackToProfileListUrl($referer = null, $scheme = null, $host = null, $uri = null)
379
    {
380
        // Make sure the referer is coming from the site we are currently on and not the current page
381
        if ($referer === null
1✔
382
            || $referer == $scheme.'://'.$host.$uri
1✔
383
            || strpos($referer, $host) === false
1✔
384
        ) {
385
            return (config('base.profile_default_back_url')) ?? config('base.profile.default_back_url');
1✔
386
        }
387

388
        return $referer;
1✔
389
    }
390

391
    /**
392
     * {@inheritdoc}
393
     */
394
    public function getSiteID($data)
395
    {
396
        return !empty(config('base.profile.site_id')) ? config('base.profile.site_id') : $data['site']['id'];
4✔
397
    }
398

399
    /**
400
     * {@inheritdoc}
401
     */
402
    public function parseProfileConfig(array $data): void
403
    {
404
        $profile_config = [];
6✔
405

406
        if (!empty($data['data']['profile-config'])) {
6✔
407
            // Remove all spaces and line breaks
408
            $value = preg_replace('/\s*\R\s*/', '', $data['data']['profile-config']);
1✔
409

410
            // Last item cannot have comma at the end of it
411
            $value = preg_replace('(,})', '}', $value);
1✔
412

413
            // Parse the JSON
414
            if (Str::startsWith($value, '{')) {
1✔
415
                $profile_config = json_decode($value, true);
1✔
416

417
                foreach ($profile_config as $key => $value) {
1✔
418
                    Config::set('base.profile.'.$key, $value);
1✔
419
                }
420
            }
421
        }
422

423
        // Legacy support for profile_group_id
424
        if (!empty($data['data']['profile_group_id']) && empty($profile_config['group_id'])) {
6✔
425
            Config::set('base.profile.group_id', $data['data']['profile_group_id']);
3✔
426
        }
427

428
        // Legacy support for profile_site_id
429
        if (!empty($data['data']['profile_site_id']) && empty($profile_config['site_id'])) {
6✔
430
            Config::set('base.profile.site_id', $data['data']['profile_site_id']);
1✔
431
        }
432

433
        // Legacy support for table_of_contents
434
        if (!empty($data['data']['table_of_contents']) && empty($profile_config['table_of_contents'])) {
6✔
435
            Config::set('base.profile.table_of_contents', $data['data']['table_of_contents']);
3✔
436
        }
437

438
        // Legacy support for profiles_by_accessid
439
        if (!empty($data['data']['profiles_by_accessid'])) {
6✔
440
            Config::set('base.profile.profiles_by_accessid', $data['data']['profiles_by_accessid']);
1✔
441
        }
442
    }
443

444
    /**
445
     * {@inheritdoc}
446
     */
447
    public function orderProfilesById($profile_listing, $profiles_by_accessid): array
448
    {
UNCOV
449
        $accessids = collect(explode('|', $profiles_by_accessid))->map(function ($item) {
×
UNCOV
450
            return trim($item);
×
UNCOV
451
        })->all();
×
452

453
        // Find the profiles by a specific order
UNCOV
454
        $profiles_ordered = collect($accessids)->map(function ($accessid) use ($profile_listing) {
×
UNCOV
455
            return collect($profile_listing)->firstWhere('data.AccessID', $accessid);
×
UNCOV
456
        })->filter(null);
×
457

458
        // Remove the profiles that we found so there aren't duplicates
UNCOV
459
        $profiles_all = collect($profile_listing)->reject(function ($profile) use ($accessids) {
×
UNCOV
460
            return in_array($profile['data']['AccessID'], $accessids);
×
UNCOV
461
        });
×
462

UNCOV
463
        return $profiles_ordered->merge($profiles_all)->toArray();
×
464
    }
465

466
    /**
467
     * Get unique groups from a collection of profiles.
468
     *
469
     * @param array $profiles
470
     * @return array
471
     */
472
    protected function getUniqueGroupsFromProfiles(array $profiles): array
473
    {
474
        return collect($profiles)
3✔
475
            ->filter(function ($profile) {
3✔
476
                return !empty($profile['groups']) && is_array($profile['groups']);
3✔
477
            })
3✔
478
            ->flatMap(function ($profile) {
3✔
479
                return array_values($profile['groups']);
3✔
480
            })
3✔
481
            ->unique()
3✔
482
            ->values()
3✔
483
            ->toArray();
3✔
484
    }
485
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc