diff --git a/spec/Phpro/SoapClient/CodeGenerator/Model/TypeSpec.php b/spec/Phpro/SoapClient/CodeGenerator/Model/TypeSpec.php index 52413438..645e5b65 100644 --- a/spec/Phpro/SoapClient/CodeGenerator/Model/TypeSpec.php +++ b/spec/Phpro/SoapClient/CodeGenerator/Model/TypeSpec.php @@ -56,6 +56,14 @@ function it_should_not_replace_underscores_in_paths() $this->getFileInfo('my/some_dir')->getPathname()->shouldReturn('my/some_dir/MyType32.php'); } + function it_should_prefix_reserved_keywords() + { + $this->beConstructedWith('MyNamespace', 'Final', ['xor' => 'string']); + $this->getFileInfo('my/some_dir')->getPathname()->shouldReturn('my/some_dir/FinalType.php'); + $this->getName()->shouldReturn('FinalType'); + $this->getProperties()[0]->getName()->shouldReturn('xorType'); + } + function it_has_properties() { $props = $this->getProperties(); diff --git a/spec/Phpro/SoapClient/CodeGenerator/Util/NormalizerSpec.php b/spec/Phpro/SoapClient/CodeGenerator/Util/NormalizerSpec.php index 77f043d5..b5fa5bde 100644 --- a/spec/Phpro/SoapClient/CodeGenerator/Util/NormalizerSpec.php +++ b/spec/Phpro/SoapClient/CodeGenerator/Util/NormalizerSpec.php @@ -4,7 +4,6 @@ use Phpro\SoapClient\CodeGenerator\Util\Normalizer; use PhpSpec\ObjectBehavior; -use Prophecy\Argument; /** * Class NormalizerSpec @@ -30,12 +29,14 @@ function it_can_normalize_namespace() function it_can_normalize_classnames() { $this->normalizeClassname('myType')->shouldReturn('MyType'); + $this->normalizeClassname('final')->shouldReturn('FinalType'); $this->normalizeClassname('my-./*type_123')->shouldReturn('MyType123'); } function it_noramizes_properties() { $this->normalizeProperty('prop1')->shouldReturn('prop1'); + $this->normalizeProperty('final')->shouldReturn('finalType'); $this->normalizeProperty('my-./*prop_123')->shouldReturn('myProp_123'); } @@ -73,7 +74,8 @@ function it_gets_classname_from_fqn() function it_gets_complete_use_statement() { - $this->getCompleteUseStatement('Namespace\MyClass', 'ClassAlias')->shouldReturn('Namespace\MyClass as ClassAlias'); + $this->getCompleteUseStatement('Namespace\MyClass', + 'ClassAlias')->shouldReturn('Namespace\MyClass as ClassAlias'); $this->getCompleteUseStatement('Namespace\MyClass', null)->shouldReturn('Namespace\MyClass'); $this->getCompleteUseStatement('MyClass', '')->shouldReturn('MyClass'); } diff --git a/src/Phpro/SoapClient/CodeGenerator/Model/Type.php b/src/Phpro/SoapClient/CodeGenerator/Model/Type.php index 8fcd8e03..4cc483d7 100644 --- a/src/Phpro/SoapClient/CodeGenerator/Model/Type.php +++ b/src/Phpro/SoapClient/CodeGenerator/Model/Type.php @@ -76,21 +76,22 @@ public function getXsdName(): string return $this->xsdName; } - /** * @param string $destination * * @return SplFileInfo */ - public function getFileInfo(string $destination) : SplFileInfo + public function getFileInfo(string $destination): SplFileInfo { - $path = rtrim($destination, '/\\').DIRECTORY_SEPARATOR.$this->getName().'.php'; + $name = Normalizer::normalizeClassname($this->getName()); + $path = rtrim($destination, '/\\').DIRECTORY_SEPARATOR.$name.'.php'; return new SplFileInfo($path); } /** * @param string $destination + * * @deprecated please use getFileInfo instead * @return string */ diff --git a/src/Phpro/SoapClient/CodeGenerator/Util/Normalizer.php b/src/Phpro/SoapClient/CodeGenerator/Util/Normalizer.php index e12aae83..1aa5eccc 100644 --- a/src/Phpro/SoapClient/CodeGenerator/Util/Normalizer.php +++ b/src/Phpro/SoapClient/CodeGenerator/Util/Normalizer.php @@ -11,20 +11,111 @@ class Normalizer { private static $normalizations = [ - 'long' => 'int', - 'short' => 'int', + 'long' => 'int', + 'short' => 'int', 'datetime' => '\\DateTime', - 'date' => '\\DateTime', - 'boolean' => 'bool', - 'decimal' => 'float', - 'double' => 'float', - 'string' => 'string', - 'self' => 'self', + 'date' => '\\DateTime', + 'boolean' => 'bool', + 'decimal' => 'float', + 'double' => 'float', + 'string' => 'string', + 'self' => 'self', 'callable' => 'callable', 'iterable' => 'iterable', - 'array' => 'array', + 'array' => 'array', ]; + /** + * @var array + * @see https://secure.php.net/manual/en/reserved.keywords.php + */ + private static $reservedKeywords = [ + '__halt_compiler', + 'abstract', + 'and', + 'array', + 'as', + 'break', + 'callable', + 'case', + 'catch', + 'class', + 'clone', + 'const', + 'continue', + 'declare', + 'default', + 'die', + 'do', + 'echo', + 'else', + 'elseif', + 'empty', + 'enddeclare', + 'endfor', + 'endforeach', + 'endif', + 'endswitch', + 'endwhile', + 'eval', + 'exit', + 'extends', + 'final', + 'finally', + 'for', + 'foreach', + 'function', + 'global', + 'goto', + 'if', + 'implements', + 'include', + 'include_once', + 'instanceof', + 'insteadof', + 'interface', + 'isset', + 'list', + 'namespace', + 'new', + 'or', + 'print', + 'private', + 'protected', + 'public', + 'require', + 'require_once', + 'return', + 'static', + 'switch', + 'throw', + 'trait', + 'try', + 'unset', + 'use', + 'var', + 'while', + 'xor', + 'yield', + ]; + + /** + * @param string $name + * @param bool $ucfirst + * + * @return string + */ + private static function normalizeReservedKeywords(string $name, $ucfirst = true): string + { + if (!\in_array(strtolower($name), self::$reservedKeywords, true)) { + return $name; + } + $name = ucfirst($name); + $name .= 'Type'; + + return $ucfirst ? ucfirst($name) : lcfirst($name); + } + /** * @param string $namespace * @@ -36,12 +127,13 @@ public static function normalizeNamespace(string $namespace): string } /** - * @param $name + * @param string $name * * @return string */ - public static function normalizeClassname($name): string + public static function normalizeClassname(string $name): string { + $name = self::normalizeReservedKeywords($name); $className = trim(preg_replace('{[^a-z0-9]+}i', ' ', $name)); $className = ucwords($className); @@ -49,12 +141,13 @@ public static function normalizeClassname($name): string } /** - * @param $property + * @param string $property * - * @return mixed + * @return string */ - public static function normalizeProperty($property) + public static function normalizeProperty(string $property) { + $property = self::normalizeReservedKeywords($property, false); $property = trim(preg_replace('{[^a-z0-9_]}i', ' ', $property)); $property = ucwords($property); $property = lcfirst($property); @@ -108,10 +201,10 @@ public static function getClassNameFromFQN(string $name): string * * @return string */ - public static function getCompleteUseStatement(string $useName, $useAlias): string + public static function getCompleteUseStatement(string $useName, string $useAlias = null): string { $use = $useName; - if (!empty($useAlias)) { + if (null !== $useAlias && $useAlias !== '') { $use .= ' as '.$useAlias; }