/** * @param SchemaId|string $id * @param array $parameters */ public function __construct($id, array $parameters = []) { $this->id = $id instanceof SchemaId ? $id : SchemaId::fromString($id); foreach ($parameters as $key => $value) { $classProperty = lcfirst(StringUtils::toCamelFromSlug($key)); // existing properties if (property_exists(get_called_class(), $classProperty)) { switch ($classProperty) { case 'isMixin': case 'isLatestVersion': case 'deprecated': $value = (bool) $value; break; case 'fields': $fields = []; /** @var FieldDescriptor $field */ foreach ($value as $field) { $fields[$field->getName()] = $field; } $value = $fields; break; case 'mixins': $mixins = []; /** @var SchemaDescriptor $mixin */ foreach ($value as $mixin) { $mixins[$mixin->getId()->getCurieWithMajorRev()] = $mixin; } $value = $mixins; break; } $this->{$classProperty} = $value; } } }
/** * @param Schema $schema * @param \stdClass $rootObject * @param string $path * @return array */ protected function mapSchema(Schema $schema, \stdClass $rootObject, $path = null) { $map = []; foreach ($schema->getFields() as $field) { $fieldName = $field->getName(); $type = $field->getType(); $fieldPath = empty($path) ? $fieldName : $path . '.' . $fieldName; if ($fieldName === Schema::PBJ_FIELD_NAME) { $map[$fieldName] = ['type' => 'string', 'index' => 'not_analyzed', 'include_in_all' => false]; continue; } $method = 'map' . ucfirst(StringUtils::toCamelFromSlug($type->getTypeValue())); if ($field->isAMap()) { $templateName = str_replace('-', '_', SlugUtils::create($fieldPath . '-template')); if (is_callable([$this, $method])) { $rootObject->dynamic_templates[] = [$templateName => ['path_match' => $fieldPath . '.*', 'mapping' => $this->{$method}($field, $rootObject, $fieldPath)]]; } else { $rootObject->dynamic_templates[] = [$templateName => ['path_match' => $fieldPath . '.*', 'mapping' => $this->applyAnalyzer($this->types[$type->getTypeValue()], $field, $rootObject, $path)]]; } } else { if (is_callable([$this, $method])) { $map[$fieldName] = $this->{$method}($field, $rootObject, $fieldPath); } else { $map[$fieldName] = $this->applyAnalyzer($this->types[$type->getTypeValue()], $field, $rootObject, $path); } } } return $map; }
/** * @param SchemaDescriptor $schema * @param string $filename * @param string $directory * @param bool $isLatest * * @return string */ protected function getSchemaTarget(SchemaDescriptor $schema, $filename, $directory = null, $isLatest = false) { $filename = str_replace(['{vendor}', '{package}', '{category}', '{version}', '{major}'], [$schema->getId()->getVendor(), $schema->getId()->getPackage(), $schema->getId()->getCategory(), $schema->getId()->getVersion()->toString(), $schema->getId()->getVersion()->getMajor()], $filename); if ($directory === null) { $directory = sprintf('%s/%s/%s', StringUtils::toCamelFromSlug($schema->getId()->getVendor()), StringUtils::toCamelFromSlug($schema->getId()->getPackage()), StringUtils::toCamelFromSlug($schema->getId()->getCategory())); } if ($directory) { $directory .= '/'; } return sprintf('%s/%s%s%s', $this->compileOptions->getOutput(), $directory, $filename, $this->extension); }
/** * @param SchemaDescriptor $schema * @param bool $majorRev * @param string $baseClassName * @param bool $withAs * * @return string */ public function getClassName(SchemaDescriptor $schema, $majorRev = false, $baseClassName = null, $withAs = false) { $className = StringUtils::toCamelFromSlug($schema->getId()->getMessage()); if ($majorRev) { $className = sprintf('%sV%d', StringUtils::toCamelFromSlug($schema->getId()->getMessage()), $schema->getId()->getVersion()->getMajor()); } if ($baseClassName == $className) { $classNameBase = sprintf('%s%s%s', StringUtils::toCamelFromSlug($schema->getId()->getVendor()), StringUtils::toCamelFromSlug($schema->getId()->getPackage()), $className); if ($withAs) { $className = sprintf('%s as %s', $className, $classNameBase); } else { $className = $classNameBase; } } return $className; }
/** * @param string $name * @param array $parameters * * @throws \InvalidArgumentException */ public function __construct($name, array $parameters) { if (!$name || strlen($name) > 127 || preg_match(self::VALID_NAME_PATTERN, $name) === false) { throw new \InvalidArgumentException(sprintf('Field [%s] must match pattern [%s] with less than 127 characters.', $name, self::VALID_NAME_PATTERN)); } foreach ($parameters as $key => $value) { $classProperty = lcfirst(StringUtils::toCamelFromSlug($key)); // existing properties if (property_exists(get_called_class(), $classProperty)) { switch ($classProperty) { case 'name': case 'languages': continue 2; case 'type': /** @var \Gdbots\Pbjc\Type\Type $class */ $class = sprintf('\\Gdbots\\Pbjc\\Type\\%sType', StringUtils::toCamelFromSlug($parameters['type'])); $value = $class::create(); break; case 'rule': if (null !== $value && in_array($value, FieldRule::values())) { $value = FieldRule::create($value); } break; case 'format': if (null !== $value && in_array($value, Format::values())) { $value = Format::create($value); } break; case 'required': case 'useTypeDefault': case 'overridable': case 'deprecated': $value = (bool) $value; break; case 'min': case 'max': case 'minLength': case 'maxLength': case 'precision': case 'scale': $value = (int) $value; break; } $this->{$classProperty} = $value; } elseif (substr($key, -8) == '-options') { $language = substr($key, 0, -8); // remove "-options" if (is_array($value)) { $value = new LanguageBag($value); } $this->getLanguages()->set($language, $value); } } $this->name = $name; $this->applyDefaults(); $this->applyFieldRule(); $this->applyStringOptions(); $this->applyNumericOptions(); }
/** * @param string $slug * * @return string */ public function toCamelFromSlug($slug) { return StringUtils::toCamelFromSlug($slug); }
/** * {@inheritdoc} */ public function generateManifest(array $schemas) { $messages = []; if (!($filename = $this->compileOptions->getManifest())) { return; } // extract previous schemas if (file_exists($filename)) { $content = file_get_contents($filename); if (preg_match_all('/\'([a-z0-9-]+:[a-z0-9\\.-]+:[a-z0-9-]+?:[a-z0-9-]+(:v[0-9]+)?)\' => \'(.*)\'/', $content, $matches) !== false) { foreach ($matches[1] as $key => $value) { $messages[$value] = $matches[3][$key]; } } } // merge with selected schemas (only non-mixin schema's) /** @var SchemaDescriptor $schema */ foreach ($schemas as $schema) { if ($schema->isMixinSchema()) { continue; } if (!array_key_exists($schema->getId()->getCurie(), $messages)) { $messages[$schema->getId()->getCurie()] = sprintf('%s\\%sV%d', $schema->getLanguage('php')->get('namespace'), StringUtils::toCamelFromSlug($schema->getId()->getMessage()), $schema->getId()->getVersion()->getMajor()); } if (SchemaStore::hasOtherSchemaMajorRev($schema->getId())) { /** @var SchemaDescriptor $s */ foreach (SchemaStore::getOtherSchemaMajorRev($schema->getId()) as $s) { if (!array_key_exists($s->getId()->getCurieWithMajorRev(), $messages)) { $messages[$s->getId()->getCurieWithMajorRev()] = sprintf('%s\\%sV%d', $s->getLanguage('php')->get('namespace'), StringUtils::toCamelFromSlug($s->getId()->getMessage()), $s->getId()->getVersion()->getMajor()); } } } } // delete invalid schemas foreach ($messages as $key => $value) { if (!SchemaStore::getSchemaById($key, true)) { unset($messages[$key]); } } $response = new GeneratorResponse(); $response->addFile($this->renderFile('manifest.twig', $filename, ['messages' => $messages])); return $response; }
/** * Generates and writes files for each schema. * * @param string $language * @param CompileOptions $options * * @throws \InvalidArgumentException */ public function run($language, CompileOptions $options) { $namespaces = $options->getNamespaces(); if (!$namespaces || count($namespaces) === 0) { throw new \InvalidArgumentException('Missing "namespaces" options.'); } if (!is_array($namespaces)) { $namespaces = [$namespaces]; } foreach ($namespaces as $namespace) { if (!preg_match('/^([a-z0-9-]+):([a-z0-9\\.-]+)$/', $namespace)) { throw new \InvalidArgumentException(sprintf('The namespace "%s" must follow "vendor:package" format.', $namespace)); } } if (!$options->getOutput()) { throw new \InvalidArgumentException('Missing "output" directory options.'); } $class = sprintf('\\Gdbots\\Pbjc\\Generator\\%sGenerator', StringUtils::toCamelFromSlug($language)); /** @var \Gdbots\Pbjc\Generator\Generator $generator */ $generator = new $class($options); $outputFiles = []; /** @var EnumDescriptor $enum */ foreach (SchemaStore::getEnums() as $enum) { if (!$options->getIncludeAll() && !in_array($enum->getId()->getNamespace(), $namespaces)) { continue; } /** @var $response \Gdbots\Pbjc\Generator\GeneratorResponse */ if ($response = $generator->generateEnum($enum)) { $outputFiles = array_merge($outputFiles, $response->getFiles()); } } /** @var SchemaDescriptor $schema */ foreach (SchemaStore::getSchemas() as $schema) { if (!$options->getIncludeAll() && !in_array($schema->getId()->getNamespace(), $namespaces)) { continue; } /** @var $response \Gdbots\Pbjc\Generator\GeneratorResponse */ if ($response = $generator->generateSchema($schema)) { $outputFiles = array_merge($outputFiles, $response->getFiles()); } } if ($options->getManifest()) { /** @var $response \Gdbots\Pbjc\Generator\GeneratorResponse */ if ($response = $generator->generateManifest(SchemaStore::getSchemas())) { $outputFiles = array_merge($outputFiles, $response->getFiles()); } } if ($callback = $options->getCallback()) { foreach ($outputFiles as $outputFile) { call_user_func($callback, $outputFile); } } }