diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php index b286539..b3dbffa 100644 --- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php +++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityNormalizer.php @@ -8,7 +8,7 @@ namespace Drupal\jsonld; use Drupal\jsonld\JsonldNormalizerBase; -use Drupal\rdf\RdfMappingException; +use Drupal\rdf\Mapping\RdfMappingException; use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php index a2e49e3..957bd4a 100644 --- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php +++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldEntityWrapper.php @@ -85,7 +85,7 @@ public function getId() { /** * Get the type URI. * - * @todo Once RdfMappingManager has a mapOutputTypes event, use that instead + * @todo Once RdfMappingManager has a mapBundleForOutput event, use that instead * of simply returning the site schema URI. */ public function getTypeUri() { @@ -93,12 +93,12 @@ public function getTypeUri() { $bundle = $this->entity->bundle(); switch ($this->format) { case 'drupal_jsonld': - $schema_path = SiteSchema::CONTENT_DEPLOYMENT; + $schema_id = SiteSchema::CONTENT_DEPLOYMENT; break; case 'jsonld': - $schema_path = SiteSchema::SYNDICATION; + $schema_id = SiteSchema::SYNDICATION; } - $schema = $this->siteSchemaManager->getSchema($schema_path); + $schema = $this->siteSchemaManager->getSchema($schema_id); return $schema->bundle($entity_type, $bundle)->getUri(); } diff --git a/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php b/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php index e898da8..ee6d09f 100644 --- a/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php +++ b/core/modules/jsonld/lib/Drupal/jsonld/JsonldNormalizerBase.php @@ -8,7 +8,7 @@ namespace Drupal\jsonld; use ReflectionClass; -use Drupal\rdf\RdfMappingManager; +use Drupal\rdf\Mapping\RdfMappingManager; use Drupal\rdf\SiteSchema\SiteSchemaManager; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Normalizer\SerializerAwareNormalizer; @@ -42,7 +42,7 @@ /** * The RDF mapping manager. * - * @var \Drupal\rdf\RdfMappingManager + * @var \Drupal\rdf\Mapping\RdfMappingManager */ protected $rdfMappingManager; @@ -51,7 +51,7 @@ * * @param \Drupal\rdf\SiteSchema\SiteSchemaManager $site_schema_manager * The site schema manager. - * @param \Drupal\rdf\RdfMappingManager $rdf_mapping_manager + * @param \Drupal\rdf\Mapping\RdfMappingManager $rdf_mapping_manager * The RDF mapping manager. */ public function __construct(SiteSchemaManager $site_schema_manager, RdfMappingManager $rdf_mapping_manager) { diff --git a/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php b/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php index d0eb0c3..f83a70d 100644 --- a/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php +++ b/core/modules/jsonld/lib/Drupal/jsonld/Tests/JsonldTestSetupHelper.php @@ -12,7 +12,7 @@ use Drupal\jsonld\JsonldEntityNormalizer; use Drupal\jsonld\JsonldEntityReferenceNormalizer; use Drupal\jsonld\JsonldFieldItemNormalizer; -use Drupal\rdf\RdfMappingManager; +use Drupal\rdf\Mapping\RdfMappingManager; use Drupal\rdf\EventSubscriber\MappingSubscriber; use Drupal\rdf\SiteSchema\SiteSchemaManager; use Symfony\Component\EventDispatcher\EventDispatcher; @@ -33,7 +33,7 @@ class JsonldTestSetupHelper { /** * The RDF mapping manager. * - * @var \Drupal\rdf\RdfMappingManager + * @var \Drupal\rdf\Mapping\RdfMappingManager */ protected $rdfMappingManager; @@ -87,7 +87,7 @@ public function getSiteSchemaManager() { /** * Get the RdfMappingManager object. * - * @return \Drupal\rdf\RdfMappingManager + * @return \Drupal\rdf\Mapping\RdfMappingManager * The RdfMappingManager, which is also injected into the Normalizers. */ public function getRdfMappingManager() { diff --git a/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php b/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php index c4422aa..3cbfae4 100644 --- a/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php +++ b/core/modules/jsonld/lib/Drupal/jsonld/Tests/RdfSchemaSerializationTest.php @@ -46,7 +46,7 @@ function testSchemaSerialization() { $parsed_term = $decoded[0]; $this->assertEqual($parsed_term->{'@id'}, $bundle_schema->getUri(), 'JSON-LD for schema term uses correct @id.'); - $this->assertEqual($parsed_term->{'@type'}, 'http://www.w3.org/2000/01/rdf-schema#class', 'JSON-LD for schema term uses correct @type.'); + $this->assertEqual($parsed_term->{'@type'}, 'http://www.w3.org/2000/01/rdf-schema#Class', 'JSON-LD for schema term uses correct @type.'); // The @id and @type should be placed in the beginning of the array. $array_keys = array_keys((array) $parsed_term); $this->assertEqual(array('@id', '@type'), array_slice($array_keys, 0, 2), 'JSON-LD keywords are placed before other properties.'); diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 9e8fbd3..1ecd4a1 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -822,53 +822,6 @@ function node_type_set_defaults($info = array()) { } /** - * Implements hook_rdf_mapping(). - */ -function node_rdf_mapping() { - return array( - array( - 'type' => 'node', - 'bundle' => RDF_DEFAULT_BUNDLE, - 'mapping' => array( - 'rdftype' => array('sioc:Item', 'foaf:Document'), - 'title' => array( - 'predicates' => array('dc:title'), - ), - 'created' => array( - 'predicates' => array('dc:date', 'dc:created'), - 'datatype' => 'xsd:dateTime', - 'callback' => 'date_iso8601', - ), - 'changed' => array( - 'predicates' => array('dc:modified'), - 'datatype' => 'xsd:dateTime', - 'callback' => 'date_iso8601', - ), - 'body' => array( - 'predicates' => array('content:encoded'), - ), - 'uid' => array( - 'predicates' => array('sioc:has_creator'), - 'type' => 'rel', - ), - 'name' => array( - 'predicates' => array('foaf:name'), - ), - 'comment_count' => array( - 'predicates' => array('sioc:num_replies'), - 'datatype' => 'xsd:integer', - ), - 'last_activity' => array( - 'predicates' => array('sioc:last_activity_date'), - 'datatype' => 'xsd:dateTime', - 'callback' => 'date_iso8601', - ), - ), - ), - ); -} - -/** * Determines whether a node hook exists. * * @param string $type diff --git a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php index 764c2f9..82f4512 100644 --- a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php +++ b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php @@ -6,7 +6,7 @@ namespace Drupal\rdf\EventSubscriber; -use Drupal\rdf\RdfMappingEvents; +use Drupal\rdf\Mapping\RdfMappingEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -21,10 +21,10 @@ class MappingSubscriber implements EventSubscriberInterface { * mapping is unnecessary. Mapping is only necessary if the incoming type URI * is from an external vocabulary. * - * @param \Drupal\rdf\MapTypesFromInputEvent $event + * @param \Drupal\rdf\Mapping\MapTypesFromInputEvent $event * The mapping event. */ - public function mapTypesFromInput(\Drupal\rdf\MapTypesFromInputEvent $event) { + public function mapTypesFromInput(\Drupal\rdf\Mapping\MapTypesFromInputEvent $event) { $input_uris = $event->getInputUris(); $site_schema_types = $event->getSiteSchemaTypes(); foreach ($input_uris as $input_uri) { @@ -35,11 +35,41 @@ public function mapTypesFromInput(\Drupal\rdf\MapTypesFromInputEvent $event) { } } + public function mapBundleForOutput(\Drupal\rdf\Mapping\MapBundleForOutputEvent $event) { + $term_schema = $event->getTermSchema(); + // @todo When the $schema is SYNDICATION, allow sites to exclude the site + // schema URI from the mapping. + $site_schema_curie = $term_schema->getCurie(); + $event->addTypes(array($site_schema_curie)); + + $config = config($term_schema->getMappingConfigName()); + $types = $config->get('types'); + if (!empty($types)) { + $event->addTypes($types); + } + } + + public function mapFieldForOutput(\Drupal\rdf\Mapping\MapFieldForOutputEvent $event) { + $term_schema = $event->getTermSchema(); + // @todo When the $schema is SYNDICATION, allow sites to exclude the site + // schema URI from the mapping. + $site_schema_curie = $term_schema->getCurie(); + $event->addPredicates(array($site_schema_curie)); + + $config = config($term_schema->getMappingConfigName()); + $curies = $config->get('properties'); + if (!empty($curies)) { + $event->addPredicates($curies); + } + } + /** * Implements EventSubscriberInterface::getSubscribedEvents(). */ static function getSubscribedEvents() { $events[RdfMappingEvents::MAP_TYPES_FROM_INPUT] = 'mapTypesFromInput'; + $events[RdfMappingEvents::MAP_BUNDLE_FOR_OUTPUT] = 'mapBundleForOutput'; + $events[RdfMappingEvents::MAP_FIELD_FOR_OUTPUT] = 'mapFieldForOutput'; return $events; } } diff --git a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php index 123493b..cf04c94 100644 --- a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php +++ b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/RouteSubscriber.php @@ -50,10 +50,10 @@ public function routes(RouteBuildEvent $event) { foreach ($this->siteSchemaManager->getSchemas() as $schema) { $routes = $schema->getRoutes(); foreach ($routes as $controller => $pattern) { - $schema_path = $schema->getPath(); + $schema_id = $schema->getId(); $route = new Route($pattern, array( '_controller' => 'Drupal\rdf\SiteSchema\SchemaController::' . $controller, - 'schema_path' => $schema_path, + 'schema_id' => $schema_id, ), array( '_method' => 'GET', '_access' => 'TRUE', @@ -61,7 +61,7 @@ public function routes(RouteBuildEvent $event) { // Create the route name to use in the RouteCollection. Remove the // trailing slash and replace characters, so that a path such as // site-schema/syndication/ becomes rdf.site_schema.syndication. - $route_name = 'rdf.' . str_replace(array('-','/'), array('_', '.'), substr_replace($schema_path ,"",-1)); + $route_name = 'rdf.' . str_replace(array('-','/'), array('_', '.'), substr_replace($schema_id ,"",-1)); $collection->add($route_name, $route); } } diff --git a/core/modules/rdf/lib/Drupal/rdf/Mapping/BundleRdfMappingStorageController.php b/core/modules/rdf/lib/Drupal/rdf/Mapping/BundleRdfMappingStorageController.php new file mode 100644 index 0000000..01ca528 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Mapping/BundleRdfMappingStorageController.php @@ -0,0 +1,25 @@ +siteSchema->bundle($entity->entity_type, $entity->bundle); + } + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/Mapping/FieldRdfMappingStorageController.php b/core/modules/rdf/lib/Drupal/rdf/Mapping/FieldRdfMappingStorageController.php new file mode 100644 index 0000000..8ed5bc2 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Mapping/FieldRdfMappingStorageController.php @@ -0,0 +1,26 @@ +siteSchema->field($entity->entity_type, $entity->bundle, $entity->field_name); + } + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/Mapping/MapBundleForOutputEvent.php b/core/modules/rdf/lib/Drupal/rdf/Mapping/MapBundleForOutputEvent.php new file mode 100644 index 0000000..9a359b0 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Mapping/MapBundleForOutputEvent.php @@ -0,0 +1,63 @@ +termSchema = $term_schema; + $this->types = array(); + } + + public function getTermSchema() { + return $this->termSchema; + } + + /** + * Add RDF types to the CURIEs array. + * + * @param array $curies + * + * @todo Add namespace IDs. + */ + public function addTypes($curies) { + if (!is_array($curies)) { + $curies = array($curies); + } + $this->types = array_merge($this->types, $curies); + } + + /** + * @return array + * An array of CURIE strings/arrays. + */ + public function getTypes() { + return $this->types; + } +} diff --git a/core/modules/rdf/lib/Drupal/rdf/Mapping/MapFieldForOutputEvent.php b/core/modules/rdf/lib/Drupal/rdf/Mapping/MapFieldForOutputEvent.php new file mode 100644 index 0000000..7b95b25 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Mapping/MapFieldForOutputEvent.php @@ -0,0 +1,71 @@ +termSchema = $term_schema; + $this->predicates = array(); + } + + public function getTermSchema() { + return $this->termSchema; + } + + /** + * Add CURIEs to the predicates array. + * + * @param array $curies + * + * @todo Add namespace IDs. + */ + public function addPredicates($curies) { + if (!is_array($curies)) { + $curies = array($curies); + } + $this->predicates = array_merge($this->predicates, $curies); + } + + public function getPredicates() { + return $this->predicates; + } + + public function getDatatype() { + return $this->datatype; + } + + public function getDatatypeCallback() { + return $this->datatype_callback; + } +} diff --git a/core/modules/rdf/lib/Drupal/rdf/MapTypesFromInputEvent.php b/core/modules/rdf/lib/Drupal/rdf/Mapping/MapTypesFromInputEvent.php similarity index 98% rename from core/modules/rdf/lib/Drupal/rdf/MapTypesFromInputEvent.php rename to core/modules/rdf/lib/Drupal/rdf/Mapping/MapTypesFromInputEvent.php index c54fe0d..7ca6ea4 100644 --- a/core/modules/rdf/lib/Drupal/rdf/MapTypesFromInputEvent.php +++ b/core/modules/rdf/lib/Drupal/rdf/Mapping/MapTypesFromInputEvent.php @@ -5,7 +5,7 @@ * Contains MapInputTypesEvent. */ -namespace Drupal\rdf; +namespace Drupal\rdf\Mapping; use Symfony\Component\EventDispatcher\Event; diff --git a/core/modules/rdf/lib/Drupal/rdf/Mapping/RdfMappingEvents.php b/core/modules/rdf/lib/Drupal/rdf/Mapping/RdfMappingEvents.php new file mode 100644 index 0000000..5fea94a --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Mapping/RdfMappingEvents.php @@ -0,0 +1,65 @@ +dispatcher = $dispatcher; + $this->siteSchemaManager = $site_schema_manager; + } + + /** + * Convert an array of RDF type URIs to the corresponding TypedData IDs. + * + * @param array $input_rdf_types + * An array of URIs for the type. + * + * @return array + * An array containing entity_type and bundle. + * + * @throws \Drupal\rdf\Mapping\RdfMappingException + */ + public function getTypedDataIdsFromTypeUris($input_rdf_types) { + // Get the cache of site schema types. + $site_schema_types = $this->siteSchemaManager->getTypes(); + // Map the RDF type from the incoming data to an RDF type defined in the + // internal site schema. + $type_uri = $this->mapTypesFromInput($input_rdf_types); + // If no site schema URI has been determined, then it's impossible to know + // what entity type to create. Throw an exception. + if ($type_uri == FALSE) { + throw new RdfMappingException(sprintf('No mapping to a site schema type URI found for incoming types (%s).', implode(',', $input_rdf_types))); + } + // Use the mapped RDF type URI to get the TypedData API ids the rest of the + // system uses (entity type and bundle). + return $site_schema_types[$type_uri]; + } + + /** + * Convert a bundle's Typed Data IDs to an RDF mapping array. + * + * Bundles will have different mappings based on whether the data is to be + * used for content deployment or for syndication. The site schema id is used + * to specify which to return. + * + * @param string $entity_type + * The entity type of the bundle which the mapping corresponds to. + * @param string $bundle + * The name of the bundle which the mapping corresponds to. + * @param string $schema_id + * The id of the site schema which is being mapped to. + * + * @return array + * The RDF mapping. + */ + public function getBundleMapping($entity_type, $bundle, $schema_id = SiteSchema::SYNDICATION) { + $site_schema = $this->siteSchemaManager->getSchema($schema_id); + $term_schema = $site_schema->bundle($entity_type, $bundle); + // Get the mapping, which contains the RDF types used when publishing data. + return $this->mapBundleForOutput($term_schema); + } + + /** + * Convert a field instance's Typed Data IDs to an RDF mapping array. + * + * Field instances will have different mappings based on whether the data is + * to be used for content deployment or for syndication. The site schema id + * is used to specify which to return. + * + * @param string $entity_type + * The entity type of the field instance which the mapping corresponds to. + * @param string $bundle + * The bundle of the field instance which the mapping corresponds to. + * @param string field_name + * The field name of the field instance which the mapping corresponds to. + * @param string $schema_id + * The id of the site schema which is being mapped to. + * + * @return array + * The RDF mapping. + */ + public function getFieldMapping($entity_type, $bundle, $field_name, $schema_id = SiteSchema::SYNDICATION) { + $site_schema = $this->siteSchemaManager->getSchema($schema_id); + $term_schema = $site_schema->field($entity_type, $bundle, $field_name); + return $this->mapFieldForOutput($term_schema); + } + + /** + * Get the mapping config entity for a bundle. + * + * Bundles will have different mappings based on whether the data is to be + * used for content deployment or for syndication. The site schema id is used + * to specify which to return. + * + * @param string $entity_type + * The entity type of the bundle which the mapping corresponds to. + * @param string $bundle + * The name of the bundle which the mapping corresponds to. + * @param string $schema_id + * The id of the site schema which is being mapped to. + * + * @return array + * The RDF mapping config entity. + */ + public function getBundleMappingConfig($entity_type, $bundle, $schema_id = SiteSchema::SYNDICATION) { + $bundle_schema = $this->siteSchemaManager->getSchema($schema_id)->bundle($entity_type, $bundle); + return $bundle_schema->getMappingConfig(); + } + + /** + * Get the field mapping config entity for a field instance. + * + * Field instances will have different mappings based on whether the data is + * to be used for content deployment or for syndication. The site schema id + * is used to specify which to return. + * + * @param string $entity_type + * The entity type of the field instance which the mapping corresponds to. + * @param string $bundle + * The bundle of the field instance which the mapping corresponds to. + * @param string field_name + * The field name of the field instance which the mapping corresponds to. + * @param string $schema_id + * The id of the site schema which is being mapped to. + * + * @return array + * The RDF mapping. + */ + public function getFieldMappingConfig($entity_type, $bundle, $field_name, $schema_id = SiteSchema::SYNDICATION) { + $field_schema = $this->siteSchemaManager->getSchema($schema_id)->field($entity_type, $bundle, $field_name); + return $field_schema->getMappingConfig(); + } + + /** + * Map an array of incoming URIs to an internal site schema URI. + * + * @param array $input_rdf_types + * An array of RDF type URIs. + * + * @return string + * The corresponding site schema type URI. + */ + protected function mapTypesFromInput($input_rdf_types) { + // Create the event using the array of incoming RDF type URIs and the cache + // of internal site schema URIs. + $site_schema_types = $this->siteSchemaManager->getTypes(); + $mapping_event = new MapTypesFromInputEvent($input_rdf_types, $site_schema_types); + + // Allow other modules to map the incoming type URIs to an internal site + // schema type URI. For example, a content deployment module could take + // URIs from the staging site's schema and map them to the corresponding + // URI in the live site's schema. + $this->dispatcher->dispatch(RdfMappingEvents::MAP_TYPES_FROM_INPUT, $mapping_event); + + return $mapping_event->getSiteSchemaUri(); + } + + /** + * Map a bundle's site schema term to external vocabularies. + * + * @param \Drupal\rdf\SiteSchema\SchemaTermInterface $term_schema + * The term object. + * + * @return string + * The corresponding RDF mapping. + */ + protected function mapBundleForOutput($term_schema) { + $mapping = array(); + $map_event = new MapBundleForOutputEvent($term_schema); + $this->dispatcher->dispatch(RdfMappingEvents::MAP_BUNDLE_FOR_OUTPUT, $map_event); + $types = $map_event->getTypes(); + if (!empty($types)) { + $mapping['types'] = $types; + } + return $mapping; + } + + /** + * Map a field instance's site schema term to external vocabularies. + * + * @param \Drupal\rdf\SiteSchema\SchemaTermInterface $term_schema + * The term object. + * + * @return string + * The corresponding RDF mapping. + */ + protected function mapFieldForOutput($term_schema) { + $mapping = array(); + $map_event = new MapFieldForOutputEvent($term_schema); + $this->dispatcher->dispatch(RdfMappingEvents::MAP_FIELD_FOR_OUTPUT, $map_event); + + $predicates = $map_event->getPredicates(); + if (!empty($predicates)) { + $mapping['properties'] = $predicates; + $mapping['datatype'] = $map_event->getDatatype(); + $mapping['datatype_callback'] = $map_event->getDatatypeCallback(); + } + return array_filter($mapping); + } + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/Mapping/RdfMappingStorageControllerBase.php b/core/modules/rdf/lib/Drupal/rdf/Mapping/RdfMappingStorageControllerBase.php new file mode 100644 index 0000000..8129c85 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Mapping/RdfMappingStorageControllerBase.php @@ -0,0 +1,54 @@ +siteSchema = drupal_container()->get('rdf.site_schema_manager')->getSchema(SiteSchema::SYNDICATION); + } + + /** + * Overrides \Drupal\Core\Config\Entity\ConfigStorageController::save(). + */ + public function save(EntityInterface $entity) { + if (!isset($entity->mid)) { + $entity->mid = $this->getTermSchema($entity)->getMappingConfigId(); + } + parent::save($entity); + } + + /** + * Get the site schema term object that is being mapped. + * + * This is used by the storage controller to determine what the name of the + * mapping config object should be. + * + * @param \Drupal\Core\Entity\Entity $entity + * The config entity. + * + * @return \Drupal\rdf\SiteSchema\SchemaTermInterface + * The site schema term object. + */ + abstract protected function getTermSchema($entity); + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/BundleRdfMapping.php b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/BundleRdfMapping.php new file mode 100644 index 0000000..ec30afd --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/BundleRdfMapping.php @@ -0,0 +1,74 @@ +mid; + } +} diff --git a/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/FieldRdfMapping.php b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/FieldRdfMapping.php new file mode 100644 index 0000000..7c1dc1c --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/Plugin/Core/Entity/FieldRdfMapping.php @@ -0,0 +1,95 @@ +mid; + } +} diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfBundle.php b/core/modules/rdf/lib/Drupal/rdf/RdfBundle.php index 40affcc..295ebfc 100644 --- a/core/modules/rdf/lib/Drupal/rdf/RdfBundle.php +++ b/core/modules/rdf/lib/Drupal/rdf/RdfBundle.php @@ -30,7 +30,7 @@ public function build(ContainerBuilder $container) { $container->register('rdf.site_schema_manager', 'Drupal\rdf\SiteSchema\SiteSchemaManager') ->addArgument(new Reference('cache.rdf.site_schema.types')); // Mapping manager service. - $container->register('rdf.mapping_manager', 'Drupal\rdf\RdfMappingManager') + $container->register('rdf.mapping_manager', 'Drupal\rdf\Mapping\RdfMappingManager') ->addArgument(new Reference('event_dispatcher')) ->addArgument(new Reference('rdf.site_schema_manager')); diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php b/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php index b64ae91..4ac035f 100644 --- a/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php +++ b/core/modules/rdf/lib/Drupal/rdf/RdfConstants.php @@ -12,8 +12,9 @@ */ abstract class RdfConstants { const RDF_TYPE = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'; + const RDF_PROPERTY = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Property'; // RDF Schema terms. - const RDFS_CLASS = 'http://www.w3.org/2000/01/rdf-schema#class'; + const RDFS_CLASS = 'http://www.w3.org/2000/01/rdf-schema#Class'; const RDFS_DOMAIN = 'http://www.w3.org/2000/01/rdf-schema#domain'; const RDFS_IS_DEFINED_BY = 'http://www.w3.org/2000/01/rdf-schema#isDefinedBy'; const RDFS_RANGE = 'http://www.w3.org/2000/01/rdf-schema#range'; diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php b/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php deleted file mode 100644 index 0e3fdae..0000000 --- a/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php +++ /dev/null @@ -1,29 +0,0 @@ -dispatcher = $dispatcher; - $this->siteSchemaManager = $site_schema_manager; - } - - /** - * Convert an array of RDF type URIs to the corresponding TypedData IDs. - * - * @param array $input_rdf_types - * An array of URIs for the type. - * - * @return array - * An array containing entity_type and bundle. - * - * @throws \Drupal\rdf\RdfMappingException - */ - public function getTypedDataIdsFromTypeUris($input_rdf_types) { - // Get the cache of site schema types. - $site_schema_types = $this->siteSchemaManager->getTypes(); - // Map the RDF type from the incoming data to an RDF type defined in the - // internal site schema. - $type_uri = $this->mapTypesFromInput($input_rdf_types); - // If no site schema URI has been determined, then it's impossible to know - // what entity type to create. Throw an exception. - if ($type_uri == FALSE) { - throw new RdfMappingException(sprintf('No mapping to a site schema type URI found for incoming types (%s).', implode(',', $input_rdf_types))); - } - // Use the mapped RDF type URI to get the TypedData API ids the rest of the - // system uses (entity type and bundle). - return $site_schema_types[$type_uri]; - } - - /** - * Map an array of incoming URIs to an internal site schema URI. - * - * @param array $input_rdf_types - * An array of RDF type URIs. - * - * @return string - * The corresponding site schema type URI. - */ - protected function mapTypesFromInput($input_rdf_types) { - // Create the event using the array of incoming RDF type URIs and the cache - // of internal site schema URIs. - $site_schema_types = $this->siteSchemaManager->getTypes(); - $mapping_event = new MapTypesFromInputEvent($input_rdf_types, $site_schema_types); - - // Allow other modules to map the incoming type URIs to an internal site - // schema type URI. For example, a content deployment module could take - // URIs from the staging site's schema and map them to the corresponding - // URI in the live site's schema. - $this->dispatcher->dispatch(RdfMappingEvents::MAP_TYPES_FROM_INPUT, $mapping_event); - - return $mapping_event->getSiteSchemaUri(); - } -} diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php index 2c92696..ff79559 100644 --- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php @@ -22,6 +22,8 @@ class BundleSchema extends EntitySchema { */ public static $uriPattern = '{entity_type}/{bundle}'; + protected $configPrefix = 'rdf.mapping.bundle'; + /** * The bundle that this term identifies. * @@ -45,11 +47,14 @@ public function __construct($site_schema, $entity_type, $bundle) { } /** - * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getUri(). + * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getPath(). */ - public function getUri() { - $path = str_replace(array('{entity_type}', '{bundle}'), array($this->entityType, $this->bundle), static::$uriPattern); - return $this->siteSchema->getUri() . $path; + public function getPath() { + return $this->siteSchema->getPath() . $this->prepareUriPattern(); + } + + protected function prepareUriPattern() { + return str_replace(array('{entity_type}', '{bundle}'), array($this->entityType, $this->bundle), static::$uriPattern); } /** @@ -61,4 +66,10 @@ public function getProperties() { return $properties; } + public function getTermIds() { + $keys = parent::getTermIds(); + $keys['bundle'] = $this->bundle; + return $keys; + } + } diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php index 48a69fc..5d4dd7b 100644 --- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/EntitySchema.php @@ -54,11 +54,11 @@ public function getGraph() { } /** - * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getUri(). + * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getPath(). */ - public function getUri() { + public function getPath() { $path = str_replace('{entity_type}', $this->entityType , static::$uriPattern); - return $this->siteSchema->getUri() . $path; + return $this->siteSchema->getPath() . $path; } /** @@ -70,4 +70,11 @@ public function getProperties() { return $properties; } + public function getTermIds() { + return array( + 'schema_id' => $this->siteSchema->getId(), + 'entity_type' => $this->entityType, + ); + } + } diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/FieldSchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/FieldSchema.php new file mode 100644 index 0000000..e7c9425 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/FieldSchema.php @@ -0,0 +1,105 @@ +entityType = $entity_type; + $this->bundle = $bundle; + $this->fieldName = $field_name; + } + + /** + * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getGraph(). + * + * @todo Loop through all fields and add their RDF descriptions. + */ + public function getGraph() { + // @todo Implement this. + } + + /** + * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getPath(). + */ + public function getPath() { + return $this->siteSchema->getPath() . $this->prepareUriPattern(); + } + + protected function prepareUriPattern() { + return str_replace(array('{entity_type}', '{bundle}', '{field_name}'), array($this->entityType, $this->bundle, $this->fieldName), static::$uriPattern); + } + + /** + * Overrides \Drupal\rdf\SiteSchema\SchemaTermBase::getProperties(). + */ + public function getProperties() { + $properties = parent::getProperties(); + $properties[RdfConstants::RDF_TYPE] = RdfConstants::RDF_PROPERTY; + return $properties; + } + + public function getTermIds() { + return array( + 'schema_id' => $this->siteSchema->getId(), + 'entity_type' => $this->entityType, + 'bundle' => $this->bundle, + 'field_name' => $this->fieldName, + ); + } + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php index b60eb84..9617401 100644 --- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaController.php @@ -42,7 +42,7 @@ public function setContainer(ContainerInterface $container = NULL) { * The entity type. * @param string $bundle * The entity bundle. - * @param string $schema_path + * @param string $schema_id * The relative base path for the schema. * * @return \Symfony\Component\HttpFoundation\Response @@ -50,7 +50,7 @@ public function setContainer(ContainerInterface $container = NULL) { * * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ - public function bundle($entity_type, $bundle, $schema_path) { + public function bundle($entity_type, $bundle, $schema_id) { if (!$entity_info = entity_get_info($entity_type)) { throw new NotFoundHttpException(t('Entity type @entity_type not found', array('@entity_type' => $entity_type))); } @@ -60,7 +60,7 @@ public function bundle($entity_type, $bundle, $schema_path) { $serializer = $this->container->get('serializer'); $site_schema_manager = $this->container->get('rdf.site_schema_manager'); - $schema = $site_schema_manager->getSchema($schema_path); + $schema = $site_schema_manager->getSchema($schema_id); // @todo Remove hard-coded mimetype once we have proper conneg. $content = $serializer->serialize($schema->bundle($entity_type, $bundle), 'jsonld'); return new Response($content, 200, array('Content-type' => 'application/json')); diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php index d7afd1c..66ef931 100644 --- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermBase.php @@ -28,6 +28,8 @@ */ protected $siteSchema; + protected $configPrefix; + /** * Constructor. * @@ -39,6 +41,17 @@ public function __construct($site_schema) { } /** + * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getUri(). + */ + function getUri() { + return url($this->getPath(), array('absolute' => TRUE)); + } + + public function getCurie() { + return $this->siteSchema->getPrefix() . ':' . $this->prepareUriPattern(); + } + + /** * Implements \Drupal\rdf\SiteSchema\SchemaTermInterface::getProperties(). */ public function getProperties() { @@ -47,4 +60,26 @@ public function getProperties() { ); } + public function getMappingConfig() { + $config_name = $this->getMappingConfigName(); + $config = config($config_name); + + // If the entity type isn't set, then the config didn't exist before and the + // config factory created a new config entity. Fill in the keys and save it. + $entity_type = $config->get('entity_type'); + if (empty($entity_type)) { + $config->mid = $config_name; + foreach ($this->getTermIds() as $key => $value) { + $config->set($key, $value); + } + $config->save(); + } + + return $config; + } + + public function getMappingConfigName() { + return $this->configPrefix . '.' . implode(';', $this->getTermIds()); + } + } diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php index 342b51e..239126e 100644 --- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SchemaTermInterface.php @@ -41,4 +41,15 @@ public function getProperties(); * The URI of the term. */ public function getUri(); + + /** + * Get the relative path of the term. + * + * Implementations of this method will use the URI patterns defined in + * $uriPattern static variables and replace placeholders with actual values. + * + * @return string + * The relative path of the term. + */ + public function getPath(); } diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php index e3153d1..dbb36d1 100644 --- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchema.php @@ -19,8 +19,8 @@ class SiteSchema { // are not intended to be extensible. If a site wants to use external // vocabulary terms, the appropriate way to do this is to use the RDF mapping // system. - const CONTENT_DEPLOYMENT = 'site-schema/content-deployment/'; - const SYNDICATION = 'site-schema/syndication/'; + const CONTENT_DEPLOYMENT = 'content-deployment'; + const SYNDICATION = 'syndication'; /** * The relative base path of the instantiated schema. @@ -29,20 +29,26 @@ class SiteSchema { */ protected $schemaPath; + protected $schemaId; + + protected $prefix; + /** * Constructor. * - * @param string $schema_path + * @param string $schema_id * The schema path constant, used to determine which schema to instantiate. * * @throws \UnexpectedValueException */ - public function __construct($schema_path) { + public function __construct($schema_id) { $valid_paths = array(self::CONTENT_DEPLOYMENT, self::SYNDICATION); - if (!in_array($schema_path, $valid_paths)) { - throw new \UnexpectedValueException(sprintf('%s is not a valid site schema path. Schema path must be one of %s.'), $schema_path, implode(', ', $valid_paths)); + if (!in_array($schema_id, $valid_paths)) { + throw new \UnexpectedValueException(sprintf('%s is not a valid site schema path. Schema path must be one of %s.'), $schema_id, implode(', ', $valid_paths)); } - $this->schemaPath = $schema_path; + $this->schemaId = $schema_id; + $this->schemaPath = 'site-schema/' . $schema_id . '/'; + $this->prefix = ($schema_id == self::CONTENT_DEPLOYMENT) ? 'site-cd' : 'site-syn'; } /** @@ -60,6 +66,13 @@ public function bundle($entity_type, $bundle) { } /** + * Get a field instance's term definition in this vocabulary. + */ + public function field($entity_type, $bundle, $field_name) { + return new FieldSchema($this, $entity_type, $bundle, $field_name); + } + + /** * Get the URI of the schema. * * @return string @@ -69,6 +82,10 @@ public function getUri() { return url($this->schemaPath, array('absolute' => TRUE)); } + public function getId() { + return $this->schemaId; + } + /** * Get the relative base path of the schema. */ @@ -76,6 +93,10 @@ public function getPath() { return $this->schemaPath; } + public function getPrefix() { + return $this->prefix; + } + /** * Get the routes for the types of terms defined in this schema. * diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php index 7ca9ca8..6caa8fd 100644 --- a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php +++ b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/SiteSchemaManager.php @@ -65,8 +65,8 @@ public function getSchemas() { return $this->siteSchemas; } - public function getSchema($schema_path) { - return $this->siteSchemas[$schema_path]; + public function getSchema($schema_id) { + return $this->siteSchemas[$schema_id]; } /** diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php index 3383f94..5257ef2 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/CrudTest.php @@ -19,7 +19,7 @@ class CrudTest extends WebTestBase { * * @var array */ - public static $modules = array('rdf', 'rdf_test'); + public static $modules = array('rdf', 'entity_test'); public static function getInfo() { return array( @@ -33,53 +33,54 @@ public static function getInfo() { * Tests inserting, loading, updating, and deleting RDF mappings. */ function testCRUD() { - // Verify loading of a default mapping. - $mapping = _rdf_mapping_load('test_entity', 'test_bundle'); - $this->assertTrue(count($mapping), 'Default mapping was found.'); + $entity_type = $bundle = 'entity_test'; + $mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $bundle_mapping_config_name = "rdf.mapping.bundle.syndication;$entity_type;$bundle"; + $user_id_mapping_config_name = "rdf.mapping.field.syndication;$entity_type;$bundle;user_id"; - // Verify saving a mapping. - $mapping = array( - 'type' => 'crud_test_entity', - 'bundle' => 'crud_test_bundle', - 'mapping' => array( - 'rdftype' => array('sioc:Post'), - 'title' => array( - 'predicates' => array('dc:title'), - ), - 'uid' => array( - 'predicates' => array('sioc:has_creator', 'dc:creator'), - 'type' => 'rel', - ), - ), - ); - $this->assertTrue(rdf_mapping_save($mapping) === SAVED_NEW, 'Mapping was saved.'); - - // Read the raw record from the {rdf_mapping} table. - $result = db_query('SELECT * FROM {rdf_mapping} WHERE type = :type AND bundle = :bundle', array(':type' => $mapping['type'], ':bundle' => $mapping['bundle'])); - $stored_mapping = $result->fetchAssoc(); - $stored_mapping['mapping'] = unserialize($stored_mapping['mapping']); - $this->assertEqual($mapping, $stored_mapping, 'Mapping was stored properly in the {rdf_mapping} table.'); + // Save bundle mapping config. + $bundle_mapping = $mapping_manager->getBundleMappingConfig($entity_type, $bundle); + $bundle_mapping->set('types', array('sioc:Post'))->save(); + // Save field mapping config. + $user_id_mapping = $mapping_manager->getFieldMappingConfig($entity_type, $bundle, 'user_id'); + $user_id_mapping->set('properties', array('sioc:has_creator', 'dc:creator'))->save(); - // Verify loading of saved mapping. - $this->assertEqual($mapping['mapping'], _rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Saved mapping loaded successfully.'); + // Test that config files were saved. + $bundle_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.bundle'); + $this->assertTrue(in_array($bundle_mapping_config_name, $bundle_mapping_configs), 'Bundle mapping config saved.'); + $field_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.field'); + $this->assertTrue(in_array($user_id_mapping_config_name, $field_mapping_configs), 'Field mapping config saved.'); - // Verify updating of mapping. - $mapping['mapping']['title'] = array( - 'predicates' => array('dc2:bar2'), - ); - $this->assertTrue(rdf_mapping_save($mapping) === SAVED_UPDATED, 'Mapping was updated.'); + // Test that config can be loaded. + $loaded_bundle_config = $mapping_manager->getBundleMappingConfig($entity_type, $bundle); + $bundle_config_array = $loaded_bundle_config->get(); + $this->assertTrue(!empty($bundle_config_array), 'Bundle mapping config loaded.'); + $loaded_field_config = $mapping_manager->getFieldMappingConfig($entity_type, $bundle, 'user_id'); + $field_config_array = $loaded_field_config->get(); + $this->assertTrue(!empty($field_config_array), 'Field mapping config loaded.'); - // Read the raw record from the {rdf_mapping} table. - $result = db_query('SELECT * FROM {rdf_mapping} WHERE type = :type AND bundle = :bundle', array(':type' => $mapping['type'], ':bundle' => $mapping['bundle'])); - $stored_mapping = $result->fetchAssoc(); - $stored_mapping['mapping'] = unserialize($stored_mapping['mapping']); - $this->assertEqual($mapping, $stored_mapping, 'Updated mapping was stored properly in the {rdf_mapping} table.'); + // Test that the values were saved correctly. + $types = config($bundle_mapping_config_name)->get('types'); + $this->assertTrue(in_array('sioc:Post', $types), 'Bundle mapping config values set properly.'); + $properties = config($user_id_mapping_config_name)->get('properties'); + $this->assertTrue(in_array('sioc:has_creator', $properties) && in_array('dc:creator', $properties), 'Field mapping config values set properly.'); - // Verify loading of saved mapping. - $this->assertEqual($mapping['mapping'], _rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Saved mapping loaded successfully.'); + // Test that mapping can be updated. + $bundle_mapping->set('types', array('schema:Thing'))->save(); + $loaded_bundle_config = $mapping_manager->getBundleMappingConfig($entity_type, $bundle); + $types = $loaded_bundle_config->get('types'); + $this->assert(in_array('schema:Thing', $types) && !in_array('sioc:Post', $types), 'Bundle mapping was updated.'); + $user_id_mapping->set('properties', array('schema:author'))->save(); + $loaded_config = $mapping_manager->getFieldMappingConfig($entity_type, $bundle, 'user_id'); + $properties = $loaded_config->get('properties'); + $this->assert(in_array('schema:author', $properties) && !in_array('sioc:has_creator', $properties), 'Field mapping was updated.'); - // Verify deleting of mapping. - $this->assertTrue(rdf_mapping_delete($mapping['type'], $mapping['bundle']), 'Mapping was deleted.'); - $this->assertFalse(_rdf_mapping_load($mapping['type'], $mapping['bundle']), 'Deleted mapping is no longer found in the database.'); + // Test that the mapping can be deleted. + $bundle_mapping->delete(); + $bundle_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.bundle'); + $this->assertFalse(in_array($bundle_mapping_config_name, $bundle_mapping_configs), 'Bundle mapping config deleted.'); + $user_id_mapping->delete(); + $field_mapping_configs = config_get_storage_names_with_prefix('rdf.mapping.field'); + $this->assertFalse(in_array($user_id_mapping_config_name, $field_mapping_configs), 'Field mapping config deleted.'); } } diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/GetNamespacesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/GetNamespacesTest.php index a133230..0457ee4 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/GetNamespacesTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/GetNamespacesTest.php @@ -19,7 +19,7 @@ class GetNamespacesTest extends WebTestBase { * * @var array */ - public static $modules = array('rdf', 'rdf_test'); + public static $modules = array('rdf', 'rdf_test_namespaces'); public static function getInfo() { return array( diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/GetRdfNamespacesTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/GetRdfNamespacesTest.php index 362a416..b2e881c 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/GetRdfNamespacesTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/GetRdfNamespacesTest.php @@ -19,7 +19,7 @@ class GetRdfNamespacesTest extends WebTestBase { * * @var array */ - public static $modules = array('rdf', 'rdf_test'); + public static $modules = array('rdf', 'rdf_test_namespaces'); public static function getInfo() { return array( diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/MappingHookTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/MappingHookTest.php deleted file mode 100644 index eb1340e..0000000 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/MappingHookTest.php +++ /dev/null @@ -1,50 +0,0 @@ - 'RDF mapping hook', - 'description' => 'Test hook_rdf_mapping().', - 'group' => 'RDF', - ); - } - - /** - * Tests that hook_rdf_mapping() correctly returns and processes mapping. - */ - function testMapping() { - // Test that the mapping is returned correctly by the hook. - $mapping = rdf_mapping_load('test_entity', 'test_bundle'); - $this->assertIdentical($mapping['rdftype'], array('sioc:Post'), 'Mapping for rdftype is sioc:Post.'); - $this->assertIdentical($mapping['title'], array('predicates' => array('dc:title')), 'Mapping for title is dc:title.'); - $this->assertIdentical($mapping['created'], array( - 'predicates' => array('dc:created'), - 'datatype' => 'xsd:dateTime', - 'callback' => 'date_iso8601', - ), 'Mapping for created is dc:created with datatype xsd:dateTime and callback date_iso8601.'); - $this->assertIdentical($mapping['uid'], array('predicates' => array('sioc:has_creator', 'dc:creator'), 'type' => 'rel'), 'Mapping for uid is sioc:has_creator and dc:creator, and type is rel.'); - - $mapping = rdf_mapping_load('test_entity', 'test_bundle_no_mapping'); - $this->assertEqual($mapping, array(), 'Empty array returned when an entity type, bundle pair has no mapping.'); - } -} diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfMappingEventTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfMappingEventTest.php index 7a7a7b5..d50d953 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfMappingEventTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfMappingEventTest.php @@ -7,13 +7,13 @@ namespace Drupal\rdf\Tests; use Drupal\Core\Cache\DatabaseBackend; -use Drupal\rdf\RdfMappingManager; +use Drupal\rdf\Mapping\RdfMappingManager; use Drupal\rdf\EventSubscriber\MappingSubscriber; use Drupal\rdf_test_mapping\EventSubscriber\TestMappingSubscriber; use Drupal\rdf\SiteSchema\BundleSchema; use Drupal\rdf\SiteSchema\SiteSchema; use Drupal\rdf\SiteSchema\SiteSchemaManager; -use Drupal\simpletest\WebTestBase; +use Drupal\simpletest\DrupalUnitTestBase; use Symfony\Component\EventDispatcher\EventDispatcher; /** @@ -21,14 +21,21 @@ * * This is implemented as a WebTest because it depends on entity info. */ -class RdfMappingEventTest extends WebTestBase { +class RdfMappingEventTest extends DrupalUnitTestBase { /** * Modules to enable. * * @var array */ - public static $modules = array('rdf', 'rdf_test_mapping', 'entity_test'); + public static $modules = array('system', 'rdf', 'rdf_test_mapping', 'entity_test'); + + /** + * The mock RDF mapping manager. + * + * @var \Drupal\rdf\Mapping\RdfMappingManager + */ + protected $mappingManager; public static function getInfo() { return array( @@ -39,26 +46,65 @@ public static function getInfo() { } /** - * Test that other modules can define incoming type mappings. + * Overrides \Drupal\simpletest\DrupalUnitTestBase::setUp(). */ - public function testMapInputType() { + public function setUp() { + parent::setUp(); + $this->enableModules(array('rdf', 'rdf_test_mapping', 'system')); + + // Set up the mock mapping manager. $dispatcher = new EventDispatcher(); $dispatcher->addSubscriber(new MappingSubscriber()); $dispatcher->addSubscriber(new TestMappingSubscriber()); $site_schema_manager = new SiteSchemaManager(new DatabaseBackend('cache')); - $mapping_manager = new RdfMappingManager($dispatcher, $site_schema_manager); + $this->mappingManager = new RdfMappingManager($dispatcher, $site_schema_manager); + } + /** + * Test that other modules can define incoming type mappings. + */ + public function testMapTypesFromInput() { // Test that a site schema URI is mapped to itself. This is the default // behavior. $schema = new SiteSchema(SiteSchema::CONTENT_DEPLOYMENT); $bundle_schema = $schema->bundle('entity_test', 'entity_test'); $site_schema_type = $bundle_schema->getUri(); - $typed_data_ids = $mapping_manager->getTypedDataIdsFromTypeUris(array($site_schema_type)); - $this->assertTrue($typed_data_ids['bundle'] == 'entity_test', 'An internal site schema type URI is properly handled.'); + $typed_data_ids = $this->mappingManager->getTypedDataIdsFromTypeUris(array($site_schema_type)); + $this->assertTrue($typed_data_ids['bundle'] == 'entity_test', 'An internal site schema type URI is properly handled on input.'); // Test that a module can map an external URI to a site schema URI. - $typed_data_ids = $mapping_manager->getTypedDataIdsFromTypeUris(array(TestMappingSubscriber::STAGING_SITE_TYPE_URI)); - $this->assertTrue($typed_data_ids['bundle'] == 'entity_test', 'Modules can map external type URIs to a site schema type.'); + $typed_data_ids = $this->mappingManager->getTypedDataIdsFromTypeUris(array(TestMappingSubscriber::STAGING_SITE_TYPE_URI)); + $this->assertTrue($typed_data_ids['bundle'] == 'entity_test', 'Modules can map external type URIs to a site schema type on input.'); + } + + /** + * Test that other modules can define output mappings for bundles. + */ + public function testMapBundleForOutput() { + $mapping = $this->mappingManager->getBundleMapping('entity_test', 'entity_test'); + + // Test that the site schema URI is automatically added in the mapping. + $schema = new SiteSchema(SiteSchema::SYNDICATION); + $bundle_schema = $schema->bundle('entity_test', 'entity_test'); + $this->assertTrue(in_array($bundle_schema->getCurie(), $mapping['types']), 'Internal site schema type included in mapping on output.'); + + // Test that a module can add types to a mapping via an event. + $this->assertTrue(in_array(TestMappingSubscriber::STAGING_SITE_TYPE_URI, $mapping['types']), 'Modules can map site schema types to external type URIs on output.'); + } + + /** + * Test that other modules can define output mappings for fields. + */ + public function testMapFieldForOutput() { + $mapping = $this->mappingManager->getFieldMapping('entity_test', 'entity_test', 'user_id'); + + // Test that the site schema URI is automatically added in the mapping. + $schema = new SiteSchema(SiteSchema::SYNDICATION); + $field_schema = $schema->field('entity_test', 'entity_test', 'user_id'); + $this->assertTrue(in_array($field_schema->getCurie(), $mapping['properties']), 'Internal site schema property included in mapping on output.'); + + // Test that a module can add types to a mapping via an event. + $this->assertTrue(in_array(TestMappingSubscriber::STAGING_SITE_PROPERTY_URI, $mapping['properties']), 'Modules can map site schema types to external property URIs on output.'); } } diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php index 1c69a0e..b1377c0 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/RdfaMarkupTest.php @@ -7,7 +7,12 @@ namespace Drupal\rdf\Tests; +use Drupal\Core\Cache\DatabaseBackend; +use Drupal\rdf\EventSubscriber\MappingSubscriber; +use Drupal\rdf\Mapping\RdfMappingManager; +use Drupal\rdf\SiteSchema\SiteSchemaManager; use Drupal\simpletest\WebTestBase; +use Symfony\Component\EventDispatcher\EventDispatcher; /** * Tests RDFa markup generation. @@ -19,10 +24,9 @@ class RdfaMarkupTest extends WebTestBase { * * @var array */ - public static $modules = array('rdf', 'field_test', 'rdf_test'); + public static $modules = array('rdf', 'field_test'); protected $profile = 'standard'; - public static function getInfo() { return array( 'name' => 'RDFa markup', @@ -32,63 +36,15 @@ public static function getInfo() { } /** - * Tests rdf_rdfa_attributes(). + * Overrides \Drupal\simpletest\DrupalUnitTestBase::setUp(). */ - function testDrupalRdfaAttributes() { - // Same value as the one in the HTML tag (no callback function). - $expected_attributes = array( - 'property' => array('dc:title'), - ); - $mapping = rdf_mapping_load('test_entity', 'test_bundle'); - $attributes = rdf_rdfa_attributes($mapping['title']); - ksort($expected_attributes); - ksort($attributes); - $this->assertEqual($expected_attributes, $attributes); - - // Value different from the one in the HTML tag (callback function). - $date = 1252750327; - $isoDate = date('c', $date); - $expected_attributes = array( - 'datatype' => 'xsd:dateTime', - 'property' => array('dc:created'), - 'content' => $isoDate, - ); - $mapping = rdf_mapping_load('test_entity', 'test_bundle'); - $attributes = rdf_rdfa_attributes($mapping['created'], $date); - ksort($expected_attributes); - ksort($attributes); - $this->assertEqual($expected_attributes, $attributes); - - // Same value as the one in the HTML tag with datatype. - $expected_attributes = array( - 'datatype' => 'foo:bar1type', - 'property' => array('foo:bar1'), - ); - $mapping = rdf_mapping_load('test_entity', 'test_bundle'); - $attributes = rdf_rdfa_attributes($mapping['foobar1']); - ksort($expected_attributes); - ksort($attributes); - $this->assertEqual($expected_attributes, $attributes); - - // ObjectProperty mapping (rel). - $expected_attributes = array( - 'rel' => array('sioc:has_creator', 'dc:creator'), - ); - $mapping = rdf_mapping_load('test_entity', 'test_bundle'); - $attributes = rdf_rdfa_attributes($mapping['foobar_objproperty1']); - ksort($expected_attributes); - ksort($attributes); - $this->assertEqual($expected_attributes, $attributes); - - // Inverse ObjectProperty mapping (rev). - $expected_attributes = array( - 'rev' => array('sioc:reply_of'), - ); - $mapping = rdf_mapping_load('test_entity', 'test_bundle'); - $attributes = rdf_rdfa_attributes($mapping['foobar_objproperty2']); - ksort($expected_attributes); - ksort($attributes); - $this->assertEqual($expected_attributes, $attributes); + public function setUp() { + parent::setUp(); + // Set up the mock mapping manager. + $dispatcher = new EventDispatcher(); + $dispatcher->addSubscriber(new MappingSubscriber()); + $site_schema_manager = new SiteSchemaManager(new DatabaseBackend('cache')); + $this->mappingManager = new RdfMappingManager($dispatcher, $site_schema_manager); } /** @@ -124,10 +80,10 @@ function testAttributesInMarkupFile() { ->save(); // Set the RDF mapping for the new field. - $rdf_mapping = rdf_mapping_load('node', $bundle_name); - $rdf_mapping += array($field_name => array('predicates' => array('rdfs:seeAlso'), 'type' => 'rel')); - $rdf_mapping_save = array('mapping' => $rdf_mapping, 'type' => 'node', 'bundle' => $bundle_name); - rdf_mapping_save($rdf_mapping_save); + $rdf_mapping_manager = + $config = $this->mappingManager->getFieldMappingConfig('node', 'article', $field_name); + $field_mapping = array_merge($config->get(), array('properties' => array('rdfs:seeAlso'), 'type' => 'rel')); + $config->setData($field_mapping)->save(); // Get the test file that simpletest provides. $file = current($this->drupalGetTestFiles('text')); @@ -146,25 +102,12 @@ function testAttributesInMarkupFile() { $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); - // Get filenames and nid for comparison with HTML output. - $file_filename = $file->filename; - $image_filename = $image->filename; - $nid = $node->nid; - // Navigate to front page, where node is displayed in teaser form. - $this->drupalGet('node'); - - // We only check to make sure that the resource attribute contains '.txt' - // instead of the full file name because the filename is altered on upload. - $file_rel = $this->xpath('//div[contains(@about, :node-uri)]//div[contains(@rel, "rdfs:seeAlso") and contains(@resource, ".txt")]', array( - ':node-uri' => 'node/' . $nid, - )); - $this->assertTrue(!empty($file_rel), "Attribute 'rel' set on file field. Attribute 'resource' is also set."); - $image_rel = $this->xpath('//div[contains(@about, :node-uri)]//div[contains(@rel, "rdfs:seeAlso") and contains(@resource, :image)]//img[contains(@typeof, "foaf:Image")]', array( - ':node-uri' => 'node/' . $nid, - ':image' => $image_filename, - )); - - $this->assertTrue(!empty($image_rel), "Attribute 'rel' set on image field. Attribute 'resource' is also set."); + // Prepares filenames for lookup in RDF graph. + $node = node_load($node->nid); + $node_uri = url('node/' . $node->nid, array('absolute' => TRUE)); + $file_uri = file_create_url(file_load($node->file_test['und'][0]['fid'])->uri); + $image_uri = image_style_url('medium', file_load($node->field_image['und'][0]['fid'])->uri); + $base_uri = url('', array('absolute' => TRUE)); // Edits the node to add tags. $tag1 = $this->randomName(8); @@ -172,17 +115,91 @@ function testAttributesInMarkupFile() { $edit = array(); $edit['field_tags[' . LANGUAGE_NOT_SPECIFIED . ']'] = "$tag1, $tag2"; $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save')); - // Ensures the RDFa markup for the relationship between the node and its - // tags is correct. - $term_rdfa_meta = $this->xpath('//div[@about=:node-url and contains(@typeof, "sioc:Item") and contains(@typeof, "foaf:Document")]//ul[@class="links"]/li[@rel="dc:subject"]/a[@typeof="skos:Concept" and @datatype="" and text()=:term-name]', array( - ':node-url' => url('node/' . $node->nid), - ':term-name' => $tag1, - )); - $this->assertTrue(!empty($term_rdfa_meta), 'Property dc:subject is present for the tag1 field item.'); - $term_rdfa_meta = $this->xpath('//div[@about=:node-url and contains(@typeof, "sioc:Item") and contains(@typeof, "foaf:Document")]//ul[@class="links"]/li[@rel="dc:subject"]/a[@typeof="skos:Concept" and @datatype="" and text()=:term-name]', array( - ':node-url' => url('node/' . $node->nid), - ':term-name' => $tag2, - )); - $this->assertTrue(!empty($term_rdfa_meta), 'Property dc:subject is present for the tag2 field item.'); + $term_1_id = key(taxonomy_term_load_multiple_by_name($tag1)); + $taxonomy_term_1_uri = url('taxonomy/term/' . $term_1_id, array('absolute' => TRUE)); + $term_2_id = key(taxonomy_term_load_multiple_by_name($tag2)); + $taxonomy_term_2_uri = url('taxonomy/term/' . $term_2_id, array('absolute' => TRUE)); + + // Parses front page where the node is displayed in its teaser form. + $parser = new \EasyRdf_Parser_Rdfa(); + $graph = new \EasyRdf_Graph(); + $parser->parse($graph, $this->drupalGet('node'), 'rdfa', $base_uri); + $rdf_output = $graph->toArray(); + + // Inspects RDF graph output. + // Node relations to attached file. + $expected_value = array( + 'type' => 'uri', + 'value' => $file_uri, + ); + $this->assertTrue($graph->hasProperty($node_uri, 'http://www.w3.org/2000/01/rdf-schema#seeAlso', $expected_value), 'Node to file relation found in RDF output (rdfs:seeAlso).'); + + // Node relations to attached image. + $expected_value = array( + 'type' => 'uri', + 'value' => $image_uri, + ); + $this->assertTrue($graph->hasProperty($node_uri, 'http://www.w3.org/2000/01/rdf-schema#seeAlso', $expected_value), 'Node to file relation found in RDF output (rdfs:seeAlso).'); + $expected_value = array( + 'type' => 'uri', + 'value' => $image_uri, + ); + $this->assertTrue($graph->hasProperty($node_uri, 'http://ogp.me/ns#image', $expected_value), 'Node to file relation found in RDF output (og:image).'); + // Image type. + $expected_value = array( + 'type' => 'uri', + 'value' => 'http://xmlns.com/foaf/0.1/Image', + ); + $this->assertTrue($graph->hasProperty($image_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Image type found in RDF output (foaf:Image).'); + + // Node relations to taxonomy terms. + $expected_value = array( + 'type' => 'uri', + 'value' => $taxonomy_term_1_uri, + ); + $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/subject', $expected_value), 'Node to term relation found in RDF output (dc:subject).'); + $expected_value = array( + 'type' => 'uri', + 'value' => $taxonomy_term_2_uri, + ); + $this->assertTrue($graph->hasProperty($node_uri, 'http://purl.org/dc/terms/subject', $expected_value), 'Node to term relation found in RDF output (dc:subject).'); + + // Taxonomy terms triples. + // Term 1. + $expected_value = array( + 'type' => 'uri', + 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', + ); + $this->assertTrue($graph->hasProperty($taxonomy_term_1_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Taxonomy term type found in RDF output (skos:Concept).'); + $expected_value = array( + 'type' => 'literal', + 'value' => $tag1, + 'lang' => 'en', + ); + $this->assertTrue($graph->hasProperty($taxonomy_term_1_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Taxonomy term name found in RDF output (rdfs:label).'); + $expected_value = array( + 'type' => 'literal', + 'value' => $tag1, + 'lang' => 'en', + ); + $this->assertTrue($graph->hasProperty($taxonomy_term_1_uri, 'http://www.w3.org/2004/02/skos/core#prefLabel', $expected_value), 'Taxonomy term name found in RDF output (skos:prefLabel).'); + // Term 2. + $expected_value = array( + 'type' => 'uri', + 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', + ); + $this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', $expected_value), 'Taxonomy term type found in RDF output (skos:Concept).'); + $expected_value = array( + 'type' => 'literal', + 'value' => $tag2, + 'lang' => 'en', + ); + $this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/2000/01/rdf-schema#label', $expected_value), 'Taxonomy term name found in RDF output (rdfs:label).'); + $expected_value = array( + 'type' => 'literal', + 'value' => $tag2, + 'lang' => 'en', + ); + $this->assertTrue($graph->hasProperty($taxonomy_term_2_uri, 'http://www.w3.org/2004/02/skos/core#prefLabel', $expected_value), 'Taxonomy term name found in RDF output (skos:prefLabel).'); } } diff --git a/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php b/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php index 0cfe07f..b8d20ce 100644 --- a/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php +++ b/core/modules/rdf/lib/Drupal/rdf/Tests/SiteSchemaTest.php @@ -44,7 +44,7 @@ function testSiteSchema() { $bundle_uri = url("$schema_path$entity_type/$bundle", array('absolute' => TRUE)); $bundle_properties = array( 'http://www.w3.org/2000/01/rdf-schema#isDefinedBy' => url($schema_path, array('absolute' => TRUE)), - 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => 'http://www.w3.org/2000/01/rdf-schema#class', + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => 'http://www.w3.org/2000/01/rdf-schema#Class', 'http://www.w3.org/2000/01/rdf-schema#subClassOf' => url("$schema_path$entity_type", array('absolute' => TRUE)), ); diff --git a/core/modules/rdf/rdf.install b/core/modules/rdf/rdf.install index 10d3f8d..be2cde1 100644 --- a/core/modules/rdf/rdf.install +++ b/core/modules/rdf/rdf.install @@ -4,46 +4,3 @@ * @file * Install, update and uninstall functions for the rdf module. */ - -/** - * Implements hook_schema(). - */ -function rdf_schema() { - $schema['rdf_mapping'] = array( - 'description' => 'Stores custom RDF mappings for user defined content types or overriden module-defined mappings', - 'fields' => array( - 'type' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'description' => 'The name of the entity type a mapping applies to (node, user, comment, etc.).', - ), - 'bundle' => array( - 'type' => 'varchar', - 'length' => 128, - 'not null' => TRUE, - 'description' => 'The name of the bundle a mapping applies to.', - ), - 'mapping' => array( - 'description' => 'The serialized mapping of the bundle type and fields to RDF terms.', - 'type' => 'blob', - 'not null' => FALSE, - 'size' => 'big', - 'serialize' => TRUE, - ), - ), - 'primary key' => array('type', 'bundle'), - ); - - return $schema; -} - -/** - * Implements hook_install(). - */ -function rdf_install() { - // Collect any RDF mappings that were declared by modules installed before - // this one. - $modules = module_implements('rdf_mapping'); - rdf_modules_installed($modules); -} diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index 55d89cb..7d67e94 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -67,16 +67,6 @@ function rdf_help($path, $arg) { */ /** - * RDF bundle flag: Default bundle. - * - * Implementations of hook_rdf_mapping() should use this constant for the - * 'bundle' key when defining a default set of RDF mappings for an entity type. - * Each bundle will inherit the default mappings defined for the entity type - * unless the bundle defines its own specific mappings. - */ -const RDF_DEFAULT_BUNDLE = ''; - -/** * Implements hook_rdf_namespaces(). */ function rdf_rdf_namespaces() { @@ -118,100 +108,34 @@ function rdf_get_namespaces() { * @param $type * An entity type. * @param $bundle - * (optional) A bundle name. + * A bundle name. * * @return * The mapping corresponding to the requested entity type/bundle pair or an * empty array. */ -function rdf_mapping_load($type, $bundle = RDF_DEFAULT_BUNDLE) { - // Retrieves the bundle-specific mapping from the entity info. - $entity_info = entity_get_info($type); - if (!empty($entity_info['bundles'][$bundle]['rdf_mapping'])) { - return $entity_info['bundles'][$bundle]['rdf_mapping']; - } - // If there is no mapping defined for this bundle, we return the default - // mapping that is defined for this entity type. - else { - return _rdf_get_default_mapping($type); - } -} - -/** - * @} End of "defgroup rdf". - */ - -/** - * Gets the default RDF mapping for a given entity type. - * - * @param $type - * An entity type, e.g. 'node' or 'comment'. - * - * @return - * The RDF mapping or an empty array if no mapping is defined for this entity - * type. - */ -function _rdf_get_default_mapping($type) { - $default_mappings = &drupal_static(__FUNCTION__); - - if (!isset($default_mappings)) { - // Get all of the modules that implement hook_rdf_mapping(). - $modules = module_implements('rdf_mapping'); - - // Only consider the default entity mapping definitions. - foreach ($modules as $module) { - $mappings = module_invoke($module, 'rdf_mapping'); - foreach ($mappings as $mapping) { - if ($mapping['bundle'] === RDF_DEFAULT_BUNDLE) { - $default_mappings[$mapping['type']] = $mapping['mapping']; - } +function rdf_mapping_load($type, $bundle) { + $mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $mapping = array( + 'rdftypes' => $mapping_manager->getBundleMapping($type, $bundle), + ); + $entity = entity_create($type, array('type' => $bundle)); + + $properties = $entity->getPropertyDefinitions(); + if (!empty($properties)) { + foreach ($properties as $field_name => $field_info) { + $field_mapping = $mapping_manager->getFieldMapping($type, $bundle, $field_name); + if (!empty($field_mapping)) { + $mapping[$field_name] = $field_mapping; } } } - - return isset($default_mappings[$type]) ? $default_mappings[$type] : array(); + return $mapping; } /** - * Retrieves an RDF mapping from the database. - * - * @param $type - * The entity type the mapping refers to. - * @param $bundle - * The bundle the mapping refers to. - * - * @return - * An RDF mapping structure or, FALSE if the mapping does not exist. - */ -function _rdf_mapping_load($type, $bundle) { - $mappings = _rdf_mapping_load_multiple($type, array($bundle)); - return $mappings ? reset($mappings) : FALSE; -} - -/** - * Helper function to retrieve a set of RDF mappings from the database. - * - * @param $type - * The entity type of the mappings. - * @param $bundles - * The bundles the mappings refer to. - * - * @return - * An array of RDF mapping structures, or an empty array. + * @} End of "defgroup rdf". */ -function _rdf_mapping_load_multiple($type, array $bundles) { - $mappings = db_select('rdf_mapping') - ->fields(NULL, array('bundle', 'mapping')) - ->condition('type', $type) - ->condition('bundle', $bundles) - ->execute() - ->fetchAllKeyed(); - - foreach ($mappings as $bundle => $mapping) { - $mappings[$bundle] = unserialize($mapping); - } - return $mappings; -} /** * @addtogroup rdf @@ -219,61 +143,6 @@ function _rdf_mapping_load_multiple($type, array $bundles) { */ /** - * Saves an RDF mapping to the database. - * - * Takes a mapping structure returned by hook_rdf_mapping() implementations - * and creates or updates a record mapping for each encountered entity - * type/bundle pair. If available, adds default values for non-existent mapping - * keys. - * - * @param $mapping - * The RDF mapping to save. - * - * @return - * MergeQuery object that indicates the outcome of the operation. - */ -function rdf_mapping_save($mapping) { - // In the case where a field has a mapping defined in the default entity - // mapping, but a mapping is not specified in the bundle-specific mapping, - // then use the default mapping for that field. - $mapping['mapping'] += _rdf_get_default_mapping($mapping['type']); - - $status = db_merge('rdf_mapping') - ->key(array( - 'type' => $mapping['type'], - 'bundle' => $mapping['bundle'], - )) - ->fields(array( - 'mapping' => serialize($mapping['mapping']), - )) - ->execute(); - - entity_info_cache_clear(); - - return $status; -} - -/** - * Deletes the mapping for the given bundle from the database. - * - * @param $type - * The entity type the mapping refers to. - * @param $bundle - * The bundle the mapping refers to. - * - * @return - * TRUE if the mapping is deleted, FALSE if not. - */ -function rdf_mapping_delete($type, $bundle) { - $num_rows = db_delete('rdf_mapping') - ->condition('type', $type) - ->condition('bundle', $bundle) - ->execute(); - - return (bool) ($num_rows > 0); -} - -/** * Builds an array of RDFa attributes for a given mapping. * * This array will typically be passed through Drupal\Core\Template\Attribute @@ -309,13 +178,13 @@ function rdf_rdfa_attributes($mapping, $data = NULL) { // The mapping expresses the relationship between two resources. case 'rel': case 'rev': - $attributes[$type] = $mapping['predicates']; + $attributes[$type] = $mapping['properties']; break; // The mapping expresses the relationship between a resource and some // literal text. case 'property': - $attributes['property'] = $mapping['predicates']; + $attributes['property'] = $mapping['properties']; // Convert $data to a specific format as per the callback function. if (isset($data) && isset($mapping['callback'])) { $callback = $mapping['callback']; @@ -335,98 +204,6 @@ function rdf_rdfa_attributes($mapping, $data = NULL) { */ /** - * Implements hook_modules_installed(). - * - * Checks if the installed modules have any RDF mapping definitions to declare - * and stores them in the rdf_mapping table. - * - * While both default entity mappings and specific bundle mappings can be - * defined in hook_rdf_mapping(), default entity mappings are not stored in the - * database. Only overridden mappings are stored in the database. The default - * entity mappings can be overriden by specific bundle mappings which are - * stored in the database and can be altered via the RDF CRUD mapping API. - */ -function rdf_modules_installed($modules) { - foreach ($modules as $module) { - $function = $module . '_rdf_mapping'; - if (function_exists($function)) { - foreach ($function() as $mapping) { - // Only the bundle mappings are saved in the database. - if ($mapping['bundle'] !== RDF_DEFAULT_BUNDLE) { - rdf_mapping_save($mapping); - } - } - } - } -} - -/** - * Implements hook_modules_uninstalled(). - */ -function rdf_modules_uninstalled($modules) { - // @todo Remove RDF mappings of uninstalled modules. -} - -/** - * Implements hook_entity_info_alter(). - * - * Adds the proper RDF mapping to each entity type/bundle pair. - * - * @todo May need to move the comment below to another place. - * This hook should not be used by modules to alter the bundle mappings. The UI - * should always be authoritative. UI mappings are stored in the database and - * if hook_entity_info_alter() was used to override module defined mappings, it - * would override the user defined mapping as well. - * - */ -function rdf_entity_info_alter(&$entity_info) { - // Loop through each entity type and its bundles. - foreach ($entity_info as $entity_type => $entity_type_info) { - if (!empty($entity_type_info['bundles'])) { - $bundles = array_keys($entity_type_info['bundles']); - $mappings = _rdf_mapping_load_multiple($entity_type, $bundles); - - foreach ($bundles as $bundle) { - if (isset($mappings[$bundle])) { - $entity_info[$entity_type]['bundles'][$bundle]['rdf_mapping'] = $mappings[$bundle]; - } - else { - // If no mapping was found in the database, assign the default RDF - // mapping for this entity type. - $entity_info[$entity_type]['bundles'][$bundle]['rdf_mapping'] = _rdf_get_default_mapping($entity_type); - } - } - } - } -} - -/** - * Implements hook_entity_load(). - */ -function rdf_entity_load($entities, $type) { - foreach ($entities as $entity) { - // Extracts the bundle of the entity being loaded. - $entity->rdf_mapping = rdf_mapping_load($type, $entity->bundle()); - } -} - -/** - * Implements hook_comment_load(). - */ -function rdf_comment_load($comments) { - foreach ($comments as $comment) { - // Pages with many comments can show poor performance. This information - // isn't needed until rdf_preprocess_comment() is called, but set it here - // to optimize performance for websites that implement an entity cache. - $comment->rdf_data['date'] = rdf_rdfa_attributes($comment->rdf_mapping['created'], $comment->created); - $comment->rdf_data['nid_uri'] = url('node/' . $comment->nid); - if ($comment->pid) { - $comment->rdf_data['pid_uri'] = url('comment/' . $comment->pid, array('fragment' => 'comment-' . $comment->pid)); - } - } -} - -/** * Implements hook_theme(). */ function rdf_theme() { @@ -501,14 +278,17 @@ function rdf_preprocess_node(&$variables) { // URI of the resource described within the HTML element, while the @typeof // attribute indicates its RDF type (e.g., foaf:Document, sioc:Person, and so // on.) + $mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $bundle_mapping = $mapping_manager->getBundleMapping('node', $variables['type']); $variables['attributes']['about'] = empty($variables['node_url']) ? NULL: $variables['node_url']; - $variables['attributes']['typeof'] = empty($variables['node']->rdf_mapping['rdftype']) ? NULL : $variables['node']->rdf_mapping['rdftype']; + $variables['attributes']['typeof'] = empty($bundle_mapping['rdftype']) ? NULL : $bundle_mapping['rdftype']; // Adds RDFa markup to the title of the node. Because the RDFa markup is // added to the

tag which might contain HTML code, we specify an empty // datatype to ensure the value of the title read by the RDFa parsers is a // literal. - $variables['title_attributes']['property'] = empty($variables['node']->rdf_mapping['title']['predicates']) ? NULL : $variables['node']->rdf_mapping['title']['predicates']; + $title_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'title'); + $variables['title_attributes']['property'] = empty($title_mapping['properties']) ? NULL : $title_mapping['properties']; $variables['title_attributes']['datatype'] = ''; // In full node mode, the title is not displayed by node.tpl.php so it is @@ -521,35 +301,38 @@ function rdf_preprocess_node(&$variables) { 'about' => $variables['node_url'], ), ); - if (!empty($variables['node']->rdf_mapping['title']['predicates'])) { - $element['#attributes']['property'] = $variables['node']->rdf_mapping['title']['predicates']; + if (!empty($title_mapping['properties'])) { + $element['#attributes']['property'] = $title_mapping['properties']; } drupal_add_html_head($element, 'rdf_node_title'); } // Adds RDFa markup for the date. - if (!empty($variables['node']->rdf_mapping['created'])) { - $date_attributes = rdf_rdfa_attributes($variables['node']->rdf_mapping['created'], $variables['node']->created); + $created_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'created'); + if (!empty($created_mapping)) { + $date_attributes = rdf_rdfa_attributes($created_mapping, $variables['node']->created); $variables['rdf_template_variable_attributes']['date'] = $date_attributes; if ($variables['submitted']) { $variables['rdf_template_variable_attributes']['submitted'] = $date_attributes; } } // Adds RDFa markup for the relation between the node and its author. - if (!empty($variables['node']->rdf_mapping['uid'])) { - $variables['rdf_template_variable_attributes']['name']['rel'] = $variables['node']->rdf_mapping['uid']['predicates']; + $uid_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'uid'); + if (!empty($uid_mapping)) { + $variables['rdf_template_variable_attributes']['name']['rel'] = $uid_mapping['properties']; if ($variables['submitted']) { - $variables['rdf_template_variable_attributes']['submitted']['rel'] = $variables['node']->rdf_mapping['uid']['predicates']; + $variables['rdf_template_variable_attributes']['submitted']['rel'] = $uid_mapping['properties']; } } // Adds RDFa markup annotating the number of comments a node has. - if (isset($variables['node']->comment_count) && !empty($variables['node']->rdf_mapping['comment_count']['predicates'])) { + $comment_count_mapping = $mapping_manager->getFieldMapping('node', $variables['type'], 'comment_count'); + if (isset($variables['node']->comment_count) && !empty($comment_count_mapping['properties'])) { // Annotates the 'x comments' link in teaser view. if (isset($variables['content']['links']['comment']['#links']['comment-comments'])) { - $comment_count_attributes['property'] = $variables['node']->rdf_mapping['comment_count']['predicates']; + $comment_count_attributes['property'] = $comment_count_mapping['properties']; $comment_count_attributes['content'] = $variables['node']->comment_count; - $comment_count_attributes['datatype'] = $variables['node']->rdf_mapping['comment_count']['datatype']; + $comment_count_attributes['datatype'] = $comment_count_mapping['datatype']; // According to RDFa parsing rule number 4, a new subject URI is created // from the href attribute if no rel/rev attribute is present. To get the // original node URL from the about attribute of the parent container we @@ -566,9 +349,9 @@ function rdf_preprocess_node(&$variables) { '#tag' => 'meta', '#attributes' => array( 'about' => $variables['node_url'], - 'property' => $variables['node']->rdf_mapping['comment_count']['predicates'], + 'property' => $comment_count_mapping['properties'], 'content' => $variables['node']->comment_count, - 'datatype' => $variables['node']->rdf_mapping['comment_count']['datatype'], + 'datatype' => isset($comment_count_mapping['datatype']) ? $comment_count_mapping['datatype'] : NULL, ), ); drupal_add_html_head($element, 'rdf_node_comment_count'); @@ -580,13 +363,16 @@ function rdf_preprocess_node(&$variables) { * Implements hook_preprocess_HOOK() for field.tpl.php. */ function rdf_preprocess_field(&$variables) { + $mapping_manager = drupal_container()->get('rdf.mapping_manager'); $element = $variables['element']; - $mapping = rdf_mapping_load($element['#entity_type'], $element['#bundle']); + $entity_type = $element['#entity_type']; + $bundle = $element['#bundle']; $field_name = $element['#field_name']; + $field_mapping = $mapping_manager->getFieldMappingConfig($entity_type, $bundle, $field_name)->get(); - if (!empty($mapping) && !empty($mapping[$field_name])) { + if (!empty($field_mapping)) { foreach ($element['#items'] as $delta => $item) { - $variables['item_attributes'][$delta] = rdf_rdfa_attributes($mapping[$field_name], $item); + $variables['item_attributes'][$delta] = rdf_rdfa_attributes($field_mapping, $item); // If this field is an image, RDFa will not output correctly when the // image is in a containing tag. If the field is a file, RDFa will // not output correctly if the filetype icon comes before the link to the @@ -610,11 +396,13 @@ function rdf_preprocess_field(&$variables) { function rdf_preprocess_user(&$variables) { $account = $variables['elements']['#user']; $uri = $account->uri(); + $mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $bundle_mapping = $mapping_manager->getBundleMapping('user', 'user'); // Adds RDFa markup to the user profile page. Fields displayed in this page // will automatically describe the user. - if (!empty($account->rdf_mapping['rdftype'])) { - $variables['attributes']['typeof'] = $account->rdf_mapping['rdftype']; + if (!empty($bundle_mapping['types'])) { + $variables['attributes']['typeof'] = $bundle_mapping['types']; $variables['attributes']['about'] = url($uri['path'], $uri['options']); } // Adds the relationship between the sioc:UserAccount and the foaf:Person who @@ -629,11 +417,12 @@ function rdf_preprocess_user(&$variables) { ), ); // Adds the markup for username. + $name_mapping = $mapping_manager->getFieldMapping('user', 'user', 'name'); $username_meta = array( '#tag' => 'meta', '#attributes' => array( 'about' => url($uri['path'], $uri['options']), - 'property' => $account->rdf_mapping['name']['predicates'], + 'property' => $name_mapping['properties'], 'content' => $account->name, ) ); @@ -683,12 +472,12 @@ function rdf_preprocess_username(&$variables) { // datatype attribute to ensure the username is parsed as a plain literal // in RDFa 1.0 and 1.1. if (!empty($rdf_mapping['name'])) { - $attributes['property'] = $rdf_mapping['name']['predicates']; + $attributes['property'] = $rdf_mapping['name']['properties']; $attributes['datatype'] = ''; } // Add the homepage RDFa markup if present. if (!empty($variables['homepage']) && !empty($rdf_mapping['homepage'])) { - $attributes['rel'] = $rdf_mapping['homepage']['predicates']; + $attributes['rel'] = $rdf_mapping['homepage']['properties']; } // The remaining attributes can have multiple values listed, with whitespace // separating the values in the RDFa attributes @@ -723,15 +512,15 @@ function rdf_preprocess_comment(&$variables) { } // Adds RDFa markup for the relation between the comment and its author. if (!empty($comment->rdf_mapping['uid'])) { - $variables['rdf_template_variable_attributes']['author']['rel'] = $comment->rdf_mapping['uid']['predicates']; - $variables['rdf_template_variable_attributes']['submitted']['rel'] = $comment->rdf_mapping['uid']['predicates']; + $variables['rdf_template_variable_attributes']['author']['rel'] = $comment->rdf_mapping['uid']['properties']; + $variables['rdf_template_variable_attributes']['submitted']['rel'] = $comment->rdf_mapping['uid']['properties']; } if (!empty($comment->rdf_mapping['title'])) { // Adds RDFa markup to the subject of the comment. Because the RDFa markup // is added to an

tag which might contain HTML code, we specify an // empty datatype to ensure the value of the title read by the RDFa parsers // is a literal. - $variables['title_attributes']['property'] = $comment->rdf_mapping['title']['predicates']; + $variables['title_attributes']['property'] = $comment->rdf_mapping['title']['properties']; $variables['title_attributes']['datatype'] = ''; } @@ -739,7 +528,7 @@ function rdf_preprocess_comment(&$variables) { // it belongs to. If available, the parent comment is also annotated. if (!empty($comment->rdf_mapping['pid'])) { // Adds the relation to the parent node. - $parent_node_attributes['rel'] = $comment->rdf_mapping['pid']['predicates']; + $parent_node_attributes['rel'] = $comment->rdf_mapping['pid']['properties']; // The parent node URI is precomputed as part of the rdf_data so that it can // be cached as part of the entity. $parent_node_attributes['resource'] = $comment->rdf_data['nid_uri']; @@ -747,7 +536,7 @@ function rdf_preprocess_comment(&$variables) { // Adds the relation to parent comment, if it exists. if ($comment->pid != 0) { - $parent_comment_attributes['rel'] = $comment->rdf_mapping['pid']['predicates']; + $parent_comment_attributes['rel'] = $comment->rdf_mapping['pid']['properties']; // The parent comment URI is precomputed as part of the rdf_data so that // it can be cached as part of the entity. $parent_comment_attributes['resource'] = $comment->rdf_data['pid_uri']; @@ -760,14 +549,17 @@ function rdf_preprocess_comment(&$variables) { * Implements hook_preprocess_HOOK() for taxonomy-term.tpl.php. */ function rdf_preprocess_taxonomy_term(&$variables) { - // Adds the RDF type of the term and the term name in a tag. $term = $variables['term']; + $mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $bundle_mapping = $mapping_manager->getBundleMapping('taxonomy_term', $term->vid); + $name_field_mapping = $mapping_manager->getFieldMapping('taxonomy_term', $term->vid, 'name'); + // Adds the RDF type of the term and the term name in a tag. $term_label_meta = array( '#tag' => 'meta', '#attributes' => array( 'about' => url('taxonomy/term/' . $term->tid), - 'typeof' => $term->rdf_mapping['rdftype'], - 'property' => $term->rdf_mapping['name']['predicates'], + 'typeof' => $bundle_mapping['types'], + 'property' => $name_field_mapping['properties'], 'content' => $term->label(), ), ); @@ -788,13 +580,16 @@ function rdf_field_attach_view_alter(&$output, $context) { // yet and thus have no $item['taxonomy_term']. if (isset($item['taxonomy_term'])) { $term = $item['taxonomy_term']; - if (!empty($term->rdf_mapping['rdftype'])) { - $element[$delta]['#options']['attributes']['typeof'] = $term->rdf_mapping['rdftype']; + $mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $bundle_mapping = $mapping_manager->getBundleMapping('taxonomy_term', $term->vid); + if (!empty($bundle_mapping['types'])) { + $element[$delta]['#options']['attributes']['typeof'] = $bundle_mapping['types']; } - if (!empty($term->rdf_mapping['name']['predicates'])) { + $name_field_mapping = $mapping_manager->getFieldMapping('taxonomy_term', $term->vid, 'name'); + if (!empty($name_field_mapping['properties'])) { // A property attribute is used with an empty datatype attribute so // the term name is parsed as a plain literal in RDFa 1.0 and 1.1. - $element[$delta]['#options']['attributes']['property'] = $term->rdf_mapping['name']['predicates']; + $element[$delta]['#options']['attributes']['property'] = $name_field_mapping['properties']; $element[$delta]['#options']['attributes']['datatype'] = ''; } } diff --git a/core/modules/rdf/tests/rdf_test.module b/core/modules/rdf/tests/rdf_test.module index 4d90472..27e4382 100644 --- a/core/modules/rdf/tests/rdf_test.module +++ b/core/modules/rdf/tests/rdf_test.module @@ -46,14 +46,3 @@ function rdf_test_rdf_mapping() { ), ); } - -/** - * Implements hook_rdf_namespaces(). - */ -function rdf_test_rdf_namespaces() { - return array( - 'dc' => 'http://purl.org/conflicting/namespace', - 'foaf' => 'http://xmlns.com/foaf/0.1/', - 'foaf1' => 'http://xmlns.com/foaf/0.1/', - ); -} diff --git a/core/modules/rdf/tests/rdf_test_mapping/lib/Drupal/rdf_test_mapping/EventSubscriber/TestMappingSubscriber.php b/core/modules/rdf/tests/rdf_test_mapping/lib/Drupal/rdf_test_mapping/EventSubscriber/TestMappingSubscriber.php index 44e9460..9c03f7e 100644 --- a/core/modules/rdf/tests/rdf_test_mapping/lib/Drupal/rdf_test_mapping/EventSubscriber/TestMappingSubscriber.php +++ b/core/modules/rdf/tests/rdf_test_mapping/lib/Drupal/rdf_test_mapping/EventSubscriber/TestMappingSubscriber.php @@ -7,7 +7,7 @@ namespace Drupal\rdf_test_mapping\EventSubscriber; -use Drupal\rdf\RdfMappingEvents; +use Drupal\rdf\Mapping\RdfMappingEvents; use Drupal\rdf\SiteSchema\BundleSchema; use Drupal\rdf\SiteSchema\SiteSchema; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -15,11 +15,12 @@ class TestMappingSubscriber implements EventSubscriberInterface { const STAGING_SITE_TYPE_URI = 'http://staging.com/entity_test_bundle'; + const STAGING_SITE_PROPERTY_URI = 'http://staging.com/entity_test_bundle/user_id'; /** - * Demonstrate mapping between external type and site schema type. + * Demonstrate mapping external type to site schema type on consumption. * - * @param \Drupal\rdf\MapTypesFromInputEvent $event + * @param \Drupal\rdf\Mapping\MapTypesFromInputEvent $event * The mapping event. */ public function mapTypesFromInput($event) { @@ -48,10 +49,46 @@ public function mapTypesFromInput($event) { } /** + * Demonstrate mapping bundle to external type for publishing. + * + * Generally, one should set mappings for output in the RDF mapping config + * instead of this event. + * + * @param \Drupal\rdf\Mapping\MapBundleForOutputEvent $event + * The mapping event. + */ + public function mapBundleForOutput($event) { + $term_schema = $event->getTermSchema(); + $ids = $term_schema->getTermIds(); + if ($ids['entity_type'] == 'entity_test' && $ids['bundle'] == 'entity_test') { + $event->addTypes(array(self::STAGING_SITE_TYPE_URI)); + } + } + + /** + * Demonstrate mapping field to external property for publishing. + * + * Generally, one should set mappings for output in the RDF mapping config + * instead of this event. + * + * @param \Drupal\rdf\Mapping\MapFieldForOutputEvent $event + * The mapping event. + */ + public function mapFieldForOutput($event) { + $term_schema = $event->getTermSchema(); + $ids = $term_schema->getTermIds(); + if ($ids['entity_type'] == 'entity_test' && $ids['bundle'] == 'entity_test' && $ids['field_name'] == 'user_id') { + $event->addPredicates(array(self::STAGING_SITE_PROPERTY_URI)); + } + } + + /** * Implements EventSubscriberInterface::getSubscribedEvents(). */ static function getSubscribedEvents() { $events[RdfMappingEvents::MAP_TYPES_FROM_INPUT] = 'mapTypesFromInput'; + $events[RdfMappingEvents::MAP_BUNDLE_FOR_OUTPUT] = 'mapBundleForOutput'; + $events[RdfMappingEvents::MAP_FIELD_FOR_OUTPUT] = 'mapFieldForOutput'; return $events; } diff --git a/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.info b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.info new file mode 100644 index 0000000..c44f047 --- /dev/null +++ b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.info @@ -0,0 +1,6 @@ +name = "RDF module namespaces test" +description = "Test namespace declaration." +package = Testing +core = 8.x +hidden = TRUE +dependencies[] = rdf diff --git a/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.module b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.module new file mode 100644 index 0000000..c938927 --- /dev/null +++ b/core/modules/rdf/tests/rdf_test_namespaces/rdf_test_namespaces.module @@ -0,0 +1,17 @@ + 'http://purl.org/conflicting/namespace', + 'foaf' => 'http://xmlns.com/foaf/0.1/', + 'foaf1' => 'http://xmlns.com/foaf/0.1/', + ); +} diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index a15874e..8c29f2c 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -1315,30 +1315,6 @@ function taxonomy_rdf_mapping() { 'name' => array( 'predicates' => array('rdfs:label', 'skos:prefLabel'), ), - 'description' => array( - 'predicates' => array('skos:definition'), - ), - 'vid' => array( - 'predicates' => array('skos:inScheme'), - 'type' => 'rel', - ), - 'parent' => array( - 'predicates' => array('skos:broader'), - 'type' => 'rel', - ), - ), - ), - array( - 'type' => 'taxonomy_vocabulary', - 'bundle' => RDF_DEFAULT_BUNDLE, - 'mapping' => array( - 'rdftype' => array('skos:ConceptScheme'), - 'name' => array( - 'predicates' => array('dc:title'), - ), - 'description' => array( - 'predicates' => array('rdfs:comment'), - ), ), ), ); diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 02f5072..23e3fb9 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -2730,28 +2730,6 @@ function user_cookie_delete($cookie_name) { } /** - * Implements hook_rdf_mapping(). - */ -function user_rdf_mapping() { - return array( - array( - 'type' => 'user', - 'bundle' => RDF_DEFAULT_BUNDLE, - 'mapping' => array( - 'rdftype' => array('sioc:UserAccount'), - 'name' => array( - 'predicates' => array('foaf:name'), - ), - 'homepage' => array( - 'predicates' => array('foaf:page'), - 'type' => 'rel', - ), - ), - ), - ); -} - -/** * Implements hook_file_download_access(). */ function user_file_download_access($field, EntityInterface $entity, File $file) { diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index 5cb8fb3..81d1d68 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -108,34 +108,6 @@ function standard_install() { node_add_body_field($type); } - // Insert default pre-defined RDF mapping into the database. - $rdf_mappings = array( - array( - 'type' => 'node', - 'bundle' => 'page', - 'mapping' => array( - 'rdftype' => array('foaf:Document'), - ), - ), - array( - 'type' => 'node', - 'bundle' => 'article', - 'mapping' => array( - 'field_image' => array( - 'predicates' => array('og:image', 'rdfs:seeAlso'), - 'type' => 'rel', - ), - 'field_tags' => array( - 'predicates' => array('dc:subject'), - 'type' => 'rel', - ), - ), - ), - ); - foreach ($rdf_mappings as $rdf_mapping) { - rdf_mapping_save($rdf_mapping); - } - // Default "Basic page" to not be promoted and have comments disabled. variable_set('node_options_page', array('status')); variable_set('comment_page', COMMENT_NODE_HIDDEN); @@ -328,4 +300,95 @@ function standard_install() { theme_enable(array('seven')); config('system.theme')->set('admin', 'seven')->save(); variable_set('node_admin_theme', '1'); + + // Save the Node RDF mapping configuration. + $rdf_mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $node_shared_field_mappings = array( + 'title' => array( + 'properties' => array('dc:title'), + ), + 'created' => array( + 'properties' => array('dc:date', 'dc:created'), + 'datatype' => 'xsd:dateTime', + 'datatype_callback' => 'date_iso8601', + ), + 'changed' => array( + 'properties' => array('dc:modified'), + 'datatype' => 'xsd:dateTime', + 'datatype_callback' => 'date_iso8601', + ), + 'body' => array( + 'properties' => array('content:encoded'), + ), + 'uid' => array( + 'properties' => array('sioc:has_creator'), + 'type' => 'rel', + ), + 'name' => array( + 'properties' => array('foaf:name'), + ), + 'comment_count' => array( + 'properties' => array('sioc:num_replies'), + 'datatype' => 'xsd:integer', + ), + 'last_activity' => array( + 'properties' => array('sioc:last_activity_date'), + 'datatype' => 'xsd:dateTime', + 'datatype_callback' => 'date_iso8601', + ), + ); + // Save the bundle mapping and shared field mappings for both node bundles. + foreach (array('article', 'page') as $bundle) { + // Save bundle mapping config. + $config = $rdf_mapping_manager->getBundleMappingConfig('node', $bundle); + $bundle_mapping = array_merge($config->get(), array('types' => array('foaf:Document', 'sioc:Item'))); + $config->setData($bundle_mapping)->save(); + // Iterate over shared field mappings and save. + foreach ($node_shared_field_mappings as $field_name => $field_mapping) { + $config = $rdf_mapping_manager->getFieldMappingConfig('node', $bundle, $field_name); + $field_mapping = array_merge($config->get(), $field_mapping); + $config->setData($field_mapping)->save(); + } + } + + // Save the RDF mappings for fields which are unique to articles. + $field_image_mapping = array( + 'properties' => array('og:image', 'rdfs:seeAlso'), + 'type' => 'rel', + ); + $field_tags_mapping = array( + 'properties' => array('dc:subject'), + 'type' => 'rel', + ); + // Configure RDF mapping for field_image on Article bundle. + $config = $rdf_mapping_manager->getFieldMappingConfig('node', 'article', 'field_image'); + $field_mapping = array_merge($config->get(), $field_image_mapping); + $config->setData($field_mapping)->save(); + // Configure RDF mapping for field_tags on Article bundle. + $config = $rdf_mapping_manager->getFieldMappingConfig('node', 'article', 'field_tags'); + $field_mapping = array_merge($config->get(), $field_tags_mapping); + $config->setData($field_mapping)->save(); + + // Configure RDF mapping for User bundle. + $config = $rdf_mapping_manager->getBundleMappingConfig('user', 'user'); + $bundle_mapping = array_merge($config->get(), array('types' => array('sioc:UserAccount'))); + $config->setData($bundle_mapping)->save(); + // @todo Change to reflect field names once User uses real fields. + // Configure RDF mapping for name field on User bundle. + $config = $rdf_mapping_manager->getFieldMappingConfig('user', 'user', 'name'); + $field_mapping = array_merge($config->get(), array('properties' => array('foaf:name'))); + $config->setData($field_mapping)->save(); + // Configure RDF mapping for homepage field on User bundle. + $config = $rdf_mapping_manager->getFieldMappingConfig('user', 'user', 'homepage'); + $field_mapping = array_merge($config->get(), array('properties' => array('foaf:page'), 'type' => 'rel')); + $config->setData($field_mapping)->save(); + + // Configure RDF mapping for Tags bundle. + $config = $rdf_mapping_manager->getBundleMappingConfig('taxonomy_term', 'tags'); + $bundle_mapping = array_merge($config->get(), array('types' => array('skos:Concept'))); + $config->setData($bundle_mapping)->save(); + // Configure RDF mapping for name field on Tags bundle. + $config = $rdf_mapping_manager->getFieldMappingConfig('taxonomy_term', 'tags', 'name'); + $field_mapping = array_merge($config->get(), array('properties' => array('rdfs:label', 'skos:prefLabel'))); + $config->setData($field_mapping)->save(); }