-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
94a2c04
commit 9a72e5b
Showing
10 changed files
with
1,017 additions
and
2 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
namespace PhpCollection; | ||
|
||
/** | ||
* Implementation for ObjectBasics for entity-like objects. | ||
* | ||
* Two objects are considered equal if they refer to the same instance. | ||
* | ||
* @author Johannes M. Schmitt <[email protected]> | ||
*/ | ||
trait EntityLikeObject | ||
{ | ||
public function hash() | ||
{ | ||
return spl_object_hash($this); | ||
} | ||
|
||
public function equals(ObjectBasics $other) | ||
{ | ||
return $this === $other; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
namespace PhpCollection; | ||
|
||
/** | ||
* Interface that must be implemented by objects that are used as keys, or in sets. | ||
* | ||
* For entities, you can use the "EntityLikeObject" trait. | ||
* | ||
* @author Johannes M. Schmitt <[email protected]> | ||
*/ | ||
interface ObjectBasics | ||
{ | ||
/** | ||
* Produces a hash for the given object. | ||
* | ||
* If two objects are equal (as per the equals() method), the hash() method must produce | ||
* the same hash for them. | ||
* | ||
* The reverse can, but does not necessarily have to be true. That is, if two objects have the | ||
* same hash, they do not necessarily have to be equal, but the equals() method must be called | ||
* to be sure. | ||
* | ||
* When implementing this method try to use a simple and fast algorithm that produces reasonably | ||
* different results for non-equal objects, and shift the heavy comparison logic to equals(). | ||
* | ||
* @return string|integer | ||
*/ | ||
public function hash(); | ||
|
||
/** | ||
* Whether two objects are equal. | ||
* | ||
* This can compare by referential equality (===), or in case of value objects like (\DateTime) compare | ||
* the individual properties of the objects; it's up to the implementation. | ||
* | ||
* @return boolean | ||
*/ | ||
public function equals(ObjectBasics $other); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?php | ||
|
||
namespace PhpCollection; | ||
|
||
/** | ||
* Interface for external handlers that provide ObjectBasics functionality. | ||
* | ||
* @author Johannes M. Schmitt <[email protected]> | ||
*/ | ||
interface ObjectBasicsHandler | ||
{ | ||
/** | ||
* @param object $object This object is guaranteed to be of the type the handler was registered for. | ||
* @return string|integer | ||
*/ | ||
public function hash($object); | ||
|
||
/** | ||
* @param object $firstObject This object is guaranteed to be of the type the handler was registered for. | ||
* @param object $secondObject This might be an object of any class. | ||
* @return boolean | ||
*/ | ||
public function equals($firstObject, $secondObject); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
namespace PhpCollection\ObjectBasicsHandler; | ||
|
||
use PhpCollection\ObjectBasicsHandler; | ||
|
||
class DateTimeHandler implements ObjectBasicsHandler | ||
{ | ||
public function hash($object) | ||
{ | ||
if ( ! $object instanceof \DateTime) { | ||
throw new \LogicException('$object must be an instance of \DateTime.'); | ||
} | ||
|
||
return $object->getTimestamp(); | ||
} | ||
|
||
public function equals($thisObject, $otherObject) | ||
{ | ||
if ( ! $thisObject instanceof \DateTime) { | ||
throw new \LogicException('$thisObject must be an instance of \DateTime.'); | ||
} | ||
if ( ! $otherObject instanceof \DateTime) { | ||
return false; | ||
} | ||
|
||
return $thisObject->format(\DateTime::ISO8601) === $otherObject->format(\DateTime::ISO8601); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
<?php | ||
|
||
namespace PhpCollection\ObjectBasicsHandler; | ||
|
||
use PhpCollection\ObjectBasicsHandler; | ||
|
||
class IdentityHandler implements ObjectBasicsHandler | ||
{ | ||
public function hash($object) | ||
{ | ||
return spl_object_hash($object); | ||
} | ||
|
||
public function equals($a, $b) | ||
{ | ||
return $a === $b; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<?php | ||
|
||
namespace PhpCollection; | ||
use PhpCollection\ObjectBasicsHandler\IdentityHandler; | ||
|
||
/** | ||
* Registry for handlers that provide ObjectBasics functionality for classes. | ||
* | ||
* You want to register a handler if you cannot implement the ObjectBasics interface, for example | ||
* because a class is provided by a third-party package, or built into PHP. | ||
* | ||
* @author Johannes M. Schmitt <[email protected]> | ||
*/ | ||
abstract class ObjectBasicsHandlerRegistry | ||
{ | ||
private static $handlers = array( | ||
'DateTime' => 'PhpCollection\\ObjectBasicsHandler\\DateTimeHandler', | ||
); | ||
private static $defaultObjectHandler; | ||
|
||
private static $aliases = array(); | ||
|
||
/** | ||
* Defines an alias. | ||
* | ||
* $aliasClass must be a sub-type (extend or implement) $handlingClass; otherwise you will run into trouble. | ||
* | ||
* Aliases can only be one level deep, | ||
* | ||
* i.e. aliasClass -> handlingClass is supported, | ||
* but aliasClass -> anotherAliasClass -> handlingClass is not. | ||
* | ||
* @param string $handlingClass The class that should be aliased, i.e. MyDateTime | ||
* @param string $aliasClass The class that should be used instead, i.e. DateTime | ||
*/ | ||
public static function addAliasFor($handlingClass, $aliasClass) | ||
{ | ||
self::$aliases[$handlingClass] = $aliasClass; | ||
} | ||
|
||
public static function addHandlerFor($handlingClass, $handlerInstanceOrClassName) | ||
{ | ||
if ( ! $handlerInstanceOrClassName instanceof ObjectBasicsHandler && ! is_string($handlerInstanceOrClassName)) { | ||
throw new \LogicException('$handler must be an instance of ObjectBasicsHandler, or a string referring to the handlers class.'); | ||
} | ||
|
||
self::$handlers[$handlingClass] = $handlerInstanceOrClassName; | ||
} | ||
|
||
public static function getHandler($className) | ||
{ | ||
if (isset(self::$aliases[$className])) { | ||
$className = self::$aliases[$className]; | ||
} | ||
|
||
if ( ! isset(self::$handlers[$className])) { | ||
if (self::$defaultObjectHandler === null) { | ||
self::$defaultObjectHandler = new IdentityHandler(); | ||
} | ||
|
||
return self::$defaultObjectHandler; | ||
} | ||
|
||
if (self::$handlers[$className] instanceof ObjectBasicsHandler) { | ||
return self::$handlers[$className]; | ||
} | ||
|
||
if (is_string(self::$handlers[$className])) { | ||
$handlerClass = self::$handlers[$className]; | ||
|
||
return self::$handlers[$className] = new $handlerClass(); | ||
} | ||
|
||
throw new \LogicException(sprintf( | ||
'Unknown handler type ("%s") for class "%s" - should never be reached.', | ||
gettype(self::$handlers[$className]), | ||
$className | ||
)); | ||
} | ||
|
||
private final function __construct() { } | ||
} |
Oops, something went wrong.