Skip to content

Instantly share code, notes, and snippets.

@dan2k3k4
Created February 17, 2015 16:55
Show Gist options
  • Save dan2k3k4/025e7965c8e6d9239014 to your computer and use it in GitHub Desktop.
Save dan2k3k4/025e7965c8e6d9239014 to your computer and use it in GitHub Desktop.
// This is the rawData, key'd by date
$dataKey = sha1(serialize($config) . date('d m Y H'));
// testing, no cache
$this->cacheService->removeItem($dataKey);
// Use cacheService
if (!$data = $this->cacheService->getItem($dataKey)) {
$data = $this->weatherService->fetchWeatherData($config);
$data = json_encode($data);
$this->cacheService->setItem($dataKey, $data);
}
return new JsonModel(array_merge(json_decode($data, true), ['test' => 'voilà']));
<?php
use Zend\Dom\Document;
use Zend\Stdlib\ErrorHandler;
class Meteo
{
public function fetchFeed(array $configuration)
{
$data = '';
ErrorHandler::start(\E_ALL);
// $configuration['url'] = ['ftp://site'];
foreach ((array) $configuration['url'] as $url) {
$content = file_get_contents($url);
$content = mb_convert_encoding($content, 'UTF-8', 'HTML-ENTITIES');
/* $content = '
<div id="hpw_1">
<span class="hpw_date_short">Me</span>
<span class="hpw_date_long">Mercredi</span>
<span class="hpw_comma">, </span>
<span class="hpw_date_exp">18 février 2015</span>
<span class="hpw_date_num">18.2.</span>
<span id="hpw_img_1" class="hpw_img_code_4"></span>
<span class="hpw_txt">changeant à nuageux</span>
<span class="hpw_temp_min">0°</span>
<span class="hpw_temp_delim">|</span>
<span class="hpw_temp_max">5°</span>
</div>
<div id="hpw_2">
<span class="hpw_date_short">Je</span>
<span class="hpw_date_long">Jeudi</span>
<span class="hpw_comma">, </span>
<span class="hpw_date_exp">19 février 2015</span>
<span class="hpw_date_num">19.2.</span>
<span id="hpw_img_2" class="hpw_img_code_27"></span>
<span class="hpw_txt">stratus</span>
<span class="hpw_temp_min">-1°</span>
<span class="hpw_temp_delim">|</span>
<span class="hpw_temp_max">6°</span>
</div>
'; */
$file = substr(strrchr($url, '/'), 1);
$data .= sprintf('<content url="%s">%s</content>', $file, $content);
}
ErrorHandler::stop(true);
return $data;
}
/**
* {@inheritdoc}
*/
public function processFeed($data, array $configuration)
{
$document = new Document($data);
$forecasts = [];
$dayForecasts = Document\Query::execute('//*/div[@id!="hpw"]', $document);
foreach ($dayForecasts as $forecast) {
$html = $forecast->ownerDocument->saveHTML($forecast);
$forecastDoc = new Document($html);
$spans = Document\Query::execute('//span', $forecastDoc);
$spanData = [];
foreach($spans as $span) {
$id = $span->attributes->getNamedItem('id');
$id = isset($id) ? $id->nodeValue : null;
$class = $span->attributes->getNamedItem('class');
$class = isset($class) ? $class->nodeValue : null;
// Strip numbers from class and use as key [as numbers increment per day]
$spanData[preg_replace('#\d+#', '', $class)] = [
'id' => $id,
'class' => $class,
'content' => $span->textContent,
];
}
// Strip content and only keep year
$year = preg_replace('#.+(\d{4})#', '$1', $spanData['hpw_date_exp']['content']);
$date = sprintf('%s.%s 00:00', rtrim($spanData['hpw_date_num']['content'], '.'), $year);
$date = \DateTime::createFromFormat('d.m.Y H:i', $date)->format('Y-m-d H:i');
$forecasts[$date] = $spanData;
}
// For better view
ksort($forecasts);
return $forecasts;
}
/**
* {@inheritdoc}
*/
public function filter($data, array $configuration)
{
$forecastData = [];
foreach($data as $key => $day) {
$forecast = new Feed\Forecast();
$forecast->setSource('meteosuisse');
$dateTime = new \DateTime($key);
$forecast->setDateTime($dateTime);
$weather = new Feed\Weather();
$temperature = new Feed\Temperature();
$weather->setDescription($day['hpw_txt']['content']);
$weather->setIcon($day['hpw_img_code_']['class']);
$weather->setId($day['hpw_img_code_']['class']);
$weather->setIconSet('meteosuisse');
$tempDay = isset($day['hpw_temp_']['content']) ? $day['hpw_temp_']['content'] : null;
$temperature->setDay($tempDay);
$tempMin = isset($day['hpw_temp_min']['content']) ? $day['hpw_temp_min']['content'] : null;
$temperature->setMin($tempMin);
$tempMax = isset($day['hpw_temp_max']['content']) ? $day['hpw_temp_max']['content'] : null;
$temperature->setMax($tempMax);
// Set sub-objects
$forecast->setWeather($weather)
->setTemperature($temperature);
$forecastData[$dateTime->format(AbstractProcessor::DATE_FORMAT)] = $forecast;
}
return $forecastData;
}
}
<?php
use GuzzleHttp\Client;
use Zend\Stdlib\Hydrator\ClassMethods;
class WeatherService
{
/**
* @param Client $client
*/
public function __construct(Client $client)
{
$this->client = $client;
}
public function fetchWeatherData(array $configuration)
{
// Config check
if (!isset($configuration['processor']) || !class_exists($configuration['processor'])) {
throw new \Exception(
sprintf('Invalid processor "%s" in configuration', $configuration['processor'])
);
}
// Fetch the feed
$processor = new $configuration['processor']($this->client);
$data = $processor->fetchFeed($configuration);
// Process it
$data = $processor->processFeed($data, $configuration);
// Filter it
$data = $processor->filter($data, $configuration);
// Extract object to array
foreach($data as $date => &$forecast) {
$forecast = (array) $forecast;
// Replace Forecast keys from object class name to readable string
$result = preg_replace('#.+\x00#', '', array_keys($forecast));
$forecast = array_combine($result, array_values($forecast));
// For each 'object' in Forecast, replace
foreach($forecast as $key => &$object) {
$object = (array) $object;
// Replace 'Object' keys from object class name to readable string
$result = preg_replace('#.+\x00#', '', array_keys($object));
$object = array_combine($result, array_values($object));
$forecast[$key] = $object;
}
}
return $data;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment