Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 97 additions & 25 deletions src/Plugin/Block/LeafletjsBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\file\Entity\File;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\file\FileUsage\FileUsageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;

/**
* Provides a 'LeafletJS' Block.
Expand All @@ -16,7 +20,84 @@
* category = @Translation("Custom"),
* )
*/
class LeafletjsBlock extends BlockBase {
class LeafletjsBlock extends BlockBase implements ContainerFactoryPluginInterface {

/**
* The messenger service.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;

/**
* The file system.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;

/**
* The file usage.
*
* @var \Drupal\file\FileUsage\FileUsageInterface
*/
protected $fileUsage;

/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;

/**
* Constructs a LeafletJS object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger service.
* @param \Drupal\Core\File\FileSystemInterface $fileSystem
* The file system.
* @param \Drupal\file\FileUsage\FileUsageInterface $fileUsage
* The file usage.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
MessengerInterface $messenger,
FileSystemInterface $fileSystem,
FileUsageInterface $fileUsage,
EntityTypeManagerInterface $entityTypeManager,
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->messenger = $messenger;
$this->fileSystem = $fileSystem;
$this->fileUsage = $fileUsage;
$this->entityTypeManager = $entityTypeManager;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('messenger'),
$container->get('file_system'),
$container->get('file.usage'),
$container->get('entity_type.manager')
);
}

/**
* {@inheritdoc}
Expand Down Expand Up @@ -122,8 +203,7 @@ public function blockSubmit($form, FormStateInterface $form_state) {
// Handle file upload and processing.
$custom_file = $form_state->getValue('custom_location_file');
if (!empty($custom_file[0])) {
// phpcs:ignore -- File::load calls should be avoided in classes, use dependency injection instead
$file = File::load($custom_file[0]);
$file = $this->entityTypeManager->getStorage('file')->load($custom_file[0]);
if ($file) {
$file_uri = $file->getFileUri();
$file_contents = file_get_contents($file_uri);
Expand All @@ -142,8 +222,7 @@ public function blockSubmit($form, FormStateInterface $form_state) {
// GeoJSON.
$geojson_data = json_decode($file_contents, TRUE);
if (!$geojson_data) {
// phpcs:ignore -- \Drupal calls should be avoided in classes, use dependency injection instead
\Drupal::messenger()->addError($this->t('Invalid JSON file'));
$this->messenger()->addError($this->t('Invalid JSON file'));
return;
}
$address_points = $geojson_data;
Expand Down Expand Up @@ -181,15 +260,13 @@ public function blockSubmit($form, FormStateInterface $form_state) {
}

if (empty($address_points)) {
//phpcs:ignore -- \Drupal calls should be avoided in classes, use dependency injection instead
\Drupal::messenger()->addError($this->t('No valid locations in CSV'));
$this->messenger()->addError($this->t('No valid locations in CSV'));
return;
}
}
else {
// Invalid file type.
//phpcs:ignore -- \Drupal calls should be avoided in classes, use dependency injection instead
\Drupal::messenger()->addError($this->t('File must be .csv, .json, or .geojson'));
$this->messenger()->addError($this->t('File must be .csv, .json, or .geojson'));
return;
}

Expand All @@ -198,10 +275,9 @@ public function blockSubmit($form, FormStateInterface $form_state) {
? 'var geoJsonData = ' . json_encode($address_points)
: 'var addressPoints = ' . json_encode($address_points);

// phpcs:disable
// Save processed data to .js file in public://leafletjs/ directory.
$directory = 'public://leafletjs';
\Drupal::service('file_system')->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);
$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY);

// Filename.
$filename = 'addressPoints_' . time() . '.js';
Expand All @@ -210,7 +286,7 @@ public function blockSubmit($form, FormStateInterface $form_state) {
file_put_contents($file_uri, $file_content);

// Create Drupal managed file entity for js file.
$txt_file = File::create([
$txt_file = $this->entityTypeManager->getStorage('file')->create([
'uri' => $file_uri,
'status' => 1,
]);
Expand All @@ -219,9 +295,9 @@ public function blockSubmit($form, FormStateInterface $form_state) {

// Delete previous location data file if one exists.
if (!empty($this->configuration['custom_location_file']) && $this->configuration['custom_location_file'] != $custom_file[0]) {
$old_file = File::load($this->configuration['custom_location_file']);
$old_file = $this->entityTypeManager->getStorage('file')->load($this->configuration['custom_location_file']);
if ($old_file) {
\Drupal::service('file.usage')->delete($old_file, 'leafletjs', 'block', $this->getPluginId());
$this->fileUsage->delete($old_file, 'leafletjs', 'block', $this->getPluginId());
$old_file->delete();
}
}
Expand All @@ -233,30 +309,27 @@ public function blockSubmit($form, FormStateInterface $form_state) {
$this->configuration['custom_location_file'] = $txt_file->id();

// Track file usage.
\Drupal::service('file.usage')->add($txt_file, 'leafletjs', 'block', $this->getPluginId());
$this->fileUsage->add($txt_file, 'leafletjs', 'block', $this->getPluginId());

// Success message.
$count = in_array($extension, ['json', 'geojson']) ? count($address_points['features'] ?? []) : count($address_points);
\Drupal::messenger()->addStatus($this->t('Successfully processed @count locations', ['@count' => $count]));
$this->messenger()->addStatus($this->t('Successfully processed @count locations', ['@count' => $count]));

// phpcs:enable
}
}
}
}
else {
// phpcs:disable
// File was removed and no new file.
if (!empty($this->configuration['custom_location_file'])) {
$old_file = File::load($this->configuration['custom_location_file']);
$old_file = $this->entityTypeManager->getStorage('file')->load($this->configuration['custom_location_file']);
if ($old_file) {
\Drupal::service('file.usage')->delete($old_file, 'leafletjs', 'block', $this->getPluginId());
$this->fileUsage->delete($old_file, 'leafletjs', 'block', $this->getPluginId());
$old_file->delete();
\Drupal::messenger()->addStatus($this->t('Location data file has been removed'));
$this->messenger()->addStatus($this->t('Location data file has been removed'));
}
}
$this->configuration['custom_location_file'] = NULL;
// phpcs:enable
}
}

Expand Down Expand Up @@ -286,8 +359,7 @@ public function build() {

// Load processed location data file if configured.
if (!empty($this->configuration['custom_location_file'])) {
// phpcs:ignore -- File::load calls should be avoided in classes, use dependency injection instead
$file = File::load($this->configuration['custom_location_file']);
$file = $this->entityTypeManager->getStorage('file')->load($this->configuration['custom_location_file']);
if ($file) {
$file_url = $file->createFileUrl();

Expand Down
57 changes: 57 additions & 0 deletions tests/src/Functional/LoadTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Drupal\Tests\leafletjs\Functional;

use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;

/**
* Simple test to ensure that main page loads with module enabled.
*
* @group leafletjs
*/
#[RunTestsInSeparateProcesses]
class LoadTest extends BrowserTestBase {

/**
* Modules to enable.
*
* @var array
*/
protected static $modules = ['leafletjs'];

/**
* The theme to install as the default for testing.
*
* Defaults to the install profile's default theme, if it specifies any.
*
* @var string
*/
protected $defaultTheme = 'stark';

/**
* A user with permission to administer site configuration.
*
* @var \Drupal\user\UserInterface
*/
protected $user;

/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->user = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($this->user);
}

/**
* Tests that the home page loads with a 200 response.
*/
public function testLoad() {
$this->drupalGet(Url::fromRoute('<front>'));
$this->assertSession()->statusCodeEquals(200);
}

}