Het dode spoor van Wordpress

Door StephanVierkant op vrijdag 4 december 2015 14:58 - Reacties (19)
Categorie: php, Views: 6.563

Ik ben begonnen met programmeren zoals veel programmeurs. Eerst een standaard HTML-template (met animated gifjes, Flash hover buttons, <marquee>, etc.) aanpassen in FrontPage, overstappen naar DreamWeaver en PHP 4 op een site Tripod (van Lycos Inc.). Later stapte ik over naar een shared hosting provider, waar ik het extra dataverkeer dat mijn phpBB-forum trok betaalde per gigabyte. In guldens. Naast het hobbymatige gepuzzel kwamen steeds meer kennissen met de vraag of ik ook een site voor hen wilde maken. Samen met enkele vrienden deden we dat met veel plezier en zo werden mijn kroegbezoeken gefinancierd.

Onder programmeurs werd PHP echter niet als volwaardig gezien. Het blog ‘PHP: a fractal of bad design’ is een klassieker die elke programmeur zou moeten lezen. Inmiddels is er veel veranderd. Veel van de genoemde punten zijn inmiddels opgelost of niet meer relevant. Met de komst van PHP versie 7 worden nog meer zaken verbeterd.

Met de komst van WordPress 3.0 ontwikkelde de blogsoftware zich steeds meer als CMS. Zaken zoals de ‘custom post types’ zorgden voor veel flexibiliteit en de hoeveelheid thema’s, plugins en tutorials groeide razendsnel. Ik stapte af van een eigen gebouwd CMS en de vele statische websites werden steeds dynamischer.

Gemaakt door en voor luie programmeurs

WordPress is langzaam gegroeid van weblog-software naar een CMS met focus op nieuwe functionaliteiten en vlakke leercurve. Dat heeft veel nieuwe functies en veel nieuwe ontwikkelaars gebracht, maar heeft er ook voor gezorgd dat WordPress technisch behoorlijk rammelt. Een (heel) kleine bloemlezing:
  • Er wordt gebruik gemaakt van Global variables. Dit wordt breed gezien als een bad practise: zo maakt het de uitkomst van functies erg onberekenbaar. Voor mij als programmeur is dat echt verschrikkelijk.
  • Ook functienaamgeving is ondoorgrondelijk. Zo heb je ‘the_title()’, dat niets anders doet dan ‘echo get_the_title()’. In combinatie met de global variables die door The Loop worden gebruikt, maakt dit de code slecht leesbaar. Of een functie iets echo’t of returnt is compleet willekeurig. En waarom is er Łberhaupt een functie nodig? Wat is er mis met ‘$post->title’ of ‘$post->getTitle()’?
  • De afhandeling van fouten is nauwelijks mogelijk door de onbegrijpelijke implementatie van WP_Error. Wat is er mis met Exceptions? Eigenlijk is er geen fouthandeling in WordPress: dit moet je zelf inbouwen door functies af te vangen als ze ‘false’ returnen. Het zal niet verbazen dat dit vaak mis gaat: WordPress is gemaakt voor luie programmeurs (die de fouten dus niet goed afvangen) en omdat je bij ‘false’ niet weet of je verzoek mislukt is of het gewoon geen resultaten heeft gevonden.
  • Last but not least: de grote hoeveelheid plugins en thema’s is een sterkte en een zwakte tegelijkertijd. Het aanbod is gigantisch, maar de lage leercurve heeft ook luie programmeurs aangetrokken. De meeste plugins zijn slecht onderhouden en de kwaliteit ervan is soms schandalig laag. De levendige handel in thema’s is een walhalla voor hackers.

PHP als ecosysteem: composer en namespaces

PHP heeft zich de afgelopen jaren flink ontwikkeld. Niet alleen door beetje bij beetje de eerder genoemde ‘designfouten’ te verbeteren, maar de grootste ontwikkeling kwam misschien wel van buitenaf: Composer. Sinds PHP 5.3 namespaces ondersteunt is het uitwisselen van componenten eenvoudiger en de ‘Dependency Manager for PHP’ heeft er voor gezorgd dat programmeurs bibliotheken eenvoudig kunnen binnenhalen. Hiermee is PHP uitgegroeid van scripttaal naar ecosysteem.

Ontwikkelaars hebben dit massaal omarmd. Iedereen snapt dat ‘het wiel opnieuw uitvinden’ geen goed idee is en veel grote softwarepakketten gebruiken composer. Zo worden de componenten uit Symfony in veel grote projecten gebruikt. Met Drupal 8 hebben de ontwikkelaars naar eigen zeggen afscheid genomen van het ‘Not Invented Here’ syndroom.

