diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..f7e2a69
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,21 @@
+# This file is for unifying the coding style for different editors and IDEs
+# editorconfig.org
+
+root = true
+
+[*]
+end_of_line = lf
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.neon]
+indent_style = tab
+
+[phars.xml]
+indent_size = 2
+
+[*.js]
+indent_size = 2
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2378dde
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,32 @@
+/composer.lock
+*.diff
+*.err
+*.log
+*.orig
+*.rej
+*.swo
+*.swp
+*.vi
+*~
+.idea/*
+nbproject/*
+.vscode
+.DS_Store
+.cache
+.phpunit.cache
+.project
+.settings
+.svn
+errors.err
+tags
+node_modules
+package-lock.json
+/.phpunit.result.cache
+/nbproject/
+/tools
+/vendor
+/phpunit.xml
+/webroot/css/style.css.map
+/webroot/mix.js.map
+/webroot/mix-manifest.json
+.ddev/*
\ No newline at end of file
diff --git a/Console/Command/Task/NewRelicTask.php b/Console/Command/Task/NewRelicTask.php
deleted file mode 100644
index 386f143..0000000
--- a/Console/Command/Task/NewRelicTask.php
+++ /dev/null
@@ -1,10 +0,0 @@
-setName($controller->request);
- $this->start();
-
- if ($controller->Auth) {
- $this->user($controller->Auth->user('id'), $controller->Auth->user('email'), '');
- }
-
- $this->captureParams(true);
-
- $this->addTracer('CakeRoute::match');
- $this->addTracer('CrudComponent::executeAction');
- $this->addTracer('Controller::render');
- $this->addTracer('View::render');
- $this->addTracer('View::element');
- $this->addTracer('View::renderLayout');
- $this->addTracer('DboSource::_execute');
- $this->addTracer('AttemptChecker::attempt');
- }
-
-}
diff --git a/Lib/NewRelic.php b/Lib/NewRelic.php
deleted file mode 100644
index 1e11401..0000000
--- a/Lib/NewRelic.php
+++ /dev/null
@@ -1,217 +0,0 @@
-hasNewRelic()) {
- return;
- }
-
- newrelic_set_appname($name);
- }
-
-/**
- * Start a New Relic transaction
- *
- * @param string $name
- * @return void
- */
- public function start($name = null) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_start_transaction(NEW_RELIC_APP_NAME);
- newrelic_name_transaction($name);
- }
-
-/**
- * End a New Relic transaction
- *
- * @param boolean $ignore Should the statistics NewRelic gathered be discarded?
- * @return void
- */
- public function stop($ignore = false) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_end_transaction($ignore);
- }
-
-/**
- * Ignore the current transaction
- *
- * @return
- */
- public function ignoreTransaction() {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_ignore_transaction();
- }
-
-/**
- * Ignore the current apdex
- *
- * @return
- */
- public function ignoreApdex() {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_ignore_apdex();
- }
-
-/**
- * Should NewRelic capture params ?
- *
- * @param boolean $boolean
- * @return void
- */
- public function captureParams($boolean) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_capture_params($boolean);
- }
-
-/**
- * Add custom tracer method
- *
- * @param string $method
- */
- public function addTracer($method) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_add_custom_tracer($method);
- }
-
-/**
- * Add a custom parameter to the New Relic transaction
- *
- * @param string $key
- * @param mixed $value
- */
- public function parameter($key, $value) {
- if (!$this->hasNewRelic()) {
- return false;
- }
-
- if (!is_scalar($value)) {
- $value = json_encode($value);
- }
-
- newrelic_add_custom_parameter($key, $value);
- }
-
-/**
- * Track a custom metric
- *
- * @param string $key
- * @param integer|float $value
- * @return
- */
- public function metric($key, $value) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- if (!is_numeric($value)) {
- throw new CakeException('Value must be numeric');
- }
-
- newrelic_custom_metric($key, $value);
- }
-
-/**
- * Add a custom method to have traced by NewRelic
- *
- * @param string $method
- * @return void
- */
- public function tracer($method) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_add_custom_tracer($method);
- }
-
-/**
- * Send an exception to New Relic
- *
- * @param Exception $e
- * @return void
- */
- public function sendException(Exception $e) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_notice_error(null, $e);
- }
-
-/**
- * Set user attributes
- *
- * @param string $user
- * @param string $account
- * @param string $product
- * @return void
- */
- public function user($user, $account, $product) {
- if (!$this->hasNewRelic()) {
- return;
- }
-
- newrelic_set_user_attributes($user, $account, $product);
- }
-
-/**
- * Check if the NewRelic PHP extension is loaded
- *
- * @return boolean
- */
- public function hasNewRelic() {
- return extension_loaded('newrelic');
- }
-
-}
diff --git a/README.md b/README.md
index e498b4d..6fc3f99 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# CakePHP <3 NewRelic
-You can modify your files like this
+You can modify your files like this to have full NewRelic support.
## Things included
@@ -9,9 +9,21 @@ You can modify your files like this
- NewRelicTrait trait
- NewRelic.NewRelic
-### Console
+## Requirements
+- [New Relic PHP agent](https://docs.newrelic.com/docs/agents/php-agent/getting-started/introduction-new-relic-php) installed as a PHP module
-Include this snippet in `app/Console/AppShell.php`
+## Installation
+
+Note: This branch is for CakePHP 5.x
+
+```
+composer require jippi/cakephp-newrelic:dev-cake4
+```
+
+
+### Shell
+
+Include this snippet in `src/Shell/AppShell.php`
```php
public function startup() {
@@ -29,12 +41,11 @@ Include this snippet in `app/Console/AppShell.php`
Simply add `NewRelic.NewRelic` to your `$components` list
-## app/webroot/index.php
+## webroot/index.php
Add this in top of your file before `define('DS', 'DIRECTORY_SEPARATOR')`
```php
-_deriveNameFromShell($name);
- }
-
- if ($name instanceof CakeRequest) {
- $name = $this->_deriveNameFromRequest($name);
- }
-
- $this->_name = $name;
- }
-
-/**
- * Get the name
- *
- * @return string
- */
- public function getName() {
- return $this->_name;
- }
-
-/**
- * Change the application name
- *
- * @param string $name
- * @return void
- */
- public function applicationName($name) {
- NewRelic::getInstance()->applicationName($name);
- }
-
-/**
- * Start a NewRelic transaction
- *
- * @param null|string $name
- * @return void
- */
- public function start($name = null) {
- NewRelic::getInstance()->start($this->_getTransactionName($name));
- }
-
-/**
- * Stop a transaction
- *
- * @return void
- */
- public function stop($ignore = false) {
- NewRelic::getInstance()->stop($ignore);
- }
-
-/**
- * Ignore current transaction
- *
- * @return void
- */
- public function ignoreTransaction() {
- NewRelic::getInstance()->ignoreTransaction();
- }
-
-/**
- * Ignore current apdex
- *
- * @return void
- */
- public function ignoreApdex() {
- NewRelic::getInstance()->ignoreApdex();
- }
-
-/**
- * Add custom parameter to transaction
- *
- * @param string $key
- * @param scalar $value
- * @return void
- */
- public function parameter($key, $value) {
- NewRelic::getInstance()->parameter($key, $value);
- }
-
-/**
- * Add custom metric
- *
- * @param string $key
- * @param float $value
- * @return void
- */
- public function metric($key, $value) {
- NewRelic::getInstance()->metric($key, $value);
- }
-
-/**
- * capture params
- *
- * @param boolean $capture
- * @return void
- */
- public function captureParams($capture) {
- NewRelic::getInstance()->captureParams($capture);
- }
-
-/**
- * Add custom tracer method
- *
- * @param string $method
- */
- public function addTracer($method) {
- NewRelic::getInstance()->addTracer($method);
- }
-
-/**
- * Set user attributes
- *
- * @param string $user
- * @param string $account
- * @param string $product
- * @return void
- */
- public function user($user, $account, $product) {
- NewRelic::getInstance()->user($user, $account, $product);
- }
-
-/**
- * Send an exception to New Relic
- *
- * @param Exception $e
- * @return void
- */
- public function sendException(Exception $e) {
- NewRelic::getInstance()->sendException($e);
- }
-
-/**
- * Get transaction name
- *
- * @param string $name
- * @return string
- */
- protected function _getTransactionName($name) {
- if (is_string($name)) {
- return $name;
- }
-
- return $this->_name;
- }
-
-/**
- * Derive the transaction name
- *
- * @param Shell $name
- * @return string
- */
- protected function _deriveNameFromShell(Shell $shell) {
- $name = [];
-
- if ($shell->plugin) {
- $name[] = $shell->plugin;
- }
-
- $name[] = $shell->name;
- $name[] = $shell->command;
-
- return join('/', $name);
- }
-
- /**
- * Compute name based on request information
- *
- * @param CakeRequest $request
- * @return string
- */
- protected function _deriveNameFromRequest(CakeRequest $request) {
- $name = [];
-
- if ($request->prefix) {
- $name[] = $request->prefix;
- }
-
- if ($request->plugin) {
- $name[] = $request->plugin;
- }
-
- $name[] = $request->controller;
- $name[] = $request->action;
-
- $name = join('/', $name);
-
- if ($request->ext) {
- $name .= '.' . $request->ext;
- }
-
- return $name;
- }
-
-}
diff --git a/VERSION.txt b/VERSION.txt
new file mode 100644
index 0000000..2468aa9
--- /dev/null
+++ b/VERSION.txt
@@ -0,0 +1 @@
+3.0.0-dev
diff --git a/composer.json b/composer.json
index 7f3a210..49fa85a 100644
--- a/composer.json
+++ b/composer.json
@@ -1,32 +1,56 @@
{
- "name":"jippi/cakephp-newrelic",
- "version": "1.0.0",
- "description":"CakePHP <3 NewRelic",
- "type":"cakephp-plugin",
- "keywords":[
+ "name": "jippi/cakephp-newrelic",
+ "version": "3.0.0",
+ "description": "CakePHP <3 NewRelic",
+ "type": "cakephp-plugin",
+ "keywords": [
"cakephp",
"newrelic",
"apm",
"plugin"
],
- "homepage":"https://github.com/jippi/cakephp-newrelic",
- "license":"MIT",
- "authors":[
+ "homepage": "https://github.com/jippi/cakephp-newrelic",
+ "license": "MIT",
+ "authors": [
{
- "name":"Christian Winther",
- "role":"Author",
- "homepage":"http://cakephp.nu/"
+ "name": "Christian Winther",
+ "role": "Author",
+ "homepage": "http://cakephp.nu/"
}
],
- "support":{
- "source":"https://github.com/jippi/cakephp-newrelic",
- "issues":"https://github.com/jippi/cakephp-newrelic/issues",
- "irc":"irc://irc.freenode.org/friendsofcake"
+ "support": {
+ "source": "https://github.com/jippi/cakephp-newrelic",
+ "issues": "https://github.com/jippi/cakephp-newrelic/issues",
+ "irc": "irc://irc.freenode.org/friendsofcake"
},
- "require":{
- "composer/installers":"*"
+ "require": {
+ "php": ">=8.1",
+ "cakephp/cakephp": "5.x-dev"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^10.1.0",
+ "cakephp/cakephp-codesniffer": "^5.0"
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true,
+ "autoload": {
+ "psr-4": {
+ "NewRelic\\": "src",
+ "NewRelic\\Test\\Fixture\\": "tests\\Fixture"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Cake\\Test\\": "vendor/cakephp/cakephp/tests",
+ "DebugKit\\Test\\": "tests"
+ }
},
"extra": {
"installer-name": "NewRelic"
+ },
+ "config": {
+ "allow-plugins": {
+ "dealerdirect/phpcodesniffer-composer-installer": true
+ }
}
}
diff --git a/config/bootstrap.php b/config/bootstrap.php
new file mode 100644
index 0000000..f651d7d
--- /dev/null
+++ b/config/bootstrap.php
@@ -0,0 +1,6 @@
+
+
+
+
+
+
+
+
+
+
+
+ tests/TestCase/
+
+
+
+
+
+
+
+ src/
+
+
+
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
new file mode 100644
index 0000000..d3a0c84
--- /dev/null
+++ b/psalm-baseline.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 0000000..0d865a6
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Controller/Component/NewRelicComponent.php b/src/Controller/Component/NewRelicComponent.php
new file mode 100644
index 0000000..4c5e714
--- /dev/null
+++ b/src/Controller/Component/NewRelicComponent.php
@@ -0,0 +1,39 @@
+setName($event->getSubject()->getRequest());
+ $this->start();
+
+ $controller = $event->getSubject();
+ if (isset($controller->Auth)) {
+ $this->user($controller->Auth->user('id'), $controller->Auth->user('email'), '');
+ }
+
+ $this->captureParams(true);
+ }
+}
diff --git a/src/Lib/NewRelic.php b/src/Lib/NewRelic.php
new file mode 100644
index 0000000..6147a24
--- /dev/null
+++ b/src/Lib/NewRelic.php
@@ -0,0 +1,337 @@
+ $value) {
+ if (!in_array($key, static::$serverVariables)) {
+ continue;
+ }
+ static::parameter('server_' . strtolower($key), $value);
+ }
+
+ foreach ($_COOKIE as $key => $value) {
+ if (!in_array($key, static::$cookieVariables)) {
+ continue;
+ }
+ static::parameter('cookie_' . strtolower($key), $value);
+ }
+ }
+}
diff --git a/src/Middleware/NewRelicErrorHandlerMiddleware.php b/src/Middleware/NewRelicErrorHandlerMiddleware.php
new file mode 100644
index 0000000..632e9a1
--- /dev/null
+++ b/src/Middleware/NewRelicErrorHandlerMiddleware.php
@@ -0,0 +1,27 @@
+_deriveNameFromCommand($argument);
+ }
+ if ($argument instanceof ServerRequest) {
+ $name = $this->_deriveNameFromRequest($argument);
+ }
+
+ $this->_newrelicTransactionName = $name;
+ }
+
+ /**
+ * Get the name
+ *
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->_newrelicTransactionName;
+ }
+
+ /**
+ * Change the application name
+ *
+ * @param string $name
+ * @return void
+ */
+ public function applicationName(string $name): void
+ {
+ NewRelic::applicationName($name);
+ }
+
+ /**
+ * Start a NewRelic transaction
+ *
+ * @param string|null $name
+ * @return void
+ */
+ public function start(?string $name = null): void
+ {
+ NewRelic::start($this->_getTransactionName($name));
+ }
+
+ /**
+ * Stop a transaction
+ *
+ * @param bool $ignore
+ * @return void
+ */
+ public function stop(bool $ignore = false): void
+ {
+ NewRelic::stop($ignore);
+ }
+
+ /**
+ * Ignore current transaction
+ *
+ * @return void
+ */
+ public function ignoreTransaction(): void
+ {
+ NewRelic::ignoreTransaction();
+ }
+
+ /**
+ * Ignore current apdex
+ *
+ * @return void
+ */
+ public function ignoreApdex(): void
+ {
+ NewRelic::ignoreApdex();
+ }
+
+ /**
+ * Add custom parameter to transaction
+ *
+ * @param string $key
+ * @param mixed $value
+ * @return void
+ */
+ public function parameter(string $key, mixed $value): void
+ {
+ NewRelic::parameter($key, $value);
+ }
+
+ /**
+ * Add custom metric
+ *
+ * @param string $key
+ * @param float $value
+ * @return void
+ * @throws \Exception
+ */
+ public function metric(string $key, float $value): void
+ {
+ NewRelic::metric($key, $value);
+ }
+
+ /**
+ * capture params
+ *
+ * @param boolean $capture
+ * @return void
+ */
+ public function captureParams(bool $capture): void
+ {
+ NewRelic::captureParams($capture);
+ }
+
+ /**
+ * Add custom tracer method
+ *
+ * @param string $method
+ */
+ public function addTracer(string $method): void
+ {
+ NewRelic::addTracer($method);
+ }
+
+ /**
+ * Set user attributes
+ *
+ * @param string $user
+ * @param string $account
+ * @param string $product
+ * @return void
+ */
+ public function user(string $user, string $account, string $product): void
+ {
+ NewRelic::user($user, $account, $product);
+ }
+
+ /**
+ * Send an exception to New Relic
+ *
+ * @param \Exception $e
+ * @return void
+ */
+ public function sendException(Exception $e): void
+ {
+ NewRelic::sendException($e);
+ }
+
+ /**
+ * Get transaction name
+ *
+ * @param string $name
+ * @return string
+ */
+ protected function _getTransactionName(string $name): string
+ {
+ if ($name) {
+ return $name;
+ }
+
+ return $this->_newrelicTransactionName;
+ }
+
+ /**
+ * Derive the transaction name
+ *
+ * @param \Cake\Command\Command $command
+ * @return string
+ */
+ protected function _deriveNameFromCommand(Command $command): string
+ {
+ return $command->getName();
+ }
+
+ /**
+ * Compute name based on request information
+ *
+ * @param \Cake\Http\ServerRequest $request
+ * @return string
+ */
+ protected function _deriveNameFromRequest(ServerRequest $request): string
+ {
+ $name = [];
+ if ($request->getParam('prefix')) {
+ $name[] = $request->getParam('prefix');
+ }
+
+ if ($request->getParam('plugin')) {
+ $name[] = $request->getParam('plugin');
+ }
+
+ $name[] = $request->getParam('controller');
+ $name[] = $request->getParam('action');
+
+ $name = join('/', $name);
+
+ if ($request->getParam('ext')) {
+ $name .= '.' . $request->getParam('ext');
+ }
+
+ return $name;
+ }
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
new file mode 100644
index 0000000..c9f40d2
--- /dev/null
+++ b/tests/bootstrap.php
@@ -0,0 +1,45 @@
+loadInternalFile(env('FIXTURE_SCHEMA_METADATA'));
+}
diff --git a/tests/schema.php b/tests/schema.php
new file mode 100644
index 0000000..353ace1
--- /dev/null
+++ b/tests/schema.php
@@ -0,0 +1,4 @@
+