Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble triggering toast notifications within an extension #637

Open
2 tasks done
jackkemmish opened this issue Sep 2, 2024 · 3 comments
Open
2 tasks done

Trouble triggering toast notifications within an extension #637

jackkemmish opened this issue Sep 2, 2024 · 3 comments
Labels

Comments

@jackkemmish
Copy link

jackkemmish commented Sep 2, 2024

Module version(s) affected

2.2

Description

I am trying to trigger a toast notification using the X-Status header within an extension file for File.php within this module. I can see my HTTP response triggering in the dev tools network tab correctly, with the X-Status header being applied, but it's not triggering the toast notification.

How to reproduce

I have a few functions i'd like to trigger this toast notification, but for simplicity I am showing one example. I am initialising an AWS S3 Client in an onBeforeWrite function, and in the function I am checking if the correct ENV vars are set. If they're not I am wanting to throw an error for configuration issues utilising a toast notification.

My config.yml:

---
Name: s3
Only:
  envvarset:
    - AWS_REGION
    - AWS_BUCKET_NAME
    - AWS_ACCESS_KEY_ID
    - AWS_SECRET_ACCESS_KEY
    - AWS_CLOUDFRONT_DOMAIN
After: '*'
---
SilverStripe\Assets\File:
  extensions:
    - S3\Extensions\FileExtension

This is the initialise function - the if block being my error I wish to throw:

private static function initialiseS3Client(): void
{
  if (self::awsKey() && self::awsSecret()) {
    $message = _t(__CLASS__ . '.ValidationError', 'Validation error') . ': ' . 'AWS S3 isn\'t configured correctly.';
    $e = new HTTPResponse_Exception($message, 403);
    $errorResponse = $e->getResponse();
    $errorResponse->addHeader('X-Status', rawurlencode($message));
    $e->setResponse($errorResponse);
    throw $e;
  }
  if (!self::$s3) self::$s3 = new S3Client([
    'region' => self::awsRegion(),
    'version' => 'latest',
    'credentials' => self::awsCredentials()
  ]);
}

The onBeforeWrite function:

public function onBeforeWrite(): void
  {
    parent::onBeforeWrite();

    $file = $this->owner;
    if ($this->isCorrectFileType($file)) {
      self::initialiseS3Client(); // Initialise S3 if correct file type
      
      ...some funky code
  }
}

When publishing a file and not having those credentials set, I can see it erroring as expected in the network tab with the messaging and the X-Status header adding to the response, but nothing visually happens in terms of toast notifications in the CMS.

I got the example for the HTTPResponse_Exception from the LeftAndMain.php within the silverstripe-admin module:

public function handleRequest(HTTPRequest $request): HTTPResponse
  {
    try {
      $response = parent::handleRequest($request);
    } catch (ValidationException $e) {
      // Nicer presentation of model-level validation errors
      $msgs = _t(__CLASS__ . '.ValidationError', 'Validation error') . ': ' . $e->getMessage();
      $e = new HTTPResponse_Exception($msgs, 403);
      $errorResponse = $e->getResponse();
      $errorResponse->addHeader('Content-Type', 'text/plain');
      $errorResponse->addHeader('X-Status', rawurlencode($msgs));
      $e->setResponse($errorResponse);
      throw $e;
  }

  ...some other code

  return $response;
}

Any thoughts on why mine might not be triggering? Is it a bug, or have I completely misunderstood the use of the X-Status header?

Thanks in advance :D

Possible Solution

No response

Additional Context

No response

Validations

  • Check that there isn't already an issue that reports the same bug
  • Double check that your reproduction steps work in a fresh installation of silverstripe/installer (with any code examples you've provided)
@emteknetnz
Copy link
Member

The JS code that uses the X-Status code is very old and relies on the XHR request being triggered specifically by request that was triggered from jQuery.ajax(), and not some other mechanism like the newer fetch(). I wasn't even personally aware you could trigger toasts via a status header until reading this issue.

There isn't really a reliable way to trigger toasts from PHP. We trigger them manually using JS within react components use a redux action, though it's also possible to trigger them via a jquery call. That's probably not too helpful for what you're doing.

Since this issue isn't a bug I'll close this issue

@GuySartorelli
Copy link
Member

GuySartorelli commented Sep 4, 2024

The X-Status header is explicitly documented as a way to trigger toasts so I'll reopen this and mark it as a bug,

If we want to discontinue that feature we'll need to do so in a major release.

@jackkemmish
Copy link
Author

Morning @emteknetnz, thanks for looking into this initially.

As @GuySartorelli mentioned, it says in the docs that it's a way to trigger toast notifications X-Status: Extended status information, used for an information popover (aka "toast" message).. If that's not the case anymore it should probably be removed from the docs.

I can see the X-Status header being used in a fair few Silverstripe modules so I'd assume it still has some use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants