c74c6c53acbefb03f4812335145229d00fc3cead
[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       while ($this->nextSource()) {
114         $this->fetchNextRow();
115         if ($this->valid()) {
116           break;
117         }
118       }
119     }
120     if ($this->valid()) {
121       foreach ($this->configuration['ids'] as $id_field_name => $id_info) {
122         $this->currentId[$id_field_name] = $this->currentItem[$id_field_name];
123       }
124     }
125   }
126
127   /**
128    * Opens the specified URL.
129    *
130    * @param string $url
131    *   URL to open.
132    *
133    * @return bool
134    *   TRUE if the URL was successfully opened, FALSE otherwise.
135    */
136   abstract protected function openSourceUrl($url);
137
138   /**
139    * Retrieves the next row of data. populating currentItem.
140    *
141    * Retrieves from the open source URL.
142    */
143   abstract protected function fetchNextRow();
144
145   /**
146    * Advances the data parser to the next source url.
147    *
148    * @return bool
149    *   TRUE if a valid source URL was opened
150    */
151   protected function nextSource() {
152     while ($this->activeUrl === NULL || (count($this->urls) - 1) > $this->activeUrl) {
153       if (is_null($this->activeUrl)) {
154         $this->activeUrl = 0;
155       }
156       else {
157         // Increment the activeUrl so we try to load the next source.
158         $this->activeUrl = $this->activeUrl + 1;
159         if ($this->activeUrl >= count($this->urls)) {
160           return FALSE;
161         }
162       }
163
164       if ($this->openSourceUrl($this->urls[$this->activeUrl])) {
165         // We have a valid source.
166         return TRUE;
167       }
168     }
169
170     return FALSE;
171   }
172
173   /**
174    * {@inheritdoc}
175    */
176   public function current() {
177     return $this->currentItem;
178   }
179
180   /**
181    * {@inheritdoc}
182    */
183   public function key() {
184     return $this->currentId;
185   }
186
187   /**
188    * {@inheritdoc}
189    */
190   public function valid() {
191     return !empty($this->currentItem);
192   }
193
194   /**
195    * {@inheritdoc}
196    */
197   public function count() {
198     $count = 0;
199     foreach ($this as $item) {
200       $count++;
201     }
202     return $count;
203   }
204
205   /**
206    * Return the selectors used to populate each configured field.
207    *
208    * @return string[]
209    *   Array of selectors, keyed by field name.
210    */
211   protected function fieldSelectors() {
212     $fields = [];
213     foreach ($this->configuration['fields'] as $field_info) {
214       if (isset($field_info['selector'])) {
215         $fields[$field_info['name']] = $field_info['selector'];
216       }
217     }
218     return $fields;
219   }
220
221 }