Merge pull request #17 from nopolabs/develop
add FileExporter for PHP SDK
diff --git a/composer.json b/composer.json
index a7ec9b5..3725bbb 100644
--- a/composer.json
+++ b/composer.json
@@ -25,7 +25,8 @@
"guzzlehttp/guzzle": "~5.0"
},
"require-dev": {
- "symfony/class-loader": "~2.3"
+ "symfony/class-loader": "~2.3",
+ "phpunit/phpunit": "4.6.*"
},
"autoload": {
"psr-4": {
diff --git a/src/predictionio/Exporter.php b/src/predictionio/Exporter.php
new file mode 100644
index 0000000..35b7a03
--- /dev/null
+++ b/src/predictionio/Exporter.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace predictionio;
+
+
+trait Exporter {
+
+ abstract public function export($json);
+
+ public function jsonEncode($data) {
+ return json_encode($data);
+ }
+
+ /**
+ * Create and export a json-encoded event.
+ *
+ * @see \predictionio\EventClient::CreateEvent()
+ *
+ * @param $event
+ * @param $entityType
+ * @param $entityId
+ * @param null $targetEntityType
+ * @param null $targetEntityId
+ * @param array $properties
+ * @param $eventTime
+ */
+ public function createEvent($event, $entityType, $entityId,
+ $targetEntityType=null, $targetEntityId=null, array $properties=null,
+ $eventTime=null) {
+
+ if (!isset($eventTime)) {
+ $eventTime = new \DateTime();
+ } elseif (!($eventTime instanceof \DateTime)) {
+ $eventTime = new \DateTime($eventTime);
+ }
+ $eventTime = $eventTime->format(\DateTime::ISO8601);
+
+ $data = [
+ 'event' => $event,
+ 'entityType' => $entityType,
+ 'entityId' => $entityId,
+ 'eventTime' => $eventTime,
+ ];
+
+ if (isset($targetEntityType)) {
+ $data['targetEntityType'] = $targetEntityType;
+ }
+
+ if (isset($targetEntityId)) {
+ $data['targetEntityId'] = $targetEntityId;
+ }
+
+ if (isset($properties)) {
+ $data['properties'] = $properties;
+ }
+
+ $json = $this->jsonEncode($data);
+
+ $this->export($json);
+ }
+
+}
\ No newline at end of file
diff --git a/src/predictionio/FileExporter.php b/src/predictionio/FileExporter.php
new file mode 100644
index 0000000..d0ee711
--- /dev/null
+++ b/src/predictionio/FileExporter.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace predictionio;
+
+/**
+ * Class FileExporter writes events to a series of JSON objects in a file for batch import.
+ *
+ * @package predictionio
+ */
+class FileExporter {
+
+ use Exporter;
+
+ private $file;
+
+ public function __construct($fileName) {
+ $this->file = fopen($fileName, 'w');
+ }
+
+ public function export($json) {
+ fwrite($this->file, "$json\n");
+ }
+
+ public function close() {
+ fclose($this->file);
+ }
+}
\ No newline at end of file
diff --git a/tests/Unit/ExporterTest.php b/tests/Unit/ExporterTest.php
new file mode 100644
index 0000000..fb2377b
--- /dev/null
+++ b/tests/Unit/ExporterTest.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace predictionio\tests\Unit;
+
+
+use predictionio\Exporter;
+
+class TestExporter {
+ use Exporter {
+ jsonEncode as traitJsonEncode;
+ }
+
+ public $json;
+ public $data;
+
+ public function __construct() {
+ $this->json = [];
+ $this->data = [];
+ }
+
+ public function jsonEncode($data) {
+ $this->data[] = $data;
+ return $this->traitJsonEncode($data);
+ }
+
+ public function export($json) {
+ $this->json[] = $json;
+ }
+}
+
+class ExporterTest extends \PHPUnit_Framework_TestCase {
+
+ /** @var TestExporter $exporter */
+ private $exporter;
+
+ protected function setUp() {
+ $this->exporter = new TestExporter();
+ }
+
+ public function testTimeIsNow() {
+ $time = new \DateTime();
+
+ $this->exporter->createEvent('event', 'entity-type', 'entity-id');
+
+ $this->assertEquals(1, count($this->exporter->data));
+ $data = $this->exporter->data[0];
+ $this->assertEquals(4, count($data));
+ $this->assertEquals('event', $data['event']);
+ $this->assertEquals('entity-type', $data['entityType']);
+ $this->assertEquals('entity-id', $data['entityId']);
+ $this->assertEquals($time->format(\DateTime::ISO8601), $data['eventTime'], 'time is now', 1);
+
+ $this->assertEquals(1, count($this->exporter->json));
+ $json = $this->exporter->json[0];
+ $pattern = '/^{"event":"event","entityType":"entity-type","entityId":"entity-id","eventTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}"}$/';
+ $this->assertTrue(preg_match($pattern, $json) === 1, 'json');
+ }
+
+ public function testTimeIsString() {
+ $time = new \DateTime('2015-04-01');
+
+ $this->exporter->createEvent('event', 'entity-type', 'entity-id', null, null, null, '2015-04-01');
+
+ $this->assertEquals(1, count($this->exporter->data));
+ $data = $this->exporter->data[0];
+ $this->assertEquals(4, count($data));
+ $this->assertEquals('event', $data['event']);
+ $this->assertEquals('entity-type', $data['entityType']);
+ $this->assertEquals('entity-id', $data['entityId']);
+ $this->assertEquals($time->format(\DateTime::ISO8601), $data['eventTime'], 'time is string', 1);
+
+ $this->assertEquals(1, count($this->exporter->json));
+ $json = $this->exporter->json[0];
+ $pattern = '/^{"event":"event","entityType":"entity-type","entityId":"entity-id","eventTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}"}$/';
+ $this->assertTrue(preg_match($pattern, $json) === 1, 'json');
+ }
+
+ public function testTimeIsDateTime() {
+ $time = new \DateTime('2015-04-01');
+
+ $this->exporter->createEvent('event', 'entity-type', 'entity-id', null, null, null, $time);
+
+ $this->assertEquals(1, count($this->exporter->data));
+ $data = $this->exporter->data[0];
+ $this->assertEquals(4, count($data));
+ $this->assertEquals('event', $data['event']);
+ $this->assertEquals('entity-type', $data['entityType']);
+ $this->assertEquals('entity-id', $data['entityId']);
+ $this->assertEquals($time->format(\DateTime::ISO8601), $data['eventTime'], 'time is DateTime', 1);
+
+ $this->assertEquals(1, count($this->exporter->json));
+ $json = $this->exporter->json[0];
+ $pattern = '/^{"event":"event","entityType":"entity-type","entityId":"entity-id","eventTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}"}$/';
+ $this->assertTrue(preg_match($pattern, $json) === 1, 'json');
+ }
+
+ public function testOptionalFields() {
+ $time = new \DateTime('2015-04-01');
+
+ $this->exporter->createEvent('event', 'entity-type', 'entity-id',
+ 'target-entity-type', 'target-entity-id', ['property' => true], $time);
+
+ $this->assertEquals(1, count($this->exporter->data));
+ $data = $this->exporter->data[0];
+ $this->assertEquals(7, count($data));
+ $this->assertEquals('event', $data['event']);
+ $this->assertEquals('entity-type', $data['entityType']);
+ $this->assertEquals('entity-id', $data['entityId']);
+ $this->assertEquals($time->format(\DateTime::ISO8601), $data['eventTime'], 'time is DateTime', 1);
+ $this->assertEquals('target-entity-type', $data['targetEntityType']);
+ $this->assertEquals('target-entity-id', $data['targetEntityId']);
+ $this->assertEquals(['property'=>true], $data['properties']);
+
+ $this->assertEquals(1, count($this->exporter->json));
+ $json = $this->exporter->json[0];
+ $pattern = '/^{"event":"event","entityType":"entity-type","entityId":"entity-id","eventTime":"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{4}","targetEntityType":"target-entity-type","targetEntityId":"target-entity-id","properties":{"property":true}}$/';
+ $this->assertTrue(preg_match($pattern, $json) === 1, 'json');
+ }
+
+}
\ No newline at end of file
diff --git a/tests/Unit/FileExporterTest.php b/tests/Unit/FileExporterTest.php
new file mode 100644
index 0000000..f23affa
--- /dev/null
+++ b/tests/Unit/FileExporterTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace predictionio\tests\Unit;
+
+
+use predictionio\FileExporter;
+
+class FileExporterTest extends \PHPUnit_Framework_TestCase {
+
+ public function setUp()
+ {
+ register_shutdown_function(function () {
+ if (file_exists('temp.file')) {
+ unlink('temp.file');
+ }
+ });
+ }
+
+ public function testExporter() {
+ $exporter = new FileExporter('temp.file');
+ $exporter->createEvent('event-1', 'entity-type-1', 'entity-id-1',
+ null, null, null, '2015-04-01');
+ $exporter->createEvent('event-2', 'entity-type-2', 'entity-id-2',
+ 'target-entity-type-2', 'target-entity-id-2', ['property' => 'blue'], '2015-04-01');
+ $exporter->close();
+
+ $exported = file_get_contents('temp.file');
+
+ $date = new \DateTime('2015-04-01');
+ $expectedDate = $date->format(\DateTime::ISO8601);
+
+ $expected =<<<EOS
+{"event":"event-1","entityType":"entity-type-1","entityId":"entity-id-1","eventTime":"$expectedDate"}
+{"event":"event-2","entityType":"entity-type-2","entityId":"entity-id-2","eventTime":"$expectedDate","targetEntityType":"target-entity-type-2","targetEntityId":"target-entity-id-2","properties":{"property":"blue"}}
+
+EOS;
+
+ $this->assertEquals($expected, $exported);
+ }
+}
\ No newline at end of file