server/src/app/Http/Controllers/Api/DateStatsController.php
author ymh <ymh.work@gmail.com>
Fri, 30 Sep 2016 00:43:04 +0200
changeset 307 07b44a378ad8
child 375 145561ff51ff
permissions -rw-r--r--
Add the datestats api

<?php

namespace CorpusParole\Http\Controllers\Api;

// use CorpusParole\Http\Requests;
use Illuminate\Http\Request;
use Log;

use CorpusParole\Libraries\Sparql\SparqlClient;

use CorpusParole\Http\Controllers\Controller;


class DateStatsController extends Controller
{
    private $sparqlClient = null;

    public function __construct(SparqlClient $sparqlClient) {
        $this->sparqlClient = $sparqlClient;
    }

    /**
     * Display the specified resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $query =  preg_replace('/\s+/', ' ', "SELECT (?d as ?date) (COUNT(?d) AS ?count)
            WHERE {
                ?_ a <http://www.europeana.eu/schemas/edm/ProvidedCHO>.
                ?_ <http://purl.org/dc/terms/created> ?d
            }
            GROUP BY ?d
            ORDER BY ?d");

        $res = $this->sparqlClient->query($query);

        $dates = [];

        foreach ($res as $row) {

            $count = intval($row->count->getValue());
            $date = $row->date;
            $dateType = $date->getDatatypeUri();

            $processedDates = [];
            if($dateType === "http://purl.org/dc/terms/Period") {
                $processedDates = $this->processPeriod($date->getValue(), $count);
            }
            elseif($dateType === "http://purl.org/dc/terms/W3CDTF") {
                $processedDates = $this->processDate($date->getValue(), $count);
            }

            $dates = array_reduce(array_keys($processedDates), function($datesArray, $item) use ($processedDates) {
                if(!isset($datesArray[$item])) {
                    $datesArray[$item] = 0;
                }
                $datesArray[$item] += $processedDates[$item];
                return $datesArray;
            }, $dates);
        }

        ksort($dates);

        return response()->json(['datestats' => $dates ]);
    }

    private function extractYear($dateStr) {
        if(preg_match("/^\\d{4}$/", $dateStr) === 1) {
            $dateStr = "$dateStr-1-1";
        }
        $date = date_create($dateStr);
        if($date === false ) {
            Log::warning("DateStatsController:extractYear bad format for date $dateStr");
        }
        return $date?$date->format("Y"):false;
    }

    private function processPeriod($periodStr, $count) {
        $start = null;
        $end = null;
        foreach(explode(";", $periodStr) as $elem) {
            $elem = trim($elem);
            if(strpos($elem, 'start=') === 0) {
                $start = intval($this->extractYear(trim(substr($elem, 6))));
                if($start === false) {
                    return [];
                }
            } elseif(strpos($elem, 'end=') === 0) {
                $end = intval($this->extractYear(trim(substr($elem, 4))));
                if($end === false) {
                    return [];
                }
            }
        }

        if(is_null($start) || is_null($end) || $start>$end ) {
            // TODO: log problem
            return [];
        }

        $res = [];
        $mean = (int)($count/($end+1-$start));
        $remains = $count%($end+1-$start);
        for($d=$start; $d<=$end; $d++) {
            $nb = $mean + ((($remains--)>0)?1:0);
            if($nb !== 0) {
                $res[strval($d)] = $nb;
            }
        }

        return $res;
    }

    private function processDate($dateStr, $count) {
        $date = $this->extractYear($dateStr);
        if($date === false)  {
            return [];
        } else {
            return [ $this->extractYear($dateStr) => $count ];
        }
    }


}