Created
March 15, 2015 12:46
-
-
Save rizqidjamaluddin/be7de406022b9a1afa43 to your computer and use it in GitHub Desktop.
Factory/Criteria pattern with service provider bindings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class CriteriaFactory { | |
protected $transformations = []; | |
public function __construct(Array $t = []) { | |
$this->transformations = $t; | |
} | |
/** | |
* $factory can either be the FQCN or a closure that generates said class | |
*/ | |
public function add($key, $factory) { | |
$this->transformations[$key] = $factory; | |
} | |
public function convert($key, Callable $callback = null) { | |
// add safety checks for missing keys here, you get the idea | |
if (is_callable($this->transformations[$key])) { | |
$i = $this->transformations[$key](); | |
} else { | |
$i = new $this->transformations[$key]; | |
} | |
if ($callback) { | |
$callback($i); | |
} | |
return $i; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class CriteriaFactoryServiceProvider extends ServiceProvider { | |
public function register() { | |
$this->app->bind(CriteriaFactory::class, function(Application $app) { | |
$i = new CriteriaFactory; | |
// this is how you register a new factory method | |
$i->add("posts-by-user", function () use ($app) { | |
return new PostsByUserCriteria($app['sentry']->getUser()); | |
}); | |
return $i; | |
}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class PostsByUserCriteria implements Criteria { | |
public function __construct(User $user) { | |
$this->user = $user; | |
} | |
public function setUser(User $user) { | |
$this->user = $user; | |
} | |
/** | |
* This gets an eloquent/QB instance | |
*/ | |
public function perform($queryBuilder) { | |
return $queryBuilder->where("user_id", $this->user->id); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// in some controller somewhere, so like you'd have ?filter=posts-by-user | |
$filters = $this->criteriaFactory->convert(Input::get('filter')); | |
// then in the repository, this just supports one criteria but yeah | |
function getPosts(Criteria $criteria) { | |
return $criteria->perform($this->startQuery())->get(); | |
} | |
// the callback thing is useful if you want to configure the filter during conversion, e.g. for ?filter=posts-by-user&user=84 | |
$this->criteriaFactory->convert(Input::get('filter'), function (PostsByUserCriteria $criteria) { | |
$criteria->setUser(Input::get('user')); | |
}) | |
// then you can use the same repository method as above |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment