CSS3 box shadow en Internet explorer <9

Nu CSS3 steeds meer onderdeel wordt van het dagelijks leven blijf je altijd weer met Internet explorer zitten. Alle meestgebruikte versies ondersteunen een hoop leuke CSS3 zaken niet. Vandaag was mijn irritatiepuntje de box shadow. Ik wilde deze met zo min mogelijk moeite werkend krijgen in IE zonder allerlei ingrepen. Nu zijn op zich de meeste zaken wel mogelijk zoals positieve, of negatieve offsets door middel van Microsoft filters. Alleen ik wilde een drop shadow langs alle kanten. Dit leek me zo voor de hand liggend maar het heeft me toch even gekost voor ik enige zinnige implementaties en voorbeelden hiervan had gevonden.

Ik heb voor het gemak even 3 heldere voorbeelden van drop shadows uiteen gezet met CSS code erbij (-webkit, -moz, CSS3 tag zelf en IE alternatief).

Resultaat in Internet explorer 8

Het resultaat in Firefox

Klik hier om de demo te bekijken

Een stap verder

Er zijn nog leukere mogelijkheden maar die vergen iets meer verdieping. Zo kun je bijvoorbeeld met een extra div voor de shadow om je primaire div heen ook nog gekkere dingen doen. Op css-tricks.com staat dit heel helder uitgelegd.

Office 365: Shared mailbox license required

Als Office 365 fans hebben wij de laatste tijd al een hoop gespeeld met de configuratie. Een probleem wat terug blijft komen (en ook erg veel terug te vinden is op het internet) is de vreemde werking van shared mailboxes in combinatie met licenties. De documentatie van Microsoft geeft op meerdere plaatsen zeer helder aan dat een shared mailbox geen licentie nodig heeft. Alleen gebruikers die deze mailbox willen openen moeten een licentie hebben (en mogen geen kiosk-account hebben).

Wat gaat er mis?

Stel je beschikt over een standaard P1 account en je maakt via de powershell een shared mailbox aan. Het lijkt een redelijke tijd goed te gaan maar ergens gaat het bij een hoop gebruikers fout als ze via de OWA proberen de mailbox te benaderen. Je krijgt dan een error ivm. te weinig toegekende licenties. Het rare is sowieso dat hij wel werkt via bijvoorbeeld Outlook 2010 en mails komen er ook gewoon in.

Na gisteren een ruim uur met een zeer vriendelijke medewerker van Microsoft dit probleem te onderzoeken heb ik zojuist als test een gedeelde mailbox opnieuw aangemaakt. Eerder had ik namelijk een beetje soep gemaakt van de mailboxen door ze ook als een user via het Office 365 admin panel aan te maken.

Mogelijke oorzaken

Omdat het via Outlook wel werkt maar via de OWA niet krijg je al vraagtekens. Wie heeft er gelijk en via welke route gaat er gewoon iets mis in het bepalen van licenties. Mijn eerste idee zou zijn dat de OWA een onjuiste manier gebruikt om de licenties te controleren. Waarom anders zouden er zoveel mensen zijn met dit probleem en er geen concrete oplossingen zijn nog. Het lijkt meer een bug dan een echt licentieprobleem te zijn. Daar de Microsoft medewerkers al enkele keren tussen neus en lippen hebben aangegeven dat zij denken dat Office 365 te snel gelanceerd is en nog best wat kinderziektes bevat ga je nog meer in deze richting neigen. Maar tot Microsoft een oplossing heeft wil je natuurlijk nadenken hoe dit probleem mogelijk kan worden omzeild. Enkele theorieen over waarom deze licentieproblemen getriggerd worden zijn:

  • P1 licenties hebben geen security groups (zoals in de E licenties wel het geval is)
    Als hier de oorzaak zit kan het nog wel eens lastig worden dit ooit werkend te krijgen

  • Standaard krijgt een shared mailbox normale quotas mee terwijl hij licentievrij maar 5 GB mag zijn
    Zou eenvoudig oplosbaar moeten zijn maar denk niet dat dit het probleem geeft.

  • Standaard wordt er met het maken van een mailbox ook een useraccount gemaakt in het Office365 panel
    Wat lastiger verhaal maar zou wel logischer zijn inzake het probleem via OWA. OWA loopt over de “office365 lagen” terwijl je lokale Outlook direct op Exchange rechten niveau werkt

Oplossingen?

Nog niet echt al denk ik ook dat dit meer een applicatie probleem is dan een configuratieprobleem aan de gebruikerskant. Ik zal de komende tijd in iedere geval alles kritisch in de gaten houden en nog wat tests uitvoeren en mocht het probleem zich niet meer voordoen bij specifieke configuraties dan zal ik hier zeker een nieuwe blogpost aan wijden.

 

WordPress style save confirmation

WordPress heeft bij het bewerken of aanmaken van een nieuwe blogpost een melding die je om bevestiging vraagt als je probeert de pagina te verlaten zonder iets op te slaan. Nooit echt bewust over nagedacht maar leek me een leuke toevoeging qua user experience in een nieuw project. Even een beetje nagedacht hoe ik dit in mijn Jquery wereld kon “opbergen” zonder dat het in de weg zou zitten en kwam met de volgende oplossing;

// Set the default state to false
jQuery.data(document.body, 'confirmationPrompt', false);

// On a keypress in any form field set confirmation to true
$('input,textarea').keypress(function() {
   jQuery.data(document.body, 'confirmationPrompt', true);
});

// On change of a select or any other form element (like radio buttons etc)
// Set confirmation to true
$('input,select').change(function() {
    jQuery.data(document.body, 'confirmationPrompt', true);
});

// On any form submit set confirmation to false
$('form').submit(function() {
    jQuery.data(document.body, 'confirmationPrompt', false);
});

// Check if confirmation is needed before unloading
window.onbeforeunload = function(){
    if(jQuery.data(document.body, 'confirmationPrompt')){
        return 'Are you sure?';
    }
};

Dit dekt op zich aardig de lading zo. De reden dat ik jquery.data() gebruik en niet gewoon een losse variabel is dat ik op deze manier ook vanuit andere functies de confirmationPrompt var op false kan zetten. Bijvoorbeeld als je sommige forms middels een AJAX call opslaat waardoor er geen formele form submit voorbij komt.

Zend Form security (basics)

Ook bij een “gesloten” applicatie kun je nooit teveel doen aan de beveiliging van je formulieren. Voor een “standaard” omgeving wil je in iedere geval basisbescherming opzetten tegen;

  • Formulier spam
  • Fake/overmatige form posts
  • Ongewenste gegevens

Met Zend Framework heb je op zich al best wat leuke mogelijkheden tot je beschikking voor het valideren en filteren van inputvelden en een stukje bescherming tegen CSRF.

Formulier spam

Voor een eenvoudige site zal een spammer niet veel moeite doen. Enige wat je wilt is een drempel die het voor “standaardscripts” onmogelijk maakt je systeem te vervuilen en tegelijkertijd niet teveel werk is om te implementeren. Een mogelijkheid is het toevoegen van een veld wat je met CSS (of JavaScript) verbergt voor normale gebruikers en wat “false” is als deze een waarde bevat. Een normale gebruiker die geen CSS en JavaScript heeft aan staan is zeldzaam maar mocht die toch voorkomen dan kun je die eventueel met een label nog informeren over het feit dat dit een veld is speciaal om spambots uit te sluiten.

Fake/overmatige form posts

Zend_Form_Element_Hash biedt hiervoor op zich in basis een goede bescherming tegen. Bij het aanmaken van je form neem je een veld op met het type “hash”. Dit veld kun je van parameters voorzien zoals een timeout etc. Bij het aanmaken van het form maakt Zend een session aan met deze hash erin. Bij de post van het form wordt deze gevalideerd tegen de hash. Als hij verlopen is geeft de form isValid false terug. Hier zit wel gelijk een “let op!” momentje in; als je in je structuur ergens de ongelukkige setup hebt waarbij het form meerdere keren gevalideerd wordt zal deze bij de 2e ronde false geven op deze hash.

Hieronder een simpele setup voor dit element in je form:

$this->addElement('hash', 'csrf_hash', array(
    'salt' => 'justSomeRandomSalt',
    'timeout' => 600,
));

ps. de documentatie op de Zend Framework website is niet erg diepgaand op dit vlak. Als je in de broncode van de Form/Element/Hash.php kijkt zie je dat er meer parameters zijn die je mee kunt geven.

  • setSalt($salt)
    String met salt. Geef je niets mee dan gebruikt hij standaard de string “salt”
  • setSession($session)
    Zend_Session_Namespace $session als je zelf een session wilt meegeven.
  • setTimeout($ttl)
    Int met timeout welke standaard op 300 staat.

Ongewenste gegevens

Hoe ver je hiermee gaat hangt een beetje van de aard van de data af, de plek waar het form zit (publiek of besloten) en of de data bijvoorbeeld naar een database gaat of alleen gemaild wordt naar een persoon. Tevens laat ik hierin de beveiliging van de opslag, verzending of wat dan ook van de data buiten wegen. Het gaat me nu even puur om de formulier-afhandeling.

Met Zend_Filter en Zend_Validator kun je krachtige combinaties maken welke de data strippen op alleen het nodige na en het resultaat hiervan valideren. Stel je hebt een select veld:


$this->addElement('select', 'is_lovingchocolate', array(
    'label' => 'Do you love chocolate?',
    'multiOptions' => array(
        1 => 'Yes',
        0 => 'No',
    ),
    'filters' => array('int'),
));

Wat je hiermee doet is in iedere geval gelijk de formulierwaarde die terugkomt met de POST typecasten naar INT.  Met de verschillende Zend_Filter classes kun je op die manier al heel veel ellende tegenhouden. Als je ingewikkeldere data-patronen hebt kun je ervoor kiezen met eenvoudige Zend_Filters alle ongewenste data eruit te halen om daarna met Zend_Validate_Regex de data tegen een hele strict patroon te matchen.

Een voorbeeld hiervan:


$this->addElement('text', 'zipcode', array(
'label' => 'Zipcode (Dutch notation)',
'required' => true,
'maxlength' => 7,
'validators' => array(
    array('NotEmpty', true),
    array(
        'regex', false, array('/^[0-9]{4} [A-Z]{2}$/',
        'messages' => array('regexNotMatch' => 'Incorrect zipcode notation. Should look like 2222 AA.'))
    ),
),
'filters' => array('StripTags', 'stringToUpper'),
));

Wat we doen met de filters is alles eruit halen wat we nu even niet willen en gelijk de letter naar hoofdletters converteren voor een uniforme dataopslag later. Na deze stap valideren we het resultaat met een reguliere expressie voor de postcode. Even los van het feit of deze expressie aansluit bij jouw idee van een goede postcode maar denk dat het idee wel helder is zo.

Office 365: Retention policy wijzigen

Retention policy is een hele coole feature in Exchange waarmee je e-mails en complete mappen een retentie periode kan geven. Stel je hebt een project wat nu loopt tot eind deze maand dan zou je er bijvoorbeeld voor kunnen kiezen om de documentatie van dit project over 2 jaar na nu automatisch te laten verwijderen.

Soorten retention tags

Standaard krijgt iedere mail de “Default Policy Tag”, daarnaast zijn er “Retention Policy Tags” die standaard op mappen zoals je inbox, prullenbank etc van toepassing zijn, als laatste zijn er de “Personal Tags” die een gebruiker zelf kan maken. Via de Powershell kun je van diverse tags de eigenschappen instellen. De onderstaande diagram van de Microsoft site geeft wel een aardig beeld van de verschillende tags en hun rol in het gehele plaatje:

Bron: http://technet.microsoft.com/en-us/library/dd297955.aspx

De tags tweaken

Standaard staat bijvoorbeeld de tag voor de prullenbak op iets van 30 dagen. Superleuk voor je hotmail account maar niet voor een productieomgeving in een bedrijf (of in ons bedrijf in iedere geval). Wil je dit wijzigen dan moet je even inloggen op de powershell. Met het volgende commando haal je de huidige tag informatie op:

get-RetentionPolicyTag "deleted items" | fl name,type,AgelimitForRetention,RetentionAction

Als je deze nu bijvoorbeeld wilt wijzigen in 5 jaar dan kun je dit doen met het volgende commando:

set-RetentionPolicyTag "deleted items" -AgeLimitForRetention 1825

De wijzigingen zullen in de loop van de komende uren bij alle gebruikers zichtbaar worden via de Outlook Web Access en de eventuele lokale Office installatie. Dit komt omdat het hele retention policy tag deel in handen is van de “Managed Folder Assistant”. Dit is een mailbox-hulpje die om de zoveel tijd de mailboxen naloopt en alle retention policies naloopt, bijstelt etc.

Op vakantie en nu?

Stel je hebt een policy die redelijk strict is (bijvoorbeeld mails van organisatie X of box Y max 14 dagen bewaren) en je bent een maand op vakantie dan wil je natuurlijk dat deze fanatieke mailboxhulp even rustig blijft en niet mails gaat lopen opruimen voor je. Hierin is gelukkig voorzien al is dit op dit moment niet mogelijk om door de gebruiker zelf in te stellen. Je zult dus als admin zelf via de commandline dit moeten plaatsen.

Set-Mailbox <name> -RetentionHoldEnabled $true

En om hem weer uit te schakelen:

Set-Mailbox <name> -RetentionHoldEnabled $false

Om het nog informatiever voor de gebruiker (en jezelf te houden) kun je ook nog een comment toevoegen aan de retention hold:

Set-Mailbox <name> -RetentionHoldEnabled $true -RetentionComment <comment>

Jquery fadeIn loop (supersimpel)

Wilde net even twee blokken met tekst in elkaar laten overlopen. Leek me overkill hiervoor een cycle plugin te gebruiken dus ging even kijken wat voor leuks ik nog niet had toegepast/ontdekt in Jquery. Nu blijkt dat je met delay() functie in combi met fadeIn/out erg leuke dingen kunt doen.

HTML:


<div id="blockHolder">
    <div id="block1">Tekst 1</div>
    <div id="block2">Tekst 2</div>
</div>

CSS:


#blockHolder {
    width: 100px;
    height: 200px;
    border: 1px solid red;
    position: relative;
}

#block1,
#block2 {
    background-color: white;
    position: absolute;
    left: 0;
    top: 0;
}

Jquery code:


function fadeLoop(){
    $('#block1').fadeIn().delay(3000).fadeOut('slow', fadeLoop).delay(3000);
}

$(document).ready(function() {
    fadeLoop();
});

Op zich redelijk basic maar werkt wel leuk zo. Wat de fadeLoop() nu doet is eigenlijk #block1 transparant maken, 3 seconde wachten, weer zichtbaar maken, 3 seconde wachten en weer zichzelf aanroepen voor een herhaling. Dit werkt prima met blokken die over elkaar gepositioneerd staan via CSS en waarbij de voorste transparant/niet-transparant wordt waardoor de achterste zichtbaar wordt.