Helaas staat WordPress op dit vlak compleet stil. WordPress ondersteunt PHP 5.2 nog steeds, terwijl deze versie al lang verouderd is. Er komen al bijna 5 jaar geen security fixes meer voor uit en het gebruik ervan wordt door iedereen sterk ontraden. Dat is ongeveer de Middeleeuwen in ICT-tijd. Deze onnavolgbare focus op het verleden remt de vooruitgang van WordPress.

De toekomst van WordPress

De plugins van WordPress zijn alleen te gebruiken binnen WordPress, terwijl de wereld om WordPress heen steeds meer bezig is met uitwisselbaarheid tussen systemen. Systemen die vroeger concurrenten leken, dragen nu samen bij aan de verbetering van het ecosysteem. Het is maar de vraag of WordPress kan concurreren tegen de rest van de PHP-wereld. Het lijkt er niet op dat WordPress de keuze om composer te gebruiken (op korte termijn) gaat maken. Mijn voorspelling (en ook hoop) is dat steeds meer ontwikkelaars WordPress de rug zullen toekeren en kiezen voor andere pakketten, waarbij templates en ‘business logic’ meer worden gescheiden van de gekozen software. Nu een klantspecifieke plugin ontwikkelen is immers kiezen voor een ‘vendor lock-in’. Daarbij komt dat alle krachtige nieuwe technieken (sass, twig, etc.) lastig zijn te implementeren in WordPress. Een CMS zonder enige vorm van scheiden tussen Model, View en Controller is anno 2015 niet meer serieus te nemen.

Ik ben nogal teleurgesteld in de ontwikkeling van WordPress en mede-oprichter Matt Mullenweg zegt het zelf ook: “We realized that the tech wasn’t going to take us to the next decade.” Het team ontwikkelde een nieuwe interface voor Wordpress.com en bracht deze open source uit. Maar pas na de lancering en bovendien alleen de client side code: de backend draait d.m.v. de plugin Jetpack op de server van Wordpress, waarmee een belangrijk deel van WordPress dus niet meer open source is. Of de backend Łberhaupt open source wordt, is nog maar de vraag: “Asked whether the new interface, dubbed Calypso, would become part of the main open source WordPress project, Mullenweg says he hopes so, but that will depend on what the community wants. There could be some technical challenges involved in integrating the new interface because Calypso isn’t just a visual redesign but a complete technical overhaul.”

De eigenaar van WordPress lijkt ook het geloof in de ontwikkeling van WordPress opgegeven te hebben. “It’s up to the community” is mijn inziens een eufemisme voor ‘zoek het allemaal lekker zelf uit’. Het doet me denken aan wat Google nu met Android doet: steeds meer onderdelen worden uit AOSP gehaald en verdwijnen (closed source) in de Play Store.

Mijn conclusie: Het open source CMS WordPress is op sterven na dood. Gezien het marktaandeel zal het een zeer langzame dood sterven, maar lijkt mij momenteel onvermijdelijk. De eigenaar legt de focus op de (closed source) Wordpress.com, de focus op het verleden (PHP 5.2) remt de ontwikkeling, terwijl de wereld om WordPress heen juist een enorme sprong voorwaarts maakt. Ik ben benieuwd of de ontwikkelaars nog een verrassing uit hun hoge hoed toveren of dat het begin van het einde is ingezet.

LinkedIn authenticatie met Zend en OAuth

Door StephanVierkant op zaterdag 11 juni 2011 13:28 - Reacties (5)
Categorie: php, Views: 3.501

Ik heb lang gezocht naar een goed script om met LinkedIn te kunnen inloggen. Ik kon eigenlijk geen goede scripts vinden. Of dat aan mijn zoekcapaciteiten ligt of aan het aanbod, laat ik even in het midden.

Ik heb uiteindelijk een script kunnen vinden. Het moest nog wat worden aangepast omdat het anderhalf jaar oud was, maar inmiddels werkt het. De site waar ik het vandaan had, is inmiddels offline.

Het script werkt met het OAuth-protocol met het Zend Framework.

Omdat ik zelf ook wat aanpassingen heb gemaakt (niet alleen maar die login via een sessie bewaren, maar ook met een cookie), wil ik het graag met iedereen delen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
*
* @abstract: This Class can be used to Access LinkedIn API using Oauth Authentication Protocol
* @author: Stephan Vierkant (original by Christophe Fiat, FormatiX.EU)
* @version: 0.2 2011-06-11
*
*/

class linkedIn
{
    private $options;
    private $consumer;
    private $client;
    private $token;

