Changeset 3380353
- Timestamp:
- 10/17/2025 10:48:31 PM (3 months ago)
- Location:
- rollbar/trunk
- Files:
-
- 7 edited
-
README.md (modified) (7 diffs)
-
composer.json (modified) (1 diff)
-
composer.lock (modified) (51 diffs)
-
mu-plugin/rollbar-mu-plugin.php (modified) (1 diff)
-
readme.txt (modified) (9 diffs)
-
src/Plugin.php (modified) (2 diffs)
-
src/Settings.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
rollbar/trunk/README.md
r2965452 r3380353 1 1 # Rollbar for WordPress 2 2 3 [](https://wordpress.org/plugins/rollbar/) [](https://wordpress.org/plugins/rollbar/) [](https://wordpress.org/plugins/rollbar/) [](https://wordpress.org/plugins/rollbar/) 3 4 4 Rollbar full-stack error tracking for WordPress 5 6 The full documentation is available [here](https://docs.rollbar.com/v1.0.0/docs/wordpress). 7 8 ## Description 5 Rollbar full-stack error tracking for WordPress. 6 9 7 Rollbar collects errors that happen in your application, notifies you, and analyzes them so you can debug and fix them. 10 11 8 This plugin integrates Rollbar into your WordPress installation. 12 9 13 Find out [how Rollbar can help you decrease development and maintenance costs](https://rollbar.com/features/). 14 15 See [real companies improving their development workflow thanks to Rollbar](https://rollbar.com/customers/). 10 #### Helpful Links 11 12 * [Documentation](https://docs.rollbar.com/docs/wordpress) 13 * [Official WordPress.org Plugin](https://wordpress.org/plugins/rollbar/) 14 * [How Rollbar Works](https://rollbar.com/discover/) 15 * [Rollbar Pricing](https://rollbar.com/pricing/) 16 16 17 17 [Official WordPress.org Plugin](https://wordpress.org/plugins/rollbar/) 18 #### Table of Contents 19 20 1. [Installation](#installation) 21 1. [Through WordPress Plugin directory](#through-wordpress-plugin-directory) 22 2. [Through Packagist](#through-packagist-recommended-new) 23 3. [Through WPackagist](#through-wpackagist) 24 2. [Configuration](#configuration) 25 1. [WordPress Admin](#wordpress-admin) 26 2. [Programmatic Configuration](#programmatic-configuration) 27 3. [Advanced Use](#advanced-use) 28 1. [Constants](#constants) 29 2. [Environment Variables](#environment-variables) 30 3. [Filters](#filters) 31 4. [Telemetry](#telemetry) 32 4. [Help / Support](#help--support) 33 5. [Special thanks](#special-thanks) 34 6. [Contributing](#contributing) 35 7. [Testing](#testing) 18 36 19 37 ## Installation … … 21 39 ### Through [WordPress Plugin directory](https://wordpress.org/plugins/rollbar/) 22 40 23 The easiest way to install the plugin is from the WordPress Plugin directory. If you have an existing WordPress installation and you want to add Rollbar: 41 The easiest way to install the plugin is from the WordPress Plugin directory. If you have an existing WordPress 42 installation, and you want to add Rollbar: 24 43 25 44 1. In your WordPress administration panel go to `Plugins` → `Add New`. … … 27 46 3. Click `Install Now` next to the `Rollbar` plugin. 28 47 4. In `Plugins` → `Installed plugins` find `Rollbar` and click `Activate` underneath. 29 5. Log into your [Rollbar account dashboard](https://rollbar.com/login/): 30 1. Go to `Settings` → `Project Access Tokens`. 31 2. Copy the token value under `post_client_item` and `post_server_item`. 32 6. In WordPress, navigate to `Settings` → `Rollbar`: 33 1. Enable `PHP error logging` and/or `Javascript error logging` depending on your needs. 34 2. Paste the tokens you copied in step 7 in `Access Token` section. 35 3. Provide the name of your environment in `Environment`. By default, the environment will be taken from `WP_ENV` environment variable if it's set otherwise it's blank. We recommend to fill this out either with `development` or `production`. 36 4. Pick a minimum logging level. Only errors at that or higher level will be reported. For reference: [PHP Manual: Predefined Error Constants](http://php.net/manual/en/errorfunc.constants.php). 37 5. Click `Save Changes`. 38 39 **Warning**: This installation method might not be suitable for complex WordPress projects. The plugin installed this way will be self-contained and include all of the required dependencies for itself and `rollbar/rollbar-php` library. In complex projects, this might lead to version conflicts between dependencies and other plugins/packages. If this is an issue in your project, we recommend the "Advanced" installation method. For more information why this might be important for you, read [Using Composer with WordPress](https://roots.io/using-composer-with-wordpress/). 40 41 ### Through [wpackagist](https://wpackagist.org/) (if you manage your project with Composer) *recommended* 42 43 This is a recommended way to install Rollbar plugin for advanced projects. This way ensures the plugin and all of its' dependencies are managed by Composer. 44 45 1. If your WordPress project is not managed with Composer yet, we suggest looking into upgrading your WordPress: [Using Composer with WordPress](https://roots.io/using-composer-with-wordpress/). 46 2. In your `composer.json` add `wpackagist-plugin/rollbar` to your `require` section, i.e.: 47 ```json 48 "require": { 49 "php": ">=5.5", 50 ..., 51 "wpackagist-plugin/rollbar": "*" 52 } 48 49 **Warning**: This installation method might not be suitable for complex WordPress projects. The plugin installed this 50 way will be self-contained and include all of the required dependencies for itself and the `rollbar/rollbar-php` 51 library. In complex projects, this might lead to version conflicts between dependencies and other plugins/packages. If 52 this is an issue in your project, we recommend the "Packagist" installation method. 53 54 ### Through [Packagist](https://packagist.org/packages/rollbar/rollbar-php-wordpress) *recommended new* 55 56 *Note: this only works if your WordPress project is managed with Composer. 57 Read [Using Composer with WordPress](https://roots.io/using-composer-with-wordpress/) for more details.* 58 59 This is a recommended way to install the Rollbar plugin for advanced projects. This way ensures the plugin and all of 60 its dependencies are managed by Composer. 61 62 You can install the plugin by running the following command in the root directory of your WordPress project: 63 64 ```txt 65 composer require rollbar/rollbar-php-wordpress:^3.0 53 66 ``` 54 3. Issue command `composer install` in the root directory of your WordPress project. 55 4. Go to step #4 above. 67 68 ### Through [WPackagist](https://wpackagist.org/) 69 70 *Note: if your WordPress project is managed with Composer, we strongly recommend installing the plugin through 71 Packagist instead.* 72 73 *Installing the plugin from wpackagist.org instead of packagist.org will result in the plugin being managed by 74 Composer. However, the downside is that it's dependencies will not be managed by composer. Instead they will be packaged 75 in the plugin's `vendor` directory not in your project's `vendor` directory. This has the potential to cause name 76 collisions if other plugins or your project use different versions of the same dependencies.* 77 78 To install the plugin from wpackagist.org run the following steps command in the root directory of your WordPress 79 project: 80 81 ```txt 82 composer require wpackagist-plugin/rollbar 83 ``` 84 85 ## Configuration 86 87 The plugin can be configured in the WordPress Admin or programmatically. 88 89 ### WordPress Admin 90 91 The plugin provides a settings page in the WordPress Admin that allows you to configure the plugin. This settings page 92 can be disabled by setting the `ROLLBAR_DISABLE_ADMIN` constant to `true` in your `wp-config.php` file. 93 94 1. In `Plugins` → `Installed plugins` find `Rollbar` and click `Activate` underneath. 95 2. Log into your [Rollbar account dashboard](https://rollbar.com/login/): 96 1. Go to `Settings` → `Project Access Tokens`. 97 2. Copy the token value under `post_client_item` and `post_server_item`. 98 3. In WordPress, navigate to `Settings` → `Rollbar`: 99 1. Enable `PHP error logging` and/or `Javascript error logging` depending on your needs. 100 2. Paste the tokens you copied in step 7 in `Access Token` section. 101 3. Provide the name of your environment in `Environment`. By default, the environment will be taken from `WP_ENV` 102 environment variable if it's set otherwise it's blank. We recommend to fill this out either with `development` or 103 `production`. 104 4. Pick a minimum logging level. Only errors at that or higher level will be reported. For 105 reference: [PHP Manual: Predefined Error Constants](http://php.net/manual/en/errorfunc.constants.php). 106 5. Click `Save Changes`. 107 108 ### Programmatic Configuration 109 110 The plugin can also be configured programmatically. This is useful if you want to configure the plugin in a more 111 advanced way or if you want to disable the admin settings page. 112 113 ```php 114 // wp-config.php 115 116 // Configure the plugin. 117 define( 'ROLLBAR_SETTINGS', [ 118 'php_logging_enabled' => true, 119 'server_side_access_token' => '<your token>', 120 'js_logging_enabled' => true, 121 'client_side_access_token' => '<your client token>', 122 'environment' => 'development', 123 'included_errno' => E_ERROR, 124 'enable_person_reporting' => true, 125 ] ); 126 127 // Optional: disable the admin settings page so the plugin is configured only programmatically. 128 define( 'ROLLBAR_DISABLE_ADMIN', true ); 129 ``` 130 131 ## Advanced Use 132 133 ### Constants 134 135 The plugin provides a number of constants that can be used to configure the plugin. These should typically be defined in 136 the `wp-config.php` file. 137 138 Note: If you define these constants, they will override the settings defined in the WordPress Admin. 139 140 * `ROLLBAR_DISABLE_ADMIN` - (optional) Removes the Rollbar Admin menu from the WordPress Admin if set to `true`. This 141 allows for the plugin to be used without the admin settings page, for example, if the plugin is managed via the 142 `wp-config.php` file. 143 * `ROLLBAR_SETTINGS` - (optional) An associative array of settings to override the settings values from the WordPress 144 Admin. Note: if you disable the admin settings page with `ROLLBAR_DISABLE_ADMIN` constant, this constant must be used 145 to configure the plugin. 146 * `ROLLBAR_ACCESS_TOKEN` - The Rollbar PHP server access token. 147 * `ROLLBAR_CLIENT_ACCESS_TOKEN` - The Rollbar JS client access token. 148 149 #### WordPress Constants 150 151 The Rollbar plugin respects the following WordPress constants: 152 153 * `WP_ENV` - (optional) The environment name. This is used to determine the environment name for the Rollbar project. 154 * `WP_PROXY_HOST` - (optional) The proxy host. If both `WP_PROXY_HOST` and `WP_PROXY_PORT` are set, the plugin will use 155 the respect the HTTP proxy when making requests to Rollbar. 156 * `WP_PROXY_PORT` - (optional) The proxy port. 157 * `WP_PROXY_USERNAME` - (optional) The proxy username. 158 * `WP_PROXY_PASSWORD` - (optional) The proxy password. 159 * `WP_PROXY_BYPASS_HOSTS` - (optional) The proxy bypass hosts. This is a comma-separated list of hosts that should not 160 be 161 proxied. If proxying is enabled, but you don't want to proxy requests to Rollbar, you can add `api.rollbar.com` to 162 this list. 163 164 ### Environment Variables 165 166 The plugin looks for the following environment variables to configure itself. Note: these are overridden by the 167 constants defined above. 168 169 * `ROLLBAR_ACCESS_TOKEN` - The Rollbar PHP server access token. 170 * `ROLLBAR_CLIENT_ACCESS_TOKEN` - The Rollbar JS client access token. 171 * `WP_ENV` - (optional) The environment name. This is used to determine the environment name for the Rollbar project. 172 173 ### Filters 174 175 The plugin provides a number of filters that allow you to customize the behavior of the plugin. 176 177 #### `apply_filters('rollbar_api_admin_permission', bool $value, string $route, WP_REST_Request $request)` 178 179 Filter to allow or deny access to a Rollbar route in the WordPress REST API used in the WordPress Admin. Generally, 180 this should be the same as the `rollbar_user_can_view_admin` filter. 181 182 **Parameters** 183 184 * `bool $value` - The initial value. Defaults is `true` for admin users, `false` for non-admin users. 185 * `string $route` - The route being accessed. 186 * `WP_REST_Request $request` - The REST request object. 187 188 #### `apply_filters('rollbar_js_config', array $config)` 189 190 Filters the Rollbar JavaScript configuration. 191 192 **Parameters** 193 194 * `array $config` - The Rollbar JavaScript configuration array. 195 196 #### `apply_filters('rollbar_plugin_settings', array $settings)` 197 198 Filters the Rollbar plugin settings. 199 200 **Parameters** 201 202 * `array $settings` - The Rollbar plugin settings array. 203 204 #### `apply_filters('rollbar_php_config', array $config)` 205 206 Filters the Rollbar Core SDK PHP configuration. 207 208 **Parameters** 209 210 * `array $config` - The Rollbar PHP configuration array. 211 212 #### `apply_filters('rollbar_telemetry_actions', array<string, int> $actions)` 213 214 Filter the list of actions to instrument with Telemetry. 215 216 **Parameters** 217 218 * `array<string, int> $actions` - An associative array where the keys are action names and the values are the number of 219 arguments accepted by the action. 220 221 #### `apply_filters('rollbar_telemetry_custom_handlers', array<string, callable(string, mixed...):string> $handlers)` 222 223 Filter the list of custom action event handlers for Telemetry. 224 225 Note: The custom action handler will only be called if the action is instrumented with Telemetry. This means you must 226 select the action on the settings page, or add it to the list of actions using the `rollbar_telemetry_actions` filter. 227 228 **Parameters** 229 230 * `array<string, callable(string, mixed...):string> $handlers` - An associative array where the keys are action names 231 and the values are the custom event handler. 232 233 #### `apply_filters('rollbar_user_can_view_admin', bool $disable)` 234 235 Filter to enable / disable the admin settings page of the plugin for the current user. 236 237 This filter cannot override the `ROLLBAR_DISABLE_ADMIN` constant. 238 239 **Parameters** 240 241 * `bool $allow` - `true` to enable the admin settings page, `false` to disable it. 242 243 ### Telemetry 244 245 Starting in version 3.0.0 of the Rollbar plugin, Telemetry is enabled by default. Telemetry is a feature that allows 246 the plugin to track events that occur in your WordPress installation prior to an exception or message being sent to 247 Rollbar. The Telemetry data is sent to Rollbar along with the exception or message, and can be used to provide 248 additional context and help debug the issue. 249 250 You can modify the list of actions you want to instrument with Telemetry by selecting them on the settings page, or 251 using the `rollbar_telemetry_actions` filter. To use a custom handler for a specific action, use the 252 `rollbar_telemetry_custom_handlers` filter. This can also be used to change the handler on any of the default actions. 253 254 #### Registering custom actions 255 256 You can also instrument custom actions like this: 257 258 ```php 259 use Rollbar\WordPress\Telemetry\Listener; 260 261 // Register a custom action with a custom handler function. 262 Listener::getInstance()->instrumentAction( 263 action: 'my_custom_action', 264 priority: 10, 265 acceptedArgs: 2, 266 argsHandler: function ($action, ...$args) { 267 $foo = $action; 268 return 'custom_listener_test_action: ' . implode(', ', $args); 269 }, 270 ); 271 272 // Use the default handler for the action. 273 Listener::getInstance()->instrumentAction( 274 action: 'my_other_custom_action', 275 priority: 10, 276 acceptedArgs: 1, 277 argsHandler: Listener::concatExtraArgs(...), 278 ); 279 ``` 280 281 Of course, you can also call `Rollbar::captureTelemetryEvent()` directly to send custom events. See the 282 [Telemetry documentation](https://docs.rollbar.com/docs/php-telemetry) for more information. 56 283 57 284 ## Help / Support … … 60 287 61 288 For bug reports, please [open an issue on GitHub](https://github.com/rollbar/rollbar-php-wordpress/issues/new). 62 63 ## Special thanks64 65 The original author of this package is [@flowdee](https://twitter.com/flowdee/). This is a fork and continuation of his efforts.66 289 67 290 ## Contributing … … 70 293 2. Create your feature branch (`git checkout -b my-new-feature`) 71 294 3. Commit your changes (`git commit -am 'Added some feature'`) 72 4. Push to the branch (`git push origin my-new-feature`)73 5. Verify your commit passes the code standards enforced by [Codacy](https://www.codacy.com).74 5. Createnew Pull Request295 4. Make sure tests pass (see below). 296 5. Push to the branch (`git push origin my-new-feature`) 297 6. Create a new Pull Request 75 298 76 299 ## Testing 77 300 78 In order to run the tests, you will need to install the dependencies for [@wordpress/env](https://www.npmjs.com/package/@wordpress/env) including Node.js, git, and docker. 79 80 1. npm install 81 2. npm run test 82 You can set the `WP_ENV_PHP_VERSION` enviormental variable to test with different versions of PHP. If you are changing the version, you can do so by running `WP_ENV_PHP_VERSION="8.2" npm run wp-env start -- --update` and setting the enviornmental variable based on 301 To run the tests, you will need to install the dependencies for 302 [@wordpress/env](https://www.npmjs.com/package/@wordpress/env) including Node.js, git, and Docker. 303 304 1. `npm install` - This will install the dependencies to set up the local environment. 305 2. `npm run start` - This will start a local WordPress installation with the Rollbar plugin installed. 306 3. `npm run test` - This will run the tests. 307 308 You can set the `WP_ENV_PHP_VERSION` environment variable to test with different versions of PHP. If you are changing 309 the version, you can do so by running `WP_ENV_PHP_VERSION="8.2" npm run wp-env start -- --update` and setting the 310 environment variable based on the version you want to test with. 311 312 ## Special thanks 313 314 The original author of this package is [@flowdee](https://twitter.com/flowdee/). This is a fork and continuation of his 315 efforts. 83 316 84 317 ## Tagging … … 91 324 3. Add record in the `Upgrade Notice` section of the `readme.txt`. 92 325 4. Bump the plugin version in `rollbar-php-wordpress.php` in the `Version:` comment. 93 5. Bump the plugin version in `src/Plugin.php` in the `\Rollbar\Wordpress\Plugin::VERSION` constant. 94 5. Add and commit the changes you made to bump the plugin version: `git add readme.txt rollbar-php-wordpress.php src/Plugin.php && git commit -m"Bump version to v[version number]"` 95 6. Bump versions of the JS and CSS files versions in Settings.php class to force refresh of those assets on users' installations. 96 7. `git push origin master` 326 5. Bump the plugin version in `src/Plugin.php` in the `\Rollbar\WordPress\Plugin::VERSION` constant. 327 6. Add and commit the changes you made to bump the plugin version: 328 `git add readme.txt rollbar-php-wordpress.php src/Plugin.php && git commit -m"Bump version to v[version number]"` 329 7. Bump versions of the JS and CSS files versions in Settings.php class to force refresh of those assets on users' 330 installations. 331 8. `git push origin master` 97 332 2. Tag the new version from the `master` branch and push upstream with `git tag v[version number] && git push --tags`. 98 333 3. Publish a new release on [GitHub](https://github.com/rollbar/rollbar-php-wordpress/releases). … … 101 336 2. Remove the contents of `trunk/` with `rm -Rf trunk`. 102 337 3. Update the contents of `trunk/` with a clone of the tag you created in step 2. 103 2. `git clone https://github.com/rollbar/rollbar-php-wordpress.git trunk` 104 3. `cd trunk && git checkout tags/v[version number] && cd ..` 105 4. `rm -Rf trunk/.git` 106 5. `svn add trunk --force` 107 6. `svn commit -m"Sync with GitHub repo"` 108 4. Create the Subversion tag: `svn copy https://plugins.svn.wordpress.org/rollbar/trunk https://plugins.svn.wordpress.org/rollbar/tags/[version number] -m"Tag [version number]"`. Notice the version number in Subversion doesn't include the "v" prefix. 338 1. `git clone https://github.com/rollbar/rollbar-php-wordpress.git trunk` 339 2. `cd trunk && git checkout tags/v[version number] && cd ..` 340 3. `rm -Rf trunk/.git` 341 4. `svn add trunk --force` 342 5. `svn commit -m"Sync with GitHub repo"` 343 4. Create the Subversion tag: 344 `svn copy https://plugins.svn.wordpress.org/rollbar/trunk https://plugins.svn.wordpress.org/rollbar/tags/[version number] -m"Tag [version number]"`. 345 Notice the version number in Subversion doesn't include the "v" prefix. 109 346 110 347 ## Disclaimer 111 348 112 349 This plugin is a community-driven contribution. All rights reserved to Rollbar. 113 114 [](https://rollbar.com/) -
rollbar/trunk/composer.json
r2965452 r3380353 3 3 "description": "WordPress plugin for Rollbar", 4 4 "type": "wordpress-plugin", 5 "require-dev": { 6 "yoast/phpunit-polyfills": "^2.0", 5 "require": { 6 "php": "^8.1", 7 "rollbar/rollbar": "^4.1.3" 8 }, 9 "require-dev": { 10 "yoast/phpunit-polyfills": "^4.0", 7 11 "dealerdirect/phpcodesniffer-composer-installer": "^0.7", 8 "squizlabs/php_codesniffer": "^3.5",9 "phpcompatibility/php-compatibility": "^9.3",10 "wp-coding-standards/wpcs": "^2.2",12 "squizlabs/php_codesniffer": "^3.5", 13 "phpcompatibility/php-compatibility": "^9.3", 14 "wp-coding-standards/wpcs": "^2.2", 11 15 "sirbrillig/phpcs-variable-analysis": "^2.8" 12 16 }, 13 "license": "G NU GPL",17 "license": "GPL-2.0-or-later", 14 18 "authors": [ 15 19 { 16 "name": "flowdee", 17 "email": "hello@flowdee.de" 18 }, 19 { 20 "name": "Artur Moczulski", 21 "email": "artur.moczulski@gmail.com" 22 }, 23 { 24 "name": "Rollbar, Inc.", 25 "email": "support@rollbar.com", 26 "role": "Developer" 20 "name": "Rollbar, Inc.", 21 "email": "support@rollbar.com", 22 "role": "Developer" 27 23 } 28 24 ], 29 30 25 "support": { 31 26 "email": "support@rollbar.com" 32 27 }, 33 34 28 "autoload": { 35 "psr-4": { 36 "Rollbar\\Wordpress\\": "src/", 37 "Rollbar\\Wordpress\\Tests\\": "tests/" 38 } 29 "files": [ 30 "src/bootstrap.php" 31 ], 32 "psr-4": { 33 "Rollbar\\WordPress\\": "src/" 34 } 35 }, 36 "autoload-dev": { 37 "psr-4": { 38 "Rollbar\\WordPress\\Tests\\": "tests/" 39 } 39 40 }, 40 41 "extra": { 41 42 "scripts-description": { 42 43 "test": "Run all tests. Wrapper around npm run test" 43 } 44 }, 44 }, 45 "installer-name": "rollbar" 46 }, 45 47 "scripts": { 46 48 "test": [ -
rollbar/trunk/composer.lock
r2965452 r3380353 5 5 "This file is @generated automatically" 6 6 ], 7 "content-hash": "f9e2f4270199951bedd2eca45c9e600b", 8 "packages": [], 7 "content-hash": "94c1a39099682e59c5eeb17e74f916ae", 8 "packages": [ 9 { 10 "name": "monolog/monolog", 11 "version": "3.9.0", 12 "source": { 13 "type": "git", 14 "url": "https://github.com/Seldaek/monolog.git", 15 "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6" 16 }, 17 "dist": { 18 "type": "zip", 19 "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6", 20 "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6", 21 "shasum": "" 22 }, 23 "require": { 24 "php": ">=8.1", 25 "psr/log": "^2.0 || ^3.0" 26 }, 27 "provide": { 28 "psr/log-implementation": "3.0.0" 29 }, 30 "require-dev": { 31 "aws/aws-sdk-php": "^3.0", 32 "doctrine/couchdb": "~1.0@dev", 33 "elasticsearch/elasticsearch": "^7 || ^8", 34 "ext-json": "*", 35 "graylog2/gelf-php": "^1.4.2 || ^2.0", 36 "guzzlehttp/guzzle": "^7.4.5", 37 "guzzlehttp/psr7": "^2.2", 38 "mongodb/mongodb": "^1.8", 39 "php-amqplib/php-amqplib": "~2.4 || ^3", 40 "php-console/php-console": "^3.1.8", 41 "phpstan/phpstan": "^2", 42 "phpstan/phpstan-deprecation-rules": "^2", 43 "phpstan/phpstan-strict-rules": "^2", 44 "phpunit/phpunit": "^10.5.17 || ^11.0.7", 45 "predis/predis": "^1.1 || ^2", 46 "rollbar/rollbar": "^4.0", 47 "ruflin/elastica": "^7 || ^8", 48 "symfony/mailer": "^5.4 || ^6", 49 "symfony/mime": "^5.4 || ^6" 50 }, 51 "suggest": { 52 "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 53 "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 54 "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", 55 "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 56 "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", 57 "ext-mbstring": "Allow to work properly with unicode symbols", 58 "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", 59 "ext-openssl": "Required to send log messages using SSL", 60 "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", 61 "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 62 "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", 63 "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", 64 "rollbar/rollbar": "Allow sending log messages to Rollbar", 65 "ruflin/elastica": "Allow sending log messages to an Elastic Search server" 66 }, 67 "type": "library", 68 "extra": { 69 "branch-alias": { 70 "dev-main": "3.x-dev" 71 } 72 }, 73 "autoload": { 74 "psr-4": { 75 "Monolog\\": "src/Monolog" 76 } 77 }, 78 "notification-url": "https://packagist.org/downloads/", 79 "license": [ 80 "MIT" 81 ], 82 "authors": [ 83 { 84 "name": "Jordi Boggiano", 85 "email": "j.boggiano@seld.be", 86 "homepage": "https://seld.be" 87 } 88 ], 89 "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 90 "homepage": "https://github.com/Seldaek/monolog", 91 "keywords": [ 92 "log", 93 "logging", 94 "psr-3" 95 ], 96 "support": { 97 "issues": "https://github.com/Seldaek/monolog/issues", 98 "source": "https://github.com/Seldaek/monolog/tree/3.9.0" 99 }, 100 "funding": [ 101 { 102 "url": "https://github.com/Seldaek", 103 "type": "github" 104 }, 105 { 106 "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", 107 "type": "tidelift" 108 } 109 ], 110 "time": "2025-03-24T10:02:05+00:00" 111 }, 112 { 113 "name": "psr/log", 114 "version": "3.0.2", 115 "source": { 116 "type": "git", 117 "url": "https://github.com/php-fig/log.git", 118 "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" 119 }, 120 "dist": { 121 "type": "zip", 122 "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", 123 "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", 124 "shasum": "" 125 }, 126 "require": { 127 "php": ">=8.0.0" 128 }, 129 "type": "library", 130 "extra": { 131 "branch-alias": { 132 "dev-master": "3.x-dev" 133 } 134 }, 135 "autoload": { 136 "psr-4": { 137 "Psr\\Log\\": "src" 138 } 139 }, 140 "notification-url": "https://packagist.org/downloads/", 141 "license": [ 142 "MIT" 143 ], 144 "authors": [ 145 { 146 "name": "PHP-FIG", 147 "homepage": "https://www.php-fig.org/" 148 } 149 ], 150 "description": "Common interface for logging libraries", 151 "homepage": "https://github.com/php-fig/log", 152 "keywords": [ 153 "log", 154 "psr", 155 "psr-3" 156 ], 157 "support": { 158 "source": "https://github.com/php-fig/log/tree/3.0.2" 159 }, 160 "time": "2024-09-11T13:17:53+00:00" 161 }, 162 { 163 "name": "rollbar/rollbar", 164 "version": "v4.1.3", 165 "source": { 166 "type": "git", 167 "url": "https://github.com/rollbar/rollbar-php.git", 168 "reference": "99eb7bd2ea1ef3be4a6e693b022911b1db1582bf" 169 }, 170 "dist": { 171 "type": "zip", 172 "url": "https://api.github.com/repos/rollbar/rollbar-php/zipball/99eb7bd2ea1ef3be4a6e693b022911b1db1582bf", 173 "reference": "99eb7bd2ea1ef3be4a6e693b022911b1db1582bf", 174 "shasum": "" 175 }, 176 "require": { 177 "ext-curl": "*", 178 "monolog/monolog": "^2 || ^3", 179 "php": ">=8.1.0 <9.0", 180 "psr/log": "^1 || ^2 || ^3" 181 }, 182 "require-dev": { 183 "mockery/mockery": "^1.5.1", 184 "phpmd/phpmd": "^2.13", 185 "phpunit/phpunit": "^9.6 || ^10.1", 186 "squizlabs/php_codesniffer": "^3.7", 187 "vimeo/psalm": "^5.9" 188 }, 189 "suggest": { 190 "fluent/logger": "Needed to use the 'fluent' handler for fluentd support" 191 }, 192 "type": "library", 193 "autoload": { 194 "psr-4": { 195 "Rollbar\\": "src/" 196 } 197 }, 198 "notification-url": "https://packagist.org/downloads/", 199 "license": [ 200 "MIT" 201 ], 202 "authors": [ 203 { 204 "name": "Rollbar, Inc.", 205 "email": "support@rollbar.com", 206 "role": "Developer" 207 } 208 ], 209 "description": "Monitors errors and exceptions and reports them to Rollbar", 210 "homepage": "https://github.com/rollbar/rollbar-php", 211 "keywords": [ 212 "debugging", 213 "errors", 214 "exceptions", 215 "logging", 216 "monitoring" 217 ], 218 "support": { 219 "email": "support@rollbar.com", 220 "issues": "https://github.com/rollbar/rollbar-php/issues", 221 "source": "https://github.com/rollbar/rollbar-php/tree/v4.1.3" 222 }, 223 "time": "2025-04-17T19:11:14+00:00" 224 } 225 ], 9 226 "packages-dev": [ 10 227 { … … 85 302 { 86 303 "name": "doctrine/instantiator", 87 "version": " 1.5.0",304 "version": "2.0.0", 88 305 "source": { 89 306 "type": "git", 90 307 "url": "https://github.com/doctrine/instantiator.git", 91 "reference": " 0a0fa9780f5d4e507415a065172d26a98d02047b"92 }, 93 "dist": { 94 "type": "zip", 95 "url": "https://api.github.com/repos/doctrine/instantiator/zipball/ 0a0fa9780f5d4e507415a065172d26a98d02047b",96 "reference": " 0a0fa9780f5d4e507415a065172d26a98d02047b",97 "shasum": "" 98 }, 99 "require": { 100 "php": "^ 7.1 || ^8.0"101 }, 102 "require-dev": { 103 "doctrine/coding-standard": "^ 9 || ^11",308 "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" 309 }, 310 "dist": { 311 "type": "zip", 312 "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", 313 "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", 314 "shasum": "" 315 }, 316 "require": { 317 "php": "^8.1" 318 }, 319 "require-dev": { 320 "doctrine/coding-standard": "^11", 104 321 "ext-pdo": "*", 105 322 "ext-phar": "*", 106 "phpbench/phpbench": "^ 0.16 || ^1",107 "phpstan/phpstan": "^1. 4",108 "phpstan/phpstan-phpunit": "^1 ",109 "phpunit/phpunit": "^ 7.5 || ^8.5 || ^9.5",110 "vimeo/psalm": "^ 4.30 || ^5.4"323 "phpbench/phpbench": "^1.2", 324 "phpstan/phpstan": "^1.9.4", 325 "phpstan/phpstan-phpunit": "^1.3", 326 "phpunit/phpunit": "^9.5.27", 327 "vimeo/psalm": "^5.4" 111 328 }, 112 329 "type": "library", … … 135 352 "support": { 136 353 "issues": "https://github.com/doctrine/instantiator/issues", 137 "source": "https://github.com/doctrine/instantiator/tree/ 1.5.0"354 "source": "https://github.com/doctrine/instantiator/tree/2.0.0" 138 355 }, 139 356 "funding": [ … … 151 368 } 152 369 ], 153 "time": "2022-12-30T00: 15:36+00:00"370 "time": "2022-12-30T00:23:10+00:00" 154 371 }, 155 372 { 156 373 "name": "myclabs/deep-copy", 157 "version": "1.1 1.1",374 "version": "1.13.4", 158 375 "source": { 159 376 "type": "git", 160 377 "url": "https://github.com/myclabs/DeepCopy.git", 161 "reference": " 7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"162 }, 163 "dist": { 164 "type": "zip", 165 "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/ 7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",166 "reference": " 7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",378 "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" 379 }, 380 "dist": { 381 "type": "zip", 382 "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", 383 "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", 167 384 "shasum": "" 168 385 }, … … 172 389 "conflict": { 173 390 "doctrine/collections": "<1.6.8", 174 "doctrine/common": "<2.13.3 || >=3 ,<3.2.2"391 "doctrine/common": "<2.13.3 || >=3 <3.2.2" 175 392 }, 176 393 "require-dev": { 177 394 "doctrine/collections": "^1.6.8", 178 395 "doctrine/common": "^2.13.3 || ^3.2.2", 396 "phpspec/prophecy": "^1.10", 179 397 "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" 180 398 }, … … 202 420 "support": { 203 421 "issues": "https://github.com/myclabs/DeepCopy/issues", 204 "source": "https://github.com/myclabs/DeepCopy/tree/1.1 1.1"422 "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" 205 423 }, 206 424 "funding": [ … … 210 428 } 211 429 ], 212 "time": "202 3-03-08T13:26:56+00:00"430 "time": "2025-08-01T08:46:24+00:00" 213 431 }, 214 432 { 215 433 "name": "nikic/php-parser", 216 "version": "v 4.16.0",434 "version": "v5.6.1", 217 435 "source": { 218 436 "type": "git", 219 437 "url": "https://github.com/nikic/PHP-Parser.git", 220 "reference": "19526a33fb561ef417e822e85f08a00db4059c17" 221 }, 222 "dist": { 223 "type": "zip", 224 "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", 225 "reference": "19526a33fb561ef417e822e85f08a00db4059c17", 226 "shasum": "" 227 }, 228 "require": { 438 "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" 439 }, 440 "dist": { 441 "type": "zip", 442 "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", 443 "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", 444 "shasum": "" 445 }, 446 "require": { 447 "ext-ctype": "*", 448 "ext-json": "*", 229 449 "ext-tokenizer": "*", 230 "php": ">=7. 0"450 "php": ">=7.4" 231 451 }, 232 452 "require-dev": { 233 453 "ircmaxell/php-yacc": "^0.0.7", 234 "phpunit/phpunit": "^ 6.5 || ^7.0 || ^8.0 || ^9.0"454 "phpunit/phpunit": "^9.0" 235 455 }, 236 456 "bin": [ … … 240 460 "extra": { 241 461 "branch-alias": { 242 "dev-master": " 4.9-dev"462 "dev-master": "5.x-dev" 243 463 } 244 464 }, … … 264 484 "support": { 265 485 "issues": "https://github.com/nikic/PHP-Parser/issues", 266 "source": "https://github.com/nikic/PHP-Parser/tree/v 4.16.0"267 }, 268 "time": "202 3-06-25T14:52:30+00:00"486 "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" 487 }, 488 "time": "2025-08-13T20:13:15+00:00" 269 489 }, 270 490 { 271 491 "name": "phar-io/manifest", 272 "version": "2.0. 3",492 "version": "2.0.4", 273 493 "source": { 274 494 "type": "git", 275 495 "url": "https://github.com/phar-io/manifest.git", 276 "reference": " 97803eca37d319dfa7826cc2437fc020857acb53"277 }, 278 "dist": { 279 "type": "zip", 280 "url": "https://api.github.com/repos/phar-io/manifest/zipball/ 97803eca37d319dfa7826cc2437fc020857acb53",281 "reference": " 97803eca37d319dfa7826cc2437fc020857acb53",496 "reference": "54750ef60c58e43759730615a392c31c80e23176" 497 }, 498 "dist": { 499 "type": "zip", 500 "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", 501 "reference": "54750ef60c58e43759730615a392c31c80e23176", 282 502 "shasum": "" 283 503 }, 284 504 "require": { 285 505 "ext-dom": "*", 506 "ext-libxml": "*", 286 507 "ext-phar": "*", 287 508 "ext-xmlwriter": "*", … … 324 545 "support": { 325 546 "issues": "https://github.com/phar-io/manifest/issues", 326 "source": "https://github.com/phar-io/manifest/tree/2.0.3" 327 }, 328 "time": "2021-07-20T11:28:43+00:00" 547 "source": "https://github.com/phar-io/manifest/tree/2.0.4" 548 }, 549 "funding": [ 550 { 551 "url": "https://github.com/theseer", 552 "type": "github" 553 } 554 ], 555 "time": "2024-03-03T12:33:53+00:00" 329 556 }, 330 557 { … … 443 670 { 444 671 "name": "phpunit/php-code-coverage", 445 "version": "9.2. 26",672 "version": "9.2.32", 446 673 "source": { 447 674 "type": "git", 448 675 "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 449 "reference": " 443bc6912c9bd5b409254a40f4b0f4ced7c80ea1"450 }, 451 "dist": { 452 "type": "zip", 453 "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ 443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",454 "reference": " 443bc6912c9bd5b409254a40f4b0f4ced7c80ea1",676 "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" 677 }, 678 "dist": { 679 "type": "zip", 680 "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", 681 "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", 455 682 "shasum": "" 456 683 }, … … 459 686 "ext-libxml": "*", 460 687 "ext-xmlwriter": "*", 461 "nikic/php-parser": "^4.1 5",688 "nikic/php-parser": "^4.19.1 || ^5.1.0", 462 689 "php": ">=7.3", 463 "phpunit/php-file-iterator": "^3.0. 3",464 "phpunit/php-text-template": "^2.0. 2",465 "sebastian/code-unit-reverse-lookup": "^2.0. 2",466 "sebastian/complexity": "^2.0 ",467 "sebastian/environment": "^5.1. 2",468 "sebastian/lines-of-code": "^1.0. 3",469 "sebastian/version": "^3.0. 1",470 "theseer/tokenizer": "^1.2. 0"471 }, 472 "require-dev": { 473 "phpunit/phpunit": "^9. 3"690 "phpunit/php-file-iterator": "^3.0.6", 691 "phpunit/php-text-template": "^2.0.4", 692 "sebastian/code-unit-reverse-lookup": "^2.0.3", 693 "sebastian/complexity": "^2.0.3", 694 "sebastian/environment": "^5.1.5", 695 "sebastian/lines-of-code": "^1.0.4", 696 "sebastian/version": "^3.0.2", 697 "theseer/tokenizer": "^1.2.3" 698 }, 699 "require-dev": { 700 "phpunit/phpunit": "^9.6" 474 701 }, 475 702 "suggest": { … … 480 707 "extra": { 481 708 "branch-alias": { 482 "dev-ma ster": "9.2-dev"709 "dev-main": "9.2.x-dev" 483 710 } 484 711 }, … … 508 735 "support": { 509 736 "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", 510 "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" 737 "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", 738 "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" 511 739 }, 512 740 "funding": [ … … 516 744 } 517 745 ], 518 "time": "202 3-03-06T12:58:08+00:00"746 "time": "2024-08-22T04:23:01+00:00" 519 747 }, 520 748 { … … 761 989 { 762 990 "name": "phpunit/phpunit", 763 "version": "9.6. 10",991 "version": "9.6.24", 764 992 "source": { 765 993 "type": "git", 766 994 "url": "https://github.com/sebastianbergmann/phpunit.git", 767 "reference": " a6d351645c3fe5a30f5e86be6577d946af65a328"768 }, 769 "dist": { 770 "type": "zip", 771 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ a6d351645c3fe5a30f5e86be6577d946af65a328",772 "reference": " a6d351645c3fe5a30f5e86be6577d946af65a328",773 "shasum": "" 774 }, 775 "require": { 776 "doctrine/instantiator": "^1. 3.1|| ^2",995 "reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701" 996 }, 997 "dist": { 998 "type": "zip", 999 "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea49afa29aeea25ea7bf9de9fdd7cab163cc0701", 1000 "reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701", 1001 "shasum": "" 1002 }, 1003 "require": { 1004 "doctrine/instantiator": "^1.5.0 || ^2", 777 1005 "ext-dom": "*", 778 1006 "ext-json": "*", … … 781 1009 "ext-xml": "*", 782 1010 "ext-xmlwriter": "*", 783 "myclabs/deep-copy": "^1.1 0.1",784 "phar-io/manifest": "^2.0. 3",785 "phar-io/version": "^3. 0.2",1011 "myclabs/deep-copy": "^1.13.4", 1012 "phar-io/manifest": "^2.0.4", 1013 "phar-io/version": "^3.2.1", 786 1014 "php": ">=7.3", 787 "phpunit/php-code-coverage": "^9.2. 13",788 "phpunit/php-file-iterator": "^3.0. 5",1015 "phpunit/php-code-coverage": "^9.2.32", 1016 "phpunit/php-file-iterator": "^3.0.6", 789 1017 "phpunit/php-invoker": "^3.1.1", 790 "phpunit/php-text-template": "^2.0. 3",791 "phpunit/php-timer": "^5.0. 2",792 "sebastian/cli-parser": "^1.0. 1",793 "sebastian/code-unit": "^1.0. 6",794 "sebastian/comparator": "^4.0. 8",795 "sebastian/diff": "^4.0. 3",796 "sebastian/environment": "^5.1. 3",797 "sebastian/exporter": "^4.0. 5",798 "sebastian/global-state": "^5.0. 1",799 "sebastian/object-enumerator": "^4.0. 3",800 "sebastian/resource-operations": "^3.0. 3",801 "sebastian/type": "^3.2 ",1018 "phpunit/php-text-template": "^2.0.4", 1019 "phpunit/php-timer": "^5.0.3", 1020 "sebastian/cli-parser": "^1.0.2", 1021 "sebastian/code-unit": "^1.0.8", 1022 "sebastian/comparator": "^4.0.9", 1023 "sebastian/diff": "^4.0.6", 1024 "sebastian/environment": "^5.1.5", 1025 "sebastian/exporter": "^4.0.6", 1026 "sebastian/global-state": "^5.0.8", 1027 "sebastian/object-enumerator": "^4.0.4", 1028 "sebastian/resource-operations": "^3.0.4", 1029 "sebastian/type": "^3.2.1", 802 1030 "sebastian/version": "^3.0.2" 803 1031 }, … … 844 1072 "issues": "https://github.com/sebastianbergmann/phpunit/issues", 845 1073 "security": "https://github.com/sebastianbergmann/phpunit/security/policy", 846 "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6. 10"1074 "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.24" 847 1075 }, 848 1076 "funding": [ … … 856 1084 }, 857 1085 { 1086 "url": "https://liberapay.com/sebastianbergmann", 1087 "type": "liberapay" 1088 }, 1089 { 1090 "url": "https://thanks.dev/u/gh/sebastianbergmann", 1091 "type": "thanks_dev" 1092 }, 1093 { 858 1094 "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", 859 1095 "type": "tidelift" 860 1096 } 861 1097 ], 862 "time": "202 3-07-10T04:04:23+00:00"1098 "time": "2025-08-10T08:32:42+00:00" 863 1099 }, 864 1100 { 865 1101 "name": "sebastian/cli-parser", 866 "version": "1.0. 1",1102 "version": "1.0.2", 867 1103 "source": { 868 1104 "type": "git", 869 1105 "url": "https://github.com/sebastianbergmann/cli-parser.git", 870 "reference": " 442e7c7e687e42adc03470c7b668bc4b2402c0b2"871 }, 872 "dist": { 873 "type": "zip", 874 "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/ 442e7c7e687e42adc03470c7b668bc4b2402c0b2",875 "reference": " 442e7c7e687e42adc03470c7b668bc4b2402c0b2",1106 "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" 1107 }, 1108 "dist": { 1109 "type": "zip", 1110 "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", 1111 "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", 876 1112 "shasum": "" 877 1113 }, … … 908 1144 "support": { 909 1145 "issues": "https://github.com/sebastianbergmann/cli-parser/issues", 910 "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0. 1"1146 "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" 911 1147 }, 912 1148 "funding": [ … … 916 1152 } 917 1153 ], 918 "time": "202 0-09-28T06:08:49+00:00"1154 "time": "2024-03-02T06:27:43+00:00" 919 1155 }, 920 1156 { … … 1031 1267 { 1032 1268 "name": "sebastian/comparator", 1033 "version": "4.0. 8",1269 "version": "4.0.9", 1034 1270 "source": { 1035 1271 "type": "git", 1036 1272 "url": "https://github.com/sebastianbergmann/comparator.git", 1037 "reference": " fa0f136dd2334583309d32b62544682ee972b51a"1038 }, 1039 "dist": { 1040 "type": "zip", 1041 "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ fa0f136dd2334583309d32b62544682ee972b51a",1042 "reference": " fa0f136dd2334583309d32b62544682ee972b51a",1273 "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5" 1274 }, 1275 "dist": { 1276 "type": "zip", 1277 "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5", 1278 "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5", 1043 1279 "shasum": "" 1044 1280 }, … … 1093 1329 "support": { 1094 1330 "issues": "https://github.com/sebastianbergmann/comparator/issues", 1095 "source": "https://github.com/sebastianbergmann/comparator/tree/4.0. 8"1331 "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9" 1096 1332 }, 1097 1333 "funding": [ … … 1099 1335 "url": "https://github.com/sebastianbergmann", 1100 1336 "type": "github" 1101 } 1102 ], 1103 "time": "2022-09-14T12:41:17+00:00" 1337 }, 1338 { 1339 "url": "https://liberapay.com/sebastianbergmann", 1340 "type": "liberapay" 1341 }, 1342 { 1343 "url": "https://thanks.dev/u/gh/sebastianbergmann", 1344 "type": "thanks_dev" 1345 }, 1346 { 1347 "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", 1348 "type": "tidelift" 1349 } 1350 ], 1351 "time": "2025-08-10T06:51:50+00:00" 1104 1352 }, 1105 1353 { 1106 1354 "name": "sebastian/complexity", 1107 "version": "2.0. 2",1355 "version": "2.0.3", 1108 1356 "source": { 1109 1357 "type": "git", 1110 1358 "url": "https://github.com/sebastianbergmann/complexity.git", 1111 "reference": " 739b35e53379900cc9ac327b2147867b8b6efd88"1112 }, 1113 "dist": { 1114 "type": "zip", 1115 "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ 739b35e53379900cc9ac327b2147867b8b6efd88",1116 "reference": " 739b35e53379900cc9ac327b2147867b8b6efd88",1117 "shasum": "" 1118 }, 1119 "require": { 1120 "nikic/php-parser": "^4. 7",1359 "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" 1360 }, 1361 "dist": { 1362 "type": "zip", 1363 "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", 1364 "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", 1365 "shasum": "" 1366 }, 1367 "require": { 1368 "nikic/php-parser": "^4.18 || ^5.0", 1121 1369 "php": ">=7.3" 1122 1370 }, … … 1150 1398 "support": { 1151 1399 "issues": "https://github.com/sebastianbergmann/complexity/issues", 1152 "source": "https://github.com/sebastianbergmann/complexity/tree/2.0. 2"1400 "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" 1153 1401 }, 1154 1402 "funding": [ … … 1158 1406 } 1159 1407 ], 1160 "time": "202 0-10-26T15:52:27+00:00"1408 "time": "2023-12-22T06:19:30+00:00" 1161 1409 }, 1162 1410 { 1163 1411 "name": "sebastian/diff", 1164 "version": "4.0. 5",1412 "version": "4.0.6", 1165 1413 "source": { 1166 1414 "type": "git", 1167 1415 "url": "https://github.com/sebastianbergmann/diff.git", 1168 "reference": " 74be17022044ebaaecfdf0c5cd504fc9cd5a7131"1169 }, 1170 "dist": { 1171 "type": "zip", 1172 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ 74be17022044ebaaecfdf0c5cd504fc9cd5a7131",1173 "reference": " 74be17022044ebaaecfdf0c5cd504fc9cd5a7131",1416 "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" 1417 }, 1418 "dist": { 1419 "type": "zip", 1420 "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", 1421 "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", 1174 1422 "shasum": "" 1175 1423 }, … … 1216 1464 "support": { 1217 1465 "issues": "https://github.com/sebastianbergmann/diff/issues", 1218 "source": "https://github.com/sebastianbergmann/diff/tree/4.0. 5"1466 "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" 1219 1467 }, 1220 1468 "funding": [ … … 1224 1472 } 1225 1473 ], 1226 "time": "202 3-05-07T05:35:17+00:00"1474 "time": "2024-03-02T06:30:58+00:00" 1227 1475 }, 1228 1476 { … … 1291 1539 { 1292 1540 "name": "sebastian/exporter", 1293 "version": "4.0. 5",1541 "version": "4.0.6", 1294 1542 "source": { 1295 1543 "type": "git", 1296 1544 "url": "https://github.com/sebastianbergmann/exporter.git", 1297 "reference": " ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d"1298 }, 1299 "dist": { 1300 "type": "zip", 1301 "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",1302 "reference": " ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d",1545 "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" 1546 }, 1547 "dist": { 1548 "type": "zip", 1549 "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", 1550 "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", 1303 1551 "shasum": "" 1304 1552 }, … … 1356 1604 "support": { 1357 1605 "issues": "https://github.com/sebastianbergmann/exporter/issues", 1358 "source": "https://github.com/sebastianbergmann/exporter/tree/4.0. 5"1606 "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" 1359 1607 }, 1360 1608 "funding": [ … … 1364 1612 } 1365 1613 ], 1366 "time": "202 2-09-14T06:03:37+00:00"1614 "time": "2024-03-02T06:33:00+00:00" 1367 1615 }, 1368 1616 { 1369 1617 "name": "sebastian/global-state", 1370 "version": "5.0. 5",1618 "version": "5.0.8", 1371 1619 "source": { 1372 1620 "type": "git", 1373 1621 "url": "https://github.com/sebastianbergmann/global-state.git", 1374 "reference": " 0ca8db5a5fc9c8646244e629625ac486fa286bf2"1375 }, 1376 "dist": { 1377 "type": "zip", 1378 "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ 0ca8db5a5fc9c8646244e629625ac486fa286bf2",1379 "reference": " 0ca8db5a5fc9c8646244e629625ac486fa286bf2",1622 "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6" 1623 }, 1624 "dist": { 1625 "type": "zip", 1626 "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6", 1627 "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6", 1380 1628 "shasum": "" 1381 1629 }, … … 1420 1668 "support": { 1421 1669 "issues": "https://github.com/sebastianbergmann/global-state/issues", 1422 "source": "https://github.com/sebastianbergmann/global-state/tree/5.0. 5"1670 "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8" 1423 1671 }, 1424 1672 "funding": [ … … 1426 1674 "url": "https://github.com/sebastianbergmann", 1427 1675 "type": "github" 1428 } 1429 ], 1430 "time": "2022-02-14T08:28:10+00:00" 1676 }, 1677 { 1678 "url": "https://liberapay.com/sebastianbergmann", 1679 "type": "liberapay" 1680 }, 1681 { 1682 "url": "https://thanks.dev/u/gh/sebastianbergmann", 1683 "type": "thanks_dev" 1684 }, 1685 { 1686 "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", 1687 "type": "tidelift" 1688 } 1689 ], 1690 "time": "2025-08-10T07:10:35+00:00" 1431 1691 }, 1432 1692 { 1433 1693 "name": "sebastian/lines-of-code", 1434 "version": "1.0. 3",1694 "version": "1.0.4", 1435 1695 "source": { 1436 1696 "type": "git", 1437 1697 "url": "https://github.com/sebastianbergmann/lines-of-code.git", 1438 "reference": " c1c2e997aa3146983ed888ad08b15470a2e22ecc"1439 }, 1440 "dist": { 1441 "type": "zip", 1442 "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/ c1c2e997aa3146983ed888ad08b15470a2e22ecc",1443 "reference": " c1c2e997aa3146983ed888ad08b15470a2e22ecc",1444 "shasum": "" 1445 }, 1446 "require": { 1447 "nikic/php-parser": "^4. 6",1698 "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" 1699 }, 1700 "dist": { 1701 "type": "zip", 1702 "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", 1703 "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", 1704 "shasum": "" 1705 }, 1706 "require": { 1707 "nikic/php-parser": "^4.18 || ^5.0", 1448 1708 "php": ">=7.3" 1449 1709 }, … … 1477 1737 "support": { 1478 1738 "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", 1479 "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0. 3"1739 "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" 1480 1740 }, 1481 1741 "funding": [ … … 1485 1745 } 1486 1746 ], 1487 "time": "202 0-11-28T06:42:11+00:00"1747 "time": "2023-12-22T06:20:34+00:00" 1488 1748 }, 1489 1749 { … … 1601 1861 { 1602 1862 "name": "sebastian/recursion-context", 1603 "version": "4.0. 5",1863 "version": "4.0.6", 1604 1864 "source": { 1605 1865 "type": "git", 1606 1866 "url": "https://github.com/sebastianbergmann/recursion-context.git", 1607 "reference": " e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"1608 }, 1609 "dist": { 1610 "type": "zip", 1611 "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/ e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",1612 "reference": " e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",1867 "reference": "539c6691e0623af6dc6f9c20384c120f963465a0" 1868 }, 1869 "dist": { 1870 "type": "zip", 1871 "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0", 1872 "reference": "539c6691e0623af6dc6f9c20384c120f963465a0", 1613 1873 "shasum": "" 1614 1874 }, … … 1652 1912 "support": { 1653 1913 "issues": "https://github.com/sebastianbergmann/recursion-context/issues", 1654 "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0. 5"1914 "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6" 1655 1915 }, 1656 1916 "funding": [ … … 1658 1918 "url": "https://github.com/sebastianbergmann", 1659 1919 "type": "github" 1660 } 1661 ], 1662 "time": "2023-02-03T06:07:39+00:00" 1920 }, 1921 { 1922 "url": "https://liberapay.com/sebastianbergmann", 1923 "type": "liberapay" 1924 }, 1925 { 1926 "url": "https://thanks.dev/u/gh/sebastianbergmann", 1927 "type": "thanks_dev" 1928 }, 1929 { 1930 "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", 1931 "type": "tidelift" 1932 } 1933 ], 1934 "time": "2025-08-10T06:57:39+00:00" 1663 1935 }, 1664 1936 { 1665 1937 "name": "sebastian/resource-operations", 1666 "version": "3.0. 3",1938 "version": "3.0.4", 1667 1939 "source": { 1668 1940 "type": "git", 1669 1941 "url": "https://github.com/sebastianbergmann/resource-operations.git", 1670 "reference": "0 f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"1671 }, 1672 "dist": { 1673 "type": "zip", 1674 "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0 f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",1675 "reference": "0 f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",1942 "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" 1943 }, 1944 "dist": { 1945 "type": "zip", 1946 "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", 1947 "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", 1676 1948 "shasum": "" 1677 1949 }, … … 1685 1957 "extra": { 1686 1958 "branch-alias": { 1687 "dev-ma ster": "3.0-dev"1959 "dev-main": "3.0-dev" 1688 1960 } 1689 1961 }, … … 1706 1978 "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1707 1979 "support": { 1708 "issues": "https://github.com/sebastianbergmann/resource-operations/issues", 1709 "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" 1980 "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" 1710 1981 }, 1711 1982 "funding": [ … … 1715 1986 } 1716 1987 ], 1717 "time": "202 0-09-28T06:45:17+00:00"1988 "time": "2024-03-14T16:00:52+00:00" 1718 1989 }, 1719 1990 { … … 1828 2099 { 1829 2100 "name": "sirbrillig/phpcs-variable-analysis", 1830 "version": "v2.1 1.16",2101 "version": "v2.12.0", 1831 2102 "source": { 1832 2103 "type": "git", 1833 2104 "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", 1834 "reference": " dc5582dc5a93a235557af73e523c389aac9a8e88"1835 }, 1836 "dist": { 1837 "type": "zip", 1838 "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/ dc5582dc5a93a235557af73e523c389aac9a8e88",1839 "reference": " dc5582dc5a93a235557af73e523c389aac9a8e88",2105 "reference": "4debf5383d9ade705e0a25121f16c3fecaf433a7" 2106 }, 2107 "dist": { 2108 "type": "zip", 2109 "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/4debf5383d9ade705e0a25121f16c3fecaf433a7", 2110 "reference": "4debf5383d9ade705e0a25121f16c3fecaf433a7", 1840 2111 "shasum": "" 1841 2112 }, … … 1848 2119 "phpcsstandards/phpcsdevcs": "^1.1", 1849 2120 "phpstan/phpstan": "^1.7", 1850 "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.5 || ^7.0 || ^8.0 || ^9.0", 1851 "sirbrillig/phpcs-import-detection": "^1.1", 1852 "vimeo/psalm": "^0.2 || ^0.3 || ^1.1 || ^4.24 || ^5.0@beta" 2121 "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.5 || ^7.0 || ^8.0 || ^9.0 || ^10.5.32 || ^11.3.3", 2122 "vimeo/psalm": "^0.2 || ^0.3 || ^1.1 || ^4.24 || ^5.0" 1853 2123 }, 1854 2124 "type": "phpcodesniffer-standard", … … 1882 2152 "wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki" 1883 2153 }, 1884 "time": "202 3-03-31T16:46:32+00:00"2154 "time": "2025-03-17T16:17:38+00:00" 1885 2155 }, 1886 2156 { 1887 2157 "name": "squizlabs/php_codesniffer", 1888 "version": "3. 7.2",1889 "source": { 1890 "type": "git", 1891 "url": "https://github.com/ squizlabs/PHP_CodeSniffer.git",1892 "reference": " ed8e00df0a83aa96acf703f8c2979ff33341f879"1893 }, 1894 "dist": { 1895 "type": "zip", 1896 "url": "https://api.github.com/repos/ squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",1897 "reference": " ed8e00df0a83aa96acf703f8c2979ff33341f879",2158 "version": "3.13.2", 2159 "source": { 2160 "type": "git", 2161 "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", 2162 "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" 2163 }, 2164 "dist": { 2165 "type": "zip", 2166 "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", 2167 "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", 1898 2168 "shasum": "" 1899 2169 }, … … 1905 2175 }, 1906 2176 "require-dev": { 1907 "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 "2177 "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" 1908 2178 }, 1909 2179 "bin": [ 1910 "bin/phpc s",1911 "bin/phpc bf"2180 "bin/phpcbf", 2181 "bin/phpcs" 1912 2182 ], 1913 2183 "type": "library", … … 1924 2194 { 1925 2195 "name": "Greg Sherwood", 1926 "role": "lead" 2196 "role": "Former lead" 2197 }, 2198 { 2199 "name": "Juliette Reinders Folmer", 2200 "role": "Current lead" 2201 }, 2202 { 2203 "name": "Contributors", 2204 "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" 1927 2205 } 1928 2206 ], 1929 2207 "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", 1930 "homepage": "https://github.com/ squizlabs/PHP_CodeSniffer",2208 "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", 1931 2209 "keywords": [ 1932 2210 "phpcs", … … 1935 2213 ], 1936 2214 "support": { 1937 "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", 1938 "source": "https://github.com/squizlabs/PHP_CodeSniffer", 1939 "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" 1940 }, 1941 "time": "2023-02-22T23:07:41+00:00" 2215 "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", 2216 "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", 2217 "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", 2218 "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" 2219 }, 2220 "funding": [ 2221 { 2222 "url": "https://github.com/PHPCSStandards", 2223 "type": "github" 2224 }, 2225 { 2226 "url": "https://github.com/jrfnl", 2227 "type": "github" 2228 }, 2229 { 2230 "url": "https://opencollective.com/php_codesniffer", 2231 "type": "open_collective" 2232 }, 2233 { 2234 "url": "https://thanks.dev/u/gh/phpcsstandards", 2235 "type": "thanks_dev" 2236 } 2237 ], 2238 "time": "2025-06-17T22:17:01+00:00" 1942 2239 }, 1943 2240 { 1944 2241 "name": "theseer/tokenizer", 1945 "version": "1.2. 1",2242 "version": "1.2.3", 1946 2243 "source": { 1947 2244 "type": "git", 1948 2245 "url": "https://github.com/theseer/tokenizer.git", 1949 "reference": " 34a41e998c2183e22995f158c581e7b5e755ab9e"1950 }, 1951 "dist": { 1952 "type": "zip", 1953 "url": "https://api.github.com/repos/theseer/tokenizer/zipball/ 34a41e998c2183e22995f158c581e7b5e755ab9e",1954 "reference": " 34a41e998c2183e22995f158c581e7b5e755ab9e",2246 "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" 2247 }, 2248 "dist": { 2249 "type": "zip", 2250 "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", 2251 "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", 1955 2252 "shasum": "" 1956 2253 }, … … 1981 2278 "support": { 1982 2279 "issues": "https://github.com/theseer/tokenizer/issues", 1983 "source": "https://github.com/theseer/tokenizer/tree/1.2. 1"2280 "source": "https://github.com/theseer/tokenizer/tree/1.2.3" 1984 2281 }, 1985 2282 "funding": [ … … 1989 2286 } 1990 2287 ], 1991 "time": "202 1-07-28T10:34:58+00:00"2288 "time": "2024-03-03T12:36:25+00:00" 1992 2289 }, 1993 2290 { … … 2044 2341 { 2045 2342 "name": "yoast/phpunit-polyfills", 2046 "version": " 2.0.0",2343 "version": "4.0.0", 2047 2344 "source": { 2048 2345 "type": "git", 2049 2346 "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", 2050 "reference": "c758753e8f9dac251fed396a73c8305af3f17922" 2051 }, 2052 "dist": { 2053 "type": "zip", 2054 "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/c758753e8f9dac251fed396a73c8305af3f17922", 2055 "reference": "c758753e8f9dac251fed396a73c8305af3f17922", 2056 "shasum": "" 2057 }, 2058 "require": { 2059 "php": ">=5.6", 2060 "phpunit/phpunit": "^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0" 2061 }, 2062 "require-dev": { 2063 "yoast/yoastcs": "^2.3.0" 2064 }, 2065 "type": "library", 2066 "extra": { 2067 "branch-alias": { 2068 "dev-main": "2.x-dev" 2347 "reference": "134921bfca9b02d8f374c48381451da1d98402f9" 2348 }, 2349 "dist": { 2350 "type": "zip", 2351 "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/134921bfca9b02d8f374c48381451da1d98402f9", 2352 "reference": "134921bfca9b02d8f374c48381451da1d98402f9", 2353 "shasum": "" 2354 }, 2355 "require": { 2356 "php": ">=7.1", 2357 "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0 || ^11.0 || ^12.0" 2358 }, 2359 "require-dev": { 2360 "php-parallel-lint/php-console-highlighter": "^1.0.0", 2361 "php-parallel-lint/php-parallel-lint": "^1.4.0", 2362 "yoast/yoastcs": "^3.1.0" 2363 }, 2364 "type": "library", 2365 "extra": { 2366 "branch-alias": { 2367 "dev-main": "4.x-dev" 2069 2368 } 2070 2369 }, … … 2098 2397 "support": { 2099 2398 "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", 2399 "security": "https://github.com/Yoast/PHPUnit-Polyfills/security/policy", 2100 2400 "source": "https://github.com/Yoast/PHPUnit-Polyfills" 2101 2401 }, 2102 "time": "202 3-06-06T20:28:24+00:00"2402 "time": "2025-02-09T18:58:54+00:00" 2103 2403 } 2104 2404 ], 2105 2405 "aliases": [], 2106 2406 "minimum-stability": "stable", 2107 "stability-flags": [],2407 "stability-flags": {}, 2108 2408 "prefer-stable": false, 2109 2409 "prefer-lowest": false, 2110 "platform": [], 2111 "platform-dev": [], 2112 "plugin-api-version": "2.3.0" 2410 "platform": { 2411 "php": "^8.1" 2412 }, 2413 "platform-dev": {}, 2414 "plugin-api-version": "2.6.0" 2113 2415 } -
rollbar/trunk/mu-plugin/rollbar-mu-plugin.php
r2034564 r3380353 2 2 3 3 /** 4 * Plugin Name: Rollbar PHP Word press Must Use Plugin4 * Plugin Name: Rollbar PHP WordPress Must Use Plugin 5 5 * Plugin URI: https://github.com/rollbar/rollbar-php-wordpress 6 * Description: "Must-use" proxy plugin for Rollbar PHP Word press.7 * Author: Rollbar8 * Author URI: https://rollbar.com6 * Description: "Must-use" proxy plugin for Rollbar PHP WordPress. 7 * Author: Rollbar 8 * Author URI: https://rollbar.com 9 9 */ 10 11 $rollbar_plugin = __DIR__ . '/../plugins/rollbar/rollbar-php-wordpress.php';12 10 13 if ( ! file_exists( $rollbar_plugin ) ) { 14 return; 11 $rollbar_plugin = __DIR__ . '/../plugins/rollbar/rollbar.php'; 12 13 if (!file_exists($rollbar_plugin)) { 14 return; 15 15 } 16 16 -
rollbar/trunk/readme.txt
r2966780 r3380353 1 1 === Rollbar === 2 Contributors: arturmoczulski, jorbin 2 Contributors: arturmoczulski, jorbin, danielmorell 3 3 Tags: rollbar, full stack, error, tracking, error tracking, error reporting, reporting, debug 4 Requires at least: 4.4.0 5 Tested up to: 6.3.1 6 Stable tag: 2.7.1 4 Requires at least: 6.5.0 5 Tested up to: 6.8 6 Requires PHP: 8.1 7 Stable tag: 3.0.0 7 8 License: GPLv2 or later 8 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 11 12 12 13 == Description == 14 13 15 Rollbar collects errors that happen in your application, notifies you, and analyzes them so you can debug and fix them. 14 15 16 This plugin integrates Rollbar into your WordPress installation. 16 17 17 Find out [how Rollbar can help you decrease development and maintenance costs](https://rollbar.com/features/).18 19 See [real companies improving their development workflow thanks to Rollbar](https://rollbar.com/customers/).20 21 18 = Features = 22 19 23 * PHP & Java script error logging24 * Define an environment for each single WordPress installation or Multisite blog 25 * Specify your desired logging level 20 * PHP & JavaScript error logging. 21 * Define an environment for each single WordPress installation or Multisite blog. 22 * Specify your desired logging level. 26 23 * Regular updates and improvements! 27 24 28 > <strong>Please note</strong><br> 29 >In order to use this plugin, a [Rollbar account](https://rollbar.com/) is required.25 **Please note:** 26 In order to use this plugin, a [Rollbar account](https://rollbar.com/) is required. 30 27 31 28 = Support = 32 29 33 * Browse [issue tracker](https://github.com/rollbar/rollbar-php-wordpress/issues) on GitHub and report new issues 34 * If you run into any issues, please email us at [support@rollbar.com](mailto:support@rollbar.com) 30 * Browse [issue tracker](https://github.com/rollbar/rollbar-php-wordpress/issues) on GitHub and report new issues. 31 * If you run into any issues, please email us at [support@rollbar.com](mailto:support@rollbar.com). 35 32 * For bug reports, please [open an issue on GitHub](https://github.com/rollbar/rollbar-php-wordpress/issues/new). 36 33 … … 47 44 The installation and configuration of the plugin are as simple as it can be. 48 45 49 = Through [WordPress Plugin directory](https://wordpress.org/plugins/rollbar/) = 50 51 The easiest way to install the plugin is from the WordPress Plugin directory. If you have an existing WordPress installation and you want to add Rollbar: 46 = Through WordPress Plugin directory = 47 48 The easiest way to install the plugin is from the WordPress Plugin directory. If you have an existing WordPress 49 installation, and you want to add Rollbar: 52 50 53 51 1. In your WordPress administration panel go to `Plugins` → `Add New`. 54 52 2. Search for "Rollbar" and find `Rollbar` by Rollbar in the search results. 55 53 3. Click `Install Now` next to the `Rollbar` plugin. 56 4. In `Plugins` → `Installed plugins` find `Rollbar` and click ` activate` underneath.57 5. Log into your [Rollbar account dashboard](https://rollbar.com/login/). 58 6. Go to `Settings` → `Project Access Tokens`. 59 7. Copy the token value under `post_client_item` and `post_server_item`. 60 8. Navigate to `Tools` → `Rollbar`. 61 9. Enable `PHP error logging` and/or `Javascript error logging` depending on your needs.62 10. Paste the tokens you copied in step 7 in `Access Token` section. 63 11. Provide the name of your environment in `Environment`. By default, the environment will be taken from `WP_ENV` environment variable if it's set otherwise it's blank. We recommend to fill this out either with `development` or `production`. 64 12. Pick a minimum logging level. Only errors at that or higher level will be reported. For reference: [PHP Manual: Predefined Error Constants](http://php.net/manual/en/errorfunc.constants.php). 65 13. Click `Save Changes`.66 67 **Warning**: This installation method might not be suitable for complex WordPress projects. The plugin installed this way will be self-contained and include all of the required dependencies for itself and `rollbar/rollbar-php` library. In complex projects, this might lead to version conflicts between dependencies and other plugins/packages. If this is an issue in your project, we recommend the "Advanced" installation method. For more information why this might be important for you, read [Using Composer with WordPress](). 68 69 = Through [wpackagist](https://wpackagist.org/) (if you manage your project with Composer) *recommended* = 70 71 This is a recommended way to install Rollbar plugin for advanced projects. This way ensures the plugin and all of its' dependencies are managed by Composer. 72 73 1. If your WordPress project is not managed with Composer yet, we suggest looking into upgrading your WordPress: [Using Composer with WordPress](). 74 2. In your `composer.json` add `wpackagist-plugin/rollbar` to your `require` section, i.e.: 54 4. In `Plugins` → `Installed plugins` find `Rollbar` and click `Activate` underneath. 55 56 **Warning**: This installation method might not be suitable for complex WordPress projects. The plugin installed this 57 way will be self-contained and include all of the required dependencies for itself and the `rollbar/rollbar-php` 58 library. In complex projects, this might lead to version conflicts between dependencies and other plugins/packages. If 59 this is an issue in your project, we recommend the "Packagist" installation method. 60 61 = Through Packagist = 62 63 *Note: this only works if your WordPress project is managed with Composer. 64 Read [Using Composer with WordPress](https://roots.io/using-composer-with-wordpress/) for more details.* 65 66 This is a recommended way to install the Rollbar plugin for advanced projects. This way ensures the plugin and all of 67 its dependencies are managed by Composer. 68 69 You can install the plugin by running the following command in the root directory of your WordPress project: 70 71 ```txt 72 composer require rollbar/rollbar-php-wordpress:^3.0 75 73 ``` 76 "require": { 77 "php": ">=5.5", 78 ..., 79 "wpackagist-plugin/rollbar": "*" 80 } 74 75 = Through WPackagist = 76 77 *Note: if your WordPress project is managed with Composer, we strongly recommend installing the plugin through 78 Packagist instead.* 79 80 *Installing the plugin from wpackagist.org instead of packagist.org will result in the plugin being managed by 81 Composer. However, the downside is that it's dependencies will not be managed by composer. Instead they will be packaged 82 in the plugin's `vendor` directory not in your project's `vendor` directory. This has the potential to cause name 83 collisions if other plugins or your project use different versions of the same dependencies.* 84 85 To install the plugin from wpackagist.org run the following steps command in the root directory of your WordPress 86 project: 87 88 ```txt 89 composer require wpackagist-plugin/rollbar 81 90 ``` 82 3. Issue command `composer install` in the root directory of your WordPress project. 83 4. In `Plugins` → `Installed plugins` find `Rollbar` and click `Activate` underneath. 84 5. Log into your [Rollbar account dashboard](https://rollbar.com/login/). 85 6. Go to `Settings` → `Project Access Tokens`. 86 7. Copy the token value under `post_client_item` and `post_server_item`. 87 8. Navigate to `Tools` → `Rollbar`. 88 9. Enable `PHP error logging` and/or `Javascript error logging` depending on your needs. 89 10. Paste the tokens you copied in step 7 in `Access Token` section. 90 11. Provide the name of your environment in `Environment`. By default, the environment will be taken from `WP_ENV` environment variable if it's set otherwise it's blank. 91 12. Pick a minimum logging level. Only errors at that or higher level will be reported. For reference: [PHP Manual: Predefined Error Constants](http://php.net/manual/en/errorfunc.constants.php). 92 13. Click `Save Changes`. 91 92 = Configuration = 93 94 The plugin can be configured in the WordPress Admin or programmatically. 95 96 **WordPress Admin** 97 98 The plugin provides a settings page in the WordPress Admin that allows you to configure the plugin. This settings page 99 can be disabled by setting the `ROLLBAR_DISABLE_ADMIN` constant to `true` in your `wp-config.php` file. 100 101 1. In `Plugins` → `Installed plugins` find `Rollbar` and click `Activate` underneath. 102 2. Log into your [Rollbar account dashboard](https://rollbar.com/login/): 103 1. Go to `Settings` → `Project Access Tokens`. 104 2. Copy the token value under `post_client_item` and `post_server_item`. 105 3. In WordPress, navigate to `Settings` → `Rollbar`: 106 1. Enable `PHP error logging` and/or `Javascript error logging` depending on your needs. 107 2. Paste the tokens you copied in step 7 in `Access Token` section. 108 3. Provide the name of your environment in `Environment`. By default, the environment will be taken from `WP_ENV` 109 environment variable if it's set otherwise it's blank. We recommend to fill this out either with `development` or 110 `production`. 111 4. Pick a minimum logging level. Only errors at that or higher level will be reported. For 112 reference: [PHP Manual: Predefined Error Constants](http://php.net/manual/en/errorfunc.constants.php). 113 5. Click `Save Changes`. 114 115 **Programmatic Configuration** 116 117 The plugin can also be configured programmatically. This is useful if you want to configure the plugin in a more 118 advanced way or if you want to disable the admin settings page. 119 120 ```php 121 // wp-config.php 122 123 // Configure the plugin. 124 define( 'ROLLBAR_SETTINGS', [ 125 'php_logging_enabled' => true, 126 'server_side_access_token' => '<your token>', 127 'js_logging_enabled' => true, 128 'client_side_access_token' => '<your client token>', 129 'environment' => 'development', 130 'included_errno' => E_ERROR, 131 'enable_person_reporting' => true, 132 ] ); 133 134 // Optional: disable the admin settings page so the plugin is configured only programmatically. 135 define( 'ROLLBAR_DISABLE_ADMIN', true ); 136 ``` 93 137 94 138 == Frequently Asked Questions == 95 139 96 140 = Multisite supported? = 97 Yes of course. Additionally, you can assign different environments to each of your blogs.141 Yes, of course. Additionally, you can assign different environments to each of your blogs. 98 142 99 143 = I have a complex WordPress project and use composer for managing dependencies. Is your plugin composer friendly? = 100 Yes. It's actually the recommended method of installation. 144 Yes. It's actually the recommended method of installation. You can install the `rollbar/rollbar-php-wordpress` package 145 using composer. 101 146 102 147 == Screenshots == 103 148 104 1. Settings page 149 1. Settings page. 105 150 106 151 == Changelog == 152 153 = Version 3.0.0 (pending) 154 * Fixed CSRF vulnerability. 155 * Removed support for PHP 8.0 and below. 156 * Updated and improved the settings page. 157 * Updated the Rollbar core PHP SDK to v4.1. 158 * Updated the Rollbar core JavaScript SDK to v2.26. 159 * Added support for telemetry and added auto-instrumentation. 160 * Added support for `ROLLBAR_DISABLE_ADMIN` to remove the plugin settings page from the admin. 161 * Added support for `ROLLBAR_SETTINGS` to configure the plugin without the admin page. 162 * Added support for `ROLLBAR_CLIENT_ACCESS_TOKEN` constant or environment variable to set the client access token. 163 * Added support for `WP_PROXY_BYPASS_HOSTS`, `WP_PROXY_USERNAME`, and `WP_PROXY_PASSWORD` for better proxy management. 164 * Added `rollbar_api_admin_permission` filter to allow custom authorization of the admin API. 165 * Added `rollbar_user_can_view_admin` filter to allow custom disabling of the admin page. 166 * Added `rollbar_php_config` filter to allow more exact control over Rollbar PHP configurations. 167 * Added `rollbar_telemetry_actions` filter to allow control of which actions are logged via telemetry. 168 * Added `rollbar_telemetry_custom_handlers` filter to allow custom control over what is logged in telemetry messages. 169 * Added 'framework' details with the WordPress version to the item payload. 107 170 108 171 = Version 2.7.1 (September 13 2023) … … 129 192 130 193 = Version 2.5.1 (February 20th 2019) = 131 * Fixed a call to Rollbar\Word press\Defaults for enableMustUsePlugin (https://github.com/rollbar/rollbar-php-wordpress/pull/75)194 * Fixed a call to Rollbar\WordPress\Defaults for enableMustUsePlugin (https://github.com/rollbar/rollbar-php-wordpress/pull/75) 132 195 133 196 = Version 2.5.0 (February 19th 2019) = … … 172 235 173 236 = Version 2.4.0 (17th May 2018) = 174 * Added capture_ip, capture_email and capture_username to the config options.237 * Added capture_ip, capture_email, and capture_username to the config options. 175 238 * Fixed populating config options from the database to the plugin for boolean values. 176 239 * Updated rollbar-php dependency to v1.5.0 … … 202 265 = Version 2.1.0 (11th October 2017) = 203 266 * Added "Send test message to Rollbar" button 204 * Fixed the plugin's name inconsistency between Word press plugin directory and composer.267 * Fixed the plugin's name inconsistency between WordPress plugin directory and composer. 205 268 206 269 = Version 2.0.1 (6th October 2017) = … … 248 311 249 312 = Version 2.5.1 (February 20th 2019) = 250 * Fixed a call to Rollbar\Word press\Defaults for enableMustUsePlugin (https://github.com/rollbar/rollbar-php-wordpress/pull/75)313 * Fixed a call to Rollbar\WordPress\Defaults for enableMustUsePlugin (https://github.com/rollbar/rollbar-php-wordpress/pull/75) 251 314 252 315 = Version 2.5.0 (February 19th 2019) = … … 291 354 292 355 = Version 2.4.0 (5th April 2018) = 293 * Added capture_ip, capture_email and capture_username to the config options.356 * Added capture_ip, capture_email, and capture_username to the config options. 294 357 * Fixed populating config options from the database to the plugin for boolean values. 295 358 * Updated rollbar-php dependency to v1.5.0 … … 321 384 = Version 2.1.0 (11th October 2017) = 322 385 * Added "Send test message to Rollbar" button 323 * Fixed the plugin's name inconsistency between Word press plugin directory and composer.386 * Fixed the plugin's name inconsistency between WordPress plugin directory and composer. 324 387 325 388 = Version 2.0.1 (6th October 2017) = -
rollbar/trunk/src/Plugin.php
r2966780 r3380353 1 1 <?php 2 3 namespace Rollbar\Wordpress; 4 5 use \Rollbar\Payload\Level as Level; 2 3 namespace Rollbar\WordPress; 4 5 use Exception; 6 use Rollbar\Rollbar; 7 use Rollbar\RollbarJsHelper; 8 use Rollbar\WordPress\Admin\FlashMessages; 9 use Rollbar\WordPress\Admin\SettingsPage; 10 use Rollbar\WordPress\API\AdminAPI; 11 use Rollbar\WordPress\Lib\AbstractSingleton; 12 use Rollbar\WordPress\Settings\SettingType; 13 use Rollbar\WordPress\Telemetry\Listener; 6 14 7 15 // Exit if accessed directly 8 if( !defined( 'ABSPATH' ) ) exit; 9 10 class Plugin { 11 12 const VERSION = "2.7.1"; 13 14 private $config; 15 16 private static $instance; 17 18 private static $pluginOptions = array( 19 'enable_must_use_plugin' 20 ); 21 22 private $settings = null; 23 24 private function __construct() { 25 $this->config = array(); 26 } 27 28 public static function instance() { 29 if( !self::$instance ) { 30 self::$instance = new Plugin(); 31 self::$instance->loadTextdomain(); 32 self::$instance->hooks(); 33 self::$instance->initSettings(); 34 self::$instance->initPhpLogging(); 35 } 36 37 return self::$instance; 38 } 39 40 public static function load() { 41 return Plugin::instance(); 42 } 43 44 public function configure(array $config) { 16 // phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols 17 defined('ABSPATH') || exit; 18 // phpcs:enable 19 20 /** 21 * Class Plugin 22 * 23 * The main plugin engine room. It is responsible for setting up and running the plugin. 24 */ 25 final class Plugin extends AbstractSingleton 26 { 27 public const VERSION = '3.0.0'; 28 29 /** 30 * Configuration array for Rollbar. 31 * 32 * @var array 33 */ 34 private array $config; 35 36 /** 37 * Settings instance for managing plugin configuration 38 * 39 * @var Settings|null 40 */ 41 private Settings|null $settings; 42 43 /** 44 * The telemetry listener instance. 45 * 46 * @var Listener|null 47 */ 48 private Listener|null $listener; 49 50 /** 51 * Initialize the Plugin instance 52 * 53 * Sets up settings, initializes configuration, registers hooks, and starts PHP logging. 54 */ 55 protected function __construct() 56 { 57 $this->settings = Settings::getInstance(); 58 $this->config = []; 59 $this->hooks(); 60 $this->initPhpLogging(); 61 } 62 63 /** 64 * Post-initialization tasks 65 * 66 * Sets up admin views and API after the main initialization is complete. 67 * 68 * @return void 69 */ 70 protected function postInit(): void 71 { 72 // Set up the telemetry listener. 73 if ($this->getSetting('enable_telemetry_listener')) { 74 $this->listener = Listener::getInstance(); 75 } 76 } 77 78 /** 79 * Handles the 'init' action hook. 80 * 81 * @return void 82 */ 83 public function onInit(): void 84 { 85 // Set up admin views and API. 86 SettingsPage::getInstance(); 87 AdminAPI::getInstance(); 88 } 89 90 /** 91 * Updates the plugin configuration 92 * 93 * Merges the provided configuration with the existing one and applies 94 * it to the Rollbar logger if available. 95 * 96 * @param array $config Configuration options to merge with existing config 97 * @return void 98 */ 99 public function configure(array $config): void 100 { 45 101 $this->config = array_merge($this->config, $config); 46 47 if ($logger = \Rollbar\Rollbar::logger()) {102 103 if ($logger = Rollbar::logger()) { 48 104 $logger->configure($this->config); 49 105 } 50 106 } 51 52 private function initSettings() { 53 Settings::init(); 54 } 55 56 public static function getEnvironment() 57 { 58 return ( getenv('WP_ENV') ?: ( defined( 'WP_ENV' ) ? WP_ENV : null ) ); 59 } 60 61 /** 62 * Fetch settings provided in Admin -> Tools -> Rollbar 63 * 64 * @returns array 65 */ 66 private function fetchSettings() { 67 68 $options = $this->settings ?: array(); 69 70 if ($saved_options = get_option( 'rollbar_wp' )) { 71 $options = array_merge($options, $saved_options); 72 } 73 74 if (!isset($options['environment']) || empty($options['environment'])) { 75 76 if ($wpEnv = $this->getEnvironment()) { 77 $options['environment'] = $wpEnv; 78 } 79 80 } 81 82 if (!isset($options['proxy']) || empty($options['proxy'])) { 83 84 if (defined('WP_PROXY_HOST') && defined('WP_PROXY_PORT')) { 85 $options['proxy'] = WP_PROXY_HOST.":". WP_PROXY_PORT; 86 } 87 88 } 89 90 if (!isset($options['server_side_access_token']) || empty($options['server_side_access_token'])) { 91 92 if (defined('ROLLBAR_ACCESS_TOKEN')) { 93 94 $options['server_side_access_token'] = ROLLBAR_ACCESS_TOKEN; 95 96 } else if ($token = getenv('ROLLBAR_ACCESS_TOKEN')) { 97 98 $options['server_side_access_token'] = $token; 99 100 } 101 } 102 103 $settings = array( 104 105 'php_logging_enabled' => (!empty($options['php_logging_enabled'])) ? 1 : 0, 106 107 'js_logging_enabled' => (!empty($options['js_logging_enabled'])) ? 1 : 0, 108 109 'server_side_access_token' => (!empty($options['server_side_access_token'])) ? 110 esc_attr(trim($options['server_side_access_token'])) : 111 '', 112 113 'client_side_access_token' => (!empty($options['client_side_access_token'])) ? 114 trim($options['client_side_access_token']) : 115 '', 116 117 'logging_level' => (!empty($options['logging_level'])) ? 118 esc_attr(trim($options['logging_level'])) : 119 Settings::DEFAULT_LOGGING_LEVEL 120 ); 121 122 foreach (self::listOptions() as $option) { 123 124 // 'access_token' and 'enabled' are different in Wordpress plugin 125 // look for 'server_side_access_token' and 'php_logging_enabled' above 126 if (in_array($option, array('access_token', 'enabled'))) { 127 continue; 128 } 129 130 if (!isset($options[$option])) { 131 $value = $this->getDefaultOption($option); 132 } else { 133 $value = $options[$option]; 134 } 135 136 $settings[$option] = $value; 137 138 } 139 140 $this->settings = \apply_filters('rollbar_plugin_settings', $settings); 141 142 } 143 144 public function setting() { 145 $args = func_get_args(); 146 $setting = $args[0]; 147 if (isset($args[1])) { 148 $value = $args[1]; 149 } 150 151 if (isset($value)) { 152 $this->settings[$setting] = $value; 153 } else { 154 return $this->settings[$setting]; 155 } 156 } 157 158 private function hooks() { 159 \add_action('wp_head', array(&$this, 'initJsLogging')); 160 \add_action('admin_head', array(&$this, 'initJsLogging')); 161 $this->registerTestEndpoint(); 162 } 163 164 private function registerTestEndpoint() { 165 \add_action( 'rest_api_init', function () { 166 \register_rest_route( 167 'rollbar/v1', 168 '/test-php-logging', 169 array( 170 'methods' => 'POST', 171 'callback' => '\Rollbar\Wordpress\Plugin::testPhpLogging', 172 'permission_callback' => '__return_true', 173 'args' => array( 174 'server_side_access_token' => array( 175 'required' => true 176 ), 177 'environment' => array( 178 'required' => true 179 ), 180 'logging_level' => array( 181 'required' => true 182 ) 183 ) 184 ) 185 ); 186 }); 187 } 188 189 public static function testPhpLogging(\WP_REST_Request $request) { 190 191 $plugin = self::instance(); 192 193 foreach(self::listOptions() as $option) { 194 $plugin->settings[$option] = $request->get_param($option); 195 } 196 197 $plugin->settings['server_side_access_token'] = $request->get_param('server_side_access_token'); 198 199 $response = null; 200 201 try { 202 $plugin->initPhpLogging(); 203 204 // in the PHP8 version, $response will be null if we use `log` instead of `report` 205 if ( is_callable( '\Rollbar\Rollbar::report' ) ){ 206 $response = \Rollbar\Rollbar::report( 207 Level::INFO, 208 "Test message from Rollbar Wordpress plugin using PHP: ". 209 "integration with Wordpress successful" 210 ); 211 } else { 212 $response = \Rollbar\Rollbar::log( 213 Level::INFO, 214 "Test message from Rollbar Wordpress plugin using PHP: ". 215 "integration with Wordpress successful" 216 ); 217 } 218 219 220 } catch( \Exception $exception ) { 221 222 return new \WP_REST_Response( 223 array( 224 'message' => $exception->getMessage() 225 ), 226 500 227 ); 228 } 229 230 $info = $response->getInfo(); 231 232 $response = array('code' => $response->getStatus()); 233 if (is_array($info)) { 234 $response = array_merge($response, $info); 235 } else { 236 $response['message'] = $info; 237 } 238 239 return new \WP_REST_Response($response, 200); 240 241 } 242 243 public function loadTextdomain() { 244 \load_plugin_textdomain( 'rollbar', false, dirname( \plugin_basename( __FILE__ ) ) . '/languages/' ); 245 } 246 247 public static function buildIncludedErrno($cutoff) 248 { 249 250 $levels = array( 107 108 /** 109 * Returns true if the admin area should be disabled. 110 * 111 * Disable the admin settings page if the `ROLLBAR_DISABLE_ADMIN` constant is defined and set to `true`. 112 * This allows for the plugin to be used without the admin settings page, for example, if the plugin is managed 113 * via the `wp-config.php` file. 114 * 115 * @return bool 116 * @since 3.0.0 117 */ 118 public static function disabledAdmin(): bool 119 { 120 return defined('ROLLBAR_DISABLE_ADMIN') && constant('ROLLBAR_DISABLE_ADMIN'); 121 } 122 123 /** 124 * Returns true if the admin area should be disabled. 125 * 126 * @return bool 127 * @since 3.0.0 128 */ 129 public static function userCanViewAdmin(): bool 130 { 131 if (self::disabledAdmin()) { 132 return false; 133 } 134 135 /** 136 * Filter to enable / disable the admin settings page of the plugin for the current user. 137 * 138 * This filter cannot override the `ROLLBAR_DISABLE_ADMIN` constant. 139 * 140 * @param bool $allow `true` to enable the admin settings page, `false` to disable it. 141 * @since 3.0.0 142 */ 143 return apply_filters('rollbar_user_can_view_admin', current_user_can('manage_options')) === true; 144 } 145 146 /** 147 * @param string $path 148 * @return string 149 * 150 * @since 3.0.0 151 */ 152 public static function getAssetUrl(string $path): string 153 { 154 if (str_starts_with($path, '/')) { 155 $path = substr($path, 1); 156 } 157 return plugin_dir_url(ROLLBAR_PLUGIN_FILE) . $path; 158 } 159 160 /** 161 * Retrieve the value of a specific setting. 162 * 163 * @param string $setting The name of the setting to retrieve. 164 * @return mixed The value of the setting, or null if the setting does not exist. 165 * 166 * @since 3.0.0 167 */ 168 public function getSetting(string $setting): mixed 169 { 170 return $this->settings->get($setting) ?? null; 171 } 172 173 /** 174 * Sets a specific setting with the provided value. 175 * 176 * @param string $setting The name of the setting to be updated. 177 * @param mixed $value The value to be assigned to the specified setting. 178 * @return void 179 * 180 * @since 3.0.0 181 */ 182 public function setSetting(string $setting, mixed $value): void 183 { 184 $this->settings->set($setting, $value); 185 } 186 187 /** 188 * Get the Settings instance used by this plugin 189 * 190 * @return Settings The settings instance 191 */ 192 public function settingsInstance(): Settings 193 { 194 return $this->settings; 195 } 196 197 /** 198 * Register WordPress hooks and actions 199 * 200 * Sets up action hooks for JavaScript logging in both frontend and admin areas. 201 * 202 * @return void 203 */ 204 private function hooks(): void 205 { 206 add_action('init', $this->onInit(...)); 207 add_action('wp_head', $this->initJsLogging(...)); 208 add_action('admin_head', $this->initJsLogging(...)); 209 } 210 211 /** 212 * Build the error reporting level bitmask 213 * 214 * Creates a bitmask of PHP error reporting levels up to and including the specified cutoff level. 215 * 216 * @param int $cutoff The maximum error level to include 217 * @return int The combined bitmask of all error levels up to the cutoff 218 */ 219 public static function buildIncludedErrno(int $cutoff): int 220 { 221 $levels = [ 251 222 E_ERROR, 252 223 E_WARNING, … … 264 235 E_DEPRECATED, 265 236 E_USER_DEPRECATED, 266 E_ALL 267 );268 237 E_ALL, 238 ]; 239 269 240 $included_errno = 0; 270 241 271 242 foreach ($levels as $level) { 272 273 243 if ($level <= $cutoff) { 274 $included_errno |= $level; 244 $included_errno |= $level; 275 245 } 276 277 } 278 246 } 247 279 248 return $included_errno; 280 249 } 281 282 public function initPhpLogging() 283 { 284 $this->fetchSettings(); 285 250 251 /** 252 * Initialize PHP error logging with Rollbar 253 * 254 * Sets up the Rollbar PHP error handler if PHP logging is enabled. 255 * Handles configuration errors by displaying appropriate error messages. 256 * 257 * @param bool $ignoreEnabledSetting If true, the plugin will not check the 'php_logging_enabled' setting first. 258 * 259 * @return void 260 */ 261 public function initPhpLogging(bool $ignoreEnabledSetting = false): void 262 { 286 263 // Return if logging is not enabled 287 if ( $this->settings['php_logging_enabled'] === 0) {264 if (!$ignoreEnabledSetting && false === $this->getSetting('php_logging_enabled')) { 288 265 return; 289 266 } 290 267 291 268 // installs global error and exception handlers 292 269 try { 293 294 \Rollbar\Rollbar::init($this->buildPHPConfig()); 295 296 } catch (\InvalidArgumentException $exception) { 297 298 \add_action( 299 'admin_notices', 300 array( 301 '\Rollbar\Wordpress\UI', 302 'pluginMisconfiguredNotice' 303 ) 270 Rollbar::init($this->buildPHPConfig()); 271 } catch (Exception $exception) { 272 FlashMessages::addMessage( 273 message: 'Rollbar is misconfigured. Please, fix your configuration here: <a href="' 274 . admin_url('/options-general.php?page=rollbar_wp') . '">Rollbar Settings</a>.', 275 type: 'error', 304 276 ); 305 306 global $wp_settings_errors; 307 $wp_settings_errors[] = array( 308 'setting' => 'rollbar-wp', 309 'code' => 'rollbar-wp', 310 'message' => 'Rollbar PHP: ' . $exception->getMessage(), 311 'type' => 'error' 312 ); 313 314 } catch (\Exception $exception) { 315 316 global $wp_settings_errors; 317 $wp_settings_errors[] = array( 318 'setting' => 'rollbar-wp', 319 'code' => 'rollbar-wp', 320 'message' => 'Rollbar PHP: ' . $exception->getMessage(), 321 'type' => 'error' 322 ); 323 324 } 325 326 } 327 328 public function buildPHPConfig() 329 { 330 $config = $this->settings; 331 332 $config['access_token'] = $this->settings['server_side_access_token']; 333 $config['included_errno'] = self::buildIncludedErrno($this->settings['logging_level']); 334 $config['timeout'] = intval($this->settings['timeout']); 335 336 foreach (UI::settingsOfType(UI::SETTING_INPUT_TYPE_PHP) as $setting) { 337 338 if (isset($config[$setting])) { 339 340 $code = is_string($config[$setting]) ?: 'return ' . var_export($config[$setting], true) . ';'; 341 342 $config[$setting] = eval($code); 277 } 278 } 279 280 /** 281 * Build the PHP configuration for Rollbar 282 * 283 * Generates the configuration array for the Rollbar PHP SDK from the plugin settings. 284 * Processes boolean values and special settings like error reporting levels and person function. 285 * 286 * @return array The complete Rollbar PHP configuration 287 */ 288 public function buildPHPConfig(): array 289 { 290 $config = $this->settings->getAll(); 291 292 $config['access_token'] = $this->getSetting('server_side_access_token'); 293 $config['included_errno'] = self::buildIncludedErrno($this->getSetting('included_errno')); 294 $config['timeout'] = intval($this->getSetting('timeout')); 295 296 // Set up telemetry 297 $config['telemetry'] = false; 298 if ($this->getSetting('enable_telemetry_listener')) { 299 $config['telemetry'] = [ 300 'includeItemsInTelemetry' => $this->getSetting('include_items_in_telemetry'), 301 'includeIgnoredItemsInTelemetry' => $this->getSetting('include_ignored_items_in_telemetry'), 302 ]; 303 } 304 305 foreach ($config as $setting => $value) { 306 if (SettingType::Boolean !== Settings::getSettingType($setting)) { 307 continue; 343 308 } 344 } 345 346 foreach (UI::settingsOfType(UI::SETTING_INPUT_TYPE_BOOLEAN) as $setting) { 347 348 if (isset($config[$setting]) && $config[$setting] === 'false') { 349 $config[$setting] = false; 350 } else if (isset($config[$setting]) && $config[$setting] === 'true') { 351 $config[$setting] = true; 352 } 353 354 // also handle 1 and 0 as booleans 355 else if (isset($config[$setting]) && $config[$setting] === '0') { 356 $config[$setting] = false; 357 } else if (isset($config[$setting]) && $config[$setting] === '1') { 358 $config[$setting] = true; 359 } 360 } 361 362 return $config; 363 } 364 365 public function initJsLogging() 309 $config[$setting] = Settings::toBoolean($value); 310 } 311 312 if ($config['enable_person_reporting'] && empty($config['person_fn']) && empty($config['person'])) { 313 $config['person_fn'] = Settings::getPersonFunction(...); 314 } 315 316 $config['framework'] = 'wordpress ' . get_bloginfo('version'); 317 318 /** 319 * Filters the Rollbar Core SDK PHP configuration. 320 * 321 * @param array $config The Rollbar PHP configuration array. 322 * @since 3.0.0 323 */ 324 return apply_filters('rollbar_php_config', $config); 325 } 326 327 /** 328 * Initialize JavaScript error logging with Rollbar 329 * 330 * Sets up the Rollbar JavaScript error handler if JS logging is enabled. 331 * Checks for valid configuration and outputs the necessary JavaScript code. 332 * 333 * @return void 334 */ 335 public function initJsLogging(): void 366 336 { 367 337 // Return if logging is not enabled 368 if ( $this->settings['js_logging_enabled'] === 0) {338 if (false === $this->getSetting('js_logging_enabled')) { 369 339 return; 370 340 } 371 341 372 342 // Return if access token is not set 373 if ($this->settings['client_side_access_token'] == '') { 374 add_action( 375 'admin_notices', 376 array( 377 '\Rollbar\Wordpress\UI', 378 'pluginMisconfiguredNotice' 379 ) 343 if (empty($this->getSetting('client_side_access_token'))) { 344 FlashMessages::addMessage( 345 message: 'Rollbar is misconfigured. Please, fix your configuration here: <a href="' 346 . admin_url('/options-general.php?page=rollbar_wp') . '">Rollbar Settings</a>.', 347 type: 'error', 380 348 ); 381 349 return; 382 350 } 383 384 $rollbarJs = \Rollbar\RollbarJsHelper::buildJs($this->buildJsConfig());385 351 352 $rollbarJs = RollbarJsHelper::buildJs($this->buildJsConfig()); 353 386 354 echo $rollbarJs; 387 388 } 389 390 public function buildJsConfig() 391 { 392 $rollbarJsConfig = array( 393 'accessToken' => $this->settings['client_side_access_token'], 394 'captureUncaught' => true, 395 'payload' => array( 396 'environment' => $this->settings['environment'] 397 ), 398 ); 399 400 $rollbarJsConfig = apply_filters('rollbar_js_config', $rollbarJsConfig); 401 402 return $rollbarJsConfig; 403 } 404 405 public function updateSettings(array $settings) 406 { 407 $option = get_option('rollbar_wp'); 408 409 $option = array_merge($option, $settings); 410 411 foreach ($settings as $setting => $value) { 412 $this->settings[$setting] = $value; 413 } 414 415 update_option('rollbar_wp', $option); 416 } 417 418 public function restoreDefaults() 419 { 420 $settings = array(); 421 422 foreach (self::listOptions() as $option) { 423 $settings[$option] = $this->getDefaultOption($option); 424 } 425 426 $this->updateSettings($settings); 427 } 428 429 public function getDefaultOption($setting) 430 { 431 $spaced = str_replace('_', ' ', $setting); 432 $method = lcfirst(str_replace(' ', '', ucwords($spaced))); 433 434 // Handle the "branch" exception 435 switch($method) { 436 case "branch": 437 $method = "gitBranch"; 438 break; 439 case "captureIp": 440 $method = "captureIP"; 441 break; 442 } 443 444 $rollbarDefaults = \Rollbar\Defaults::get(); 445 $wordpressDefaults = \Rollbar\Wordpress\Defaults::instance(); 446 447 $value = null; 448 449 if (method_exists($wordpressDefaults, $method) && $value === null) { 450 try { 451 $value = $wordpressDefaults->$method(); 452 } catch (\Throwable $e) { 453 $value = null; 454 } catch (\Exception $e) { 455 $value = null; 456 } 457 } 458 459 if (method_exists($rollbarDefaults, $method) && $value === null) { 460 try { 461 $value = $rollbarDefaults->$method(); 462 } catch (\Throwable $e) { 463 $value = null; 464 } catch (\Exception $e) { 465 $value = null; 466 } 467 } 468 469 return $value; 470 } 471 472 public static function listOptions() 473 { 474 return array_merge( 475 \Rollbar\Config::listOptions(), 476 self::$pluginOptions 477 ); 478 } 479 480 public function enableMustUsePlugin() 355 } 356 357 /** 358 * Build the JavaScript configuration for Rollbar 359 * 360 * Generates the configuration array for the Rollbar JavaScript SDK from the plugin settings. 361 * Applies filters to allow customization of the JavaScript configuration. 362 * 363 * @return array The complete Rollbar JavaScript configuration 364 */ 365 public function buildJsConfig(): array 366 { 367 $config = [ 368 'accessToken' => $this->getSetting('client_side_access_token'), 369 'captureUncaught' => true, 370 'payload' => [ 371 'environment' => $this->getSetting('environment'), 372 ], 373 ]; 374 375 /** 376 * Filters the Rollbar JavaScript configuration. 377 * 378 * @param array $config The Rollbar JavaScript configuration array. 379 * @since 3.0.0 380 * 381 */ 382 return apply_filters('rollbar_js_config', $config); 383 } 384 385 /** 386 * Check if the Must-Use plugin is enabled 387 * 388 * Determines if the Rollbar Must-Use plugin is installed and active. 389 * 390 * @return bool True if the Must-Use plugin exists, false otherwise 391 */ 392 public static function mustUsePluginEnabled(): bool 393 { 394 return file_exists(plugin_dir_path(__DIR__) . '../../mu-plugins/rollbar-mu-plugin.php'); 395 } 396 397 /** 398 * Enable the Must-Use plugin 399 * 400 * Copies the Rollbar Must-Use plugin into the WordPress mu-plugins directory, 401 * creating the directory if it doesn't exist. 402 * 403 * @return void 404 * @throws Exception If the directory cannot be created or the plugin cannot be copied 405 */ 406 public function enableMustUsePlugin(): void 481 407 { 482 408 $muPluginsDir = plugin_dir_path(__DIR__) . '../../mu-plugins/'; 483 409 484 410 $muPluginFilepath = plugin_dir_path(__DIR__) . 'mu-plugin/rollbar-mu-plugin.php'; 485 411 486 412 if (!file_exists($muPluginsDir) && !mkdir($muPluginsDir, 0700)) { 487 throw new \Exception("Can't create the mu-plugins directory: $muPluginsDir");488 } 489 413 throw new Exception('Can\'t create the mu-plugins directory: ' . $muPluginsDir); 414 } 415 490 416 if (!copy($muPluginFilepath, $muPluginsDir . 'rollbar-mu-plugin.php')) { 491 throw new \Exception("Can't copy mu-plugin from $muPluginFilepath to $muPluginsDir"); 492 } 493 } 494 495 public function disableMustUsePlugin() 417 throw new Exception('Can\'t copy mu-plugin from ' . $muPluginFilepath . ' to ' . $muPluginsDir); 418 } 419 } 420 421 /** 422 * Disable the Must-Use plugin 423 * 424 * Removes the Rollbar Must-Use plugin from the WordPress mu-plugins directory if it exists. 425 * 426 * @return void 427 * @throws Exception If the plugin file cannot be deleted 428 */ 429 public function disableMustUsePlugin(): void 496 430 { 497 431 $file = plugin_dir_path(__DIR__) . '../../mu-plugins/rollbar-mu-plugin.php'; 498 432 if (file_exists($file) && !unlink($file)) { 499 throw new \Exception("Can't delete the mu-plugin");433 throw new Exception('Can\'t delete the mu-plugin'); 500 434 } 501 435 } -
rollbar/trunk/src/Settings.php
r2965452 r3380353 1 1 <?php 2 namespace Rollbar\Wordpress; 3 4 use Michelf\Markdown; 2 3 namespace Rollbar\WordPress; 4 5 use Psr\Log\LogLevel; 6 use Rollbar\Config; 7 use Rollbar\Defaults; 8 use Rollbar\Payload\Level; 9 use Rollbar\WordPress\Lib\AbstractSingleton; 10 use Rollbar\WordPress\Settings\SettingType; 11 use Rollbar\WordPress\Telemetry\Listener; 12 use WP_HTTP_Proxy; 5 13 6 14 // Exit if accessed directly 7 if (!defined('ABSPATH')) exit; 8 9 class Settings 15 // phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols 16 defined('ABSPATH') || exit; 17 // phpcs:enable 18 19 /** 20 * Class Settings 21 * 22 * Represents the configuration management for the Rollbar plugin. This class is responsible for 23 * providing and managing settings that are configured through the WordPress admin interface, 24 * environment variables, or system constants. Implements the Singleton design pattern to ensure a 25 * single instance of the settings is used application-wide. 26 * 27 * @since 3.0.0 28 */ 29 final class Settings extends AbstractSingleton 10 30 { 11 const DEFAULT_LOGGING_LEVEL = E_ERROR; 12 13 private static $instance; 14 15 private $plugin; 16 17 private function __construct() { 18 $this->plugin = \Rollbar\Wordpress\Plugin::instance(); 19 } 20 21 public static function instance() 22 { 23 if (!self::$instance) { 24 self::$instance = new self(); 25 } 26 27 return self::$instance; 28 } 29 30 public static function init() { 31 $instance = self::instance(); 32 \add_action('admin_menu', array(&$instance, 'addAdminMenu')); 33 \add_filter('plugin_action_links_'.basename(dirname(__DIR__)).'/rollbar-php-wordpress.php', array(&$instance, 'addAdminMenuLink')); 34 \add_action('admin_init', array(&$instance, 'addSettings')); 35 \add_action('admin_enqueue_scripts', function($hook) { 36 37 if ($hook != 'settings_page_rollbar_wp') { 38 return; 39 } 40 41 \wp_register_script( 42 'RollbarWordpressSettings.js', 43 \plugin_dir_url(__FILE__)."../public/js/RollbarWordpressSettings.js", 44 array("jquery"), 45 Plugin::VERSION 46 ); 47 48 \wp_localize_script( 49 'RollbarWordpressSettings.js', 50 'RollbarWordpress', 51 array( 52 // This is used to load the rollbar snippet, assume the php8 version is more recent. 53 'plugin_url' => \plugin_dir_url(__FILE__) . "../php8/", 54 ) 55 ); 56 57 \wp_enqueue_script( 58 "RollbarWordpressSettings.js", 59 \plugin_dir_url(__FILE__)."../public/js/RollbarWordpressSettings.js", 60 array("jquery"), 61 Plugin::VERSION 62 ); 63 64 \wp_register_style( 65 'RollbarWordpressSettings', 66 \plugin_dir_url(__FILE__)."../public/css/RollbarWordpressSettings.css", 67 false, 68 Plugin::VERSION 69 ); 70 \wp_enqueue_style('RollbarWordpressSettings'); 71 }); 72 73 \add_action('admin_post_rollbar_wp_restore_defaults', array(get_called_class(), 'restoreDefaultsAction')); 74 75 \add_action('pre_update_option_rollbar_wp', array(get_called_class(), 'preUpdate')); 76 } 77 78 function addAdminMenu() 79 { 80 add_submenu_page( 81 'options-general.php', 82 'Rollbar', 83 'Rollbar', 84 'manage_options', 85 'rollbar_wp', 86 array(&$this, 'optionsPage') 87 ); 88 } 89 90 function addAdminMenuLink($links) 91 { 92 $args = array('page' => 'rollbar_wp'); 93 94 $links['settings'] = '<a href="'.admin_url( 'options-general.php?'.http_build_query( $args ) ).'">'.__('Settings', 'rollbar').'</a>'; 95 96 return $links; 97 } 98 99 function addSettings() 100 { 101 \register_setting( 102 'rollbar_wp', 103 'rollbar_wp' 104 ); 105 106 // SECTION: General 107 \add_settings_section( 108 'rollbar_wp_general', 109 false, 110 false, 111 'rollbar_wp' 112 ); 113 114 // On/off & tokens 115 \add_settings_field( 116 'rollbar_wp_status', 117 __('Status', 'rollbar'), 118 array('\Rollbar\Wordpress\UI', 'status'), 119 'rollbar_wp', 120 'rollbar_wp_general', 121 array( 122 'php_logging_enabled' => (!empty($this->plugin->setting('php_logging_enabled'))) ? 1 : 0, 123 'server_side_access_token' => $this->plugin->setting('server_side_access_token'), 124 'js_logging_enabled' => (!empty($this->plugin->setting('js_logging_enabled'))) ? 1 : 0, 125 'client_side_access_token' => $this->plugin->setting('client_side_access_token') 126 ) 127 ); 128 129 $envDescription = $this->parseSettingDescription('environment'); 130 $envDescription .= UI::environmentSettingNote(); 131 $this->addSetting( 132 'environment', 133 'rollbar_wp_general', 134 array( 135 'description' => $envDescription 136 ) 137 ); 138 139 $included_errno_options = UI::getSettingOptions('included_errno'); 140 $human_friendly_errno_options = array(); 141 foreach ($included_errno_options as $included_errno) { 142 $human_friendly_errno_options[$included_errno] = UI::getIncludedErrnoDescriptions($included_errno); 143 } 144 145 $this->addSetting( 146 'logging_level', 147 'rollbar_wp_general', 148 array( 149 'type' => UI::SETTING_INPUT_TYPE_SELECTBOX, 150 'options' => $human_friendly_errno_options, 151 'default' => E_ERROR 152 ) 153 ); 154 155 // SECTION: Advanced 156 \add_settings_section( 157 'rollbar_wp_advanced', 158 null, 159 array(&$this, 'advancedSectionHeader'), 160 'rollbar_wp' 161 ); 162 163 $options = \Rollbar\Wordpress\Plugin::listOptions(); 164 $skip = array( 165 'access_token', 'environment', 'enabled', 'included_errno', 166 'base_api_url', 'enable_must_use_plugin' 167 ); 168 169 foreach ($options as $option) { 170 if (in_array($option, $skip)) { 31 /** 32 * The option name where the plugin settings are saved. 33 */ 34 private const OPTIONS_KEY = 'rollbar_wp'; 35 36 /** 37 * The array of plugin settings. 38 * 39 * @var array 40 */ 41 private array $settings = []; 42 43 /** 44 * @inheritdoc 45 */ 46 protected function __construct() 47 { 48 $this->fetchSettings(); 49 $this->hooks(); 50 } 51 52 /** 53 * Register the event handlers for the settings. 54 * 55 * @return void 56 */ 57 private function hooks(): void 58 { 59 add_filter('pre_update_option_rollbar_wp', $this->preUpdate(...)); 60 } 61 62 /** 63 * Returns an array of {@see Setting} that can be used in the plugin. 64 * 65 * @return array<string, null|Setting> 66 */ 67 public static function settings(): array 68 { 69 static $settings; 70 if (isset($settings)) { 71 return $settings; 72 } 73 $env = Settings::getEnvironment(null); 74 75 $defaults = Defaults::get(); 76 77 $settings = [ 78 'php_logging_enabled' => new Setting( 79 id: 'php_logging_enabled', 80 type: SettingType::Boolean, 81 default: false, 82 section: 'rollbar_wp_general', 83 ), 84 'server_side_access_token' => new Setting( 85 id: 'server_side_access_token', 86 type: SettingType::Text, 87 default: '', 88 section: 'rollbar_wp_general', 89 ), 90 'js_logging_enabled' => new Setting( 91 id: 'js_logging_enabled', 92 type: SettingType::Boolean, 93 default: false, 94 section: 'rollbar_wp_general', 95 ), 96 'client_side_access_token' => new Setting( 97 id: 'client_side_access_token', 98 type: SettingType::Text, 99 default: '', 100 section: 'rollbar_wp_general', 101 ), 102 'environment' => new Setting( 103 id: 'environment', 104 type: SettingType::Text, 105 helpText: '<p><code>WP_ENV</code> environment variable: <code>' . $env . '</code></p>' . 106 '<p>Rollbar for WordPress honors the <code>WP_ENV</code> environment variable. ' . 107 'If the <code>environment</code> setting is not specified here, it will take ' . 108 'precendence over the default value.</strong></p>', 109 default: 'production', 110 section: 'rollbar_wp_general', 111 ), 112 'included_errno' => new Setting( 113 id: 'included_errno', 114 type: SettingType::Select, 115 label: 'Logging Level', 116 default: E_ERROR, 117 options: [ 118 E_ERROR => 'Fatal run-time errors (E_ERROR) only', 119 E_WARNING => 'Run-time warnings (E_WARNING) and above', 120 E_PARSE => 'Compile-time parse errors (E_PARSE) and above', 121 E_NOTICE => 'Run-time notices (E_NOTICE) and above', 122 E_USER_ERROR => 'User-generated error messages (E_USER_ERROR) and above', 123 E_USER_WARNING => 'User-generated warning messages (E_USER_WARNING) and above', 124 E_USER_NOTICE => 'User-generated notice messages (E_USER_NOTICE) and above', 125 E_STRICT => 'Suggest code changes to ensure forward compatibility (E_STRICT) and above', 126 E_DEPRECATED => 'Warnings about code that won\'t work in future versions (E_DEPRECATED) and above', 127 E_ALL => 'Absolutely everything (E_ALL)', 128 ], 129 section: 'rollbar_wp_general', 130 ), 131 'agent_log_location' => new Setting( 132 id: 'agent_log_location', 133 type: SettingType::Text, 134 default: $defaults->agentLogLocation(), 135 ), 136 'allow_exec' => new Setting( 137 id: 'allow_exec', 138 type: SettingType::Boolean, 139 default: $defaults->allowExec(), 140 ), 141 'autodetect_branch' => new Setting( 142 id: 'autodetect_branch', 143 type: SettingType::Boolean, 144 default: $defaults->autodetectBranch(), 145 ), 146 'branch' => new Setting( 147 id: 'branch', 148 type: SettingType::Text, 149 default: $defaults->branch(), 150 ), 151 'capture_error_stacktraces' => new Setting( 152 id: 'capture_error_stacktraces', 153 type: SettingType::Boolean, 154 default: $defaults->captureErrorStacktraces(), 155 ), 156 'code_version' => new Setting( 157 id: 'code_version', 158 type: SettingType::Text, 159 default: $defaults->codeVersion(), 160 ), 161 'endpoint' => new Setting( 162 id: 'endpoint', 163 type: SettingType::Text, 164 default: $defaults->endpoint(), 165 ), 166 'fluent_host' => new Setting( 167 id: 'fluent_host', 168 type: SettingType::Text, 169 default: $defaults->fluentHost(), 170 ), 171 'fluent_port' => new Setting( 172 id: 'fluent_port', 173 type: SettingType::Text, 174 default: $defaults->fluentPort(), 175 ), 176 'fluent_tag' => new Setting( 177 id: 'fluent_tag', 178 type: SettingType::Text, 179 default: $defaults->fluentTag(), 180 ), 181 'handler' => new Setting( 182 id: 'handler', 183 type: SettingType::Select, 184 default: $defaults->handler(), 185 options: [ 186 'blocking' => 'blocking', 187 'agent' => 'agent', 188 'fluent' => 'fluent', 189 ], 190 ), 191 'host' => new Setting( 192 id: 'host', 193 type: SettingType::Text, 194 default: $defaults->host(), 195 ), 196 'include_error_code_context' => new Setting( 197 id: 'include_error_code_context', 198 type: SettingType::Boolean, 199 default: $defaults->includeErrorCodeContext(), 200 ), 201 'include_exception_code_context' => new Setting( 202 id: 'include_exception_code_context', 203 type: SettingType::Boolean, 204 default: $defaults->includeExceptionCodeContext(), 205 ), 206 'include_raw_request_body' => new Setting( 207 id: 'include_raw_request_body', 208 type: SettingType::Boolean, 209 default: $defaults->rawRequestBody(), 210 ), 211 'local_vars_dump' => new Setting( 212 id: 'local_vars_dump', 213 type: SettingType::Boolean, 214 default: $defaults->localVarsDump(), 215 ), 216 'log_payload' => new Setting( 217 id: 'log_payload', 218 type: SettingType::Boolean, 219 default: $defaults->logPayload(), 220 ), 221 'max_items' => new Setting( 222 id: 'max_items', 223 type: SettingType::Integer, 224 default: $defaults->maxItems(), 225 ), 226 'max_nesting_depth' => new Setting( 227 id: 'max_nesting_depth', 228 type: SettingType::Integer, 229 default: $defaults->maxNestingDepth(), 230 ), 231 'minimum_level' => new Setting( 232 id: 'minimum_level', 233 type: SettingType::Select, 234 default: $defaults->minimumLevel(), 235 options: [ 236 100000 => Level::EMERGENCY . ', ' . Level::ALERT . ', ' . Level::CRITICAL, 237 10000 => Level::ERROR . ', ' . Level::WARNING, 238 1000 => Level::WARNING, 239 100 => Level::NOTICE . ', ' . Level::INFO, 240 10 => Level::DEBUG, 241 ], 242 ), 243 'enable_person_reporting' => new Setting( 244 id: 'enable_person_reporting', 245 type: SettingType::Boolean, 246 helpText: 'Adds the current user to the payload as a person. This will allow Rollbar to display the ' 247 . 'user\'s details in the Rollbar UI.', 248 default: false, 249 ), 250 'capture_ip' => new Setting( 251 id: 'capture_ip', 252 type: SettingType::Boolean, 253 label: 'Capture IP Address', 254 default: $defaults->captureIp(), 255 ), 256 'capture_email' => new Setting( 257 id: 'capture_email', 258 type: SettingType::Boolean, 259 default: $defaults->captureEmail(), 260 ), 261 'capture_username' => new Setting( 262 id: 'capture_username', 263 type: SettingType::Boolean, 264 default: $defaults->captureUsername(), 265 ), 266 'proxy' => new Setting( 267 id: 'proxy', 268 type: SettingType::Text, 269 default: '', 270 ), 271 'raise_on_error' => new Setting( 272 id: 'raise_on_error', 273 type: SettingType::Boolean, 274 default: $defaults->raiseOnError(), 275 ), 276 'report_suppressed' => new Setting( 277 id: 'report_suppressed', 278 type: SettingType::Boolean, 279 default: $defaults->reportSuppressed(), 280 ), 281 'root' => new Setting( 282 id: 'root', 283 type: SettingType::Text, 284 default: ABSPATH, 285 ), 286 'send_message_trace' => new Setting( 287 id: 'send_message_trace', 288 type: SettingType::Boolean, 289 default: $defaults->sendMessageTrace(), 290 ), 291 'timeout' => new Setting( 292 id: 'timeout', 293 type: SettingType::Integer, 294 default: $defaults->timeout(), 295 ), 296 'transmit' => new Setting( 297 id: 'transmit', 298 type: SettingType::Boolean, 299 default: $defaults->transmit(), 300 ), 301 'use_error_reporting' => new Setting( 302 id: 'use_error_reporting', 303 type: SettingType::Boolean, 304 default: $defaults->useErrorReporting(), 305 ), 306 'verbose' => new Setting( 307 id: 'verbose', 308 type: SettingType::Select, 309 default: $defaults->verbose(), 310 options: [ 311 LogLevel::EMERGENCY => LogLevel::EMERGENCY, 312 LogLevel::ALERT => LogLevel::ALERT, 313 LogLevel::CRITICAL => LogLevel::CRITICAL, 314 LogLevel::ERROR => LogLevel::ERROR, 315 LogLevel::WARNING => LogLevel::WARNING, 316 LogLevel::NOTICE => LogLevel::NOTICE, 317 LogLevel::INFO => LogLevel::INFO, 318 LogLevel::DEBUG => LogLevel::DEBUG, 319 ], 320 ), 321 'enable_must_use_plugin' => new Setting( 322 id: 'enable_must_use_plugin', 323 type: SettingType::Boolean, 324 helpText: 'Allows Rollbar plugin to be loaded as early as possible as a Must-Use plugin. Activating / ' 325 . 'deactivating the plugin in the plugins admin panel won\'t have an effect as long as this option ' 326 . 'in enabled.', 327 default: false, 328 ), 329 'enable_telemetry_listener' => new Setting( 330 id: 'enable_telemetry_listener', 331 type: SettingType::Boolean, 332 helpText: 'Enables the collection of telemetry data to help debug issues.', 333 default: true, 334 section: 'rollbar_wp_telemetry', 335 ), 336 'include_items_in_telemetry' => new Setting( 337 id: 'include_items_in_telemetry', 338 type: SettingType::Boolean, 339 helpText: 'Include Rollbar captured exceptions and messages in the telemetry data of future exceptions ' 340 . 'and messages.', 341 default: true, 342 section: 'rollbar_wp_telemetry', 343 ), 344 'include_ignored_items_in_telemetry' => new Setting( 345 id: 'include_ignored_items_in_telemetry', 346 type: SettingType::Boolean, 347 helpText: 'Include Rollbar captured exceptions and messages in the telemetry data of future exceptions ' 348 . 'and messages even if they they are ignored because they have a lower level.', 349 default: false, 350 section: 'rollbar_wp_telemetry', 351 ), 352 'telemetry_hooks' => new Setting( 353 id: 'telemetry_hooks', 354 type: SettingType::CheckBox, 355 label: 'Enable Telemetry Actions', 356 helpText: 'Adds a telemetry event for each action that is hooked enabled in this list.', 357 default: array_keys(Listener::DEFAULT_ACTIONS), 358 options: array_combine(array_keys(Listener::ALL_ACTIONS), array_keys(Listener::ALL_ACTIONS)), 359 section: 'rollbar_wp_telemetry', 360 inputArgs: [ 361 'sort' => true, 362 ], 363 ), 364 // The following fields are intentionally left out of the Admin UI. They will be set later in the plugin or 365 // can be programmed by an end user in their WP site. 366 'access_token' => null, 367 'ca_cert_path' => null, 368 'check_ignore' => null, 369 'custom' => null, 370 'custom_data_method' => null, 371 'custom_truncation' => null, 372 'base_api_url' => null, 373 'enabled' => null, 374 'error_sample_rates' => null, 375 'exception_sample_rates' => null, 376 'log_payload_logger' => null, 377 'person' => null, 378 'person_fn' => null, 379 'scrubber' => null, 380 'scrub_fields' => null, 381 'scrub_safelist' => null, 382 'transformer' => null, 383 'telemetry' => null, 384 'verbose_logger' => null, 385 ]; 386 return $settings; 387 } 388 389 /** 390 * Returns the type of the setting, otherwise null if the key is not found, or it is skipped. 391 * 392 * @param string $key The setting key. 393 * @return SettingType|null 394 */ 395 public static function getSettingType(string $key): null|SettingType 396 { 397 return self::settings()[$key]?->type ?? null; 398 } 399 400 /** 401 * Returns the default value for a setting. 402 * 403 * @param string $setting 404 * @return mixed 405 */ 406 public static function getDefaultOption(string $setting): mixed 407 { 408 return self::settings()[$setting]?->default ?? null; 409 } 410 411 /** 412 * The filter applied before the `rollbar_wp` settings are saved to the DB. 413 * 414 * @param array $settings The array of settings. 415 * @return array 416 */ 417 public static function preUpdate(array $settings): array 418 { 419 // Empty checkboxes don't get sent in the $_POST. Fill missing boolean settings with default values. 420 foreach (Settings::settings() as $setting) { 421 if (null == $setting || isset($settings[$setting->id]) || SettingType::Boolean !== $setting->type) { 171 422 continue; 172 423 } 173 174 // TODO: https://github.com/rollbar/rollbar-php-wordpress/issues/41 175 if (UI::getSettingType($option) == UI::SETTING_INPUT_TYPE_PHP) { 176 continue; 177 } 178 179 $this->addSetting($option, 'rollbar_wp_advanced'); 180 } 181 182 $this->addSetting( 183 'enable_must_use_plugin', 184 'rollbar_wp_advanced', 185 array( 186 'type' => UI::getSettingType('enable_must_use_plugin'), 187 'default' => \Rollbar\Wordpress\Defaults::instance()->enableMustUsePlugin(), 188 'description' => __('Allows Rollbar plugin to be loaded as early ' . 189 'as possible as a Must-Use plugin. Activating / ' . 190 'deactivating the plugin in the plugins admin panel ' . 191 'won\'t have an effect as long as this option in enabled.', 'rollbar'), 192 'display_name' => __('Enable as a Must-Use plugin', 'rollbar') 193 ) 194 ); 195 } 196 197 private function addSetting($setting, $section, array $overrides = array()) 198 { 199 $type = isset($overrides['type']) ? 200 $overrides['type'] : 201 UI::getSettingType($setting); 202 203 $options = isset($overrides['options']) ? 204 $overrides['options'] : 205 UI::getSettingOptions($setting); 206 207 if ($type === false || $options === false) { 208 return; 209 } 210 211 $display_name = isset($overrides['display_name']) ? 212 $overrides['display_name'] : 213 ucfirst(str_replace("_", " ", $setting)); 214 215 if (isset($overrides['description'])) { 216 $description = $overrides['description']; 217 } else { 218 $description = $this->parseSettingDescription($setting); 219 } 220 221 $default = isset($overrides['default']) ? 222 $overrides['default'] : 223 $this->settingDefault($setting); 224 225 $value = $this->setting($setting); 226 227 \add_settings_field( 228 'rollbar_wp_' . $setting, 229 __($display_name, 'rollbar'), 230 array('Rollbar\Wordpress\UI', 'setting'), 231 'rollbar_wp', 232 $section, 233 array( 234 'label_for' => 'rollbar_wp_' . $setting, 235 'name' => $setting, 236 'display_name' => $display_name, 237 'value' => $value, 238 'description' => $description, 239 'type' => $type, 240 'options' => $options, 241 'default' => $default 242 ) 243 ); 244 } 245 246 private function setting($setting) 247 { 248 return $this->settingToString($this->plugin->setting($setting)); 249 } 250 251 private function settingToString($value) 252 { 253 if (is_string($value)) { 254 $value = esc_attr(trim($value)); 255 } else if (is_array($value)) { 256 $value = var_export($value, true); 257 } 258 259 return $value; 260 } 261 262 public function settingDefault($setting) 263 { 264 return $this->settingToString($this->plugin->getDefaultOption($setting)); 265 } 266 267 public function advancedSectionHeader() 268 { 269 $output = ''; 270 271 $output .= "<h3 class='hover-pointer' id='rollbar_settings_advanced_header'>" . 272 " <span id='rollbar_settings_advanced_toggle'>►</span> " . 273 " Advanced" . 274 "</h3>"; 275 276 $output .= "<div id='rollbar_settings_advanced' style='display:none;'>"; 277 278 echo $output; 279 } 280 281 function optionsPage() 282 { 283 284 UI::flashMessage(); 285 286 ?> 287 <form action='options.php' method='post'> 288 289 <h2 class="rollbar-header"> 290 <img class="logo" alt="Rollbar" src="//cdn.rollbar.com/static/img/rollbar-icon-white.svg?ts=1548370449v8" width="auto" height="24"> 291 Rollbar for WordPress 292 </h2> 293 294 <?php 295 \settings_fields('rollbar_wp'); 296 \do_settings_sections('rollbar_wp'); 297 ?> 298 </div> 299 300 <?php 301 \submit_button(); 302 ?> 303 304 </form> 305 <?php 306 307 UI::restoreAllDefaultsButton(); 308 UI::testButton(); 309 } 310 311 private function parseSettingDescription($option) 312 { 313 314 if ( version_compare( PHP_VERSION, '8.0.0', '<' ) ) { 315 $readme = file_get_contents(__DIR__ . '/../php7/vendor/rollbar/rollbar/README.md'); 316 } else { 317 $readme = file_get_contents(__DIR__ . '/../php8/vendor/rollbar/rollbar/README.md'); 318 } 319 320 $option_pos = stripos($readme, '<dt>' . $option); 321 322 $desc = ''; 323 324 if ($option_pos !== false) { 325 326 $desc_pos = stripos($readme, '<dd>', $option_pos) + strlen('<dd>'); 327 328 $desc_close = stripos($readme, '</dd>', $desc_pos); 329 330 $desc = substr($readme, $desc_pos, $desc_close - $desc_pos); 331 332 } 333 334 $desc = str_replace('```php', '```', $desc); 335 $desc = Markdown::defaultTransform($desc); 336 $desc = str_replace('```', '', $desc); 337 338 return $desc; 339 } 340 341 public static function restoreDefaultsAction() 342 { 343 \Rollbar\Wordpress\Plugin::instance()->restoreDefaults(); 344 345 self::flashRedirect( 346 "updated", 347 __("Default Rollbar settings restored.", "rollbar") 348 ); 349 } 350 351 public static function flashRedirect($type, $message) 352 { 353 self::flashMessage($type, $message); 354 355 wp_redirect(admin_url('/options-general.php?page=rollbar_wp')); 356 } 357 358 public static function flashMessage($type, $message) 359 { 360 // This is only designed to run in the admin for the main HTML request. 361 // If there is no session at this point something has gone terribly 362 // wrong, and we should bail out. 363 if( ! is_admin() || ! session_id() || wp_doing_cron() ) { 364 return; 365 } 366 367 $_SESSION['rollbar_wp_flash_message'] = array( 368 "type" => $type, 369 "message" => $message 370 ); 371 } 372 373 public static function preUpdate($settings) 374 { 375 376 // Empty checkboxes don't get propagated into the $_POST at all. Fill out 377 // missing boolean settings with default values. 378 foreach (UI::settingsOfType(UI::SETTING_INPUT_TYPE_BOOLEAN) as $setting) { 379 380 if (!isset($settings[$setting])) { 381 $settings[$setting] = false; 382 } 383 384 } 385 386 $settings['enabled'] = isset($settings['php_logging_enabled']) && $settings['php_logging_enabled']; 387 424 $settings[$setting->id] = false; 425 } 426 427 $settings['enabled'] = $settings['php_logging_enabled'] ?? false; 428 388 429 if (isset($settings['enable_must_use_plugin']) && $settings['enable_must_use_plugin']) { 389 430 try { 390 Plugin:: instance()->enableMustUsePlugin();431 Plugin::getInstance()->enableMustUsePlugin(); 391 432 } catch (\Exception $exception) { 392 433 add_action('admin_notices', function () { 393 echo '<div class="error notice"><p><strong>Error:</strong> failed to enable the Rollbar Must-Use plugin.</p></div>'; 434 echo '<div class="error notice"><p><strong>Error:</strong>' 435 . 'failed to enable the Rollbar Must-Use plugin.</p></div>'; 394 436 }); 395 437 $settings['enable_must_use_plugin'] = false; … … 397 439 } else { 398 440 try { 399 Plugin:: instance()->disableMustUsePlugin();441 Plugin::getInstance()->disableMustUsePlugin(); 400 442 } catch (\Exception $exception) { 401 443 add_action('admin_notices', function () { 402 echo '<div class="error notice"><p><strong>Error:</strong> failed to disable the Rollbar Must-Use plugin.</p></div>'; 444 echo '<div class="error notice"><p><strong>Error:</strong>' 445 . 'failed to disable the Rollbar Must-Use plugin.</p></div>'; 403 446 }); 404 447 $settings['enable_must_use_plugin'] = true; 405 448 } 406 449 } 407 408 // Don't store default values in the database. This is so that future updates 409 // to default values in PHP SDK don't get stored in users databases. 450 451 // Don't store default values in the database, so future updates to default values in the SDK get propagated. 410 452 foreach ($settings as $setting_name => $setting_value) { 411 if ($setting_value == Plugin::instance()->getDefaultOption($setting_name)) { 453 // Loose comparison to allow for boolean values to be set to 0 or 1 and integers to be strings, which is how 454 // they are posted via HTTP. 455 if ($setting_value == Plugin::getInstance()->settingsInstance()->getDefaultOption($setting_name)) { 412 456 unset($settings[$setting_name]); 413 457 } 414 458 } 415 459 416 460 return $settings; 417 461 } 462 463 /** 464 * Returns all the settings as an array. 465 * 466 * @return array 467 */ 468 public function getAll(): array 469 { 470 return $this->settings; 471 } 472 473 /** 474 * Returns a single setting, otherwise null if the $name is invalid. 475 * 476 * @param string $name The setting name. 477 * @return mixed 478 */ 479 public function get(string $name): mixed 480 { 481 return $this->settings[$name] ?? null; 482 } 483 484 /** 485 * Sets a value to the setting of the given name. 486 * 487 * @param string $name The name of the setting. 488 * @param mixed $value The value of the setting. 489 * @return void 490 */ 491 public function set(string $name, mixed $value): void 492 { 493 $this->settings[$name] = $value; 494 } 495 496 /** 497 * Save settings to the DB. 498 * 499 * @param array $settings 500 * @return void 501 */ 502 public function saveSettings(array $settings): void 503 { 504 $option = get_option('rollbar_wp'); 505 506 $option = array_merge($option, $settings); 507 508 foreach ($settings as $setting => $value) { 509 $this->settings[$setting] = $value; 510 } 511 512 update_option('rollbar_wp', $option); 513 } 514 515 /** 516 * Sets all the settings back to the default value. 517 * 518 * @return void 519 */ 520 public function restoreDefaults(): void 521 { 522 $settings = []; 523 524 foreach (Settings::listOptions() as $option) { 525 $settings[$option] = $this->getDefaultOption($option); 526 } 527 528 $this->saveSettings($settings); 529 } 530 531 /** 532 * Returns the array of option names for the Rollbar configs. 533 * 534 * @return string[] 535 */ 536 public static function listOptions(): array 537 { 538 return array_merge( 539 Config::listOptions(), 540 array_keys(self::settings()), 541 ); 542 } 543 544 /** 545 * Returns a reasonable boolean from a given value. 546 * 547 * @param mixed $value 548 * @return bool 549 */ 550 public static function toBoolean(mixed $value): bool 551 { 552 if (is_bool($value)) { 553 return $value; 554 } 555 if (is_string($value)) { 556 return in_array(strtolower($value), ['true', '1', 'yes', 'on']); 557 } 558 if (is_int($value)) { 559 return $value !== 0; 560 } 561 return boolval($value); 562 } 563 564 /** 565 * Returns a reasonable integer from a given value. 566 * 567 * @param mixed $value The value to convert to an integer. 568 * @return int 569 */ 570 public static function toInteger(mixed $value): int 571 { 572 if (is_int($value)) { 573 return $value; 574 } 575 if (is_string($value)) { 576 return intval($value); 577 } 578 if (is_bool($value)) { 579 return $value ? 1 : 0; 580 } 581 if (is_numeric($value)) { 582 return intval($value); 583 } 584 return 0; 585 } 586 587 /** 588 * Returns a reasonable string from a given value. 589 * 590 * @param mixed $value The value to convert to a string. 591 * @return string 592 */ 593 public static function toString(mixed $value): string 594 { 595 if (is_string($value)) { 596 return $value; 597 } 598 if (is_bool($value)) { 599 return $value ? 'true' : 'false'; 600 } 601 if (is_int($value)) { 602 return (string) $value; 603 } 604 if (is_numeric($value)) { 605 return (string) $value; 606 } 607 return ''; 608 } 609 610 /** 611 * Returns an array of strings from a given value. 612 * 613 * @param mixed $value The value to convert to an array of strings. 614 * @return string[] 615 */ 616 public static function toStringArray(mixed $value): array 617 { 618 if (is_array($value)) { 619 return array_map(fn($v) => self::toString($v), $value); 620 } 621 if (is_string($value)) { 622 return [$value]; 623 } 624 return []; 625 } 626 627 /** 628 * Fetch settings provided in Admin -> Tools -> Rollbar 629 * 630 * @returns void 631 */ 632 private function fetchSettings(): void 633 { 634 $options = $this->settings; 635 636 if (!Plugin::disabledAdmin() && $saved_options = get_option(self::OPTIONS_KEY)) { 637 $options = array_merge($options, $saved_options); 638 } 639 if (defined('ROLLBAR_SETTINGS') && is_array(constant('ROLLBAR_SETTINGS'))) { 640 $options = array_merge($options, constant('ROLLBAR_SETTINGS')); 641 } 642 643 $options['environment'] = self::getEnvironment($options['environment'] ?? null); 644 $options['proxy'] = self::getProxySettings($options['proxy'] ?? null); 645 $options['server_side_access_token'] = self::getServerAccessToken( 646 $options['server_side_access_token'] ?? null, 647 ); 648 $options['client_side_access_token'] = self::getClientAccessToken( 649 $options['client_side_access_token'] ?? null, 650 ); 651 652 $this->settings = self::normalizeSettings($options); 653 } 654 655 /** 656 * Normalizes the settings array to ensure all required fields are set and properly formatted. 657 * 658 * @param array<string, mixed> $options 659 * @return array 660 */ 661 public static function normalizeSettings(array $options): array 662 { 663 $settings = [ 664 'php_logging_enabled' => (!empty($options['php_logging_enabled'])) ? 1 : 0, 665 'js_logging_enabled' => (!empty($options['js_logging_enabled'])) ? 1 : 0, 666 'server_side_access_token' => (!empty($options['server_side_access_token'])) ? 667 esc_attr(trim($options['server_side_access_token'])) : 668 '', 669 'client_side_access_token' => (!empty($options['client_side_access_token'])) ? 670 esc_attr(trim($options['client_side_access_token'])) : 671 '', 672 'included_errno' => (!empty($options['included_errno'])) ? 673 esc_attr(trim($options['included_errno'])) : 674 self::getDefaultOption('included_errno'), 675 ]; 676 677 // Filter out options that are not in the list of options. 678 $options = array_intersect_key($options, array_flip(self::listOptions())); 679 680 foreach (self::settings() as $key => $setting) { 681 // 'access_token' and 'enabled' are different in WordPress plugin 682 // look for 'server_side_access_token' and 'php_logging_enabled' above 683 if (in_array($key, ['access_token', 'enabled'])) { 684 continue; 685 } 686 687 $value = $options[$key] ?? ($setting?->default ?? null); 688 if ($setting !== null) { 689 $value = $setting->coerceValue($value); 690 } elseif (!isset($options[$key])) { 691 continue; 692 } 693 $settings[$key] = $value; 694 } 695 696 /** 697 * Filter the Rollbar plugin settings. 698 * 699 * @param array $settings The Rollbar plugin settings array. 700 * @since 3.0.0 701 * 702 */ 703 return apply_filters('rollbar_plugin_settings', $settings); 704 } 705 706 /** 707 * Returns the provided environment if set, otherwise retrieves it from the system config or environment. 708 * 709 * @param string|null $environment The current environment value. 710 * @return string|null 711 */ 712 public static function getEnvironment(string|null $environment): string|null 713 { 714 if (null !== $environment) { 715 $environment = trim($environment); 716 } 717 if (empty($environment)) { 718 $environment = null; 719 } 720 $environment = trim(self::getSystemSetting('WP_ENV', $environment) ?? ''); 721 if (!empty($environment)) { 722 return $environment; 723 } 724 return trim(self::getSystemSetting('WP_ENVIRONMENT_TYPE', $environment) ?? ''); 725 } 726 727 /** 728 * The default `person_fn` method. 729 * 730 * @return array|null 731 */ 732 public static function getPersonFunction(): null|array 733 { 734 $user = wp_get_current_user(); 735 if (!$user) { 736 return null; 737 } 738 return [ 739 'id' => $user->ID, 740 'username' => $user->user_login, 741 'email' => $user->user_email, 742 ]; 743 } 744 745 /** 746 * Returns the provided client access token if set, otherwise retrieves it from the system config or environment. 747 * 748 * @param string|null $token The current access token value. 749 * @return string|null The access token to use for the frontend. 750 */ 751 private static function getClientAccessToken(string|null $token): string|null 752 { 753 if (!empty($token)) { 754 $token = trim($token); 755 } 756 if (empty($token)) { 757 $token = null; 758 } 759 return trim(self::getSystemSetting('ROLLBAR_CLIENT_ACCESS_TOKEN', $token) ?? ''); 760 } 761 762 /** 763 * Returns the provided server access token if set, otherwise retrieves it from the system config or environment. 764 * 765 * @param string|null $token The current access token value. 766 * @return string|null The access token to use server-side. 767 */ 768 private static function getServerAccessToken(string|null $token): string|null 769 { 770 if (!empty($token)) { 771 $token = trim($token); 772 } 773 if (empty($token)) { 774 $token = null; 775 } 776 return trim(self::getSystemSetting('ROLLBAR_ACCESS_TOKEN', $token) ?? ''); 777 } 778 779 /** 780 * Retrieves the specified setting from either a constant or environment variable. 781 * 782 * If the default is provided, it will be used if the constant does not exist. If the default is `null`, the 783 * environment variable will be used if it exists. Otherwise, `null` will be returned. 784 * 785 * @param string $key The name of the constant or environment variable. 786 * @param mixed $default The default value to use if the setting is not found. 787 * @return mixed The value of the constant, environment variable, the default, or null. 788 */ 789 private static function getSystemSetting(string $key, mixed $default = null): mixed 790 { 791 if (defined($key)) { 792 return constant($key); 793 } 794 if (null !== $default) { 795 return $default; 796 } 797 if ($value = getenv($key)) { 798 return $value; 799 } 800 return $default; 801 } 802 803 /** 804 * Retrieves the proxy settings based on provided input or system config. 805 * 806 * @param string|array|null $proxy The proxy settings as string, array, or null. If null or empty, attempts to fetch 807 * system-defined proxy constants. 808 * 809 * @return string|array|null The proxy settings in string, array, or null if no proxy is defined or enabled. 810 */ 811 private function getProxySettings(string|array|null $proxy): string|array|null 812 { 813 if (!empty($proxy)) { 814 return $proxy; 815 } 816 $proxy = new WP_HTTP_Proxy(); 817 if (!$proxy->is_enabled() || !$proxy->send_through_proxy('https://api.rollbar.com/api')) { 818 return null; 819 } 820 $proxySettings = [ 821 'address' => $proxy->host() . ':' . $proxy->port(), 822 ]; 823 if ($proxy->username() && $proxy->password()) { 824 $proxySettings['username'] = $proxy->username(); 825 $proxySettings['password'] = $proxy->password(); 826 } 827 return $proxySettings; 828 } 418 829 } 419 420 ?>
Note: See TracChangeset
for help on using the changeset viewer.