3 namespace Drupal\migrate_plus\Plugin\migrate_plus\data_parser;
5 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
6 use Drupal\migrate\Exception\RequirementsException;
7 use Drupal\migrate\MigrateException;
8 use Drupal\migrate_plus\DataParserPluginBase;
11 * Obtain SOAP data for migration.
15 * title = @Translation("SOAP")
18 class Soap extends DataParserPluginBase implements ContainerFactoryPluginInterface {
21 * Iterator over the SOAP data.
28 * Method to call on the SOAP service.
35 * Parameters to pass to the SOAP service function.
39 protected $parameters;
42 * Form of the function response - 'xml', 'object', or 'array'.
46 protected $responseType;
51 * @throws \Drupal\migrate\Exception\RequirementsException
52 * If PHP SOAP extension is not installed.
54 public function __construct(array $configuration, $plugin_id, $plugin_definition) {
55 if (!class_exists('\SoapClient')) {
56 throw new RequirementsException('The PHP SOAP extension is not installed');
58 parent::__construct($configuration, $plugin_id, $plugin_definition);
59 $this->function = $configuration['function'];
60 $this->parameters = $configuration['parameters'];
61 $this->responseType = $configuration['response_type'];
68 * If there's an error in a SOAP call.
69 * @throws \Drupal\migrate\MigrateException
70 * If we can't resolve the SOAP function or its response property.
72 protected function openSourceUrl($url) {
73 // Will throw SoapFault if there's an error in a SOAP call.
74 $client = new \SoapClient($url);
75 // Determine the response property name.
76 $function_found = FALSE;
77 foreach ($client->__getFunctions() as $function_signature) {
78 // E.g., "GetWeatherResponse GetWeather(GetWeather $parameters)".
79 $response_type = strtok($function_signature, ' ');
80 $function_name = strtok('(');
81 if (strcasecmp($function_name, $this->function) === 0) {
82 $function_found = TRUE;
83 foreach ($client->__getTypes() as $type_info) {
84 // E.g., "struct GetWeatherResponse {\n string GetWeatherResult;\n}".
85 if (preg_match('|struct (.*?) {\s*[a-z]+ (.*?);|is', $type_info, $matches)) {
86 if ($matches[1] == $response_type) {
87 $response_property = $matches[2];
94 if (!$function_found) {
95 throw new MigrateException("SOAP function {$this->function} not found.");
97 elseif (!isset($response_property)) {
98 throw new MigrateException("Response property not found for SOAP function {$this->function}.");
100 $response = $client->{$this->function}($this->parameters);
101 $response_value = $response->$response_property;
102 switch ($this->responseType) {
104 $xml = simplexml_load_string($response_value);
105 $this->iterator = new \ArrayIterator($xml->xpath($this->itemSelector));
108 $this->iterator = new \ArrayIterator($response_value->{$this->itemSelector});
111 $this->iterator = new \ArrayIterator($response_value[$this->itemSelector]);
120 protected function fetchNextRow() {
121 $current = $this->iterator->current();
123 foreach ($this->fieldSelectors() as $field_name => $selector) {
124 $this->currentItem[$field_name] = $current->$selector;
126 $this->iterator->next();