From c72763e2a30bed8291d1ef01492e8456b102e036 Mon Sep 17 00:00:00 2001 From: Denis Buybarov Date: Fri, 22 Feb 2019 18:47:57 +0200 Subject: [PATCH] feeds temporary-files-path 2912130-15-D8 --- config/install/feeds.settings.yml | 1 + config/schema/feeds.schema.yml | 8 ++ feeds.links.menu.yml | 4 + feeds.routing.yml | 10 +++ src/Feeds/Fetcher/HttpFetcher.php | 41 +++++++++- src/Form/FeedsSettingForm.php | 78 +++++++++++++++++++ .../Unit/Feeds/Fetcher/HttpFetcherTest.php | 11 ++- 7 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 config/install/feeds.settings.yml create mode 100644 src/Form/FeedsSettingForm.php diff --git a/config/install/feeds.settings.yml b/config/install/feeds.settings.yml new file mode 100644 index 0000000..44f92e1 --- /dev/null +++ b/config/install/feeds.settings.yml @@ -0,0 +1 @@ +feeds_temporary_dir: false diff --git a/config/schema/feeds.schema.yml b/config/schema/feeds.schema.yml index 4639abd..65a6374 100644 --- a/config/schema/feeds.schema.yml +++ b/config/schema/feeds.schema.yml @@ -163,3 +163,11 @@ feeds.processor.entity: feeds.processor.entity:*: type: feeds.processor.entity + +feeds.settings: + type: config_object + label: 'Feeds settings' + mapping: + feeds_temporary_dir: + type: boolean + label: 'Use public directory for temporary feed files.' diff --git a/feeds.links.menu.yml b/feeds.links.menu.yml index 5555b5b..8cc1e0a 100644 --- a/feeds.links.menu.yml +++ b/feeds.links.menu.yml @@ -11,3 +11,7 @@ entity.feeds_feed_type.add_form: route_name: entity.feeds_feed_type.add_form menu_name: admin parent: entity.feeds_feed_type.collection +feeds.admin_settings: + title: 'Feeds Settings' + parent: system.admin_config_services + route_name: feeds.admin_settings diff --git a/feeds.routing.yml b/feeds.routing.yml index 0ed3f9a..e3e5338 100644 --- a/feeds.routing.yml +++ b/feeds.routing.yml @@ -86,3 +86,13 @@ entity.feeds_feed_type.mapping: _title_callback: '\Drupal\feeds\Form\MappingForm::mappingTitle' requirements: _entity_access: 'feeds_feed_type.mapping' + +feeds.admin_settings: + path: '/admin/config/feeds_settings' + defaults: + _form: '\Drupal\feeds\Form\FeedsSettingForm' + _title: 'Feeds Settings' + requirements: + _permission: 'administer feeds' + options: + _admin_route: TRUE diff --git a/src/Feeds/Fetcher/HttpFetcher.php b/src/Feeds/Fetcher/HttpFetcher.php index 171917d..5c02e0c 100644 --- a/src/Feeds/Fetcher/HttpFetcher.php +++ b/src/Feeds/Fetcher/HttpFetcher.php @@ -3,8 +3,10 @@ namespace Drupal\feeds\Feeds\Fetcher; use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\File\FileSystemInterface; use Drupal\feeds\Exception\EmptyFeedException; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\feeds\FeedInterface; use Drupal\feeds\Plugin\Type\ClearableInterface; use Drupal\feeds\Plugin\Type\Fetcher\FetcherInterface; @@ -15,6 +17,7 @@ use Drupal\feeds\Utility\Feed; use GuzzleHttp\ClientInterface; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\RequestOptions; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Response; /** @@ -28,10 +31,17 @@ use Symfony\Component\HttpFoundation\Response; * "configuration" = "Drupal\feeds\Feeds\Fetcher\Form\HttpFetcherForm", * "feed" = "Drupal\feeds\Feeds\Fetcher\Form\HttpFetcherFeedForm", * }, - * arguments = {"@http_client", "@cache.feeds_download", "@file_system"} + * arguments = {"@http_client", "@cache.feeds_download", "@file_system", "@config.factory"} * ) */ -class HttpFetcher extends PluginBase implements ClearableInterface, FetcherInterface { +class HttpFetcher extends PluginBase implements ClearableInterface, FetcherInterface, ContainerFactoryPluginInterface { + + /** + * The config factory service. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; /** * The Guzzle client. @@ -69,19 +79,42 @@ class HttpFetcher extends PluginBase implements ClearableInterface, FetcherInter * The cache backend. * @param \Drupal\Core\File\FileSystemInterface $file_system * The Drupal file system helper. + * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory + * ConfigFactoryInterface object. */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, ClientInterface $client, CacheBackendInterface $cache, FileSystemInterface $file_system) { + public function __construct(array $configuration, $plugin_id, array $plugin_definition, ClientInterface $client, CacheBackendInterface $cache, FileSystemInterface $file_system, ConfigFactoryInterface $config_factory) { $this->client = $client; $this->cache = $cache; $this->fileSystem = $file_system; + $this->configFactory = $config_factory; parent::__construct($configuration, $plugin_id, $plugin_definition); } + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('config.factory') + ); + } + /** * {@inheritdoc} */ public function fetch(FeedInterface $feed, StateInterface $state) { - $sink = $this->fileSystem->tempnam('temporary://', 'feeds_http_fetcher'); + // Default destination. + $destination = 'temporary://'; + if ($this->configFactory->get('feeds.settings')->get('feeds_temporary_dir')) { + $destination = 'public://'; + // Remove all files by mask before imported files as not needed any more. + array_map('unlink', glob($this->fileSystem->realpath($destination) . "/feeds_http_fetcher*")); + } + + $sink = $this->fileSystem->tempnam($destination, 'feeds_http_fetcher'); $sink = $this->fileSystem->realpath($sink); $response = $this->get($feed->getSource(), $sink, $this->getCacheKey($feed)); diff --git a/src/Form/FeedsSettingForm.php b/src/Form/FeedsSettingForm.php new file mode 100644 index 0000000..f673eec --- /dev/null +++ b/src/Form/FeedsSettingForm.php @@ -0,0 +1,78 @@ +get('config.factory') + ); + } + + /** + * {@inheritdoc} + */ + protected function getEditableConfigNames() { + return [ + 'feeds.settings', + ]; + } + + /** + * {@inheritdoc} + */ + public function getFormId() { + return 'feeds.settings_form'; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $config = $this->config('feeds.settings')->get(); + $form['feeds_temporary_dir'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Use public directory for temporary feed files.'), + '#default_value' => $config['feeds_temporary_dir'], + '#description' => $this->t("Site @link settings.", ['@link' => Link::fromTextAndUrl('public file system path', Url::fromRoute('system.file_system_settings'))->toString()]), + ]; + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + parent::submitForm($form, $form_state); + $feeds_temporary_dir = $form_state->getValue('feeds_temporary_dir'); + + $config = $this->configFactory->getEditable('feeds.settings'); + $config->set('feeds_temporary_dir', $feeds_temporary_dir ? TRUE : FALSE); + $config->save(); + } + +} diff --git a/tests/src/Unit/Feeds/Fetcher/HttpFetcherTest.php b/tests/src/Unit/Feeds/Fetcher/HttpFetcherTest.php index 577f8cf..bc56a63 100644 --- a/tests/src/Unit/Feeds/Fetcher/HttpFetcherTest.php +++ b/tests/src/Unit/Feeds/Fetcher/HttpFetcherTest.php @@ -3,6 +3,7 @@ namespace Drupal\Tests\feeds\Unit\Feeds\Fetcher; use Drupal\Core\Cache\CacheBackendInterface; +use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\File\FileSystemInterface; use Drupal\Tests\feeds\Unit\FeedsUnitTestCase; use Drupal\feeds\FeedInterface; @@ -23,6 +24,13 @@ use Prophecy\Argument; */ class HttpFetcherTest extends FeedsUnitTestCase { + /** + * The config factory. + * + * @var \Drupal\Core\Config\ConfigFactoryInterface + */ + protected $configFactory; + /** * The feed entity. * @@ -55,6 +63,7 @@ class HttpFetcherTest extends FeedsUnitTestCase { $this->mockHandler = new MockHandler(); $client = new Client(['handler' => HandlerStack::create($this->mockHandler)]); $cache = $this->getMock(CacheBackendInterface::class); + $config = \Drupal::configFactory(); $file_system = $this->prophesize(FileSystemInterface::class); $file_system->tempnam(Argument::type('string'), Argument::type('string'))->will(function ($args) { @@ -67,7 +76,7 @@ class HttpFetcherTest extends FeedsUnitTestCase { return realpath($args[0]); }); - $this->fetcher = new HttpFetcher(['feed_type' => $feed_type], 'http', [], $client, $cache, $file_system->reveal()); + $this->fetcher = new HttpFetcher(['feed_type' => $feed_type], 'http', [], $client, $cache, $file_system->reveal(), $config); $this->fetcher->setStringTranslation($this->getStringTranslationStub()); $this->feed = $this->prophesize(FeedInterface::class); -- 2.17.1