"Fossies" - the Fresh Open Source Software Archive

Member "drupal-8.9.9/core/modules/aggregator/src/Plugin/aggregator/processor/DefaultProcessor.php" (18 Nov 2020, 10031 Bytes) of package /linux/www/drupal-8.9.9.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "DefaultProcessor.php" see the Fossies "Dox" file reference documentation.

    1 <?php
    2 
    3 namespace Drupal\aggregator\Plugin\aggregator\processor;
    4 
    5 use Drupal\aggregator\Entity\Item;
    6 use Drupal\aggregator\FeedInterface;
    7 use Drupal\aggregator\FeedStorageInterface;
    8 use Drupal\aggregator\ItemStorageInterface;
    9 use Drupal\aggregator\Plugin\AggregatorPluginSettingsBase;
   10 use Drupal\aggregator\Plugin\ProcessorInterface;
   11 use Drupal\Component\Utility\Unicode;
   12 use Drupal\Core\Config\ConfigFactoryInterface;
   13 use Drupal\Core\Datetime\DateFormatterInterface;
   14 use Drupal\Core\Form\ConfigFormBaseTrait;
   15 use Drupal\Core\Form\FormStateInterface;
   16 use Drupal\Core\Messenger\MessengerInterface;
   17 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
   18 use Drupal\Core\Url;
   19 use Symfony\Component\DependencyInjection\ContainerInterface;
   20 
   21 /**
   22  * Defines a default processor implementation.
   23  *
   24  * Creates lightweight records from feed items.
   25  *
   26  * @AggregatorProcessor(
   27  *   id = "aggregator",
   28  *   title = @Translation("Default processor"),
   29  *   description = @Translation("Creates lightweight records from feed items.")
   30  * )
   31  */
   32 class DefaultProcessor extends AggregatorPluginSettingsBase implements ProcessorInterface, ContainerFactoryPluginInterface {
   33 
   34   use ConfigFormBaseTrait;
   35 
   36   /**
   37    * Contains the configuration object factory.
   38    *
   39    * @var \Drupal\Core\Config\ConfigFactoryInterface
   40    */
   41   protected $configFactory;
   42 
   43   /**
   44    * The entity storage for items.
   45    *
   46    * @var \Drupal\aggregator\ItemStorageInterface
   47    */
   48   protected $itemStorage;
   49 
   50   /**
   51    * The date formatter service.
   52    *
   53    * @var \Drupal\Core\Datetime\DateFormatterInterface
   54    */
   55   protected $dateFormatter;
   56 
   57   /**
   58    * The messenger.
   59    *
   60    * @var \Drupal\Core\Messenger\MessengerInterface
   61    */
   62   protected $messenger;
   63 
   64   /**
   65    * Constructs a DefaultProcessor object.
   66    *
   67    * @param array $configuration
   68    *   A configuration array containing information about the plugin instance.
   69    * @param string $plugin_id
   70    *   The plugin_id for the plugin instance.
   71    * @param mixed $plugin_definition
   72    *   The plugin implementation definition.
   73    * @param \Drupal\Core\Config\ConfigFactoryInterface $config
   74    *   The configuration factory object.
   75    * @param \Drupal\aggregator\ItemStorageInterface $item_storage
   76    *   The entity storage for feed items.
   77    * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   78    *   The date formatter service.
   79    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   80    *   The messenger.
   81    */
   82   public function __construct(array $configuration, $plugin_id, $plugin_definition, ConfigFactoryInterface $config, ItemStorageInterface $item_storage, DateFormatterInterface $date_formatter, MessengerInterface $messenger) {
   83     $this->configFactory = $config;
   84     $this->itemStorage = $item_storage;
   85     $this->dateFormatter = $date_formatter;
   86     $this->messenger = $messenger;
   87     // @todo Refactor aggregator plugins to ConfigEntity so merging
   88     //   the configuration here is not needed.
   89     parent::__construct($configuration + $this->getConfiguration(), $plugin_id, $plugin_definition);
   90   }
   91 
   92   /**
   93    * {@inheritdoc}
   94    */
   95   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
   96     return new static(
   97       $configuration,
   98       $plugin_id,
   99       $plugin_definition,
  100       $container->get('config.factory'),
  101       $container->get('entity_type.manager')->getStorage('aggregator_item'),
  102       $container->get('date.formatter'),
  103       $container->get('messenger')
  104     );
  105   }
  106 
  107   /**
  108    * {@inheritdoc}
  109    */
  110   protected function getEditableConfigNames() {
  111     return ['aggregator.settings'];
  112   }
  113 
  114   /**
  115    * {@inheritdoc}
  116    */
  117   public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
  118     $config = $this->config('aggregator.settings');
  119     $processors = $config->get('processors');
  120     $info = $this->getPluginDefinition();
  121     $counts = [3, 5, 10, 15, 20, 25];
  122     $items = array_map(function ($count) {
  123       return $this->formatPlural($count, '1 item', '@count items');
  124     }, array_combine($counts, $counts));
  125     $intervals = [3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800];
  126     $period = array_map([$this->dateFormatter, 'formatInterval'], array_combine($intervals, $intervals));
  127     $period[FeedStorageInterface::CLEAR_NEVER] = t('Never');
  128 
  129     $form['processors'][$info['id']] = [];
  130     // Only wrap into details if there is a basic configuration.
  131     if (isset($form['basic_conf'])) {
  132       $form['processors'][$info['id']] = [
  133         '#type' => 'details',
  134         '#title' => t('Default processor settings'),
  135         '#description' => $info['description'],
  136         '#open' => in_array($info['id'], $processors),
  137       ];
  138     }
  139 
  140     $form['processors'][$info['id']]['aggregator_summary_items'] = [
  141       '#type' => 'select',
  142       '#title' => t('Number of items shown in listing pages'),
  143       '#default_value' => $config->get('source.list_max'),
  144       '#empty_value' => 0,
  145       '#options' => $items,
  146     ];
  147 
  148     $form['processors'][$info['id']]['aggregator_clear'] = [
  149       '#type' => 'select',
  150       '#title' => t('Discard items older than'),
  151       '#default_value' => $config->get('items.expire'),
  152       '#options' => $period,
  153       '#description' => t('Requires a correctly configured <a href=":cron">cron maintenance task</a>.', [':cron' => Url::fromRoute('system.status')->toString()]),
  154     ];
  155 
  156     $lengths = [0, 200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000];
  157     $options = array_map(function ($length) {
  158       return ($length == 0) ? t('Unlimited') : $this->formatPlural($length, '1 character', '@count characters');
  159     }, array_combine($lengths, $lengths));
  160 
  161     $form['processors'][$info['id']]['aggregator_teaser_length'] = [
  162       '#type' => 'select',
  163       '#title' => t('Length of trimmed description'),
  164       '#default_value' => $config->get('items.teaser_length'),
  165       '#options' => $options,
  166       '#description' => t('The maximum number of characters used in the trimmed version of content.'),
  167     ];
  168     return $form;
  169   }
  170 
  171   /**
  172    * {@inheritdoc}
  173    */
  174   public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
  175     $this->configuration['items']['expire'] = $form_state->getValue('aggregator_clear');
  176     $this->configuration['items']['teaser_length'] = $form_state->getValue('aggregator_teaser_length');
  177     $this->configuration['source']['list_max'] = $form_state->getValue('aggregator_summary_items');
  178     // @todo Refactor aggregator plugins to ConfigEntity so this is not needed.
  179     $this->setConfiguration($this->configuration);
  180   }
  181 
  182   /**
  183    * {@inheritdoc}
  184    */
  185   public function process(FeedInterface $feed) {
  186     if (!is_array($feed->items)) {
  187       return;
  188     }
  189     foreach ($feed->items as $item) {
  190       // @todo: The default entity view builder always returns an empty
  191       //   array, which is ignored in aggregator_save_item() currently. Should
  192       //   probably be fixed.
  193       if (empty($item['title'])) {
  194         continue;
  195       }
  196 
  197       // Save this item. Try to avoid duplicate entries as much as possible. If
  198       // we find a duplicate entry, we resolve it and pass along its ID is such
  199       // that we can update it if needed.
  200       if (!empty($item['guid'])) {
  201         $values = ['fid' => $feed->id(), 'guid' => $item['guid']];
  202       }
  203       elseif ($item['link'] && $item['link'] != $feed->link && $item['link'] != $feed->url) {
  204         $values = ['fid' => $feed->id(), 'link' => $item['link']];
  205       }
  206       else {
  207         $values = ['fid' => $feed->id(), 'title' => $item['title']];
  208       }
  209 
  210       // Try to load an existing entry.
  211       if ($entry = $this->itemStorage->loadByProperties($values)) {
  212         $entry = reset($entry);
  213       }
  214       else {
  215         $entry = Item::create(['langcode' => $feed->language()->getId()]);
  216       }
  217       if ($item['timestamp']) {
  218         $entry->setPostedTime($item['timestamp']);
  219       }
  220 
  221       // Make sure the item title and author fit in the 255 varchar column.
  222       $entry->setTitle(Unicode::truncate($item['title'], 255, TRUE, TRUE));
  223       $entry->setAuthor(Unicode::truncate($item['author'], 255, TRUE, TRUE));
  224 
  225       $entry->setFeedId($feed->id());
  226       $entry->setLink($item['link']);
  227       $entry->setGuid($item['guid']);
  228 
  229       $description = '';
  230       if (!empty($item['description'])) {
  231         $description = $item['description'];
  232       }
  233       $entry->setDescription($description);
  234 
  235       $entry->save();
  236     }
  237   }
  238 
  239   /**
  240    * {@inheritdoc}
  241    */
  242   public function delete(FeedInterface $feed) {
  243     if ($items = $this->itemStorage->loadByFeed($feed->id())) {
  244       $this->itemStorage->delete($items);
  245     }
  246     // @todo This should be moved out to caller with a different message maybe.
  247     $this->messenger->addStatus(t('The news items from %site have been deleted.', ['%site' => $feed->label()]));
  248   }
  249 
  250   /**
  251    * Implements \Drupal\aggregator\Plugin\ProcessorInterface::postProcess().
  252    *
  253    * Expires items from a feed depending on expiration settings.
  254    */
  255   public function postProcess(FeedInterface $feed) {
  256     $aggregator_clear = $this->configuration['items']['expire'];
  257 
  258     if ($aggregator_clear != FeedStorageInterface::CLEAR_NEVER) {
  259       // Delete all items that are older than flush item timer.
  260       $age = REQUEST_TIME - $aggregator_clear;
  261       $result = $this->itemStorage->getQuery()
  262         ->condition('fid', $feed->id())
  263         ->condition('timestamp', $age, '<')
  264         ->execute();
  265       if ($result) {
  266         $entities = $this->itemStorage->loadMultiple($result);
  267         $this->itemStorage->delete($entities);
  268       }
  269     }
  270   }
  271 
  272   /**
  273    * {@inheritdoc}
  274    */
  275   public function getConfiguration() {
  276     return $this->configFactory->get('aggregator.settings')->get();
  277   }
  278 
  279   /**
  280    * {@inheritdoc}
  281    */
  282   public function setConfiguration(array $configuration) {
  283     $config = $this->config('aggregator.settings');
  284     foreach ($configuration as $key => $value) {
  285       $config->set($key, $value);
  286     }
  287     $config->save();
  288   }
  289 
  290 }