maandag 23 maart 2015

Weg met de captcha's!

Formulier-spam is al jaren een enorm probleem. Talloze 'robots' speuren het web af naar html-formulieren om die, al of niet voorzien van de nodige links en spamteksen, automatisch te versturen. Webmasters en website-eigenaars hebben er een hekel aan.

Doe je bezoekers geen captcha's aan

Dus gaan webbouwers en programmeurs op zoek naar oplossingen. Heel vaak kiest men dan voor een oplossing zoals een captcha, een methode waarbij de bezoeker op één of andere manier moet aantonen dat hij een echt mens is en geen stukje software. Vaak moet de bezoeker bijvoorbeeld een paar cijfers of letters intoetsen, of een eenvoudig rekensommetje oplossen.

Op zich werkt een captcha prima natuurlijk, maar eigenlijk wil je dat je bezoekers toch niet aandoen? Immers, elke strohalm die je jouw bezoeker in de weg legt om een actie te nemen (in dit geval om een formulier te versturen) is er eentje die de kans vergroot dat de bezoeker afhaakt. En dat is het laatste wat je wil bereiken natuurlijk.

Alternatieve anti-formulierspam zónder de bezoeker lastig te vallen

Ik vond een eenvoudig alternatief voor de captcha. Een anti-spam oplossing waar geen enkele websitebezoeker iets van zal merken. Met een heel klein stukje jQuery zorg je ervoor dat er een automatische 'robot' controle plaats vindt. Het werkt als volgt:

stap 1:
Zorg dat je html-formulier een uniek id krijgt  ( <form id="mijnFormulier" .. )

stap 2:
Voeg dit hele kleine scriptje toe aan je pagina, bijvoorbeeld vlak boven je formulier of in de head van je html-document:

<script>
function pqAntiSpam(){
    jQuery("#formulier").append('<input type="hidden" name="isHuman" value="1"/>');
    return true;
}
</script>

stap 3:
Voeg de volgende onsubmit-opdracht toe aan je form-tag: onsubmit="return pqAntiSpam();"
De html-code van je formulier zou dus kunnen beginnen met:
<form id="mijnFormulier" onsubmit="return pqAntiSpam()" method="post" action="">

stap 4:
De werking van het scriptje is heel simpel: Op het moment dat een menselijke bezoeker het formulier verstuurt wordt er door de jQuery-opdracht een extra (hidden) veld toegevoegd aan het formulier, vlak voordat het formulier wordt verzonden.

stap 5:
Het serverside script (meestal je PHP-script) hoeft nu alleen maar te controleren of de variabele 'isHuman' is ge-POST. Indien de variabele is ge-POST is het formulier dus middels jQuery (javascript) 'behandeld' en dus verstuurd door een mens, en niet door een spam-robot. En vervolgens kan je in je PHP-script dus voorkomen dat het ingevulde formulier wordt verwerkt wanneer het niet door een menselijke actie is verzonden.

--
Ik gebruikte in mijn voorbeeld jQuery code. Uiteraard kan dit ook zonder jQuery worden gerealiseerd, dus puur met javascript. Omdat de jQuery code het kortst is, en vrijwel iedere website tegenwoordig met jQuery 'draait' heb ik voor dit voorbeeld gekozen.


Niet waterdicht, wél een bruikbaar en gebruikersvriendelijk alternatief

Waterdicht? Nee, vast niet. Maar de meeste spammers werken toch écht met robots die geen javascript of jQuery kunnen uitvoeren. Dus ik ga er vanuit dat je hiermee efficiënt veel fornulierspam kunt voorkomen. En je valt je bezoekers er dus helemaal niet mee lastig.

En nog een potentieel nadeel: er zijn gebruikers die javascript op hun computer volledig hebben uitgeschakeld. Ook daar zal het niet zomaar werken. Maar dat zijn er zo weinig dat dat geen probleem zal zijn. En bovendien werken dan de bekende captcha's natuurlijk ook niet..

