Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'dev'

  • Loading branch information...
commit e5d7338a5e282806a4578999ac743d96f5cfdb5c 2 parents 41ab56f + 9cb627c
@nateabele nateabele authored
View
6 action/Request.php
@@ -586,9 +586,9 @@ protected function _url() {
return rtrim($_GET['url'], '/');
}
if ($uri = $this->env('REQUEST_URI')) {
- return trim(preg_replace(
- '/^' . preg_quote($this->env('base'), '/') . '/', '', parse_url($uri, PHP_URL_PATH)
- ), '/') ?: '/';
+ list($uri) = explode('?', $uri, 2);
+ $base = '/^' . preg_quote($this->env('base'), '/') . '/';
+ return trim(preg_replace($base, '', $uri), '/') ?: '/';
}
return '/';
}
View
20 data/Entity.php
@@ -371,16 +371,20 @@ public function modified() {
$fields = array_fill_keys(array_keys($this->_data), false);
foreach ($this->_updated as $field => $value) {
- if (!is_object($value) || !method_exists($value, 'modified')) {
+ if (is_object($value) && method_exists($value, 'modified')) {
+ if (!isset($this->_data[$field])) {
+ $fields[$field] = true;
+ continue;
+ }
+ $modified = $value->modified();
+
$fields[$field] = (
- !isset($fields[$field]) ||
- $this->_data[$field] !== $this->_updated[$field]
+ $modified === true || is_array($modified) && in_array(true, $modified, true)
+ );
+ } else {
+ $fields[$field] = (
+ !isset($fields[$field]) || $this->_data[$field] !== $this->_updated[$field]
);
- continue;
- }
- if (!isset($this->_data[$field])) {
- $fields[$field] = true;
- continue;
}
$modified = $value->modified();
View
4 data/Model.php
@@ -244,8 +244,8 @@ class Model extends \lithium\core\StaticObject {
* a collection, along with a `'data'` key, which contains the schema for that collection, in
* the format specified above.
*
- * When defining `'$_schema'` where the data source is MongoDB, the types map to database types
- * as follows:
+ * When defining `'$_schema'` where the data source is MongoDB, the types map to database
+ * types as follows:
*
* {{{
* id => MongoId
View
4 net/http/Media.php
@@ -113,9 +113,9 @@ public static function to($format, $data, array $options = array()) {
* Examples:
* {{{ embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(1-2) }}}
*
- * {{{ embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(19-20) }}}
+ * {{{ embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(19-23) }}}
*
- * {{{ embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(40-41) }}}
+ * {{{ embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(43-44) }}}
*
* Alternatively, can be used to detect the type name of a registered content type:
* {{{
View
10 net/http/Response.php
@@ -198,13 +198,19 @@ protected function _parseMessage($body) {
if (array_filter($headers) == array()) {
return trim($body);
}
- preg_match('/HTTP\/(\d+\.\d+)\s+(\d+)\s+(.*)/i', array_shift($headers), $match);
+ preg_match('/HTTP\/(\d+\.\d+)\s+(\d+)(?:\s+(.*))?/i', array_shift($headers), $match);
$this->headers($headers);
if (!$match) {
return trim($body);
}
- list($line, $this->version, $code, $message) = $match;
+ list($line, $this->version, $code) = $match;
+ if (isset($this->_statuses[$code])) {
+ $message = $this->_statuses[$code];
+ }
+ if (isset($match[3])) {
+ $message = $match[3];
+ }
$this->status = compact('code', 'message') + $this->status;
$this->protocol = "HTTP/{$this->version}";
return $body;
View
2  net/http/Service.php
@@ -216,8 +216,8 @@ protected function _request($method, $path, $data, $options) {
$request->method = $method = strtoupper($method);
$hasBody = in_array($method, array('POST', 'PUT'));
- $hasBody ? $request->body($data) : $request->query = $data;
$hasBody ? $request->type($options['type']) : null;
+ $hasBody ? $request->body($data) : $request->query = $data;
return $request;
}
}
View
4 net/socket/Curl.php
@@ -50,6 +50,7 @@ public function __construct(array $config = array()) {
* Opens a curl connection and initializes the internal resource handle.
*
* @param array $options update the config settings
+ * if $options['options'] exists, will be passed to $this->set()
* @return mixed Returns `false` if the socket configuration does not contain the
* `'scheme'` or `'host'` settings, or if configuration fails, otherwise returns a
* resource stream.
@@ -62,6 +63,9 @@ public function open(array $options = array()) {
if (empty($config['scheme']) || empty($config['host'])) {
return false;
}
+ if (!empty($config['options'])) {
+ $this->set($config['options']);
+ }
$url = "{$config['scheme']}://{$config['host']}";
$this->_resource = curl_init($url);
View
19 template/helper/Form.php
@@ -37,7 +37,7 @@ class Form extends \lithium\template\Helper {
* @var array
*/
protected $_strings = array(
- 'button' => '<button{:options}>{:name}</button>',
+ 'button' => '<button{:options}>{:title}</button>',
'checkbox' => '<input type="checkbox" name="{:name}"{:options} />',
'checkbox-multi' => '<input type="checkbox" name="{:name}[]"{:options} />',
'checkbox-multi-group' => '{:raw}',
@@ -493,6 +493,23 @@ protected function _fields(array $fields, array $options = array()) {
}
/**
+ * Generates an HTML button `<button></button>`.
+ *
+ * @param string $title The title of the button.
+ * @param array $options Any options passed are converted to HTML attributes within the
+ * `<button></button>` tag.
+ * @return string Returns a `<button></button>` tag with the given title and HTML attributes.
+ */
+ public function button($title = null, array $options = array()) {
+ $defaults = array('escape' => true);
+ list($scope, $options) = $this->_options($defaults, $options);
+ list($title, $options, $template) = $this->_defaults(__METHOD__, $title, $options);
+
+ $arguments = compact('type', 'title', 'options', 'value');
+ return $this->_render(__METHOD__, 'button', $arguments, $scope);
+ }
+
+ /**
* Generates an HTML `<input type="submit" />` object.
*
* @param string $title The title of the submit button.
View
31 template/helper/Html.php
@@ -133,8 +133,8 @@ public function charset($encoding = null) {
* anchor name starting with `'#'` (i.e. `'#top'`), or an array defining a set
* of request parameters that should be matched against a route in `Router`.
* @param array $options The available options are:
- * - `'escape'` _boolean_: Whether or not the title content should be escaped or not.
- * Defaults to true.
+ * - `'escape'` _boolean_: Whether or not the title content should be escaped.
+ * Defaults to `true`.
* - `'type'` _string_: The meta-link type, which is looked up in `Html::$_metaLinks`.
* By default it accepts `atom`, `rss` and `icon`.
* If a `type` is specified, this method will render a document meta-link (`<link />`),
@@ -164,10 +164,17 @@ public function link($title, $url = null, array $options = array()) {
* @param mixed $path String The name of a JavaScript file, or an array of names.
* @param array $options Available options are:
* - `'inline'` _boolean_: Whether or not the `<script />` element should be output inline.
+<<<<<<< HEAD
* When set to false, the `scripts()` handler prints out the script, and other specified
* scripts to be included in the layout. Defaults to `true`. This is useful when
* page-specific scripts are created inline in the page, and you'd like to place them
* in the `<head />` along with your other scripts.
+=======
+ * When set to false, the `scripts()` handler prints out the script, and other specified
+ * scripts to be included in the layout. Defaults to true.
+ * This is useful when page-specific scripts are created inline in the page,
+ * and you'd like to place them in the <head /> along with your other scripts.
+>>>>>>> dev
* - any other options specified are rendered as HTML attributes of the element.
* @return string
* @filter This method can be filtered.
@@ -199,16 +206,27 @@ public function script($path, array $options = array()) {
/**
* Creates a `<link />` element for CSS stylesheets or a `<style />` tag. If the filename is
* prefixed with `'/'`, the path will be relative to the base path of your application.
+<<<<<<< HEAD
* Otherwise, the path will be relative to your stylesheets path, usually `webroot/css`.
+=======
+ * Otherwise, the path will be relative to your Stylesheets path, usually `webroot/css`.
+>>>>>>> dev
*
* @param mixed $path The name of a CSS stylesheet in `/app/webroot/css`, or an array
* containing names of CSS stylesheets in that directory.
* @param array $options Available options are:
* - `'inline'` _boolean_: Whether or not the `<style />` element should be output inline.
+<<<<<<< HEAD
* When set to `false`, the `styles()` handler prints out the styles, and other specified
* styles to be included in the layout. Defaults to `true`. This is useful when
* page-specific styles are created inline in the page, and you'd like to place them in
* the `<head />` along with your other styles.
+=======
+ * When set to false, the `styles()` handler prints out the styles, and other specified
+ * styles to be included in the layout. Defaults to true.
+ * This is useful when page-specific styles are created inline in the page,
+ * and you'd like to place them in the <head /> along with your other styles.
+>>>>>>> dev
* - `'type'` _string_: By default, accepts `stylesheet` or `import`,
* which respectively correspond to `style-link` and `style-import` strings templates
* defined in `Html::$_strings`.
@@ -275,10 +293,17 @@ public function head($tag, array $options) {
* Creates a formatted `<img />` element.
*
* @param string $path Path to the image file. If the filename is prefixed with
+<<<<<<< HEAD
* `'/'`, the path will be relative to the base path of your application. Otherwise, the path
* will be relative to the images directory, usually `webroot/img/`. If the name starts with
* `'http://'`, this is treated as an external URL.
*
+=======
+ * `'/'`, the path will be relative to the base path of your application.
+ * Otherwise the path will be relative to the images directory, usually `app/webroot/img/`.
+ * If the name starts with `'http://'`, this is treated as an external url used as the `src`
+ * attribute.
+>>>>>>> dev
* @param array $options Array of HTML attributes.
* @return string Returns a formatted `<img />` tag.
* @filter This method can be filtered.
@@ -301,7 +326,7 @@ public function image($path, array $options = array()) {
* @param string $type The title of the external resource
* @param mixed $url The address of the external resource or string for content attribute
* @param array $options Other attributes for the generated tag. If the type attribute
- * is 'html', 'rss', 'atom', or 'icon', the mime-type is returned.
+ * 4 is 'html', 'rss', 'atom', or 'icon', the mime-type is returned.
* @return string
*/
protected function _metaLink($type, $url = null, array $options = array()) {
View
10 test/filter/Coverage.php
@@ -8,6 +8,7 @@
namespace lithium\test\filter;
+use RuntimeException;
use lithium\core\Libraries;
use lithium\analysis\Inspector;
@@ -34,7 +35,12 @@ class Coverage extends \lithium\test\Filter {
public static function apply($report, $tests, array $options = array()) {
$defaults = array('method' => 'run');
$options += $defaults;
- $m = $options['method'];
+
+ if (!function_exists('xdebug_start_code_coverage')) {
+ $msg = "Xdebug not installed. Please install Xdebug before running code coverage.";
+ throw new RuntimeException($msg);
+ }
+
$filter = function($self, $params, $chain) use ($report, $options) {
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
$chain->next($self, $params, $chain);
@@ -42,7 +48,7 @@ public static function apply($report, $tests, array $options = array()) {
xdebug_stop_code_coverage();
$report->collect(__CLASS__, array($self->subject() => $results));
};
- $tests->invoke('applyFilter', array($m, $filter));
+ $tests->invoke('applyFilter', array($options['method'], $filter));
return $tests;
}
View
17 tests/cases/action/RequestTest.php
@@ -177,6 +177,23 @@ public function testRequestWithoutUrlQueryParam() {
$this->assertEqual('pages/test_app', $request->url);
}
+ public function testRequestWithColon() {
+ unset($_GET['url']);
+ $request = new Request(array('env' => array(
+ 'PHP_SELF' => '/test_app/app/webroot/index.php',
+ 'REQUEST_URI' => '/test_app/pages/test_app/test:a'
+ )));
+ $this->assertEqual('/test_app', $request->env('base'));
+ $this->assertEqual('pages/test_app/test:a', $request->url);
+
+ $request = new Request(array('env' => array(
+ 'PHP_SELF' => '/test_app/app/webroot/index.php',
+ 'REQUEST_URI' => '/test_app/pages/test_app/test:1'
+ )));
+ $this->assertEqual('/test_app', $request->env('base'));
+ $this->assertEqual('pages/test_app/test:1', $request->url);
+ }
+
public function testRequestWithoutUrlQueryParamAndNoApp() {
unset($_GET['url']);
$request = new Request(array('env' => array(
View
37 tests/cases/net/http/ResponseTest.php
@@ -106,7 +106,7 @@ public function testConstructionWithBody() {
public function testParseMessage() {
$message = join("\r\n", array(
- 'HTTP/1.1 200 OK',
+ 'HTTP/1.1 404 Not Found',
'Header: Value',
'Connection: close',
'Content-Type: application/json;charset=iso-8859-1',
@@ -118,6 +118,9 @@ public function testParseMessage() {
$this->assertEqual($message, (string) $response);
$this->assertEqual('application/json', $response->type);
$this->assertEqual('ISO-8859-1', $response->encoding);
+ $this->assertEqual('404', $response->status['code']);
+ $this->assertEqual('Not Found', $response->status['message']);
+ $this->assertEqual('HTTP/1.1 404 Not Found', $response->status());
$body = 'Not a Message';
$expected = join("\r\n", array('HTTP/1.1 200 OK', '', '', 'Not a Message'));
@@ -307,6 +310,38 @@ public function testDigestParsing() {
$result = array_filter($response->digest());
$this->assertEqual($expected, $result);
}
+
+ public function testMalformedStatus() {
+ $expected = "HTTP/1.1 304 Not Modified";
+
+ $message = join("\r\n", array(
+ 'HTTP/1.1 304',
+ 'Header: Value',
+ 'Connection: close',
+ 'Content-Type: application/json;charset=iso-8859-1',
+ '',
+ 'Test!'
+ ));
+
+ $response = new Response(compact('message'));
+ $result = $response->status();
+ $this->assertEqual($expected, $result);
+
+ $expected = "HTTP/1.1 500 Internal Server Error";
+
+ $message = join("\r\n", array(
+ 'HTTP/1.1 500',
+ 'Header: Value',
+ 'Connection: close',
+ 'Content-Type: application/json;charset=iso-8859-1',
+ '',
+ 'Test!'
+ ));
+
+ $response = new Response(compact('message'));
+ $result = $response->status();
+ $this->assertEqual($expected, $result);
+ }
}
?>
View
10 tests/cases/net/http/ServiceTest.php
@@ -178,15 +178,15 @@ public function testDelete() {
public function testJsonPost() {
$http = new Service($this->_testConfig);
- $http->post('update.xml', array('status' => 'cool'), array('type' => 'json'));
+ $http->post('update.xml', array('status' => array('cool', 'awesome')), array('type' => 'json'));
$expected = join("\r\n", array(
'POST /update.xml HTTP/1.1',
'Host: localhost:80',
'Connection: Close',
'User-Agent: Mozilla/5.0',
'Content-Type: application/json',
- 'Content-Length: 17',
- '', '{"status":"cool"}'
+ 'Content-Length: 29',
+ '', '{"status":["cool","awesome"]}'
));
$result = (string) $http->last->request;
$this->assertEqual($expected, $result);
@@ -197,8 +197,8 @@ public function testJsonPost() {
'Connection: Close',
'User-Agent: Mozilla/5.0',
'Content-Type: application/json',
- 'Content-Length: 17',
- '', '{"status":"cool"}'
+ 'Content-Length: 29',
+ '', '{"status":["cool","awesome"]}'
));
$result = (string) $http->last->response;
$this->assertEqual($expected, $result);
View
13 tests/cases/net/socket/CurlTest.php
@@ -140,6 +140,19 @@ public function testSettingOfOptions() {
$this->assertEqual('Changed Dummy Value', $stream->options['DummyFlag']);
}
+ public function testSettingOfOptionsInConfig() {
+ $config = $this->_testConfig + array('options' => array('DummyFlag' => 'Dummy Value'));
+ $stream = new Curl($config);
+ $stream->open();
+ $this->assertEqual('Dummy Value', $stream->options['DummyFlag']);
+ }
+
+ public function testSettingOfOptionsInOpen() {
+ $stream = new Curl($this->_testConfig);
+ $stream->open(array('options' => array('DummyFlag' => 'Dummy Value')));
+ $this->assertEqual('Dummy Value', $stream->options['DummyFlag']);
+ }
+
public function testSendPostThenGet() {
$postConfig = array('method' => 'POST', 'body' => '{"body"}');
$stream = new Curl($this->_testConfig);
View
9 tests/cases/template/helper/FormTest.php
@@ -1241,9 +1241,16 @@ public function testFormCreationWithNoContext() {
* Tests that magic method support can be used to automatically generate a `<button />` tag
* based on the default string template.
*/
- public function testAutoMagicButton() {
+ public function testButton() {
$result = $this->form->button('Foo!', array('id' => 'bar'));
$this->assertTags($result, array('button' => array('id' => 'bar'), 'Foo!', '/button'));
+
+ $result = $this->form->button('Continue >', array('type' => 'submit'));
+ $this->assertTags($result, array(
+ 'button' => array('type' => 'submit', 'id' => 'Continue'),
+ 'Continue &gt;',
+ '/button'
+ ));
}
/**
Please sign in to comment.
Something went wrong with that request. Please try again.