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 while ($this->nextSource()) {
114 $this->fetchNextRow();
115 if ($this->valid()) {
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];
128 * Opens the specified URL.
134 * TRUE if the URL was successfully opened, FALSE otherwise.
136 abstract protected function openSourceUrl($url);
139 * Retrieves the next row of data. populating currentItem.
141 * Retrieves from the open source URL.
143 abstract protected function fetchNextRow();
146 * Advances the data parser to the next source url.
149 * TRUE if a valid source URL was opened
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;
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)) {
164 if ($this->openSourceUrl($this->urls[$this->activeUrl])) {
165 // We have a valid source.
176 public function current() {
177 return $this->currentItem;
183 public function key() {
184 return $this->currentId;
190 public function valid() {
191 return !empty($this->currentItem);
197 public function count() {
199 foreach ($this as $item) {
206 * Return the selectors used to populate each configured field.
209 * Array of selectors, keyed by field name.
211 protected function fieldSelectors() {
213 foreach ($this->configuration['fields'] as $field_info) {
214 if (isset($field_info['selector'])) {
215 $fields[$field_info['name']] = $field_info['selector'];