public function getPath(ClassGenerator $php) { foreach ($this->namespaces as $namespace => $dir) { if (strpos(trim($php->getNamespaceName()) . "\\", $namespace) === 0) { $d = strtr(substr($php->getNamespaceName(), strlen($namespace)), "\\", "/"); $dir = rtrim($dir, "/") . "/" . $d; if (!is_dir($dir) && !mkdir($dir, 0777, true)) { throw new PathGeneratorException("Can't create the '{$dir}' directory"); } return rtrim($dir, "/") . "/" . $php->getName() . ".php"; } } throw new PathGeneratorException("Can't find a defined location where save '{$php->getNamespaceName()}\\{$php->getName()}' object"); }
/** * Write generated code to disk and return the class code * * {@inheritDoc} */ public function generate(ClassGenerator $classGenerator) { $className = trim($classGenerator->getNamespaceName(), '\\') . '\\' . trim($classGenerator->getName(), '\\'); $generatedCode = $classGenerator->generate(); $fileName = $this->fileLocator->getProxyFileName($className); $tmpFileName = $fileName . '.' . uniqid('', true); // renaming files is necessary to avoid race conditions when the same file is written multiple times // in a short time period file_put_contents($tmpFileName, "<?php\n\n" . $generatedCode); rename($tmpFileName, $fileName); return $generatedCode; }
/** * Write generated code to disk and return the class code * * {@inheritDoc} */ public function generate(ClassGenerator $classGenerator) { $className = trim($classGenerator->getNamespaceName(), '\\') . '\\' . trim($classGenerator->getName(), '\\'); $generatedCode = $classGenerator->generate(); $fileName = $this->fileLocator->getProxyFileName($className); set_error_handler($this->emptyErrorHandler); try { $this->writeFile("<?php\n\n" . $generatedCode, $fileName); } catch (FileNotWritableException $fileNotWritable) { restore_error_handler(); throw $fileNotWritable; } restore_error_handler(); return $generatedCode; }
/** * @param ClassGenerator $classGenerator * @return string * @throws FileNotWritableException */ public function generate(ClassGenerator $classGenerator) { $className = trim($classGenerator->getNamespaceName(), '\\') . '\\' . trim($classGenerator->getName(), '\\'); $generatedCode = $classGenerator->generate(); $fileName = $this->file->getProxyFileName($className); set_error_handler(function () { }); try { $this->write("<?php\n\n" . $generatedCode, $fileName); } catch (FileNotWritableException $exception) { throw $exception; } finally { restore_error_handler(); } return $fileName; }
/** * Generates a dynamic class implementing specified interfaces (and ServiceAwareInterface). * @return string class name */ public function build() { $generator = new ClassGenerator(uniqid('Proxy_'), 'SoPhp\\Rpc\\Proxy'); $generator->setImplementedInterfaces($this->getImplements()); $generator->setExtendedClass('\\SoPhp\\Rpc\\Proxy\\ProxyAbstract'); $source = $generator->generate(); $className = $generator->getNamespaceName() . '\\' . $generator->getName(); try { eval($source); } catch (\Exception $e) { throw new BuildFailed("Could not evaluate source code for proxy. " . $source, 0, $e); } if (!class_exists($className, false)) { throw new BuildFailed("Proxy class `{$className}` does not exist"); } return $className; }
/** * @group namespace */ public function testSetNameShouldDetermineIfNamespaceSegmentIsPresent() { $classGeneratorClass = new ClassGenerator(); $classGeneratorClass->setName('My\Namespaced\FunClass'); $this->assertEquals('My\Namespaced', $classGeneratorClass->getNamespaceName()); }
/** * {@inheritdoc} */ public function getNamespaceName() { return ltrim(parent::getNamespaceName(), '\\'); }
/** * Write a class to disk. * * @param ClassGenerator $classGenerator Representation of class to write * @param string $module Module in which to write class * @param bool $allowOverwrite Allow overwrite of existing file? * @param bool $skipBackup Should we skip backing up the file? * * @return void * @throws \Exception */ protected function writeClass(ClassGenerator $classGenerator, $module, $allowOverwrite = false, $skipBackup = false) { // Use the class name parts from the previous step to determine a path // and filename, then create the new path. $parts = explode('\\', $classGenerator->getNamespaceName()); array_unshift($parts, 'module', $module, 'src'); $this->createTree($parts); // Generate the new class: $generator = FileGenerator::fromArray(['classes' => [$classGenerator]]); $filename = $classGenerator->getName() . '.php'; $fullPath = APPLICATION_PATH . '/' . implode('/', $parts) . '/' . $filename; if (file_exists($fullPath)) { if ($allowOverwrite) { if (!$skipBackup) { $this->backUpFile($fullPath); } } else { throw new \Exception("{$fullPath} already exists."); } } if (!file_put_contents($fullPath, $generator->generate())) { throw new \Exception("Problem writing to {$fullPath}."); } Console::writeLine("Saved file: {$fullPath}"); }
/** * Fill file level phpdoc * * @param ClassGenerator $class contained class */ protected function defineFileInfo(ClassGenerator $class) { $doc = DocBlockGenerator::fromArray(array('shortDescription' => 'Contains ' . $class->getName() . ' class file', 'longDescription' => 'Generated Automatically.' . PHP_EOL . 'Please do not modify', 'tags' => array(array('name' => 'author', 'description' => $this->data['_author']), array('name' => 'license', 'description' => $this->data['_license']), array('name' => 'package', 'description' => $class->getNamespaceName())))); $this->fileGenerator->setDocBlock($doc); }
/** * Copied from ClassGenerator::fromReflection and tweaked slightly * @param ClassReflection $classReflection * * @return ClassGenerator */ public function getGeneratorFromReflection(ClassReflection $classReflection) { // class generator $cg = new ClassGenerator($classReflection->getName()); $cg->setSourceContent($cg->getSourceContent()); $cg->setSourceDirty(false); if ($classReflection->getDocComment() != '') { $docblock = DocBlockGenerator::fromReflection($classReflection->getDocBlock()); $docblock->setIndentation(Generator::$indentation); $cg->setDocBlock($docblock); } $cg->setAbstract($classReflection->isAbstract()); // set the namespace if ($classReflection->inNamespace()) { $cg->setNamespaceName($classReflection->getNamespaceName()); } /* @var \Zend\Code\Reflection\ClassReflection $parentClass */ $parentClass = $classReflection->getParentClass(); if ($parentClass) { $cg->setExtendedClass('\\' . ltrim($parentClass->getName(), '\\')); $interfaces = array_diff($classReflection->getInterfaces(), $parentClass->getInterfaces()); } else { $interfaces = $classReflection->getInterfaces(); } $interfaceNames = array(); foreach ($interfaces as $interface) { /* @var \Zend\Code\Reflection\ClassReflection $interface */ $interfaceNames[] = $interface->getName(); } $cg->setImplementedInterfaces($interfaceNames); $properties = array(); foreach ($classReflection->getProperties() as $reflectionProperty) { if ($reflectionProperty->getDeclaringClass()->getName() == $classReflection->getName()) { $property = PropertyGenerator::fromReflection($reflectionProperty); $property->setIndentation(Generator::$indentation); $properties[] = $property; } } $cg->addProperties($properties); $methods = array(); foreach ($classReflection->getMethods() as $reflectionMethod) { $className = $cg->getNamespaceName() ? $cg->getNamespaceName() . "\\" . $cg->getName() : $cg->getName(); if ($reflectionMethod->getDeclaringClass()->getName() == $className) { $method = MethodGenerator::fromReflection($reflectionMethod); $method->setBody(preg_replace("/^\\s+/m", '', $method->getBody())); $method->setIndentation(Generator::$indentation); $methods[] = $method; } } $cg->addMethods($methods); return $cg; }
/** * Serialize to disk the given class code * * @param \Zend\Code\Generator\ClassGenerator $class */ protected function serializeClass(ClassGenerator $class) { // serialize the class $fs = new Filesystem(); $file = new FileGenerator(array('class' => $class)); $outputPath = array($this->config->getOutputPath()); // if the psr0 autoloader has been selected, transform the class namespace into a filesystem path if ($this->config->getAutoloader() === Config::AUTOLOADER_PSR0) { $outputPath[] = str_ireplace('\\', DIRECTORY_SEPARATOR, $class->getNamespaceName()); } // append the file name $outputPath[] = $class->getName() . '.php'; // finalize the output path $outputPath = implode(DIRECTORY_SEPARATOR, $outputPath); $fs->mkdir(dirname($outputPath)); file_put_contents($outputPath, $file->generate()); }