304 lines
16 KiB
PHP
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;
|
|
}
|
|
}
|