Skip to content
This repository has been archived by the owner on Nov 29, 2017. It is now read-only.

Commit

Permalink
Initial src
Browse files Browse the repository at this point in the history
  • Loading branch information
tyx committed Aug 29, 2013
1 parent 194abf5 commit 228653e
Show file tree
Hide file tree
Showing 50 changed files with 2,491 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .atoum.bootstrap.php
@@ -0,0 +1,2 @@
<?php
require_once __DIR__.'/vendor/autoload.php';
17 changes: 17 additions & 0 deletions .atoum.php
@@ -0,0 +1,17 @@
<?php
use mageekguy\atoum;

$script->addTestAllDirectory(__DIR__.'/tests/unit');

$script
->addDefaultReport()
->addField(new atoum\report\fields\runner\result\logo())
->addField(new atoum\report\fields\runner\coverage\html(
'Code coverage',
__DIR__.'/web/code-coverage'
)
)
;

$script->noCodeCoverageForNamespaces(array('mageekguy', 'symfony'));
$script->bootstrapFile(__DIR__ . DIRECTORY_SEPARATOR . '.atoum.bootstrap.php');
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
bin
composer.lock
vendor
web
examples/temp
23 changes: 21 additions & 2 deletions README.md
@@ -1,4 +1,23 @@
jobflow
JobFlow
=======

Simpler, Easier, Faster
Makes batch jobs creation Simpler, Easier, Faster.

ETL pattern support thanks to : https://github.com/docteurklein/php-etl

**Warning** : This code has not been executed in production.

Usage
-----

Have a look to the [first example](/examples/basic.php)

Tests
-----

Units tests powered by atoum : https://github.com/atoum/atoum

Credits
-------

Builder Architecture heavily inspired by Symfony Form Component : https://github.com/symfony/Form
44 changes: 44 additions & 0 deletions composer.json
@@ -0,0 +1,44 @@
{
"name": "rezzza/jobflow",
"description": "Makes batch job creation easier",
"keywords": ["batch", "job", "etl"],
"type": "standalone",
"homepage": "https://github.com/rezzza/jobflow",
"license": "MIT",
"authors": [{
"name": "Community contributors",
"homepage": "https://github.com/rezzza/jobflow/contributors"
}],
"require": {
"php": ">=5.4.0",

"symfony/options-resolver": "~2.3",
"knplabs/etl": "dev-waiting"
},
"suggest": {
"doctrine/orm": "To use ORM loader"
},
"require-dev": {
"atoum/atoum": "*@dev",
"monolog/monolog": "*"
},
"autoload": {
"psr-0": {
"Rezzza\\JobFlow": "src/"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/tyx/php-etl"
}
],
"config": {
"bin-dir": "bin"
}
}
50 changes: 50 additions & 0 deletions examples/basic.php
@@ -0,0 +1,50 @@
<?php

require_once __DIR__.'/../vendor/autoload.php';

use Rezzza\JobFlow\Jobs;
use Rezzza\JobFlow\Io;
use Rezzza\JobFlow\Scheduler\JobScheduler;
use Rezzza\JobFlow\Scheduler\Transport\PhpTransport;

$logger = new \Monolog\Logger('jobflow');
$jobFactory = Jobs::createJobFactory();
$transport = new PhpTransport();
$scheduler = new JobScheduler($transport);
$scheduler->setLogger($logger);

$io = new Io\IoDescriptor(
new Io\Input('file://'.__DIR__.'/fixtures.csv'),
new Io\Output('file:///'.__DIR__.'/temp/result.json')
);

