1<?php 2/* 3 * This file is part of the Comparator package. 4 * 5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11namespace SebastianBergmann\Comparator; 12 13/** 14 * Factory for comparators which compare values for equality. 15 */ 16class Factory 17{ 18 /** 19 * @var Comparator[] 20 */ 21 private $comparators = array(); 22 23 /** 24 * @var Factory 25 */ 26 private static $instance; 27 28 /** 29 * Constructs a new factory. 30 */ 31 public function __construct() 32 { 33 $this->register(new TypeComparator); 34 $this->register(new ScalarComparator); 35 $this->register(new NumericComparator); 36 $this->register(new DoubleComparator); 37 $this->register(new ArrayComparator); 38 $this->register(new ResourceComparator); 39 $this->register(new ObjectComparator); 40 $this->register(new ExceptionComparator); 41 $this->register(new SplObjectStorageComparator); 42 $this->register(new DOMNodeComparator); 43 $this->register(new MockObjectComparator); 44 $this->register(new DateTimeComparator); 45 } 46 47 /** 48 * @return Factory 49 */ 50 public static function getInstance() 51 { 52 if (self::$instance === null) { 53 self::$instance = new self; 54 } 55 56 return self::$instance; 57 } 58 59 /** 60 * Returns the correct comparator for comparing two values. 61 * 62 * @param mixed $expected The first value to compare 63 * @param mixed $actual The second value to compare 64 * @return Comparator 65 */ 66 public function getComparatorFor($expected, $actual) 67 { 68 foreach ($this->comparators as $comparator) { 69 if ($comparator->accepts($expected, $actual)) { 70 return $comparator; 71 } 72 } 73 } 74 75 /** 76 * Registers a new comparator. 77 * 78 * This comparator will be returned by getInstance() if its accept() method 79 * returns TRUE for the compared values. It has higher priority than the 80 * existing comparators, meaning that its accept() method will be tested 81 * before those of the other comparators. 82 * 83 * @param Comparator $comparator The registered comparator 84 */ 85 public function register(Comparator $comparator) 86 { 87 array_unshift($this->comparators, $comparator); 88 89 $comparator->setFactory($this); 90 } 91 92 /** 93 * Unregisters a comparator. 94 * 95 * This comparator will no longer be returned by getInstance(). 96 * 97 * @param Comparator $comparator The unregistered comparator 98 */ 99 public function unregister(Comparator $comparator) 100 { 101 foreach ($this->comparators as $key => $_comparator) { 102 if ($comparator === $_comparator) { 103 unset($this->comparators[$key]); 104 } 105 } 106 } 107} 108