Categorieën
API PHP

Beschermd: Windfinder API

Deze inhoud is beschermd met een wachtwoord. Voer hieronder je wachtwoord in om het te bekijken:

Categorieën
PHP WordPress

Hoe werkt het WordPress update systeem?

WordPress is uitgerust met een zeer eenvoudig en krachtig update systeem. Dankzij dit systeem kunnen WordPress gebruikers eenvoudig WordPress, plugins en thema’s eenvoudig updaten. Ik als ontwikkelaar was erg benieuwd naar deze opzet van dit systeem. Ik ben daarom de WordPress code ingedoken om de werking van dit systeem te onderzoeken.

Het WordPress update systeem maakt gebruik van een API die op WordPress.org staat. Dankzij deze API is eenvoudig informatie op te vragen over WordPress, plugins en thema’s. Elke WordPress installatie informeert om de 12 uren of er updates beschikbaar zijn via de WordPress.org API. De WordPress.org API kun je benaderen via de volgende URL: http://api.wordpress.org/

Als je de WordPress broncode doorzoekt op deze URL zul je een tiental bestanden vinden waarin hier gebruik van gemaakt wordt. In het bestand wp-includes\update.php is te zien op welke wijze WordPress controleert of er nieuwe versies zijn van WordPress, plugins of thema’s. Ik zal hieronder met enkele code fragmenten laten zien hoe gecontroleerd wordt of er thema update beschikbaar is.

WordPress zal in eerste instantie informatie over de geïnstalleerde WordPress thema’s opvragen met behulp van de get_themes() functie. Vervolgens zal deze informatie met behulp van HTTP POST verzoek worden verstuurd naar de WordPress.org API. Hiervoor wordt gebruik gemaakt van de wp_remote_post() functie die onderdeel is van de WordPress HTTP API. De WordPress.org API zal vervolgens aangeven of er updates beschikbaar zijn voor de geïnstalleerde thema’s.

In onderstaande code fragment is globaal te zien hoe een dergelijk verzoek wordt opgebouwd en uitgevoerd:

$themes = array(
	'twentyten' => array(
		'Name' => 'Twenty Ten' ,
		'Version' => '1.0'
	) ,
	'platform' => array(
		'Name' => 'Platform' ,
		'Version' => '1.0'
	) ,
	'delicate' => array(
		'Name' => 'Delicate' ,
		'Version' => '1.0'
	)
);

$args = array(
	'body' => array('themes' => serialize($themes))
);

$response = wp_remote_post('http://api.wordpress.org/themes/update-check/1.0/', $args);

if(is_wp_error($response)) {
	exit('Sorry, something went wrong.');
}

if(200 != $response['response']['code']) {
	exit('Sorry, something went wrong.');
}

$result = unserialize($response['body']);

Als alles goed gaat dan zal de variabele $result informatie over thema’s bevatten waar updates voor beschikbaar zijn. Hieronder zie je een voorbeeld dump van de $result variabele:

array(3) {
	["twentyten"]=>
	array(3) {
		["new_version"]=>
		string(3) "1.1"
		["url"]=>
		string(44) "http://wordpress.org/extend/themes/twentyten"
		["package"]=>
		string(61) "http://wordpress.org/extend/themes/download/twentyten.1.1.zip"
	}
	["platform"]=>
	array(3) {
		["new_version"]=>
		string(5) "1.3.1"
		["url"]=>
		string(43) "http://wordpress.org/extend/themes/platform"
		["package"]=>
		string(62) "http://wordpress.org/extend/themes/download/platform.1.3.1.zip"
	}
	["delicate"]=>
	array(3) {
		["new_version"]=>
		string(5) "3.4.3"
		["url"]=>
		string(43) "http://wordpress.org/extend/themes/delicate"
		["package"]=>
		string(62) "http://wordpress.org/extend/themes/download/delicate.3.4.3.zip"
	}
}

