@php /** * Helper function to get column value, handling JSON path columns correctly. * For JSON path columns (e.g., 'ecommerce_settings.shopify.enabled'), this accesses * the nested value from the JSON column instead of trying to access a non-existent attribute. */ $getColumnValue = function($column, $form) { $columnName = $column['name']; $default = $column['default'] ?? null; $model = $form['data']; // For insert mode (empty model), return the default value if (!$model->exists && empty($model->getAttributes())) { return $default; } // Check if this is a JSON path column if (str_contains($columnName, '.') && isset($column['json_path_info']['is_json_path']) && $column['json_path_info']['is_json_path']) { $jsonColumn = $column['json_path_info']['json_column']; $jsonPath = $column['json_path_info']['json_path']; // Safely get the JSON column value try { $jsonData = $model->getAttribute($jsonColumn); } catch (\Throwable $e) { return $default; } if (is_array($jsonData)) { $value = $jsonData; foreach (explode('.', $jsonPath) as $segment) { $value = $value[$segment] ?? null; if ($value === null) break; } return $value ?? $default; } return $default; } // Standard attribute access - use getAttribute to avoid MissingAttributeException // Note: Only use default for INSERT (new records), not for EDIT where null is intentional try { $value = $model->getAttribute($columnName); // For existing records, return null as-is (user may have intentionally cleared the field) // Only apply default for new records (insert mode) if ($value === null && $model->exists) { return null; // Respect the null value - don't override with default } $result = $value ?? $default; // Minor units conversion for currency fields stored as cents/minor units // Example: minorUnits=100 means 1000 stored → 10.00 displayed // Supports: 100 (most currencies), 1 (JPY/KRW), 1000 (BHD/KWD/OMR) if (isset($column['minorUnits']) && $column['minorUnits'] > 1 && is_numeric($result)) { $divided = $result / $column['minorUnits']; // Calculate decimal places from minorUnits: 100 → 2, 1000 → 3 $decimals = (int) log10($column['minorUnits']); $result = number_format($divided, $decimals, '.', ''); } // Decimal formatting for decimal(10,2) fields that store actual decimals (not cents) // Uses explicit 'decimalPlaces' setting, or calculates from 'step' value // Example: step=0.01 means 2 decimal places, step=0.001 means 3 decimal places elseif (is_numeric($result) && $result !== null && $result !== '') { $decimals = null; // Explicit decimalPlaces setting takes priority if (isset($column['decimalPlaces'])) { $decimals = (int) $column['decimalPlaces']; } // Otherwise calculate from step value (0.01 → 2, 0.001 → 3) elseif (isset($column['step']) && is_numeric($column['step']) && $column['step'] < 1) { $decimals = max(0, (int) -log10((float) $column['step'])); } if ($decimals !== null && $decimals > 0) { $result = number_format((float) $result, $decimals, '.', ''); } } // Date formatting: Convert Carbon instances to Y-m-d for HTML date inputs // Without this, Carbon's __toString() outputs full datetime which can't parse if ($result instanceof \Carbon\Carbon && ($column['format'] ?? null) === 'date') { $result = $result->format('Y-m-d'); } return $result; } catch (\Throwable $e) { return $default; } }; @endphp @if (in_array($column['type'], ['string', 'textarea'])) @if ($column['translatable']) @php // Get the default locale - only this locale is required $defaultLocale = config('app.locale'); $hasMultipleLanguages = count($languages['all']) > 1; $isRequired = in_array('required', $column['validate']); // Find the default language in the list (for proper label rendering) $defaultLanguage = collect($languages['all'])->firstWhere('locale', $defaultLocale) ?? $languages['current']; // Other languages (excluding the default) $otherLanguages = collect($languages['all'])->filter(fn($lang) => $lang['locale'] !== $defaultLocale)->values(); @endphp @if ($hasMultipleLanguages)
@endif @else @if ($column['type'] == 'string')