WORDPRESS ONDERHOUD
WEBSITE
SERVICE
OVEREENKOMST
Met een Website Service Overeenkomst (WSO) van Oil4 heeft u een WordPress website die altijd up-to-date – en dus veilig – is.
Met een Website Service Overeenkomst (WSO) van Oil4 heeft u een WordPress website die altijd up-to-date – en dus veilig – is.
Met een Website Service Overeenkomst van Oil4 heeft u een WordPress website die altijd up-to-date – en dus veilig – is. Daarnaast kunt u met al uw vragen – en eventuele problemen – omtrent uw website direct bij ons terecht. Bij spoedgevallen ook buiten kantoortijden.
Het is van groot belang om uw WordPress website up-to-date te houden, hierdoor blijft uw website stabiel, snel en veilig. Met de Website Service Overeenkomst nemen wij het technisch onderhoud voor u uit handen. Uw WordPress versie en geïnstalleerde plugins worden regelmatig bijgewerkt naar de meest recente versie. Eventuele beschikbare security updates worden direct uitgevoerd.
Voor alle bedrijven, instellingen en zzp’ers die hun website op een professionele manier aan relaties, opdrachtgevers en potentiële klanten willen presenteren.

€ 47,50 per maand
excl. 21% BTW
HIER BEGINT MOBIEL

Met een Website Service Overeenkomst (WSO) van Oil4 heeft u een WordPress website die altijd up-to-date / veilig is.
Met een Website Service Overeenkomst van Oil4 heeft u een WordPress website die altijd up-to-date – en dus veilig – is. Daarnaast kunt u met al uw vragen – en eventuele problemen – omtrent uw website direct bij ons terecht. Bij spoedgevallen ook buiten kantoortijden.
Het is van groot belang om uw WordPress website up-to-date te houden, hierdoor blijft uw website stabiel, snel en veilig. Met de Website Service Overeenkomst nemen wij het technisch onderhoud voor u uit handen. Uw WordPress versie en geïnstalleerde plugins worden regelmatig bijgewerkt naar de meest recente versie. Eventuele beschikbare security updates worden direct uitgevoerd.
Voor alle bedrijven, instellingen en zzp’ers die hun website op een professionele manier aan relaties, opdrachtgevers en potentiële klanten willen presenteren.

