Version 1
[yaffs-website] / web / modules / contrib / migrate_plus / src / DataParserPluginBase.php
1 <?php
2
3 namespace Drupal\migrate_plus;
4
5 use Drupal\Core\Plugin\PluginBase;
6 use Symfony\Component\DependencyInjection\ContainerInterface;
7
8 /**
9  * Defines a base data parser implementation.
10  *
11  * @see \Drupal\migrate_plus\Annotation\DataParser
12  * @see \Drupal\migrate_plus\DataParserPluginInterface
13  * @see \Drupal\migrate_plus\DataParserPluginManager
14  * @see plugin_api
15  */
16 abstract class DataParserPluginBase extends PluginBase implements DataParserPluginInterface {
17
18   /**
19    * List of source urls.
20    *
21    * @var string[]
22    */
23   protected $urls;
24
25   /**
26    * Index of the currently-open url.
27    *
28    * @var int
29    */
30   protected $activeUrl;
31
32   /**
33    * String indicating how to select an item's data from the source.
34    *
35    * @var string
36    */
37   protected $itemSelector;
38
39   /**
40    * Current item when iterating.
41    *
42    * @var mixed
43    */
44   protected $currentItem = NULL;
45
46   /**
47    * Value of the ID for the current item when iterating.
48    *
49    * @var string
50    */
51   protected $currentId = NULL;
52
53   /**
54    * The data retrieval client.
55    *
56    * @var \Drupal\migrate_plus\DataFetcherPluginInterface
57    */
58   protected $dataFetcher;
59
60   /**
61    * {@inheritdoc}
62    */
63   public function __construct(array $configuration, $plugin_id, $plugin_definition) {
64     parent::__construct($configuration, $plugin_id, $plugin_definition);
65     $this->urls = $configuration['urls'];
66     $this->itemSelector = $configuration['item_selector'];
67   }
68
69   /**
70    * {@inheritdoc}
71    */
72   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
73     return new static($configuration, $plugin_id, $plugin_definition);
74   }
75
76   /**
77    * Returns the initialized data fetcher plugin.
78    *
79    * @return \Drupal\migrate_plus\DataFetcherPluginInterface
80    *   The data fetcher plugin.
81    */
82   public function getDataFetcherPlugin() {
83     if (!isset($this->dataFetcherPlugin)) {
84       $this->dataFetcherPlugin = \Drupal::service('plugin.manager.migrate_plus.data_fetcher')->createInstance($this->configuration['data_fetcher_plugin'], $this->configuration);
85     }
86     return $this->dataFetcherPlugin;
87   }
88
89   /**
90    * {@inheritdoc}
91    */
92   public function rewind() {
93     $this->activeUrl = NULL;
94     $this->next();
95   }
96
97   /**
98    * Implementation of Iterator::next().
99    */
100   public function next() {
101     $this->currentItem = $this->currentId = NULL;
102     if (is_null($this->activeUrl)) {
103       if (!$this->nextSource()) {
104         // No data to import.
105         return;
106       }
107     }
108     // At this point, we have a valid open source url, try to fetch a row from
109     // it.
110     $this->fetchNextRow();
111     // If there was no valid row there, try the next url (if any).
112     if (is_null($this->currentItem)) {
113       if ($this->nextSource()) {
114         $this->fetchNextRow();
115       }
116     }
117     if ($this->valid()) {
118       foreach ($this->configuration['ids'] as $id_field_name => $id_info) {
119         $this->currentId[$id_field_name] = $this->currentItem[$id_field_name];
120       }
121     }
122   }
123
124   /**
125    * Opens the specified URL.
126    *
127    * @param $url
128    *   URL to open.
129    *
130    * @return bool
131    *   TRUE if the URL was successfully opened, FALSE otherwise.
132    */
133   abstract protected function openSourceUrl($url);
134
135   /**
136    * Retrieves the next row of data from the open source URL, populating
137    * currentItem.
138    */
139   abstract protected function fetchNextRow();
140
141   /**
142    * Advances the data parser to the next source url.
143    *
144    * @return bool
145    *   TRUE if a valid source URL was opened
146    */
147   protected function nextSource() {
148     while ($this->activeUrl === NULL || (count($this->urls) - 1) > $this->activeUrl) {
149       if (is_null($this->activeUrl)) {
150         $this->activeUrl = 0;
151       }
152       else {
153         // Increment the activeUrl so we try to load the next source.
154         $this->activeUrl = $this->activeUrl + 1;
155         if ($this->activeUrl >= count($this->urls)) {
156           return FALSE;
157         }
158       }
159
160       if ($this->openSourceUrl($this->urls[$this->activeUrl])) {
161         // We have a valid source.
162         return TRUE;
163       }
164     }
165
166     return FALSE;
167   }
168
169   /**
170    * {@inheritdoc}
171    */
172   public function current() {
173     return $this->currentItem;
174   }
175
176   /**
177    * {@inheritdoc}
178    */
179   public function key() {
180     return $this->currentId;
181   }
182
183   /**
184    * {@inheritdoc}
185    */
186   public function valid() {
187     return !empty($this->currentItem);
188   }
189
190   /**
191    * {@inheritdoc}
192    */
193   public function count() {
194     $count = 0;
195     foreach ($this as $item) {
196       $count++;
197     }
198     return $count;
199   }
200
201   /**
202    * Return the selectors used to populate each configured field.
203    *
204    * @return string[]
205    *   Array of selectors, keyed by field name.
206    */
207   protected function fieldSelectors() {
208     $fields = [];
209     foreach ($this->configuration['fields'] as $field_info) {
210       if (isset($field_info['selector'])) {
211         $fields[$field_info['name']] = $field_info['selector'];
212       }
213     }
214     return $fields;
215   }
216
217 }