De WordPress.org API geeft dus aan welke versie nu beschikbaar is en waar deze te vinden is. WordPress zal vervolgens met behulp van de Transient API het updaten van de thema’s kenbaar maken aan de WordPress beheerders. De beheerder krijgen daardoor een melding te zien dat er updates beschikbaar zijn. Zodra de beheerder de update uitvoert zal de package URL gedownload worden en de thema bestanden vervangen worden. Hiervoor gebruikt WordPress onder andere de  Theme_Upgrader PHP klasse.

Categorieën
Geen categorie

OpenOffice Calc cellen samenvoegen met nieuwe lijnen

Voor het importeren van een aantal berichten naar WordPress moest ik een aantal cellen in een Excel document samenvoegen naar 1 cel. De waarden van deze cellen moest onder elkaar komen te staan binnen 1 cel. Om dit te realiseren heb ik gebruik gemaakt van OpenOffice Calc, de gratis opensource variant van Microsoft Excel.

Na een zoektocht op Google naar “openoffice calc concatenate new line” was de oplossing snel gevonden. Veel van deze oplossingen zijn echter beschreven in het Engels, waardoor ze niet direct werken in een Nederlandse OpenOffice installatie. De functienamen moeten namelijk ook vertaald worden naar het Nederlands. Het soms nog een hele uitdaging om de juiste Nederlandse functie naam te vinden.

Op het OpenOffice.org forum was de volgende functie te vinden:

=CONCATENATE(C37;CHAR(13);CHAR(10);C38)

Deze is als volgt te gebruiken in een Nederlandse OpenOffice installatie:

=TEKST.SAMENVOEGEN(A1;TEKEN(13);TEKEN(10);B1;TEKEN(13);TEKEN(10);C1)

TEKEN(13) staat in dit geval voor een Carriage Return (CR), ook wel beter bekend als “\r”. De TEKEN(10) staat voor een Line Feed (LF), ook wel beter bekend als “\n”. De combinatie “\r\n” (CRLF) wordt op Windows omgevingen gebruikt om aan te geven dat er op een nieuwe regel gestart moet worden.

Categorieën
PHP WordPress

WordPress zoeken sorteren op relevantie en datum

De standaard zoekfunctie van WordPress is erg eenvoudig en beperkt. De zoekresultaten zijn standaard gesorteerd op datum. Het is niet mogelijk om deze te sorteren op bijvoorbeeld relevantie. Daarnaast is het ook niet mogelijk om fancy operators te gebruiken in je zoekopdracht zoals we gewend zijn bij andere zoekmachines. Gelukkig zijn er allerlei plugins die de zoekfunctie van WordPress uitbreid.

Ik wilde op een WordPress website de bezoekers de mogelijkheid geven om te sorteren op relevantie of op datum. Om dit mogelijk te maken heb ik ik de Relevanssi plugin van Mikko Saari (twitter: @msaari) geïnstalleerd en de volgende code toegevoegd aan de search.php template.

<?php 

$url = add_query_arg('s', get_search_query(), home_url('/'));

printf(
	__('ordered by %s | %s', 'text_domain') ,
	sprintf('<a href="%s">%s</a>',
		add_query_arg('orderby', 'relevance', $url) ,
		__('relevance', 'text_domain')
	) ,
	sprintf('<a href="%s">%s</a>',
		add_query_arg('orderby', 'post_date', $url) ,
		__('date', 'text_domain')
	)
);

?>
Categorieën
PHP WordPress

WordPress berichten inclusief bijlagen verwijderen

In mijn vorige blog kon je lezen hoe je WordPress berichten kunt verwijderen die geen gekoppelde media (attachments) hebben. In dit bericht laat ik een code snippet zien waarmee je berichten inclusief gekoppelde bijlagen kunt verwijderen. Als je een bericht binnen de WordPress beheerpaneel verwijderd blijven de gekoppelde bijlagen staan. Als je ook de gekoppelde bestanden wilt verwijderen kun je gebruik maken van de volgende code:

$query = new \WP_Query();
$query->query(array(
	'post_type' => 'project' ,
	'tax_query' => array(
		array(
			'taxonomy' => 'phase' ,
			'field' => 'slug' ,
			'terms' => 'test'
		)
	) ,
	'posts_per_page' => -1
));