    public function __construct($consumerKey, $consumerSecret)
    {
        set_include_path('../' . PATH_SEPARATOR . get_include_path() );

        require_once('Zend/Oauth/Consumer.php');

        $this->options = array(
        'version' => '1.0',
        'siteUrl' =>  'https://api.linkedin.com/uas/oauth',
        'callbackUrl' => 'http://localhost/',
        'requestTokenUrl' => 'https://api.linkedin.com/uas/oauth/requestToken',
        'userAuthorisationUrl' => 'https://api.linkedin.com/uas/oauth/authorize',
        'accessTokenUrl' => 'https://api.linkedin.com/uas/oauth/accessToken',
        'consumerKey' => $consumerKey,
        'consumerSecret' => $consumerSecret
        );

        $this->consumer = new Zend_Oauth_Consumer( $this->options );
    }
    private function setToken($token)
    {
        $_SESSION['ACCESS_TOKEN'] = serialize ( $token );
        
        //set time
        $time = 60 * 60 * 24 * 7;
        setcookie("ACCESS_TOKEN", serialize ( $token ), time()+ $time);
    }
    private function getToken()
    {
        if (isset($_SESSION ['ACCESS_TOKEN']))
        {
            return unserialize($_SESSION ['ACCESS_TOKEN']);
        }
        elseif(isset($_COOKIE['ACCESS_TOKEN']))
        {
            return unserialize(stripslashes($_COOKIE['ACCESS_TOKEN']));
        }
        else
        {
            return false;
        }
    }

    public function connect()
    {
        // Start Session to be able to store Request Token and Access Token
        session_start ();
        
        if ( $this->getToken() == false)
        {
            // We do not have any Access token Yet
            if (! empty ( $_GET ))
            {
                // But We have some parameters passed throw the URL

                // Get the LinkedIn Access Token
                $this->token = $this->consumer->getAccessToken ( $_GET, unserialize ( $_SESSION ['REQUEST_TOKEN'] ) );

                // Store the LinkedIn Access Token
                $this->setToken($this->token);
            }
            else
            {
                //We have Nothing

                // Start Requesting a LinkedIn Request Token
                $this->token = $this->consumer->getRequestToken ();

                // Store the LinkedIn Request Token
                $_SESSION ['REQUEST_TOKEN'] = serialize ( $this->token );
            
                // Redirect the Web User to LinkedIn Authentication  Page
                $this->consumer->redirect ();
            }
        } else {
            //We've already Got a LinkedIn Access Token

            // Restore The LinkedIn Access Token
            $this->token = $this->getToken();
        }

        // Use HTTP Client with built-in OAuth request handling
        $this->client = $this->token->getHttpClient($this->options);
    }

    public function getId()
    {
        // Set LinkedIn URI
        $this->client->setUri('https://api.linkedin.com/v1/people/~:(id)');
        // Set Method (GET, POST or PUT)
        $this->client->setMethod(Zend_Http_Client::GET);
        // Get Request Response
        $response = $this->client->request();

        // Get the XML containing User's Profile
        $content =  $response->getBody();

        // Use simplexml to transform XML to a PHP Object
        $xml = simplexml_load_string($content);

        // Uncomment Following Line To display Simple XML Object Structure
        return $xml->id;
    }

} // Class End



Als je hem wilt gebruiken:

PHP:
1
2
3
4
5
$linkedin = new linkedIn('consumerKey', 'consumerSecret');
$linkedin->connect();

//met dit ID kun je vervolgens verder werken (bijvoorbeeld in je eigen database kijken of deze persoon toegang tot je applicatie heeft)
$linkedin->getID();


To-do:
  • Er is nog geen functie voor het uitloggen (anders dan gewoon de cookie en/of sessie unsetten)
Dit is eigenlijk de eerste keer dat ik een (weliswaar aangepast) script met de wereld deel, dus suggesties/klachten/verzoekjes zijn zeer welkom!

Zonder mod_rewrite toch (seo)vriendelijke url

Door StephanVierkant op maandag 31 mei 2010 22:05 - Reacties (9)
Categorie: php, Views: 5.390

Veel (beginnende) programmeurs stoeien met het probleem van de 'vriendelijke' url. Geen domein.tld/weblog.php?id=1&foo=bar maar gewoon domein.tld/weblog/1/bar

Er zijn verschillende opties:
  • De eerste is lekker gemakkelijk: gebruik Wordpress ;) (of natuurlijk een ander CMS);
  • Een tweede optie is je te verdiepen in mod_rewrite. Google is your friend;
  • Onderstaande optie:
Ik kwam de optie ooit ergens tegen en gebruik hem nog steeds regelmatig. Het is handig voor mensen die geen zin hebben zich te verdiepen in mod_rewrite en toch even snel iets in elkaar willen zetten.

Stap 1: htaccess
Allereerst moet je dit in je .htaccess zetten:

code:
1
Options Indexes FollowSymLinks MultiViews All



Stap 2: variabelen definiŽren
Plaats dit boven iedere pagina waar je het wilt gebruiken:

PHP:
1
list ($id, $foo) = explode("/", substr($_SERVER['PATH_INFO'],1));



Stap 3: use it!
Gemakkelijker kunnen we het niet maken. Gewoon $id en $foo aanroepen!

Eerlijk is eerlijk, het is niet de ideale optie; maar ik wilde hem toch wel even noemen.