Skip to content

Commit

Permalink
Merge pull request #143 from pantheon-systems/cms-728-post-schema
Browse files Browse the repository at this point in the history
[CMS-728] Allow users to post custom schema files.
  • Loading branch information
kporras07 authored Jul 12, 2022
2 parents 7ee4df9 + 6b1d681 commit bf3bfc8
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 29 deletions.
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ on:
repository_dispatch:
schedule:
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
tmate_enabled:
description: Enable tmate debugging
required: true
default: 0
jobs:
linting:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -79,6 +85,10 @@ jobs:
- name: Composer install
run: composer install --ignore-platform-req=php

- name: Setup tmate session
if: ${{ github.event.inputs.tmate_enabled == 1 }}
uses: mxschmitt/action-tmate@v3

- name: Run tests
run: |
export TERMINUS_ORG=$TERMINUS_ORG
Expand Down
30 changes: 29 additions & 1 deletion RoboFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public function testFull(int $drupal_version = 9, string $site_name = NULL) {
$this->testCreateSite($site_name, $options);
$this->testConnectionGit($site_name, 'dev', 'git');
$this->testCloneSite($site_name);
$this->testAllowPlugins($site_name);

// If received Drupal 8, downgrade the recently created site to Drupal 8.
if ($drupal_version === 8) {
Expand Down Expand Up @@ -212,7 +213,7 @@ public function waitForWorkflow(string $site_name, string $env = 'dev') {
if ( $info['status'] !== 'succeeded' ) {
$this->output()->write('Waiting for platform', true);
exec(
"terminus build:workflow:wait --max=260 --progress-delay=5 $site_name.$env",
"terminus build:workflow:wait --max=260 $site_name.$env",
$finished,
$status
);
Expand Down Expand Up @@ -302,6 +303,33 @@ public function testCloneSite(string $site_name) {
return ResultData::EXITCODE_OK;
}

/**
* Add allow plugins section to composer.
*
* @param string $site_name
* The machine name of the site to add the allow plugins section to.
*/
public function testAllowPlugins(string $site_name) {
$site_folder = $this->getSiteFolder($site_name);
chdir($site_folder);
$plugins = [
'composer/installers',
'drupal/core-composer-scaffold',
'cweagans/composer-patches',
];

foreach ($plugins as $plugin_name) {
$this->taskExec('composer')
->args(
'config',
'--no-interaction',
'allow-plugins.' . $plugin_name,
'true'
)
->run();
}
}

/**
* Downgrade given site to Drupal 8.
*
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@
"http-interop/http-factory-guzzle": "^1.0",
"kint-php/kint": "^4.1",
"php-http/guzzle6-adapter": "^2.0",
"psr/event-dispatcher": "^1.0"
"psr/event-dispatcher": "^1.0",
"symfony/finder": "^4|^5"
},
"require-dev": {
"consolidation/robo": "^3.0",
Expand Down
80 changes: 76 additions & 4 deletions modules/search_api_pantheon_admin/src/Form/PostSolrSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Drupal\search_api\ServerInterface;
use Drupal\search_api_pantheon\Services\SchemaPoster;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Finder\Finder;

/**
* The Solr admin form.
Expand All @@ -22,6 +23,13 @@ class PostSolrSchema extends FormBase {
*/
protected SchemaPoster $schemaPoster;

/**
* Search api server.
*
* @var \Drupal\search_api\ServerInterface
*/
protected ServerInterface $server;

/**
* Constructs a new EntityController.
*/
Expand Down Expand Up @@ -49,18 +57,82 @@ public function getFormId() {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, ServerInterface $search_api_server = NULL) {
$messages = $this->schemaPoster->postSchema($search_api_server->id());
$form['results'] = [
'#markup' => implode('<br>', $messages),
];
$this->server = $search_api_server;

$form['path'] = [
'#type' => 'textfield',
'#title' => $this->t('Path to config files to post'),
'#description' => $this->t('Path to the config files to post. This should be a directory containing the configuration files to post. Leave empty to use search_api_solr defaults.'),
'#default_value' => '',
'#required' => FALSE,
'#attributes' => [
'placeholder' => $this->t('Leave empty to use search_api_solr defaults.'),
],
];

$form['actions'] = ['#type' => 'actions'];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Post Schema'),
];

return $form;
}

/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$path = $form_state->getValue('path');
if ($path) {
if (!is_dir($path)) {
$form_state->setErrorByName('path', $this->t('The path %path is not a directory.', ['%path' => $path]));
return;
}
$finder = new Finder();
// Only work with direct children.
$finder->depth('== 0');
$finder->files()->in($path);
if (!$finder->hasResults()) {
$form_state->setErrorByName('path', $this->t('The path %path does not contain any files.', ['%path' => $path]));
}
}
}

/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$path = $form_state->getValue('path');
$files = [];
if ($path) {
$finder = new Finder();
// Only work with direct children.
$finder->depth('== 0');
$finder->files()->in($path);
foreach ($finder as $file) {
$files[$file->getfilename()] = $file->getContents();
}
}
$message = $this->schemaPoster->postSchema($this->server->id(), $files);
$method = $this->getMessageFunction($message[0]);
$this->messenger()->{$method}($message[1]);
}

/**
* Get the right function to call based on the message type.
*/
protected function getMessageFunction(string $type) {
$functions = [
'info' => 'addStatus',
'error' => 'addError',
];
if (isset($functions[$type])) {
return $functions[$type];
}

$this->messenger()->addWarning(t('Unknown message type: @type', ['@type' => $message[0]]));
return 'addStatus';
}

}
33 changes: 29 additions & 4 deletions src/Commands/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Drupal\search_api_pantheon\Services\PantheonGuzzle;
use Drupal\search_api_pantheon\Services\SchemaPoster;
use Drush\Commands\DrushCommands;
use Symfony\Component\Finder\Finder;