while($query->have_posts()) {
	$query->the_post();

	$postId = get_the_ID();

	echo $postId, ' - ', get_the_title(), '<br />';

	$attachmentsQuery = new \WP_Query();
	$attachmentsQuery->query(array(
		'post_type' => 'attachment' ,
		'post_status' => 'inherit' ,
		'post_parent' => $postId
	));

	while($attachmentsQuery->have_posts()) {
		$attachmentsQuery->the_post();

		$attachmentId = get_the_ID();

		echo '- ', $attachmentId, ' - ', get_the_title(), '<br />'; 

		$result = wp_delete_attachment($attachmentId, true);
	}

	$result = wp_delete_post($postId, true);
}

Je kunt uiteraard de WP_Query->query() parameters helemaal naar wens aanpassen.

Categorieën
PHP WordPress

Verwijder WordPress berichten zonder bijlagen

Bij Pronamic zetten we regelmatig websites om naar WordPress. We maken hierbij gebruik van verschillende importeer technieken. Helaas gaat er bij het importeren ook wel eens iets fout. Zo gebeurd het soms dat de bijlagen bij een bericht niet goed worden overgenomen. We moeten dan alle berichten zonder gekoppelde bijlagen verwijderen. Binnen het beheerpaneel van WordPress is dit niet eenvoudig te realiseren. Daarom hebben we een simpel scriptje ontwikkeld waarmee we deze berichten kunnen verwijderen.

$query = new WP_Query();
$query->query(array(
	'post_type' => 'post' ,
	'posts_per_page' => -1
));

while($query->have_posts()) {
	$query->the_post();

	$id = get_the_ID();

	$attachmentsQuery = new \WP_Query();
	$attachmentsQuery->query(array(
		'post_type' => 'attachment' ,
		'post_status' => 'inherit' ,
		'post_parent' => $id ,
		'posts_per_page' => -1
	));

	if($attachmentsQuery->post_count == 0) {
		wp_delete_post($id, true);
	}
}
Categorieën
PHP Twinfield

Twinfield usability en API

Sinds een jaar gebruiken we bij Pronamic het online boekhoudsysteem Twinfield. Met dit pakket zou je eenvoudig online je administratie moeten kunnen beheren. In dit bericht zet ik daar mijn vraagtekens bij, is Twinfield wel zo eenvoudig en gebruiksvriendelijk?

Ik moet hierbij vermelden dat ik erg weinig doe met Twinfield. Ik gebruik Twinfield voornamelijk voor het opvragen van facturen en het controleren van betalingen. Toch zie ik enorm veel verbeterpunten bij deze eenvoudige handelingen. In dit bericht kort een aantal verbeterpunten.

Inloggen

Om in Twinfield in te loggen moet je naar de pagina https://login.twinfield.com/ surfen. Ik ken deze URL in principe uit mijn hoofd, maar ik type hem zelden met ‘https’ ervoor. Als je echter naar http://login.twinfield.com/ surft krijg je de melding: “De wachttijd voor de verbinding is verstreken“. Zou het zo lastig zijn om http://login.twinfield.com/ netjes door te linken naar https://login.twinfield.com/?

Zodra je uiteindelijk het inlogformulier voor je hebt begint de voglende uitdaging. Je moet een gebruikersnaam, wachtwoord en een omgeving invoeren. De gebruikersnaam en wachtwoord zijn erg gebruikelijk, maar waar dient ‘omgeving’ voor? Het zal vast een doel hebben binnen Twinfield, maar ik vind het een onnodig extra veld.

Deze problemen zijn in principe eenvoudig te verhelpen door de login URL en de logingegevens op te slaan binnen je webbrowser. De ontwikkelaars van Twinfield zouden dit echter ook kunnen vereenvoudigen. Met de kreet “Snel starten en overal toegankelijk” op hun website zou je dat wel mogen verwachten, want snel Twinfield starten is mij nog niet gelukt ;).

Navigeren

Als ik vervolgens ben ingelogd en een factuur wil bekijken klik ik in het hoofdmenu op het item “Facturatie”. Ik krijg zodra ik met mijn muis over dit item ga keurig een ‘pointer’ cursor te zien. Door de ‘pointer’ cursor krijg ik het idee dat dit item linkt naar een pagina “Facturatie”, maar dit blijkt niet zo te zijn.

