You are here

class MigrateItemsXML in Migrate 6.2

Same name and namespace in other branches
  1. 7.2 plugins/sources/xml.inc \MigrateItemsXML

Implementation of MigrateItems, for providing a list of IDs and for retrieving a parsed XML document given an ID from this list.

Hierarchy

Expanded class hierarchy of MigrateItemsXML

File

plugins/sources/xml.inc, line 301
Support for migration from XML sources.

View source
class MigrateItemsXML extends MigrateItems {

  /**
   * A URL pointing to an XML document containing the ids and data.
   *
   * @var string
   */
  protected $xmlUrl;

  /**
   * Stores the loaded XML document.
   *
   * @var SimpleXMLElement
   */
  protected $xml = FALSE;

  /**
   * xpath identifying the element used for each item
   */
  protected $itemXpath;
  public function getItemXpath() {
    return $this->itemXpath;
  }

  /**
   * xpath identifying the subelement under itemXpath that holds the id for
   * each item.
   */
  protected $itemIDXpath;
  public function getIDXpath() {
    return $this->itemIDXpath;
  }
  public function __construct($xml_url, $item_xpath = 'item', $itemID_xpath = 'id') {
    parent::__construct();
    $this->xmlUrl = $xml_url;
    $this->itemXpath = $item_xpath;
    $this->itemIDXpath = $itemID_xpath;

    // Suppress errors during parsing, so we can pick them up after
    libxml_use_internal_errors(TRUE);
  }

  /**
   * Our public face is the URL we're getting items from
   *
   * @return string
   */
  public function __toString() {
    return 'url = ' . $this->xmlUrl . ' | item xpath = ' . $this->itemXpath . ' | item ID xpath = ' . $this->itemIDXpath;
  }

  /**
   * Load and return the xml from the defined xmlUrl.
   * @return SimpleXMLElement
   */
  public function &xml() {
    if (!$this->xml && !empty($this->xmlUrl)) {
      $this->xml = simplexml_load_file($this->xmlUrl);
      if (!$this->xml) {
        Migration::displayMessage(t('Loading of !xmlUrl failed:', array(
          '!xmlUrl' => $this->xmlUrl,
        )));
        foreach (libxml_get_errors() as $error) {
          Migration::displayMessage(self::parseLibXMLError($error));
        }
      }
    }
    return $this->xml;
  }

  /**
   * Parses a LibXMLError to a error message string.
   * @param LibXMLError $error
   * @return string
   */
  public static function parseLibXMLError(LibXMLError $error) {
    $error_code_name = 'Unknown Error';
    switch ($error->level) {
      case LIBXML_ERR_WARNING:
        $error_code_name = t('Warning');
        break;
      case LIBXML_ERR_ERROR:
        $error_code_name = t('Error');
        break;
      case LIBXML_ERR_FATAL:
        $error_code_name = t('Fatal Error');
        break;
    }
    return t("!libxmlerrorcodename !libxmlerrorcode: !libxmlerrormessage\n" . "Line: !libxmlerrorline\n" . "Column: !libxmlerrorcolumn\n" . "File: !libxmlerrorfile", array(
      '!libxmlerrorcodename' => $error_code_name,
      '!libxmlerrorcode' => $error->code,
      '!libxmlerrormessage' => trim($error->message),
      '!libxmlerrorline' => $error->line,
      '!libxmlerrorcolumn' => $error->column,
      '!libxmlerrorfile' => $error->file ? $error->file : NULL,
    ));
  }

  /**
   * Load the XML at the given URL, and return an array of the IDs found
   * within it.
   *
   * @return array
   */
  public function getIdList() {
    migrate_instrument_start("Retrieve {$this->xmlUrl}");
    $xml = $this
      ->xml();
    migrate_instrument_stop("Retrieve {$this->xmlUrl}");
    if ($xml !== FALSE) {
      return $this
        ->getIDsFromXML($xml);
    }
    return NULL;
  }

  /**
   * Given an XML object, parse out the IDs for processing and return them as
   * an array. The location of the IDs in the XML are based on the item xpath
   * and item ID xpath set in the constructor.
   *    eg, xpath = itemXpath . '/' . itemIDXpath
   * IDs are cached.  The list of IDs are returned from the cache except when
   * this is the first call (ie, cache is NULL) OR the refresh parameter is
   * TRUE.
   *
   * @param SimpleXMLElement $xml
   * @param boolean $refresh
   *
   * @return array
   */
  protected $cache_ids = NULL;
  protected function getIDsFromXML(SimpleXMLElement $xml, $refresh = FALSE) {
    if ($refresh !== TRUE && $this->cache_ids != NULL) {
      return $this->cache_ids;
    }
    $this->cache_ids = NULL;
    $result = $xml
      ->xpath($this->itemXpath);
    $ids = array();
    if ($result) {
      foreach ($result as $element) {
        $id = $this
          ->getItemID($element);
        if (!is_null($id)) {
          $ids[] = (string) $id;
        }
      }
    }
    $this->cache_ids = array_unique($ids);
    return $this->cache_ids;
  }

  /**
   * Return a count of all available IDs from the source listing.
   */
  public function computeCount() {
    $count = 0;
    $xml = $this
      ->xml();
    if ($xml !== FALSE) {
      $ids = $this
        ->getIDsFromXML($xml, TRUE);
      $count = count($ids);
    }
    return $count;
  }

