/**
  * @return Config
  */
 public function build()
 {
     $config = new Config('cs278', 'Chris Smith\'s personal coding standard.');
     $config->setUsingCache(true);
     $config->level(FixerInterface::SYMFONY_LEVEL);
     $config->fixers(['newline_after_open_tag', 'ordered_use', 'phpdoc_order', 'short_array_syntax']);
     $config->finder($this->finder);
     return $config;
 }
Example #2
0
 /**
  * Execute the code generation
  */
 public function generate()
 {
     /*
      * PROXY CONFIGURATION
      */
     $proxy = current(array_filter(array(getenv('HTTP_PROXY'), getenv('http_proxy')), 'strlen'));
     if ($proxy) {
         $parsedWsdlPath = Url::createFromUrl($this->config->getWsdlDocumentPath());
         // if not fetching the wsdl file from filesystem and a proxy has been set
         if ($parsedWsdlPath->getScheme()->get() !== 'file') {
             $proxy = Url::createFromUrl($proxy);
             libxml_set_streams_context(stream_context_get_default(array($proxy->getScheme()->get() => array('proxy' => 'tcp://' . $proxy->getAuthority() . $proxy->getRelativeUrl(), 'request_fulluri' => true))));
         }
     }
     unset($proxy);
     /*
      * LOAD THE WSDL DOCUMENT
      */
     $wsdlDocument = SimpleXMLElement::loadFile($this->config->getWsdlDocumentPath());
     $wsdlDocument->registerXPathNamespace('wsdl', static::WSDL_NS);
     $schemaReader = new SchemaReader();
     /* @var \Goetas\XML\XSDReader\Schema\Schema[] $schemas */
     $schemas = array();
     /* @var \Goetas\XML\XSDReader\Schema\Type\Type[] $types */
     $types = array();
     /*
      * LOAD THE XML SCHEMAS
      */
     // read the schemas included in the wsdl document
     foreach ($wsdlDocument->xpath('/wsdl:definitions/wsdl:types/xsd:schema') as $schemaNode) {
         $schemas[] = $schemaReader->readNode(dom_import_simplexml($schemaNode));
     }
     // exclude the schemas having the following namespaces
     $unusedSchemaNamespaces = array(SchemaReader::XML_NS, SchemaReader::XSD_NS);
     // recursively read all the schema chain
     $processedSchemas = array();
     while (!empty($schemas)) {
         /* @var \Goetas\XML\XSDReader\Schema\Schema $currentSchema */
         $currentSchema = array_shift($schemas);
         if (!in_array($currentSchema, $processedSchemas) and !in_array($currentSchema->getTargetNamespace(), $unusedSchemaNamespaces)) {
             $processedSchemas[] = $currentSchema;
             $schemas = array_merge($schemas, $currentSchema->getSchemas());
         }
     }
     $schemas = $processedSchemas;
     // cleanup
     unset($currentSchema);
     unset($processedSchemas);
     unset($unusedSchemaNamespaces);
     unset($schemaNode);
     unset($schemaReader);
     /*
      * LOAD THE DEFINED TYPES
      */
     // get the complete list of defined types
     foreach ($schemas as $schema) {
         $types = array_merge($types, $schema->getTypes());
     }
     /*
      * LOAD THE SERVICES
      */
     $services = $wsdlDocument->xpath('/wsdl:definitions/wsdl:portType');
     /*
      * CODE GENERATION
      */
     $classFactory = new ClassFactory($this->config, $schemas, $types);
     foreach ($types as $type) {
         if ($type instanceof SimpleType) {
             // build the inheritance chain of the current SimpleType
             /* @var \Goetas\XML\XSDReader\Schema\Type\SimpleType[] $inheritanceChain */
             $inheritanceChain = array($type->getRestriction());
             // loop through the type inheritance chain untill the base type
             while (end($inheritanceChain) !== null) {
                 $inheritanceChain[] = end($inheritanceChain)->getBase()->getParent();
             }
             // remove the null value
             array_pop($inheritanceChain);
             // remove the 'anySimpleType'
             array_pop($inheritanceChain);
             // now the last element of the chain is the base simple type
             // enums are built only of string enumerations
             if (end($inheritanceChain)->getBase()->getName() === 'string' and array_key_exists('enumeration', $type->getRestriction()->getChecks())) {
                 $className = $classFactory->createEnum($type);
                 $this->eventDispatcher->dispatch(Event::ENUM_CREATE, new Event($className));
             }
         } elseif ($type instanceof ComplexType) {
             $className = $classFactory->createDTO($type);
             $this->eventDispatcher->dispatch(Event::DTO_CREATE, new Event($className));
         }
     }
     foreach ($services as $service) {
         $className = $classFactory->createService($service);
         $this->eventDispatcher->dispatch(Event::SERVICE_CREATE, new Event($className));
     }
     $className = $classFactory->createClassmap();
     $this->eventDispatcher->dispatch(Event::CLASSMAP_CREATE, new Event($className));
     /*
      * GENERATED CODE FIX
      */
     // create the coding standards fixer
     $fixer = new Fixer();
     $config = new FixerConfig();
     $config->setDir($this->config->getOutputPath());
     // register all the existing fixers
     $fixer->registerBuiltInFixers();
     $config->fixers(array_filter($fixer->getFixers(), function (FixerInterface $fixer) {
         return $fixer->getLevel() === FixerInterface::PSR2_LEVEL;
     }));
     // fix the generated code
     $fixer->fix($config);
 }
 public function main()
 {
     try {
         /*
          * PROPERTIES VALIDATION
          */
         // check if the proxy flag has been set
         $proxy = $this->getProject()->getUserProperty('proxy');
         $proxy = $proxy !== null ? filter_var($proxy, FILTER_VALIDATE_BOOLEAN) : true;
         // determine the url of the WSDL document
         $wsdlUrl = $this->getProject()->getUserProperty('wsdl.url');
         $wsdlUrl = $wsdlUrl ? $wsdlUrl : static::WSDL_URL;
         /*
          * PROXY CONFIGURATION
          */
         // read the proxy configuration from the environment variables
         $proxy = $proxy ? current(array_filter(array(getenv('HTTP_PROXY'), getenv('http_proxy')), 'strlen')) : null;
         // prepare an empty url for the stream context
         $streamContextProxyUrl = null;
         // if the proxy is configured in the system
         if ($proxy) {
             // parse the WSDL url
             $parsedWsdlPath = Url::createFromUrl($wsdlUrl);
             // parse the proxy url
             $proxy = Url::createFromUrl($proxy);
             // if not fetching the wsdl file from filesystem and a proxy has been configured
             if ($parsedWsdlPath->getScheme()->get() !== 'file') {
                 $streamContextProxyUrl = 'tcp://' . $proxy->getAuthority() . $proxy->getRelativeUrl();
                 libxml_set_streams_context(stream_context_get_default(array($proxy->getScheme()->get() => array('proxy' => $streamContextProxyUrl, 'request_fulluri' => true))));
             }
         }
         /*
          * INITIALIZATION
          */
         // prepare the path to the generated code
         $outputDir = $this->project->getBasedir() . '/src';
         $output = new ConsoleOutput();
         $progress = new ProgressBar($output, 100);
         $progress->setFormat(ProgressBar::getFormatDefinition('normal') . ' %message%...');
         $progress->setMessage('Starting');
         $progress->start();
         $progress->setMessage('Cleaning the environment');
         // clean the output directory
         array_map('unlink', glob($outputDir . '/*'));
         $progress->advance(10);
         /*
          * GENERATION
          */
         // prepare the generator configuration
         $progress->setMessage('Configuring the generator');
         $optionFeatures = array();
         if ($proxy) {
             /* @var \League\Url\UrlInterface $proxy */
             $optionFeatures['proxy_host'] = $proxy->getHost()->get();
             $optionFeatures['proxy_port'] = $proxy->getPort()->get();
         }
         $config = new Config($wsdlUrl, $outputDir);
         $config->setNoTypeConstructor(true);
         $config->setOptionFeatures($optionFeatures);
         $config->setCreateAccessors(false);
         $config->setWsdlCache(false);
         $progress->advance(10);
         // generate the code
         $progress->setMessage('Generating the code');
         $gen = new Generator();
         $gen->generate($config);
         $progress->advance(10);
         /*
          * FIX
          */
         // the 'optionFeatures' configuration options is misused by the generator:
         // it is correctly used as the default 'features' options of the service (its values are bitwised and put
         // in the service class constructor), but it is also used as the '$options' argument of the \SoapClient
         // class when it connects to the service to inspect it (hence the need to define the 'proxy_host' and
         // 'proxy_port' keys). this makes the generated code clash, so we need to fix it, removing the unneeded
         // values from the bitwise operation.
         $defaultFeatures = array('SOAP_SINGLE_ELEMENT_ARRAYS', 'SOAP_WAIT_ONE_WAY_CALLS');
         // fix the option 'features' management
         $fileContent = file_get_contents("{$outputDir}/ClabService.php");
         $fileContent = preg_replace('/(\\$options\\[\'features\'\\] = ).*/', '$1' . implode(' | ', $defaultFeatures) . ';', $fileContent, -1, $count);
         // if no features option has been found, they must be added manually
         if ($count === 0) {
             $fileContent = preg_replace('/parent::__construct/', "if (isset(\$options['features']) == false) {\n\$options['features'] = " . implode(' | ', $defaultFeatures) . ";\n}\n\nparent::__construct", $fileContent, -1, $count);
         }
         file_put_contents("{$outputDir}/ClabService.php", $fileContent);
         /*
          * LICENSE MANAGEMENT
          */
         $progress->setMessage('Applying the license to the generated files');
         // read the license header
         $licenseHeader = file_get_contents($this->project->getBasedir() . '/resources/license_header.txt');
         // print the license on top of every file
         foreach (glob($outputDir . '/*.php') as $sourceFile) {
             $fileContent = file_get_contents($sourceFile);
             $fileContent = preg_replace('/^(<\\?php)/', "\$1\n\n" . $licenseHeader, $fileContent);
             file_put_contents($sourceFile, $fileContent);
         }
         unset($sourceFile);
         $progress->advance(10);
         /*
          * CODING STANDARDS FIXES
          */
         // create the coding standards fixer
         $progress->setMessage('Configuring the Coding Standards fixer');
         $fixer = new Fixer();
         $csConfig = new CSConfig();
         $csConfig->setDir($outputDir);
         $progress->advance(10);
         // register all the existing fixers
         $fixer->registerBuiltInFixers();
         $progress->advance(10);
         // register all fixers from all PSR levels
         /* @var $csFixer \Symfony\CS\FixerInterface */
         $fixers = array();
         foreach ($fixer->getFixers() as $csFixer) {
             if ($csFixer->getLevel() === ($csFixer->getLevel() & FixerInterface::PSR2_LEVEL)) {
                 $fixers[] = $csFixer;
             }
         }
         // fix the generated code
         $progress->setMessage('Fixing the generated code');
         $csConfig->fixers($fixers);
         $progress->advance(10);
         $fixer->fix($csConfig);
         $progress->advance(10);
         $progress->setFormat(ProgressBar::getFormatDefinition('normal') . ' %message%');
         $progress->setMessage('Done');
         $progress->finish();
         $output->writeln('');
     } catch (\Exception $e) {
         $this->log($e->getMessage(), \Project::MSG_ERR);
     }
 }