€ 47,50 per maand
excl. 21% BTW
Deze website wordt het beste weergegeven in portret modus.
Deze website wordt het beste weergegeven in landscape modus.
STATUS CONTROLEREN
CHECKING
ACTIVE SERVICES
LIVE
UPTIME HISTORY
LAST 14 DAYS
(function(){
/* ========================================================== CONFIGURATIE ========================================================== */
const STATUS_URL = 'https://status.oil4.nl/index.json';
/* * Oil4 nieuwe server live: * 14 september 2026. * * Na 30 dagen schakelt SINCE LAUNCH * automatisch naar 30 DAYS. */
const LAUNCH_DATE = new Date('2026-09-14T00:00:00+02:00');
const REFRESH_INTERVAL = 60000;
const WANTED_SERVICES = [
{ key:'web', label:'Web' },
{ key:'plesk', label:'Plesk' },
{ key:'imap', label:'IMAP' },
{ key:'pop3', label:'POP3' },
{ key:'smtp', label:'SMTP' }
];
/* ========================================================== HELPERS ========================================================== */
function clamp(value,min,max){
return Math.min( Math.max(value,min), max );
}
/* * Better Stack availability kan afhankelijk * van output bijvoorbeeld 1.0 of 100 zijn. */
function normalizeAvailability(value){
if( value === null || value === undefined || value === '' ){ return null; }
let number = parseFloat(value);
if(isNaN(number)){ return null; }
if(number >= 0 && number <= 1){ number *= 100; } return clamp( number, 0, 100 ); } function normalizeName(name){ return String(name || '') .toLowerCase() .replace( /^oil4[\s\-_:]*/i, '' ) .replace( /[^a-z0-9]/g, '' ); } function isOperational(status){ const state = String(status || '') .toLowerCase(); return( state === 'operational' || state === 'up' || state === 'resolved' ); } function uptimeClass(value){ if( value === null || value === undefined || isNaN(value) ){ return 'status-na'; } value = Number(value); if(value >= 99.999){ return 'status-perfect'; }
if(value >= 99.90){ return 'status-good'; }
if(value >= 99){ return 'status-warning'; }
return 'status-bad';
}
function percentage(value){
if( value === null || value === undefined || isNaN(value) ){ return '--.--%'; }
return Number(value) .toFixed(2) + '%';
}
function displayDate(date){
return date .toLocaleDateString( 'nl-NL', { day:'2-digit', month:'short' } )
.replace('.','')
.toUpperCase();
}
function localDayString(date){
const year = date.getFullYear();
const month = String( date.getMonth() + 1 ).padStart(2,'0');
const day = String( date.getDate() ).padStart(2,'0');
return( year + '-' + month + '-' + day );
}
/* ========================================================== SINCE LAUNCH / 30 DAYS ========================================================== */
function updatePeriodLabel(){
const now = new Date();
const elapsedDays =
( now.getTime() - LAUNCH_DATE.getTime() ) / 86400000;
document.getElementById( 'oil4-period-label' ).textContent =
elapsedDays >= 30
? '30 DAYS'
: 'SINCE LAUNCH';
}
/* ========================================================== GAUGE ========================================================== */
function setGauge(value){
const gauge = document.getElementById( 'oil4-gauge-progress' );
gauge.classList.remove( 'status-perfect', 'status-good', 'status-warning', 'status-bad' );
if( value === null || isNaN(value) ){
gauge.style.strokeDashoffset = 553;
return;
}
const p = clamp( Number(value), 0, 100 );
gauge.style.strokeDashoffset =
553 -
( p / 100 ) * 553;
gauge.classList.add( uptimeClass(p) );
}
/* ========================================================== BETTER STACK RESOURCES ========================================================== */
function getResources(json){
if( !json || !Array.isArray(json.included) ){
return [];
}
return json.included
.filter( function(item){
return( item && item.type === 'status_page_resource' && item.attributes );
} )
.map( function(item){
const a = item.attributes;
return{
id:item.id,
name: a.public_name || '',
status: a.status || 'not_monitored',
availability: normalizeAvailability( a.availability ),
history: Array.isArray( a.status_history ) ? a.status_history : []
};
} );
}
/* ========================================================== SERVICE MATCHING ========================================================== */
function findResource( resources, service ){
const wanted = normalizeName( service.key );
/* * Eerst exacte match. */
let resource = resources.find( function(item){
return( normalizeName( item.name ) === wanted );
} );
if(resource){ return resource; }
/* * Daarna bijvoorbeeld: * * Oil4 Web * Oil4 - Web * Oil4 Web Server */
resource = resources.find( function(item){
const name = normalizeName( item.name );
return( name.includes( wanted ) );
} );
return resource || null;
}
/* ========================================================== SERVICES RENDEREN ========================================================== */
function renderServices(resources){
const container = document.getElementById( 'oil4-services-list' );
container.innerHTML = '';
const matched = [];
WANTED_SERVICES.forEach( function(service){
const resource = findResource( resources, service );
matched.push({ service:service, resource:resource });
const row = document.createElement( 'div' );
/* * Alleen expliciete downtime/degraded * wordt als probleem weergegeven. * * Niet gevonden = UNKNOWN, * dus niet automatisch OFFLINE. */
let status = resource ? resource.status : 'unknown';
let availability = resource ? resource.availability : null;
let online = resource ? isOperational(status) : null;
let cssClass;
if(online === false){
cssClass = 'status-bad';
} else if( availability !== null ){
cssClass = uptimeClass( availability );
} else if( online === true ){
cssClass = 'status-perfect';
} else{
cssClass = 'status-na';
}
row.className = 'oil4-service-row ' + cssClass;
let barWidth = 0;
if(online === false){
barWidth = 0;
} else if( availability !== null ){
barWidth = availability;
} else if( online === true ){
barWidth = 100;
}
let label;
/* * Gebruiker wilde rechts: * ONLINE / OFFLINE. */
if(online === true){
label = 'ONLINE';
} else if(online === false){
label = 'OFFLINE';
} else{
label = '---';
}
row.innerHTML =
'
'' +
'' + service.label + '' +
'
' +
'
'' +
'
' +
'
label +
'
';
container.appendChild( row );
} );
return matched;
}
/* ========================================================== DAG-UPTIME ========================================================== */
function calculateDayUptime( matchedResources, date ){
const day = localDayString(date);
const now = new Date();
const isToday = localDayString(now) === day;
let elapsedSeconds;
if(isToday){
const start = new Date(date);
start.setHours( 0,0,0,0 );
elapsedSeconds =
( now.getTime() - start.getTime() ) / 1000;
} else{
elapsedSeconds = 86400;
}
elapsedSeconds = Math.max( elapsedSeconds, 1 );
const uptimes = [];
matchedResources.forEach( function(match){
const resource = match.resource;
if(!resource){ return; }
const record = resource.history.find( function(entry){
return( String( entry.day || '' ) .substring(0,10) === day );
} );
if(!record){ return; }
const downtime = parseFloat( record.downtime_duration || 0 );
/* * Per service: * * uptime = * actieve seconden - downtime. */
const uptime =
( ( elapsedSeconds - downtime ) / elapsedSeconds ) * 100;
uptimes.push( clamp( uptime, 0, 100 ) );
} );
if(!uptimes.length){
return null;
}
/* * Voor totale infrastructuur nemen we * de slechtste service van die dag. * * Daarmee wordt een storing niet * weggemiddeld. */
return Math.min.apply( null, uptimes );
}
/* ========================================================== HISTORY ========================================================== */
function renderHistory( matchedResources ){
const container = document.getElementById( 'oil4-history' );
container.innerHTML = '';
const today = new Date();
today.setHours( 0,0,0,0 );
const launch = new Date( LAUNCH_DATE );
launch.setHours( 0,0,0,0 );
const values = [];
for( let offset = 13; offset >= 0; offset-- ){
const date = new Date(today);
date.setDate( date.getDate() - offset );
const beforeLaunch = date < launch; let uptime = null; if(!beforeLaunch){ uptime = calculateDayUptime( matchedResources, date ); } /* * Vandaag kan Better Stack vlak na * livegang nog geen history-record * hebben. * * Als alle gematchte services nu * operational zijn, tonen we voor * VANDAAG 100%. */ if( offset === 0 && uptime === null ){ const realResources = matchedResources .map( item => item.resource ) .filter(Boolean);
if( realResources.length && realResources.every( resource => isOperational( resource.status ) ) ){
uptime = 100;
}
}
if( !beforeLaunch && uptime !== null ){
values.push({ date:date, value:uptime });
}
const element = document.createElement( 'div' );
let cssClass;
if(beforeLaunch){
cssClass = 'status-na';
} else if( uptime === null ){
cssClass = 'status-na';
} else{
cssClass = uptimeClass( uptime );
}
element.className = 'oil4-day ' + cssClass;
if(offset === 0){
element.classList.add( 'today' );
}
let fillHeight;
if( beforeLaunch || uptime === null ){
fillHeight = 12;
} else{
/* * 99.9% moet visueel nog steeds * bijna vol zijn. */
fillHeight = Math.max( 15, uptime );
}
const uptimeText =
beforeLaunch ? 'N/A'
: uptime === null ? '--'
: percentage( uptime );
const label =
offset === 0 ? 'VANDAAG' : displayDate(date);
element.innerHTML =
'
'
' +
'
' +
'
' +
'
';
container.appendChild( element );
}
return values;
}
/* ========================================================== GROTE UPTIME ========================================================== */
function calculateOverall( historyValues, matchedResources ){
const now = new Date();
const daysSinceLaunch =
( now.getTime() - LAUNCH_DATE.getTime() ) / 86400000;
const maxDays = daysSinceLaunch >= 30 ? 30 : 30;
/* * We gebruiken echte historische * daggegevens wanneer beschikbaar. */
const validHistory = historyValues .slice( -maxDays );
if(validHistory.length){
let total = 0;
validHistory.forEach( item => {
total += item.value;
} );
return( total / validHistory.length );
}
/* * Dag 1: * history kan nog leeg zijn. * * Dan availability gebruiken. */
const availabilities =
matchedResources
.map( item => item.resource ? item.resource.availability : null )
.filter( value => value !== null && !isNaN(value) );
if(availabilities.length){
return Math.min.apply( null, availabilities );
}
/* * Zijn alle services operationeel, * maar heeft Better Stack nog geen * availability/history opgebouwd? * * Dan is vandaag vanaf launch 100%. */
const actualResources =
matchedResources
.map( item => item.resource )
.filter(Boolean);
if( actualResources.length && actualResources.every( resource => isOperational( resource.status ) ) ){
return 100;
}
return null;
}
/* ========================================================== MASTER STATUS ========================================================== */
function renderMasterStatus( json, matchedResources ){
const master = document.getElementById( 'oil4-master-status' );
const text = document.getElementById( 'oil4-master-text' );
const meter = document.getElementById( 'oil4-meter-online' );
/* * Better Stack heeft zelf ook een * aggregate_state op de statuspagina. */
const aggregateState =
json && json.data && json.data.attributes
? String( json.data.attributes .aggregate_state || '' ).toLowerCase()
: '';
const resources =
matchedResources
.map( item => item.resource )
.filter(Boolean);
let operational;
if(aggregateState){
operational = aggregateState === 'operational';
} else if(resources.length){
operational = resources.every( resource => isOperational( resource.status ) );
} else{
operational = null;
}
master.classList.remove( 'loading', 'operational', 'issue' );
meter.classList.remove( 'offline' );
if(operational === true){
master.classList.add( 'operational' );
text.textContent = 'ALL SYSTEMS OPERATIONAL';
meter.innerHTML = ' ONLINE';
} else if(operational === false){
master.classList.add( 'issue' );
text.textContent = 'SYSTEM ALERT';
meter.classList.add( 'offline' );
meter.innerHTML = ' ALERT';
} else{
text.textContent = 'STATUS UNKNOWN';
meter.innerHTML = ' CHECKING';
}
}
/* ========================================================== LAST UPDATE ========================================================== */
function updateClock(){
const now = new Date();
const date = now.toLocaleDateString( 'nl-NL', { day:'2-digit', month:'short', year:'numeric' } );
const time = now.toLocaleTimeString( 'nl-NL', { hour:'2-digit', minute:'2-digit', second:'2-digit' } );
document.getElementById( 'oil4-last-update' ).textContent =
'LAST UPDATE: ' + date.toUpperCase() + ' · ' + time;
}
/* ========================================================== LOAD STATUS ========================================================== */
async function loadOil4Status(){
try{
const response = await fetch( STATUS_URL, { cache:'no-store' } );
if(!response.ok){
throw new Error( 'HTTP ' + response.status );
}
const json = await response.json();
/* * Juiste Better Stack structuur: * * included[] * type=status_page_resource * attributes.public_name * attributes.status * attributes.availability * attributes.status_history */
const resources = getResources( json );
const matchedResources = renderServices( resources );
renderMasterStatus( json, matchedResources );
const historyValues = renderHistory( matchedResources );
const overall = calculateOverall( historyValues, matchedResources );
document.getElementById( 'oil4-main-uptime' ).textContent =
overall !== null ? percentage(overall) : '--.--%';
setGauge( overall );
updatePeriodLabel();
updateClock();
} catch(error){
console.error( 'Oil4 status error:', error );
document.getElementById( 'oil4-master-text' ).textContent = 'STATUS FEED OFFLINE';
const master = document.getElementById( 'oil4-master-status' );
master.classList.remove( 'operational' );
master.classList.add( 'issue' );
const meter = document.getElementById( 'oil4-meter-online' );
meter.classList.add( 'offline' );
meter.innerHTML = ' FEED OFFLINE';
document.getElementById( 'oil4-main-uptime' ).textContent = '--.--%';
setGauge(null);
}
}
/* ========================================================== START ========================================================== */
updatePeriodLabel();
loadOil4Status();
setInterval( loadOil4Status, REFRESH_INTERVAL );
})();
Controleer direct uw domeinnaam en registreer eenvoudig online.