Zodra ik op dit item klik opent er niet een nieuwe pagina, maar sluit het zojuist automatische geopende submenu. Dit terwijl het submenu de enige manier is om naar een pagina te navigeren is.

Als je veel met Twinfield werkt zul je wel snel gewend zijn aan het feit dat hoofdmenu items niet bruikbaar zijn. Voor de gebruikers die minder regelmatig met Twinfield werken is dat toch minder gebruiksvriendelijk.

Bladeren

Waar ik me nog het meeste over verbaas is dat je binnen Twinfield niet direct vanuit het hoofdmenu lijsten met gegevens kunt opvragen. Vanuit veel webapplicaties ben ik gewend dat zodra je op een hoofd menu item klikt je direct door gegevens heen kunt bladeren. Zo kun je in WordPress in het hoofdmenu klikken op “Berichten” en krijg je direct de meest recente berichten te zien:

Waarom kan ik binnen Twinfield niet via het hoofdmenu een overzicht met crediteuren, debiteuren, facturen, bankafschriften, etc. tevoorschijn toveren? Data opvragen binnen Twinfield moet blijkbaar beslist via allerlei onhandige zoekformulieren. Zo moet ik voor het bekijken van de laatst verzonden facturen naar “Opvragen” onder het menu item “Facturatie” gaan en vervolgens het volgende formulier invullen:

Als ze nou eens onder het hoofdmenu item “Facturatie” meteen de meest recente facturen weergeven zou me dat enorm veel tijd besparen. Hetzelfde geldt ook voor allerlei andere objecten zoals crediteuren en debiteuren. Eenvoudig een overzicht naar voren halen en daardoor heen bladeren zit er bij Twinfield naar mijn idee niet in.

Permalinks

Permalinks zijn denk ik de basis van elke goede webapplicatie. Alle data binnen een webapplicatie moet naar mijn idee bereikbaar zijn onder een unieke permanente link. Gelukkig beseffen veel ontwikkelaars wereldwijd dit en is data steeds vaker terug te vinden onder een unieke permanente link.

Bij Pronamic werken we met allerlei webapplicaties. Je kunt daarbij denken aan de webapplicaties van 37signals (Basecamp, Highrise, etc.) en het Pronamic intranet met alle klant- en projectdata. Alle data binnen deze webapplicaties zijn via een unieke URL op te vragen. Ik merk dat we deze URL’s intern steeds vaker gebruiken, zo linken we in e-mails, chats en andere applicaties naar gerelateerde data.

Helaas is data binnen Twinfield nog lang niet altijd goed onder een unieke permanente link beschikbaar. Dit terwijl ik juist regelmatig naar administratieve data in Twinfield wil linken. Zo zou ik bij vragen over data binnen Twinfield een collega kunnen mailen met een link naar de betreffende data.

Conclusie

Ik denk dat Twinfield qua usability nog flink aan de weg moeten werken. Administratief gezien zullen bepaalde dingen vast en zeker handig opgezet zijn. Voor iemand die echt eenvoudig en snel zijn administratie wil doen lijkt Twinfield mij minder handig. Ik denk dat voor mensen zoals mij hippen en moderne webapplicaties zoals MoneyBird veel fijner werken.

Gelukkig heeft Twinfield ook een API beschikbaar gesteld. Het is dus mogelijk om Twinfield data via een eigen applicatie op te vragen en gebruiksvriendelijker weer te geven. Ik heb op Google Code: https://code.google.com/p/twinfield/ wat meer informatie over deze API gepubliceerd. Naast dat heb ik ook een aantal experimentele PHP 5.3+ classes ontwikkeld waarmee bepaalde Twinfield data is op te vragen.

Dummy code

<?php

namespace Pronamic\Twinfield;

$twinfieldClient = new TwinfieldClient();

// Inloggen
$result = $twinfieldClient->logon($username, $password, $organisation);

// Kantoren opvragen
$offices = $twinfieldClient->getOffices();

// Zoeken
$finder = $twinfieldClient->getFinder();

