3 namespace Drupal\migrate_plus;
5 use Drupal\Core\Plugin\PluginBase;
6 use Symfony\Component\DependencyInjection\ContainerInterface;
9 * Defines a base data parser implementation.
11 * @see \Drupal\migrate_plus\Annotation\DataParser
12 * @see \Drupal\migrate_plus\DataParserPluginInterface
13 * @see \Drupal\migrate_plus\DataParserPluginManager
16 abstract class DataParserPluginBase extends PluginBase implements DataParserPluginInterface {
19 * List of source urls.
26 * Index of the currently-open url.
33 * String indicating how to select an item's data from the source.
37 protected $itemSelector;
40 * Current item when iterating.
44 protected $currentItem = NULL;
47 * Value of the ID for the current item when iterating.
51 protected $currentId = NULL;
54 * The data retrieval client.
56 * @var \Drupal\migrate_plus\DataFetcherPluginInterface
58 protected $dataFetcher;
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'];
72 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
73 return new static($configuration, $plugin_id, $plugin_definition);
77 * Returns the initialized data fetcher plugin.
79 * @return \Drupal\migrate_plus\DataFetcherPluginInterface
80 * The data fetcher plugin.
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);
86 return $this->dataFetcherPlugin;
92 public function rewind() {
93 $this->activeUrl = NULL;
98 * Implementation of Iterator::next().
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.
108 // At this point, we have a valid open source url, try to fetch a row from
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();
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];
125 * Opens the specified URL.
131 * TRUE if the URL was successfully opened, FALSE otherwise.
133 abstract protected function openSourceUrl($url);
136 * Retrieves the next row of data from the open source URL, populating
139 abstract protected function fetchNextRow();
142 * Advances the data parser to the next source url.
145 * TRUE if a valid source URL was opened
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;
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)) {
160 if ($this->openSourceUrl($this->urls[$this->activeUrl])) {
161 // We have a valid source.
172 public function current() {
173 return $this->currentItem;
179 public function key() {
180 return $this->currentId;
186 public function valid() {
187 return !empty($this->currentItem);
193 public function count() {
195 foreach ($this as $item) {
202 * Return the selectors used to populate each configured field.
205 * Array of selectors, keyed by field name.
207 protected function fieldSelectors() {
209 foreach ($this->configuration['fields'] as $field_info) {
210 if (isset($field_info['selector'])) {
211 $fields[$field_info['name']] = $field_info['selector'];