60db902046d7c65622d61ef3f5be1cac5277badd
[yaffs-website] / web / modules / contrib / migrate_plus / src / Plugin / migrate_plus / data_parser / Soap.php
1 <?php
2
3 namespace Drupal\migrate_plus\Plugin\migrate_plus\data_parser;
4
5 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
6 use Drupal\migrate\MigrateException;
7 use Drupal\migrate_plus\DataParserPluginBase;
8
9 /**
10  * Obtain SOAP data for migration.
11  *
12  * @DataParser(
13  *   id = "soap",
14  *   title = @Translation("SOAP")
15  * )
16  */
17 class Soap extends DataParserPluginBase implements ContainerFactoryPluginInterface {
18
19   /**
20    * Iterator over the SOAP data.
21    *
22    * @var \Iterator
23    */
24   protected $iterator;
25
26   /**
27    * Method to call on the SOAP service.
28    *
29    * @var string
30    */
31   protected $function;
32
33   /**
34    * Parameters to pass to the SOAP service function.
35    *
36    * @var array
37    */
38   protected $parameters;
39
40   /**
41    * Form of the function response - 'xml', 'object', or 'array'.
42    *
43    * @var string
44    */
45   protected $responseType;
46
47   /**
48    * {@inheritdoc}
49    */
50   public function __construct(array $configuration, $plugin_id, $plugin_definition) {
51     parent::__construct($configuration, $plugin_id, $plugin_definition);
52     $this->function = $configuration['function'];
53     $this->parameters = $configuration['parameters'];
54     $this->responseType = $configuration['response_type'];
55   }
56
57   /**
58    * {@inheritdoc}
59    *
60    * @throws \SoapFault
61    *   If there's an error in a SOAP call.
62    * @throws \Drupal\migrate\MigrateException
63    *   If we can't resolve the SOAP function or its response property.
64    */
65   protected function openSourceUrl($url) {
66     // Will throw SoapFault if there's
67     $client = new \SoapClient($url);
68     // Determine the response property name.
69     $function_found = FALSE;
70     foreach ($client->__getFunctions() as $function_signature) {
71       // E.g., "GetWeatherResponse GetWeather(GetWeather $parameters)".
72       $response_type = strtok($function_signature, ' ');
73       $function_name = strtok('(');
74       if (strcasecmp($function_name, $this->function) === 0) {
75         $function_found = TRUE;
76         foreach ($client->__getTypes() as $type_info) {
77           // E.g., "struct GetWeatherResponse {\n string GetWeatherResult;\n}".
78           if (preg_match('|struct (.*?) {\s*[a-z]+ (.*?);|is', $type_info, $matches)) {
79             if ($matches[1] == $response_type) {
80               $response_property = $matches[2];
81             }
82           }
83         }
84         break;
85       }
86     }
87     if (!$function_found) {
88       throw new MigrateException("SOAP function {$this->function} not found.");
89     }
90     elseif (!isset($response_property)) {
91       throw new MigrateException("Response property not found for SOAP function {$this->function}.");
92     }
93     $response = $client->{$this->function}($this->parameters);
94     $response_value = $response->$response_property;
95     switch ($this->responseType) {
96       case 'xml':
97         $xml = simplexml_load_string($response_value);
98         $this->iterator = new \ArrayIterator($xml->xpath($this->itemSelector));
99         break;
100       case 'object':
101         $this->iterator = new \ArrayIterator($response_value->{$this->itemSelector});
102         break;
103       case 'array':
104         $this->iterator = new \ArrayIterator($response_value[$this->itemSelector]);
105         break;
106     }
107     return TRUE;
108   }
109
110   /**
111    * {@inheritdoc}
112    */
113   protected function fetchNextRow() {
114     $current = $this->iterator->current();
115     if ($current) {
116       foreach ($this->fieldSelectors() as $field_name => $selector) {
117         $this->currentItem[$field_name] = $current->$selector;
118       }
119       $this->iterator->next();
120     }
121   }
122
123 }