Files
admin/app/Http/Resources/ItemCollection.php
Husanjonazamov e0f1989655 classify admin
2026-02-24 12:52:01 +05:00

304 lines
16 KiB
PHP

<?php
namespace App\Http\Resources;
use App\Models\City;
use App\Models\Language;
use App\Services\CurrencyFormatterService;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Pagination\AbstractPaginator;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use JsonSerializable;
use Throwable;
class ItemCollection extends ResourceCollection
{
/**
* Transform the resource into an array.
*
* @return array|Arrayable|JsonSerializable
*
* @throws Throwable
*/
public function toArray(Request $request)
{
try {
$formatter = app(CurrencyFormatterService::class);
$response = [];
// Get current language once
$contentLangCode = $request->header('Content-Language') ?? app()->getLocale();
$currentLanguage = Language::where('code', $contentLangCode)->first();
$currentLangId = $currentLanguage->id ?? 1;
$defaultLangId = 1;
foreach ($this->collection as $key => $collection) {
// Base response
$response[$key] = $collection->toArray();
// return response()->json($collection);
// Currency & price formatting
// $response[$key]['currency_symbol'] = $collection->currency_symbol;
// $response[$key]['currency_position'] = $collection->currency_position;
// $response[$key]['formatted_price'] = $collection->formatted_price;
// $response[$key]['formatted_min_salary'] = $collection->formatted_min_salary;
// $response[$key]['formatted_max_salary'] = $collection->formatted_max_salary;
// $response[$key]['formatted_salary_range'] = $collection->formatted_salary_range ?? null;
// $response[$key]['price'] = $collection->price;
// return response()->json($collection->currencyRelation->currency_symbol);
$response[$key]['formatted_price'] = $formatter->formatPrice(
$collection?->price,
$collection?->currency
);
$response[$key]['formatted_salary_range'] = $formatter->formatSalaryRange(
$collection?->min_salary,
$collection?->max_salary,
$collection?->currency
);
// Feature status
$response[$key]['is_feature'] = $collection->status == 'approved' && $collection->relationLoaded('featured_items')
? $collection->featured_items->isNotEmpty()
: false;
// Favourites
if ($collection->relationLoaded('favourites')) {
$response[$key]['total_likes'] = $collection->favourites->count();
$response[$key]['is_liked'] = Auth::check()
? $collection->favourites->where('item_id', $collection->id)->where('user_id', Auth::id())->count() > 0
: false;
}
// User info
if ($collection->relationLoaded('user') && ! is_null($collection->user)) {
$response[$key]['user'] = $collection->user;
$response[$key]['user']['reviews_count'] = $collection->user->sellerReview()->count();
$response[$key]['user']['average_rating'] = $collection->user->sellerReview->avg('ratings');
if ($collection->user->show_personal_details == 0) {
$response[$key]['user']['mobile'] = '';
$response[$key]['user']['country_code'] = '';
$response[$key]['user']['email'] = '';
}
}
// Load city once
$city = City::with(['translations', 'state', 'country'])
->where('name', $collection->city)
->whereHas('state', fn($q) => $q->where('name', $collection->state))
->first();
// Translated item
$translatedItem = [
'name' => $collection->name,
'description' => $collection->description,
'address' => $collection->address,
'rejected_reason' => $collection->rejected_reason ?? null,
'admin_edit_reason' => $collection->admin_edit_reason ?? null,
'city' => $city->translated_name ?? $collection->city,
'state' => $city->state->translated_name ?? $collection->state,
'country' => $city->country->translated_name ?? $collection->country,
];
if ($currentLanguage && $collection->relationLoaded('translations')) {
$translation = $collection->translations->firstWhere('language_id', $currentLangId);
if ($translation) {
$translatedItem = [
'name' => $translation->name,
'description' => $translation->description,
'address' => $translation->address,
'rejected_reason' => $translation->rejected_reason,
'admin_edit_reason' => $translation->admin_edit_reason,
'city' => $city->translated_name ?? $collection->city,
'state' => $city->state->translated_name ?? $collection->state,
'country' => $city->country->translated_name ?? $collection->country,
];
}
}
$response[$key]['translated_item'] = $translatedItem;
$response[$key]['translated_area'] = $collection->area->translated_name ?? '';
$response[$key]['translated_city'] = $city?->translated_name ?? $collection->city;
$response[$key]['translated_state'] = $city->state->translated_name ?? $collection->state;
$response[$key]['translated_country'] = $city->country->translated_name ?? $collection->country;
$response[$key]['translated_address'] =
(! empty($response[$key]['translated_area']) ? $response[$key]['translated_area'] . ', ' : '') .
$response[$key]['translated_city'] . ', ' .
$response[$key]['translated_state'] . ', ' .
$response[$key]['translated_country'];
// Custom fields
if ($collection->relationLoaded('item_custom_field_values')) {
$response[$key]['custom_fields'] = [];
$response[$key]['translated_custom_fields'] = [];
$response[$key]['all_translated_custom_fields'] = [];
$grouped = $collection->item_custom_field_values->groupBy('custom_field_id');
foreach ($grouped as $customFieldId => $fieldValues) {
$default = $fieldValues->firstWhere('language_id', $defaultLangId);
$translated = $currentLanguage ? $fieldValues->firstWhere('language_id', $currentLangId) : null;
// Default fields
if ($default && $default->relationLoaded('custom_field') && ! empty($default->custom_field)) {
$field = $default->custom_field;
$tempRow = $field->toArray();
$tempRow['value'] = $field->type === 'fileinput'
? (! empty($default->value) ? [url(Storage::url($default->value))] : [])
: (is_array($default->value) ? $default->value : json_decode($default->value, true));
$tempRow['custom_field_value'] = $default->toArray();
unset($tempRow['custom_field_value']['custom_field']);
$tempRow['translated_selected_values'] = $this->resolveTranslatedSelectedValues($field, $default);
$response[$key]['custom_fields'][] = $tempRow;
}
// Translated fields
$activeField = $translated ?? $default;
if ($activeField && $activeField->relationLoaded('custom_field') && ! empty($activeField->custom_field)) {
$field = $activeField->custom_field;
$tempRow = $field->toArray();
$tempRow['value'] = $field->type === 'fileinput'
? (! empty($activeField->value) ? url(Storage::url($activeField->value)) : '')
: (is_array($activeField->value) ? $activeField->value : json_decode($activeField->value, true));
$tempRow['custom_field_value'] = $activeField->toArray();
unset($tempRow['custom_field_value']['custom_field']);
$tempRow['language_id'] = $activeField->language_id;
$tempRow['translated_selected_values'] = $this->resolveTranslatedSelectedValues($field, $activeField);
$response[$key]['translated_custom_fields'][] = $tempRow;
}
// All translated custom fields
foreach ($fieldValues as $fieldValue) {
if ($fieldValue->relationLoaded('custom_field') && ! empty($fieldValue->custom_field)) {
$field = $fieldValue->custom_field;
$tempRow = $field->toArray();
// $tempRow['value'] = $field->type === "fileinput"
// ? (!empty($fieldValue->value) ? url(Storage::url($fieldValue->value)) : '')
// : (is_array($fieldValue->value) ? $fieldValue->value : json_decode($fieldValue->value, true));
if ($field->type === 'fileinput') {
if (! empty($fieldValue->value)) {
// ✅ Only decode if it looks like JSON
$rawValue = is_string($fieldValue->value) && (str_starts_with($fieldValue->value, '[') || str_starts_with($fieldValue->value, '{'))
? json_decode($fieldValue->value, true)
: $fieldValue->value;
// ✅ Handle both single and multiple files
if (is_array($rawValue)) {
$value = array_map(fn($file) => url(Storage::url($file)), $fieldValue->value);
} else {
$value = url(Storage::url($fieldValue->value));
}
} else {
$value = '';
}
} else {
$value = is_array($fieldValue->value)
? $fieldValue->value
: json_decode($fieldValue->value, true);
}
$tempRow['value'] = $value;
$tempRow['custom_field_value'] = $tempRow;
unset($tempRow['custom_field_value']['custom_field']);
$tempRow['language_id'] = $fieldValue->language_id;
$tempRow['translated_selected_values'] = $this->resolveTranslatedSelectedValues($field, $fieldValue);
$response[$key]['all_translated_custom_fields'][] = $tempRow;
}
}
}
unset($response[$key]['item_custom_field_values']);
}
// Item Offers, Reports, Purchases, Job Applications
$response[$key]['is_already_offered'] = $collection->relationLoaded('item_offers') && Auth::check()
? $collection->item_offers->where('item_id', $collection->id)->where('buyer_id', Auth::id())->count() > 0
: false;
$response[$key]['is_already_reported'] = $collection->relationLoaded('user_reports') && Auth::check()
? $collection->user_reports->where('user_id', Auth::id())->count() > 0
: false;
$response[$key]['is_purchased'] = Auth::check() && $collection->sold_to == Auth::id() ? 1 : 0;
$response[$key]['is_already_job_applied'] = $collection->relationLoaded('job_applications') && Auth::check()
? $collection->job_applications->where('item_id', $collection->id)->where('user_id', Auth::id())->count() > 0
: false;
}
// Featured and normal rows
$featuredRows = [];
$normalRows = [];
foreach ($response as $value) {
$value['is_feature'] ? $featuredRows[] = $value : $normalRows[] = $value;
}
$response = array_merge($featuredRows, $normalRows);
$totalCount = count($response);
if ($this->resource instanceof AbstractPaginator) {
return [
...$this->resource->toArray(),
'data' => $response,
'total_item_count' => $totalCount,
];
}
return $response;
} catch (Throwable $th) {
throw $th;
}
}
public function resolveTranslatedSelectedValues($field, $fieldValue)
{
$type = $field->type ?? null;
$values = $fieldValue->value ?? null;
$allPossibleValues = $field->values ?? [];
$selected = [];
$contentLangCode = request()->header('Content-Language') ?? app()->getLocale();
$currentLanguage = Language::where('code', $contentLangCode)->first();
$currentLangId = $currentLanguage->id ?? 1;
$translatedValues = [];
if (! empty($field->translations)) {
$translation = collect($field->translations)->firstWhere('language_id', $currentLangId);
$translatedValues = $translation['value'] ?? [];
}
if (in_array($type, ['checkbox', 'radio', 'dropdown'])) {
$actualValues = is_array($values) ? $values : json_decode($values, true);
if (! is_array($actualValues)) {
$actualValues = [$actualValues];
}
foreach ($actualValues as $val) {
$index = array_search($val, $allPossibleValues);
$translatedVal = (is_array($translatedValues) && $index !== false && isset($translatedValues[$index]))
? $translatedValues[$index]
: $val;
$selected[] = $translatedVal;
}
} elseif (in_array($type, ['textbox', 'number'])) {
$actualValue = is_array($values) ? ($values[0] ?? '') : $values;
$selected[] = $actualValue;
}
return $selected;
}
}