graphql_core_schema-1.0.x-dev/modules/graphql_translatable_config_pages/src/Plugin/GraphQL/SchemaExtension/TranslatableConfigPages.php
modules/graphql_translatable_config_pages/src/Plugin/GraphQL/SchemaExtension/TranslatableConfigPages.php
<?php
namespace Drupal\graphql_translatable_config_pages\Plugin\GraphQL\SchemaExtension;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\graphql\GraphQL\ResolverBuilder;
use Drupal\graphql\GraphQL\ResolverRegistryInterface;
use Drupal\graphql\Plugin\GraphQL\SchemaExtension\SdlSchemaExtensionPluginBase;
use Drupal\graphql_core_schema\CoreSchemaExtensionInterface;
use Drupal\graphql_core_schema\Plugin\GraphQL\SchemaExtension\CoreComposableConfigurableExtensionTrait;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A schema extension for config pages.
*
* @SchemaExtension(
* id = "translatable_config_pages",
* name = "Translatable Config Pages",
* description = "An extension that provides translatable config pages.",
* schema = "core_composable"
* )
*/
class TranslatableConfigPages extends SdlSchemaExtensionPluginBase implements CoreSchemaExtensionInterface {
use CoreComposableConfigurableExtensionTrait;
/**
* The entity type bundle info service.
*
* @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
*/
protected $entityTypeBundleInfo;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('module_handler'),
$container->get('entity_type.bundle.info')
);
}
/**
* TranslatableConfigPages constructor.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The entity type bundle info service.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
$module_handler,
EntityTypeBundleInfoInterface $entity_type_bundle_info,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler);
$this->entityTypeBundleInfo = $entity_type_bundle_info;
}
/**
* {@inheritdoc}
*/
public function getEntityTypeDependencies() {
return ['translatable_config_pages'];
}
/**
* {@inheritdoc}
*/
public function getExtensionDependencies() {
return [];
}
/**
* {@inheritdoc}
*/
public function getExtensionDefinition() {
$bundles = $this->getBundles();
if (empty($bundles)) {
return '';
}
$schema_lines = ["extend type Query {"];
foreach ($bundles as $bundle_id => $bundle_info) {
$field_name = $this->bundleToCamelCase($bundle_id) . 'Config';
$type_name = 'TranslatableConfigPages' . $this->bundleToPascalCase($bundle_id);
$schema_lines[] = " {$field_name}: {$type_name}";
}
$schema_lines[] = "}";
return implode("\n", $schema_lines);
}
/**
* {@inheritdoc}
*/
public function registerResolvers(ResolverRegistryInterface $registry): void {
$builder = new ResolverBuilder();
$bundles = $this->getBundles();
foreach ($bundles as $bundle_id => $bundle_info) {
$field_name = $this->bundleToCamelCase($bundle_id) . 'Config';
$registry->addFieldResolver('Query', $field_name, $builder->compose(
$builder->produce('translatable_config_page')
->map('type', $builder->fromValue($bundle_id))
->map('language', $builder->produce('current_language'))
));
}
}
/**
* Get enabled bundles for the translatable_config_pages entity type.
*
* Only bundles that are enabled in the GraphQL server configuration are
* returned.
*
* @return array
* An array of bundle information keyed by bundle ID.
*/
protected function getBundles(): array {
$entity_type_id = 'translatable_config_pages';
$all_bundles = $this->entityTypeBundleInfo->getBundleInfo($entity_type_id);
if (empty($all_bundles)) {
return [];
}
// Get enabled bundles from GraphQL configuration.
$config = $this->getCoreComposableConfig();
$enabled_bundles = [];
$configured_bundles = $config->getEnabledEntityBundles()[$entity_type_id] ?? [];
foreach ($all_bundles as $bundle_id => $bundle_info) {
// A bundle is enabled if it exists in the bundles configuration and is marked as enabled.
if (isset($configured_bundles[$bundle_id]) && ($configured_bundles[$bundle_id]['enabled'] ?? FALSE)) {
$enabled_bundles[$bundle_id] = $bundle_info;
}
}
return $enabled_bundles;
}
/**
* Convert bundle ID to camelCase for GraphQL field names.
*
* @param string $bundle_id
* The bundle ID (e.g., "global", "footer_config").
*
* @return string
* The camelCase version (e.g., "global", "footerConfig").
*/
protected function bundleToCamelCase(string $bundle_id): string {
$parts = explode('_', $bundle_id);
$first = array_shift($parts);
$rest = array_map('ucfirst', $parts);
return $first . implode('', $rest);
}
/**
* Convert bundle ID to PascalCase for GraphQL type names.
*
* @param string $bundle_id
* The bundle ID (e.g., "global", "footer_config").
*
* @return string
* The PascalCase version (e.g., "Global", "FooterConfig").
*/
protected function bundleToPascalCase(string $bundle_id): string {
$parts = explode('_', $bundle_id);
$parts = array_map('ucfirst', $parts);
return implode('', $parts);
}
}
