7f8c694e2f5b7a6038ef08ebd96537e91b1c4999
[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\Exception\RequirementsException;
7 use Drupal\migrate\MigrateException;
8 use Drupal\migrate_plus\DataParserPluginBase;
9
10 /**
11  * Obtain SOAP data for migration.
12  *
13  * @DataParser(
14  *   id = "soap",
15  *   title = @Translation("SOAP")
16  * )
17  */
18 class Soap extends DataParserPluginBase implements ContainerFactoryPluginInterface {
19
20   /**
21    * Iterator over the SOAP data.
22    *
23    * @var \Iterator
24    */
25   protected $iterator;
26
27   /**
28    * Method to call on the SOAP service.
29    *
30    * @var string
31    */
32   protected $function;
33
34   /**
35    * Parameters to pass to the SOAP service function.
36    *
37    * @var array
38    */
39   protected $parameters;
40
41   /**
42    * Form of the function response - 'xml', 'object', or 'array'.
43    *
44    * @var string
45    */
46   protected $responseType;
47
48   /**
49    * {@inheritdoc}
50    *
51    * @throws \Drupal\migrate\Exception\RequirementsException
52    *   If PHP SOAP extension is not installed.
53    */
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');
57     }
58     parent::__construct($configuration, $plugin_id, $plugin_definition);
59     $this->function = $configuration['function'];
60     $this->parameters = $configuration['parameters'];
61     $this->responseType = $configuration['response_type'];
62   }
63
64   /**
65    * {@inheritdoc}
66    *
67    * @throws \SoapFault
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.
71    */
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];
88             }
89           }
90         }
91         break;
92       }
93     }
94     if (!$function_found) {
95       throw new MigrateException("SOAP function {$this->function} not found.");
96     }
97     elseif (!isset($response_property)) {
98       throw new MigrateException("Response property not found for SOAP function {$this->function}.");
99     }
100     $response = $client->{$this->function}($this->parameters);
101     $response_value = $response->$response_property;
102     switch ($this->responseType) {
103       case 'xml':
104         $xml = simplexml_load_string($response_value);
105         $this->iterator = new \ArrayIterator($xml->xpath($this->itemSelector));
106         break;
107       case 'object':
108         $this->iterator = new \ArrayIterator($response_value->{$this->itemSelector});
109         break;
110       case 'array':
111         $this->iterator = new \ArrayIterator($response_value[$this->itemSelector]);
112         break;
113     }
114     return TRUE;
115   }
116
117   /**
118    * {@inheritdoc}
119    */
120   protected function fetchNextRow() {
121     $current = $this->iterator->current();
122     if ($current) {
123       foreach ($this->fieldSelectors() as $field_name => $selector) {
124         $this->currentItem[$field_name] = $current->$selector;
125       }
126       $this->iterator->next();
127     }
128   }
129
130 }