@@ -44,7 +44,8 @@ final class PluginClient implements HttpClient, HttpAsyncClient
4444 * @param Plugin[] $plugins
4545 * @param array $options {
4646 *
47- * @var int $max_restarts
47+ * @var int $max_restarts
48+ * @var Plugin[] $debug_plugins an array of plugins that are injected between each normal plugin
4849 * }
4950 *
5051 * @throws \RuntimeException if client is not an instance of HttpClient or HttpAsyncClient
@@ -110,8 +111,22 @@ private function configure(array $options = [])
110111 $ resolver = new OptionsResolver ();
111112 $ resolver ->setDefaults ([
112113 'max_restarts ' => 10 ,
114+ 'debug_plugins ' => [],
113115 ]);
114116
117+ $ resolver
118+ ->setAllowedTypes ('debug_plugins ' , 'array ' )
119+ ->setAllowedValues ('debug_plugins ' , function (array $ plugins ) {
120+ foreach ($ plugins as $ plugin ) {
121+ // Make sure each object passed with the `debug_plugins` is an instance of Plugin.
122+ if (!$ plugin instanceof Plugin) {
123+ return false ;
124+ }
125+ }
126+
127+ return true ;
128+ });
129+
115130 return $ resolver ->resolve ($ options );
116131 }
117132
@@ -127,7 +142,16 @@ private function createPluginChain($pluginList, callable $clientCallable)
127142 {
128143 $ firstCallable = $ lastCallable = $ clientCallable ;
129144
130- while ($ plugin = array_pop ($ pluginList )) {
145+ /*
146+ * Inject debug plugins between each plugin.
147+ */
148+ $ pluginListWithDebug = $ this ->options ['debug_plugins ' ];
149+ foreach ($ pluginList as $ plugin ) {
150+ $ pluginListWithDebug [] = $ plugin ;
151+ $ pluginListWithDebug = array_merge ($ pluginListWithDebug , $ this ->options ['debug_plugins ' ]);
152+ }
153+
154+ while ($ plugin = array_pop ($ pluginListWithDebug )) {
131155 $ lastCallable = function (RequestInterface $ request ) use ($ plugin , $ lastCallable , &$ firstCallable ) {
132156 return $ plugin ->handleRequest ($ request , $ lastCallable , $ firstCallable );
133157 };
0 commit comments