Nog een laatste opmerking, speciaal voor webmasters en programmeurs: bij veel CMS-systemen (Joomla, WordPress enzovoorts) is het niet heel eenvoudig om in de formulierafhandeling te controleren op de aanwezigheid van de dynamisch toegevoegde POST-variabele. Maar het kán natuurlijk wel, en ik geloof dat je met deze methode een prima oplossing hebt voor de formulierspam, en een in veel gevallen bruikbaar alternatief voor die klant-onvriendelijke captcha's.

 

woensdag 11 februari 2015

case study: warmteklacht.nl

Als PHP-programmeur ben ik breed inzetbaar. Hieronder vindt u een beknopte beschrijving van één van de door mij uitgevoerde opdrachten.

Project: warmteklacht.nl
Opdrachtgever: Lamain Technical Support

Opdracht:
Opdrachtgever wilde een website die als doel heeft te helpen bij het oplossen van storingen aan verwarmingsketels. Moderne verwarmingsketels tonen, wanneer ze in storing zijn gevallen, meestal een specifieke storingscode in het display van de ketel.
Opdrachtgever heeft de meeste van deze storingscodes in kaart gebracht en tevens oplossingen voor de storingen beschreven.
De te bouwen website moest de volgende mogelijkheden bieden:
  • invoeren van een storingscode door de gebruiker, waarna de website direct de oorzaak & oplossing van de storing dient te tonen;
  • Opzoeken van storingscodes door middel van het zoeken door ketelmerken en -types;


Uitvoering:
Ik heb een beheersysteem gebouwd waarin opdrachtgever op een eenvoudige manier merken, keteltypes en storingscodes/oorzaken/oplossingen kan invoeren. Alle gegevens worden in een database opgeslagen.
De front-end van de website biedt op een eenvoudige manier aan de bezoeker de mogelijkheid een storingscode op te zoeken. Wanneer de storing gevonden is ziet de bezoeker de oorzaak en mogelijke oplossing van de storing.
Belangrijk onderdeel van het verdienmodel is het tonen van advertenties op de website. Functionaliteit voor het toevoegen of wijzigen van advertentiecode is daarom ook in het beheersysteem ingebouwd.

Sinds het 'live' gaan in 2013 is onder andere de volgende extra functionaliteit toegevoegd:
  • Er werd een complete webshop gekoppeld aan de website. Deze webshopsoftware is volledig door mij ontwikkeld en aangepast voor deze specifieke opdrachtgever. In die webshop verkoopt opdrachtgever allerlei onderdelen en accessoires op het gebied van (verwarmings-) installatie techniek.
    Indien een gevonden oplossing voor een storing het nodig maakt een onderdeel te vervangen, dan wordt de bezoeker middels een link direct verwezen naar het webshop-artikel om daarmee de storing op te lossen.
  • Wanneer een oplossing van een storing in beeld is, wordt de bezoeker aangeboden om online offerte aan te vragen bij meerdere installateurs in zijn/haar omgeving. Door in een eenvoudig formuliertje enkele gegevens in te vullen ontvangen een geselecteerd aantal installateurs een uitnodiging tot het doen van offerte. Daarbij wordt de installateur al direct op de hoogte gesteld van de aard van de storing zodat hij gericht een aanbieding kan doen.

In een later stadium is een mobiele versie van de website gebouwd die specifiek gericht is op gebruikers van tablets en smartphones.
Bovendien zijn inmiddels een versie voor de Engelse markt en voor de Duitse markt gerealiseerd.

En begin 2015 is een 'overkoepelende' en meertalige website gerealiseer die realtime middels een API gegevens uit de diverse databases opvraagt en presenteert.


zaterdag 13 september 2014

case study: autowasstraten online verkoop

Als PHP-programmeur ben ik breed inzetbaar. Hieronder vindt u een beknopte beschrijving van één van de door mij uitgevoerde opdrachten.

Project: autowasstraten online verkoop
Opdrachtgever: webbio.nl

Opdracht:
Een keten van auto-wasstraten in het westen van het land had al een website. Men wilde echter diverse zaken via internet gaan verkopen:
  • losse wasbeurten
  • abonnementen
  • prepaid saldokaarten
