@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, ']*>/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 !!}