first init
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use App\Models\Document;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
|
||||
trait HasDocuments
|
||||
{
|
||||
/**
|
||||
* Get all documents for this model.
|
||||
*/
|
||||
public function documents()
|
||||
{
|
||||
return $this->morphMany(Document::class, 'documentable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documents of a specific type.
|
||||
*/
|
||||
public function documentsOfType($type)
|
||||
{
|
||||
return $this->documents()->where('document_type', $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload a document for this model.
|
||||
*/
|
||||
public function uploadDocument(UploadedFile $file, $documentType = 'general', $description = null)
|
||||
{
|
||||
// Generate unique filename
|
||||
$fileName = time().'_'.$file->getClientOriginalName();
|
||||
|
||||
// Store file in a folder named after the model
|
||||
$folderName = strtolower(class_basename($this));
|
||||
$filePath = $file->storeAs("documents/{$folderName}", $fileName);
|
||||
|
||||
// Create document record
|
||||
return $this->documents()->create([
|
||||
'document_name' => $file->getClientOriginalName(),
|
||||
'document_path' => $filePath,
|
||||
'file_size' => $file->getSize(),
|
||||
'mime_type' => $file->getClientMimeType(),
|
||||
'document_type' => $documentType,
|
||||
'description' => $description,
|
||||
'uploaded_by' => auth()->id(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a document by ID.
|
||||
*/
|
||||
public function deleteDocument($documentId)
|
||||
{
|
||||
$document = $this->documents()->findOrFail($documentId);
|
||||
|
||||
return $document->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documents count.
|
||||
*/
|
||||
public function getDocumentsCountAttribute()
|
||||
{
|
||||
return $this->documents()->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get documents count by type.
|
||||
*/
|
||||
public function getDocumentsCountByType($type)
|
||||
{
|
||||
return $this->documentsOfType($type)->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if model has documents.
|
||||
*/
|
||||
public function hasDocuments()
|
||||
{
|
||||
return $this->documents()->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if model has documents of specific type.
|
||||
*/
|
||||
public function hasDocumentsOfType($type)
|
||||
{
|
||||
return $this->documentsOfType($type)->exists();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use App\Services\VisibilityService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
trait HasVisibility
|
||||
{
|
||||
/**
|
||||
* Get the visibility service instance
|
||||
*/
|
||||
protected function getVisibilityService(): VisibilityService
|
||||
{
|
||||
return app(VisibilityService::class);
|
||||
}
|
||||
|
||||
public function scopeVisibleTo(Builder $query, $user)
|
||||
{
|
||||
$includeUnitsWithoutFormation = property_exists($this, 'includeUnitsWithoutFormation')
|
||||
? (bool) $this->includeUnitsWithoutFormation
|
||||
: false;
|
||||
|
||||
// Check if model has a direct unit column
|
||||
$unitColumn = property_exists($this, 'unitColumn') ? $this->unitColumn : 'unit_id';
|
||||
|
||||
// Check if model has an indirect unit relationship
|
||||
$unitRelationship = property_exists($this, 'unitRelationship') ? $this->unitRelationship : null;
|
||||
|
||||
if ($unitRelationship) {
|
||||
return $this->getVisibilityService()->applyVisibilityToIndirectQuery(
|
||||
$query,
|
||||
$user,
|
||||
$unitRelationship,
|
||||
$includeUnitsWithoutFormation
|
||||
);
|
||||
}
|
||||
|
||||
return $this->getVisibilityService()->applyVisibilityToQuery(
|
||||
$query,
|
||||
$user,
|
||||
$unitColumn,
|
||||
$includeUnitsWithoutFormation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all units under the same government as the user's unit
|
||||
* Handles both direct government relationships and formation-government relationships
|
||||
* Priority: Direct government_id takes precedence over formation government
|
||||
*
|
||||
* @deprecated Use VisibilityService::getUnitsUnderGovernment() instead
|
||||
*/
|
||||
protected function getUnitsUnderGovernment($userUnit)
|
||||
{
|
||||
return $this->getVisibilityService()->getUnitsUnderGovernment($userUnit);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
trait HttpClientTrait
|
||||
{
|
||||
/**
|
||||
* Get a configured HTTP client with global settings.
|
||||
*
|
||||
* @param array $additionalHeaders Additional headers to add
|
||||
* @param bool $withoutVerifying Whether to skip SSL verification
|
||||
* @return \Illuminate\Http\Client\PendingRequest
|
||||
*/
|
||||
protected function getHttpClient(array $additionalHeaders = [], bool $withoutVerifying = false)
|
||||
{
|
||||
$client = Http::withHeaders($additionalHeaders);
|
||||
|
||||
if ($withoutVerifying) {
|
||||
$client = $client->withoutVerifying();
|
||||
}
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a configured HTTP client with authentication.
|
||||
*
|
||||
* @param string $token Bearer token for authentication
|
||||
* @param array $additionalHeaders Additional headers to add
|
||||
* @param bool $withoutVerifying Whether to skip SSL verification
|
||||
* @return \Illuminate\Http\Client\PendingRequest
|
||||
*/
|
||||
protected function getAuthenticatedHttpClient(string $token, array $additionalHeaders = [], bool $withoutVerifying = false)
|
||||
{
|
||||
$headers = array_merge([
|
||||
'Authorization' => 'Bearer '.$token,
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
], $additionalHeaders);
|
||||
|
||||
return $this->getHttpClient($headers, $withoutVerifying);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log HTTP request details for debugging.
|
||||
*
|
||||
* @param string $method HTTP method
|
||||
* @param string $url Request URL
|
||||
* @param array $data Request data
|
||||
* @param array $headers Request headers
|
||||
*/
|
||||
protected function logHttpRequest(string $method, string $url, array $data = [], array $headers = [])
|
||||
{
|
||||
Log::debug('HTTP Request', [
|
||||
'method' => $method,
|
||||
'url' => $url,
|
||||
'data' => $data,
|
||||
'headers' => array_keys($headers), // Don't log sensitive header values
|
||||
'environment' => config('app.env'),
|
||||
'proxy_enabled' => $this->isProxyEnabled(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log HTTP response details for debugging.
|
||||
*
|
||||
* @param \Illuminate\Http\Client\Response $response
|
||||
* @param string $context Additional context
|
||||
*/
|
||||
protected function logHttpResponse($response, string $context = '')
|
||||
{
|
||||
Log::debug('HTTP Response'.($context ? " - {$context}" : ''), [
|
||||
'status' => $response->status(),
|
||||
'successful' => $response->successful(),
|
||||
'body_length' => strlen($response->body()),
|
||||
'headers' => $response->headers(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if proxy is enabled for current environment.
|
||||
*/
|
||||
protected function isProxyEnabled(): bool
|
||||
{
|
||||
$config = config('http');
|
||||
$proxyConfig = $config['proxy'] ?? [];
|
||||
|
||||
return isset($proxyConfig['enabled']) && $proxyConfig['enabled'] &&
|
||||
in_array(config('app.env'), $proxyConfig['environments'] ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current proxy configuration.
|
||||
*/
|
||||
protected function getProxyConfig(): array
|
||||
{
|
||||
$config = config('http');
|
||||
|
||||
return $config['proxy'] ?? [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Modules\Auth\Entities\User;
|
||||
|
||||
trait NotifiesAdmins
|
||||
{
|
||||
/**
|
||||
* Get admin users (PENTADBIR and DEVELOPER) who should receive all notifications
|
||||
*/
|
||||
protected function getAdminUsers(): Collection
|
||||
{
|
||||
return User::whereHas('roles', function ($query) {
|
||||
$query->whereIn('name', ['PENTADBIR', 'DEVELOPER']);
|
||||
})->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge admin users with specific role users and return unique collection
|
||||
*/
|
||||
protected function mergeWithAdmins(Collection $specificUsers): Collection
|
||||
{
|
||||
$adminUsers = $this->getAdminUsers();
|
||||
return $specificUsers->merge($adminUsers)->unique('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users with specific roles and merge with admins
|
||||
*/
|
||||
protected function getUsersWithRolesAndAdmins(array $roles): Collection
|
||||
{
|
||||
$specificUsers = User::whereHas('roles', function ($query) use ($roles) {
|
||||
$query->whereIn('name', $roles);
|
||||
})->get();
|
||||
|
||||
return $this->mergeWithAdmins($specificUsers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user IDs from a collection and merge with admin user IDs
|
||||
*/
|
||||
protected function mergeUserIdsWithAdmins($userIds): Collection
|
||||
{
|
||||
$adminIds = $this->getAdminUsers()->pluck('id');
|
||||
|
||||
if ($userIds instanceof Collection) {
|
||||
return $userIds->merge($adminIds)->unique()->filter();
|
||||
}
|
||||
|
||||
return collect($userIds)->merge($adminIds)->unique()->filter();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user