You've already forked Atomcms-edit
fix: disable APP_DEBUG in production, fix .htaccess structure, add .gitignore cleanup
- Set APP_DEBUG=false in .env to prevent stack trace leakage - Use strict comparison (===) for MD5 password migration check - Fix duplicate rewrite rules and orphaned closing tag in .htaccess - Remove leftover test files (cookies.txt, ci_test.txt, test-registration.php) - Remove duplicate package-lock.json (using yarn only) - Update .gitignore for above files
This commit is contained in:
@@ -31,5 +31,12 @@ check-updates.sh
|
||||
/storage/debugbar/rr
|
||||
.rr.yaml
|
||||
|
||||
# Lockfiles (kies 1 package manager)
|
||||
package-lock.json
|
||||
|
||||
# Overgebleven test/temp bestanden
|
||||
ci_test.txt
|
||||
cookies.txt
|
||||
|
||||
# GitHub workflows (pushen naar GitLab)
|
||||
!/.github/workflows/
|
||||
|
||||
@@ -179,7 +179,7 @@ class RedirectIfTwoFactorAuthenticatable
|
||||
|
||||
private function convertUserPassword(User $user, string $password): void
|
||||
{
|
||||
if ($user->password == md5($password)) {
|
||||
if ($user->password === md5($password)) {
|
||||
$user->update([
|
||||
'password' => Hash::make($password),
|
||||
]);
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Last pipeline test: 2026-05-23 17:11:24 UTC
|
||||
@@ -1,4 +0,0 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
Regular → Executable
Generated
-7837
File diff suppressed because it is too large
Load Diff
@@ -44,20 +44,3 @@
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json application/xml
|
||||
</IfModule>
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
# Handle Authorization Header
|
||||
RewriteCond %{HTTP:Authorization} .
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
|
||||
# Redirect Trailing Slashes If Not A Folder...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} (.+)/$
|
||||
RewriteRule ^ %1 [L,R=301]
|
||||
|
||||
# Send Requests To Front Controller...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* Standard Button Style - ALL buttons same size */
|
||||
/* Standard Button Style */
|
||||
.toolbar-btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
@@ -110,270 +110,10 @@
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* Radio Bar - Same height as buttons */
|
||||
.radio-container {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 2px solid {{ setting('toolbar_border_color', setting('button_border_color', '#cf9d15')) }};
|
||||
border-radius: 6px;
|
||||
background: linear-gradient(135deg, {{ setting('toolbar_primary_color', setting('button_primary_color', '#eeb425')) }} 0%, {{ setting('toolbar_hover_color', setting('button_hover_color', '#cf9d15')) }} 100%);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
|
||||
overflow: hidden;
|
||||
transition: width 0.3s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.radio-container.expanded {
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.radio-toggle {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
min-width: 36px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: {{ setting('button_text_color', '#1a1a2e') }};
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.radio-status-dot {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 6px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #10b981;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
.radio-status-dot.live {
|
||||
background: #ef4444;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.radio-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 8px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.radio-container.expanded .radio-content {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.radio-divider {
|
||||
width: 1px;
|
||||
height: 24px;
|
||||
background: rgba(26, 26, 46, 0.3);
|
||||
}
|
||||
|
||||
.radio-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.radio-dj-avatar {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid rgba(26, 26, 46, 0.3);
|
||||
background: rgba(26, 26, 46, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.radio-dj-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.radio-dj-name {
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
color: var(--button-text-color);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.radio-song {
|
||||
font-size: 9px;
|
||||
color: var(--button-text-color);
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.radio-control-btn {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: #1a1a2e;
|
||||
color: var(--color-primary);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.radio-volume {
|
||||
width: 50px;
|
||||
height: 4px;
|
||||
background: rgba(26, 26, 46, 0.3);
|
||||
border-radius: 2px;
|
||||
appearance: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.radio-volume::-webkit-slider-thumb {
|
||||
appearance: none;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: #1a1a2e;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.radio-listeners {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
color: var(--button-text-color);
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* DJ Avatar Popup */
|
||||
.dj-popup {
|
||||
position: fixed;
|
||||
bottom: 100px;
|
||||
right: 24px;
|
||||
background: linear-gradient(145deg, rgba(20, 20, 30, 0.98) 0%, rgba(10, 10, 20, 0.99) 100%);
|
||||
border: 2px solid var(--color-primary);
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
min-width: 280px;
|
||||
transform: translateX(400px);
|
||||
opacity: 0;
|
||||
transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
}
|
||||
|
||||
.dj-popup.show {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dj-popup-avatar {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 50%;
|
||||
border: 3px solid var(--color-primary);
|
||||
background: var(--color-primary);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32px;
|
||||
box-shadow: 0 8px 24px rgba(238, 180, 37, 0.4);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.dj-popup-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.dj-popup-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.dj-popup-label {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.dj-popup-name {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
.dj-popup-show {
|
||||
font-size: 13px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.dj-popup-close {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.dj-popup-close:hover {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.dj-popup-indicator {
|
||||
position: absolute;
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
right: -4px;
|
||||
bottom: -4px;
|
||||
border: 2px solid #10b981;
|
||||
border-radius: 18px;
|
||||
animation: djPopupPulse 2s infinite;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@keyframes djPopupPulse {
|
||||
0%, 100% { opacity: 1; transform: scale(1); }
|
||||
50% { opacity: 0.5; transform: scale(1.02); }
|
||||
}
|
||||
|
||||
{{-- Client Loading Overlay --}}
|
||||
@if($loginData)
|
||||
@php $ic = $loginData['icon_color']; $bg = $loginData['background']; @endphp
|
||||
@@ -689,76 +429,12 @@
|
||||
</svg>
|
||||
<span id="onlineCount" style="margin-left: 4px; font-size: 11px; font-weight: 700;">0</span>
|
||||
</button>
|
||||
|
||||
|
||||
</button>
|
||||
|
||||
{{-- Radio Player --}}
|
||||
<div id="radioContainer" class="radio-container">
|
||||
<button class="radio-toggle" onclick="toggleRadioBar()" title="Radio">
|
||||
<div class="radio-status-dot" id="radioStatus"></div>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M9 18V5l12-2v13"></path>
|
||||
<circle cx="6" cy="18" r="3"></circle>
|
||||
<circle cx="18" cy="16" r="3"></circle>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="radio-content">
|
||||
<div class="radio-divider"></div>
|
||||
|
||||
<div class="radio-info">
|
||||
<div class="radio-dj-avatar" id="radioDjAvatar">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="12" cy="7" r="4"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column;">
|
||||
<span class="radio-dj-name" id="radioDj">{{ __('radio.music') }}</span>
|
||||
<span class="radio-song" id="radioSong">{{ __('radio.loading') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="radio-divider"></div>
|
||||
|
||||
<button class="radio-control-btn" onclick="toggleRadioPlay()" title="Play/Pause">
|
||||
<svg id="playIcon" width="12" height="12" viewBox="0 0 24 24" fill="currentColor">
|
||||
<polygon points="5 3 19 12 5 21 5 3"/>
|
||||
</svg>
|
||||
<svg id="pauseIcon" width="12" height="12" viewBox="0 0 24 24" fill="currentColor" class="hidden">
|
||||
<rect x="6" y="4" width="4" height="16"/>
|
||||
<rect x="14" y="4" width="4" height="16"/>
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<div class="radio-divider"></div>
|
||||
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#1a1a2e" stroke-width="2">
|
||||
<polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/>
|
||||
</svg>
|
||||
<input type="range" class="radio-volume" id="radioVolume" min="0" max="100" value="50" onchange="setRadioVolume(this.value)">
|
||||
|
||||
<div class="radio-divider"></div>
|
||||
|
||||
<div class="radio-listeners">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#1a1a2e" stroke-width="2">
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
|
||||
<circle cx="9" cy="7" r="4"/>
|
||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
|
||||
</svg>
|
||||
<span id="radioListeners">0</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Nitro Client --}}
|
||||
{{-- Nitro Client URL Setup --}}
|
||||
@php
|
||||
$nitroUrl = sprintf('%s/index.html?sso=%s', setting('nitro_path'), $sso);
|
||||
$toolbarParams = [];
|
||||
// Toolbar with fallback to button colors (don't URL encode - # is valid in URLs)
|
||||
$toolbarParams[] = 'toolbar_primary=' . (setting('toolbar_primary_color') ?: setting('button_primary_color', '#eeb425'));
|
||||
$toolbarParams[] = 'toolbar_hover=' . (setting('toolbar_hover_color') ?: setting('button_hover_color', '#cf9d15'));
|
||||
$toolbarParams[] = 'toolbar_border=' . (setting('toolbar_border_color') ?: setting('button_border_color', '#cf9d15'));
|
||||
@@ -840,24 +516,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- DJ Avatar Popup --}}
|
||||
@if(setting('radio_show_dj_avatar_popup'))
|
||||
<div id="djPopup" class="dj-popup">
|
||||
<div class="dj-popup-indicator"></div>
|
||||
<button class="dj-popup-close" onclick="hideDjPopup()">✕</button>
|
||||
<div class="dj-popup-avatar" id="djPopupAvatar">
|
||||
🎵
|
||||
</div>
|
||||
<div class="dj-popup-info">
|
||||
<div class="dj-popup-label">Nu Live</div>
|
||||
<div class="dj-popup-name" id="djPopupName">DJ Name</div>
|
||||
<div class="dj-popup-show" id="djPopupShow">Show Name</div>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<audio id="radioAudio" preload="none"></audio>
|
||||
|
||||
<script>
|
||||
// Fullscreen
|
||||
function toggleFullscreen() {
|
||||
@@ -880,140 +538,6 @@
|
||||
|
||||
setInterval(updateOnlineCount, 15000);
|
||||
updateOnlineCount();
|
||||
|
||||
// Radio
|
||||
let radioPlaying = false;
|
||||
let radioStreamUrl = null;
|
||||
let radioExpanded = false;
|
||||
const radioAudio = document.getElementById('radioAudio');
|
||||
|
||||
function toggleRadioBar() {
|
||||
const container = document.getElementById('radioContainer');
|
||||
radioExpanded = !radioExpanded;
|
||||
|
||||
if (radioExpanded) {
|
||||
container.classList.add('expanded');
|
||||
if (!radioStreamUrl) loadRadio();
|
||||
} else {
|
||||
container.classList.remove('expanded');
|
||||
}
|
||||
}
|
||||
|
||||
function loadRadio() {
|
||||
fetch("{{ route('api.radio.config') }}")
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.enabled && data.stream_url) {
|
||||
radioStreamUrl = data.stream_url;
|
||||
radioAudio.src = radioStreamUrl;
|
||||
document.getElementById('radioSong').textContent = 'Gereed';
|
||||
|
||||
fetch("{{ route('api.settings.radio.auto-play') }}")
|
||||
.then(r => r.json())
|
||||
.then(settings => {
|
||||
if (settings.auto_play) toggleRadioPlay();
|
||||
});
|
||||
} else {
|
||||
document.getElementById('radioSong').textContent = 'Offline';
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
document.getElementById('radioSong').textContent = 'Error';
|
||||
});
|
||||
}
|
||||
|
||||
function toggleRadioPlay() {
|
||||
if (!radioStreamUrl) {
|
||||
loadRadio();
|
||||
return;
|
||||
}
|
||||
|
||||
const playIcon = document.getElementById('playIcon');
|
||||
const pauseIcon = document.getElementById('pauseIcon');
|
||||
|
||||
if (radioPlaying) {
|
||||
radioAudio.pause();
|
||||
playIcon.classList.remove('hidden');
|
||||
pauseIcon.classList.add('hidden');
|
||||
radioPlaying = false;
|
||||
} else {
|
||||
radioAudio.volume = document.getElementById('radioVolume').value / 100;
|
||||
radioAudio.play()
|
||||
.then(() => {
|
||||
playIcon.classList.add('hidden');
|
||||
pauseIcon.classList.remove('hidden');
|
||||
radioPlaying = true;
|
||||
})
|
||||
.catch(() => {
|
||||
document.getElementById('radioSong').textContent = 'Fout';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function setRadioVolume(val) {
|
||||
radioAudio.volume = val / 100;
|
||||
localStorage.setItem('radioVol', val);
|
||||
}
|
||||
|
||||
const savedVol = localStorage.getItem('radioVol');
|
||||
if (savedVol) {
|
||||
document.getElementById('radioVolume').value = savedVol;
|
||||
}
|
||||
|
||||
// Update radio info
|
||||
function updateRadioInfo() {
|
||||
if (!radioStreamUrl) return;
|
||||
|
||||
fetch("{{ route('api.radio.config') }}")
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
const defaultLook = '{{ setting("radio_default_avatar_figure", "hr-893-45.hd-180-2.ch-210-62.lg-285-62.sh-295-62.ha-1012-62.wa-2007-0") }}';
|
||||
const defaultName = '{{ setting("radio_default_dj_name", "Frank") }}';
|
||||
const avatarUrl = "{{ setting('avatar_imager') }}" + (data.dj?.look || defaultLook) + '&headonly=1';
|
||||
|
||||
const avatarEl = document.getElementById('radioDjAvatar');
|
||||
if (data.dj?.look) {
|
||||
avatarEl.innerHTML = '<img src="' + avatarUrl + '" alt="DJ">';
|
||||
} else {
|
||||
avatarEl.innerHTML = '<img src="' + avatarUrl + '" alt="' + defaultName + '">';
|
||||
}
|
||||
|
||||
const dj = data.dj ? (typeof data.dj === 'object' ? data.dj.username : data.dj) : defaultName;
|
||||
document.getElementById('radioDj').textContent = dj;
|
||||
|
||||
const status = document.getElementById('radioStatus');
|
||||
if (data.dj) {
|
||||
status.classList.add('live');
|
||||
} else {
|
||||
status.classList.remove('live');
|
||||
}
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
fetch("{{ route('api.radio.now-playing') }}")
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
const song = data.song || data.title || (data.now_playing?.title) || 'Live';
|
||||
document.getElementById('radioSong').textContent = song;
|
||||
})
|
||||
.catch(() => {});
|
||||
|
||||
fetch("{{ route('api.radio.listeners') }}")
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
document.getElementById('radioListeners').textContent = data.count || '0';
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
setInterval(updateRadioInfo, 10000);
|
||||
|
||||
// Init
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
loadRadio();
|
||||
updateRadioInfo();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<script src="{{ asset('assets/js/atom.js') }}"></script>
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
$app = require __DIR__ . '/bootstrap/app.php';
|
||||
$kernel = $app->make(Kernel::class);
|
||||
$kernel->bootstrap();
|
||||
|
||||
try {
|
||||
$user = User::create([
|
||||
'username' => 'testreg123',
|
||||
'mail' => 'testreg123@test.nl',
|
||||
'password' => bcrypt('test123'),
|
||||
'account_created' => time(),
|
||||
'last_login' => time(),
|
||||
'motto' => 'Test registration',
|
||||
'look' => 'hr-100-61.hd-180-1.ch-210-66',
|
||||
'auth_ticket' => '',
|
||||
'home_room' => 0,
|
||||
'ip_register' => '127.0.0.1',
|
||||
'ip_current' => '127.0.0.1',
|
||||
]);
|
||||
|
||||
echo 'SUCCESS! User created with ID: ' . $user->id . "\n";
|
||||
echo 'ip_register: ' . $user->ip_register . "\n";
|
||||
echo 'ip_current: ' . $user->ip_current . "\n";
|
||||
|
||||
$user->delete();
|
||||
echo "Test user deleted. All good!\n";
|
||||
} catch (Exception $e) {
|
||||
echo 'ERROR: ' . $e->getMessage() . "\n";
|
||||
echo 'File: ' . $e->getFile() . ' line ' . $e->getLine() . "\n";
|
||||
}
|
||||
Reference in New Issue
Block a user