Poulegegevens van handbal.nl op eigen website tonen

Voor Westlandia heb ik vorig jaar een koppeling geschreven die competitie gegevens van handbal.nl kan tonen. Voor veel verenigingen is dit een gewenste functionaliteit om te hebben op de eigen site. De afgelopen tijd heb ik regelmatig wat vragen gekregen hoe ik dit op de site van Westlandia voor elkaar heb gekregen.

Als we de huidige site van Handbal.nl analyseren dan zien we op het moment dat we poules en uitslagen bekijken zijn AJAX request als:

http://www.handbal.nl/ajax/competition/show_program/6200

In deze URL zijn twee dynamisch element. Het laatste gedeelte is de poule id. Het ene laatste gedeelte beschrijft de mogelijke onderdelen die je kan ophalen. Dit zijn de mogelijkheden:

  • show_standing | Stand
  • show_program | programma
  • show_result | uitslagen

Met deze kennis kunnen we vrij eenvoudig een simpel script maken om de juiste informatie per poule op te halen. Overigens hebben we bij de site van Westlandia voor iedere team een eigen pagina waar de poule ID geregistreerd staat.


namespace Services\Competition;

/**
* Description of Collector
*
* @author Paul de Raaij <paul@paulderaaij.nl>
*/
class Collector {
const BASE_URL = "http://www.handbal.nl/ajax/competition/";
const CACHE_LIFETIME_MILLISECS = 3000;

private $cachePath = null;

public function __construct() {
      $this->cachePath = JPATH_SITE . '/cache/com_ivejo/competitions/';
}

public function collectRanking($competitionId) {
      return $this->collectDataFromExternalSite(self::BASE_URL . "show_standing/" . $competitionId . "/", $this->generateIdentifier($competitionId, 'show_standing'));
}

public function collectProgram($competitionId) {
      return $this->collectDataFromExternalSite(self::BASE_URL . "show_program/" . $competitionId . "/", $this->generateIdentifier($competitionId, 'show_program'));
}

public function collectResults($competitionId) {
      return $this->collectDataFromExternalSite(self::BASE_URL . "show_result/" . $competitionId . "/", $this->generateIdentifier($competitionId, 'show_result'));
}

private function generateIdentifier($competition, $action) {
      return $action . '_' . $competition;
}

private function collectDataFromExternalSite($url, $identifier) {
      $filename = $this->cachePath . '/' . $identifier . '.chc';

      if ($this->cacheFolderExists()) {
            if (!file_exists($filename) || $this->lastUpdatedDiff($filename) > self::CACHE_LIFETIME_MILLISECS) {
                  $ch = curl_init();
                  curl_setopt($ch, CURLOPT_URL, $url);
                  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                  if (strpos($identifier, 'show_program') !== false) {
                      curl_setopt($ch, CURLOPT_POSTFIELDS, array('date_from' => date("d-m-Y"),
'date_to' => date("d-m-Y", strtotime("+1 year"))));
                  }
                  $returnData = curl_exec($ch);
                  curl_close($ch);
                  $result = $this->formatResultData($returnData, $identifier);

                  if ($result == null) {
                      return file_get_contents($filename);
                  }

                  file_put_contents($filename, $result);
                  return $result;
          }
    }

    return file_get_contents($filename);
}

private function formatResultData($data, $identifier) {
    if (strpos($identifier, 'show_standing') !== false) {
        preg_match_all('/<div id="content_standings_" class="cf clear">.*?<script type="text\/javascript">/s', $data, $matches, PREG_PATTERN_ORDER);
    } else {
        preg_match_all('/<div class="cf clear" id="content_(.*)">.*?<script type="text\/javascript">/s', $data, $matches, PREG_PATTERN_ORDER);
    }

    if (isset($matches[0][0])) {
        $html = strip_tags($matches[0][0], '<table><thead><th><tr><td><div><strong><br>');
    }

    return $html;
}

private function lastUpdatedDiff($path) {
    return time() - filemtime($path);
}

private function cacheFolderExists() {
    if (!is_dir($this->cachePath)) {
        mkdir($this->cachePath, 0644, true);
    }
    return true;
}
}

Om de server van handbal.nl nog wat te sparen heb ik caching ingebouwd die enige tijd de resultaten vasthoud. Mocht de server van handbal.nl plat liggen dan pakken we automatisch het resultaat uit de cache en kunnen wij altijd informatie laten zien.

Overigens zie je dat we de response nog wat strippen van HTML zodat we het netjes kunnen weergeven.

Met behulp van dit script hebben wij op de site van Westlandia een koppeling naar handbal.nl. Pagina’s zoals: http://www.westlandia.nl/component/ivejo/?task=team.dashboard

2 thoughts on “Poulegegevens van handbal.nl op eigen website tonen

  1. Hallo Paul,

    Wij zouden op de website van handbalvereniging Witte Ster ook graag de standen tonen. Er wordt momenteel een nieuwe website gebouwd in Joomla maar het lukt ons niet om bovenstaand script werkend te krijgen. Is het component com_ivejo iets wat je zelf hebt ontwikkeld? Ik heb geprobeerd dit script in een joomla (3.2.1) artikel te plaatsen maar dat werkt niet. Ik ben benieuwd of je ons iets wijzer kunt maken…

  2. Niels,

    Ivejo is een component in ontwikkeling en eigenlijk niet gereed voor publicatie. Ik zal van het weekend het component op github plaatsen zodat je er naar kan kijken.

    Stuur anders een mail naar paul@paulderaaij.nl wat er precies niet lukt. Wellicht kan ik helpen.

Leave a Reply

Your email address will not be published. Required fields are marked *