Permalink
Browse files

Request_Client::callback_params() carries arbitrary data for header c…

…allbacks [refs #4353]

Request_Client::callback_params() provides a simple key-value store for
parameters that should be passed on to header callbacks. Parameter values
are copied into sub-requests triggered by a callback.
  • Loading branch information...
1 parent ab62bf5 commit 4e00844ab77b385a103a04121c6affb0a587333a @acoulton committed Mar 5, 2012
Showing with 117 additions and 7 deletions.
  1. +71 −7 classes/Kohana/Request/Client.php
  2. +46 −0 tests/kohana/request/ClientTest.php
@@ -51,6 +51,11 @@
protected $_callback_depth = 0;
/**
+ * @var array Arbitrary parameters that are shared with header callbacks through their Request_Client object
+ */
+ protected $_callback_params = array();
+
+ /**
* Creates a new `Request_Client` object,
* allows for dependency injection.
*
@@ -118,13 +123,8 @@ public function execute(Request $request)
if ($cb_result instanceof Request)
{
// If the callback returns a request, automatically assign client params
- $client = $cb_result->client();
- $client->cache($this->cache());
- $client->follow($this->follow());
- $client->follow_headers($this->follow_headers());
- $client->header_callbacks($this->header_callbacks());
- $client->callback_depth($this->callback_depth() + 1);
- $client->max_callback_depth($this->max_callback_depth());
+ $this->assign_client_properties($cb_result->client());
+ $cb_result->client()->callback_depth($this->callback_depth() + 1);
// Execute the request
$response = $cb_result->execute();
@@ -301,6 +301,70 @@ public function callback_depth($depth = NULL)
}
/**
+ * Getter/Setter for the callback_params array, which allows additional
+ * application-specific parameters to be shared with callbacks.
+ *
+ * As with other Kohana setter/getters, usage is:
+ *
+ * // Set full array
+ * $client->callback_params(array('foo'=>'bar'));
+ *
+ * // Set single key
+ * $client->callback_params('foo','bar');
+ *
+ * // Get full array
+ * $params = $client->callback_params();
+ *
+ * // Get single key
+ * $foo = $client->callback_params('foo');
+ *
+ * @param string|array $param
+ * @param mixed $value
+ * @return Request_Client|mixed
+ */
+ public function callback_params($param = NULL, $value = NULL)
+ {
+ // Getter for full array
+ if ($param === NULL)
+ return $this->_callback_params;
+
+ // Setter for full array
+ if (is_array($param))
+ {
+ $this->_callback_params = $param;
+ return $this;
+ }
+ // Getter for single value
+ elseif ($value === NULL)
+ {
+ return Arr::get($this->_callback_params, $param);
+ }
+ // Setter for single value
+ else
+ {
+ $this->_callback_params[$param] = $value;
+ return $this;
+ }
+
+ }
+
+ /**
+ * Assigns the properties of the current Request_Client to another
+ * Request_Client instance - used when setting up a subsequent request.
+ *
+ * @param Request_Client $client
+ */
+ public function assign_client_properties(Request_Client $client)
+ {
+ $client->cache($this->cache());
+ $client->follow($this->follow());
+ $client->follow_headers($this->follow_headers());
+ $client->header_callbacks($this->header_callbacks());
+ $client->max_callback_depth($this->max_callback_depth());
+ $client->callback_params($this->callback_params());
+ }
+
+ /**
* The default handler for following redirects, triggered by the presence of
* a Location header in the response.
*
@@ -387,6 +387,52 @@ public function test_deep_recursive_callbacks_are_aborted()
->execute();
}
+ /**
+ * Header callback for testing that arbitrary callback_params are available
+ * to the callback.
+ *
+ * @param Request $request
+ * @param Response $response
+ * @param Request_Client $client
+ */
+ public function callback_assert_params($request, $response, $client)
+ {
+ $this->assertEquals('foo', $client->callback_params('constructor_param'));
+ $this->assertEquals('bar', $client->callback_params('setter_param'));
+ $response->body('assertions_ran');
+ }
+
+ /**
+ * Test that arbitrary callback_params can be passed to the callback through
+ * the Request_Client and are assigned to subsequent requests
+ */
+ public function test_client_can_hold_params_for_callbacks()
+ {
+ // Test with param in constructor
+ $request = Request::factory(
+ $this->_dummy_uri(
+ 302,
+ array('Location' => $this->_dummy_uri('200',array('X-cb'=>'1'), 'followed')),
+ 'not-followed'),
+ array(
+ 'follow' => TRUE,
+ 'header_callbacks' => array(
+ 'x-cb' => array($this, 'callback_assert_params'),
+ 'location' => 'Request_Client::on_header_location',
+ ),
+ 'callback_params' => array(
+ 'constructor_param' => 'foo'
+ )
+ ));
+
+ // Test passing param to setter
+ $request->client()->callback_params('setter_param', 'bar');
+
+ // Callback will throw assertion exceptions when executed
+ $response = $request->execute();
+ $this->assertEquals('assertions_ran', $response->body());
+ }
+
} // End Kohana_Request_ClientTest

1 comment on commit 4e00844

@kemo
kemo commented on 4e00844 Mar 6, 2012

https://github.com/acoulton/core/blob/4e00844ab77b385a103a04121c6affb0a587333a/classes/Kohana/Request/Client.php#L100

I think this should be

if ($this->callback_depth() === $this->max_callback_depth() - 1)

I didn't really read the whole code but this caught my attention

Please sign in to comment.