You are here

class RestWSFormatXML in RESTful Web Services 7.2

Same name and namespace in other branches
  1. 7 restws.formats.inc \RestWSFormatXML

A formatter for XML.

Hierarchy

Expanded class hierarchy of RestWSFormatXML

2 string references to 'RestWSFormatXML'
hook_restws_format_info in ./restws.api.php
Define restws compatible formats.
restws_restws_format_info in ./restws.module
Implements hook_restws_format_info().

File

./restws.formats.inc, line 488
RESTful web services module formats.

View source
class RestWSFormatXML extends RestWSBaseFormat {

  /**
   * Gets the representation of a resource.
   */
  public function viewResource($resourceController, $id) {
    $xml = new DOMDocument('1.0', 'utf-8');
    $element = $xml
      ->createElement($resourceController
      ->resource());
    self::addToXML($xml, $element, $resourceController
      ->wrapper($id));
    $xml
      ->appendChild($element);
    $function = __FUNCTION__;
    drupal_alter('restws_response', $xml, $function, $this->formatName, $resourceController);
    return $xml
      ->saveXML();
  }

  /**
   * Creates a new resource.
   */
  public function createResource($resourceController, $data) {
    $values = $this
      ->unserialize($resourceController
      ->propertyInfo(), $data);
    $id = $resourceController
      ->create($values);
    $xml = new DOMDocument('1.0', 'utf-8');
    $element = $xml
      ->createElement('uri');
    self::setXMLReference($element, $resourceController
      ->resource(), $id);
    $xml
      ->appendChild($element);
    $function = __FUNCTION__;
    drupal_alter('restws_response', $xml, $function, $this->formatName, $resourceController);
    return $xml
      ->saveXML();
  }

  /**
   * Overrides RestWSBaseFormat::queryResource().
   */
  public function queryResource($resourceController, $payload) {
    $xml = new DOMDocument('1.0', 'utf-8');
    $element = $xml
      ->createElement('list');
    $rest_controls = restws_meta_controls();
    $parameters = drupal_get_query_parameters();
    $properties = $resourceController
      ->propertyInfo();
    $split_parameters = $this
      ->splitParameters($properties, $parameters);
    $links = $this
      ->generateQueryURIs($resourceController, $parameters, $split_parameters['filters']);
    foreach ($links as $rel => $link) {
      $item = $xml
        ->createElement('link');
      $item
        ->setAttribute('rel', $rel);
      $item
        ->setAttribute('href', $link);
      $element
        ->appendChild($item);
    }
    $full = isset($split_parameters['meta_controls'][$rest_controls['full']]) ? $split_parameters['meta_controls'][$rest_controls['full']] : 1;
    $result = $resourceController
      ->query($split_parameters['filters'], $split_parameters['meta_controls']);
    if ($full === '0') {
      foreach ($result as $id) {
        $item = $xml
          ->createElement($resourceController
          ->resource());
        self::setXMLReference($item, $resourceController
          ->resource(), $id);
        $element
          ->appendChild($item);
      }
    }
    else {
      foreach ($result as $id) {
        $item = $xml
          ->createElement($resourceController
          ->resource());
        self::addToXML($xml, $item, $resourceController
          ->wrapper($id));
        $element
          ->appendChild($item);
      }
    }
    $xml
      ->appendChild($element);
    $function = __FUNCTION__;
    drupal_alter('restws_response', $xml, $function, $this->formatName, $resourceController);
    return $xml
      ->saveXML();
  }
  public function serialize($data) {

    // Return an empty XML document.
    $xml = new DOMDocument('1.0', 'utf-8');
    return $xml
      ->saveXML();
  }
  public function unserialize($properties, $data) {

    // Disable XML external entity expansion for security reasons.
    libxml_disable_entity_loader(TRUE);
    $xml = simplexml_load_string($data);
    return $this
      ->xmlToArray($properties, $xml);
  }

