-
Notifications
You must be signed in to change notification settings - Fork 69
feat(agent): add support for CakePHP 4.x and 5.x #983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
3f9f7b9
9110805
a4df00d
0c5036f
5cc7987
b9f327f
7adc8d6
6ecae1a
c6f59c8
86108b5
da0860e
a1dbe2e
5641a40
fb77ac9
64dc7cc
9118bff
2a8975e
fd5ef92
f358d9d
fa779f5
d0a6282
7d009f9
6540e70
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,8 @@ | |
#include "util_logging.h" | ||
#include "util_memory.h" | ||
|
||
#define PHP_PACKAGE_NAME "cakephp/cakephp" | ||
|
||
nr_framework_classification_t nr_cakephp_special_1( | ||
const char* filename TSRMLS_DC) { | ||
NR_UNUSED_TSRMLS; | ||
|
@@ -129,15 +131,11 @@ NR_PHP_WRAPPER(nr_cakephp_name_the_wt_pre20) { | |
NR_PHP_WRAPPER_END | ||
|
||
/* | ||
* For CakePHP 2.0 and on, we do things a little differently as the params | ||
* array doesn't exist in the component any more. Instead we hook the | ||
* Controller's invokeAction method. This gets the request as a parameter | ||
* and we get the action from the params array in that object. The | ||
* controller object ($this) has a name, and that name is used (along | ||
* with the word "Controller" appended which is what the CakePHP code does). | ||
* | ||
* CakePHP 2.x is end-of-life and in maintenance mode (critical bugfixes only). | ||
* As such, functionality added in PHP 7.1+ is not well supported. | ||
* For CakePHP 4.0 and on, we retrieve the current controller object | ||
* and are able to extract the controller name from that. We then | ||
* retrieve the request object from the controller and are able to | ||
* extract the action name from that. We then concatenate the two | ||
* strings to form the transaction name. | ||
* | ||
* txn naming scheme: | ||
* In this case, `nr_txn_set_path` is called after `NR_PHP_WRAPPER_CALL` with | ||
|
@@ -147,17 +145,17 @@ NR_PHP_WRAPPER_END | |
* default way of calling the wrapped function in func_end. | ||
* | ||
*/ | ||
NR_PHP_WRAPPER(nr_cakephp_name_the_wt_2) { | ||
zval* arg1 = 0; | ||
NR_PHP_WRAPPER(nr_cakephp_name_the_wt_4) { | ||
zval* this_var = 0; | ||
zval* czval = 0; | ||
char* controller = 0; | ||
char* action = 0; | ||
int clen = 0; | ||
int alen = 0; | ||
char* name = 0; | ||
zval* params; | ||
zval* azval; | ||
zval* action_zval = NULL; | ||
zval* request = NULL; | ||
zval action_param; | ||
|
||
(void)wraprec; | ||
NR_UNUSED_SPECIALFN; | ||
|
@@ -193,37 +191,24 @@ NR_PHP_WRAPPER(nr_cakephp_name_the_wt_2) { | |
} | ||
} | ||
|
||
arg1 = nr_php_arg_get(1, NR_EXECUTE_ORIG_ARGS TSRMLS_CC); | ||
if (!nr_php_is_zval_valid_object(arg1)) { | ||
NR_PHP_WRAPPER_CALL; | ||
goto end; | ||
} | ||
|
||
NR_PHP_WRAPPER_CALL; | ||
|
||
params = nr_php_get_zval_object_property(arg1, "params" TSRMLS_CC); | ||
if (0 == params) { | ||
nrl_verbosedebug(NRL_FRAMEWORK, "CakePHP: no params found in request"); | ||
request = nr_php_call(this_var, "getRequest"); | ||
if (!nr_php_is_zval_valid_object(request)) { | ||
nrl_verbosedebug(NRL_FRAMEWORK, "CakePHP: no request found in controller"); | ||
goto end; | ||
} | ||
|
||
if (IS_ARRAY != Z_TYPE_P(params)) { | ||
nrl_verbosedebug(NRL_FRAMEWORK, "CakePHP: request params is not an array"); | ||
nr_php_zval_str(&action_param, "action"); | ||
action_zval = nr_php_call(request, "getParam", &action_param); | ||
zval_dtor(&action_param); | ||
if (!nr_php_is_zval_valid_string(action_zval)) { | ||
hahuja2 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
nrl_verbosedebug(NRL_FRAMEWORK, "CakePHP: no action param found in request"); | ||
goto end; | ||
} | ||
|
||
azval = nr_php_get_zval_object_property(params, "action" TSRMLS_CC); | ||
if (0 == azval) { | ||
nrl_verbosedebug(NRL_FRAMEWORK, "CakePHP: no params['action'] in request"); | ||
} else { | ||
if (!nr_php_is_zval_valid_string(azval)) { | ||
nrl_verbosedebug(NRL_FRAMEWORK, | ||
"CakePHP: no string-valued params['action'] in request"); | ||
} else { | ||
alen = Z_STRLEN_P(azval); | ||
action = (char*)nr_alloca(alen + 1); | ||
nr_strxcpy(action, Z_STRVAL_P(azval), alen); | ||
} | ||
alen = Z_STRLEN_P(action_zval); | ||
action = (char*)nr_alloca(alen + 1); | ||
nr_strxcpy(action, Z_STRVAL_P(action_zval), alen); | ||
} | ||
|
||
if ((0 == clen) && (0 == alen)) { | ||
|
@@ -249,8 +234,9 @@ NR_PHP_WRAPPER(nr_cakephp_name_the_wt_2) { | |
NR_NOT_OK_TO_OVERWRITE); | ||
|
||
end: | ||
nr_php_arg_release(&arg1); | ||
nr_php_scope_release(&this_var); | ||
nr_php_zval_free(&request); | ||
nr_php_zval_free(&action_zval); | ||
} | ||
NR_PHP_WRAPPER_END | ||
|
||
|
@@ -281,24 +267,21 @@ NR_PHP_WRAPPER(nr_cakephp_problem_1) { | |
NR_PHP_WRAPPER_END | ||
|
||
/* | ||
* CakePHP 2.0+ | ||
* CakePHP 4.0+ | ||
* | ||
* If the action or controller is not found during the dispatch process, the | ||
* appropriate Exception will be created and thrown. We wrap the CakeException | ||
* constructor instead of the Exception handler, since CakePHP allows for the | ||
* handler to be completely replaced. | ||
* | ||
* CakePHP 2.x is end-of-life and in maintenance mode (critical bugfixes only). | ||
* As such, functionality added in PHP 7.1+ is not well supported. | ||
* | ||
* txn naming scheme: | ||
* In this case, `nr_txn_set_path` is called before `NR_PHP_WRAPPER_CALL` with | ||
* `NR_NOT_OK_TO_OVERWRITE` and as this corresponds to calling the wrapped | ||
* function in func_begin it needs to be explicitly set as a before_callback to | ||
* ensure OAPI compatibility. This entails that the first wrapped call gets to | ||
* name the txn. | ||
*/ | ||
NR_PHP_WRAPPER(nr_cakephp_problem_2) { | ||
NR_PHP_WRAPPER(nr_cakephp_problem_4) { | ||
const char* name = "Exception"; | ||
|
||
(void)wraprec; | ||
|
@@ -324,17 +307,22 @@ void nr_cakephp_enable_1(TSRMLS_D) { | |
} | ||
|
||
/* | ||
* Enable CakePHP 2.0+ | ||
* Enable CakePHP 4.0+ | ||
*/ | ||
void nr_cakephp_enable_2(TSRMLS_D) { | ||
nr_php_wrap_user_function(NR_PSTR("Controller::invokeAction"), | ||
nr_cakephp_name_the_wt_2 TSRMLS_CC); | ||
void nr_cakephp_enable(TSRMLS_D) { | ||
nr_php_wrap_user_function( | ||
NR_PSTR("Cake\\Controller\\Controller::invokeAction"), | ||
nr_cakephp_name_the_wt_4 TSRMLS_CC); | ||
nr_txn_suggest_package_supportability_metric(NRPRG(txn), PHP_PACKAGE_NAME, | ||
PHP_PACKAGE_VERSION_UNKNOWN); | ||
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \ | ||
&& !defined OVERWRITE_ZEND_EXECUTE_DATA | ||
nr_php_wrap_user_function_before_after_clean( | ||
NR_PSTR("CakeException::__construct"), nr_cakephp_problem_2, NULL, NULL); | ||
NR_PSTR("Cake\\Core\\Exception\\CakeException::__construct"), | ||
nr_cakephp_problem_4, NULL, NULL); | ||
|
||
#else | ||
nr_php_wrap_user_function(NR_PSTR("CakeException::__construct"), | ||
nr_cakephp_problem_2 TSRMLS_CC); | ||
nr_php_wrap_user_function( | ||
NR_PSTR("Cake\\Core\\Exception\\CakeException::__construct"), | ||
nr_cakephp_problem_4 TSRMLS_CC); | ||
#endif | ||
} |
Uh oh!
There was an error while loading. Please reload this page.