diff --git a/src/Zynga/Framework/Factory/V2/Base.hh b/src/Zynga/Framework/Factory/V2/Base.hh index 35cd9e9..16e77d3 100644 --- a/src/Zynga/Framework/Factory/V2/Base.hh +++ b/src/Zynga/Framework/Factory/V2/Base.hh @@ -131,6 +131,69 @@ abstract class Base implements FactoryInterface { } } + + public static function getDriverByClassname( + classname $driverName, + string $configName, + ): TDriver { + + try { + + $template = self::getFactoryTemplate(); + + if ($template->getUseMockDrivers() === true) { + + // -- + // First we run the driver as is to prevent people from using + // non-existant configs and invalid configs. Then we discard the driver + // and override it with the mock one. + // -- + $driver = $template->getDriverByClassname($driverName, $configName); + + $name = 'Mock'; + + } + + $driver = $template->getDriverByClassname($driverName, $configName); + + // -- + // JEO: And a word from our sponsor, so what we are doing here is refining + // the generic type that is stored within the template to the actual + // driver that user is wanting to have. + // -- + /* HH_FIXME[4162]: Instanceof on a generic classname is now an error. + * Consider using different logic to avoid use of classname. + */ + if ($driver instanceof $driverName) { + return $driver; + } + + $classImplements = ''; + + if (is_object($driver)) { + + $raw = class_implements($driver); + if ($raw !== false && is_array($raw)) { + $classImplements = implode(', ', $raw); + } + } + + throw new FailedToLoadDriverException( + 'Failed to load driver for driver name='. + $driverName. + ' classType='. + get_class($driver). + ' classImplements='. + $classImplements. + ' configName='. + $configName, + ); + + } catch (Exception $e) { + throw $e; + } + + } public static function clear(): bool { diff --git a/src/Zynga/Framework/Factory/V2/Interfaces/FactoryInterface.hh b/src/Zynga/Framework/Factory/V2/Interfaces/FactoryInterface.hh index 421c87e..77cef54 100644 --- a/src/Zynga/Framework/Factory/V2/Interfaces/FactoryInterface.hh +++ b/src/Zynga/Framework/Factory/V2/Interfaces/FactoryInterface.hh @@ -21,6 +21,11 @@ interface FactoryInterface { classname $driverName, string $name, ): TDriver; + + public static function getDriverByClassname( + classname $driverName, + string $configName, + ): TDriver; public static function clear(): bool; diff --git a/src/Zynga/Framework/Factory/V2/Interfaces/FactoryTemplateInterface.hh b/src/Zynga/Framework/Factory/V2/Interfaces/FactoryTemplateInterface.hh index 119b4b5..45c824c 100644 --- a/src/Zynga/Framework/Factory/V2/Interfaces/FactoryTemplateInterface.hh +++ b/src/Zynga/Framework/Factory/V2/Interfaces/FactoryTemplateInterface.hh @@ -58,6 +58,11 @@ interface FactoryTemplateInterface { * @return DriverInterface */ public function factory(string $name): DriverInterface; + + public function getDriverByClassname( + classname $driverName, + string $configName, + ): DriverInterface; /** * Clears all drivers from the factory. diff --git a/src/Zynga/Framework/Factory/V2/Template.hh b/src/Zynga/Framework/Factory/V2/Template.hh index ff781a6..1373095 100644 --- a/src/Zynga/Framework/Factory/V2/Template.hh +++ b/src/Zynga/Framework/Factory/V2/Template.hh @@ -258,6 +258,53 @@ class Template implements FactoryTemplateInterface { } } + + /** + * Responsible for creating or returning driver for this factory template. + * @return DriverInterface + */ + public function getDriverByClassname( + classname $driverName, + string $configName, + ): DriverInterface { + + try { + + // if the driver is already stood up, return it. + $driverContainer = $this->_drivers; + + $driver = null; + + if ($driverContainer->isDriverCached($driverName) === true) { + return $driverContainer->getDriverFromCache($driverName); + } + + $driver = null; + + if (DynamicClassCreation::doesClassExist($driverName) === true) { + + $config = $this->getConfigForName($configName); + // Try to stand up the driver shell + $driver = DynamicClassCreation::createClassByNameGeneric( + $driverName, + Vector {$config}, + ); + + // cache the driver + $driverContainer->addDriverToCache($driverName, $driver); + + // return the driver + return $driverContainer->getDriverFromCache($driverName); + + } + + throw new FailedToLoadDriverException('driverName='.$driverName.' . configName='.$configName); + + } catch (Exception $e) { + throw $e; + } + + } /** * Clears all drivers from the factory.