  /**
   * Load the XML at the given URL, and return an array of the Items found
   * within it.
   *
   * @return array
   */
  public function getAllItems() {
    $xml = $this
      ->xml();
    if ($xml !== FALSE) {
      return $this
        ->getItemsFromXML($xml);
    }
    return NULL;
  }

  /**
   * Given an XML object, parse out the items for processing and return them as
   * an array. The location of the items in the XML are based on the item xpath
   * set in the constructor.  Items are cached.  The list of items are returned
   * from the cache except when this is the first call (ie, cache is NULL) OR
   * the refresh parameter is TRUE.
   *
   * Items are cached as an array of key=ID and value=stdclass object with
   * attribute xml containing the xml SimpleXMLElement object of the item.
   *
   * @param SimpleXMLElement $xml
   * @param boolean $refresh
   *
   * @return array
   */
  protected $cache_items = NULL;
  public function getItemsFromXML(SimpleXMLElement $xml, $refresh = FALSE) {
    if ($refresh !== FALSE && $this->cache_items != NULL) {
      return $this->cache_items;
    }
    $this->cache_items = NULL;
    $items = array();
    $result = $xml
      ->xpath($this->itemXpath);
    if ($result) {
      foreach ($result as $item_xml) {
        $id = $this
          ->getItemID($item_xml);
        $item = new stdclass();
        $item->xml = $item_xml;
        $items[$id] = $item;
      }
      $this->cache_items = $items;
      return $items;
    }
    else {
      return NULL;
    }
  }

  /**
   * Get the item ID from the itemXML based on itemIDXpath.
   *
   * @return string
   */
  protected function getItemID($itemXML) {
    return $this
      ->getElementValue($itemXML, $this->itemIDXpath);
  }

  /**
   * Get an element from the itemXML based on an xpath.
   *
   * @return string
   */
  protected function getElementValue($itemXML, $xpath) {
    $value = NULL;
    if ($itemXML) {
      $result = $itemXML
        ->xpath($xpath);
      if ($result) {
        $value = (string) $result[0];
      }
    }
    return $value;
  }

  /**
   * Implementors are expected to return an object representing a source item.
   * Items are cached as an array of key=ID and value=stdclass object with
   * attribute xml containing the xml SimpleXMLElement object of the item.
   *
   * @param mixed $id
   *
   * @return stdClass
   */
  public function getItem($id) {

    // Make sure we actually have an ID
    if (empty($id)) {
      return NULL;
    }
    $items = $this
      ->getAllItems();
    $item = $items[$id];
    if ($item) {
      return $item;
    }
    else {
      $migration = Migration::currentMigration();
      $message = t('Loading of item XML for ID !id failed:', array(
        '!id' => $id,
      ));
      foreach (libxml_get_errors() as $error) {
        $message .= "\n" . $error->message;
      }
      $migration
        ->getMap()
        ->saveMessage(array(
        $id,
      ), $message, MigrationBase::MESSAGE_ERROR);
      libxml_clear_errors();
      return NULL;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
MigrateItemsXML::$cache_ids protected property Given an XML object, parse out the IDs for processing and return them as an array. The location of the IDs in the XML are based on the item xpath and item ID xpath set in the constructor. eg, xpath = itemXpath . '/' . itemIDXpath IDs are…
MigrateItemsXML::$cache_items protected property Given an XML object, parse out the items for processing and return them as an array. The location of the items in the XML are based on the item xpath set in the constructor. Items are cached. The list of items are returned from the cache except when…
MigrateItemsXML::$itemIDXpath protected property xpath identifying the subelement under itemXpath that holds the id for each item.
MigrateItemsXML::$itemXpath protected property xpath identifying the element used for each item
MigrateItemsXML::$xml protected property Stores the loaded XML document.
MigrateItemsXML::$xmlUrl protected property A URL pointing to an XML document containing the ids and data.
MigrateItemsXML::computeCount public function Return a count of all available IDs from the source listing. Overrides MigrateItems::computeCount
MigrateItemsXML::getAllItems public function Load the XML at the given URL, and return an array of the Items found within it.
MigrateItemsXML::getElementValue protected function Get an element from the itemXML based on an xpath.
MigrateItemsXML::getIdList public function Load the XML at the given URL, and return an array of the IDs found within it. Overrides MigrateItems::getIdList
MigrateItemsXML::getIDsFromXML protected function
MigrateItemsXML::getIDXpath public function
MigrateItemsXML::getItem public function Implementors are expected to return an object representing a source item. Items are cached as an array of key=ID and value=stdclass object with attribute xml containing the xml SimpleXMLElement object of the item. Overrides MigrateItems::getItem
MigrateItemsXML::getItemID protected function Get the item ID from the itemXML based on itemIDXpath.
MigrateItemsXML::getItemsFromXML public function
MigrateItemsXML::getItemXpath public function
MigrateItemsXML::parseLibXMLError public static function Parses a LibXMLError to a error message string.
MigrateItemsXML::xml public function Load and return the xml from the defined xmlUrl.
MigrateItemsXML::__construct public function Overrides MigrateItems::__construct
MigrateItemsXML::__toString public function Our public face is the URL we're getting items from Overrides MigrateItems::__toString