Skip to content

Commit

Permalink
Merge pull request rollbar#186 from ArturMoczulski/github-137-inject-…
Browse files Browse the repository at this point in the history
…rollbarjs

Github Issue rollbar#137: Add helper function to inject javascript snippet in views
  • Loading branch information
rokob authored May 31, 2017
2 parents 5932c52 + 16f421a commit c73b83d
Show file tree
Hide file tree
Showing 4 changed files with 522 additions and 0 deletions.
33 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,39 @@ Rollbar::init(array(
?>
```

## Integration with Rollbar.js

In case you want to report your JavaScript errors using [Rollbar.js](https://github.com/rollbar/rollbar.js), you can configure the SDK to enable Rollbar.js on your site. Example:

```php
$rollbarJs = Rollbar\RollbarJsHelper::buildJs(
array(
"accessToken" => "POST_CLIENT_ITEM_ACCESS_TOKEN",
"captureUncaught" => true,
"payload" => array(
"environment" => "production"
),
/* other configuration you want to pass to RollbarJS */
)
);
```

Or if you are using Content-Security-Policy: script-src 'unsafe-inline'
```php
$rollbarJs = Rollbar\RollbarJsHelper::buildJs(
array(
"accessToken" => "POST_CLIENT_ITEM_ACCESS_TOKEN",
"captureUncaught" => true,
"payload" => array(
"environment" => "production"
),
/* other configuration you want to pass to RollbarJS */
),
headers_list(),
$yourNonceString
);
```

## Basic Usage

That's it! Uncaught errors and exceptions will now be reported to Rollbar.
Expand Down
1 change: 1 addition & 0 deletions data/rollbar.snippet.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

170 changes: 170 additions & 0 deletions src/RollbarJsHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?php namespace Rollbar;

class RollbarJsHelper
{

protected $config;

/**
* @param array $config The array passed to he should have the same
* available options that you can find in Rollbar.js, using symbols or
* strings for the keys.
*/
public function __construct($config)
{
$this->config = $config;
}

/**
* Shortcut method for building the RollbarJS Javascript
*
* @param array $config @see addJs()
* @param string $nonce @see addJs()
*
* @return string
*/
public static function buildJs($config, $headers = null, $nonce = null)
{
$helper = new self($config);
return $helper->addJs($headers, $nonce);
}

/**
* Build Javascript required to include RollbarJS on
* an HTML page
*
* @param array $headers Response headers usually retrieved through
* headers_list() used to verify if nonce should be added to script
* tags based on Content-Security-Policy
* @param string $nonce Content-Security-Policy nonce string if exists
*
* @return string
*/
public function addJs($headers = null, $nonce = null)
{
return $this->scriptTag(
$this->configJsTag() .$this->jsSnippet(),
$headers,
$nonce
);
}

/**
* Build RollbarJS config script
*
* @return string
*/
public function configJsTag()
{
$config = isset($this->config['options']) ? $this->config['options'] : new \stdClass();
return "var _rollbarConfig = " . json_encode($config) . ";";
}

/**
* Build rollbar.snippet.js string
*
* @return string
*/
public function jsSnippet()
{
return file_get_contents(
$this->snippetPath()
);
}

/**
* @return string Path to the rollbar.snippet.js
*/
public function snippetPath()
{
return realpath(__DIR__ . "/../data/rollbar.snippet.js");
}

/**
* Should JS snippet be added to the HTTP response
*
* @param int $status
* @param array $headers
*
* @return boolean
*/
public function shouldAddJs($status, $headers)
{
return
$status == 200 &&
$this->isHtml($headers) &&
!$this->hasAttachment($headers);

/**
* @todo not sure if below two conditions will be applicable
*/
/* !env[JS_IS_INJECTED_KEY] */
/* && !streaming?(env) */
}

/**
* Is the HTTP response a valid HTML response
*
* @param array $headers
*
* @return boolean
*/
public function isHtml($headers)
{
return in_array('Content-Type: text/html', $headers);
}

/**
* Does the HTTP response include an attachment
*
* @param array $headers
*
* @return boolean
*/
public function hasAttachment($headers)
{
return in_array('Content-Disposition: attachment', $headers);
}

/**
* Is `nonce` attribute on the script tag needed?
*
* @param array $headers
*
* @return boolean
*/
public function shouldAppendNonce($headers)
{
foreach ($headers as $header) {
if (strpos($header, 'Content-Security-Policy') !== false &&
strpos($header, "'unsafe-inline'") !== false) {
return true;
}
}

return false;
}

/**
* Build safe HTML script tag
*
* @param string $content
* @param array $headers
* @param
*
* @return string
*/
public function scriptTag($content, $headers = null, $nonce = null)
{
if ($headers !== null && $this->shouldAppendNonce($headers)) {
if (!$nonce) {
throw new \Exception('Content-Security-Policy is script-src '.
'inline-unsafe but nonce value not provided.');
}

return "\n<script type=\"text/javascript\" nonce=\"$nonce\">$content</script>";
} else {
return "\n<script type=\"text/javascript\">$content</script>";
}
}
}
Loading

0 comments on commit c73b83d

Please sign in to comment.