Permalink
Browse files

Refactor to OOP using pimple as DI container.

  • Loading branch information...
cbenard committed Jul 31, 2015
1 parent faa5ec2 commit 66640d88a5cdc0da51a99d9ce4b0ca805cec89ad
View
@@ -1,5 +1,5 @@
application: comicfeeds-1022
version: 2
version: 3
runtime: php55
api_version: 1
threadsafe: no
View
@@ -0,0 +1,11 @@
<?php
class DilbertService extends GenericComicService {
public function __construct(FeedService $feedService, Logger $logger, StorageService $store) {
parent::__construct("dilbert_default", $feedService, $logger, $store);
$this->feed = "http://dilbert.com/feed.rss";
$this->pattern = '/data-image="(.+?)"/';
$this->entrySearchText = "Comic for ";
}
}
View
@@ -0,0 +1,48 @@
<?php
class FeedService {
private $log;
public function __construct(Logger $logger) {
$this->log = $logger;
}
public function fetchFeed($url) {
$doc = simplexml_load_file($url);
if ($doc === FALSE) {
throw new Exception('Unable to load XML');
}
return $doc;
}
public function fetchPageContents($url) {
$contents = file_get_contents($url);
if ($contents === FALSE) {
throw new Exception('Unable to load page contents');
}
return $contents;
}
public function getLinkFromEntry(SimpleXMLElement $entry) {
$url = $entry->link['href'];
return $url;
}
public function getImageUrl($contents, $regexPattern) {
$ret = preg_match($regexPattern, $contents, $matches);
if ($ret === FALSE) {
throw new Exception("Regex error occurred.");
} elseif ($ret === 0) {
throw new Exception("Regex did not match subject.");
} elseif ($ret !== 1) {
throw new Exception("Unexpected regex return value: $ret");
} elseif (count($matches) < 2) {
throw new Exception("Regex had no matches.");
}
$imageUrl = $matches[1];
return $imageUrl;
}
}
@@ -0,0 +1,76 @@
<?php
class GenericComicService {
protected $feed;
protected $feedService;
protected $log;
protected $pattern;
protected $entrySearchText;
protected $name;
protected $store;
public function __construct(
$name, FeedService $feedService,
Logger $logger, StorageService $store) {
$this->feedService = $feedService;
$this->log = $logger;
$this->name = $name;
$this->store = $store;
}
public function fetchAndStore() {
$xml = $this->fetch();
$filename = "feed_" . $this->name;
$this->store->save($filename, $xml);
}
protected function fetch() {
$doc = $this->feedService->fetchFeed($this->feed);
$count = count($doc->entry);
if ($count < 1) {
throw new Exception("No entries found in feed {$this->feed}.");
}
for ($i = $count - 1; $i >= 0; $i--) {
$entry = $doc->entry[$i];
if (strpos($entry->title, $this->entrySearchText) === FALSE) {
unset($doc->entry[$i]);
}
else {
$this->log->log("Processing $entry->title...");
if (isset($entry->description)) {
$entry->description = '';
} else {
$entry->addChild("description");
}
if (isset($entry->content)) {
unset($entry->content);
}
$newContents = $this->getEntryContents($entry);
$domNode = dom_import_simplexml($entry->description);
$owner = $domNode->ownerDocument;
$domNode->appendChild($owner->createCDATASection($newContents));
$this->log->log("\tDone.\n");
}
}
print_r($doc);
return $doc->asXml();
}
private function getEntryContents(SimpleXMLElement $entry) {
$url = $entry->link['href'];
$this->log->log("\tFetching URL: $url");
$contents = $this->feedService->fetchPageContents($url);
$imageUrl = $this->feedService->getImageUrl($contents, $this->pattern);
$newContents = "<img src=\"$imageUrl\"/>";
return $newContents;
}
}
View
@@ -0,0 +1,7 @@
<?php
class Logger {
public function log($text) {
echo $text . "\n";
}
}
View
@@ -0,0 +1,24 @@
<?php
class StorageService {
private $prefix;
private $ctx;
public function __construct() {
$this->prefix = "gs://#default#/";
$options = ['gs' => ['Content-Type' => 'text/plain']];
$this->ctx = stream_context_create($options);
}
public function save($filename, $contents) {
file_put_contents($this->prefix . $filename, $contents, 0, $this->ctx);
}
public function load($filename) {
$newFilename = $this->prefix . $filename;
if (!file_exists($newFilename)) {
throw new Exception("Sorry. That feed does not exist.");
}
return file_get_contents($newFilename);
}
}
View
@@ -0,0 +1,32 @@
<?php
class ViewService {
protected $log;
protected $store;
public function __construct(Logger $logger, StorageService $store) {
$this->log = $logger;
$this->store = $store;
}
public function getFeed($requestUri) {
$pattern = "@^/view/(.+?)/(.+?)$@";
$ret = preg_match($pattern, $requestUri, $matches);
if ($ret === FALSE) {
throw new Exception("Regex error occurred.");
} elseif ($ret === 0) {
throw new Exception("Regex did not match subject.");
} elseif ($ret !== 1) {
throw new Exception("Unexpected regex return value: $ret");
} elseif (count($matches) < 3) {
throw new Exception("Regex had no matches.");
}
$feedName = $matches[1];
$feedType = $matches[2];
$filename = "feed_{$feedName}_{$feedType}";
return $this->store->load($filename);
}
}
View
@@ -0,0 +1,5 @@
{
"require": {
"pimple/pimple": "~3.0"
}
}
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -1,2 +1,2 @@
google_app_engine.enable_functions = "libxml_disable_entity_loader"
output_buffering = "Off"
output_buffering = "On"
View
@@ -1,3 +1,21 @@
<?php
ob_start();
libxml_disable_entity_loader(false);
spl_autoload_register(function ($class) {
include __DIR__ . '/../classes/' . $class . '.php';
});
require(__DIR__ . '/../vendor/autoload.php');
require('scripts/dependency_injection.php');
set_exception_handler(function($ex) {
ob_end_clean();
header('Content-Type: text/plain');
http_response_code(500);
echo $ex->getMessage();
});
@@ -0,0 +1,20 @@
<?php
use Pimple\Container;
$container = new Container();
$container['logger'] = function($c) {
return new Logger;
};
$container['storage'] = function($c) {
return new StorageService;
};
$container['feed'] = function($c) {
return new FeedService($c['logger']);
};
$container['dilbert'] = function($c) {
return new DilbertService($c['feed'], $c['logger'], $c['storage']);
};
$container['view'] = function ($c) {
return new ViewService($c['logger'], $c['storage']);
};
@@ -3,7 +3,14 @@
header("Content-Type: text/plain");
require_once("common.php");
$dilbert = $container['dilbert'];
$dilbert->fetchAndStore();
/*
$feed = "http://dilbert.com/feed.rss";
$pattern = '/data-image="(.+?)"/';
$doc = simplexml_load_file($feed) or die('Unable to load XML');
$count = count($doc->entry);
@@ -51,3 +58,4 @@ function get_image_url($contents) {
print_r($outputXml);
file_put_contents("gs://#default#/feed_dilbert_default", $outputXml);
*/
View
@@ -1,6 +1,9 @@
<?php
require_once("common.php");
header("Content-Type: application/rss+xml");
echo file_get_contents("gs://#default#/feed_dilbert_default");
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + (60*60*2)) . ' GMT');
header('Cache-Control: public, must-revalidate, max-age=7200');
$view = $container['view'];
echo $view->getFeed($_SERVER['REQUEST_URI']);

0 comments on commit 66640d8

Please sign in to comment.