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 from the open source URL, populating
142 abstract protected function fetchNextRow();
145 * Advances the data parser to the next source url.
148 * TRUE if a valid source URL was opened
150 protected function nextSource() {
151 while ($this->activeUrl === NULL || (count($this->urls) - 1) > $this->activeUrl) {
152 if (is_null($this->activeUrl)) {
153 $this->activeUrl = 0;
156 // Increment the activeUrl so we try to load the next source.
157 $this->activeUrl = $this->activeUrl + 1;
158 if ($this->activeUrl >= count($this->urls)) {
163 if ($this->openSourceUrl($this->urls[$this->activeUrl])) {
164 // We have a valid source.
175 public function current() {
176 return $this->currentItem;
182 public function key() {
183 return $this->currentId;
189 public function valid() {
190 return !empty($this->currentItem);
196 public function count() {
198 foreach ($this as $item) {
205 * Return the selectors used to populate each configured field.
208 * Array of selectors, keyed by field name.
210 protected function fieldSelectors() {
212 foreach ($this->configuration['fields'] as $field_info) {
213 if (isset($field_info['selector'])) {
214 $fields[$field_info['name']] = $field_info['selector'];