app/Models/Post.php)Los posts son polimórficos por el campo tipo:
| Tipo | Campos principales | Descripción |
|---|---|---|
imagen |
imagen, imagen_mini, titulo, descripcion |
Post con imagen (WebP optimizado) |
musica |
itunes_*, apple_music_url, spotify_web_url, titulo, descripcion |
Post con metadata de canción de iTunes |
texto |
texto, titulo, descripcion |
Post de solo texto |
archivo |
archivo, archivo_nombre_original, titulo, descripcion |
Post con archivo adjunto (PDF, DOC, ZIP) |
protected $fillable = [
'titulo', 'descripcion', 'imagen', 'imagen_mini', 'archivo',
'archivo_nombre_original', 'user_id', 'tipo', 'visibility',
// Campos iTunes
'itunes_track_id', 'itunes_track_name', 'itunes_artist_name',
'itunes_collection_name', 'itunes_artwork_url', 'itunes_preview_url',
'itunes_track_view_url', 'itunes_track_time_millis', 'itunes_country',
'itunes_primary_genre_name', 'music_source',
// Cross-platform
'apple_music_url', 'spotify_web_url', 'artist_search_term', 'track_search_term',
// Texto
'texto'
];
Al crear un post de imagen, el PostController::store() procesa la imagen con Intervention Image:
Imagen original
├── Full: scaleDown(width: 1200) → WebP 85% → $nombreBase_full.webp
└── Mini: scaleDown(width: 600) → WebP 70% → $nombreBase_feed.webp
imagen almacena el nombre del archivo fullimagen_mini almacena el nombre del archivo mini (para feed)// URL de imagen para el feed (prefiere mini, cae a full)
$post->imagen_feed_url
// Tiempo transcurrido compacto: "ahora", "5 mins", "2 horas", "3 días", "1 semana", "2 meses"
$post->compact_time
// Tiempo transcurrido completo: "Publicado hace 5 minutos"
$post->full_time
$post->isMusicPost() // tipo === 'musica'
$post->isImagePost() // tipo === 'imagen'
$post->isFilePost() // tipo === 'archivo'
$post->isTextPost() // tipo === 'texto'
$post->visibility // 'public' | 'followers'
$post->isPublic()
$post->isForFollowersOnly()
$post->canBeViewedBy($user) // Lógica completa: público, dueño, o follower
$post->getTrackName() // itunes_track_name
$post->getArtistName() // itunes_artist_name
$post->getAlbumName() // itunes_collection_name
$post->getArtworkUrl() // itunes_artwork_url
$post->getPreviewUrl() // itunes_preview_url (30s audio)
$post->getExternalUrl() // itunes_track_view_url
$post->getFormattedDuration() // "3:45" desde itunes_track_time_millis
$post->hasPreview() // true si tiene URL de preview
$post->getGenre() // itunes_primary_genre_name
$post->getAppleMusicUrl() // apple_music_url || itunes_track_view_url
$post->getSpotifyUrl() // spotify_web_url
$post->hasAppleMusicLink()
$post->hasSpotifyLink()
$post->getSearchTerms() // ['artist' => ..., 'track' => ...]