@php
$contenidoModulo = isset($contenidoModulo) ? (string) $contenidoModulo : '';
$notificacionesUsuario = isset($notificaciones_usuario) ? $notificaciones_usuario : collect();
$patronAnclaNotificaciones = '/
]*\bdata-module-notifications-anchor(?:=["\'][^"\']*["\'])?[^>]*>\s*<\/div>/i';
$buscarCierreDiv = function ($htmlInterno, $inicioDiv) {
$longitud = strlen($htmlInterno);
$posicion = $inicioDiv;
$profundidad = 0;
while ($posicion < $longitud && preg_match('/<\/?div\b[^>]*>/i', $htmlInterno, $coincidencia, PREG_OFFSET_CAPTURE, $posicion)) {
$etiqueta = $coincidencia[0][0];
$offset = $coincidencia[0][1];
if (stripos($etiqueta, '
]*class=["\'][^"\']*\bmodule-notification-stack\b[^"\']*["\'][^>]*>/i';
while (preg_match($patronStack, $html, $coincidencia, PREG_OFFSET_CAPTURE, $offset)) {
$inicioStack = $coincidencia[0][1];
$aperturaStack = $coincidencia[0][0];
$finStack = $buscarCierreDiv($html, $inicioStack);
if ($finStack === false) {
break;
}
$inicioContenidoStack = $inicioStack + strlen($aperturaStack);
$longitudContenidoStack = $finStack - $inicioContenidoStack - strlen('');
if ($longitudContenidoStack > 0) {
$contenidoStack = trim(substr($html, $inicioContenidoStack, $longitudContenidoStack));
if ($contenidoStack !== '') {
$stacks[] = $contenidoStack;
}
}
// Copia por segmentos sin reconstruir todo el HTML en cada coincidencia.
$htmlSinStacks .= substr($html, $cursorCopia, $inicioStack - $cursorCopia);
$cursorCopia = $finStack;
$offset = $finStack;
}
$htmlSinStacks .= substr($html, $cursorCopia);
return [
'html' => $htmlSinStacks,
'stacks' => $stacks,
];
};
$extraerTarjetasNotificaciones = function ($html) use ($buscarCierreDiv) {
$tarjetas = [];
$offset = 0;
$cursorCopia = 0;
$htmlSinTarjetas = '';
$patronTarjeta = '/]*class=["\'][^"\']*\bmodule-notification-card\b[^"\']*["\'][^>]*>/i';
while (preg_match($patronTarjeta, $html, $coincidencia, PREG_OFFSET_CAPTURE, $offset)) {
$inicioTarjeta = $coincidencia[0][1];
$finTarjeta = $buscarCierreDiv($html, $inicioTarjeta);
if ($finTarjeta === false) {
break;
}
$tarjetas[] = substr($html, $inicioTarjeta, $finTarjeta - $inicioTarjeta);
$htmlSinTarjetas .= substr(
$html,
$cursorCopia,
$inicioTarjeta - $cursorCopia
);
$cursorCopia = $finTarjeta;
$offset = $finTarjeta;
}
$htmlSinTarjetas .= substr($html, $cursorCopia);
return [
'html' => $htmlSinTarjetas,
'tarjetas' => $tarjetas,
];
};
$stacksNotificaciones = [];
$contenidoExtraido = $extraerStacksNotificaciones($contenidoModulo);
$contenidoModulo = $contenidoExtraido['html'];
$notificacionesGlobalesParaModulo = collect($notificacionesUsuario);
if (request()->routeIs('informes.index')) {
// Validación conserva la tarjeta nativa aprobada; el espejo global no se pinta dos veces.
$notificacionesGlobalesParaModulo = $notificacionesGlobalesParaModulo
->reject(function ($notificacionUsuario) {
$datosNotificacion = $notificacionUsuario
? $notificacionUsuario->datos_notificacion
: null;
return $datosNotificacion
&& $datosNotificacion->tabla_origen === 'modificaciones_validacion';
})
->values();
}
$notificacionesGlobalesModulo = trim(view('Notificaciones.partials.global_module_cards', [
'notificaciones_usuario' => $notificacionesGlobalesParaModulo,
])->render());
$globalesExtraidas = $extraerStacksNotificaciones($notificacionesGlobalesModulo);
$stacksNotificaciones = array_merge($stacksNotificaciones, $globalesExtraidas['stacks']);
if (trim($globalesExtraidas['html']) !== '') {
$stacksNotificaciones[] = trim($globalesExtraidas['html']);
}
// Informes integra las tarjetas nativas de Validación en el orden compartido.
if (request()->routeIs('informes.index')) {
foreach ($contenidoExtraido['stacks'] as $stackNativo) {
$tarjetasNativas = $extraerTarjetasNotificaciones($stackNativo);
foreach ($tarjetasNativas['tarjetas'] as $tarjetaNativa) {
if (!preg_match(
'/\bdata-notification-order-group=["\']modificaciones_validacion["\']/i',
$tarjetaNativa
)) {
continue;
}
$stacksNotificaciones[] = $tarjetaNativa;
}
}
}
$stacksNotificaciones = array_values(array_filter($stacksNotificaciones, function ($stack) {
return trim((string) $stack) !== '';
}));
$tarjetasNotificaciones = [];
$contenidoResidualStacks = [];
foreach ($stacksNotificaciones as $indiceStack => $stack) {
$resultadoTarjetas = $extraerTarjetasNotificaciones($stack);
foreach ($resultadoTarjetas['tarjetas'] as $indiceTarjeta => $tarjeta) {
$tarjetasNotificaciones[] = [
'html' => $tarjeta,
'indice' => ($indiceStack * 10000) + $indiceTarjeta,
];
}
if (trim($resultadoTarjetas['html']) !== '') {
$contenidoResidualStacks[] = trim($resultadoTarjetas['html']);
}
}
$obtenerDatoOrdenTarjeta = function ($html, $atributo, $valorPredeterminado = '') {
$patron = '/\b'.preg_quote($atributo, '/').'=["\']([^"\']*)["\']/i';
if (preg_match($patron, $html, $coincidencia)) {
return html_entity_decode($coincidencia[1], ENT_QUOTES, 'UTF-8');
}
return $valorPredeterminado;
};
usort($tarjetasNotificaciones, function ($tarjetaA, $tarjetaB) use ($obtenerDatoOrdenTarjeta) {
$grupoA = $obtenerDatoOrdenTarjeta($tarjetaA['html'], 'data-notification-order-group', 'general');
$grupoB = $obtenerDatoOrdenTarjeta($tarjetaB['html'], 'data-notification-order-group', 'general');
$comparacionGrupo = strcmp($grupoA, $grupoB);
if ($comparacionGrupo !== 0) {
return $comparacionGrupo;
}
$fechaA = (int) $obtenerDatoOrdenTarjeta($tarjetaA['html'], 'data-notification-order-date', 0);
$fechaB = (int) $obtenerDatoOrdenTarjeta($tarjetaB['html'], 'data-notification-order-date', 0);
if ($fechaA !== $fechaB) {
return $fechaB <=> $fechaA;
}
$secuenciaA = (int) $obtenerDatoOrdenTarjeta($tarjetaA['html'], 'data-notification-order-sequence', 0);
$secuenciaB = (int) $obtenerDatoOrdenTarjeta($tarjetaB['html'], 'data-notification-order-sequence', 0);
if ($secuenciaA !== $secuenciaB) {
return $secuenciaB <=> $secuenciaA;
}
return $tarjetaA['indice'] <=> $tarjetaB['indice'];
});
$stacksNotificaciones = array_map(function ($tarjeta) {
return $tarjeta['html'];
}, $tarjetasNotificaciones);
$stacksNotificaciones = array_merge($stacksNotificaciones, $contenidoResidualStacks);
$notificacionesGlobalesModulo = '';
if (count($stacksNotificaciones) > 0) {
$notificacionesGlobalesModulo = '
'
."\n".implode("\n", $stacksNotificaciones)."\n"
.'
';
}
$insertarEnAnclaModulo = function ($html, $bloqueNotificaciones) use ($patronAnclaNotificaciones) {
// El ancla explícita se consume aun cuando el usuario no tenga tarjetas.
if (preg_match($patronAnclaNotificaciones, $html, $ancla, PREG_OFFSET_CAPTURE)) {
$inicioAncla = $ancla[0][1];
$finAncla = $inicioAncla + strlen($ancla[0][0]);
return substr($html, 0, $inicioAncla)
.$bloqueNotificaciones
.substr($html, $finAncla);
}
// Respaldo seguro: no analiza la estructura ni oculta tarjetas si aparece una vista nueva sin ancla.
if (trim((string) $bloqueNotificaciones) === '') {
return $html;
}
return $bloqueNotificaciones."\n".$html;
};
$contenidoModulo = $insertarEnAnclaModulo($contenidoModulo, $notificacionesGlobalesModulo);
@endphp
{!! $contenidoModulo !!}