331 lines
9.9 KiB
PHP
331 lines
9.9 KiB
PHP
<?php
|
|
|
|
namespace App\Traits;
|
|
|
|
use App\Models\Account;
|
|
use App\Models\Tag;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\App;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Spatie\Activitylog\Models\Activity;
|
|
|
|
trait ProfileTrait
|
|
{
|
|
/***
|
|
* Retrieve the online status of the user and sets the properties isOnline and isAway accordingly.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getOnlineStatus()
|
|
{
|
|
|
|
// TODO: Replace commented rtippin messenger logic with wirechat logic
|
|
// Check online status of the user
|
|
// $messenger = app(Messenger::class);
|
|
// $status = $messenger->getProviderOnlineStatus($this->profile);
|
|
|
|
// if ($status === 1) {
|
|
// $this->isOnline = true;
|
|
// $this->isAway = false;
|
|
// } elseif ($status === 2) {
|
|
// $this->isOnline = false;
|
|
// $this->isAway = true;
|
|
// } else {
|
|
// $this->isOnline = false;
|
|
// $this->isAway = false;
|
|
// }
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieve the phone number of the profile.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getPhone($profile)
|
|
{
|
|
if ($profile->phone_public) {
|
|
return $profile->phone;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the profile's location and generate a link to OpenStreetMap.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getLocation($profile)
|
|
{
|
|
return$profile->getLocationFirst(true);
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieve the user's languages and their language competence.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getLanguages($profile)
|
|
{
|
|
// If languages is null, return an empty collection
|
|
if (empty($profile->languages)) {
|
|
return collect();
|
|
}
|
|
|
|
return $profile->languages->map(function ($language) {
|
|
$language->competence_name = DB::table('language_competences')->find($language->pivot->competence)->name;
|
|
return $language;
|
|
});
|
|
}
|
|
|
|
|
|
public function getLangPreference($profile)
|
|
{
|
|
// Get the user's language preference (if it exists)
|
|
$lang_preference = DB::table('languages')->where('lang_code',$profile->lang_preference)->first();
|
|
if ($lang_preference) {
|
|
return $lang_preference->name;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieves the skills of this user.
|
|
*
|
|
* @return \Illuminate\Support\Collection
|
|
*/
|
|
//TODO! This will set the skill Cache, and not get the skills from cache! FIX THIS!
|
|
public function getSkills($profile)
|
|
{
|
|
$skillsCache = Cache::remember('skills-user-' .$profile->id . '-lang-' . app()->getLocale(), now()->addDays(7), function () use ($profile) { // remember cache
|
|
$tagIds = $profile->tags->pluck('tag_id');
|
|
$translatedTags = collect((new Tag())->translateTagIdsWithContexts($tagIds, App::getLocale(), App::getFallbackLocale())); // Translate to app locale, if not available to fallback locale, if not available do not translate
|
|
|
|
$skills = $translatedTags->map(function ($item) {
|
|
return [
|
|
'tag_id' => $item['tag_id'],
|
|
'name' => $item['tag'],
|
|
'foreign' => (isset($item['locale']['locale']) && $item['locale']['locale'] == App::getLocale()) ? false : true,
|
|
'example' => (isset($item['locale']) && isset($item['locale']['example'])) ? $item['locale']['example'] : null,
|
|
'category' => $item['category'],
|
|
'category_path' => $item['category_path'],
|
|
'category_color' => $item['category_color'],
|
|
'title' => $item['category_path']
|
|
];
|
|
});
|
|
|
|
$skills = collect($skills);
|
|
|
|
return $skills;
|
|
});
|
|
|
|
$skills = $skillsCache;
|
|
|
|
if ($skills) {
|
|
return $skills;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
public function getAge($profile)
|
|
{
|
|
// Check if the table has the date_of_birth column
|
|
if (Schema::hasColumn($profile->getTable(), 'date_of_birth') && $profile->date_of_birth) {
|
|
return Carbon::parse($profile->date_of_birth)->age;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the last login time for the profile.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getLastLogin($profile)
|
|
{
|
|
$activityLog =
|
|
Activity::where('subject_id', $profile->id)
|
|
->where('subject_type', get_class($profile))
|
|
->whereNotNull('properties->old->last_login_at')
|
|
->get('properties')->last();
|
|
if (isset($activityLog)) {
|
|
$lastLoginAt = json_decode($activityLog, true)['properties']['old']['last_login_at'];
|
|
return Carbon::createFromTimeStamp(strtotime($lastLoginAt))->diffForHumans();
|
|
} elseif ($profile->last_login_at) {
|
|
$lastLoginAt = $profile->last_login_at;
|
|
return Carbon::createFromTimeStamp(strtotime($lastLoginAt))->diffForHumans();
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Retrieves the totals of the user's accounts.
|
|
* This method calls the `getAccountsTotals` method of the `Account` model to calculate the totals of the user's accounts.
|
|
*
|
|
*/
|
|
public function getAccountsTotals($profile)
|
|
{
|
|
$type = strtolower(class_basename($profile));
|
|
$totals = (new Account())->getAccountsTotals(get_class($profile), $profile->id, timebank_config('account_info.'.$type.'.countTransfersSince'));
|
|
|
|
if ($totals) {
|
|
return $totals;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the last exchange date for the profile.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getLastExchangeAt($accountsTotals = null, $profile = null)
|
|
{
|
|
if (!$accountsTotals && $profile) {
|
|
$accountsTotals = (new Account())->getAccountsTotals($profile->id, timebank_config('account_info.account_totals.countTransfersSince'));
|
|
}
|
|
|
|
// Normalize lastTransferDate to always be an array
|
|
if (!isset($accountsTotals['lastTransferDate'])) {
|
|
$accountsTotals['lastTransferDate'] = [];
|
|
} elseif (!is_array($accountsTotals['lastTransferDate'])) {
|
|
$accountsTotals['lastTransferDate'] = [$accountsTotals['lastTransferDate']];
|
|
}
|
|
|
|
if (!empty($accountsTotals['lastTransferDate'][0])) {
|
|
$date = $accountsTotals['lastTransferDate'][0];
|
|
if ($date instanceof \Illuminate\Support\Carbon) {
|
|
return $date->diffForHumans();
|
|
} else {
|
|
return Carbon::parse($date)->diffForHumans();
|
|
}
|
|
} else {
|
|
return null; // no transfers
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Calculates and sets the registered since date for the user.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getRegisteredSince($profile)
|
|
{
|
|
$createdAt = Carbon::parse($profile->created_at);
|
|
$registeredSince = $createdAt->diffForHumans();
|
|
|
|
if ($registeredSince) {
|
|
return $registeredSince;
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Retrieves the social media accounts associated with this user.
|
|
*
|
|
* @return void
|
|
*/
|
|
public function getSocials($profile)
|
|
{
|
|
$socials = $profile->socials()
|
|
->withPivot(['user_on_social', 'server_of_social', 'created_at', 'updated_at'])
|
|
->orderByPivot('updated_at', 'desc')
|
|
->limit(10)
|
|
->get();
|
|
|
|
return $socials->isNotEmpty() ? $socials : collect();
|
|
}
|
|
|
|
|
|
/**
|
|
* Check if a model has an incomplete profile based on configured fields and relations.
|
|
*
|
|
* @param \Illuminate\Database\Eloquent\Model $model
|
|
* @return bool
|
|
*/
|
|
public function hasIncompleteProfile($model)
|
|
{
|
|
$config = timebank_config('profile_incomplete');
|
|
|
|
if (!$config) {
|
|
return false;
|
|
}
|
|
|
|
$checkFields = $config['check_fields'] ?? [];
|
|
$checkRelations = $config['check_relations'] ?? [];
|
|
$minTotalLength = $config['check_fields_min_total_length'] ?? 0;
|
|
|
|
// Check if at least one field has data and calculate total length
|
|
$hasFieldData = false;
|
|
$totalFieldLength = 0;
|
|
foreach ($checkFields as $field) {
|
|
if (!empty($model->{$field})) {
|
|
$hasFieldData = true;
|
|
$totalFieldLength += strlen(trim($model->{$field}));
|
|
}
|
|
}
|
|
|
|
// Check if minimum total length requirement is met
|
|
$meetsMinLength = $totalFieldLength >= $minTotalLength;
|
|
|
|
// Check if at least one relation has data
|
|
$hasRelationData = false;
|
|
foreach ($checkRelations as $relation) {
|
|
if (!$model->relationLoaded($relation)) {
|
|
$model->load($relation);
|
|
}
|
|
|
|
if (!$model->{$relation}->isEmpty()) {
|
|
$hasRelationData = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Profile is complete (return false) when ALL three conditions are met:
|
|
// 1. At least one field has data
|
|
// 2. Total length meets minimum requirement
|
|
// 3. At least one relation has data
|
|
$isComplete = $hasFieldData && $meetsMinLength && $hasRelationData;
|
|
|
|
// Return true if incomplete, false if complete
|
|
return !$isComplete;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the profile has never received a transaction on any of its active accounts.
|
|
*/
|
|
public function hasNeverReceivedTransaction($model): bool
|
|
{
|
|
if (!method_exists($model, 'accounts')) {
|
|
return false;
|
|
}
|
|
|
|
$accountIds = $model->accounts()->pluck('id');
|
|
|
|
if ($accountIds->isEmpty()) {
|
|
return true;
|
|
}
|
|
|
|
return !\App\Models\Transaction::whereIn('to_account_id', $accountIds)->exists();
|
|
}
|
|
|
|
}
|