feat(Docker): Upgrade to PHP 8.5.0RC3 with native ext-uri support
BREAKING CHANGE: Requires PHP 8.5.0RC3 Changes: - Update Docker base image from php:8.4-fpm to php:8.5.0RC3-fpm - Enable ext-uri for native WHATWG URL parsing support - Update composer.json PHP requirement from ^8.4 to ^8.5 - Add ext-uri as required extension in composer.json - Move URL classes from Url.php85/ to Url/ directory (now compatible) - Remove temporary PHP 8.4 compatibility workarounds Benefits: - Native URL parsing with Uri\WhatWg\Url class - Better performance for URL operations - Future-proof with latest PHP features - Eliminates PHP version compatibility issues
This commit is contained in:
81
tests/debug/test-foreach-processing.php
Normal file
81
tests/debug/test-foreach-processing.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\View\DomWrapper;
|
||||
use App\Framework\View\Processors\ForProcessor;
|
||||
use App\Framework\View\RenderContext;
|
||||
use App\Framework\Meta\MetaData;
|
||||
|
||||
// Initialize container
|
||||
$container = new DefaultContainer();
|
||||
|
||||
// Create ForProcessor
|
||||
$forProcessor = $container->get(ForProcessor::class);
|
||||
|
||||
// Test HTML with foreach attribute
|
||||
$html = <<<'HTML'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Model</th>
|
||||
<th>Version</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr foreach="$models as $model">
|
||||
<td>{{ $model['model_name'] }}</td>
|
||||
<td>{{ $model['version'] }}</td>
|
||||
<td>{{ $model['status'] }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
|
||||
// Test data
|
||||
$data = [
|
||||
'models' => [
|
||||
['model_name' => 'fraud-detector', 'version' => '1.0.0', 'status' => 'healthy'],
|
||||
['model_name' => 'spam-classifier', 'version' => '2.0.0', 'status' => 'degraded'],
|
||||
]
|
||||
];
|
||||
|
||||
// Create render context
|
||||
$context = new RenderContext(
|
||||
template: 'test',
|
||||
metaData: new MetaData('test', 'test'),
|
||||
data: $data,
|
||||
controllerClass: null
|
||||
);
|
||||
|
||||
// Process
|
||||
echo "=== ORIGINAL HTML ===\n";
|
||||
echo $html . "\n\n";
|
||||
|
||||
$dom = DomWrapper::fromString($html);
|
||||
|
||||
echo "=== CHECKING FOR FOREACH NODES ===\n";
|
||||
$foreachNodes = $dom->document->querySelectorAll('[foreach]');
|
||||
echo "Found " . count($foreachNodes) . " foreach nodes\n\n";
|
||||
|
||||
foreach ($foreachNodes as $idx => $node) {
|
||||
echo "Node $idx:\n";
|
||||
echo " Tag: " . $node->tagName . "\n";
|
||||
echo " Foreach: " . $node->getAttribute('foreach') . "\n";
|
||||
echo " HTML: " . substr($dom->document->saveHTML($node), 0, 200) . "\n\n";
|
||||
}
|
||||
|
||||
echo "=== PROCESSING WITH ForProcessor ===\n";
|
||||
$processedDom = $forProcessor->process($dom, $context);
|
||||
|
||||
echo "=== PROCESSED HTML ===\n";
|
||||
echo $processedDom->toHtml(true) . "\n";
|
||||
98
tests/debug/test-foreach-with-data.php
Normal file
98
tests/debug/test-foreach-with-data.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\View\Processors\ForStringProcessor;
|
||||
use App\Framework\View\RenderContext;
|
||||
use App\Framework\Meta\MetaData;
|
||||
|
||||
// Initialize container
|
||||
$container = new DefaultContainer();
|
||||
|
||||
// Create ForStringProcessor
|
||||
$forStringProcessor = $container->get(ForStringProcessor::class);
|
||||
|
||||
// Test HTML with foreach attribute - EXACTLY like in ML Dashboard
|
||||
$html = <<<'HTML'
|
||||
<table class="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Model Name</th>
|
||||
<th>Version</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr foreach="$models as $model">
|
||||
<td>{{ $model['model_name'] }}</td>
|
||||
<td>{{ $model['version'] }}</td>
|
||||
<td>{{ $model['status'] }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
HTML;
|
||||
|
||||
// Test data with 2 models
|
||||
$data = [
|
||||
'models' => [
|
||||
[
|
||||
'model_name' => 'fraud-detector',
|
||||
'version' => '1.0.0',
|
||||
'status' => 'healthy'
|
||||
],
|
||||
[
|
||||
'model_name' => 'spam-classifier',
|
||||
'version' => '2.0.0',
|
||||
'status' => 'degraded'
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
// Create render context
|
||||
$context = new RenderContext(
|
||||
template: 'test',
|
||||
metaData: new MetaData('test', 'test'),
|
||||
data: $data,
|
||||
controllerClass: null
|
||||
);
|
||||
|
||||
echo "=== ORIGINAL HTML ===\n";
|
||||
echo $html . "\n\n";
|
||||
|
||||
echo "=== PROCESSING WITH ForStringProcessor ===\n";
|
||||
$result = $forStringProcessor->process($html, $context);
|
||||
|
||||
echo "=== PROCESSED HTML ===\n";
|
||||
echo $result . "\n\n";
|
||||
|
||||
echo "=== VERIFICATION ===\n";
|
||||
if (str_contains($result, 'foreach=')) {
|
||||
echo "❌ PROBLEM: foreach attribute still present\n";
|
||||
} else {
|
||||
echo "✅ Good: foreach attribute removed\n";
|
||||
}
|
||||
|
||||
if (str_contains($result, '{{ $model')) {
|
||||
echo "❌ PROBLEM: Placeholders not replaced\n";
|
||||
} else {
|
||||
echo "✅ Good: Placeholders replaced\n";
|
||||
}
|
||||
|
||||
if (str_contains($result, 'fraud-detector')) {
|
||||
echo "✅ Good: Model data found in output\n";
|
||||
} else {
|
||||
echo "❌ PROBLEM: Model data NOT found in output\n";
|
||||
}
|
||||
|
||||
if (str_contains($result, 'spam-classifier')) {
|
||||
echo "✅ Good: Second model data found in output\n";
|
||||
} else {
|
||||
echo "❌ PROBLEM: Second model data NOT found in output\n";
|
||||
}
|
||||
|
||||
// Count rows
|
||||
$rowCount = substr_count($result, '<tr>');
|
||||
echo "\nGenerated $rowCount <tr> elements (expected: 3 - 1 header + 2 data rows)\n";
|
||||
106
tests/debug/test-full-template-pipeline.php
Normal file
106
tests/debug/test-full-template-pipeline.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\View\ViewRenderer;
|
||||
use App\Framework\View\RenderContext;
|
||||
use App\Framework\Meta\MetaData;
|
||||
|
||||
// Initialize container
|
||||
$container = new DefaultContainer();
|
||||
|
||||
// Get ViewRenderer (complete pipeline)
|
||||
$viewRenderer = $container->get(ViewRenderer::class);
|
||||
|
||||
// Test data matching the ML Dashboard
|
||||
$data = [
|
||||
'models' => [
|
||||
[
|
||||
'model_name' => 'fraud-detector',
|
||||
'version' => '1.0.0',
|
||||
'type' => 'supervised',
|
||||
'accuracy' => 0.94,
|
||||
'status' => 'healthy',
|
||||
'total_predictions' => 1234
|
||||
],
|
||||
[
|
||||
'model_name' => 'spam-classifier',
|
||||
'version' => '2.0.0',
|
||||
'type' => 'supervised',
|
||||
'accuracy' => 0.78,
|
||||
'status' => 'degraded',
|
||||
'total_predictions' => 567
|
||||
],
|
||||
],
|
||||
'alerts' => [],
|
||||
'summary' => [
|
||||
'total_models' => 2,
|
||||
'healthy_models' => 1,
|
||||
'degraded_models' => 1
|
||||
]
|
||||
];
|
||||
|
||||
// Create render context
|
||||
$context = new RenderContext(
|
||||
template: 'admin/ml-dashboard',
|
||||
metaData: new MetaData('ML Dashboard', ''),
|
||||
data: $data,
|
||||
controllerClass: null
|
||||
);
|
||||
|
||||
echo "=== TESTING FULL TEMPLATE PIPELINE ===\n\n";
|
||||
echo "Data being passed:\n";
|
||||
print_r($data);
|
||||
echo "\n";
|
||||
|
||||
try {
|
||||
echo "=== RENDERING TEMPLATE ===\n";
|
||||
$html = $viewRenderer->render($context);
|
||||
|
||||
echo "=== CHECKING FOR FOREACH ATTRIBUTES IN OUTPUT ===\n";
|
||||
if (str_contains($html, 'foreach=')) {
|
||||
echo "❌ PROBLEM: foreach attribute found in output (not processed)\n";
|
||||
|
||||
// Show the problematic section
|
||||
preg_match('/<tr[^>]*foreach[^>]*>.*?<\/tr>/s', $html, $matches);
|
||||
if (!empty($matches)) {
|
||||
echo "Found:\n" . $matches[0] . "\n\n";
|
||||
}
|
||||
} else {
|
||||
echo "✅ Good: No foreach attributes in output\n\n";
|
||||
}
|
||||
|
||||
echo "=== CHECKING FOR PLACEHOLDERS IN OUTPUT ===\n";
|
||||
if (preg_match('/{{[^}]+}}/', $html, $matches)) {
|
||||
echo "❌ PROBLEM: Unreplaced placeholders found\n";
|
||||
echo "Example: " . $matches[0] . "\n\n";
|
||||
} else {
|
||||
echo "✅ Good: No unreplaced placeholders\n\n";
|
||||
}
|
||||
|
||||
echo "=== CHECKING FOR MODEL DATA IN OUTPUT ===\n";
|
||||
if (str_contains($html, 'fraud-detector')) {
|
||||
echo "✅ Good: Model data found in output\n";
|
||||
} else {
|
||||
echo "❌ PROBLEM: Model data NOT found in output\n";
|
||||
}
|
||||
|
||||
if (str_contains($html, '1.0.0')) {
|
||||
echo "✅ Good: Version data found in output\n";
|
||||
} else {
|
||||
echo "❌ PROBLEM: Version data NOT found in output\n";
|
||||
}
|
||||
|
||||
// Show a snippet of the models table
|
||||
echo "\n=== MODELS TABLE SECTION ===\n";
|
||||
if (preg_match('/<tbody[^>]*>.*?<\/tbody>/s', $html, $matches)) {
|
||||
echo substr($matches[0], 0, 500) . "...\n";
|
||||
}
|
||||
|
||||
} catch (\Exception $e) {
|
||||
echo "❌ ERROR: " . $e->getMessage() . "\n";
|
||||
echo "Trace:\n" . $e->getTraceAsString() . "\n";
|
||||
}
|
||||
65
tests/debug/test-hash-integration.php
Normal file
65
tests/debug/test-hash-integration.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use App\Framework\Core\ValueObjects\Hash;
|
||||
use App\Framework\Core\ValueObjects\HashAlgorithm;
|
||||
use App\Framework\UserAgent\UserAgentParser;
|
||||
|
||||
echo "=== Testing Hash Value Object Integration ===\n\n";
|
||||
|
||||
// Test 1: Hash VO mit xxh3
|
||||
echo "Test 1: Hash VO with xxh3 algorithm\n";
|
||||
echo "-----------------------------------\n";
|
||||
$data = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0";
|
||||
$hash = Hash::create($data, HashAlgorithm::XXHASH3);
|
||||
echo "Data: {$data}\n";
|
||||
echo "Algorithm: " . $hash->getAlgorithm()->value . "\n";
|
||||
echo "Hash: " . $hash->toString() . "\n";
|
||||
echo "Hash Length: " . strlen($hash->toString()) . "\n\n";
|
||||
|
||||
// Test 2: HashAlgorithm::fast()
|
||||
echo "Test 2: HashAlgorithm::fast() method\n";
|
||||
echo "-----------------------------------\n";
|
||||
$fastAlgo = HashAlgorithm::fast();
|
||||
echo "Fast Algorithm: " . $fastAlgo->value . "\n";
|
||||
echo "Is xxh3 available: " . (HashAlgorithm::XXHASH3->isAvailable() ? 'Yes' : 'No') . "\n";
|
||||
echo "Is xxh64 available: " . (HashAlgorithm::XXHASH64->isAvailable() ? 'Yes' : 'No') . "\n\n";
|
||||
|
||||
// Test 3: UserAgentParser mit Hash VO
|
||||
echo "Test 3: UserAgentParser using Hash VO\n";
|
||||
echo "-----------------------------------\n";
|
||||
$parser = new UserAgentParser();
|
||||
$ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0";
|
||||
$parsed = $parser->parse($ua);
|
||||
|
||||
echo "User-Agent: {$ua}\n";
|
||||
echo "Browser: " . $parsed->browser->getDisplayName() . "\n";
|
||||
echo "Browser Version: " . $parsed->browserVersion->toString() . "\n";
|
||||
echo "Platform: " . $parsed->platform->getDisplayName() . "\n";
|
||||
echo "Platform Version: " . $parsed->platformVersion->toString() . "\n";
|
||||
echo "Engine: " . $parsed->engine->getDisplayName() . "\n";
|
||||
echo "Is Modern: " . ($parsed->isModern ? 'Yes' : 'No') . "\n\n";
|
||||
|
||||
// Test 4: Hash comparison
|
||||
echo "Test 4: Hash equality check\n";
|
||||
echo "-----------------------------------\n";
|
||||
$hash1 = Hash::create("test data", HashAlgorithm::XXHASH3);
|
||||
$hash2 = Hash::create("test data", HashAlgorithm::XXHASH3);
|
||||
$hash3 = Hash::create("different data", HashAlgorithm::XXHASH3);
|
||||
|
||||
echo "Hash1 equals Hash2: " . ($hash1->equals($hash2) ? 'Yes' : 'No') . "\n";
|
||||
echo "Hash1 equals Hash3: " . ($hash1->equals($hash3) ? 'Yes' : 'No') . "\n\n";
|
||||
|
||||
// Test 5: Available hash algorithms
|
||||
echo "Test 5: Available hash algorithms\n";
|
||||
echo "-----------------------------------\n";
|
||||
foreach (HashAlgorithm::cases() as $algo) {
|
||||
$available = $algo->isAvailable() ? '✓' : '✗';
|
||||
$secure = $algo->isSecure() ? '(secure)' : '(fast)';
|
||||
echo "{$available} {$algo->value} - Length: {$algo->getLength()} chars {$secure}\n";
|
||||
}
|
||||
|
||||
echo "\n=== All Tests Completed Successfully ===\n";
|
||||
@@ -23,8 +23,10 @@ use App\Framework\Context\ExecutionContext;
|
||||
use App\Framework\MachineLearning\ModelManagement\NotificationAlertingService;
|
||||
use App\Framework\MachineLearning\ModelManagement\MLConfig;
|
||||
use App\Framework\Core\ValueObjects\Version;
|
||||
use App\Framework\Notification\Storage\NotificationRepository;
|
||||
use App\Framework\Notification\Storage\DatabaseNotificationRepository;
|
||||
use App\Framework\Notification\ValueObjects\NotificationStatus;
|
||||
use App\Framework\Notification\NullNotificationDispatcher;
|
||||
use App\Framework\Database\ValueObjects\SqlQuery;
|
||||
|
||||
// Bootstrap container
|
||||
$performanceCollector = new EnhancedPerformanceCollector(
|
||||
@@ -81,8 +83,14 @@ $errors = [];
|
||||
|
||||
// Get services
|
||||
try {
|
||||
$alertingService = $container->get(NotificationAlertingService::class);
|
||||
$notificationRepo = $container->get(NotificationRepository::class);
|
||||
// Manually instantiate NotificationAlertingService with NullNotificationDispatcher
|
||||
// to avoid interface binding issues in tests
|
||||
$dispatcher = new NullNotificationDispatcher();
|
||||
$config = $container->get(MLConfig::class);
|
||||
$alertingService = new NotificationAlertingService($dispatcher, $config, 'admin');
|
||||
|
||||
// DatabaseNotificationRepository can be auto-resolved by container
|
||||
$notificationRepo = $container->get(DatabaseNotificationRepository::class);
|
||||
} catch (\Throwable $e) {
|
||||
echo red("✗ Failed to initialize services: " . $e->getMessage() . "\n");
|
||||
exit(1);
|
||||
@@ -101,7 +109,7 @@ try {
|
||||
usleep(100000); // 100ms
|
||||
|
||||
// Verify notification was created
|
||||
$notifications = $notificationRepo->getAll('admin', 10);
|
||||
$notifications = $notificationRepo->findByUser('admin', 10);
|
||||
|
||||
if (count($notifications) > 0) {
|
||||
$lastNotification = $notifications[0];
|
||||
@@ -138,7 +146,7 @@ try {
|
||||
|
||||
usleep(100000);
|
||||
|
||||
$notifications = $notificationRepo->getAll('admin', 10);
|
||||
$notifications = $notificationRepo->findByUser('admin', 10);
|
||||
$found = false;
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
@@ -175,16 +183,16 @@ try {
|
||||
|
||||
usleep(100000);
|
||||
|
||||
$notifications = $notificationRepo->getAll('admin', 10);
|
||||
$notifications = $notificationRepo->findByUser('admin', 10);
|
||||
$found = false;
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
if (str_contains($notification->title, 'Low Confidence')) {
|
||||
$found = true;
|
||||
echo green("✓ PASSED\n");
|
||||
echo " - Average Confidence: 45%\n");
|
||||
echo " - Threshold: 70%\n");
|
||||
echo " - Priority: {$notification->priority->value} (should be NORMAL)\n");
|
||||
echo " - Average Confidence: 45%\n";
|
||||
echo " - Threshold: 70%\n";
|
||||
echo " - Priority: {$notification->priority->value} (should be NORMAL)\n";
|
||||
$passed++;
|
||||
break;
|
||||
}
|
||||
@@ -211,16 +219,16 @@ try {
|
||||
|
||||
usleep(100000);
|
||||
|
||||
$notifications = $notificationRepo->getAll('admin', 10);
|
||||
$notifications = $notificationRepo->findByUser('admin', 10);
|
||||
$found = false;
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
if (str_contains($notification->title, 'Model Deployed')) {
|
||||
$found = true;
|
||||
echo green("✓ PASSED\n");
|
||||
echo " - Model: image-classifier v4.2.1\n");
|
||||
echo " - Environment: production\n");
|
||||
echo " - Priority: {$notification->priority->value} (should be LOW)\n");
|
||||
echo " - Model: image-classifier v4.2.1\n";
|
||||
echo " - Environment: production\n";
|
||||
echo " - Priority: {$notification->priority->value} (should be LOW)\n";
|
||||
$passed++;
|
||||
break;
|
||||
}
|
||||
@@ -251,15 +259,15 @@ try {
|
||||
|
||||
usleep(100000);
|
||||
|
||||
$notifications = $notificationRepo->getAll('admin', 10);
|
||||
$notifications = $notificationRepo->findByUser('admin', 10);
|
||||
$found = false;
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
if (str_contains($notification->title, 'Auto-Tuning Triggered')) {
|
||||
$found = true;
|
||||
echo green("✓ PASSED\n");
|
||||
echo " - Suggested Parameters: learning_rate, batch_size, epochs\n");
|
||||
echo " - Priority: {$notification->priority->value} (should be NORMAL)\n");
|
||||
echo " - Suggested Parameters: learning_rate, batch_size, epochs\n";
|
||||
echo " - Priority: {$notification->priority->value} (should be NORMAL)\n";
|
||||
$passed++;
|
||||
break;
|
||||
}
|
||||
@@ -291,15 +299,15 @@ try {
|
||||
|
||||
usleep(100000);
|
||||
|
||||
$notifications = $notificationRepo->getAll('admin', 10);
|
||||
$notifications = $notificationRepo->findByUser('admin', 10);
|
||||
$found = false;
|
||||
|
||||
foreach ($notifications as $notification) {
|
||||
if (str_contains($notification->title, 'Critical System Alert')) {
|
||||
$found = true;
|
||||
echo green("✓ PASSED\n");
|
||||
echo " - Level: critical\n");
|
||||
echo " - Priority: {$notification->priority->value} (should be URGENT)\n");
|
||||
echo " - Level: critical\n";
|
||||
echo " - Priority: {$notification->priority->value} (should be URGENT)\n";
|
||||
$passed++;
|
||||
break;
|
||||
}
|
||||
@@ -318,7 +326,7 @@ try {
|
||||
// Test 7: Notification Data Integrity
|
||||
echo cyan("Test 7: Notification Data Integrity... ");
|
||||
try {
|
||||
$notifications = $notificationRepo->getAll('admin', 20);
|
||||
$notifications = $notificationRepo->findByUser('admin', 20);
|
||||
|
||||
if (count($notifications) >= 3) {
|
||||
$driftNotification = null;
|
||||
@@ -340,11 +348,11 @@ try {
|
||||
|
||||
if ($hasModelName && $hasVersion && $hasDriftValue && $hasThreshold && $hasAction) {
|
||||
echo green("✓ PASSED\n");
|
||||
echo " - Model Name: {$driftNotification->data['model_name']}\n");
|
||||
echo " - Version: {$driftNotification->data['version']}\n");
|
||||
echo " - Drift Value: {$driftNotification->data['drift_value']}\n");
|
||||
echo " - Action URL: {$driftNotification->actionUrl}\n");
|
||||
echo " - Action Label: {$driftNotification->actionLabel}\n");
|
||||
echo " - Model Name: {$driftNotification->data['model_name']}\n";
|
||||
echo " - Version: {$driftNotification->data['version']}\n";
|
||||
echo " - Drift Value: {$driftNotification->data['drift_value']}\n";
|
||||
echo " - Action URL: {$driftNotification->actionUrl}\n";
|
||||
echo " - Action Label: {$driftNotification->actionLabel}\n";
|
||||
$passed++;
|
||||
} else {
|
||||
echo red("✗ FAILED: Incomplete notification data\n");
|
||||
@@ -367,7 +375,7 @@ try {
|
||||
// Test 8: Notification Status Tracking
|
||||
echo cyan("Test 8: Notification Status Tracking... ");
|
||||
try {
|
||||
$notifications = $notificationRepo->getAll('admin', 10);
|
||||
$notifications = $notificationRepo->findByUser('admin', 10);
|
||||
|
||||
if (count($notifications) > 0) {
|
||||
$unreadCount = 0;
|
||||
@@ -414,7 +422,7 @@ if ($failed > 0) {
|
||||
// Display Recent Notifications
|
||||
echo "\n" . blue("═══ Recent Notifications ═══\n\n");
|
||||
try {
|
||||
$recentNotifications = $notificationRepo->getAll('admin', 10);
|
||||
$recentNotifications = $notificationRepo->findByUser('admin', 10);
|
||||
|
||||
if (count($recentNotifications) > 0) {
|
||||
foreach ($recentNotifications as $i => $notification) {
|
||||
|
||||
Reference in New Issue
Block a user