diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php index dc0fe82010e656e4c93e4d8ff87ae78e90b2a054..89386ca44c69153b37c5d7b2c91aa33a4cb3e894 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php @@ -78,6 +78,11 @@ public function viewElements(FieldItemListInterface $items) { $suffix = (count($suffixes) > 1) ? format_plural($item->value, $suffixes[0], $suffixes[1]) : $suffixes[0]; $output = $prefix . $output . $suffix; } + // Output the raw value in a content attribute if the text of the HTML + // element differs from the raw value (for example when a prefix is used). + if (!empty($item->_attributes) && $item->value != $output) { + $item->_attributes += array('content' => $item->value); + } $elements[$delta] = array('#markup' => $output); } diff --git a/core/modules/rdf/src/Tests/Field/FieldRdfaTestBase.php b/core/modules/rdf/src/Tests/Field/FieldRdfaTestBase.php index 5332912534cf0fa0ec32249af3f76f85320f4e8c..e14eb913af35ba47a4a4c4ecae0837ce73f384f5 100644 --- a/core/modules/rdf/src/Tests/Field/FieldRdfaTestBase.php +++ b/core/modules/rdf/src/Tests/Field/FieldRdfaTestBase.php @@ -96,6 +96,7 @@ protected function assertFormatterRdfa($formatter, $property, $expected_rdf_valu $build = entity_view($this->entity, 'default'); $output = drupal_render($build); $graph = new \EasyRdf_Graph($this->uri, $output, 'rdfa'); + $this->setRawContent($output); // If verbose debugging is turned on, display the HTML and parsed RDF // in the results. @@ -109,8 +110,11 @@ protected function assertFormatterRdfa($formatter, $property, $expected_rdf_valu /** * Creates the field for testing. + * + * @param array $field_settings + * (optional) An array of field settings. */ - protected function createTestField() { + protected function createTestField($field_settings = array()) { entity_create('field_storage_config', array( 'name' => $this->fieldName, 'entity_type' => 'entity_test', @@ -120,6 +124,7 @@ protected function createTestField() { 'entity_type' => 'entity_test', 'field_name' => $this->fieldName, 'bundle' => 'entity_test', + 'settings' => $field_settings, ))->save(); } @@ -136,4 +141,52 @@ protected function getAbsoluteUri($entity) { return $entity->url('canonical', array('absolute' => TRUE)); } + /** + * Parses a content and return the html element. + * + * @param string $content + * The html to parse. + * + * @return array + * An array containing simplexml objects. + */ + protected function parseContent($content) { + $htmlDom = new \DOMDocument(); + @$htmlDom->loadHTML('<?xml encoding="UTF-8">' . $content); + $elements = simplexml_import_dom($htmlDom); + + return $elements; + } + + /** + * Performs an xpath search on a certain content. + * + * The search is relative to the root element of the $content variable. + * + * @param string $content + * The html to parse. + * @param string $xpath + * The xpath string to use in the search. + * @param array $arguments + * Some arguments for the xpath. + * + * @return array|FALSE + * The return value of the xpath search. For details on the xpath string + * format and return values see the SimpleXML documentation, + * http://php.net/manual/function.simplexml-element-xpath.php. + */ + protected function xpathContent($content, $xpath, array $arguments = array()) { + if ($elements = $this->parseContent($content)) { + $xpath = $this->buildXPathQuery($xpath, $arguments); + $result = $elements->xpath($xpath); + // Some combinations of PHP / libxml versions return an empty array + // instead of the documented FALSE. Forcefully convert any falsish values + // to an empty array to allow foreach(...) constructions. + return $result ? $result : array(); + } + else { + return FALSE; + } + } + } diff --git a/core/modules/rdf/src/Tests/Field/NumberFieldRdfaTest.php b/core/modules/rdf/src/Tests/Field/NumberFieldRdfaTest.php new file mode 100644 index 0000000000000000000000000000000000000000..a8a607d6c4db502b8ba69ee8828a22879242cee6 --- /dev/null +++ b/core/modules/rdf/src/Tests/Field/NumberFieldRdfaTest.php @@ -0,0 +1,197 @@ +<?php +/** + * @file + * Contains \Drupal\rdf\Tests\Field\NumberFieldRdfaTest. + */ + +namespace Drupal\rdf\Tests\Field; + +/** + * Tests RDFa output by number field formatters. + * + * @group rdf + */ +class NumberFieldRdfaTest extends FieldRdfaTestBase { + + /** + * Tests the integer formatter. + */ + public function testIntegerFormatter() { + $this->fieldType = 'integer'; + $testValue = 3; + $this->createTestField(); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa(array('type' => $this->fieldType), 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is not created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content]'); + $this->assertFalse($result); + } + + /** + * Tests the integer formatter with settings. + */ + public function testIntegerFormatterWithSettings() { + $this->fieldType = 'integer'; + $formatter = array( + 'type' => $this->fieldType, + 'settings' => array( + 'thousand_separator' => '.', + 'prefix_suffix' => TRUE, + ), + ); + $testValue = 3333333.33; + $field_instance_settings = array( + 'prefix' => '#', + 'suffix' => ' llamas.', + ); + $this->createTestField($field_instance_settings); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content=:testValue]', array(':testValue' => $testValue)); + $this->assertTrue($result); + } + + /** + * Tests the float formatter. + */ + public function testFloatFormatter() { + $this->fieldType = 'float'; + $testValue = 3.33; + $this->createTestField(); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa(array('type' => $this->fieldType), 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is not created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content]'); + $this->assertFalse($result); + } + + /** + * Tests the float formatter with settings. + */ + public function testFloatFormatterWithSettings() { + $this->fieldType = 'float'; + $formatter = array( + 'type' => $this->fieldType, + 'settings' => array( + 'thousand_separator' => '.', + 'decimal_separator' => ',', + 'prefix_suffix' => TRUE, + ), + ); + $testValue = 3333333.33; + $field_instance_settings = array( + 'prefix' => '$', + 'suffix' => ' more.', + ); + $this->createTestField($field_instance_settings); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content=:testValue]', array(':testValue' => $testValue)); + $this->assertTrue($result); + } + + /** + * Tests the float formatter with a scale. Scale is not exercised. + */ + public function testFloatFormatterWithScale() { + $this->fieldType = 'float'; + $formatter = array( + 'type' => $this->fieldType, + 'settings' => array( + 'scale' => 5, + ), + ); + $testValue = 3.33; + $this->createTestField(); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is not created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content]'); + $this->assertFalse($result); + } + + /** + * Tests the float formatter with a scale. Scale is exercised. + */ + public function testFloatFormatterWithScaleExercised() { + $this->fieldType = 'float'; + $formatter = array( + 'type' => $this->fieldType, + 'settings' => array( + 'scale' => 5, + ), + ); + $testValue = 3.1234567; + $this->createTestField(); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content=:testValue]', array(':testValue' => $testValue)); + $this->assertTrue($result); + } + + /** + * Tests the decimal formatter. + */ + public function testDecimalFormatter() { + $this->fieldType = 'decimal'; + $testValue = 3.33; + $this->createTestField(); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa(array('type' => $this->fieldType), 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is not created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content]'); + $this->assertFalse($result); + } + + /** + * Tests the decimal formatter with settings. + */ + public function testDecimalFormatterWithSettings() { + $this->fieldType = 'decimal'; + $formatter = array( + 'type' => $this->fieldType, + 'settings' => array( + 'thousand_separator' => 't', + 'decimal_separator' => '#', + 'prefix_suffix' => TRUE, + ), + ); + $testValue = 3333333.33; + $field_instance_settings = array( + 'prefix' => '$', + 'suffix' => ' more.', + ); + $this->createTestField($field_instance_settings); + $this->createTestEntity($testValue); + $this->assertFormatterRdfa($formatter, 'http://schema.org/baseSalary', array('value' => $testValue)); + + // Test that the content attribute is created. + $result = $this->xpathContent($this->getRawContent(), '//div[contains(@class, "field-item") and @content=:testValue]', array(':testValue' => $testValue)); + $this->assertTrue($result); + } + + /** + * Creates the RDF mapping for the field. + */ + protected function createTestEntity($testValue) { + // Add the mapping. + $mapping = rdf_get_mapping('entity_test', 'entity_test'); + $mapping->setFieldMapping($this->fieldName, array( + 'properties' => array('schema:baseSalary'), + ))->save(); + + // Set up test entity. + $this->entity = entity_create('entity_test', array()); + $this->entity->{$this->fieldName}->value = $testValue; + } +}