Skip to content

Added fallback on common classes. Puli is now optional #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion spec/ClassDiscoverySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function it_throws_an_exception_when_binding_not_found(Discovery $discovery)
{
$discovery->findBindings('InvalidBinding')->willReturn([]);

$this->shouldThrow('Http\Discovery\NotFoundException')->duringFindOneByType('InvalidBinding');
$this->shouldThrow('Http\Discovery\Exception\NotFoundException')->duringFindOneByType('InvalidBinding');
}

function it_returns_a_class_binding(Discovery $discovery, ClassBinding $binding)
Expand Down
35 changes: 33 additions & 2 deletions src/ClassDiscovery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

namespace Http\Discovery;

use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Exception\PuliNotAvailableException;
use Http\Discovery\FallbackStrategy\HttpClients;
use Http\Discovery\FallbackStrategy\DiactorosFactory;
use Http\Discovery\FallbackStrategy\GuzzleFactory;
use Puli\Discovery\Api\Discovery;

/**
Expand Down Expand Up @@ -29,13 +34,13 @@ public static function getPuliFactory()
{
if (null === self::$puliFactory) {
if (!defined('PULI_FACTORY_CLASS')) {
throw new \RuntimeException('Puli Factory is not available');
throw new PuliNotAvailableException('Puli Factory is not available');
}

$puliFactoryClass = PULI_FACTORY_CLASS;

if (!class_exists($puliFactoryClass)) {
throw new \RuntimeException('Puli Factory class does not exist');
throw new PuliNotAvailableException('Puli Factory class does not exist');
}

self::$puliFactory = new $puliFactoryClass();
Expand Down Expand Up @@ -95,6 +100,32 @@ public static function getPuliDiscovery()
* @throws NotFoundException
*/
public static function findOneByType($type)
{
try {
return self::puliFindOneByType($type);
} catch (PuliNotAvailableException $e) {
if (false !== $class = HttpClients::findOneByType($type)) {
return $class;
} elseif (false !== $class = GuzzleFactory::findOneByType($type)) {
return $class;
} elseif (false !== $class = DiactorosFactory::findOneByType($type)) {
return $class;
}
throw new NotFoundException('Could not find resource using Puli nor common Guzzle/Diactoros classes', 0, $e);
}
}

/**
* Finds a class using Puli.
*
* @param $type
*
* @return string
*
* @throws NotFoundException
* @throws PuliNotAvailableException
*/
private static function puliFindOneByType($type)
{
$bindings = self::getPuliDiscovery()->findBindings($type);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Http\Discovery;
namespace Http\Discovery\Exception;

/**
* Thrown when a discovery does not find any matches.
Expand Down
12 changes: 12 additions & 0 deletions src/Exception/PuliNotAvailableException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Http\Discovery\Exception;

/**
* Thrown when we can't use Puli for discovery.
*
* @author Tobias Nyholm <[email protected]>
*/
class PuliNotAvailableException extends \RuntimeException
{
}
41 changes: 41 additions & 0 deletions src/FallbackStrategy/DiactorosFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Http\Discovery\FallbackStrategy;

/**
* Find Diactoros factories.
*
* @author Tobias Nyholm <[email protected]>
*/
class DiactorosFactory implements FallbackStrategy
{
/**
* {@inheritdoc}
*/
public static function findOneByType($type)
{
if (!class_exists('Zend\Diactoros\Request')) {
return false;
}

switch ($type) {
case 'Http\Message\MessageFactory':
if (class_exists('Http\Message\MessageFactory\DiactorosMessageFactory')) {
return 'Http\Message\MessageFactory\DiactorosMessageFactory';
}
break;
case 'Http\Message\StreamFactory':
if (class_exists('Http\Message\StreamFactory\DiactorosStreamFactory')) {
return 'Http\Message\StreamFactory\DiactorosStreamFactory';
}
break;
case 'Http\Message\UriFactory':
if (class_exists('Http\Message\UriFactory\DiactorosUriFactory')) {
return 'Http\Message\UriFactory\DiactorosUriFactory';
}
break;
}

return false;
}
}
16 changes: 16 additions & 0 deletions src/FallbackStrategy/FallbackStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Http\Discovery\FallbackStrategy;

/**
* @author Tobias Nyholm <[email protected]>
*/
interface FallbackStrategy
{
/**
* @param $type
*
* @return string|bool class name of boolean false
*/
public static function findOneByType($type);
}
41 changes: 41 additions & 0 deletions src/FallbackStrategy/GuzzleFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Http\Discovery\FallbackStrategy;

/**
* Find Guzzle factories.
*
* @author Tobias Nyholm <[email protected]>
*/
class GuzzleFactory implements FallbackStrategy
{
/**
* {@inheritdoc}
*/
public static function findOneByType($type)
{
if (!class_exists('GuzzleHttp\Psr7\Request')) {
return false;
}

switch ($type) {
case 'Http\Message\MessageFactory':
if (class_exists('Http\Message\MessageFactory\GuzzleMessageFactory')) {
return 'Http\Message\MessageFactory\GuzzleMessageFactory';
}
break;
case 'Http\Message\StreamFactory':
if (class_exists('Http\Message\StreamFactory\GuzzleStreamFactory')) {
return 'Http\Message\StreamFactory\GuzzleStreamFactory';
}
break;
case 'Http\Message\UriFactory':
if (class_exists('Http\Message\UriFactory\GuzzleUriFactory')) {
return 'Http\Message\UriFactory\GuzzleUriFactory';
}
break;
}

return false;
}
}
38 changes: 38 additions & 0 deletions src/FallbackStrategy/HttpClients.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Http\Discovery\FallbackStrategy;

/**
* Find common HTTP clients.
*
* @author Tobias Nyholm <[email protected]>
*/
class HttpClients implements FallbackStrategy
{
/**
* {@inheritdoc}
*/
public static function findOneByType($type)
{
switch ($type) {
case 'Http\Client\HttpAsyncClient':
$clients = ['Http\Adapter\Guzzle6\Client'];
foreach ($clients as $class) {
if (class_exists($class)) {
return $class;
}
}
break;
case 'Http\Client\HttpClient':
$clients = ['Http\Adapter\Guzzle6\Client', 'Http\Adapter\Guzzle5\Client'];
foreach ($clients as $class) {
if (class_exists($class)) {
return $class;
}
}
break;
}

return false;
}
}
1 change: 1 addition & 0 deletions src/MessageFactoryDiscovery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Http\Discovery;

use Http\Discovery\Exception\NotFoundException;
use Http\Message\MessageFactory;

/**
Expand Down
1 change: 1 addition & 0 deletions src/StreamFactoryDiscovery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Http\Discovery;

use Http\Discovery\Exception\NotFoundException;
use Http\Message\StreamFactory;

/**
Expand Down
1 change: 1 addition & 0 deletions src/UriFactoryDiscovery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Http\Discovery;

use Http\Discovery\Exception\NotFoundException;
use Http\Message\UriFactory;

/**
Expand Down