$search = new Search();
$search->setType(Search::TYPE_DIMENSION);
$search->setPattern('*');
$search->setField(Search::FIELD_ALL_CODE_OR_NAME);
$search->setFirstRow(1);
$search->setMaxRows(Search::ROWS_ALL);

?>

Ik wil dit te zijner tijd verder gaan ontwikkelen en het opvragen van bepaalde data in Twinfield vereenvoudigen. Wellicht zijn er vervolgens ook mogelijkheden om andere PHP applicaties te koppelen aan Twinfield. Zo is er volgens mij veel interesse in een stabiele Magento Twinfield koppeling.

Categorieën
SEO

Valide HTML, SEO en code / tekst verhouding

Onlangs twitterde ik over de YouTube video “Is HTML validation necessary for ranking?” uit het Google Webmaster Help kanaal. Uit deze video blijkt dat Google eigenlijk helemaal niet naar de correctheid van HTML kijkt.

Collega Martijn Duker reageerde hier op met de volgende tweet:

@remcotolsma Validatie is direct niet van invloed., maar indirect weer wel, schone code is vaak kortere code = snellere laadtijd. #SEO #W3C

Ik denk dat Martijn daarmee de spijker op de kop slaat. Het werken volgens de W3C standaarden kan indirect heel veel invloed hebben op je positie bij zoekmachines. Door volgens de HTML standaarden te werken is je content in veel gevallen beter gestructureerd. Daarnaast is je code vaak ‘schoner’ en daardoor sneller.

Concullega Harmen Visser van TRES internet tweette vervolgens dat er bij schonere code er in verhouding meer content is en dat je juist daarmee goed scoort. In de zoekmachine optimalisatie wereld noemen ze dit ook wel de “Code to Text Ratio”. De “Code to Text Ratio” geeft de verhouding tussen content en code (HTML, CSS, JavaScript, etc.) aan.

@MDuker @remcotolsma Bij schonere code is er in verhouding meer content. Juist dat scoort goed bij Google.

@remcotolsma @mduker Google beoordeelt een pagina oa obv de verhouding content vs. code. Hoe minder code hoe beter de score. #SEO

Het leek mij persoonlijk heel erg onwaarschijnlijk dat juist hierdoor websites hoger scoren. Het aantal HTML elementen die gebruikt worden zouden naar mijn idee namelijk niet invloed moeten hebben op de indxering van een webpagina. Het goed structureren van content kan in sommige gevallen immers zelfs zorgen voor meer code.

Naar aanleiding van de tweet van Harmen ben ik hier even wat dieper ingedoken. Allereerst heb ik de Google Webmaster Help kanaal op YouTube eens doorzocht. Helaas kon daar ik geen video’s vinden over dit onderwerp. Eén video die hier misschien een beetje aan gerelateerd is gaat over witruimte in een webpagina.

Uit deze video blijkt dat extra witruimte eigenlijk geen invloed heeft op je positie bij Google. Kan ik daaruit concluderen dat minder of meer code ook geen invloed heeft?

Op de Wemaster Tools Help Forum van Google zijn gelukkig wel een aantal berichten te vinden gerelateerd aan de “Code to Text Ratio“. In de meeste berichten wordt duidelijk gemaakt dat de code / content verhouding nauwelijks of geen invloed heeft op je positie bij
Google. Eén persoon die stelt zichzelf de volgende vragen:

  • Heb je een tool gezien in de Google Webmaster hulppgromma’s voor de “Code to Text Ratio”?
  • Heb je hier ooit een bericht, waarschuwing en/of melding over gezien in de Google Webmaster hulppgromma’s?
  • Denk je echt dat een pagina met een eenvoudig ontwerp en minimale structuur hoger scoort dan een grotere ingewikkelde pagina met meer code?
  • Is het niet waarschijnlijker dat Google geen of weinig aandacht besteeds aan zulke dingen?

Ik denk dat dit de mensen wel aan het denken zet: de “Code to Text Ratio” daar hecht Google geen waarde aan. Dat een goede “Code to Text Ratio” juist hoog scoort bij Google is naar mijn idee in ieder geval onjuist. Ik ben echter erg benieuwd naar jullie mening over dit onderwerp.

Extra informatie

Categorieën
Linux

CentOS tijd instellen / synchroniseren

Tijd op een server is erg belangrijk, het is heel vervelend als de tijd van een server onjuist is. Ik had onlangs wel te maken met een Linux machine waarop de tijd verkeerd stond. Dit is gelukkig eenvoudig op te lossen door de tijd te synchroniseren met een NTP server.

Om binnen CentOS te controleren of de tijd goed is ingesteld kun je de volgende commando uitvoeren:

[ ~]# date
Fri Mar 18 21:50:43 CET 2011

Hier staat CET voor de tijdzone “Central European Time”, dit is de tijdzone voor de wintertijd. In de zomertijd zal CEST zijn, wat staat voor “Central European Summer Time. Mocht de tijd bij jou niet correct staan dan kun je hier voor NTP installeren. Dit kun je doen door de volgende commando uit te voeren:

[ ~]# yum install ntp

Als het goed is wordt nu NTP geïnstalleerd of krijg je de melding “Nothing to do” als dit pakket al op je machine staan. Vervolgens kun je het volgende commando uitvoeren om de tijd te synchroniseren:

[ ~]# ntpdate pool.ntp.org

Als je de melding krijgt dat de NTP socket al in gebruik is dan is er waarschijnlijk al een NTP proces (daemon) actief. Deze kun je uitschakelen door het volgende commando uit te voeren:

[ ~]# /etc/init.d/ntpd stop

Als het goed moet je vervolgens wel de ntpdate commando kunnen uitvoeren.

[ ~]# ntpdate pool.ntp.org
18 Mar 22:05:57 ntpdate[24291]: adjust time server 204.62.14.98 offset -0.010934 sec

Vervolgens kun je de NTP deamon weer starten door het volgende commando
uit te voeren:

[ ~]# /etc/init.d/ntpd start

Als ik het goed begrepen heb worden processen binnen CentOS niet automatisch gestart. Als je het NTP proces automatisch wilt laten starten dan dien je het volgende commando uit te voeren:

[ ~]# chkconfig ntpd on

Het kan overigens ook zijn dat de tijdzone niet correct staat ingesteld op je machine. Voor het instellen van de tijdzone moet je een symlink maken naar een zoneinfo bestand. Voor de Nederlandse tijdzone zal dat er zo moeten uitzien:

/etc/localtime -> /usr/share/zoneinfo/Europe/Amsterdam

Je kunt deze symlink aanmaken door het voglende commando uit
te voeren:

[ ~]# ln -sf /usr/share/zoneinfo/Europe/Amsterdam /etc/localtime
Categorieën
Geen categorie

Zang verwijderen uit MP3 liedje

Voor de 50e verjaardag van mijn vader hebben we een liedje geschreven op
de melodie van een bestaand liedje. Helaas konden we van dit liedje niet
een karaoke versie vinden. Gelukkig zijn er allerlei programma’s die de
zang uit een liedje kunnen verwijderen.

Voor het verwijderen van de zang heb ik gebruik gemaakt van de
“Vocal Remover” Winamp plugin van Brian Andrews. Zodra je deze plugin activeert kun je procentueel aangeven hoeveel zang er verwijderd moet worden. Voor de beste resultaten zul je hier een beetje mee moeten spelen.

Zodra je plugin heb gedownload en geïnstalleerd kun je de plugin activeren:
“Opties » Voorkeuren…” (sneltoets Ctrl + P) en vervolgens naar
“Plugin-ins » DSP/Effect” en klikken op “AnalogX Vocal Remover [dsp_vr.dll]”.

De plugin werkt helaas niet voor alle liedjes even goed, maar voor een
gratis plugin is het zeker niet verkeerd. Zodra je de plugin goed hebt
afgesteld kun je er voor kiezen het aangepaste liedje op te slaan in een WAV
bestand. Hiervoor ga je naar: “Opties » Voorkeuren…” (sneltoets Ctrl + P)
en vervolgens naar “Plugin-ins » Uitvoer” klikken op “Nullsoft Disk Write v2.14 [out_disk.dll]” en het liedje afspalen.