Ook wilde men dat de diverse wasstraat-vestigingen middels eigen software ook abonnementen en prepaid waspassen konden gaan verkopen. Bovendien moest de afhandeling van alle aangekochte producten volledig web-based kunnen worden afgehandeld.
Als laatste moest er een beheersysteem worden gebouwd waarin de eigenaar van de wasstraten het beheer kon voeren over vestigingen, klanten, abonnementen en marketingacties.

Een standaard webshop is niet geschikt voor het verkopen van abonnementen en prepaid saldokaarten. Een maatwerk oplossing moest gebouwd worden.

Uitvoering:
Ik heb bestaande, door mijzelf ontwikkelde webshopsoftware aangepast en sterk uitgebreid zodat het voldoet aan de wensen van de opdrachtgever.

Zo kunnen klanten losse wasbeurten kopen, maar ook abonnementen voor een door de klant zelf te bepalen periode en ingangsdatum. Bovendien kan men online een prepaid waspas aanschaffen, opwaarderen of de transacties op de prepaid kaart bekijken.

De verkochte losse wasbeurten, abonnementen of prepaid waspas worden automatisch direct na ontvangst van de betaling (via iDeal of PayPal kan men betalen) via email uitgeleverd aan de klant. Men ontvangt dan een afhaalbon (pdf) met daarop een unieke afhaalcode, in de vorm van een QR-code. Deze afhaalbon kan de klant printen en meenemen naar de autowasstraat, maar men kan hem ook op de smartphone laten staan.

De medewerker op de wasstraat leest met een barcodescanner de QR-code in, vanaf papier of rechtstreeks vanaf het beeldscherm van de smartphone. De software herkent de gescande afhaalcode en controleert of de code nog geldig is. De medewerker ziet op zijn scherm precies welk product de klant online heeft aangekocht en kan de wasbeurt leveren.

In geval van een prepaid waspas wordt de waarde van een wasbeurt afgeboekt van het pre-paid saldo en ontvangt de klant per email netjes een bevestiging van zijn transactie.
Uiteraard kan de medewerker op de wasstraat zelf ook online prepaid waspassen en abonnementen verkopen.

Aan het eind van de dag worden alle transacties netjes op een dagstaat verzameld.

Voor de eigenaar van de wasstraten heb ik software gebouwd waarmee hij inzicht krijgt in de transacties die hebben plaatsgevonden op de wasstraten. Men kan o.a. resultaten opvragen per periode, per wasstraat of per marketing-actie (mailing). Maar ook het toevoegen/wijzigen/verwijderen van wasstraat-vestigingen en gebruikers is mogelijk gemaakt.

case study: beheer van vaccinatietrajecten

Als PHP-programmeur ben ik breed inzetbaar. Hieronder vindt u een beknopte beschrijving van één van de door mij uitgevoerde opdrachten.


Project: beheer van vaccinatietrajecten
Opdrachtgever: Een opdrachtgever in de medische branche

Opdracht:
Opdrachtgever voert vaccinatie-programma's uit. Voornamelijk op onderwijsinstellingen, maar ook voor particulieren. Denk daarbij aan vaccinatietrajecten voor Hepatitis B of aan vaccinaties voor reizigers naar exotische bestemmingen waarbij vaccinaties aangeraden worden of verplicht zijn.

Een vaccinatietraject bestaat vaak uit een reeks van vaccinaties gedurende een bepaalde periode, gevolgd door bijvoorbeeld een bloedafname om de titerwaarde te kunnen bepalen.

Opdrachtgever hield voorheen alle vaccinatietrajecten bij middels excel-documenten maar wilde een andere, meer werkbare oplossing. Bovendien wilde opdrachtgever dat het verwerken en administreren van uitgevoerde vaccinaties online zou plaatsvinden omdat men erg vaak op locatie de vaccinaties uitvoerde met meerdere gebruikers.

Uitvoering:
Een uitgebreide database met bijbehorend beheersysteem werd door mij ontworpen op basis van de wensen van de opdrachtgever. Zo werd het mogelijk om vaccinatietrajecten te definiëren, klanten en hun eventuele vestigingen in te voeren en te beheren, assistenten en contactpersonen te beheren enzovoorts.

Per klant of vestiging kunnen vaccinatieprojecten worden gekoppeld waaraan dan weer een aantal cliënten kan worden toegevoegd (handmatig of door middel van het importeren van excel-documenten). Uitgevoerde vaccinaties worden automatisch geregistreerd in het systeem waardoor voor alle gebruikers altijd actueel inzicht is wie wanneer en door wie er is gevaccineerd.

Opdrachtgever kan middels managementlijsten inzicht krijgen in de status van vaccinatieprojecten en gebruikt deze gegevens als basis voor zijn facturatie.

De web-applicatie biedt verder mogelijkheden als het versturen van mailings (gepersonaliseerd en indien gewenst met bijlages) naar cliënten, en beschikt over een nieuwsberichten-systeem om gebruikers in informeren, al of niet gepersonaliseerd.



Een complete en uitgebreide web-applicatie is het resultaat. Voor opdrachtgever een aanzienlijke verbetering van de workflow, minder kans op administratieve fouten en daardoor een structureel betere bedrijfsvoering.

case study: klantbeheer voor online taalcursussen

Als PHP-programmeur ben ik breed inzetbaar. Hieronder vindt u een beknopte beschrijving van één van de door mij uitgevoerde opdrachten.


Project: klantbeheer voor online taalcursussen
Opdrachtgever: addisco.nl

Opdracht:
Opdrachtgever is een bedrijf dat talencursussen geeft (Latijn en Grieks).
Men wilde een systeem waarbij het mogelijk werd ook online talencursussen aan te bieden. Men beschikte al over een website en ook de online cursussen waren al gereed voor gebruik. Wat nog ontbrak was een systeem om de toegang tot de online cursussen te beheren.

Uitvoering:
Een web-applicatie werd door mij ontworpen die onder andere de volgende mogelijkheden biedt:
  • Opdrachtgever kan cursussen definiëren, een aanmeldlinks genereren waarmee cursisten zichzelf kunnen aanmelden voor een cursus.
  • Hij kan beheren welke cursisten toegang hebben tot welke online cursussen en gedurende welke periode die toegang geldig is.
  • Cursisten kunnen inloggen om een online-cursus te openen. Er is ervoor gezorgd dat een cursist niet vaker dan 1x tegelijk ingelogd kan zijn en een cursist krijgt alleen toegang binnen de door opdrachtgever gedefinieerde periode.
  • De front-end pagina's voor de cursisten zijn meertalig (Nederlandstalig en Engelstalig).


Met deze web-app heeft opdrachtgever haar dienstenpakket uitgebreid met online cursussen en zijn er mogelijkheden geopend voor verdere uitbreiding van de bedrijfsactiviteiten.

maandag 24 maart 2014

css-tip: steeds de laatste css-versie aanbieden met php

Tijdens het wijzigen van de opmaak van een website zal je als designer geregeld de css-code aanpassen. En je weet ook dat je, om de nieuwe css te laten renderen, de webpagina met de F5-toets (windows) moet verversen. Doe je dat niet, dan gebruikt de browser nog de oude css-code omdat die nog in de cache staat.

Je weet dus ook dat wanneer je je css-bestand gewijzigd hebt en op je webserver geplaatst, dat dan de bezoekers van je website in principe ook niet meteen de nieuwe css-code krijgt, en dus geen bijgewerkte opmaak. En dat is niet wat je wilt natuurlijk.

Er zijn verschillende oplossingen. De meest voor de hand liggende (en beste)  oplossing is om de naam van je css-bestand te wijzigen zodra je wijzigingen in je css-bestand heb aangebracht. De browsercache van de bezoekers kent die nieuwe naam niet en zal dus het nieuwe bestand downloaden en renderen.
Alleen soms is dat een beetje gedoe, zeker als je regelmatig kleine wijzigingen aanbrengt.