/**
* Drush Search Api Pantheon Schema Commands.
Expand Down Expand Up @@ -52,19 +53,43 @@ public function __construct(
/**
* Search_api_pantheon:postSchema.
*
* @usage search_api_pantheon:postSchema {$server_id}
* @usage search-api-pantheon:postSchema [server_id] [path]
* Post the latest schema to the given Server.
* Default server ID = pantheon_solr8.
* Default path = empty (build files using search_api_solr mechanism).
*
* @command search-api-pantheon:postSchema
*
* @param $server_id
* Server id to post schema for.
* @param $path
* Path to schema files (Leave empty to use default schema).
*
* @command search-api-pantheon:postSchema ${$server_id}
* @aliases sapps
*/
public function postSchema(?string $server_id = NULL) {
public function postSchema(?string $server_id = NULL, ?string $path = NULL) {
if (!$server_id) {
$server_id = PantheonSolrConnector::getDefaultEndpoint();
}
try {
$this->schemaPoster->postSchema($server_id);
$files = [];
if ($path) {
if (!is_dir($path)) {
throw new \Exception("Path '$path' is not a directory.");
}
$finder = new Finder();
// Only work with direct children.
$finder->depth('== 0');
$finder->files()->in($path);
if (!$finder->hasResults()) {
throw new \Exception("Path '$path' does not contain any files.");
}
foreach ($finder as $file) {
$files[$file->getfilename()] = $file->getContents();
}
}

$this->schemaPoster->postSchema($server_id, $files);
}
catch (\Exception $e) {
$this->logger()->error((string) $e);
Expand Down
55 changes: 36 additions & 19 deletions src/Services/SchemaPoster.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,24 @@ public function __construct(
*
* @param string $server_id
* Search Api Server ID.
* @param array $files
* Array of files to post.
*
* @return array
* Array of response messages.
* Message to be displayed to user (type, message).
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
* @throws \Drupal\search_api\SearchApiException
* @throws \Drupal\search_api_solr\SearchApiSolrException
*/
public function postSchema(string $server_id): array {
public function postSchema(string $server_id, $files = []): array {
// PANTHEON Environment.
if (isset($_ENV['PANTHEON_ENVIRONMENT'])) {
$response = $this->uploadSchemaFiles($this->getSolrFiles($server_id));
if (!$files) {
$files = $this->getSolrFiles($server_id);
}
$response = $this->uploadSchemaFiles($files);
}
// LOCAL DOCKER.
if (isset($_SERVER['ENV']) && $_SERVER['ENV'] === 'local') {
Expand All @@ -89,25 +94,37 @@ public function postSchema(string $server_id): array {
if (!$response instanceof Response) {
throw new \Exception('Cannot post schema to environment url.');
}

return $this->processResponse($response);
}

/**
* Process response and return message to be shown to user.
*
* @param \GuzzleHttp\Psr7\Response $response
* Response from Guzzle.
*
* @return array
* Message to be displayed to user (type, message).
*/
public function processResponse(Response $response): array {
$log_function = in_array($response->getStatusCode(), [
200,
201,
202,
203,
204,
])
? 'info'
: 'error';
200,
201,
202,
203,
204,
]) ? 'info' : 'error';
$this->logger->{$log_function}('Files uploaded: {status_code} {reason}', [
'status_code' => $response->getStatusCode(),
'reason' => $response->getReasonPhrase(),
]);
'status_code' => $response->getStatusCode(),
'reason' => $response->getReasonPhrase(),
]);
$message = vsprintf($this->t('Result: %s Status code: %d - %s'), [
$log_function == 'error' ? 'NOT UPLOADED' : 'UPLOADED',
$response->getStatusCode(),
$response->getReasonPhrase(),
]);
return [$message];
$log_function == 'error' ? 'NOT UPLOADED' : 'UPLOADED',
$response->getStatusCode(),
$response->getReasonPhrase(),
]);
return [$log_function, $message];
}

/**
Expand Down

0 comments on commit bf3bfc8

Please sign in to comment.