$job = $jobFactory->createBuilder('job', $io)
->add(
'example_extractor',
'extractor'
)
->add(
'example_transformer',
'transformer',
array(
'transformer_callback' => function($data, $target) {
$target['firstname'] = $data[0];
$target['name'] = $data[1];
$target['url'] = sprintf('http://www.lequipe.fr/Football/FootballFicheJoueur%s.html', $data[2]);

return json_encode($target, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}
)
)
->add(
'example_loader',
'loader'
)
->getJob()
;

$scheduler
->setJob($job)
->init()
->run()
;
3 changes: 3 additions & 0 deletions examples/fixtures.csv
@@ -0,0 +1,3 @@
Zinedine;Zidane;4112
Michel;Platini;9663
Raymond;Kopa;13179
43 changes: 43 additions & 0 deletions src/Rezzza/JobFlow/AbstractJobType.php
@@ -0,0 +1,43 @@
<?php

namespace Rezzza\JobFlow;

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

use Rezzza\JobFlow\Io\IoDescriptor;
use Rezzza\JobFlow\Scheduler\ExecutionContext;

/**
* @author Timothée Barray <tim@amicalement-web.net>
*/
abstract class AbstractJobType implements JobTypeInterface
{
/**
* {@inheritdoc}
*/
public function execute($input, ExecutionContext $execution)
{
}

/**
* {@inheritdoc}
*/
public function buildJob(JobBuilder $builder, array $options)
{
}

/**
* {@inheritdoc}
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
}

/**
* {@inheritdoc}
*/
public function getParent()
{
return 'job';
}
}
137 changes: 137 additions & 0 deletions src/Rezzza/JobFlow/Extension/BaseExtension.php
@@ -0,0 +1,137 @@
<?php

namespace Rezzza\JobFlow\Extension;

use Rezzza\JobFlow\JobTypeInterface;
use Rezzza\JobFlow\Io\IoWrapperInterface;

abstract class BaseExtension implements JobExtensionInterface
{
/**
* @var JobTypeInterface[]
*/
protected $types;

/**
* @var IoWrapperInterface[]
*/
protected $wrappers;

public function addType(JobTypeInterface $type)
{
$this->types[$type->getName()] = $type;
}

/**
* {@inheritdoc}
*/
public function getType($name)
{
if (null === $this->types) {
$this->initTypes();
}

if (!isset($this->types[$name])) {
throw new \InvalidArgumentException(sprintf('The type "%s" can not be loaded by this extension', $name));
}

return $this->types[$name];
}

/**
* {@inheritdoc}
*/
public function hasType($name)
{
if (null === $this->types) {
$this->initTypes();
}

return isset($this->types[$name]);
}

public function addWrapper(IoWrapperInterface $wrapper)
{
$this->wrappers[$wrapper->getName()] = $wrapper;
}

/**
* {@inheritdoc}
*/
public function getWrapper($name)
{
if (null === $this->wrappers) {
$this->initWrappers();
}

if (!isset($this->wrappers[$name])) {
throw new \InvalidArgumentException(sprintf('The wrapper "%s" can not be loaded by this extension', $name));
}

return $this->wrappers[$name];
}

/**
* {@inheritdoc}
*/
public function hasWrapper($name)
{
if (null === $this->wrappers) {
$this->initWrappers();
}

return isset($this->wrappers[$name]);
}

/**
* Registers the types.
*
* @return JobTypeInterface[]
*/
protected function loadTypes()
{
return array();
}

/**
* Registers the wrappers.
*
* @return IoWrapperInterface[]
*/
protected function loadWrappers()
{
return array();
}

/**
* Initializes the types.
*/
private function initTypes()
{
$this->types = array();

foreach ($this->loadTypes() as $type) {
if (!$type instanceof JobTypeInterface) {
throw new \InvalidArgumentException(sprintf('Type %s should implements JobTypeInterface', get_class($type)));
}

$this->types[$type->getName()] = $type;
}
}

/**
* Initializes the types.
*/
private function initWrappers()
{
$this->wrappers = array();

foreach ($this->loadWrappers() as $wrapper) {
if (!$wrapper instanceof IoWrapperInterface) {
throw new \InvalidArgumentException(sprintf('Wrapper %s should implements IoWrapperInterface', get_class($wrapper)));
}

$this->wrappers[$wrapper->getName()] = $wrapper;
}
}
}
28 changes: 28 additions & 0 deletions src/Rezzza/JobFlow/Extension/Core/CoreExtension.php
@@ -0,0 +1,28 @@
<?php

namespace Rezzza\JobFlow\Extension\Core;

use Rezzza\JobFlow\Extension\BaseExtension;

class CoreExtension extends BaseExtension
{
public function loadTypes()
{
return array(
new Type\JobType(),
new Type\Extractor\ExtractorType(),
new Type\Transformer\TransformerType(),
new Type\Loader\LoaderType()
);
}

public function loadWrappers()
{
return array(
new Wrapper\JobWrapper(),
new Wrapper\CsvWrapper(),
new Wrapper\TsvWrapper(),
new Wrapper\JsonWrapper()
);
}
}

0 comments on commit 228653e

Please sign in to comment.