Er is een simpel trucje om niet steeds de bestandsnaam te hoeven wijzigen. Wanneer je in je html de aanroep naar het css-bestand uitbreidt met een klein stukje PHP-code dan wordt altijd de meest recente css-versie van de server gehaald en gerenderd.

De oorspronkelijke aanroep is bijvoorbeeld:
<link rel="stylesheet" type="text/css" href="css/mijncss.css" media="screen, projection">

Wijzig deze aanroep door dit kleine stukje code in te voegen: ?v=<?php echo time()?>

De nieuwe aanroep wordt dus:
<link rel="stylesheet" type="text/css" href="css/paqqa2.css?v=<?php echo time()?>" media="screen, projection">

Nu is de url van het css-bestand bij elke pagina-aanroep anders, en dus krijgt de bezoeker elke pagina-aanroep het meest recente css-bestand te zien.

Let op: dit is slechts een trucje wat handig is als je in je 'live' website aan het werken bent en je je bezoekers gelijk het aangepaste css-bestand wil aanbieden. Nadeel is natuurlijk dat bij elke pagina-aanroep het css-bestand geladen moeten worden en dat vertraagt de weergave van je website, en het kost onnodige bandbreedte.

Dus zodra je wijzigingen definitief zijn: wijzig de naam van je css-bestand alsnog daadwerkelijk (en je aanroep in de html natuurlijk ook). Op die manier zal geen enkele gebruiker nog de oude css te zien krijgen.


woensdag 17 oktober 2012

Vraag toestemming voor cookies van Google Analytics

Eenvoudig cookie-toestemmings-script voor Google Analytics

Enorm veel webshops en andere websites maken gebruik van cookies om de website aan te sturen, winkelwagentjes te vullen, enzovoorts. Handige en noodzakelijke cookies dus.
Maar heel veel site gebruiken ook Google Analytics. En de cookies die Google Analytics op de computer van je websitebezoeker installeert, die zijn niet persé noodzakelijk voor het goed functioneren van je website.

Nu is er sinds 5 juni 2012 een wettelijke verplichting in Nederland om bezoekers de keus te geven of ze cookies van onder andere Google Analytics willen accepteren. En die wet verplicht iedere (ja, iedere) website aan de bezoeker expliciet toestemming te vragen voor het plaatsen van die niet-noodzakelijke cookies. Dat geldt dus ook voor jouw website, als je daar Google Analytics op geïnstalleerd hebt.
Je website zal je dus moeten aanpassen om expliciet toestemming te krijgen van je bezoekers voor het plaatsen van de Google Analytics cookies.

Hierbij een oplossing die je simpel in je website kunt toepassen om de toestemming voor de cookies van Google Analytics te regelen.

Met dit script kan de bezoeker van je website eenvoudig aangeven of hij wél of geen toestemming geeft om de niet-essentiële cookies van Google Analytics te accepteren. Google Analytics wordt alleen opgestart indien er wel toestemming is gegeven. De gebruiker kan op ieder moment met 1 klik de cookie-instelling wijzigen.

Het script werkt in principe in alle websites. Dus ook in je Joomla, Wordpress of welk ander CMS je ook gebruikt. En dus ook in VirtueMart en andere webshops!

Het script kan ook simpel worden uitgebreid naar andere niet-persé-noodzakelijke cookies op je website, maar ik denk dat heel veel sites alleen de Google Analytics cookies hoeven te 'regelen'.

 

Downloaden en installeren

Download het volgende bestandje en sla het op in een map op je webserver met de naam 'js' *:
cookie-permissie.js

Vervolgens plak je de volgende code in de head van je webpagina(s), bijvoorbeeld vlak voor de afsluitende </head>-tag:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="js/cookie-permissie.js" type="text/javascript"></script>
<script type="text/javascript">
if (getCookie('_paqqa') == 'allow')
{
  var _gaq = _gaq || []; _
  gaq.push(['_setAccount', 'JOUW-GOOGLE-ID']);
 _gaq.push(['_gat._anonymizeIp']);
 _gaq.push(['_trackPageview']);
 (function()
 {
   var ga = document.createElement('script');
   ga.type = 'text/javascript';
   ga.async = true;
   ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') +      
   '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0];
   s.parentNode.insertBefore(ga, s);
 })();
}
</script>

Let op:
De eerste regel in bovenstaande code is een aanroep naar jQuery. Nu gebruiken veel websites al jQuery en is het dus goed mogelijk dat in de head van jouw website de aanroep naar jQuery al gedaan wordt. Als dat zo is, dan even de jQuery-regel uit bovenstaande code verwijderen. Dat voorkomt conflicten.

(*) In plaats van de map 'js' kan je natuurlijk ook een andere map gebruiken. Zorg dan wel dat je die map-naam in de derde regel van bovenstaande code aanpast.

 

Werkt het?

Als alles goed is ben je nu al bijna klaar. Vul alleen in het bovenstaande script nog even je eigen Google-Analytics-ID in, anders worden je statistieken niet bijgehouden.
Let op: de cookie-instelling bovenin je scherm zie je slechts één keer, namelijk de eerste keer dat je de pagina bezoekt. Zo wordt je bezoeker dus niet bij ieder bezoek lastig gevallen door de opvallende cookie-keuzemogelijkheid bovenin het scherm. Onderaan de webpagina blijft wél altijd de keuzemogelijkheid staan. Precies zoals de Nederlandse wetgever het graag wil dus.

Werkt het niet?

Wanneer je alles goed geïnstalleerd hebt zou je bovenin óf onderin je webpagina's voortaan een mogelijkheid moeten zien om de cookie-instelling te veranderen. Zie je dat niet, dan is er iets nog niet goed gegaan. Als het script niet lijkt te werken controleer dan of je het javascript-bestandje hebt geplaatst in de map 'js'. Als die map nog niet bestaat, moet je die eerst even aanmaken.


Waarom is dit script nou zo handig?

Er zijn online veel vergelijkbare oplossingen te vinden voor de cookie-wetgeving. Veel daarvan hebben het nadeel dat ze, iedere keer als een webpagina wordt geladen, verbinding maken met een andere server dan die van jou, omdat ze daar de scripts vanaf moeten halen. Dat is slecht voor de snelheid van je website. Je hebt bovendien geen invloed op hoe de opmaak van de cookie-venstertjes eruit ziet. En de installatieprocedure is soms nogal ingewikkeld (..). 
Mijn script draait op je eigen webserver, en de opmaak van de vensters kan je 100% zelf instellen. Hetzij met je eigen css-sheet, óf door het aanpassen van de opmaakinstellingen in het script zelf. Lekker snel dus, en lekker makkelijk.


Waarom is dit script nou zo ónhandig?

Het is bekend dat heel veel mensen, als ze de vraag gesteld wordt, géén expliciete toestemming geven voor het plaatsen van niet-essentiële cookies. Meer dan 90% zelfs zou het weigeren. En dat vinden veel webmasters niet leuk omdat ze dan veel minder informatie krijgen van hun Google Analytics account.
Daarom wordt door webmasters vaak een variant gebruikt waarbij de bezoeker van de website wel wordt geïnformeerd over het gebruik van de cookies, maar niet expliciet om toestemming wordt gevraagd.
Mijn script werkt volgens het principe van expliciete toestemming. Met een klein beetje kennis van javascript pas je het echter snel aan naar een versie die werkt volgens het principe van niet-expliciete toestemming.

Disclaimer

Iedere eigenaar van een website is zelf verantwoordelijk voor de inhoud van zijn website. Ik bied deze oplossing voor de cookie-wetgeving aan, maar accepteer geen enkele verantwoordelijkheid voor wat je ermee doet. De software is naar eer en geweten gemaakt en voldoet naar mijn idee aan de nieuwe wetgeving. Maar ik zal nooit en te nimmer aansprakelijkheid accepteren voor welke schade dan ook, ontstaan uit het gebruik van mijn software. "As is", noemen ze dat in goed engels. En voel je volledig vrij de software te gebruiken voor je eigen websites, commercieel of niet.