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/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 a37679c..d53f10e 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -811,53 +811,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/BundleRdfMappingStorageController.php b/core/modules/rdf/lib/Drupal/rdf/BundleRdfMappingStorageController.php new file mode 100644 index 0000000..051623a --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/BundleRdfMappingStorageController.php @@ -0,0 +1,19 @@ +siteSchema->bundle($entity->entity_type, $entity->bundle); + } + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php index 764c2f9..f58658d 100644 --- a/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php +++ b/core/modules/rdf/lib/Drupal/rdf/EventSubscriber/MappingSubscriber.php @@ -35,11 +35,41 @@ public function mapTypesFromInput(\Drupal\rdf\MapTypesFromInputEvent $event) { } } + public function mapBundleForOutput(\Drupal\rdf\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\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/FieldRdfMappingStorageController.php b/core/modules/rdf/lib/Drupal/rdf/FieldRdfMappingStorageController.php new file mode 100644 index 0000000..04b5b7f --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/FieldRdfMappingStorageController.php @@ -0,0 +1,20 @@ +siteSchema->field($entity->entity_type, $entity->bundle, $entity->field_name); + } + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/MapBundleForOutputEvent.php b/core/modules/rdf/lib/Drupal/rdf/MapBundleForOutputEvent.php new file mode 100644 index 0000000..59bfce0 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/MapBundleForOutputEvent.php @@ -0,0 +1,59 @@ +termSchema = $term_schema; + $this->curies = 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->curies = array_merge($this->curies, $curies); + } + + public function getCuries() { + return $this->curies; + } +} diff --git a/core/modules/rdf/lib/Drupal/rdf/MapFieldForOutputEvent.php b/core/modules/rdf/lib/Drupal/rdf/MapFieldForOutputEvent.php new file mode 100644 index 0000000..2294c3a --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/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/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/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 index 0e3fdae..f74c791 100644 --- a/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php +++ b/core/modules/rdf/lib/Drupal/rdf/RdfMappingEvents.php @@ -26,4 +26,24 @@ */ const MAP_TYPES_FROM_INPUT = 'rdf.map_types_from_input'; + /** + * Maps a bundle to corresponding RDF URIs. + * + * In contrast to MAP_INPUT_TYPES, this event is triggered when RDF is being + * published. Modules can use this event to add RDF types to a mapping, which + * will then be published in the site's RDFa, JSON-LD, etc. However, a module + * does not have to use this event to add RDF types. RDF module manages an + * RDF mapping configuration file for each bundle which modules can also use + * to register mappings. + * + * @todo Add a note about this being cached once it is. + * + * @see \Drupal\rdf\RdfMappingManager + * + * @var string + */ + const MAP_BUNDLE_FOR_OUTPUT = 'rdf.map_bundle_for_output'; + + const MAP_FIELD_FOR_OUTPUT = 'rdf.map_field_for_output'; + } diff --git a/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php b/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php index 90588e9..6ab6341 100644 --- a/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php +++ b/core/modules/rdf/lib/Drupal/rdf/RdfMappingManager.php @@ -10,6 +10,8 @@ use ReflectionClass; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\rdf\MapTypesFromInputEvent; +use Drupal\rdf\MapBundleForOutputEvent; +use Drupal\rdf\MapFieldForOutputEvent; use Drupal\rdf\RdfMappingEvents; use Drupal\rdf\SiteSchema\BundleSchema; use Drupal\rdf\SiteSchema\SiteSchema; @@ -76,6 +78,40 @@ public function getTypedDataIdsFromTypeUris($input_rdf_types) { } /** + * Convert Typed Data IDs to an array of RDF types. + * + * @param string $entity_type + * The entity type of the bundle which the types correspond to. + * @param string $bundle + * The name of the bundle which the types correspond to. + * @param string $schema_id + * The site schema which is being mapped to. + */ + 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 site schema URI which corresponds to the bundle. + $curies = $this->mapBundleForOutput($term_schema); + return $curies; + } + + 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); + } + + 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(); + } + + 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 @@ -98,4 +134,30 @@ protected function mapTypesFromInput($input_rdf_types) { return $mapping_event->getSiteSchemaUri(); } + + protected function mapBundleForOutput($term_schema) { + $mapping = array(); + $typeMap = new MapBundleForOutputEvent($term_schema); + $this->dispatcher->dispatch(RdfMappingEvents::MAP_BUNDLE_FOR_OUTPUT, $typeMap); + $types = $typeMap->getCuries(); + if (!empty($types)) { + $mapping['types'] = $types; + } + return $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/RdfMappingStorageControllerBase.php b/core/modules/rdf/lib/Drupal/rdf/RdfMappingStorageControllerBase.php new file mode 100644 index 0000000..afbe5d7 --- /dev/null +++ b/core/modules/rdf/lib/Drupal/rdf/RdfMappingStorageControllerBase.php @@ -0,0 +1,40 @@ +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); + } + +} diff --git a/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php b/core/modules/rdf/lib/Drupal/rdf/SiteSchema/BundleSchema.php index 2c92696..e82b9ed 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; } + protected function getMappingConfigKeys() { + $keys = parent::getMappingConfigKeys(); + $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..a1665e8 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; } + protected function getMappingConfigKeys() { + 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..0d56ca5 --- /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; + } + + protected function getMappingConfigKeys() { + 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..edc7c34 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->getMappingConfigKeys() as $key => $value) { + $config->set($key, $value); + } + $config->save(); + } + + return $config; + } + + public function getMappingConfigName() { + return $this->configPrefix . '.' . implode(':', $this->getMappingConfigKeys()); + } + } 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..3fafc3b 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/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 264a090..2cf869c 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -128,100 +128,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 @@ -229,61 +163,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 @@ -345,98 +224,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() { @@ -511,14 +298,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['predicates']) ? NULL : $title_mapping['predicates']; $variables['title_attributes']['datatype'] = ''; // In full node mode, the title is not displayed by node.tpl.php so it is @@ -531,35 +321,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['predicates'])) { + $element['#attributes']['property'] = $title_mapping['predicates']; } 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['predicates']; 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['predicates']; } } // 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['predicates'])) { // 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['predicates']; $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 @@ -576,9 +369,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['predicates'], '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'); diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index 48da6b1..2325c14 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -218,34 +218,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); @@ -432,4 +404,75 @@ function standard_install() { theme_enable(array('seven')); config('system.theme')->set('admin', 'seven')->save(); variable_set('node_admin_theme', '1'); + + // Save the RDF mapping configuration. + $rdf_mapping_manager = drupal_container()->get('rdf.mapping_manager'); + $bundle_mapping = array( + 'types' => array('foaf:Document', 'sioc:Item'), + ); + $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(), $bundle_mapping); + $config->setData($bundle_mapping)->save(); + // Iterate over shared field mappings and save. + foreach ($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', + ); + // Save field_image mapping. + $config = $rdf_mapping_manager->getFieldMappingConfig('node', 'article', 'field_image'); + $field_mapping = array_merge($config->get(), $field_image_mapping); + $config->setData($field_mapping)->save(); + // Save field_tags mapping. + $rdf_mapping_manager->getFieldMappingConfig('node', 'article', 'field_tags'); + $field_mapping = array_merge($config->get(), $field_tags_mapping); + $config->setData($field_mapping)->save(); } diff --git a/index.php b/index.php index 98bcddb..53c6199 100644 --- a/index.php +++ b/index.php @@ -37,6 +37,7 @@ // Create a request object from the HTTPFoundation. $request = Request::createFromGlobals(); +$mapping = rdf_mapping_load('node', 'article'); $response = $kernel->handle($request)->prepare($request)->send(); $kernel->terminate($request, $response);