  /**
   * Turns the xml structure into an array of values.
   */
  public function xmlToArray($properties, SimpleXMLElement $xml, $listItemType = NULL) {
    foreach ($xml
      ->children() as $name => $element) {

      // Check if we are processing an entity, an item from a list or a list.
      if (isset($properties[$name]['type']) && (entity_property_list_extract_type($properties[$name]['type']) || entity_get_info($properties[$name]['type'])) || isset($listItemType)) {

        // If we are processing a list, then set the type of the list and save
        // the results into a a numeric array.
        if (isset($listItemType)) {
          $type = $listItemType;
          $result_pointer =& $result[];
        }
        else {
          $type = $properties[$name]['type'];
          $result_pointer =& $result[$name];
        }

        // Check if the type is a list.
        if (entity_property_list_extract_type($type)) {
          $result_pointer = $this
            ->xmlToArray($properties, $element, entity_property_list_extract_type($type));
        }
        else {
          $attributes = $element
            ->attributes();
          $values['id'] = (string) $attributes['id'];
          $values['resource'] = (string) $attributes['resource'];
          $values['uri'] = $this
            ->xmlToArray($properties, $element);
          $id = $this
            ->getResourceReferenceValue($type, $values);

          // If an id could be extracted, then a resource array was send.
          if ($id !== FALSE) {
            $result_pointer = $id;
          }
          else {

            // If no ID could be extracted, then save the inner text content of
            // the node, which is saved in the $values['uri'].
            $result_pointer = $values['uri'];
          }
        }
      }
      else {
        $result[$name] = $this
          ->xmlToArray($properties, $element);
      }
      foreach ($xml
        ->attributes() as $attribute_name => $attribute_value) {
        $result[$attribute_name] = $attribute_value;
      }
    }
    if (!isset($result)) {
      $result = ($string = (string) $xml) ? $string : NULL;
    }
    return $result;
  }

  /**
   * Adds the data of the given wrapper to the given XML element.
   */
  public static function addToXML(DOMDocument $doc, DOMNode $parent, $wrapper) {
    $filtered = restws_property_access_filter($wrapper);
    foreach ($filtered as $name => $property) {
      try {
        if ($property instanceof EntityDrupalWrapper) {

          // For referenced entities only return the URI.
          if ($id = $property
            ->getIdentifier()) {
            $element = $doc
              ->createElement(is_numeric($name) ? 'item' : $name);
            $parent
              ->appendChild($element);
            self::setXMLReference($element, $property
              ->type(), $id);
          }
        }
        elseif ($property instanceof EntityValueWrapper) {

          // Only primitive data types are allowed here. There might be complex
          // arrays/objects in EntityValueWrapper if no property information is
          // provided (example: the "data" property of commerce_price fields.
          if (is_scalar($property
            ->value())) {
            $escaped = $doc
              ->createTextNode($property
              ->value());
            $element = $doc
              ->createElement(is_numeric($name) ? 'item' : $name);
            $element
              ->appendChild($escaped);
            $parent
              ->appendChild($element);
          }
        }
        elseif ($property instanceof EntityListWrapper || $property instanceof EntityStructureWrapper) {
          $element = $doc
            ->createElement(is_numeric($name) ? 'item' : $name);
          $parent
            ->appendChild($element);
          self::addToXML($doc, $element, $property);
        }
      } catch (EntityMetadataWrapperException $e) {

        // A property causes problems - ignore that.
      }
    }
  }
  public static function setXMLReference(DOMElement $node, $resource, $id) {
    $node->nodeValue = restws_resource_uri($resource, $id);
    $node
      ->setAttribute('resource', $resource);
    $node
      ->setAttribute('id', $id);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
RestWSBaseFormat::$formatInfo protected property
RestWSBaseFormat::$formatName protected property
RestWSBaseFormat::deleteResource public function Deletes a resource. Overrides RestWSFormatInterface::deleteResource
RestWSBaseFormat::generateQueryURIs protected function Generates all navigation links for querying.
RestWSBaseFormat::getData public function Gets a simple PHP array using URI references for some wrapped data.
RestWSBaseFormat::getName public function Returns the short name of this format. Overrides RestWSFormatInterface::getName
RestWSBaseFormat::getPropertyValues protected function Transforms simple-array data values to valid entity property values.
RestWSBaseFormat::getResourceReference public function
RestWSBaseFormat::getResourceReferenceValue protected function Gets the resource reference value.
RestWSBaseFormat::mimeType public function Returns the mime type of this format, e.g. 'application/json' or 'application/xml'. Overrides RestWSFormatInterface::mimeType
RestWSBaseFormat::splitParameters protected function Splits a query parameter into two sub arrays containing the filters and meta controls.
RestWSBaseFormat::updateResource public function Updates a resource. Overrides RestWSFormatInterface::updateResource 1
RestWSBaseFormat::__construct public function 1
RestWSFormatXML::addToXML public static function Adds the data of the given wrapper to the given XML element.
RestWSFormatXML::createResource public function Creates a new resource. Overrides RestWSBaseFormat::createResource
RestWSFormatXML::queryResource public function Overrides RestWSBaseFormat::queryResource(). Overrides RestWSBaseFormat::queryResource
RestWSFormatXML::serialize public function
RestWSFormatXML::setXMLReference public static function
RestWSFormatXML::unserialize public function
RestWSFormatXML::viewResource public function Gets the representation of a resource. Overrides RestWSBaseFormat::viewResource
RestWSFormatXML::xmlToArray public function Turns the xml structure into an array of values.