1<?php 2 3/* 4 * This file is part of the Prophecy. 5 * (c) Konstantin Kudryashov <ever.zet@gmail.com> 6 * Marcello Duarte <marcello.duarte@gmail.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Prophecy\Doubler; 13 14use ReflectionClass; 15 16/** 17 * Cached class doubler. 18 * Prevents mirroring/creation of the same structure twice. 19 * 20 * @author Konstantin Kudryashov <ever.zet@gmail.com> 21 */ 22class CachedDoubler extends Doubler 23{ 24 private $classes = array(); 25 26 /** 27 * {@inheritdoc} 28 */ 29 public function registerClassPatch(ClassPatch\ClassPatchInterface $patch) 30 { 31 $this->classes[] = array(); 32 33 parent::registerClassPatch($patch); 34 } 35 36 /** 37 * {@inheritdoc} 38 */ 39 protected function createDoubleClass(ReflectionClass $class = null, array $interfaces) 40 { 41 $classId = $this->generateClassId($class, $interfaces); 42 if (isset($this->classes[$classId])) { 43 return $this->classes[$classId]; 44 } 45 46 return $this->classes[$classId] = parent::createDoubleClass($class, $interfaces); 47 } 48 49 /** 50 * @param ReflectionClass $class 51 * @param ReflectionClass[] $interfaces 52 * 53 * @return string 54 */ 55 private function generateClassId(ReflectionClass $class = null, array $interfaces) 56 { 57 $parts = array(); 58 if (null !== $class) { 59 $parts[] = $class->getName(); 60 } 61 foreach ($interfaces as $interface) { 62 $parts[] = $interface->getName(); 63 } 64 sort($parts); 65 66 return md5(implode('', $parts)); 67 } 68} 69