5
5
#include "php_agent.h"
6
6
#include "php_call.h"
7
7
#include "php_user_instrument.h"
8
+ #include "php_error.h"
8
9
#include "php_execute.h"
9
10
#include "php_wrapper.h"
10
11
#include "fw_hooks.h"
14
15
#include "util_strings.h"
15
16
16
17
/*
17
- * Set the web transaction name from the action .
18
+ * Yii1: Set the web transaction name from the controllerId + actionId combo .
18
19
*
19
20
* * txn naming scheme:
20
21
* In this case, `nr_txn_set_path` is called before `NR_PHP_WRAPPER_CALL` with
23
24
* ensure OAPI compatibility. This entails that the first wrapped call gets to
24
25
* name the txn.
25
26
*/
26
-
27
- NR_PHP_WRAPPER (nr_yii_runWithParams_wrapper ) {
27
+ NR_PHP_WRAPPER (nr_yii1_runWithParams_wrapper ) {
28
28
zval * classz = NULL ;
29
29
zval * idz = NULL ;
30
30
zval * this_var = NULL ;
@@ -37,7 +37,7 @@ NR_PHP_WRAPPER(nr_yii_runWithParams_wrapper) {
37
37
(void )wraprec ;
38
38
NR_UNUSED_SPECIALFN ;
39
39
40
- NR_PHP_WRAPPER_REQUIRE_FRAMEWORK (NR_FW_YII );
40
+ NR_PHP_WRAPPER_REQUIRE_FRAMEWORK (NR_FW_YII1 );
41
41
42
42
this_var = nr_php_scope_get (NR_EXECUTE_ORIG_ARGS TSRMLS_CC );
43
43
if (NULL == this_var ) {
@@ -76,8 +76,9 @@ NR_PHP_WRAPPER(nr_yii_runWithParams_wrapper) {
76
76
NR_NOT_OK_TO_OVERWRITE );
77
77
}
78
78
}
79
+ nr_php_zval_free (& idz );
79
80
}
80
-
81
+ nr_php_zval_free ( & classz );
81
82
end :
82
83
NR_PHP_WRAPPER_CALL ;
83
84
@@ -86,21 +87,138 @@ NR_PHP_WRAPPER(nr_yii_runWithParams_wrapper) {
86
87
NR_PHP_WRAPPER_END
87
88
88
89
/*
89
- * Enable Yii instrumentation.
90
+ * Enable Yii1 instrumentation.
90
91
*/
91
- void nr_yii_enable (TSRMLS_D ) {
92
+ void nr_yii1_enable (TSRMLS_D ) {
92
93
#if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
93
94
&& !defined OVERWRITE_ZEND_EXECUTE_DATA
94
95
nr_php_wrap_user_function_before_after_clean (
95
- NR_PSTR ("CAction::runWithParams" ), nr_yii_runWithParams_wrapper , NULL ,
96
+ NR_PSTR ("CAction::runWithParams" ), nr_yii1_runWithParams_wrapper , NULL ,
96
97
NULL );
97
98
nr_php_wrap_user_function_before_after_clean (
98
- NR_PSTR ("CInlineAction::runWithParams" ), nr_yii_runWithParams_wrapper ,
99
+ NR_PSTR ("CInlineAction::runWithParams" ), nr_yii1_runWithParams_wrapper ,
99
100
NULL , NULL );
100
101
#else
101
102
nr_php_wrap_user_function (NR_PSTR ("CAction::runWithParams" ),
102
- nr_yii_runWithParams_wrapper TSRMLS_CC );
103
+ nr_yii1_runWithParams_wrapper TSRMLS_CC );
103
104
nr_php_wrap_user_function (NR_PSTR ("CInlineAction::runWithParams" ),
104
- nr_yii_runWithParams_wrapper TSRMLS_CC );
105
+ nr_yii1_runWithParams_wrapper TSRMLS_CC );
106
+ #endif
107
+ }
108
+
109
+ /*
110
+ * Yii2: Set the web transaction name from the unique action ID.
111
+ */
112
+ NR_PHP_WRAPPER (nr_yii2_runWithParams_wrapper ) {
113
+ zval * this_var = NULL ;
114
+ zval * unique_idz = NULL ;
115
+ const char * unique_id = NULL ;
116
+ nr_string_len_t unique_id_length ;
117
+ char * transaction_name = NULL ;
118
+
119
+ (void )wraprec ;
120
+ NR_UNUSED_SPECIALFN ;
121
+
122
+ NR_PHP_WRAPPER_REQUIRE_FRAMEWORK (NR_FW_YII2 );
123
+
124
+ this_var = nr_php_scope_get (NR_EXECUTE_ORIG_ARGS TSRMLS_CC );
125
+ if (NULL == this_var ) {
126
+ nrl_verbosedebug (NRL_FRAMEWORK , "Yii2: improper this" );
127
+ goto end ;
128
+ }
129
+
130
+ unique_idz = nr_php_call (this_var , "getUniqueId" );
131
+ if (nr_php_is_zval_non_empty_string (unique_idz )) {
132
+ unique_id = Z_STRVAL_P (unique_idz );
133
+ unique_id_length = Z_STRLEN_P (unique_idz );
134
+
135
+ if (unique_id_length > 256 ) {
136
+ nrl_warning (NRL_FRAMEWORK ,
137
+ "Yii2 unique ID is too long (> %d); Yii2 naming not used" ,
138
+ 256 );
139
+ } else {
140
+ transaction_name = (char * )nr_alloca (unique_id_length + 1 );
141
+ nr_strxcpy (transaction_name , unique_id , unique_id_length );
142
+
143
+ nr_txn_set_path ("Yii2" , NRPRG (txn ), transaction_name , NR_PATH_TYPE_ACTION ,
144
+ NR_NOT_OK_TO_OVERWRITE );
145
+ }
146
+ } else {
147
+ nrl_verbosedebug (NRL_FRAMEWORK ,
148
+ "getUniqueId does not return a non empty string (%d)" ,
149
+ Z_TYPE_P (unique_idz ));
150
+ }
151
+ nr_php_zval_free (& unique_idz );
152
+ end :
153
+ NR_PHP_WRAPPER_CALL ;
154
+
155
+ nr_php_scope_release (& this_var );
156
+ }
157
+ NR_PHP_WRAPPER_END
158
+
159
+ #if ZEND_MODULE_API_NO < ZEND_8_0_X_API_NO \
160
+ || defined OVERWRITE_ZEND_EXECUTE_DATA
161
+ /*
162
+ * Yii2: Report errors and exceptions when built-in ErrorHandler is enabled.
163
+ */
164
+ NR_PHP_WRAPPER (nr_yii2_error_handler_wrapper ) {
165
+ zval * exception = NULL ;
166
+
167
+ NR_UNUSED_SPECIALFN ;
168
+ (void )wraprec ;
169
+
170
+ NR_PHP_WRAPPER_REQUIRE_FRAMEWORK (NR_FW_YII2 );
171
+
172
+ exception = nr_php_arg_get (1 , NR_EXECUTE_ORIG_ARGS TSRMLS_CC );
173
+ if (!nr_php_is_zval_valid_object (exception )) {
174
+ nrl_verbosedebug (NRL_FRAMEWORK , "%s: exception is NULL or not an object" ,
175
+ __func__ );
176
+ goto end ;
177
+ }
178
+
179
+ if (NR_SUCCESS
180
+ != nr_php_error_record_exception (
181
+ NRPRG (txn ), exception , nr_php_error_get_priority (E_ERROR ), true,
182
+ "Uncaught exception " , & NRPRG (exception_filters ) TSRMLS_CC )) {
183
+ nrl_verbosedebug (NRL_FRAMEWORK , "%s: unable to record exception" , __func__ );
184
+ }
185
+
186
+ end :
187
+ nr_php_arg_release (& exception );
188
+ }
189
+ NR_PHP_WRAPPER_END
190
+ #endif
191
+
192
+ /*
193
+ * Enable Yii2 instrumentation.
194
+ */
195
+ void nr_yii2_enable (TSRMLS_D ) {
196
+ #if ZEND_MODULE_API_NO >= ZEND_8_0_X_API_NO \
197
+ && !defined OVERWRITE_ZEND_EXECUTE_DATA
198
+ nr_php_wrap_user_function_before_after_clean (
199
+ NR_PSTR ("yii\\base\\Action::runWithParams" ),
200
+ nr_yii2_runWithParams_wrapper , NULL , NULL );
201
+ nr_php_wrap_user_function_before_after_clean (
202
+ NR_PSTR ("yii\\base\\InlineAction::runWithParams" ),
203
+ nr_yii2_runWithParams_wrapper , NULL , NULL );
204
+ #else
205
+ nr_php_wrap_user_function (NR_PSTR ("yii\\base\\Action::runWithParams" ),
206
+ nr_yii2_runWithParams_wrapper TSRMLS_CC );
207
+ nr_php_wrap_user_function (NR_PSTR ("yii\\base\\InlineAction::runWithParams" ),
208
+ nr_yii2_runWithParams_wrapper TSRMLS_CC );
209
+ /*
210
+ * Wrap Yii2 global error and exception handling methods.
211
+ * Given that: ErrorHandler::handleException(), ::handleError() and
212
+ * ::handleFatalError() all call ::logException($exception) at the right time,
213
+ * we will wrap this one to cover all cases.
214
+ * @see
215
+ * https://github.com/yiisoft/yii2/blob/master/framework/base/ErrorHandler.php
216
+ *
217
+ * Note: one can also set YII_ENABLE_ERROR_HANDLER constant to FALSE, this way
218
+ * allowing default PHP error handler to be intercepted by the NewRelic agent
219
+ * implementation.
220
+ */
221
+ nr_php_wrap_user_function (NR_PSTR ("yii\\base\\ErrorHandler::logException" ),
222
+ nr_yii2_error_handler_wrapper TSRMLS_CC );
105
223
#endif
106
224
}
0 commit comments