Skip to content
Snippets Groups Projects
Commit 881ccd1f authored by Daniel Cothran's avatar Daniel Cothran
Browse files

Issue #3446009 by andileco, nikathone: Make column selector a select list based on the headers

parent 99858f12
No related branches found
No related tags found
1 merge request!3Issue #3446009 by andileco: Make column selector a select list based on the headers
Pipeline #189996 passed with warnings
......@@ -7,6 +7,7 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Markup;
use Drupal\views\Plugin\views\field\FieldPluginBase;
use Drupal\views\ResultRow;
use Drupal\views_csv_source\Plugin\views\query\ViewsCsvQuery;
/**
* Base field handler for views_csv_source.
......@@ -66,13 +67,28 @@ class ViewsCsvField extends FieldPluginBase {
*/
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['key'] = [
'#title' => $this->t('Column Selector'),
'#description' => $this->t('Choose a column'),
'#type' => 'textfield',
'#default_value' => $this->options['key'],
'#required' => TRUE,
];
// Get the query.
$query = $this->view->query;
assert($query instanceof ViewsCsvQuery, 'Query must be of type ViewsCsvQuery');
// Ensure the query is of the correct type.
if ($headers = $query->getCsvHeader()) {
$form['key']['#type'] = 'select';
$form['key']['#options'] = array_combine($headers, $headers);
}
else {
// Fall back to text value if CSV has not been selected.
$form['key']['#type'] = 'textfield';
}
$form['trusted_html'] = [
'#title' => $this->t('Trusted HTML'),
'#description' => $this->t('This field is from a trusted source and contains raw HTML markup to render here. Use with caution.'),
......
......@@ -607,6 +607,16 @@ class ViewsCsvQuery extends QueryPluginBase {
return strtoupper($group_type);
}
/**
* Get the CSV headers.
*
* @return array
* The headers of the CSV file.
*/
public function getCsvHeader(): array {
return $this->connection->getCsvHeader($this->getCsvFileUri());
}
/**
* Returns a list of non-aggregates to be added to the "group by" clause.
*
......
......@@ -12,6 +12,8 @@ use Drupal\Core\Config\ImmutableConfig;
use Drupal\views_csv_source\Event\PreCacheEvent;
use Drupal\views_csv_source\UriParserTrait;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use League\Csv\Reader;
use Psr\Http\Message\ResponseInterface;
/**
......@@ -108,8 +110,6 @@ class Connection {
*
* @throws \Exception
* If the file is not found.
* @throws \GuzzleHttp\Exception\GuzzleException
* If the request fails.
*/
public function fetchContent(string $uri, array $options = []): string {
if ($this->csvContent) {
......@@ -141,11 +141,16 @@ class Connection {
'cache_id' => Crypt::randomBytesBase64(),
];
// Add the request headers if available.
$result = $this->getRequestResponse($uri, $options);
try {
// Add the request headers if available.
$result = $this->getRequestResponse($uri, $options);
}
catch (GuzzleException $e) {
$result = NULL;
}
if (isset($result->error)) {
$message = sprintf('HTTP response: %s. URI: %s', $result->error, $uri);
if (isset($result->error) || $result === NULL) {
$message = sprintf('HTTP response: %s. URI: %s', $result->error ?? 'Unknown', $uri);
throw new \Exception($message);
}
......@@ -163,6 +168,29 @@ class Connection {
return $this->csvContent;
}
/**
* Get the headers from the CSV file.
*
* @param string $uri
* The URI of the CSV file.
*
* @return array
* The headers of the CSV file.
*/
public function getCsvHeader(string $uri = ''): array {
if (empty($uri)) {
$uri = $this->csvUri;
}
try {
$csv = Reader::createFromString($this->fetchContent($uri));
return $csv->nth(0) ?? [];
}
catch (\Exception $e) {
return [];
}
}
/**
* Get request result.
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment