Browse Source

Remove lithium source code from our repository

Hamilton Turner 10 years ago
parent
commit
1c79109868
100 changed files with 0 additions and 22504 deletions
  1. 0 5
      frameworks/PHP/php-lithium/libraries/lithium/.gitignore
  2. 0 20
      frameworks/PHP/php-lithium/libraries/lithium/.travis.yml
  3. 0 12
      frameworks/PHP/php-lithium/libraries/lithium/CONTRIBUTING.md
  4. 0 25
      frameworks/PHP/php-lithium/libraries/lithium/LICENSE.txt
  5. 0 313
      frameworks/PHP/php-lithium/libraries/lithium/action/Controller.php
  6. 0 21
      frameworks/PHP/php-lithium/libraries/lithium/action/DispatchException.php
  7. 0 269
      frameworks/PHP/php-lithium/libraries/lithium/action/Dispatcher.php
  8. 0 640
      frameworks/PHP/php-lithium/libraries/lithium/action/Request.php
  9. 0 175
      frameworks/PHP/php-lithium/libraries/lithium/action/Response.php
  10. 0 1
      frameworks/PHP/php-lithium/libraries/lithium/action/readme.md
  11. 0 205
      frameworks/PHP/php-lithium/libraries/lithium/analysis/Debugger.php
  12. 0 122
      frameworks/PHP/php-lithium/libraries/lithium/analysis/Docblock.php
  13. 0 590
      frameworks/PHP/php-lithium/libraries/lithium/analysis/Inspector.php
  14. 0 196
      frameworks/PHP/php-lithium/libraries/lithium/analysis/Logger.php
  15. 0 315
      frameworks/PHP/php-lithium/libraries/lithium/analysis/Parser.php
  16. 0 81
      frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/Cache.php
  17. 0 83
      frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/File.php
  18. 0 194
      frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/FirePhp.php
  19. 0 247
      frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/Growl.php
  20. 0 86
      frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/Syslog.php
  21. 0 22
      frameworks/PHP/php-lithium/libraries/lithium/composer.json
  22. 0 423
      frameworks/PHP/php-lithium/libraries/lithium/console/Command.php
  23. 0 202
      frameworks/PHP/php-lithium/libraries/lithium/console/Dispatcher.php
  24. 0 203
      frameworks/PHP/php-lithium/libraries/lithium/console/Request.php
  25. 0 142
      frameworks/PHP/php-lithium/libraries/lithium/console/Response.php
  26. 0 55
      frameworks/PHP/php-lithium/libraries/lithium/console/Router.php
  27. 0 260
      frameworks/PHP/php-lithium/libraries/lithium/console/command/Create.php
  28. 0 36
      frameworks/PHP/php-lithium/libraries/lithium/console/command/G11n.php
  29. 0 322
      frameworks/PHP/php-lithium/libraries/lithium/console/command/Help.php
  30. 0 729
      frameworks/PHP/php-lithium/libraries/lithium/console/command/Library.php
  31. 0 140
      frameworks/PHP/php-lithium/libraries/lithium/console/command/Route.php
  32. 0 325
      frameworks/PHP/php-lithium/libraries/lithium/console/command/Test.php
  33. 0 84
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Controller.php
  34. 0 74
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Mock.php
  35. 0 33
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Model.php
  36. 0 105
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Test.php
  37. 0 92
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/View.php
  38. BIN
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/app.phar.gz
  39. 0 47
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/controller.txt.php
  40. 0 6
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/mock.txt.php
  41. 0 6
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/model.txt.php
  42. BIN
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/plugin.phar.gz
  43. BIN
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/test-app-replacements.phar.gz
  44. 0 12
      frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/test.txt.php
  45. 0 173
      frameworks/PHP/php-lithium/libraries/lithium/console/command/g11n/Extract.php
  46. 0 9
      frameworks/PHP/php-lithium/libraries/lithium/console/li3
  47. 0 8
      frameworks/PHP/php-lithium/libraries/lithium/console/li3.bat
  48. 0 112
      frameworks/PHP/php-lithium/libraries/lithium/console/lithium.php
  49. 0 191
      frameworks/PHP/php-lithium/libraries/lithium/console/readme.md
  50. 0 331
      frameworks/PHP/php-lithium/libraries/lithium/core/Adaptable.php
  51. 0 20
      frameworks/PHP/php-lithium/libraries/lithium/core/ClassNotFoundException.php
  52. 0 20
      frameworks/PHP/php-lithium/libraries/lithium/core/ConfigException.php
  53. 0 348
      frameworks/PHP/php-lithium/libraries/lithium/core/Environment.php
  54. 0 326
      frameworks/PHP/php-lithium/libraries/lithium/core/ErrorHandler.php
  55. 0 1079
      frameworks/PHP/php-lithium/libraries/lithium/core/Libraries.php
  56. 0 21
      frameworks/PHP/php-lithium/libraries/lithium/core/NetworkException.php
  57. 0 292
      frameworks/PHP/php-lithium/libraries/lithium/core/Object.php
  58. 0 175
      frameworks/PHP/php-lithium/libraries/lithium/core/StaticObject.php
  59. 0 625
      frameworks/PHP/php-lithium/libraries/lithium/data/Collection.php
  60. 0 189
      frameworks/PHP/php-lithium/libraries/lithium/data/Connections.php
  61. 0 116
      frameworks/PHP/php-lithium/libraries/lithium/data/DocumentSchema.php
  62. 0 494
      frameworks/PHP/php-lithium/libraries/lithium/data/Entity.php
  63. 0 1377
      frameworks/PHP/php-lithium/libraries/lithium/data/Model.php
  64. 0 177
      frameworks/PHP/php-lithium/libraries/lithium/data/Schema.php
  65. 0 301
      frameworks/PHP/php-lithium/libraries/lithium/data/Source.php
  66. 0 139
      frameworks/PHP/php-lithium/libraries/lithium/data/collection/DocumentSet.php
  67. 0 264
      frameworks/PHP/php-lithium/libraries/lithium/data/collection/MultiKeyRecordSet.php
  68. 0 245
      frameworks/PHP/php-lithium/libraries/lithium/data/collection/RecordSet.php
  69. 0 478
      frameworks/PHP/php-lithium/libraries/lithium/data/entity/Document.php
  70. 0 33
      frameworks/PHP/php-lithium/libraries/lithium/data/entity/Record.php
  71. 0 828
      frameworks/PHP/php-lithium/libraries/lithium/data/model/Query.php
  72. 0 22
      frameworks/PHP/php-lithium/libraries/lithium/data/model/QueryException.php
  73. 0 174
      frameworks/PHP/php-lithium/libraries/lithium/data/model/Relationship.php
  74. 0 1483
      frameworks/PHP/php-lithium/libraries/lithium/data/source/Database.php
  75. 0 311
      frameworks/PHP/php-lithium/libraries/lithium/data/source/Http.php
  76. 0 64
      frameworks/PHP/php-lithium/libraries/lithium/data/source/Mock.php
  77. 0 844
      frameworks/PHP/php-lithium/libraries/lithium/data/source/MongoDb.php
  78. 0 196
      frameworks/PHP/php-lithium/libraries/lithium/data/source/Result.php
  79. 0 363
      frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/MySql.php
  80. 0 439
      frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/PostgreSql.php
  81. 0 327
      frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/Sqlite3.php
  82. 0 57
      frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/pdo/Result.php
  83. 0 512
      frameworks/PHP/php-lithium/libraries/lithium/data/source/http/adapter/CouchDb.php
  84. 0 189
      frameworks/PHP/php-lithium/libraries/lithium/data/source/mongo_db/Exporter.php
  85. 0 33
      frameworks/PHP/php-lithium/libraries/lithium/data/source/mongo_db/Result.php
  86. 0 58
      frameworks/PHP/php-lithium/libraries/lithium/data/source/mongo_db/Schema.php
  87. 0 152
      frameworks/PHP/php-lithium/libraries/lithium/g11n/Catalog.php
  88. 0 321
      frameworks/PHP/php-lithium/libraries/lithium/g11n/Locale.php
  89. 0 220
      frameworks/PHP/php-lithium/libraries/lithium/g11n/Message.php
  90. 0 168
      frameworks/PHP/php-lithium/libraries/lithium/g11n/Multibyte.php
  91. 0 102
      frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/Adapter.php
  92. 0 191
      frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Code.php
  93. 0 519
      frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Gettext.php
  94. 0 67
      frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Memory.php
  95. 0 121
      frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Php.php
  96. 0 81
      frameworks/PHP/php-lithium/libraries/lithium/g11n/multibyte/adapter/Iconv.php
  97. 0 83
      frameworks/PHP/php-lithium/libraries/lithium/g11n/multibyte/adapter/Intl.php
  98. 0 81
      frameworks/PHP/php-lithium/libraries/lithium/g11n/multibyte/adapter/Mbstring.php
  99. 0 16
      frameworks/PHP/php-lithium/libraries/lithium/g11n/resources/php/da_DK/validation/default.php
  100. 0 21
      frameworks/PHP/php-lithium/libraries/lithium/g11n/resources/php/de/message/default.php

+ 0 - 5
frameworks/PHP/php-lithium/libraries/lithium/.gitignore

@@ -1,5 +0,0 @@
-# OS X
-.DS_Store
-
-# Vim
-.*.sw[a-z]

+ 0 - 20
frameworks/PHP/php-lithium/libraries/lithium/.travis.yml

@@ -1,20 +0,0 @@
-language: php
-
-env:
-  - OPCODE_CACHE=apc
- #- OPCODE_CACHE=xcache
-
-php:
-  - 5.3
-  - 5.4
-
-before_script:
- - php tests/ci_depends.php $OPCODE_CACHE
-# - cd ../ && git clone git://github.com/UnionOfRAD/li3_quality.git && cd lithium
-
-script:
- - console/li3 test --filters=Profiler tests/cases
-# - console/li3 test --filters=Profiler tests/cases && cd ../li3_quality && for FILE in $(cd ../lithium/ && git diff-index --name-only --diff-filter=AM HEAD~1); do ../lithium/console/li3 quality syntax ../lithium/${FILE} --silent; done
-
-notifications:
-    irc: "irc.freenode.org#li3-core"

+ 0 - 12
frameworks/PHP/php-lithium/libraries/lithium/CONTRIBUTING.md

@@ -1,12 +0,0 @@
-# Contributing guidelines
-
-Thank you for your interest in contributing to Lithium! This project is built by a thriving community of developers who value cutting-edge technology and concise, maintainable code. If you've found a bug, or have an idea for a feature, we encourage your participation in making Lithium better.
-
-Here's what you need to stick to in order to have the best chance of getting your code pushed to the core:
-
- * **Integration**: all pull requests should be submitted against the [`dev`](https://github.com/UnionOfRAD/lithium/tree/dev) branch for integration testing
- * **Conceptual integrity**: code should conform to the goals of the framework
- * **Maintainability**: code should pass existing tests, have adequate test coverage and should conform to our coding standards & QA guidelines
- * **Comprehensibility**: code should be concise and expressive, and should be accompanied by new documentation as appropriate, or updates to existing docs
-
-Please see the full documentation over at the [contribution guidelines](http://lithify.me/docs/manual/appendices/contributing.wiki) at [lithify.me](http://lithify.me/)

+ 0 - 25
frameworks/PHP/php-lithium/libraries/lithium/LICENSE.txt

@@ -1,25 +0,0 @@
-Copyright (c) 2013, Union of RAD http://union-of-rad.org
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-		this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-		this list of conditions and the following disclaimer in the documentation
-		and/or other materials provided with the distribution.
-    * Neither the name of Lithium, Union of Rad, nor the names of its contributors 
-		may be used to endorse or promote products derived from this software 
-		without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
-OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 313
frameworks/PHP/php-lithium/libraries/lithium/action/Controller.php

@@ -1,313 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\action;
-
-use lithium\util\Inflector;
-use lithium\action\DispatchException;
-use lithium\core\Libraries;
-
-/**
- * The `Controller` class is the fundamental building block of your application's request/response
- * cycle. Controllers are organized around a single logical entity, usually one or more model
- * classes (i.e. `lithium\data\Model`) and are tasked with performing operations against that
- * entity.
- *
- * Each controller has a series of 'actions' which are defined as class methods of the `Controller`
- * classes. Each action has a specific responsibility, such as listing a set of objects, updating an
- * object, or deleting an object.
- *
- * A controller object is instantiated by the `Dispatcher` (`lithium\action\Dispatcher`), and is
- * given an instance of the `lithium\action\Request` class, which contains all necessary request
- * state, including routing information, `GET` & `POST` data, and server variables. The controller
- * is then invoked (using PHP's magic `__invoke()` syntax), and the proper action is called,
- * according to the routing information stored in the `Request` object.
- *
- * A controller then returns a response (i.e. using `redirect()` or `render()`) which includes HTTP
- * headers, and/or a serialized data response (JSON or XML, etc.) or HTML webpage.
- *
- * For more information on returning serialized data responses for web services, or manipulating
- * template rendering from within your controllers, see the settings in `$_render` and the
- * `lithium\net\http\Media` class.
- *
- * @see lithium\net\http\Media
- * @see lithium\action\Dispatcher
- * @see lithium\action\Controller::$_render
- */
-class Controller extends \lithium\core\Object {
-
-	/**
-	 * Contains an instance of the `Request` object with all the details of the HTTP request that
-	 * was dispatched to the controller object. Any parameters captured in routing, such as
-	 * controller or action name are accessible as properties of this object, i.e.
-	 * `$this->request->controller` or `$this->request->action`.
-	 *
-	 * @see lithium\action\Request
-	 * @var object
-	 */
-	public $request = null;
-
-	/**
-	 * Contains an instance of the `Response` object which aggregates the headers and body content
-	 * to be written back to the client (browser) when the result of the request is rendered.
-	 *
-	 * @see lithium\action\Response
-	 * @var object
-	 */
-	public $response = null;
-
-	/**
-	 * Lists the rendering control options for responses generated by this controller.
-	 *
-	 * - The `'type'` key is the content type that will be rendered by default, unless another is
-	 *   explicitly specified (defaults to `'html'`).
-	 * - The `'data'` key contains an associative array of variables to be sent to the view,
-	 *   including any variables created in `set()`, or if an action returns any variables (as an
-	 *   associative array).
-	 * - When an action is invoked, it will by default attempt to render a response, set the
-	 *   `'auto'` key to `false` to prevent this behavior.
-	 * - If you manually call `render()` within an action, the `'hasRendered'` key stores this
-	 *   state, so that responses are not rendered multiple times, either manually or automatically.
-	 * - The `'layout'` key specifies the name of the layout to be used (defaults to `'default'`).
-	 *   Typically, layout files are looked up as
-	 *   `<app-path>/views/layouts/<layout-name>.<type>.php`. Based on the default settings, the
-	 *   actual path would be `path-to-app/views/layouts/default.html.php`.
-	 * - Though typically introspected from the action that is executed, the `'template'` key can be
-	 *   manually specified. This sets the template to be rendered, and is looked up (by default) as
-	 *   `<app-path>/views/<controller>/<action>.<type>.php`, i.e.:
-	 *   `path-to-app/views/posts/index.html.php`.
-	 * - To enable automatic content-type negotiation (i.e. determining the content type of the
-	 *   response based on the value of the
-	 *   [HTTP Accept header](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html)), set the
-	 *   `'negotiate'` flag to `true`. Otherwise, the response will only be based on the `type`
-	 *   parameter of the request object (defaulting to `'html'` if no type is present in the
-	 *   `Request` parameters).
-	 *
-	 * Keep in mind that most of these settings may be passed to `Controller::render()` as well. To
-	 * change how these settings operate (i.e. template paths, default render settings for
-	 * individual media types), see the `Media` class.
-	 *
-	 * @var array
-	 * @see lithium\action\Controller::render()
-	 * @see lithium\net\http\Media::type()
-	 * @see lithium\net\http\Media::render()
-	 */
-	protected $_render = array(
-		'type'        => null,
-		'data'        => array(),
-		'auto'        => true,
-		'layout'      => 'default',
-		'template'    => null,
-		'hasRendered' => false,
-		'negotiate'   => false
-	);
-
-	/**
-	 * Lists `Controller`'s class dependencies. For details on extending or replacing a class,
-	 * please refer to that class's API.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'media' => 'lithium\net\http\Media',
-		'router' => 'lithium\net\http\Router',
-		'response' => 'lithium\action\Response'
-	);
-
-	/**
-	 * Auto configuration properties.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('render' => 'merge', 'classes' => 'merge');
-
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'request' => null, 'response' => array(), 'render' => array(), 'classes' => array()
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Populates the `$response` property with a new instance of the `Response` class passing it
-	 * configuration, and sets some rendering options, depending on the incoming request.
-	 *
-	 * @return void
-	 */
-	protected function _init() {
-		parent::_init();
-		$this->request = $this->request ?: $this->_config['request'];
-		$this->response = $this->_instance('response', $this->_config['response']);
-
-		if (!$this->request || $this->_render['type']) {
-			return;
-		}
-		if ($this->_render['negotiate']) {
-			$this->_render['type'] = $this->request->accepts();
-			return;
-		}
-		$this->_render['type'] = $this->request->get('params:type') ?: 'html';
-	}
-
-	/**
-	 * Called by the Dispatcher class to invoke an action.
-	 *
-	 * @param object $request The request object with URL and HTTP info for dispatching this action.
-	 * @param array $dispatchParams The array of parameters that will be passed to the action.
-	 * @param array $options The dispatch options for this action.
-	 * @return object Returns the response object associated with this controller.
-	 * @filter This method can be filtered.
-	 */
-	public function __invoke($request, $dispatchParams, array $options = array()) {
-		$render =& $this->_render;
-		$params = compact('request', 'dispatchParams', 'options');
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use (&$render) {
-			$dispatchParams = $params['dispatchParams'];
-
-			$action = isset($dispatchParams['action']) ? $dispatchParams['action'] : 'index';
-			$args = isset($dispatchParams['args']) ? $dispatchParams['args'] : array();
-			$result = null;
-
-			if (substr($action, 0, 1) === '_' || method_exists(__CLASS__, $action)) {
-				throw new DispatchException('Attempted to invoke a private method.');
-			}
-			if (!method_exists($self, $action)) {
-				throw new DispatchException("Action `{$action}` not found.");
-			}
-			$render['template'] = $render['template'] ?: $action;
-
-			if ($result = $self->invokeMethod($action, $args)) {
-				if (is_string($result)) {
-					$self->render(array('text' => $result));
-					return $self->response;
-				}
-				if (is_array($result)) {
-					$self->set($result);
-				}
-			}
-
-			if (!$render['hasRendered'] && $render['auto']) {
-				$self->render();
-			}
-			return $self->response;
-		});
-	}
-
-	/**
-	 * This method is used to pass along any data from the controller to the view and layout
-	 *
-	 * @param array $data sets of `<variable name> => <variable value>` to pass to view layer.
-	 * @return void
-	 */
-	public function set($data = array()) {
-		$this->_render['data'] = (array) $data + $this->_render['data'];
-	}
-
-	/**
-	 * Uses results (typically coming from a controller action) to generate content and headers for
-	 * a `Response` object.
-	 *
-	 * @see lithium\action\Controller::$_render
-	 * @param array $options An array of options, as follows:
-	 *        - `'data'`: An associative array of variables to be assigned to the template. These
-	 *          are merged on top of any variables set in `Controller::set()`.
-	 *        - `'head'`: If true, only renders the headers of the response, not the body. Defaults
-	 *          to `false`.
-	 *        - `'template'`: The name of a template, which usually matches the name of the action.
-	 *          By default, this template is looked for in the views directory of the current
-	 *          controller, i.e. given a `PostsController` object, if template is set to `'view'`,
-	 *          the template path would be `views/posts/view.html.php`. Defaults to the name of the
-	 *          action being rendered.
-	 *
-	 * The options specified here are merged with the values in the `Controller::$_render`
-	 * property. You may refer to it for other options accepted by this method.
-	 * @return object Returns the `Response` object associated with this `Controller` instance.
-	 */
-	public function render(array $options = array()) {
-		$media = $this->_classes['media'];
-		$class = get_class($this);
-		$name = preg_replace('/Controller$/', '', substr($class, strrpos($class, '\\') + 1));
-		$key = key($options);
-
-		if (isset($options['data'])) {
-			$this->set($options['data']);
-			unset($options['data']);
-		}
-		$defaults = array(
-			'status'     => null,
-			'location'   => false,
-			'data'       => null,
-			'head'       => false,
-			'controller' => Inflector::underscore($name),
-			'library'    => Libraries::get($class)
-		);
-
-		$options += $this->_render + $defaults;
-
-		if ($key && $media::type($key)) {
-			$options['type'] = $key;
-			$this->set($options[$key]);
-			unset($options[$key]);
-		}
-
-		$this->_render['hasRendered'] = true;
-		$this->response->type($options['type']);
-		$this->response->status($options['status']);
-		$this->response->headers('Location', $options['location']);
-
-		if ($options['head']) {
-			return;
-		}
-		$response = $media::render($this->response, $this->_render['data'], $options + array(
-			'request' => $this->request
-		));
-		return ($this->response = $response ?: $this->response);
-	}
-
-	/**
-	 * Creates a redirect response by calling `render()` and providing a `'location'` parameter.
-	 *
-	 * @see lithium\net\http\Router::match()
-	 * @see lithium\action\Controller::$response
-	 * @param mixed $url The location to redirect to, provided as a string relative to the root of
-	 *              the application, a fully-qualified URL, or an array of routing parameters to be
-	 *              resolved to a URL. Post-processed by `Router::match()`.
-	 * @param array $options Options when performing the redirect. Available options include:
-	 *              - `'status'` _integer_: The HTTP status code associated with the redirect.
-	 *                Defaults to `302`.
-	 *              - `'head'` _boolean_: Determines whether only headers are returned with the
-	 *                response. Defaults to `true`, in which case only headers and no body are
-	 *                returned. Set to `false` to render a body as well.
-	 *              - `'exit'` _boolean_: Exit immediately after rendering. Defaults to `false`.
-	 *                Because `redirect()` does not exit by default, you should always prefix calls
-	 *                with a `return` statement, so that the action is always immediately exited.
-	 * @return object Returns the instance of the `Response` object associated with this controller.
-	 * @filter This method can be filtered.
-	 */
-	public function redirect($url, array $options = array()) {
-		$router = $this->_classes['router'];
-		$defaults = array('location' => null, 'status' => 302, 'head' => true, 'exit' => false);
-		$options += $defaults;
-		$params = compact('url', 'options');
-
-		$this->_filter(__METHOD__, $params, function($self, $params) use ($router) {
-			$options = $params['options'];
-			$location = $options['location'] ?: $router::match($params['url'], $self->request);
-			$self->render(compact('location') + $options);
-		});
-
-		if ($options['exit']) {
-			$this->response->render();
-			$this->_stop();
-		}
-		return $this->response;
-	}
-}
-
-?>

+ 0 - 21
frameworks/PHP/php-lithium/libraries/lithium/action/DispatchException.php

@@ -1,21 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\action;
-
-/**
- * This exception covers a range of scenarios that generally revolve around attempting to dispatch
- * to something which cannot handle a request, i.e. a controller which can't be found, objects
- * which aren't callable, or un-routable (private) controller methods.
- */
-class DispatchException extends \RuntimeException {
-
-	protected $code = 404;
-}
-
-?>

+ 0 - 269
frameworks/PHP/php-lithium/libraries/lithium/action/Dispatcher.php

@@ -1,269 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\action;
-
-use lithium\util\String;
-use lithium\util\Inflector;
-use lithium\core\Libraries;
-use lithium\action\DispatchException;
-use lithium\core\ClassNotFoundException;
-
-/**
- * `Dispatcher` is the outermost layer of the framework, responsible for both receiving the initial
- * HTTP request and sending back a response at the end of the request's life cycle.
- *
- * After either receiving or instantiating a `Request` object instance, the `Dispatcher` passes that
- * instance to the `Router`, which produces the parameters necessary to dispatch the request
- * (unless no route matches, in which case an exception is thrown).
- *
- * Using these parameters, the `Dispatcher` loads and instantiates the correct `Controller` object,
- * and passes it the `Request` object instance. The `Controller` returns a `Response` object to the
- * `Dispatcher`, where the headers and content are rendered and sent to the browser.
- *
- * @see lithium\net\http\Router
- * @see lithium\action\Request
- * @see lithium\action\Response
- * @see lithium\action\Controller
- */
-class Dispatcher extends \lithium\core\StaticObject {
-
-	/**
-	 * Fully-namespaced router class reference.  Class must implement a `parse()` method,
-	 * which must return an array with (at a minimum) 'controller' and 'action' keys.
-	 *
-	 * @see lithium\net\http\Router::parse()
-	 * @var array
-	 */
-	protected static $_classes = array(
-		'router' => 'lithium\net\http\Router'
-	);
-
-	/**
-	 * Contains pre-process format strings for changing Dispatcher's behavior based on 'rules'.
-	 *
-	 * Each key in the array represents a 'rule'; if a key that matches the rule is present (and
-	 * not empty) in a route, (i.e. the result of `lithium\net\http\Router::parse()`) then the
-	 * rule's value will be applied to the route before it is dispatched.  When applying a rule, any
-	 * array elements of the flag which are present in the route will be modified
-	 * using a `lithium\util\String::insert()`-formatted string.  Alternatively,
-	 * a callback can be used to do custom transformations other than the
-	 * default `lithium\util\String::insert()`.
-	 *
-	 * For example, to implement action prefixes (i.e. `admin_index()`), set a rule named 'admin',
-	 * with a value array containing a modifier key for the `action` element of a route, i.e.:
-	 * `array('action' => 'admin_{:action}')`. Now, if the `'admin'` key is present and not empty
-	 * in the parameters returned from routing, the value of `'action'` will be rewritten per the
-	 * settings in the rule.
-	 *
-	 * Here's another example.  To support normalizing actions,
-	 * set a rule named 'action' with a value array containing a callback that uses
-	 * `lithium\util\Inflector` to camelize the action:
-	 *
-	 * {{{
-	 * use lithium\action\Dispatcher;
-	 * use lithium\util\Inflector;
-	 *
-	 * Dispatcher::config(array('rules' => array(
-	 * 	'action' => array('action' => function($params) {
-	 * 		return Inflector::camelize(strtolower($params['action']), false);
-	 * 	})
-	 * )));
-	 * }}}
-	 *
-	 * The rules can be a callback as well:
-	 *
-	 * {{{
-	 * Dispatcher::config(array('rules' => function($params) {
-	 * 	if (isset($params['admin'])) {
-	 * 		return array('special' => array('action' => 'special_{:action}'));
-	 * 	}
-	 * 	return array();
-	 * }));
-	 * }}}
-	 *
-	 * @see lithium\action\Dispatcher::config()
-	 * @see lithium\util\String::insert()
-	 */
-	protected static $_rules = array();
-
-	/**
-	 * Used to set configuration parameters for the `Dispatcher`.
-	 *
-	 * @see lithium\action\Dispatcher::$_rules
-	 * @param array $config Possible key settings are `'classes'` which sets the class dependencies
-	 *              for `Dispatcher` (i.e. `'request'` or `'router'`) and `'rules'`, which sets the
-	 *              pre-processing rules for routing parameters. For more information on the
-	 *              `'rules'` setting, see the `$_rules` property.
-	 * @return array If no parameters are passed, returns an associative array with the current
-	 *         configuration, otherwise returns `null`.
-	 */
-	public static function config(array $config = array()) {
-		if (!$config) {
-			return array('rules' => static::$_rules);
-		}
-
-		foreach ($config as $key => $val) {
-			$key = "_{$key}";
-			if (!is_array($val)) {
-				static::${$key} = $val;
-				continue;
-			}
-			if (isset(static::${$key})) {
-				static::${$key} = $val + static::${$key};
-			}
-		}
-	}
-
-	/**
-	 * Dispatches a request based on a request object (an instance or subclass of
-	 * `lithium\net\http\Request`).
-	 *
-	 * @see lithium\action\Request
-	 * @see lithium\action\Response
-	 * @param object $request An instance of a request object (usually `lithium\action\Request`)
-	 *               with HTTP request information.
-	 * @param array $options
-	 * @return mixed Returns the value returned from the callable object retrieved from
-	 *         `Dispatcher::_callable()`, which is either a string or an instance of
-	 *         `lithium\action\Response`.
-	 * @filter
-	 */
-	public static function run($request, array $options = array()) {
-		$router = static::$_classes['router'];
-		$params = compact('request', 'options');
-
-		return static::_filter(__FUNCTION__, $params, function($self, $params) use ($router) {
-			$request = $params['request'];
-			$options = $params['options'];
-
-			if (($result = $router::process($request)) instanceof Response) {
-				return $result;
-			}
-			$params = $self::applyRules($result->params);
-
-			if (!$params) {
-				throw new DispatchException('Could not route request.');
-			}
-			$callable = $self::invokeMethod('_callable', array($result, $params, $options));
-			return $self::invokeMethod('_call', array($callable, $result, $params));
-		});
-	}
-
-	/**
-	 * Attempts to apply a set of formatting rules from `$_rules` to a `$params` array, where each
-	 * formatting rule is applied if the key of the rule in `$_rules` is present and not empty in
-	 * `$params`.  Also performs sanity checking against `$params` to ensure that no value
-	 * matching a rule is present unless the rule check passes.
-	 *
-	 * @param array $params An array of route parameters to which rules will be applied.
-	 * @return array Returns the `$params` array with formatting rules applied to array values.
-	 */
-	public static function applyRules(&$params) {
-		$result = array();
-		$values = array();
-		$rules = static::$_rules;
-
-		if (!$params) {
-			return false;
-		}
-
-		if (isset($params['controller']) && is_string($params['controller'])) {
-			$controller = $params['controller'];
-
-			if (strpos($controller, '.') !== false) {
-				list($library, $controller) = explode('.', $controller);
-				$controller = $library . '.' . Inflector::camelize($controller);
-				$params += compact('library');
-			} elseif (strpos($controller, '\\') === false) {
-				$controller = Inflector::camelize($controller);
-
-				if (isset($params['library'])) {
-					$controller = "{$params['library']}.{$controller}";
-				}
-			}
-			$values = compact('controller');
-		}
-		$values += $params;
-
-		if (is_callable($rules)) {
-			$rules = $rules($params);
-		}
-		foreach ($rules as $rule => $value) {
-			if (!isset($values[$rule])) {
-				continue;
-			}
-			foreach ($value as $k => $v) {
-				if (is_callable($v)) {
-					$result[$k] = $v($values);
-					continue;
-				}
-				$match = preg_replace('/\{:\w+\}/', '@', $v);
-				$match = preg_replace('/@/', '.+', preg_quote($match, '/'));
-				if (preg_match('/' . $match . '/i', $values[$k])) {
-					continue;
-				}
-				$result[$k] = String::insert($v, $values);
-			}
-		}
-		return $result + $values;
-	}
-
-	/**
-	 * Accepts parameters generated by the `Router` class in `Dispatcher::run()`, and produces a
-	 * callable controller object. By default, this method uses the `'controller'` path lookup
-	 * configuration in `Libraries::locate()` to return a callable object.
-	 *
-	 * @param object $request The instance of the `Request` class either passed into or generated by
-	 *               `Dispatcher::run()`.
-	 * @param array $params The parameter array generated by routing the request.
-	 * @param array $options Not currently implemented.
-	 * @return object Returns a callable object which the request will be routed to.
-	 * @filter
-	 */
-	protected static function _callable($request, $params, $options) {
-		$params = compact('request', 'params', 'options');
-
-		return static::_filter(__FUNCTION__, $params, function($self, $params) {
-			$options = array('request' => $params['request']) + $params['options'];
-			$controller = $params['params']['controller'];
-
-			try {
-				return Libraries::instance('controllers', $controller, $options);
-			} catch (ClassNotFoundException $e) {
-				throw new DispatchException("Controller `{$controller}` not found.", null, $e);
-			}
-		});
-	}
-
-	/**
-	 * Invokes the callable object returned by `_callable()`, and returns the results, usually a
-	 * `Response` object instance.
-	 *
-	 * @see lithium\action
-	 * @param object $callable Typically a closure or instance of `lithium\action\Controller`.
-	 * @param object $request An instance of `lithium\action\Request`.
-	 * @param array $params An array of parameters to pass to `$callable`, along with `$request`.
-	 * @return mixed Returns the return value of `$callable`, usually an instance of
-	 *         `lithium\action\Response`.
-	 * @throws lithium\action\DispatchException Throws an exception if `$callable` is not a
-	 *         `Closure`, or does not declare the PHP magic `__invoke()` method.
-	 * @filter
-	 */
-	protected static function _call($callable, $request, $params) {
-		$params = compact('callable', 'request', 'params');
-		return static::_filter(__FUNCTION__, $params, function($self, $params) {
-			if (is_callable($callable = $params['callable'])) {
-				return $callable($params['request'], $params['params']);
-			}
-			throw new DispatchException('Result not callable.');
-		});
-	}
-}
-
-?>

+ 0 - 640
frameworks/PHP/php-lithium/libraries/lithium/action/Request.php

@@ -1,640 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\action;
-
-use lithium\util\Set;
-use lithium\util\Validator;
-
-/**
- * A `Request` object is passed into the `Dispatcher`, and is responsible for identifying and
- * storing all the information about an HTTP request made to an application,  including status,
- * headers, and any GET, POST or PUT data, as well as any data returned from the
- * `Router`, after the `Request` object has been matched against a `Route`. Includes a property
- * accessor method (`__get()`) which allows any parameters returned from routing to be accessed as
- * properties of the `Request` object.
- *
- * @see lithium\action\Dispatcher
- * @see lithium\action\Controller
- * @see lithium\net\http\Router
- * @see lithium\net\http\Route
- * @see lithium\action\Request::__get()
- */
-class Request extends \lithium\net\http\Request {
-
-	/**
-	 * Current url of request.
-	 *
-	 * @var string
-	 */
-	public $url = null;
-
-	/**
-	 * Params for request.
-	 *
-	 * @var array
-	 */
-	public $params = array();
-
-	/**
-	 * Route parameters that should persist when generating URLs in this request context.
-	 *
-	 * @var array
-	 */
-	public $persist = array();
-
-	/**
-	 * POST data.
-	 *
-	 * @var data
-	 */
-	public $data = array();
-
-	/**
-	 * GET data.
-	 *
-	 * @var string
-	 */
-	public $query = array();
-
-	/**
-	 * Base path.
-	 *
-	 * @var string
-	 */
-	protected $_base = null;
-
-	/**
-	 * Holds the environment variables for the request. Retrieved with env().
-	 *
-	 * @var array
-	 * @see lithium\action\Request::env()
-	 */
-	protected $_env = array();
-
-	/**
-	 * Classes used by `Request`.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array('media' => 'lithium\net\http\Media');
-
-	/**
-	 * If POST / PUT data is coming from an input stream (rather than `$_POST`), this specified
-	 * where to read it from.
-	 *
-	 * @var stream
-	 */
-	protected $_stream = null;
-
-	/**
-	 * Options used to detect request type.
-	 *
-	 * @see lithium\action\Request::detect()
-	 * @var array
-	 */
-	protected $_detectors = array(
-		'mobile'  => array('HTTP_USER_AGENT', null),
-		'ajax'    => array('HTTP_X_REQUESTED_WITH', 'XMLHttpRequest'),
-		'flash'   => array('HTTP_USER_AGENT', 'Shockwave Flash'),
-		'ssl'     => 'HTTPS',
-		'get'     => array('REQUEST_METHOD', 'GET'),
-		'post'    => array('REQUEST_METHOD', 'POST'),
-		'put'     => array('REQUEST_METHOD', 'PUT'),
-		'delete'  => array('REQUEST_METHOD', 'DELETE'),
-		'head'    => array('REQUEST_METHOD', 'HEAD'),
-		'options' => array('REQUEST_METHOD', 'OPTIONS')
-	);
-
-	/**
-	 * Auto configuration properties.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array(
-		'classes' => 'merge', 'env', 'detectors' => 'merge', 'base', 'type', 'stream'
-	);
-
-	/**
-	 * Contains an array of content-types, sorted by quality (the priority which the browser
-	 * requests each type).
-	 *
-	 * @var array
-	 */
-	protected $_acceptContent = array();
-
-	/**
-	 * Holds the value of the current locale, set through the `locale()` method.
-	 *
-	 * @var string
-	 */
-	protected $_locale = null;
-
-	/**
-	 * Initialize request object, pulling request data from superglobals.
-	 *
-	 * Defines an artificial `'PLATFORM'` environment variable as either
-	 * `'IIS'`, `'CGI'` or `null` to allow checking for the SAPI in a
-	 * normalized way.
-	 *
-	 * @return void
-	 */
-	protected function _init() {
-		parent::_init();
-
-		$mobile = array(
-			'iPhone', 'MIDP', 'AvantGo', 'BlackBerry', 'J2ME', 'Opera Mini', 'DoCoMo', 'NetFront',
-			'Nokia', 'PalmOS', 'PalmSource', 'portalmmm', 'Plucker', 'ReqwirelessWeb', 'iPod',
-			'SonyEricsson', 'Symbian', 'UP\.Browser', 'Windows CE', 'Xiino', 'Android'
-		);
-		if (!empty($this->_config['detectors']['mobile'][1])) {
-			$mobile = array_merge($mobile, (array) $this->_config['detectors']['mobile'][1]);
-		}
-		$this->_detectors['mobile'][1] = $mobile;
-		$defaults = array('REQUEST_METHOD' => 'GET', 'CONTENT_TYPE' => 'text/html');
-		$this->_env += (array) $_SERVER + (array) $_ENV + $defaults;
-		$envs = array('isapi' => 'IIS', 'cgi' => 'CGI', 'cgi-fcgi' => 'CGI');
-		$this->_env['PLATFORM'] = isset($envs[PHP_SAPI]) ? $envs[PHP_SAPI] : null;
-		$this->_base = $this->_base();
-		$this->url = $this->_url();
-
-		if (!empty($this->_config['query'])) {
-			$this->query = $this->_config['query'];
-		}
-		if (isset($_GET)) {
-			$this->query += $_GET;
-		}
-		if (!empty($this->_config['data'])) {
-			$this->data = $this->_config['data'];
-		}
-		if (isset($_POST)) {
-			$this->data += $_POST;
-		}
-		if (isset($this->data['_method'])) {
-			$this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'] = strtoupper($this->data['_method']);
-			unset($this->data['_method']);
-		}
-		if (!empty($this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
-			$this->_env['REQUEST_METHOD'] = $this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'];
-		}
-		$type = $this->type($this->_config['type'] ?: $this->env('CONTENT_TYPE'));
-		$this->method = $method = strtoupper($this->_env['REQUEST_METHOD']);
-		$hasBody = in_array($method, array('POST', 'PUT', 'PATCH'));
-
-		if (!$this->data && $hasBody && $type !== 'html') {
-			$this->_stream = $this->_stream ?: fopen('php://input', 'r');
-			$media = $this->_classes['media'];
-			$this->data = (array) $media::decode($type, stream_get_contents($this->_stream));
-			fclose($this->_stream);
-		}
-		$this->data = Set::merge((array) $this->data, $this->_parseFiles());
-	}
-
-	/**
-	 * Allows request parameters to be accessed as object properties, i.e. `$this->request->action`
-	 * instead of `$this->request->params['action']`.
-	 *
-	 * @see lithium\action\Request::$params
-	 * @param string $name The property name/parameter key to return.
-	 * @return mixed Returns the value of `$params[$name]` if it is set, otherwise returns null.
-	 */
-	public function __get($name) {
-		if (isset($this->params[$name])) {
-			return $this->params[$name];
-		}
-	}
-
-	/**
-	 * Allows request parameters to be checked using short-hand notation. See the `__get()` method
-	 * for more details.
-	 *
-	 * @see lithium\action\Request::__get()
-	 * @param string $name The name of the request parameter to check.
-	 * @return boolean Returns true if the key in `$name` is set in the `$params` array, otherwise
-	 *         `false`.
-	 */
-	public function __isset($name) {
-		return isset($this->params[$name]);
-	}
-
-	/**
-	 * Queries PHP's environment settings, and provides an abstraction for standardizing expected
-	 * environment values across varying platforms, as well as specify custom environment flags.
-	 *
-	 * @param string $key The environment variable required.
-	 * @return string The requested variables value.
-	 * @todo Refactor to lazy-load environment settings
-	 */
-	public function env($key) {
-		if (strtolower($key) === 'base') {
-			return $this->_base;
-		}
-
-		if ($key === 'SCRIPT_NAME' && !isset($this->_env['SCRIPT_NAME'])) {
-			if ($this->_env['PLATFORM'] === 'CGI' || isset($this->_env['SCRIPT_URL'])) {
-				$key = 'SCRIPT_URL';
-			}
-		}
-
-		$val = array_key_exists($key, $this->_env) ? $this->_env[$key] : getenv($key);
-		$this->_env[$key] = $val;
-
-		if ($key == 'REMOTE_ADDR') {
-			$https = array('HTTP_X_FORWARDED_FOR', 'HTTP_PC_REMOTE_ADDR', 'HTTP_X_REAL_IP');
-			foreach ($https as $altKey) {
-				if ($addr = $this->env($altKey)) {
-					$val = $addr;
-					break;
-				}
-			}
-		}
-
-		if ($val !== null && $val !== false && $key !== 'HTTPS') {
-			return $val;
-		}
-
-		switch ($key) {
-			case 'HTTPS':
-				if (isset($this->_env['SCRIPT_URI'])) {
-					return (strpos($this->_env['SCRIPT_URI'], 'https://') === 0);
-				}
-				if (isset($this->_env['HTTPS'])) {
-					return (!empty($this->_env['HTTPS']) && $this->_env['HTTPS'] !== 'off');
-				}
-				return false;
-			case 'SERVER_ADDR':
-				if (empty($this->_env['SERVER_ADDR']) && !empty($this->_env['LOCAL_ADDR'])) {
-					return $this->_env['LOCAL_ADDR'];
-				}
-				return $this->_env['SERVER_ADDR'];
-			case 'SCRIPT_FILENAME':
-				if ($this->_env['PLATFORM'] == 'IIS') {
-					return str_replace('\\\\', '\\', $this->env('PATH_TRANSLATED'));
-				}
-				return $this->env('DOCUMENT_ROOT') . $this->env('PHP_SELF');
-			case 'DOCUMENT_ROOT':
-				$fileName = $this->env('SCRIPT_FILENAME');
-				$offset = (!strpos($this->env('SCRIPT_NAME'), '.php')) ? 4 : 0;
-				$offset = strlen($fileName) - (strlen($this->env('SCRIPT_NAME')) + $offset);
-				return substr($fileName, 0, $offset);
-			case 'PHP_SELF':
-				return str_replace('\\', '/', str_replace(
-					$this->env('DOCUMENT_ROOT'), '', $this->env('SCRIPT_FILENAME')
-				));
-			case 'CGI':
-			case 'CGI_MODE':
-				return ($this->_env['PLATFORM'] === 'CGI');
-			case 'HTTP_BASE':
-				return preg_replace('/^([^.])*/i', null, $this->_env['HTTP_HOST']);
-		}
-	}
-
-	/**
-	 * Returns information about the type of content that the client is requesting.
-	 *
-	 * @see lithium\net\http\Media::negotiate()
-	 * @param $type mixed If not specified, returns the media type name that the client prefers,
-	 *              using content negotiation. If a media type name (string) is passed, returns
-	 *              `true` or `false`, indicating whether or not that type is accepted by the client
-	 *              at all. If `true`, returns the raw content types from the `Accept` header,
-	 *              parsed into an array and sorted by client preference.
-	 * @return string Returns a simple type name if the type is registered (i.e. `'json'`), or
-	 *         a fully-qualified content-type if not (i.e. `'image/jpeg'`), or a boolean or array,
-	 *         depending on the value of `$type`.
-	 */
-	public function accepts($type = null) {
-		if ($type === true) {
-			return $this->_parseAccept();
-		}
-		if (!$type && isset($this->params['type'])) {
-			return $this->params['type'];
-		}
-		$media = $this->_classes['media'];
-		return $media::negotiate($this) ?: 'html';
-	}
-
-	protected function _parseAccept() {
-		if ($this->_acceptContent) {
-			return $this->_acceptContent;
-		}
-		$accept = $this->env('HTTP_ACCEPT');
-		$accept = (preg_match('/[a-z,-]/i', $accept)) ? explode(',', $accept) : array('text/html');
-
-		foreach (array_reverse($accept) as $i => $type) {
-			unset($accept[$i]);
-			list($type, $q) = (explode(';q=', $type, 2) + array($type, 1.0 + $i / 100));
-			$accept[$type] = ($type === '*/*') ? 0.1 : floatval($q);
-		}
-		arsort($accept, SORT_NUMERIC);
-
-		if (isset($accept['application/xhtml+xml']) && $accept['application/xhtml+xml'] >= 1) {
-			unset($accept['application/xml']);
-		}
-		$media = $this->_classes['media'];
-
-		if (isset($this->params['type']) && ($handler = $media::type($this->params['type']))) {
-			if (isset($handler['content'])) {
-				$type = (array) $handler['content'];
-				$accept = array(current($type) => 1) + $accept;
-			}
-		}
-		return $this->_acceptContent = array_keys($accept);
-	}
-
-	/**
-	 * This method allows easy extraction of any request data using a prefixed key syntax. By
-	 * passing keys in the form of `'prefix:key'`, it is possible to query different information of
-	 * various different types, including GET and POST data, and server environment variables. The
-	 * full list of prefixes is as follows:
-	 *
-	 * - `'data'`: Retrieves values from POST data.
-	 * - `'params'`: Retrieves query parameters returned from the routing system.
-	 * - `'query'`: Retrieves values from GET data.
-	 * - `'env'`: Retrieves values from the server or environment, such as `'env:https'`, or custom
-	 *   environment values, like `'env:base'`. See the `env()` method for more info.
-	 * - `'http'`: Retrieves header values (i.e. `'http:accept'`), or the HTTP request method (i.e.
-	 *   `'http:method'`).
-	 *
-	 * This method is used in several different places in the framework in order to provide the
-	 * ability to act conditionally on different aspects of the request. See `Media::type()` (the
-	 * section on content negotiation) and the routing system for more information.
-	 *
-	 *  _Note_: All keys should be _lower-cased_, even when getting HTTP headers.
-	 * @see lithium\action\Request::env()
-	 * @see lithium\net\http\Media::type()
-	 * @see lithium\net\http\Router
-	 * @param string $key A prefixed key indicating what part of the request data the requested
-	 *               value should come from, and the name of the value to retrieve, in lower case.
-	 * @return string Returns the value of a GET, POST, routing or environment variable, or an
-	 *         HTTP header or method name.
-	 */
-	public function get($key) {
-		list($var, $key) = explode(':', $key);
-
-		switch (true) {
-			case in_array($var, array('params', 'data', 'query')):
-				return isset($this->{$var}[$key]) ? $this->{$var}[$key] : null;
-			case ($var === 'env'):
-				return $this->env(strtoupper($key));
-			case ($var === 'http' && $key === 'method'):
-				return $this->env('REQUEST_METHOD');
-			case ($var === 'http'):
-				return $this->env('HTTP_' . strtoupper($key));
-		}
-	}
-
-	/**
-	 * Provides a simple syntax for making assertions about the properties of a request.
-	 * By default, the `Request` object is configured with several different types of assertions,
-	 * which are individually known as _detectors_. Detectors are invoked by calling the `is()` and
-	 * passing the name of the detector flag, i.e. `$request->is('<name>')`, which returns `true` or
-	 * `false`, depending on whether or not the the properties (usually headers or data) contained
-	 * in the request match the detector. The default detectors include the following:
-	 *
-	 * - `'mobile'`: Uses a regular expression to match common mobile browser user agents.
-	 * - `'ajax'`: Checks to see if the `X-Requested-With` header is present, and matches the value
-	 *    `'XMLHttpRequest'`.
-	 * - `'flash'`: Checks to see if the user agent is `'Shockwave Flash'`.
-	 * - `'ssl'`: Verifies that the request is SSL-secured.
-	 * - `'get'` / `'post'` / `'put'` / `'delete'` / `'head'` / `'options'`: Checks that the HTTP
-	 *   request method matches the one specified.
-	 *
-	 * In addition to the above, this method also accepts media type names (see `Media::type()`) to
-	 * make assertions against the format of the request body (for POST or PUT requests), i.e.
-	 * `$request->is('json')`. This will return `true` if the client has made a POST request with
-	 * JSON data.
-	 *
-	 * For information about adding custom detectors or overriding the ones in the core, see the
-	 * `detect()` method.
-	 *
-	 * While these detectors are useful in controllers or other similar contexts, they're also
-	 * useful when performing _content negotiation_, which is the process of modifying the response
-	 * format to suit the client (see the `'conditions'` field of the `$options` parameter in
-	 * `Media::type()`).
-	 *
-	 * @see lithium\action\Request::detect()
-	 * @see lithium\net\http\Media::type()
-	 * @param string $flag The name of the flag to check, which should be the name of a valid
-	 *               detector (that is either built-in or defined with `detect()`).
-	 * @return boolean Returns `true` if the detector check succeeds (see the details for the
-	 *         built-in detectors above, or `detect()`), otherwise `false`.
-	 */
-	public function is($flag) {
-		$media = $this->_classes['media'];
-
-		if (!isset($this->_detectors[$flag])) {
-			if (!in_array($flag, $media::types())) {
-				return false;
-			}
-			return $this->type() == $flag;
-		}
-		$detector = $this->_detectors[$flag];
-
-		if (!is_array($detector) && is_callable($detector)) {
-			return $detector($this);
-		}
-		if (!is_array($detector)) {
-			return (boolean) $this->env($detector);
-		}
-		list($key, $check) = $detector + array('', '');
-
-		if (is_array($check)) {
-			$check = '/' . join('|', $check) . '/i';
-		}
-		if (Validator::isRegex($check)) {
-			return (boolean) preg_match($check, $this->env($key));
-		}
-		return ($this->env($key) == $check);
-	}
-
-	/**
-	 * Sets/Gets the content type. If `'type'` is null, the method will attempt to determine the
-	 * type from the params, then from the environment setting
-	 *
-	 * @param string $type a full content type i.e. `'application/json'` or simple name `'json'`
-	 * @return string A simple content type name, i.e. `'html'`, `'xml'`, `'json'`, etc., depending
-	 *         on the content type of the request.
-	 */
-	public function type($type = null) {
-		if (!$type && !empty($this->params['type'])) {
-			$type = $this->params['type'];
-		}
-		return parent::type($type);
-	}
-
-	/**
-	 * Creates a _detector_ used with `Request::is()`.  A detector is a boolean check that is
-	 * created to determine something about a request.
-	 *
-	 * A detector check can be either an exact string match or a regular expression match against a
-	 * header or environment variable. A detector check can also be a closure that accepts the
-	 * `Request` object instance as a parameter.
-	 *
-	 * For example, to detect whether a request is from an iPhone, you can do the following:
-	 * {{{ embed:lithium\tests\cases\action\RequestTest::testDetect(11-12) }}}
-	 *
-	 * @see lithium\action\Request::is()
-	 * @param string $flag The name of the detector check. Used in subsequent calls to
-	 *               `Request::is()`.
-	 * @param mixed $detector Detectors can be specified in four different ways:
-	 *              - The name of an HTTP header or environment variable. If a string, calling the
-	 *                detector will check that the header or environment variable exists and is set
-	 *                to a non-empty value.
-	 *              - A two-element array containing a header/environment variable name, and a value
-	 *                to match against. The second element of the array must be an exact match to
-	 *                the header or variable value.
-	 *              - A two-element array containing a header/environment variable name, and a
-	 *                regular expression that matches against the value, as in the example above.
-	 *              - A closure which accepts an instance of the `Request` object and returns a
-	 *                boolean value.
-	 * @return void
-	 */
-	public function detect($flag, $detector = null) {
-		if (is_array($flag)) {
-			$this->_detectors = $flag + $this->_detectors;
-		} else {
-			$this->_detectors[$flag] = $detector;
-		}
-	}
-
-	/**
-	 * Gets the referring URL of this request.
-	 *
-	 * @param string $default Default URL to use if HTTP_REFERER cannot be read from headers.
-	 * @param boolean $local If true, restrict referring URLs to local server.
-	 * @return string Referring URL.
-	 */
-	public function referer($default = null, $local = false) {
-		if ($ref = $this->env('HTTP_REFERER')) {
-			if (!$local) {
-				return $ref;
-			}
-			if (strpos($ref, '://') === false) {
-				return $ref;
-			}
-		}
-		return ($default != null) ? $default : '/';
-	}
-
-	/**
-	 * Overrides `lithium\net\http\Request::to()` to provide the correct options for generating
-	 * URLs. For information about this method, see the parent implementation.
-	 *
-	 * @see lithium\net\http\Request::to()
-	 * @param string $format The format to convert to.
-	 * @param array $options Override options.
-	 * @return mixed The return value type depends on `$format`.
-	 */
-	public function to($format, array $options = array()) {
-		$defaults = array(
-			'scheme' => $this->env('HTTPS') ? 'https' : 'http',
-			'host' => $this->env('HTTP_HOST'),
-			'path' => $this->_base . '/' . $this->url
-		);
-		return parent::to($format, $options + $defaults);
-	}
-
-	/**
-	 * Sets or returns the current locale string. For more information, see
-	 * "[Globalization](http://lithify.me/docs/manual/07_globalization)" in the manual.
-	 *
-	 * @param string $locale An optional locale string like `'en'`, `'en_US'` or `'de_DE'`. If
-	 *               specified, will overwrite the existing locale.
-	 * @return Returns the currently set locale string.
-	 */
-	public function locale($locale = null) {
-		if ($locale) {
-			$this->_locale = $locale;
-		}
-		if ($this->_locale) {
-			return $this->_locale;
-		}
-		if (isset($this->params['locale'])) {
-			return $this->params['locale'];
-		}
-	}
-
-	/**
-	 * Find the base path of the current request.
-	 *
-	 * @todo Replace string directory names with configuration.
-	 * @return string
-	 */
-	protected function _base() {
-		if (isset($this->_base)) {
-			return $this->_base;
-		}
-		$base = str_replace('\\', '/', dirname($this->env('PHP_SELF')));
-		return rtrim(str_replace(array("/app/webroot", '/webroot'), '', $base), '/');
-	}
-
-	/**
-	 * Return the full url of the current request.
-	 *
-	 * @return string
-	 */
-	protected function _url() {
-		if (isset($this->_config['url'])) {
-			return rtrim($this->_config['url'], '/');
-		}
-		if (!empty($_GET['url'])) {
-			return rtrim($_GET['url'], '/');
-		}
-		if ($uri = $this->env('REQUEST_URI')) {
-			list($uri) = explode('?', $uri, 2);
-			$base = '/^' . preg_quote($this->env('base'), '/') . '/';
-			return trim(preg_replace($base, '', $uri), '/') ?: '/';
-		}
-		return '/';
-	}
-
-	/**
-	 * Normalize the data in $_FILES
-	 *
-	 * @return array
-	 */
-	protected function _parseFiles() {
-		if (isset($_FILES) && $_FILES) {
-			$result = array();
-
-			$normalize = function($key, $value) use ($result, &$normalize){
-				foreach ($value as $param => $content) {
-					foreach ($content as $num => $val) {
-						if (is_numeric($num)) {
-							$result[$key][$num][$param] = $val;
-							continue;
-						}
-						if (is_array($val)) {
-							foreach ($val as $next => $one) {
-								$result[$key][$num][$next][$param] = $one;
-							}
-							continue;
-						}
-						$result[$key][$num][$param] = $val;
-					}
-				}
-				return $result;
-			};
-			foreach ($_FILES as $key => $value) {
-				if (isset($value['name'])) {
-					if (is_string($value['name'])) {
-						$result[$key] = $value;
-						continue;
-					}
-					if (is_array($value['name'])) {
-						$result += $normalize($key, $value);
-					}
-				}
-			}
-			return $result;
-		}
-		return array();
-	}
-}
-
-?>

+ 0 - 175
frameworks/PHP/php-lithium/libraries/lithium/action/Response.php

@@ -1,175 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\action;
-
-/**
- * A `Response` object is typically instantiated automatically by the `Controller`. It is assigned
- * any headers set in the course of the request, as well as any content rendered by the
- * `Controller`. Once completed, the `Controller` returns the `Response` object to the `Dispatcher`.
- *
- * The `Response` object is responsible for writing its body content to output, and writing any
- * headers to the browser.
- *
- * @see lithium\action\Dispatcher
- * @see lithium\action\Controller
- */
-class Response extends \lithium\net\http\Response {
-
-	/**
-	 * Classes used by Response.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'router' => 'lithium\net\http\Router',
-		'media' => 'lithium\net\http\Media'
-	);
-
-	protected $_autoConfig = array('classes' => 'merge');
-
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'buffer' => 8192,
-			'location' => null,
-			'status' => 0,
-			'request' => null,
-			'decode' => false
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-		$config = $this->_config;
-		$this->status($config['status']);
-		unset($this->_config['status']);
-
-		if ($config['location']) {
-			$classes = $this->_classes;
-			$location = $classes['router']::match($config['location'], $config['request']);
-			$this->headers('Location', $location);
-		}
-	}
-
-	/**
-	 * Controls how or whether the client browser and web proxies should cache this response.
-	 *
-	 * @param mixed $expires This can be a Unix timestamp indicating when the page expires, or a
-	 *              string indicating the relative time offset that a page should expire, i.e.
-	 *              `"+5 hours". Finally, `$expires` can be set to `false` to completely disable
-	 *              browser or proxy caching.
-	 * @return void
-	 */
-	public function cache($expires) {
-		if ($expires === false) {
-			return $this->headers(array(
-				'Expires' => 'Mon, 26 Jul 1997 05:00:00 GMT',
-				'Cache-Control' => array(
-					'no-store, no-cache, must-revalidate',
-					'post-check=0, pre-check=0',
-					'max-age=0'
-				),
-				'Pragma' => 'no-cache'
-			));
-		}
-		$expires = is_int($expires) ? $expires : strtotime($expires);
-
-		return $this->headers(array(
-			'Expires' => gmdate('D, d M Y H:i:s', $expires) . ' GMT',
-			'Cache-Control' => 'max-age=' . ($expires - time()),
-			'Pragma' => 'cache'
-		));
-	}
-
-	/**
-	 * Sets/Gets the content type. If `'type'` is null, the method will attempt to determine the
-	 * type from the params, then from the environment setting
-	 *
-	 * @param string $type a full content type i.e. `'application/json'` or simple name `'json'`
-	 * @return string A simple content type name, i.e. `'html'`, `'xml'`, `'json'`, etc., depending
-	 *         on the content type of the request.
-	 */
-	public function type($type = null) {
-		if ($type === null && $this->_type === null) {
-			$type = 'html';
-		}
-		return parent::type($type);
-	}
-
-	/**
-	 * Render a response by writing headers and output. Output is echoed in chunks because of an
-	 * issue where `echo` time increases exponentially on long message bodies.
-	 *
-	 * @return void
-	 */
-	public function render() {
-		$code = null;
-		$hasLocation = (isset($this->headers['location']) || isset($this->headers['Location']));
-
-		if ($hasLocation && $this->status['code'] === 200) {
-			$code = 302;
-		}
-		$this->_writeHeader($this->status($code) ?: $this->status(500));
-
-		foreach ($this->headers as $name => $value) {
-			$key = strtolower($name);
-
-			if ($key == 'location') {
-				$this->_writeHeader("Location: {$value}", $this->status['code']);
-			} elseif ($key == 'download') {
-				$this->_writeHeader('Content-Disposition: attachment; filename="' . $value . '"');
-			} elseif (is_array($value)) {
-				$this->_writeHeader(
-					array_map(function($v) use ($name) { return "{$name}: {$v}"; }, $value)
-				);
-			} elseif (!is_numeric($name)) {
-				$this->_writeHeader("{$name}: {$value}");
-			}
-		}
-		if ($code == 302 || $code == 204) {
-			return;
-		}
-		$chunked = $this->body(null, $this->_config);
-
-		foreach ($chunked as $chunk) {
-			echo $chunk;
-		}
-	}
-
-	/**
-	 * Casts the Response object to a string.  This doesn't actually return a string, but does
-	 * a direct render and returns null.
-	 *
-	 * @return string An empty string.
-	 */
-	public function __toString() {
-		$this->render();
-		return '';
-	}
-
-	/**
-	 * Writes raw headers to output.
-	 *
-	 * @param string|array $header Either a raw header string, or an array of header strings. Use
-	 *        an array if a single header must be written multiple times with different values.
-	 *        Otherwise, additional values for duplicate headers will overwrite previous values.
-	 * @param integer $code Optional. If present, forces a specific HTTP response code.  Used
-	 *        primarily in conjunction with the 'Location' header.
-	 * @return void
-	 */
-	protected function _writeHeader($header, $code = null) {
-		if (is_array($header)) {
-			array_map(function($h) { header($h, false); }, $header);
-			return;
-		}
-		$code ? header($header, true, $code) : header($header, true);
-	}
-}
-
-?>

+ 0 - 1
frameworks/PHP/php-lithium/libraries/lithium/action/readme.md

@@ -1 +0,0 @@
-The `action` namespace relies on `lithium\http`, and includes classes required to route and dispatch HTTP requests.

+ 0 - 205
frameworks/PHP/php-lithium/libraries/lithium/analysis/Debugger.php

@@ -1,205 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis;
-
-use ReflectionClass;
-use lithium\util\String;
-use lithium\analysis\Inspector;
-
-/**
- * The `Debugger` class provides basic facilities for generating and rendering meta-data about the
- * state of an application in its current context.
- */
-class Debugger extends \lithium\core\StaticObject {
-
-	/**
-	 * Used for temporary closure caching.
-	 *
-	 * @see lithium\analysis\Debugger::_closureDef()
-	 * @var array
-	 */
-	protected static $_closureCache = array();
-
-	/**
-	 * Outputs a stack trace based on the supplied options.
-	 *
-	 * @param array $options Format for outputting stack trace. Available options are:
-	 *        - `'args'`: A boolean indicating if arguments should be included.
-	 *        - `'depth'`: The maximum depth of the trace.
-	 *        - `'format'`: Either `null`, `'points'` or `'array'`.
-	 *        - `'includeScope'`: A boolean indicating if items within scope
-	 *           should be included.
-	 *        - `'scope'`: Scope for items to include.
-	 *        - `'start'`: The depth to start with.
-	 *        - `'trace'`: A trace to use instead of generating one.
-	 * @return string Stack trace formatted according to `'format'` option.
-	 */
-	public static function trace(array $options = array()) {
-		$defaults = array(
-			'depth' => 999,
-			'format' => null,
-			'args' => false,
-			'start' => 0,
-			'scope' => array(),
-			'trace' => array(),
-			'includeScope' => true,
-			'closures' => true
-		);
-		$options += $defaults;
-
-		$backtrace = $options['trace'] ?: debug_backtrace();
-		$scope = $options['scope'];
-		$count = count($backtrace);
-		$back = array();
-		$traceDefault = array(
-			'line' => '??', 'file' => '[internal]', 'class' => null, 'function' => '[main]'
-		);
-
-		for ($i = $options['start']; $i < $count && $i < $options['depth']; $i++) {
-			$trace = array_merge(array('file' => '[internal]', 'line' => '??'), $backtrace[$i]);
-			$function = '[main]';
-
-			if (isset($backtrace[$i + 1])) {
-				$next = $backtrace[$i + 1] + $traceDefault;
-				$function = $next['function'];
-
-				if (!empty($next['class'])) {
-					$function = $next['class'] . '::' . $function . '(';
-					if ($options['args'] && isset($next['args'])) {
-						$args = array_map(array('static', 'export'), $next['args']);
-						$function .= join(', ', $args);
-					}
-					$function .= ')';
-				}
-			}
-
-			if ($options['closures'] && strpos($function, '{closure}') !== false) {
-				$function = static::_closureDef($backtrace[$i], $function);
-			}
-			if (in_array($function, array('call_user_func_array', 'trigger_error'))) {
-				continue;
-			}
-			$trace['functionRef'] = $function;
-
-			if ($options['format'] === 'points' && $trace['file'] !== '[internal]') {
-				$back[] = array('file' => $trace['file'], 'line' => $trace['line']);
-			} elseif (is_string($options['format']) && $options['format'] != 'array') {
-				$back[] = String::insert($options['format'], array_map(
-					function($data) { return is_object($data) ? get_class($data) : $data; },
-					$trace
-				));
-			} elseif (empty($options['format'])) {
-				$back[] = $function . ' - ' . $trace['file'] . ', line ' . $trace['line'];
-			} else {
-				$back[] = $trace;
-			}
-
-			if (!empty($scope) && array_intersect_assoc($scope, $trace) == $scope) {
-				if (!$options['includeScope']) {
-					$back = array_slice($back, 0, count($back) - 1);
-				}
-				break;
-			}
-		}
-
-		if ($options['format'] === 'array' || $options['format'] === 'points') {
-			return $back;
-		}
-		return join("\n", $back);
-	}
-
-	/**
-	 * Returns a parseable string representation of a variable.
-	 *
-	 * @param mixed $var The variable to export.
-	 * @return string The exported contents.
-	 */
-	public static function export($var) {
-		$export = var_export($var, true);
-
-		if (is_array($var)) {
-			$replace = array(" (", " )", "  ", " )", "=> \n\t");
-			$with = array("(", ")", "\t", "\t)", "=> ");
-			$export = str_replace($replace, $with, $export);
-		}
-		return $export;
-	}
-
-	/**
-	 * Locates original location of closures.
-	 *
-	 * @param mixed $reference File or class name to inspect.
-	 * @param integer $callLine Line number of class reference.
-	 */
-	protected static function _definition($reference, $callLine) {
-		if (file_exists($reference)) {
-			foreach (array_reverse(token_get_all(file_get_contents($reference))) as $token) {
-				if (!is_array($token) || $token[2] > $callLine) {
-					continue;
-				}
-				if ($token[0] === T_FUNCTION) {
-					return $token[2];
-				}
-			}
-			return;
-		}
-		list($class, $method) = explode('::', $reference);
-
-		if (!class_exists($class)) {
-			return;
-		}
-
-		$classRef = new ReflectionClass($class);
-		$methodInfo = Inspector::info($reference);
-		$methodDef = join("\n", Inspector::lines($classRef->getFileName(), range(
-			$methodInfo['start'] + 1, $methodInfo['end'] - 1
-		)));
-
-		foreach (array_reverse(token_get_all("<?php {$methodDef} ?>")) as $token) {
-			if (!is_array($token) || $token[2] > $callLine) {
-				continue;
-			}
-			if ($token[0] === T_FUNCTION) {
-				return $token[2] + $methodInfo['start'];
-			}
-		}
-	}
-
-	protected static function _closureDef($frame, $function) {
-		$reference = '::';
-		$frame += array('file' => '??', 'line' => '??');
-		$cacheKey = "{$frame['file']}@{$frame['line']}";
-
-		if (isset(static::$_closureCache[$cacheKey])) {
-			return static::$_closureCache[$cacheKey];
-		}
-
-		if ($class = Inspector::classes(array('file' => $frame['file']))) {
-			foreach (Inspector::methods(key($class), 'extents') as $method => $extents) {
-				$line = $frame['line'];
-
-				if (!($extents[0] <= $line && $line <= $extents[1])) {
-					continue;
-				}
-				$class = key($class);
-				$reference = "{$class}::{$method}";
-				$function = "{$reference}()::{closure}";
-				break;
-			}
-		} else {
-			$reference = $frame['file'];
-			$function = "{$reference}::{closure}";
-		}
-		$line = static::_definition($reference, $frame['line']) ?: '?';
-		$function .= " @ {$line}";
-		return static::$_closureCache[$cacheKey] = $function;
-	}
-}
-
-?>

+ 0 - 122
frameworks/PHP/php-lithium/libraries/lithium/analysis/Docblock.php

@@ -1,122 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis;
-
-/**
- * A source code doc block parser.
- *
- * This parser may be used as the basis for a variety of secondary tools, including
- * a reflection-based API generator, a code metrics analyzer, and various other code or structural
- * analysis tools.
- */
-class Docblock extends \lithium\core\StaticObject {
-
-	/**
-	 * List of supported docblock tags.
-	 *
-	 * @var array
-	 */
-	public static $tags = array(
-		'todo', 'discuss', 'fix', 'important', 'var',
-		'param', 'return', 'throws', 'see', 'link',
-		'task', 'dependencies', 'filter'
-	);
-
-	/**
-	 * Parses a doc block into its major components of `description`, `text` and `tags`.
-	 *
-	 * @param string $comment The doc block string to be parsed
-	 * @return array An associative array of the parsed comment, whose keys are `description`,
-	 *         `text` and `tags`.
-	 */
-	public static function comment($comment) {
-		$text = null;
-		$tags = array();
-		$description = null;
-		$comment = trim(preg_replace('/^(\s*\/\*\*|\s*\*{1,2}\/|\s*\* ?)/m', '', $comment));
-		$comment = str_replace("\r\n", "\n", $comment);
-
-		if ($items = preg_split('/\n@/ms', $comment, 2)) {
-			list($description, $tags) = $items + array('', '');
-			$tags = $tags ? static::tags("@{$tags}") : array();
-		}
-
-		if (strpos($description, "\n\n")) {
-			list($description, $text) = explode("\n\n", $description, 2);
-		}
-		$text = trim($text);
-		$description = trim($description);
-		return compact('description', 'text', 'tags');
-	}
-
-	/**
-	 * Parses `@<tagname>` docblock tags and their descriptions from a docblock.
-	 *
-	 * See the `$tags` property for the list of supported tags.
-	 *
-	 * @param string $string The string to be parsed for tags
-	 * @return array Returns an array where each docblock tag is a key name, and the corresponding
-	 *         values are either strings (if one of each tag), or arrays (if multiple of the same
-	 *         tag).
-	 */
-	public static function tags($string) {
-		$regex = '/\n@(?P<type>' . join('|', static::$tags) . ")/msi";
-		$string = trim($string);
-
-		$result = preg_split($regex, "\n$string", -1, PREG_SPLIT_DELIM_CAPTURE);
-		$tags = array();
-
-		for ($i = 1; $i < count($result) - 1; $i += 2) {
-			$type = trim(strtolower($result[$i]));
-			$text = trim($result[$i + 1]);
-
-			if (isset($tags[$type])) {
-				$tags[$type] = is_array($tags[$type]) ? $tags[$type] : (array) $tags[$type];
-				$tags[$type][] = $text;
-			} else {
-				$tags[$type] = $text;
-			}
-		}
-
-		if (isset($tags['param'])) {
-			$params = $tags['param'];
-			$tags['params'] = static::_params((array) $tags['param']);
-			unset($tags['param']);
-		}
-		return $tags;
-	}
-
-	/**
-	 * Parses `@param` docblock tags to separate out the parameter type from the description.
-	 *
-	 * @param array $params An array of `@param` tags, as parsed from the `tags()` method.
-	 * @return array Returns an array where each key is a parameter name, and each value is an
-	 *         associative array containing `'type'` and `'text'` keys.
-	 */
-	protected static function _params(array $params) {
-		$result = array();
-		foreach ($params as $param) {
-			$param = explode(' ', $param, 3);
-			$type = $name = $text = null;
-
-			foreach (array('type', 'name', 'text') as $i => $key) {
-				if (!isset($param[$i])) {
-					break;
-				}
-				${$key} = $param[$i];
-			}
-			if ($name) {
-				$result[$name] = compact('type', 'text');
-			}
-		}
-		return $result;
-	}
-}
-
-?>

+ 0 - 590
frameworks/PHP/php-lithium/libraries/lithium/analysis/Inspector.php

@@ -1,590 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis;
-
-use Exception;
-use ReflectionClass;
-use ReflectionProperty;
-use ReflectionException;
-use SplFileObject;
-use lithium\core\Libraries;
-
-/**
- * General source code inspector.
- *
- * This inspector provides a simple interface to the PHP Reflection API that
- * can be used to gather information about any PHP source file for purposes of
- * test metrics or static analysis.
- */
-class Inspector extends \lithium\core\StaticObject {
-
-	/**
-	 * classes used
-	 *
-	 * @var array
-	 */
-	protected static $_classes = array(
-		'collection' => 'lithium\util\Collection'
-	);
-
-	/**
-	 * Maps reflect method names to result array keys.
-	 *
-	 * @var array
-	 */
-	protected static $_methodMap = array(
-		'name'      => 'getName',
-		'start'     => 'getStartLine',
-		'end'       => 'getEndLine',
-		'file'      => 'getFileName',
-		'comment'   => 'getDocComment',
-		'namespace' => 'getNamespaceName',
-		'shortName' => 'getShortName'
-	);
-
-	/**
-	 * Will determine if a method can be called.
-	 *
-	 * @param  string|object $class      Class to inspect.
-	 * @param  string        $method     Method name.
-	 * @param  bool          $internal   Interal call or not.
-	 * @return bool
-	 */
-	public static function isCallable($object, $method, $internal = false) {
-		$methodExists = method_exists($object, $method);
-		$callable = function($object, $method) {
-			return is_callable(array($object, $method));
-		};
-		return $internal ? $methodExists : $methodExists && $callable($object, $method);
-	}
-
-	/**
-	 * Determines if a given $identifier is a class property, a class method, a class itself,
-	 * or a namespace identifier.
-	 *
-	 * @param string $identifier The identifier to be analyzed
-	 * @return string Identifier type. One of `property`, `method`, `class` or `namespace`.
-	 */
-	public static function type($identifier) {
-		$identifier = ltrim($identifier, '\\');
-
-		if (strpos($identifier, '::')) {
-			return (strpos($identifier, '$') !== false) ? 'property' : 'method';
-		}
-		if (is_readable(Libraries::path($identifier))) {
-			if (class_exists($identifier) && in_array($identifier, get_declared_classes())) {
-				return 'class';
-			}
-		}
-		return 'namespace';
-	}
-
-	/**
-	 * Detailed source code identifier analysis
-	 *
-	 * Analyzes a passed $identifier for more detailed information such
-	 * as method/property modifiers (e.g. `public`, `private`, `abstract`)
-	 *
-	 * @param string $identifier The identifier to be analyzed
-	 * @param array $info Optionally restrict or expand the default information
-	 *        returned from the `info` method. By default, the information returned
-	 *        is the same as the array keys contained in the `$_methodMap` property of
-	 *        Inspector.
-	 * @return array An array of the parsed meta-data information of the given identifier.
-	 */
-	public static function info($identifier, $info = array()) {
-		$info = $info ?: array_keys(static::$_methodMap);
-		$type = static::type($identifier);
-		$result = array();
-		$class = null;
-
-		if ($type === 'method' || $type === 'property') {
-			list($class, $identifier) = explode('::', $identifier);
-
-			try {
-				$classInspector = new ReflectionClass($class);
-			} catch (Exception $e) {
-				return null;
-			}
-
-			if ($type === 'property') {
-				$identifier = substr($identifier, 1);
-				$accessor = 'getProperty';
-			} else {
-				$identifier = str_replace('()', '', $identifier);
-				$accessor = 'getMethod';
-			}
-
-			try {
-				$inspector = $classInspector->{$accessor}($identifier);
-			} catch (Exception $e) {
-				return null;
-			}
-			$result['modifiers'] = static::_modifiers($inspector);
-		} elseif ($type === 'class') {
-			$inspector = new ReflectionClass($identifier);
-		} else {
-			return null;
-		}
-
-		foreach ($info as $key) {
-			if (!isset(static::$_methodMap[$key])) {
-				continue;
-			}
-			if (method_exists($inspector, static::$_methodMap[$key])) {
-				$setAccess = (
-					($type === 'method' || $type === 'property') &&
-					array_intersect($result['modifiers'], array('private', 'protected')) != array()
-					&& method_exists($inspector, 'setAccessible')
-				);
-
-				if ($setAccess) {
-					$inspector->setAccessible(true);
-				}
-				$result[$key] = $inspector->{static::$_methodMap[$key]}();
-
-				if ($setAccess) {
-					$inspector->setAccessible(false);
-					$setAccess = false;
-				}
-			}
-		}
-
-		if ($type === 'property' && !$classInspector->isAbstract()) {
-			$inspector->setAccessible(true);
-
-			try {
-				$result['value'] = $inspector->getValue(static::_class($class));
-			} catch (Exception $e) {
-				return null;
-			}
-		}
-
-		if (isset($result['start']) && isset($result['end'])) {
-			$result['length'] = $result['end'] - $result['start'];
-		}
-		if (isset($result['comment'])) {
-			$result += Docblock::comment($result['comment']);
-		}
-		return $result;
-	}
-
-	/**
-	 * Gets the executable lines of a class, by examining the start and end lines of each method.
-	 *
-	 * @param mixed $class Class name as a string or object instance.
-	 * @param array $options Set of options:
-	 *        - `'self'` _boolean_: If `true` (default), only returns lines of methods defined in
-	 *          `$class`, excluding methods from inherited classes.
-	 *        - `'methods'` _array_: An arbitrary list of methods to search, as a string (single
-	 *          method name) or array of method names.
-	 *        - `'filter'` _boolean_: If `true`, filters out lines containing only whitespace or
-	 *          braces. Note: for some reason, the Zend engine does not report `switch` and `try`
-	 *          statements as executable lines, as well as parts of multi-line assignment
-	 *          statements, so they are filtered out as well.
-	 * @return array Returns an array of the executable line numbers of the class.
-	 */
-	public static function executable($class, array $options = array()) {
-		$defaults = array(
-			'self' => true,
-			'filter' => true,
-			'methods' => array(),
-			'empty' => array(' ', "\t", '}', ')', ';'),
-			'pattern' => null,
-			'blockOpeners' => array('switch (', 'try {', '} else {', 'do {', '} while')
-		);
-		$options += $defaults;
-
-		if (empty($options['pattern']) && $options['filter']) {
-			$pattern = str_replace(' ', '\s*', join('|', array_map(
-				function($str) { return preg_quote($str, '/'); },
-				$options['blockOpeners']
-			)));
-			$pattern = join('|', array(
-				"({$pattern})",
-				"\\$(.+)\($",
-				"\s*['\"]\w+['\"]\s*=>\s*.+[\{\(]$",
-				"\s*['\"]\w+['\"]\s*=>\s*['\"]*.+['\"]*\s*"
-			));
-			$options['pattern'] = "/^({$pattern})/";
-		}
-
-		if (!$class instanceof ReflectionClass) {
-			$class = new ReflectionClass(is_object($class) ? get_class($class) : $class);
-		}
-		$options += array('group' => false);
-		$result = array_filter(static::methods($class, 'ranges', $options));
-
-		if ($options['filter'] && $class->getFileName() && $result) {
-			$lines = static::lines($class->getFileName(), $result);
-			$start = key($lines);
-
-			$code = implode("\n", $lines);
-			$tokens = token_get_all('<' . '?php' . $code);
-			$tmp = array();
-
-			foreach ($tokens as $token) {
-				if (is_array($token)) {
-					if (!in_array($token[0], array(T_COMMENT, T_DOC_COMMENT, T_WHITESPACE))) {
-						$tmp[] = $token[2];
-					}
-				}
-			}
-
-			$filteredLines = array_values(array_map(
-				function($ln) use ($start) { return $ln + $start - 1; },
-				array_unique($tmp))
-			);
-
-			$lines = array_intersect_key($lines, array_flip($filteredLines));
-
-			$result = array_keys(array_filter($lines, function($line) use ($options) {
-				$line = trim($line);
-				$empty = preg_match($options['pattern'], $line);
-				return $empty ? false : (str_replace($options['empty'], '', $line) !== '');
-			}));
-		}
-		return $result;
-	}
-
-	/**
-	 * Returns various information on the methods of an object, in different formats.
-	 *
-	 * @param mixed $class A string class name or an object instance, from which to get methods.
-	 * @param string $format The type and format of data to return. Available options are:
-	 *        - `null`: Returns a `Collection` object containing a `ReflectionMethod` instance
-	 *         for each method.
-	 *        - `'extents'`: Returns a two-dimensional array with method names as keys, and
-	 *         an array with starting and ending line numbers as values.
-	 *        - `'ranges'`: Returns a two-dimensional array where each key is a method name,
-	 *         and each value is an array of line numbers which are contained in the method.
-	 * @param array $options
-	 * @return mixed array|null|object
-	 */
-	public static function methods($class, $format = null, array $options = array()) {
-		$defaults = array('methods' => array(), 'group' => true, 'self' => true);
-		$options += $defaults;
-
-		if (!(is_object($class) && $class instanceof ReflectionClass)) {
-			try {
-				$class = new ReflectionClass($class);
-			} catch (ReflectionException $e) {
-				return null;
-			}
-		}
-		$options += array('names' => $options['methods']);
-		$methods = static::_items($class, 'getMethods', $options);
-		$result = array();
-
-		switch ($format) {
-			case null:
-				return $methods;
-			case 'extents':
-				if ($methods->getName() == array()) {
-					return array();
-				}
-
-				$extents = function($start, $end) { return array($start, $end); };
-				$result = array_combine($methods->getName(), array_map(
-					$extents, $methods->getStartLine(), $methods->getEndLine()
-				));
-			break;
-			case 'ranges':
-				$ranges = function($lines) {
-					list($start, $end) = $lines;
-					return ($end <= $start + 1) ? array() : range($start + 1, $end - 1);
-				};
-				$result = array_map($ranges, static::methods(
-					$class, 'extents', array('group' => true) + $options
-				));
-			break;
-		}
-
-		if ($options['group']) {
-			return $result;
-		}
-		$tmp = $result;
-		$result = array();
-
-		array_map(function($ln) use (&$result) { $result = array_merge($result, $ln); }, $tmp);
-		return $result;
-	}
-
-	/**
-	 * Returns various information on the properties of an object.
-	 *
-	 * @param mixed $class A string class name or an object instance, from which to get methods.
-	 * @param array $options Set of options:
-	 *        -'self': If true (default), only returns properties defined in `$class`,
-	 *         excluding properties from inherited classes.
-	 * @return mixed object lithium\analysis\Inspector._items.map|null
-	 */
-	public static function properties($class, array $options = array()) {
-		$defaults = array('properties' => array(), 'self' => true);
-		$options += $defaults;
-
-		if (!(is_object($class) && $class instanceof ReflectionClass)) {
-			try {
-				$class = new ReflectionClass($class);
-			} catch (ReflectionException $e) {
-				return null;
-			}
-		}
-		$options += array('names' => $options['properties']);
-
-		return static::_items($class, 'getProperties', $options)->map(function($item) {
-			$class = __CLASS__;
-			$modifiers = array_values($class::invokeMethod('_modifiers', array($item)));
-			$setAccess = (
-				array_intersect($modifiers, array('private', 'protected')) != array()
-			);
-			if ($setAccess) {
-				$item->setAccessible(true);
-			}
-			$result = compact('modifiers') + array(
-				'docComment' => $item->getDocComment(),
-				'name' => $item->getName(),
-				'value' => $item->getValue($item->getDeclaringClass())
-			);
-			if ($setAccess) {
-				$item->setAccessible(false);
-			}
-			return $result;
-		}, array('collect' => false));
-	}
-
-	/**
-	 * Returns an array of lines from a file, class, or arbitrary string, where $data is the data
-	 * to read the lines from and $lines is an array of line numbers specifying which lines should
-	 * be read.
-	 *
-	 * @param string $data If `$data` contains newlines, it will be read from directly, and have
-	 *        its own lines returned.  If `$data` is a physical file path, that file will be
-	 *        read and have its lines returned.  If `$data` is a class name, it will be
-	 *        converted into a physical file path and read.
-	 * @param array $lines The array of lines to read. If a given line is not present in the data,
-	 *        it will be silently ignored.
-	 * @return array Returns an array where the keys are matching `$lines`, and the values are the
-	 *         corresponding line numbers in `$data`.
-	 * @todo Add an $options parameter with a 'context' flag, to pull in n lines of context.
-	 */
-	public static function lines($data, $lines) {
-		$c = array();
-
-		if (strpos($data, PHP_EOL) !== false) {
-			$c = explode(PHP_EOL, PHP_EOL . $data);
-		} else {
-			if (!file_exists($data)) {
-				$data = Libraries::path($data);
-				if (!file_exists($data)) {
-					return null;
-				}
-			}
-
-			$file = new SplFileObject($data);
-			foreach ($file as $current) {
-				$c[$file->key() + 1] = rtrim($file->current());
-			}
-		}
-
-		if (!count($c) || !count($lines)) {
-			return null;
-		}
-		return array_intersect_key($c, array_combine($lines, array_fill(0, count($lines), null)));
-	}
-
-	/**
-	 * Gets the full inheritance list for the given class.
-	 *
-	 * @param string $class Class whose inheritance chain will be returned
-	 * @param array $options Option consists of:
-	 *        - `'autoLoad'` _boolean_: Whether or not to call `__autoload` by default. Defaults
-	 *          to `true`.
-	 * @return array An array of the name of the parent classes of the passed `$class` parameter,
-	 *         or `false` on error.
-	 * @link http://php.net/manual/en/function.class-parents.php PHP Manual: `class_parents()`.
-	 */
-	public static function parents($class, array $options = array()) {
-		$defaults = array('autoLoad' => false);
-		$options += $defaults;
-		$class = is_object($class) ? get_class($class) : $class;
-
-		if (!class_exists($class, $options['autoLoad'])) {
-			return false;
-		}
-		return class_parents($class);
-	}
-
-	/**
-	 * Gets an array of classes and their corresponding definition files, or examines a file and
-	 * returns the classes it defines.
-	 *
-	 * @param array $options
-	 * @return array Associative of classes and their corresponding definition files
-	 * @todo Document valid options
-	 */
-	public static function classes(array $options = array()) {
-		$defaults = array('group' => 'classes', 'file' => null);
-		$options += $defaults;
-
-		$list = get_declared_classes();
-		$files = get_included_files();
-		$classes = array();
-
-		if ($file = $options['file']) {
-			$loaded = static::_instance('collection', array('data' => array_map(
-				function($class) { return new ReflectionClass($class); }, $list
-			)));
-			$classFiles = $loaded->getFileName();
-
-			if (in_array($file, $files) && !in_array($file, $classFiles)) {
-				return array();
-			}
-			if (!in_array($file, $classFiles)) {
-				include $file;
-				$list = array_diff(get_declared_classes(), $list);
-			} else {
-				$filter = function($class) use ($file) { return $class->getFileName() === $file; };
-				$list = $loaded->find($filter)->map(function ($class) {
-					return $class->getName() ?: $class->name;
-				}, array('collect' => false));
-			}
-		}
-
-		foreach ($list as $class) {
-			$inspector = new ReflectionClass($class);
-
-			if ($options['group'] === 'classes') {
-				$inspector->getFileName() ? $classes[$class] = $inspector->getFileName() : null;
-			} elseif ($options['group'] === 'files') {
-				$classes[$inspector->getFileName()][] = $inspector;
-			}
-		}
-		return $classes;
-	}
-
-	/**
-	 * Gets the static and dynamic dependencies for a class or group of classes.
-	 *
-	 * @param mixed $classes Either a string specifying a class, or a numerically indexed array
-	 *        of classes
-	 * @param array $options
-	 * @return array An array of the static and dynamic class dependencies
-	 * @todo Document valid options
-	 */
-	public static function dependencies($classes, array $options = array()) {
-		$defaults = array('type' => null);
-		$options += $defaults;
-		$static = $dynamic = array();
-		$trim = function($c) { return trim(trim($c, '\\')); };
-		$join = function ($i) { return join('', $i); };
-
-		foreach ((array) $classes as $class) {
-			$data = explode("\n", file_get_contents(Libraries::path($class)));
-			$data = "<?php \n" . join("\n", preg_grep('/^\s*use /', $data)) . "\n ?>";
-
-			$classes = array_map($join, Parser::find($data, 'use *;', array(
-				'return'      => 'content',
-				'lineBreaks'  => true,
-				'startOfLine' => true,
-				'capture'     => array('T_STRING', 'T_NS_SEPARATOR')
-			)));
-
-			if ($classes) {
-				$static = array_unique(array_merge($static, array_map($trim, $classes)));
-			}
-			$classes = static::info($class . '::$_classes', array('value'));
-
-			if (isset($classes['value'])) {
-				$dynamic = array_merge($dynamic, array_map($trim, array_values($classes['value'])));
-			}
-		}
-
-		if (empty($options['type'])) {
-			return array_unique(array_merge($static, $dynamic));
-		}
-		$type = $options['type'];
-		return isset(${$type}) ? ${$type} : null;
-	}
-
-	/**
-	 * Returns an instance of the given class without directly instantiating it. Inspired by the
-	 * work of Sebastian Bergmann on the PHP Object Freezer project.
-	 *
-	 * @link http://sebastian-bergmann.de/archives/831-Freezing-and-Thawing-PHP-Objects.html
-	 *       Freezing and Thawing PHP Objects
-	 * @param string $class The name of the class to return an instance of.
-	 * @return object Returns an instance of the object given by `$class` without calling that
-	 *        class' constructor.
-	 */
-	protected static function _class($class) {
-		if (!class_exists($class)) {
-			throw new RuntimeException(sprintf('Class `%s` could not be found.', $class));
-		}
-		return unserialize(sprintf('O:%d:"%s":0:{}', strlen($class), $class));
-	}
-
-	/**
-	 * Helper method to get an array of `ReflectionMethod` or `ReflectionProperty` objects, wrapped
-	 * in a `Collection` object, and filtered based on a set of options.
-	 *
-	 * @param ReflectionClass $class A reflection class instance from which to fetch.
-	 * @param string $method A getter method to call on the `ReflectionClass` instance, which will
-	 *               return an array of items, i.e. `'getProperties'` or `'getMethods'`.
-	 * @param array $options The options used to filter the resulting method list.
-	 * @return object Returns a `Collection` object instance containing the results of the items
-	 *         returned from the call to the method specified in `$method`, after being passed
-	 *         through the filters specified in `$options`.
-	 */
-	protected static function _items($class, $method, $options) {
-		$defaults = array('names' => array(), 'self' => true, 'public' => true);
-		$options += $defaults;
-
-		$params = array(
-			'getProperties' => ReflectionProperty::IS_PUBLIC | (
-				$options['public'] ? 0 : ReflectionProperty::IS_PROTECTED
-			)
-		);
-		$data = isset($params[$method]) ? $class->{$method}($params[$method]) : $class->{$method}();
-
-		if (!empty($options['names'])) {
-			$data = array_filter($data, function($item) use ($options) {
-				return in_array($item->getName(), (array) $options['names']);
-			});
-		}
-
-		if ($options['self']) {
-			$data = array_filter($data, function($item) use ($class) {
-				return ($item->getDeclaringClass()->getName() === $class->getName());
-			});
-		}
-
-		if ($options['public']) {
-			$data = array_filter($data, function($item) { return $item->isPublic(); });
-		}
-		return static::_instance('collection', compact('data'));
-	}
-
-	/**
-	 * Helper method to determine if a class applies to a list of modifiers.
-	 *
-	 * @param string $inspector ReflectionClass instance.
-	 * @param array|string $list List of modifiers to test.
-	 * @return boolean Test result.
-	 */
-	protected static function _modifiers($inspector, $list = array()) {
-		$list = $list ?: array('public', 'private', 'protected', 'abstract', 'final', 'static');
-		return array_filter($list, function($modifier) use ($inspector) {
-			$method = 'is' . ucfirst($modifier);
-			return (method_exists($inspector, $method) && $inspector->{$method}());
-		});
-	}
-}
-
-?>

+ 0 - 196
frameworks/PHP/php-lithium/libraries/lithium/analysis/Logger.php

@@ -1,196 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis;
-
-use UnexpectedValueException;
-
-/**
- * The `Logger` class provides a consistent, application-wide interface for configuring and writing
- * log messages. As with other subclasses of `Adaptable`, `Logger` can be configured with a series
- * of named configurations, each containing a log adapter to write to. `Logger` exposes a single
- * method, `write()`, which can write to one or more log adapters.
- *
- * When configuring adapters, you may specify one or more priorities for each, using the
- * `'priority'` key. This key can be a single priority level (string), or an array of multiple
- * levels. When a log message is written, all adapters that are configured to accept the priority
- * level with which the message was written will receive the message.
- *
- * {{{
- * Logger::config(array(
- * 	'default' => array('adapter' => 'Syslog'),
- * 	'badnews' => array(
- * 		'adapter' => 'File',
- * 		'priority' => array('emergency', 'alert', 'critical', 'error')
- * 	)
- * ));
- * }}}
- *
- * In the above configuration, all messages will be written to the system log (`syslogd`), but only
- * messages with the priority `error` or higher will be logged to a file. Messages can then be
- * written to the log(s) using the `write()` method:
- *
- * {{{ Logger::write('alert', 'This is an alert-level message that will be logged in 2 places'); }}}
- *
- * Messages can also be written using the log priority as a method name:
- *
- * {{{ Logger::alert('This is an alert-level message that will be logged in 2 places'); }}}
- *
- * This works identically to the above. The message priority levels which `Logger` supports are as
- * follows: `emergency`, `alert`, `critical`, `error`, `warning`, `notice`, `info` and `debug`.
- * Attempting to use any other priority level will raise an exception. See the list of available
- * adapters for more information on what adapters are available, and how to configure them.
- *
- * @see lithium\analysis\logger\adapter
- */
-class Logger extends \lithium\core\Adaptable {
-
-	/**
-	 * Stores configurations for cache adapters.
-	 *
-	 * @var object `Collection` of logger configurations.
-	 */
-	protected static $_configurations = array();
-
-	/**
-	 * Libraries::locate() compatible path to adapters for this class.
-	 *
-	 * @see lithium\core\Libraries::locate()
-	 * @var string Dot-delimited path.
-	 */
-	protected static $_adapters = 'adapter.analysis.logger';
-
-	/**
-	 * An array of valid message priorities.
-	 *
-	 * @var array
-	 */
-	protected static $_priorities = array(
-		'emergency' => 0,
-		'alert'     => 1,
-		'critical'  => 2,
-		'error'     => 3,
-		'warning'   => 4,
-		'notice'    => 5,
-		'info'      => 6,
-		'debug'     => 7
-	);
-
-	/**
-	 * Writes a message to one or more log adapters, where the adapters that are written to are the
-	 * ones that respond to the given priority level.
-	 *
-	 * @param string $priority The priority of the log message to be written.
-	 * @param string $message The message to be written.
-	 * @param array $options An array of adapter-specific options that may be passed when writing
-	 *              log messages. Some options are also handled by `Logger` itself:
-	 *              - `'name'` _string_: This option can be specified if you wish to write to a
-	 *                specific adapter configuration, instead of writing to the adapter(s) that
-	 *                respond to the given priority.
-	 * @return boolean Returns `true` if all log writes succeeded, or `false` if _any or all_ writes
-	 *         failed.
-	 * @throws UnexpectedValueException If the value of `$priority` is not a defined priority value,
-	 *         an `UnexpectedValueException` will be thrown.
-	 * @filter
-	 */
-	public static function write($priority, $message, array $options = array()) {
-		$defaults = array('name' => null);
-		$options += $defaults;
-		$result = true;
-
-		if (isset(self::$_configurations[$options['name']])) {
-			$name = $options['name'];
-			$methods = array($name => static::adapter($name)->write($priority, $message, $options));
-		} elseif (!isset(static::$_priorities[$priority])) {
-			$message = "Attempted to write log message with invalid priority `{$priority}`.";
-			throw new UnexpectedValueException($message);
-		} else {
-			$methods = static::_configsByPriority($priority, $message, $options);
-		}
-
-		foreach ($methods as $name => $method) {
-			$params = compact('priority', 'message', 'options');
-			$config = static::_config($name);
-			$result &= static::_filter(__FUNCTION__, $params, $method, $config['filters']);
-		}
-		return $methods ? $result : false;
-	}
-
-	/**
-	 * Acts as a proxy for the `write()` method, allowing log message priority names to be called as
-	 * methods, i.e.:
-	 * {{{
-	 * Logger::emergency('Something bad happened.');
-	 * // This is equivalent to Logger::write('emergency', 'Something bad happened')
-	 * }}}
-	 *
-	 * @param string $priority The name of the method called on the `Logger` class. This should map
-	 *               to a log type.
-	 * @param array $params An array of parameters passed in the method.
-	 * @return boolean Returns `true` or `false`, depending on the success of the `write()` method.
-	 */
-	public static function __callStatic($priority, $params) {
-		$params += array(null, array());
-		return static::write($priority, $params[0], $params[1]);
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public static function respondsTo($method, $internal = false) {
-		return isset(static::$_priorities[$method]) || parent::respondsTo($method, $internal);
-	}
-
-	/**
-	 * This method is called automatically to initialize the default configuration of a log adapter,
-	 * such that the adapter defaults to accepting log messages of any priority (i.e. the
-	 * `'priority'` key is set to `true`).
-	 *
-	 * @param string $name The name of the logger configuration.
-	 * @param array $config The logger configuration as specified in application code.
-	 * @return array Returns an array of configuration data, merged with default values.
-	 */
-	protected static function _initConfig($name, $config) {
-		$defaults = array('priority' => true);
-		return parent::_initConfig($name, $config) + $defaults;
-	}
-
-	/**
-	 * Gets the names of the adapter configurations that respond to a specific priority. The list
-	 * of adapter configurations returned will be used to write a message with the given priority.
-	 *
-	 * @param string $priority The priority level of a message to be written.
-	 * @param string $message The message to write to the adapter.
-	 * @param array $options Adapter-specific options.
-	 * @return array Returns an array of names of configurations which are set up to respond to the
-	 *         message priority specified in `$priority`, or configured to respond to _all_ message
-	 *        priorities.
-	 */
-	protected static function _configsByPriority($priority, $message, array $options = array()) {
-		$configs = array();
-		$key = 'priority';
-
-		foreach (array_keys(static::$_configurations) as $name) {
-			$config = static::config($name);
-			$nameMatch = ($config[$key] === true || $config[$key] === $priority);
-			$arrayMatch = (is_array($config[$key]) && in_array($priority, $config[$key]));
-
-			if ($nameMatch || $arrayMatch) {
-				$method = static::adapter($name)->write($priority, $message, $options);
-				$method ? $configs[$name] = $method : null;
-			}
-		}
-		return $configs;
-	}
-}
-
-?>

+ 0 - 315
frameworks/PHP/php-lithium/libraries/lithium/analysis/Parser.php

@@ -1,315 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis;
-
-use lithium\util\Set;
-use lithium\util\Collection;
-
-/**
- * The parser class uses PHP's tokenizer to provide methods and tools for performing static analysis
- * on PHP code.
- */
-class Parser extends \lithium\core\StaticObject {
-
-	/**
-	 * Convenience method to get the token name of a PHP code string. If multiple tokens are
-	 * present in the string, only the first is returned.
-	 *
-	 * @param string $string String of PHP code to get the token name of, i.e. `'=>'` or `'static'`.
-	 * @param array $options
-	 * @return mixed
-	 */
-	public static function token($string, array $options = array()) {
-		$defaults = array('id' => false);
-		$options += $defaults;
-
-		if (empty($string) && $string !== '0') {
-			return false;
-		}
-		list($token) = static::tokenize($string);
-		return $token[($options['id']) ? 'id' : 'name'];
-	}
-
-	/**
-	 * Splits the provided `$code` into PHP language tokens.
-	 *
-	 * @param string $code Source code to be tokenized.
-	 * @param array $options Options consists of:
-	 *        -'wrap': Boolean indicating whether or not to wrap the supplied
-	 *          code in PHP tags.
-	 *        -'ignore': An array containing PHP language tokens to ignore.
-	 *        -'include': If supplied, an array of the only language tokens
-	 *         to include in the output.
-	 * @return array An array of tokens in the supplied source code.
-	 */
-	public static function tokenize($code, array $options = array()) {
-		$defaults = array('wrap' => true, 'ignore' => array(), 'include' => array());
-		$options += $defaults;
-		$tokens = array();
-		$line = 1;
-
-		if ($options['wrap']) {
-			$code = "<?php {$code}?>";
-		}
-		foreach (token_get_all($code) as $token) {
-			$token = (isset($token[1])) ? $token : array(null, $token, $line);
-			list($id, $content, $line) = $token;
-			$name = $id ? token_name($id) : $content;
-
-			if (!empty($options['include'])) {
-				if (!in_array($name, $options['include']) && !in_array($id, $options['include'])) {
-					continue;
-				}
-			}
-
-			if (!empty($options['ignore'])) {
-				if (in_array($name, $options['ignore']) || in_array($id, $options['ignore'])) {
-					continue;
-				}
-			}
-			$tokens[] = array('id' => $id, 'name' => $name, 'content' => $content, 'line' => $line);
-
-			$line += count(preg_split('/\r\n|\r|\n/', $content)) - 1;
-		}
-
-		if ($options['wrap'] && empty($options['include'])) {
-			$tokens = array_slice($tokens, 1, count($tokens) - 2);
-		}
-		return $tokens;
-	}
-
-	/**
-	 * Finds a pattern in a block of code.
-	 *
-	 * @param string $code
-	 * @param string $pattern
-	 * @param array $options The list of options to be used when parsing / matching `$code`:
-	 *              - 'ignore': An array of token names to ignore while parsing, defaults to
-	 *               `array('T_WHITESPACE')`
-	 *              - 'lineBreaks': If true, all tokens in a single pattern match must appear on the
-	 *                same line of code, defaults to false
-	 *              - 'startOfLine': If true, the pattern must match starting with the beginning of
-	 *                the line of code to be matched, defaults to false
-	 * @return array
-	 */
-	public static function find($code, $pattern, array $options = array()) {
-		$defaults = array(
-			'all' => true, 'capture' => array(), 'ignore' => array('T_WHITESPACE'),
-			'return' => true, 'lineBreaks' => false, 'startOfLine' => false
-		);
-		$options += $defaults;
-		$results = array();
-		$matches = array();
-		$patternMatch = array();
-		$ret = $options['return'];
-
-		$tokens = new Collection(array('data' => static::tokenize($code, $options)));
-		$pattern = new Collection(array('data' => static::tokenize($pattern, $options)));
-
-		$breaks = function($token) use (&$tokens, &$matches, &$patternMatch, $options) {
-			if (!$options['lineBreaks']) {
-				return true;
-			}
-			if (empty($patternMatch) && !$options['startOfLine']) {
-				return true;
-			}
-
-			if (empty($patternMatch)) {
-				$prev = $tokens->prev();
-				$tokens->next();
-			} else {
-				$prev = reset($patternMatch);
-			}
-
-			if (empty($patternMatch) && $options['startOfLine']) {
-				return ($token['line'] > $prev['line']);
-			}
-			return ($token['line'] == $prev['line']);
-		};
-
-		$capture = function($token) use (&$matches, &$patternMatch, $tokens, $breaks, $options) {
-			if (is_null($token)) {
-				$matches = $patternMatch = array();
-				return false;
-			}
-
-			if (empty($patternMatch)) {
-				$prev = $tokens->prev();
-				$tokens->next();
-				if ($options['startOfLine'] && $token['line'] == $prev['line']) {
-					$patternMatch = $matches = array();
-					return false;
-				}
-			}
-			$patternMatch[] = $token;
-
-			if (empty($options['capture']) || !in_array($token['name'], $options['capture'])) {
-				return true;
-			}
-			if (!$breaks($token)) {
-				$matches = array();
-				return true;
-			}
-			$matches[] = $token;
-			return true;
-		};
-
-		$executors = array(
-			'*' => function(&$tokens, &$pattern) use ($options, $capture) {
-				$closing = $pattern->next();
-				$tokens->prev();
-
-				while (($t = $tokens->next()) && !Parser::matchToken($closing, $t)) {
-					$capture($t);
-				}
-				$pattern->next();
-			}
-		);
-
-		$tokens->rewind();
-		$pattern->rewind();
-
-		while ($tokens->valid()) {
-			if (!$pattern->valid()) {
-				$pattern->rewind();
-
-				if (!empty($matches)) {
-					$results[] = array_map(
-						function($i) use ($ret) { return isset($i[$ret]) ? $i[$ret] : $i; },
-						$matches
-					);
-				}
-				$capture(null);
-			}
-
-			$p = $pattern->current();
-			$t = $tokens->current();
-
-			switch (true) {
-				case (static::matchToken($p, $t)):
-					$capture($t) ? $pattern->next() : $pattern->rewind();
-				break;
-				case (isset($executors[$p['name']])):
-					$exec = $executors[$p['name']];
-					$exec($tokens, $pattern);
-				break;
-				default:
-					$capture(null);
-					$pattern->rewind();
-				break;
-			}
-			$tokens->next();
-		}
-		return $results;
-	}
-
-	/**
-	 * Token pattern matching.
-	 *
-	 * @param string $code Source code to be analyzed.
-	 * @param string $parameters An array containing token patterns to be matched.
-	 * @param array $options The list of options to be used when matching `$code`:
-	 *              - 'ignore': An array of language tokens to ignore.
-	 *              - 'return': If set to 'content' returns an array of matching tokens.
-	 * @return array Array of matching tokens.
-	 */
-	public static function match($code, $parameters, array $options = array()) {
-		$defaults = array('ignore' => array('T_WHITESPACE'), 'return' => true);
-		$options += $defaults;
-		$parameters = static::_prepareMatchParams($parameters);
-
-		$tokens = is_array($code) ? $code : static::tokenize($code, $options);
-		$results = array();
-
-		foreach ($tokens as $i => $token) {
-			if (!array_key_exists($token['name'], $parameters)) {
-				if (!in_array('*', $parameters)) {
-					continue;
-				}
-			}
-			$param = $parameters[$token['name']];
-
-			if (isset($param['before']) && $i > 0) {
-				if (!in_array($tokens[$i - 1]['name'], (array) $param['before'])) {
-					continue;
-				}
-			}
-
-			if (isset($param['after']) && $i + 1 < count($tokens)) {
-				 if (!in_array($tokens[$i + 1]['name'], (array) $param['after'])) {
-					continue;
-				}
-			}
-			$results[] = isset($token[$options['return']]) ? $token[$options['return']] : $token;
-		}
-		return $results;
-	}
-
-	/**
-	 * Compares two PHP language tokens.
-	 *
-	 * @param array $pattern Pattern token.
-	 * @param array $token Token to be compared.
-	 * @return boolean Match result.
-	 */
-	public static function matchToken($pattern, $token) {
-		if ($pattern['name'] != $token['name']) {
-			return false;
-		}
-
-		if (!isset($pattern['content'])) {
-			return true;
-		}
-
-		$match = $pattern['content'];
-		$content = $token['content'];
-
-		if ($pattern['name'] === 'T_VARIABLE') {
-			$match = substr($match, 1);
-			$content = substr($content, 1);
-		}
-
-		switch (true) {
-			case ($match === '_' || $match == $content):
-				return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Helper function to normalize parameters for token matching.
-	 *
-	 * @see lithium\analysis\Parser::match()
-	 * @param array $parameters Params to be normalized.
-	 * @return array Normalized parameters.
-	 */
-	protected static function _prepareMatchParams($parameters) {
-		foreach (Set::normalize($parameters) as $token => $scope) {
-			if (strpos($token, 'T_') !== 0) {
-				unset($parameters[$token]);
-
-				foreach (array('before', 'after') as $key) {
-					if (!isset($scope[$key])) {
-						continue;
-					}
-					$items = array();
-
-					foreach ((array) $scope[$key] as $item) {
-						$items[] = (strpos($item, 'T_') !== 0)  ? static::token($item) : $item;
-					}
-					$scope[$key] = $items;
-				}
-				$parameters[static::token($token)] = $scope;
-			}
-		}
-		return $parameters;
-	}
-}
-
-?>

+ 0 - 81
frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/Cache.php

@@ -1,81 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis\logger\adapter;
-
-use lithium\util\String;
-
-/**
- * The `Cache` logger allows log messages to be written to cache configurations set up in
- * `lithium\storage\Cache`. In order to use this adapter, you must first configure a cache adapter
- * for it to write to, as follows:
- *
- * {{{ lithium\storage\Cache::config(array(
- * 	'storage' => array('adapter' => 'Redis', 'host' => '127.0.0.1:6379')
- * ));}}}
- *
- * Then, you can configure the `Cache` logger with the `'storage'` config:
- * {{{ lithium\analysis\Logger::config(array(
- * 	'debug' => array('adapter' => 'Cache', 'config' => 'storage')
- * ));
- * }}}
- *
- * You can then send messages to the logger which will be written to the cache store:
- * {{{
- * lithium\analysis\Logger::write('debug', 'This message will be written to a Redis data store.');
- * }}}
- *
- * @see lithium\storage\Cache
- */
-class Cache extends \lithium\core\Object {
-
-	/**
-	 * Classes used by `Cache`.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'cache' => 'lithium\storage\Cache'
-	);
-
-	/**
-	 * Class constructor.
-	 *
-	 * @param array $config
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'config' => null,
-			'expiry' => '+999 days',
-			'key' => 'log_{:type}_{:timestamp}'
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Writes the message to the configured cache adapter.
-	 *
-	 * @param string $type
-	 * @param string $message
-	 * @return closure Function returning boolean `true` on successful write, `false` otherwise.
-	 */
-	public function write($type, $message) {
-		$config = $this->_config + $this->_classes;
-
-		return function($self, $params) use ($config) {
-			$params += array('timestamp' => strtotime('now'));
-			$key = $config['key'];
-			$key = is_callable($key) ? $key($params) : String::insert($key, $params);
-
-			$cache = $config['cache'];
-			return $cache::write($config['config'], $key, $params['message'], $config['expiry']);
-		};
-	}
-}
-
-?>

+ 0 - 83
frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/File.php

@@ -1,83 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis\logger\adapter;
-
-use lithium\util\String;
-use lithium\core\Libraries;
-
-/**
- * A simple log adapter that writes messages to files. By default, messages are written to
- * `resources/tmp/logs/<type>.log`, where `<type>` is the log message priority level.
- *
- * {{{
- * use lithium\analysis\Logger;
- *
- * Logger::config(array(
- * 	'simple' => array('adapter' => 'File')
- * ));
- * Logger::write('debug', 'Something happened!');
- * }}}
- *
- * This will cause the message and the timestamp of the log event to be written to
- * `resources/tmp/logs/debug.log`. For available configuration options for this adapter, see
- * the `__construct()` method.
- *
- * @see lithium\analysis\logger\adapter\File::__construct()
- */
-class File extends \lithium\core\Object {
-
-	/**
-	 * Class constructor.
-	 *
-	 * @see lithium\util\String::insert()
-	 * @param array $config Settings used to configure the adapter. Available options:
-	 *              - `'path'` _string_: The directory to write log files to. Defaults to
-	 *                `<app>/resources/tmp/logs`.
-	 *              - `'timestamp'` _string_: The `date()`-compatible timestamp format. Defaults to
-	 *                `'Y-m-d H:i:s'`.
-	 *              - `'file'` _closure_: A closure which accepts two parameters: an array
-	 *                containing the current log message details, and an array containing the `File`
-	 *                adapter's current configuration. It must then return a file name to write the
-	 *                log message to. The default will produce a log file name corresponding to the
-	 *                priority of the log message, i.e. `"debug.log"` or `"alert.log"`.
-	 *              - `'format'` _string_: A `String::insert()`-compatible string that specifies how
-	 *                the log message should be formatted. The default format is
-	 *                `"{:timestamp} {:message}\n"`.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'path' => Libraries::get(true, 'resources') . '/tmp/logs',
-			'timestamp' => 'Y-m-d H:i:s',
-			'file' => function($data, $config) { return "{$data['priority']}.log"; },
-			'format' => "{:timestamp} {:message}\n"
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Appends a message to a log file.
-	 *
-	 * @see lithium\analysis\Logger::$_priorities
-	 * @param string $priority The message priority. See `Logger::$_priorities`.
-	 * @param string $message The message to write to the log.
-	 * @return closure Function returning boolean `true` on successful write, `false` otherwise.
-	 */
-	public function write($priority, $message) {
-		$config = $this->_config;
-
-		return function($self, $params) use (&$config) {
-			$path = $config['path'] . '/' . $config['file']($params, $config);
-			$params['timestamp'] = date($config['timestamp']);
-			$message = String::insert($config['format'], $params);
-			return file_put_contents($path, $message, FILE_APPEND);
-		};
-	}
-}
-
-?>

+ 0 - 194
frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/FirePhp.php

@@ -1,194 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis\logger\adapter;
-
-/**
- * The `FirePhp` log adapter allows you to log messages to [ FirePHP](http://www.firephp.org/).
- *
- * This allows you to inspect native PHP values and objects inside the FireBug console.
- *
- * Because this adapter interacts directly with the `Response` object, some additional code is
- * required to use it. The simplest way to achieve this is to add a filter to the `Dispatcher`. For
- * example, the following can be placed in a bootstrap file:
- *
- * {{{
- * use lithium\action\Dispatcher;
- * use lithium\analysis\Logger;
- *
- * Logger::config(array(
- * 	'default' => array('adapter' => 'FirePhp')
- * ));
- *
- * Dispatcher::applyFilter('_call', function($self, $params, $chain) {
- * 	if (isset($params['callable']->response)) {
- * 		Logger::adapter('default')->bind($params['callable']->response);
- * 	}
- * 	return $chain->next($self, $params, $chain);
- * });
- * }}}
- *
- * This will cause the message and other debug settings added to the header of the
- * response, where FirePHP is able to locate and print it accordingly. As this adapter
- * implements the protocol specification directly, you don't need another vendor library to
- * use it.
- *
- * Now, in you can use the logger in your application code (like controllers, views and models).
- *
- * {{{
- * class PagesController extends \lithium\action\Controller {
- * 	public function view() {
- * 		//...
- * 		Logger::error("Something bad happened!");
- * 		//...
- * 	}
- * }
- * }}}
- *
- * Because this adapter also has a queue implemented, it is possible to log messages even when the
- * `Response` object is not yet generated. When it gets generated (and bound), all queued messages
- * get flushed instantly.
- *
- * Because FirePHP is not a conventional logging destination like a file or a database, you can
- * pass everything (except resources) to the logger and inspect it further in FirePHP. In fact,
- * every message that is passed will be encoded via `json_encode()`, so check out this built-in
- * method for more information on how your message will be encoded.
- *
- * {{{
- * Logger::debug(array('debug' => 'me'));
- * Logger::debug(new \lithium\action\Response());
- * }}}
- *
- * @see lithium\action\Response
- * @see lithium\net\http\Message::headers()
- * @link http://www.firephp.org/ FirePHP
- * @link http://www.firephp.org/Wiki/Reference/Protocol FirePHP Protocol Reference
- * @link http://php.net/manual/en/function.json-encode.php PHP Manual: `json_encode()`
- */
-class FirePhp extends \lithium\core\Object {
-
-	/**
-	 * These headers are specified by FirePHP and get added as headers to the response.
-	 *
-	 * @var array
-	 */
-	protected $_headers = array(
-		'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2',
-		'X-Wf-1-Plugin-1' =>
-			'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3',
-		'X-Wf-1-Structure-1' =>
-			'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'
-	);
-
-	/**
-	 * This is a mapping table that maps Lithium log levels to FirePHP log levels as they
-	 * do not correlate directly and FirePHP only accepts a distinct set.
-	 *
-	 * @var array
-	 */
-	protected $_levels = array(
-		'emergency' => 'ERROR',
-		'alert'     => 'ERROR',
-		'critical'  => 'ERROR',
-		'error'     => 'ERROR',
-		'warning'   => 'WARN',
-		'notice'    => 'INFO',
-		'info'      => 'INFO',
-		'debug'     => 'LOG'
-	);
-
-	/**
-	 * This self-incrementing counter allows the user to log more than one message per request.
-	 *
-	 * @var integer
-	 */
-	protected $_counter = 1;
-
-	/**
-	 * Holds the response object where the headers will be inserted.
-	 */
-	protected $_response = null;
-
-	/**
-	 * Contains messages that have been written to the log before the bind() call.
-	 */
-	protected $_queue = array();
-
-	/**
-	 * Binds the response object to the logger and sets the required Wildfire
-	 * protocol headers.
-	 *
-	 * @param object $response An instance of a response object (usually `lithium\action\Response`)
-	 *               with HTTP request information.
-	 * @return void
-	 */
-	public function bind($response) {
-		$this->_response = $response;
-		$this->_response->headers += $this->_headers;
-
-		foreach ($this->_queue as $message) {
-			$this->_write($message);
-		}
-	}
-
-	/**
-	 * Appends a log message to the response header for FirePHP.
-	 *
-	 * @param string $priority Represents the message priority.
-	 * @param string $message Contains the actual message to store.
-	 * @return boolean Always returns `true`. Note that in order for message-writing to take effect,
-	 *                 the adapter must be bound to the `Response` object instance associated with
-	 *                 the current request. See the `bind()` method.
-	 */
-	public function write($priority, $message) {
-		$_self =& $this;
-
-		return function($self, $params) use (&$_self) {
-			$priority = $params['priority'];
-			$message = $params['message'];
-			$message = $_self->invokeMethod('_format', array($priority, $message));
-			$_self->invokeMethod('_write', array($message));
-			return true;
-		};
-	}
-
-	/**
-	 * Heper method that writes the message to the header of a bound `Response` object. If no
-	 * `Response` object is bound when this method is called, it is stored in a message queue.
-	 *
-	 * @see lithium\analysis\logger\adapter\FirePhp::_format()
-	 * @param array $message A message containing the key and the content to store.
-	 * @return void
-	 */
-	protected function _write($message) {
-		if (!$this->_response) {
-			return $this->_queue[] = $message;
-		}
-		$this->_response->headers[$message['key']] = $message['content'];
-	}
-
-	/**
-	 * Generates a string representation of the type and message, suitable for FirePHP.
-	 *
-	 * @param string $type Represents the message priority.
-	 * @param string $message Contains the actual message to store.
-	 * @return array Returns the encoded string representations of the priority and message, in the
-	 *               `'key'` and `'content'` keys, respectively.
-	 */
-	protected function _format($type, $message) {
-		$key = 'X-Wf-1-1-1-' . $this->_counter++;
-
-		$content = array(array('Type' => $this->_levels[$type]), $message);
-		$content = json_encode($content);
-		$content = strlen($content) . '|' . $content . '|';
-
-		return compact('key', 'content');
-	}
-}
-
-?>

+ 0 - 247
frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/Growl.php

@@ -1,247 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis\logger\adapter;
-
-use lithium\util\Inflector;
-use lithium\core\NetworkException;
-
-/**
- * The `Growl` logger implements support for the [ Growl](http://growl.info/) notification system
- * for Mac OS X. Writing to this logger will display small, customizable status messages on the
- * screen.
- */
-class Growl extends \lithium\core\Object {
-
-	/**
-	 * Array that maps `Logger` message priority names to Growl-compatible priority levels.
-	 *
-	 * @var array
-	 */
-	protected $_priorities = array(
-		'emergency' => 2,
-		'alert'     => 1,
-		'critical'  => 1,
-		'error'     => 1,
-		'warning'   => 0,
-		'notice'    => -1,
-		'info'      => -2,
-		'debug'     => -2
-	);
-
-	/**
-	 * The Growl protocol version used to send messages.
-	 */
-	const PROTOCOL_VERSION = 1;
-
-	/**
-	 * There are two types of messages sent to Growl: one to register applications, and one to send
-	 * notifications. This type registers the application with Growl's settings.
-	 */
-	const TYPE_REG = 0;
-
-	/**
-	 * This message type is for sending notifications to Growl.
-	 */
-	const TYPE_NOTIFY = 1;
-
-	/**
-	 * Holds the connection resource used to send messages to Growl.
-	 *
-	 * @var resource
-	 */
-	protected $_connection = null;
-
-	/**
-	 * Flag indicating whether the logger has successfully registered with the Growl server.
-	 * Registration only needs to happen once, but may fail for several reasons, including inability
-	 * to connect to the server, or the server requires a password which has not been specified.
-	 *
-	 * @var boolean
-	 */
-	protected $_registered = false;
-
-	/**
-	 * Allow the Growl connection resource to be auto-configured from constructor parameters.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('connection', 'registered');
-
-	/**
-	 * Growl logger constructor. Accepts an array of settings which are merged with the default
-	 * settings and used to create the connection and handle notifications.
-	 *
-	 * @see lithium\analysis\Logger::write()
-	 * @param array $config The settings to configure the logger. Available settings are as follows:
-	 *              - `'name`' _string_: The name of the application as it should appear in Growl's
-	 *                system settings. Defaults to the directory name containing your application.
-	 *              - `'host'` _string_: The Growl host with which to communicate, usually your
-	 *                local machine. Use this setting to send notifications to another machine on
-	 *                the network. Defaults to `'127.0.0.1'`.
-	 *              - `'port'` _integer_: Port of the host machine. Defaults to the standard Growl
-	 *                port, `9887`.
-	 *              - `'password'` _string_: Only required if the host machine requires a password.
-	 *                If notification or registration fails, check this against the host machine's
-	 *                Growl settings.
-	 *              - '`protocol'` _string_: Protocol to use when opening socket communication to
-	 *                Growl. Defaults to `'udp'`.
-	 *              - `'title'` _string_: The default title to display when showing Growl messages.
-	 *                The default value is the same as `'name'`, but can be changed on a per-message
-	 *                basis by specifying a `'title'` key in the `$options` parameter of
-	 *                `Logger::write()`.
-	 *              - `'notification'` _array_: A list of message types you wish to register with
-	 *                Growl to be able to send. Defaults to `array('Errors', 'Messages')`.
-	 */
-	public function __construct(array $config = array()) {
-		$name = basename(LITHIUM_APP_PATH);
-
-		$defaults = compact('name') + array(
-			'host'     => '127.0.0.1',
-			'port'     => 9887,
-			'password' => null,
-			'protocol' => 'udp',
-			'title'    => Inflector::humanize($name),
-			'notifications' => array('Errors', 'Messages'),
-			'registered' => false
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Writes `$message` to a new Growl notification.
-	 *
-	 * @param string $type The `Logger`-based priority of the message. This value is mapped to
-	 *               a Growl-specific priority value if possible.
-	 * @param string $message Message to be shown.
-	 * @param array $options Any options that are passed to the `notify()` method. See the
-	 *              `$options` parameter of `notify()`.
-	 * @return closure Function returning boolean `true` on successful write, `false` otherwise.
-	 */
-	public function write($type, $message, array $options = array()) {
-		$_self =& $this;
-		$_priorities = $this->_priorities;
-
-		return function($self, $params) use (&$_self, $_priorities) {
-			$priority = 0;
-			$options = $params['options'];
-
-			if (isset($options['priority']) && isset($_priorities[$options['priority']])) {
-				$priority = $_priorities[$options['priority']];
-			}
-			return $_self->notify($params['message'], compact('priority') + $options);
-		};
-	}
-
-	/**
-	 * Posts a new notification to the Growl server.
-	 *
-	 * @param string $description Message to be displayed.
-	 * @param array $options Options consists of:
-	 *        -'title': The title of the displayed notification. Displays the
-	 *         name of the application's parent folder by default.
-	 * @return boolean Always returns `true`.
-	 */
-	public function notify($description = '', $options = array()) {
-		$this->_register();
-
-		$defaults = array('sticky' => false, 'priority' => 0, 'type' => 'Messages');
-		$options += $defaults + array('title' => $this->_config['title']);
-		$type = $options['type'];
-		$title = $options['title'];
-
-		$message = compact('type', 'title', 'description') + array('app' => $this->_config['name']);
-		$message = array_map('utf8_encode', $message);
-
-		$flags = ($options['priority'] & 7) * 2;
-		$flags = ($options['priority'] < 0) ? $flags |= 8 : $flags;
-		$flags = ($options['sticky']) ? $flags | 256 : $flags;
-
-		$params = array('c2n5', static::PROTOCOL_VERSION, static::TYPE_NOTIFY, $flags);
-		$lengths = array_map('strlen', $message);
-
-		$data = call_user_func_array('pack', array_merge($params, $lengths));
-		$data .= join('', $message);
-		$data .= pack('H32', md5($data . $this->_config['password']));
-
-		$this->_send($data);
-		return true;
-	}
-
-	/**
-	 * Growl server connection registration and initialization.
-	 *
-	 * @return boolean True
-	 */
-	protected function _register() {
-		if ($this->_registered) {
-			return true;
-		}
-		$ct = count($this->_config['notifications']);
-		$app = utf8_encode($this->_config['name']);
-		$nameEnc = $defaultEnc = '';
-
-		foreach ($this->_config['notifications'] as $i => $name) {
-			$name = utf8_encode($name);
-			$nameEnc .= pack('n', strlen($name)) . $name;
-			$defaultEnc .= pack('c', $i);
-		}
-		$data = pack('c2nc2', static::PROTOCOL_VERSION, static::TYPE_REG, strlen($app), $ct, $ct);
-		$data .= $app . $nameEnc . $defaultEnc;
-		$checksum = pack('H32', md5($data . $this->_config['password']));
-		$data .= $checksum;
-
-		$this->_send($data);
-		return $this->_registered = true;
-	}
-
-	/**
-	 * Creates a connection to the Growl server using the protocol, host and port configurations
-	 * specified in the constructor.
-	 *
-	 * @return resource Returns a connection resource created by `fsockopen()`.
-	 */
-	protected function _connection() {
-		if ($this->_connection) {
-			return $this->_connection;
-		}
-		$host = "{$this->_config['protocol']}://{$this->_config['host']}";
-
-		if ($this->_connection = fsockopen($host, $this->_config['port'], $message, $code)) {
-			return $this->_connection;
-		}
-		throw new NetworkException("Growl connection failed: (`{$code}`) `{$message}`.");
-	}
-
-	/**
-	 * Sends binary data to the Growl server.
-	 *
-	 * @throws NetworkException Throws an exception if the server connection could not be written
-	 *         to.
-	 * @param string $data The raw binary data to send to the Growl server.
-	 * @return boolean Always returns `true`.
-	 */
-	protected function _send($data) {
-		if (fwrite($this->_connection(), $data, strlen($data)) === false) {
-			throw new NetworkException('Could not send registration to Growl Server.');
-		}
-		return true;
-	}
-
-	/**
-	 * Destructor method. Closes and releases the socket connection to Growl.
-	 */
-	public function __destruct() {
-		if (is_resource($this->_connection)) {
-			fclose($this->_connection);
-			unset($this->_connection);
-		}
-	}
-}
-
-?>

+ 0 - 86
frameworks/PHP/php-lithium/libraries/lithium/analysis/logger/adapter/Syslog.php

@@ -1,86 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\analysis\logger\adapter;
-
-/**
- * The Syslog adapter facilitates logging messages to a `syslogd` backend. See the constructor for
- * information on configuring this adapter.
- *
- * @see lithium\analysis\logger\adapter\Syslog::__construct()
- */
-class Syslog extends \lithium\core\Object {
-
-	/**
-	 * Flag indicating whether or not the connection to `syslogd` has been opened yet.
-	 *
-	 * @var boolean
-	 */
-	protected $_isConnected = false;
-
-	/**
-	 * Array that maps `Logger` message priority names to `syslog`-compatible priority constants.
-	 *
-	 * @var array
-	 */
-	protected $_priorities = array(
-		'emergency' => LOG_EMERG,
-		'alert'     => LOG_ALERT,
-		'critical'  => LOG_CRIT,
-		'error'     => LOG_ERR,
-		'warning'   => LOG_WARNING,
-		'notice'    => LOG_NOTICE,
-		'info'      => LOG_INFO,
-		'debug'     => LOG_DEBUG
-	);
-
-	/**
-	 * Class constructor. Configures the `Syslog` adapter instance with the default settings. For
-	 * more information on these settings, see the documentation for
-	 * [the `openlog()` function](http://php.net/openlog).
-	 *
-	 * @param array $config Available configuration settings for this adapter:
-	 *              - `'identity'` _string_: The identity string to be attached to each message in
-	 *                the system log. This is usually a string that meaningfully identifies your
-	 *                application. Defaults to `false`.
-	 *              - `'options'` _integer_: The flags to use when opening the log. Defaults to
-	 *                `LOG_ODELAY`.
-	 *              - `'facility'` _integer_: A flag specifying the program to use to log the
-	 *                messages. See the `openlog()` documentation for more information. Defaults to
-	 *                `LOG_USER`.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('identity' => false, 'options'  => LOG_ODELAY, 'facility' => LOG_USER);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Appends `$message` to the system log.
-	 *
-	 * @param string $priority The message priority string. Maps to a `syslogd` priority constant.
-	 * @param string $message The message to write.
-	 * @return closure Function returning boolean `true` on successful write, `false` otherwise.
-	 */
-	public function write($priority, $message) {
-		$config = $this->_config;
-		$_priorities = $this->_priorities;
-
-		if (!$this->_isConnected) {
-			closelog();
-			openlog($config['identity'], $config['options'], $config['facility']);
-			$this->_isConnected = true;
-		}
-
-		return function($self, $params) use ($_priorities) {
-			$priority = $_priorities[$params['priority']];
-			return syslog($priority, $params['message']);
-		};
-	}
-}
-
-?>

+ 0 - 22
frameworks/PHP/php-lithium/libraries/lithium/composer.json

@@ -1,22 +0,0 @@
-{
-	"name": "UnionOfRAD/lithium",
-	"type": "lithium-library",
-	"description": "The core library of the Lithium PHP framework",
-	"keywords": ["lithium", "framework"],
-	"homepage": "http://lithify.me",
-	"license": "BSD-3-Clause",
-	"authors": [
-		{
-			"name": "Union of RAD",
-			"homepage": "http://union-of-rad.org"
-		},
-		{
-			"name": "The Lithium Community",
-			"homepage": "http://github.com/UnionOfRAD/lithium/graphs/contributors"
-		}
-	],
-	"require": {
-		"php": ">=5.3.6",
-		"composer/installers": "dev-master"
-	}
-}

+ 0 - 423
frameworks/PHP/php-lithium/libraries/lithium/console/Command.php

@@ -1,423 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console;
-
-use Exception;
-use lithium\console\command\Help;
-
-/**
- * All Commands to be run from the Lithium console must extend this class.
- *
- * The `run` method is automatically called if it exists. Otherwise, if a method does not exist
- * the `Help` command will be run.
- *
- * {{{
- * $ li3 example
- * $ li3 example --format=json
- * }}}
- *
- */
-class Command extends \lithium\core\Object {
-
-	/**
-	 * If -h or --help param exists a help screen will be returned.
-	 * Similar to running `li3 help COMMAND`.
-	 *
-	 * @var boolean
-	 */
-	public $help = false;
-
-	/**
-	 * A Request object.
-	 *
-	 * @see lithium\console\Request
-	 * @var object
-	 */
-	public $request;
-
-	/**
-	 * A Response object.
-	 *
-	 * @see lithium\console\Response
-	 * @var object
-	 */
-	public $response;
-
-	/**
-	 * Only shows only text output without styles.
-	 *
-	 * @var boolean
-	 */
-	public $plain = false;
-
-	/**
-	 * Only shows error output.
-	 *
-	 * @var boolean
-	 */
-	public $silent = false;
-
-	/**
-	 * Dynamic dependencies.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'response' => 'lithium\console\Response'
-	);
-
-	/**
-	 * Auto configuration.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('classes' => 'merge');
-
-	/**
-	 * Constructor.
-	 *
-	 * @param array $config
-	 * @return void
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('request' => null, 'response' => array(), 'classes' => $this->_classes);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Command Initializer.
-	 *
-	 * Populates the `$response` property with a new instance of the `Response` class passing it
-	 * configuration and assigns the values from named parameters of the request (if applicable) to
-	 * properties of the command.
-	 *
-	 * @return void
-	 */
-	protected function _init() {
-		parent::_init();
-		$this->request = $this->_config['request'];
-
-		if (!is_object($this->request) || !$this->request->params) {
-			return;
-		}
-		$this->response = $this->_config['response'];
-
-		if (!is_object($this->response)) {
-			$this->response = $this->_instance('response', $this->response);
-		}
-		$default = array('command' => null, 'action' => null, 'args' => null);
-		$params = array_diff_key((array) $this->request->params, $default);
-
-		foreach ($params as $key => $param) {
-			$this->{$key} = $param;
-		}
-	}
-
-	/**
-	 * Called by the `Dispatcher` class to invoke an action.
-	 *
-	 * @see lithium\console\Dispatcher
-	 * @see lithium\console\Response
-	 * @param string $action The name of the method to run.
-	 * @param array $args The arguments from the request.
-	 * @param array $options
-	 * @return object The response object associated with this command.
-	 * @todo Implement filters.
-	 */
-	public function __invoke($action, $args = array(), $options = array()) {
-		try {
-			$this->response->status = 1;
-			$result = $this->invokeMethod($action, $args);
-
-			if (is_int($result)) {
-				$this->response->status = $result;
-			} elseif ($result || $result === null) {
-				$this->response->status = 0;
-			}
-		} catch (Exception $e) {
-			$this->error($e->getMessage());
-		}
-		return $this->response;
-	}
-
-	/**
-	 * Invokes the `Help` command.
-	 *
-	 * The invoked Help command will take over request and response objects of
-	 * the originally invoked command. Thus the response of the Help command
-	 * becomes the response of the original one.
-	 *
-	 * @return boolean
-	 */
-	protected function _help() {
-		$help = new Help(array(
-			'request' => $this->request,
-			'response' => $this->response,
-			'classes' => $this->_classes
-		));
-		return $help->run(get_class($this));
-	}
-
-	/**
-	 * Writes a string to the output stream.
-	 *
-	 * @param string $output The string to write.
-	 * @param integer|string|array $options
-	 *        integer as the number of new lines.
-	 *        string as the style
-	 *        array as :
-	 *        - nl : number of new lines to add at the end
-	 *        - style : the style name to wrap around the
-	 * @return integer
-	 */
-	public function out($output = null, $options = array('nl' => 1)) {
-		if ($this->silent) {
-			return;
-		}
-		return $this->_response('output', $output, $options);
-	}
-
-	/**
-	 * Writes a string to error stream.
-	 *
-	 * @param string $error The string to write.
-	 * @param integer|string|array $options
-	 *        integer as the number of new lines.
-	 *        string as the style
-	 *        array as :
-	 *        - nl : number of new lines to add at the end
-	 *        - style : the style name to wrap around the
-	 * @return integer
-	 */
-	public function error($error = null, $options = array('nl' => 1)) {
-		return $this->_response('error', $error, $options);
-	}
-
-	/**
-	 * Handles input. Will continue to loop until `$options['quit']` or
-	 * result is part of `$options['choices']`.
-	 *
-	 * @param string $prompt
-	 * @param array $options
-	 * @return string Returns the result of the input data. If the input is equal to the `quit`
-	 *          option boolean `false` is returned
-	 */
-	public function in($prompt = null, array $options = array()) {
-		$defaults = array('choices' => null, 'default' => null, 'quit' => 'q');
-		$options += $defaults;
-		$choices = null;
-
-		if (is_array($options['choices'])) {
-			$choices = '(' . implode('/', $options['choices']) . ')';
-		}
-		$default = $options['default'] ? "[{$options['default']}] " : '';
-
-		do {
-			$this->out("{$prompt} {$choices} \n {$default}> ", false);
-			$result = trim($this->request->input());
-		} while (
-			!empty($options['choices']) && !in_array($result, $options['choices'], true)
-			&& (empty($options['quit']) || $result !== $options['quit'])
-			&& (!$options['default'] || $result !== '')
-		);
-
-		if ($result == $options['quit']) {
-			return false;
-		}
-
-		if ($options['default'] !== null && $result == '') {
-			return $options['default'];
-		}
-		return $result;
-	}
-
-	/**
-	 * Writes a header to the output stream. In addition to the actual text,
-	 * horizontal lines before and afterwards are written. The lines will have
-	 * the same length as the text. This behavior can be modified by providing
-	 * the length of lines as a second paramerter.
-	 *
-	 * Given the text `'Lithium'` this generates following output:
-	 *
-	 * {{{
-	 * -------
-	 * Lithium
-	 * -------
-	 * }}}
-	 *
-	 * @param string $text The heading text.
-	 * @param integer $line The length of the line. Defaults to the length of text.
-	 * @return void
-	 */
-	public function header($text, $line = null) {
-		if (!$line) {
-			$line = strlen($text);
-		}
-		$this->hr($line);
-		$this->out($text, 1, 'heading');
-		$this->hr($line);
-	}
-
-	/**
-	 * Writes rows of columns.
-	 *
-	 * This method expects asceding integer values as the keys, which map to the appropriate
-	 * columns. Currently, there is no special "header" option, but you can define them for your
-	 * own.
-	 *
-	 * Example Usage:
-	 *
-	 * {{{
-	 * $output = array(
-	 *     array('Name', 'Age'),
-	 *     array('----', '---'),
-	 * );
-	 * foreach($users as $user) {
-	 *     $output[] = array($user->name, $user->age);
-	 * }
-	 * $this->columns($output);
-	 * }}}
-	 *
-	 * Would render something similar to:
-	 *
-	 * {{{
-	 * Name       Age
-	 * ----       ---
-	 * Jane Doe   22
-	 * Foo Bar    18
-	 * }}}
-	 *
-	 * This method also calculates the needed space between the columns. All option params given
-	 * also get passed down to the `out()` method, which allow custom formatting. Passing something
-	 * like `$this->columns($output, array('style' => 'red)` would print the table in red.
-	 *
-	 * @see lithium\console\Response::styles()
-	 * @param array $rows The rows to print, with each column as an array element.
-	 * @param array $options Optional params:
-	 *      - separator : Different column separator, defaults to `\t`
-	 *      - style : the style name to wrap around the columns output
-	 * @return void
-	 */
-	public function columns($rows, $options = array()) {
-		$defaults = array('separator' => "\t", "error" => false);
-		$options += $defaults;
-		$lengths = array_reduce($rows, function($columns, $row) {
-			foreach ((array) $row as $key => $val) {
-				if (!isset($columns[$key]) || strlen($val) > $columns[$key]) {
-					$columns[$key] = strlen($val);
-				}
-			}
-			return $columns;
-		});
-		$rows = array_reduce($rows, function($rows, $row) use ($lengths, $options) {
-			$text = '';
-			foreach ((array) $row as $key => $val) {
-				$text = $text . str_pad($val, $lengths[$key]) . $options['separator'];
-			}
-			$rows[] = $text;
-			return $rows;
-		});
-		if ($options['error']) {
-			$this->error($rows, $options);
-			return;
-		}
-		$this->out($rows, $options);
-	}
-
-	/**
-	 * Add newlines ("\n") a given number of times and return them in a single string.
-	 *
-	 * @param integer $number The number of new lines to fill into a string.
-	 * @return string
-	 */
-	public function nl($number = 1) {
-		return str_repeat("\n", $number);
-	}
-
-	/**
-	 * Adds a horizontal line to output stream.
-	 *
-	 * @param integer $length The length of the line, defaults to 80.
-	 * @param integer $newlines How many new lines to print afterwards, defaults to 1.
-	 * @return integer
-	 */
-	public function hr($length = 80, $newlines = 1) {
-		return $this->out(str_repeat('-', $length), $newlines);
-	}
-
-	/**
-	 * Clears the entire screen.
-	 *
-	 * @return void
-	 */
-	public function clear() {
-		passthru(strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? 'cls' : 'clear');
-	}
-
-	/**
-	 * Stop execution, by exiting the script.
-	 *
-	 * @param integer $status Numeric value that will be used on `exit()`.
-	 * @param boolean $message An optional message that will be written to the stream.
-	 * @return void
-	 */
-	public function stop($status = 0, $message = null) {
-		if ($message) {
-			($status == 0) ? $this->out($message) : $this->error($message);
-		}
-		exit($status);
-	}
-
-	/**
-	 * Handles the response that is sent to the stream.
-	 *
-	 * @param string $type the stream either output or error
-	 * @param string $string the message to render
-	 * @param integer|string|array $options
-	 *        integer as the number of new lines.
-	 *        string as the style
-	 *        array as :
-	 *        - nl : number of new lines to add at the end
-	 *        - style : the style name to wrap around the
-	 * @return void
-	 */
-	protected function _response($type, $string, $options) {
-		$defaults = array('nl' => 1, 'style' => null);
-
-		if (!is_array($options)) {
-			if (!$options || is_int($options)) {
-				$options = array('nl' => $options);
-			} else if (is_string($options)) {
-				$options = array('style' => $options);
-			} else {
-				$options = array();
-			}
-		}
-		$options += $defaults;
-
-		if (is_array($string)) {
-			$method = ($type == 'error' ? $type : 'out');
-			foreach ($string as $out) {
-				$this->{$method}($out, $options);
-			}
-			return;
-		}
-		extract($options);
-
-		if ($style !== null && !$this->plain) {
-			$string = "{:{$style}}{$string}{:end}";
-		}
-		if ($nl) {
-			$string = $string . $this->nl($nl);
-		}
-		return $this->response->{$type}($string);
-	}
-}
-
-?>

+ 0 - 202
frameworks/PHP/php-lithium/libraries/lithium/console/Dispatcher.php

@@ -1,202 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console;
-
-use lithium\core\Libraries;
-use lithium\core\Environment;
-use UnexpectedValueException;
-
-/**
- * The `Dispatcher` is the outermost layer of the framework, responsible for both receiving the
- * initial console request and returning back a response at the end of the request's life cycle.
- *
- * The console dispatcher is responsible for accepting requests from scripts called from the command
- * line, and executing the appropriate `Command` class(es). The `run()` method accepts an instance
- * of `lithium\console\Request`, which encapsulates the console environment and any command-line
- * parameters passed to the script. `Dispatcher` then invokes `lithium\console\Router` to determine
- * the correct `Command` class to invoke, and which method should be called.
- */
-class Dispatcher extends \lithium\core\StaticObject {
-
-	/**
-	 * Fully-namespaced router class reference.
-	 *
-	 * Class must implement a `parse()` method, which must return an array with (at a minimum)
-	 * 'command' and 'action' keys.
-	 *
-	 * @see lithium\console\Router::parse()
-	 * @var array
-	 */
-	protected static $_classes = array(
-		'request' => 'lithium\console\Request',
-		'router' => 'lithium\console\Router'
-	);
-
-	/**
-	 * Contains pre-process format strings for changing Dispatcher's behavior based on 'rules'.
-	 *
-	 * Each key in the array represents a 'rule'; if a key that matches the rule is present (and
-	 * not empty) in a route, (i.e. the result of `lithium\console\Router::parse()`) then the rule's
-	 * value will be applied to the route before it is dispatched.  When applying a rule, any array
-	 * elements array elements of the flag which are present in the route will be modified using a
-	 * `lithium\util\String::insert()`-formatted string.
-	 *
-	 * @see lithium\console\Dispatcher::config()
-	 * @see lithium\util\String::insert()
-	 * @var array
-	 */
-	protected static $_rules = array(
-		'command' => array(array('lithium\util\Inflector', 'camelize')),
-		'action' => array(array('lithium\util\Inflector', 'camelize', array(false)))
-	);
-
-	/**
-	 * Used to set configuration parameters for the Dispatcher.
-	 *
-	 * @param array $config Optional configuration params.
-	 * @return array If no parameters are passed, returns an associative array with the
-	 *         current configuration, otherwise returns null.
-	 */
-	public static function config($config = array()) {
-		if (!$config) {
-			return array('rules' => static::$_rules);
-		}
-		foreach ($config as $key => $val) {
-			if (isset(static::${'_' . $key})) {
-				static::${'_' . $key} = $val + static::${'_' . $key};
-			}
-		}
-	}
-
-	/**
-	 * Dispatches a request based on a request object (an instance of `lithium\console\Request`).
-	 *
-	 *  If `$request` is `null`, a new request object is instantiated based on the value of the
-	 * `'request'` key in the `$_classes` array.
-	 *
-	 * @param object $request An instance of a request object with console request information.  If
-	 *        `null`, an instance will be created.
-	 * @param array $options
-	 * @return object The command action result which is an instance of `lithium\console\Response`.
-	 */
-	public static function run($request = null, $options = array()) {
-		$defaults = array('request' => array());
-		$options += $defaults;
-		$classes = static::$_classes;
-		$params = compact('request', 'options');
-
-		return static::_filter(__FUNCTION__, $params, function($self, $params) use ($classes) {
-			$request = $params['request'];
-			$options = $params['options'];
-			$router = $classes['router'];
-			$request = $request ?: new $classes['request']($options['request']);
-			$request->params = $router::parse($request);
-			$params = $self::applyRules($request->params);
-			Environment::set($request);
-			try {
-				$callable = $self::invokeMethod('_callable', array($request, $params, $options));
-				return $self::invokeMethod('_call', array($callable, $request, $params));
-			} catch (UnexpectedValueException $e) {
-				return (object) array('status' => $e->getMessage() . "\n");
-			}
-		});
-	}
-
-	/**
-	 * Determines which command to use for current request.
-	 *
-	 * @param object $request An instance of a `Request` object.
-	 * @param array $params Request params that can be accessed inside the filter.
-	 * @param array $options
-	 * @return class lithium\console\Command Returns the instantiated command object.
-	 */
-	protected static function _callable($request, $params, $options) {
-		$params = compact('request', 'params', 'options');
-		return static::_filter(__FUNCTION__, $params, function($self, $params) {
-			$request = $params['request'];
-			$params = $params['params'];
-			$name = $params['command'];
-
-			if (!$name) {
-				$request->params['args'][0] = $name;
-				$name = 'lithium\console\command\Help';
-			}
-			if (class_exists($class = Libraries::locate('command', $name))) {
-				return new $class(compact('request'));
-			}
-			throw new UnexpectedValueException("Command `{$name}` not found.");
-		});
-	}
-
-	/**
-	 * Attempts to apply a set of formatting rules from `$_rules` to a `$params` array.
-	 *
-	 * Each formatting rule is applied if the key of the rule in `$_rules` is present and not empty
-	 * in `$params`.  Also performs sanity checking against `$params` to ensure that no value
-	 * matching a rule is present unless the rule check passes.
-	 *
-	 * @param array $params An array of route parameters to which rules will be applied.
-	 * @return array Returns the `$params` array with formatting rules applied to array values.
-	 */
-	public static function applyRules($params) {
-		$result = array();
-
-		if (!$params) {
-			return false;
-		}
-
-		foreach (static::$_rules as $name => $rules) {
-			foreach ($rules as $rule) {
-				if (!empty($params[$name]) && isset($rule[0])) {
-					$options = array_merge(
-						array($params[$name]), isset($rule[2]) ? (array) $rule[2] : array()
-					);
-					$result[$name] = call_user_func_array(array($rule[0], $rule[1]), $options);
-				}
-			}
-		}
-		return $result + array_diff_key($params, $result);
-	}
-
-	/**
-	 * Calls a given command with the appropriate action.
-	 *
-	 * This method is responsible for calling a `$callable` command and returning its result.
-	 *
-	 * @param string $callable The callable command.
-	 * @param string $request The associated `Request` object.
-	 * @param string $params Additional params that should be passed along.
-	 * @return mixed Returns the result of the called action, typically `true` or `false`.
-	 */
-	protected static function _call($callable, $request, $params) {
-		$params = compact('callable', 'request', 'params');
-		return static::_filter(__FUNCTION__, $params, function($self, $params) {
-			if (is_callable($callable = $params['callable'])) {
-				$request = $params['request'];
-				$params = $params['params'];
-
-				if (!method_exists($callable, $params['action'])) {
-					array_unshift($params['args'], $request->params['action']);
-					$params['action'] = 'run';
-				}
-				$isHelp = (
-					!empty($params['help']) || !empty($params['h'])
-					|| !method_exists($callable, $params['action'])
-				);
-				if ($isHelp) {
-					$params['action'] = '_help';
-				}
-				return $callable($params['action'], $params['args']);
-			}
-			throw new UnexpectedValueException("Callable `{$callable}` is actually not callable.");
-		});
-	}
-}
-
-?>

+ 0 - 203
frameworks/PHP/php-lithium/libraries/lithium/console/Request.php

@@ -1,203 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console;
-
-/**
- * The `Request` class represents a console request and holds information about it's
- * environment as well as passed arguments.
- *
- * @see lithium\console\Dispatcher
- */
-class Request extends \lithium\core\Object {
-
-	/**
-	 * The raw data passed from the command line
-	 *
-	 * @var array
-	 */
-	public $argv = array();
-
-	/**
-	 * Parameters parsed from arguments.
-	 *
-	 * @see lithium\console\Router
-	 * @var array
-	 */
-	public $params = array(
-		'command' => null, 'action' => 'run', 'args' => array()
-	);
-
-	/**
-	 * Input (STDIN).
-	 *
-	 * @var resource
-	 */
-	public $input;
-
-	/**
-	 * Enviroment variables.
-	 *
-	 * @var array
-	 */
-	protected $_env = array();
-
-	/**
-	 * Holds the value of the current locale, set through the `locale()` method.
-	 *
-	 * @var string
-	 */
-	protected $_locale = null;
-
-	/**
-	 * Auto configuration
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('env' => 'merge');
-
-	/**
-	 * Class Constructor
-	 *
-	 * @param array $config
-	 */
-	public function __construct($config = array()) {
-		$defaults = array('args' => array(), 'input' => null);
-		$config += $defaults;
-		parent::__construct($config);
-	}
-
-	/**
-	 * Initialize request object, pulling request data from superglobals.
-	 *
-	 * Defines an artificial `'PLATFORM'` environment variable as `'CLI'` to
-	 * allow checking for the SAPI in a normalized way. This is also for
-	 * establishing consistency with this class' sister classes.
-	 *
-	 * @see lithium\action\Request::_init()
-	 * @return void
-	 */
-	protected function _init() {
-		$this->_env += (array) $_SERVER + (array) $_ENV;
-		$this->_env['working'] = getcwd() ?: null;
-		$argv = (array) $this->env('argv');
-		$this->_env['script'] = array_shift($argv);
-		$this->_env['PLATFORM'] = 'CLI';
-		$this->argv += $argv + (array) $this->_config['args'];
-		$this->input = $this->_config['input'];
-
-		if (!is_resource($this->_config['input'])) {
-			$this->input = fopen('php://stdin', 'r');
-		}
-		parent::_init();
-	}
-
-	/**
-	 * Allows request parameters to be accessed as object properties, i.e. `$this->request->action`
-	 * instead of `$this->request->params['action']`.
-	 *
-	 * @see lithium\action\Request::$params
-	 * @param string $name The property name/parameter key to return.
-	 * @return mixed Returns the value of `$params[$name]` if it is set, otherwise returns null.
-	 */
-	public function __get($name) {
-		if (isset($this->params[$name])) {
-			return $this->params[$name];
-		}
-	}
-
-	public function __isset($name) {
-		return isset($this->params[$name]);
-	}
-
-	/**
-	 * Get the value of a command line argument at a given key
-	 *
-	 * @param integer $key
-	 * @return mixed returns null if key does not exist or the value of the key in the args array
-	 */
-	public function args($key = 0) {
-		if (!empty($this->args[$key])) {
-			return $this->args[$key];
-		}
-		return null;
-	}
-
-	/**
-	 * Get environment variables.
-	 *
-	 * @param string $key
-	 * @return mixed Returns the environment key related to the `$key` argument. If `$key` is equal
-	 * to null the result will be the entire environment array. If `$key` is set but not
-	 * available, `null` will be returned.
-	 */
-	public function env($key = null) {
-		if (!empty($this->_env[$key])) {
-			return $this->_env[$key];
-		}
-		if ($key === null) {
-			return $this->_env;
-		}
-		return null;
-	}
-
-	/**
-	 * Moves params up a level. Sets command to action, action to passed[0], and so on.
-	 *
-	 * @param integer $num how many times to shift
-	 * @return self
-	 */
-	public function shift($num = 1) {
-		for ($i = $num; $i > 1; $i--) {
-			$this->shift(--$i);
-		}
-		$this->params['command'] = $this->params['action'];
-		if (isset($this->params['args'][0])) {
-			$this->params['action'] = array_shift($this->params['args']);
-		}
-		return $this;
-	}
-
-	/**
-	 * Reads a line from input.
-	 *
-	 * @return string
-	 */
-	public function input() {
-		return fgets($this->input);
-	}
-
-	/**
-	 * Sets or returns the current locale string. For more information, see
-	 * "[Globalization](http://lithify.me/docs/manual/07_globalization)" in the manual.
-	 *
-	 * @param string $locale An optional locale string like `'en'`, `'en_US'` or `'de_DE'`. If
-	 *               specified, will overwrite the existing locale.
-	 * @return Returns the currently set locale string.
-	 */
-	public function locale($locale = null) {
-		if ($locale) {
-			$this->_locale = $locale;
-		}
-		return $this->_locale;
-	}
-
-	/**
-	 * Return input
-	 * Destructor. Closes input.
-	 *
-	 * @return void
-	 */
-	public function __destruct() {
-		if ($this->input) {
-			fclose($this->input);
-		}
-	}
-}
-
-?>

+ 0 - 142
frameworks/PHP/php-lithium/libraries/lithium/console/Response.php

@@ -1,142 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console;
-
-use lithium\util\String;
-
-/**
- * The `Response` class is used by other console classes to generate output. It contains stream
- * resources for writing output and errors, as well as shell coloring information, and the response
- * status code for the currently-executing command.
- */
-class Response extends \lithium\core\Object {
-
-	/**
-	 * Output stream, STDOUT
-	 *
-	 * @var stream
-	 */
-	public $output = null;
-
-	/**
-	 * Error stream, STDERR
-	 *
-	 * @var stream
-	 */
-	public $error = null;
-
-	/**
-	 * Status code, most often used for setting an exit status.
-	 *
-	 * It should be expected that only status codes in the range of 0-255
-	 * can be properly evaluated.
-	 *
-	 * @var integer
-	 * @see lithium\console\Command
-	 */
-	public $status = 0;
-
-	/**
-	 * Construct Request object
-	 *
-	 * @param array $config
-	 *              - request object lithium\console\Request
-	 *              - output stream
-	 *              _ error stream
-	 */
-	public function __construct($config = array()) {
-		$defaults = array('output' => null, 'error' => null);
-		$config += $defaults;
-
-		$this->output = $config['output'];
-
-		if (!is_resource($this->output)) {
-			$this->output = fopen('php://stdout', 'r');
-		}
-
-		$this->error = $config['error'];
-
-		if (!is_resource($this->error)) {
-			$this->error = fopen('php://stderr', 'r');
-		}
-		parent::__construct($config);
-	}
-
-	/**
-	 * Writes string to output stream
-	 *
-	 * @param string $output
-	 * @return mixed
-	 */
-	public function output($output) {
-		return fwrite($this->output, String::insert($output, $this->styles()));
-	}
-
-	/**
-	 * Writes string to error stream
-	 *
-	 * @param string $error
-	 * @return mixed
-	 */
-	public function error($error) {
-		return fwrite($this->error, String::insert($error, $this->styles()));
-	}
-
-	/**
-	 * Destructor to close streams
-	 *
-	 * @return void
-	 *
-	 */
-	public function __destruct() {
-		if ($this->output) {
-			fclose($this->output);
-		}
-		if ($this->error) {
-			fclose($this->error);
-		}
-	}
-
-	/**
-	 * Handles styling output.
-	 *
-	 * @param array $styles
-	 * @return array
-	 */
-	public function styles($styles = array()) {
-		$defaults = array(
-			'end'    => "\033[0m",
-			'black'  => "\033[0;30m",
-			'red'    => "\033[0;31m",
-			'green'  => "\033[0;32m",
-			'yellow' => "\033[0;33m",
-			'blue'   => "\033[0;34m",
-			'purple' => "\033[0;35m",
-			'cyan'   => "\033[0;36m",
-			'white'  => "\033[0;37m",
-			'heading' => "\033[1;36m",
-			'option'  => "\033[0;35m",
-			'command' => "\033[0;35m",
-			'error'   => "\033[0;31m",
-			'success' => "\033[0;32m",
-			'bold'    => "\033[1m",
-		);
-		if ($styles === false) {
-			return array_combine(array_keys($defaults), array_pad(array(), count($defaults), null));
-		}
-		$styles += $defaults;
-
-		if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
-			return $this->styles(false);
-		}
-		return $styles;
-	}
-}
-
-?>

+ 0 - 55
frameworks/PHP/php-lithium/libraries/lithium/console/Router.php

@@ -1,55 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console;
-
-/**
- * The `Router` class uses an instance of `lithium\console\Request`, which represents an incoming
- * command-line invocation, to parse the correct command, and sub-command(s) and parameters, which
- * are used by `lithium\console\Dispatcher` to load and execute the proper `Command` class.
- */
-class Router extends \lithium\core\Object {
-
-	/**
-	 * Parse incoming request from console. Short and long (GNU-style) options
-	 * in the form of `-f`, `--foo`, `--foo-bar` and `--foo=bar` are parsed.
-	 * XF68-style long options (i.e. `-foo`) are not supported but support
-	 * can be added by extending this class.
-	 *
-	 * @param object $request lithium\console\Request
-	 * @return array $params
-	 */
-	public static function parse($request = null) {
-		$defaults = array('command' => null, 'action' => 'run', 'args' => array());
-		$params = $request ? (array) $request->params + $defaults : $defaults;
-
-		if (!empty($request->argv)) {
-			$args = $request->argv;
-
-			while ($arg = array_shift($args)) {
-				if (preg_match('/^-(?P<key>[a-zA-Z0-9])$/i', $arg, $match)) {
-					$params[$match['key']] = true;
-					continue;
-				}
-				if (preg_match('/^--(?P<key>[a-z0-9-]+)(?:=(?P<val>.+))?$/i', $arg, $match)) {
-					$params[$match['key']] = !isset($match['val']) ? true : $match['val'];
-					continue;
-				}
-				$params['args'][] = $arg;
-			}
-		}
-		foreach (array('command', 'action') as $param) {
-			if (!empty($params['args'])) {
-				$params[$param] = array_shift($params['args']);
-			}
-		}
-		return $params;
-	}
-}
-
-?>

+ 0 - 260
frameworks/PHP/php-lithium/libraries/lithium/console/command/Create.php

@@ -1,260 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command;
-
-use lithium\util\String;
-use lithium\core\Libraries;
-use lithium\util\Inflector;
-use lithium\core\ClassNotFoundException;
-
-/**
- * The `create` command allows you to rapidly develop your models, views, controllers, and tests
- * by generating the minimum code necessary to test and run your application.
- *
- * `li3 create --template=controller Posts`
- * `li3 create --template=model Posts`
- *
- */
-class Create extends \lithium\console\Command {
-
-	/**
-	 * Name of library to use
-	 *
-	 * @var string
-	 */
-	public $library = null;
-
-	/**
-	 * The name of the template to use to generate the file. This allows you to add a custom
-	 * template to be used in place of the core template for each command. Place templates in
-	 * `<library>\extensions\command\create\template`.
-	 *
-	 * @var string
-	 */
-	public $template = null;
-
-	/**
-	 * Holds library data from `lithium\core\Libraries::get()`.
-	 *
-	 * @var array
-	 */
-	protected $_library = array();
-
-	/**
-	 * Class initializer. Parses template and sets up params that need to be filled.
-	 *
-	 * @return void
-	 */
-	protected function _init() {
-		parent::_init();
-		$this->library = $this->library ?: true;
-		$defaults = array('prefix' => null, 'path' => null);
-		$this->_library = (array) Libraries::get($this->library) + $defaults;
-	}
-
-	/**
-	 * Run the create command. Takes `$command` and delegates to `$command::$method`
-	 *
-	 * @param string $command
-	 * @return boolean
-	 */
-	public function run($command = null) {
-		if ($command && !$this->request->args()) {
-			return $this->_default($command);
-		}
-		$this->request->shift();
-		$this->template = $this->template ?: $command;
-
-		if (!$command) {
-			return false;
-		}
-		if ($this->_execute($command)) {
-			return true;
-		}
-		$this->error("{$command} could not be created.");
-		return false;
-	}
-
-	/**
-	 * Execute the given sub-command for the current request.
-	 *
-	 * @param string $command The sub-command name. example: Model, Controller, Test
-	 * @return boolean
-	 */
-	protected function _execute($command) {
-		try {
-			if (!$class = $this->_instance($command)) {
-				return false;
-			}
-		} catch (ClassNotFoundException $e) {
-			return false;
-		}
-		$data = array();
-		$params = $class->invokeMethod('_params');
-
-		foreach ($params as $i => $param) {
-			$data[$param] = $class->invokeMethod("_{$param}", array($this->request));
-		}
-
-		if ($message = $class->invokeMethod('_save', array($data))) {
-			$this->out($message);
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Run through the default set. model, controller, test model, test controller
-	 *
-	 * @param string $name class name to create
-	 * @return boolean
-	 */
-	protected function _default($name) {
-		$commands = array(
-			array('model', Inflector::pluralize($name)),
-			array('controller', Inflector::pluralize($name)),
-			array('test', 'model', Inflector::pluralize($name)),
-			array('test', 'controller', Inflector::pluralize($name))
-		);
-		foreach ($commands as $args) {
-			$command = $this->template = $this->request->params['command'] = array_shift($args);
-			$this->request->params['action'] = array_shift($args);
-			$this->request->params['args'] = $args;
-
-			if (!$this->_execute($command)) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Get the namespace.
-	 *
-	 * @param string $request
-	 * @param array $options
-	 * @return string
-	 */
-	protected function _namespace($request, $options  = array()) {
-		$name = $request->command;
-		$defaults = array(
-			'prefix' => $this->_library['prefix'],
-			'prepend' => null,
-			'spaces' => array(
-				'model' => 'models', 'view' => 'views', 'controller' => 'controllers',
-				'command' => 'extensions.command', 'adapter' => 'extensions.adapter',
-				'helper' => 'extensions.helper'
-			)
-		);
-		$options += $defaults;
-
-		if (isset($options['spaces'][$name])) {
-			$name = $options['spaces'][$name];
-		}
-		return str_replace('.', '\\', $options['prefix'] . $options['prepend'] . $name);
-	}
-
-	/**
-	 * Parse a template to find available variables specified in `{:name}` format. Each variable
-	 * corresponds to a method in the sub command. For example, a `{:namespace}` variable will
-	 * call the namespace method in the model command when `li3 create model Post` is called.
-	 *
-	 * @return array
-	 */
-	protected function _params() {
-		$contents = $this->_template();
-
-		if (empty($contents)) {
-			return array();
-		}
-		preg_match_all('/(?:\{:(?P<params>[^}]+)\})/', $contents, $keys);
-
-		if (!empty($keys['params'])) {
-			return array_values(array_unique($keys['params']));
-		}
-		return array();
-	}
-
-	/**
-	 * Returns the contents of the template.
-	 *
-	 * @return string
-	 */
-	protected function _template() {
-		$file = Libraries::locate('command.create.template', $this->template, array(
-			'filter' => false, 'type' => 'file', 'suffix' => '.txt.php'
-		));
-		if (!$file || is_array($file)) {
-			return false;
-		}
-		return file_get_contents($file);
-	}
-
-	/**
-	 * Get an instance of a sub-command
-	 *
-	 * @param string $name the name of the sub-command to instantiate
-	 * @param array $config
-	 * @return object;
-	 */
-	protected function _instance($name, array $config = array()) {
-		if ($class = Libraries::locate('command.create', Inflector::camelize($name))) {
-			$this->request->params['template'] = $this->template;
-
-			return new $class(array(
-				'request' => $this->request,
-				'classes' => $this->_classes
-			));
-		}
-		return parent::_instance($name, $config);
-	}
-
-
-	/**
-	 * Save a template with the current params. Writes file to `Create::$path`.
-	 *
-	 * @param array $params
-	 * @return string A result string on success of writing the file. If any errors occur along
-	 * the way such as missing information boolean false is returned.
-	 */
-	protected function _save(array $params = array()) {
-		$defaults = array('namespace' => null, 'class' => null);
-		$params += $defaults;
-
-		if (empty($params['class']) || empty($this->_library['path'])) {
-			return false;
-		}
-		$contents = $this->_template();
-		$result = String::insert($contents, $params);
-		$namespace = str_replace($this->_library['prefix'], '\\', $params['namespace']);
-		$path = str_replace('\\', '/', "{$namespace}\\{$params['class']}");
-		$path = $this->_library['path'] . stristr($path, '/');
-		$file = str_replace('//', '/', "{$path}.php");
-		$directory = dirname($file);
-		$relative = str_replace($this->_library['path'] . '/', "", $file);
-
-		if ((!is_dir($directory)) && !mkdir($directory, 0755, true)) {
-			return false;
-		}
-		if (file_exists($file)) {
-			$prompt = "{$relative} already exists. Overwrite?";
-			$choices = array('y', 'n');
-			if ($this->in($prompt, compact('choices')) !== 'y') {
-				return "{$params['class']} skipped.";
-			}
-		}
-
-		if (file_put_contents($file, "<?php\n\n{$result}\n\n?>")) {
-			return "{$params['class']} created in {$relative}.";
-		}
-		return false;
-	}
-}
-
-?>

+ 0 - 36
frameworks/PHP/php-lithium/libraries/lithium/console/command/G11n.php

@@ -1,36 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command;
-
-use lithium\console\command\g11n\Extract;
-
-/**
- * The `G11n` set of commands deals with the extraction and merging of message templates.
- */
-class G11n extends \lithium\console\Command {
-
-	/**
-	 * The main method of the command.
-	 *
-	 * @return void
-	 */
-	public function run() {}
-
-	/**
-	 * Runs the `Extract` command.
-	 *
-	 * @return void
-	 */
-	public function extract() {
-		$extract = new Extract(array('request' => $this->request));
-		return $extract->run();
-	}
-}
-
-?>

+ 0 - 322
frameworks/PHP/php-lithium/libraries/lithium/console/command/Help.php

@@ -1,322 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command;
-
-use lithium\core\Libraries;
-use lithium\core\Environment;
-use lithium\util\Inflector;
-use lithium\analysis\Inspector;
-use lithium\analysis\Docblock;
-
-/**
- * Get information about a particular class including methods, properties,
- * and descriptions.
- */
-class Help extends \lithium\console\Command {
-
-	/**
-	 * Auto run the help command.
-	 *
-	 * @param string $command Name of the command to return help about.
-	 * @return void
-	 */
-	public function run($command = null) {
-		$message = 'Lithium console started in the ' . Environment::get() . ' environment.';
-		$message .= ' Use the --env=environment key to alter this.';
-		$this->out($message);
-
-		if (!$command) {
-			$this->_renderCommands();
-			return true;
-		}
-
-		if (!preg_match('/\\\\/', $command)) {
-			$command = Inflector::camelize($command);
-		}
-
-		if (!$class = Libraries::locate('command', $command)) {
-			$this->error("Command `{$command}` not found");
-			return false;
-		}
-
-		if (strpos($command, '\\') !== false) {
-			$command = join('', array_slice(explode("\\", $command), -1));
-		}
-		$command = strtolower(Inflector::slug($command));
-
-		$run = null;
-		$methods = $this->_methods($class);
-		$properties = $this->_properties($class);
-		$info = Inspector::info($class);
-
-		$this->out('USAGE', 'heading');
-
-		if (isset($methods['run'])) {
-			$run = $methods['run'];
-			unset($methods['run']);
-			$this->_renderUsage($command, $run, $properties);
-		}
-		foreach ($methods as $method) {
-			$this->_renderUsage($command, $method);
-		}
-
-		if (!empty($info['description'])) {
-			$this->nl();
-			$this->_renderDescription($info);
-			$this->nl();
-		}
-
-		if ($properties || $methods) {
-			$this->out('OPTIONS', 'heading');
-		}
-		if ($run) {
-			$this->_render($run['args']);
-		}
-		if ($methods) {
-			$this->_render($methods);
-		}
-		if ($properties) {
-			$this->_render($properties);
-		}
-		return true;
-	}
-
-	/**
-	 * Gets the API for the class.
-	 *
-	 * @param string $class fully namespaced class in dot notation.
-	 * @param string $type method|property
-	 * @param string $name the name of the method or property.
-	 * @return array
-	 */
-	public function api($class = null, $type = null, $name = null) {
-		$class = str_replace(".", "\\", $class);
-
-		switch ($type) {
-			default:
-				$info = Inspector::info($class);
-				$result = array('class' => array(
-					'name' => $info['shortName'],
-					'description' => trim($info['description'] . PHP_EOL . PHP_EOL . $info['text'])
-				));
-			break;
-			case 'method':
-				$result = $this->_methods($class, compact('name'));
-			break;
-			case 'property':
-				$result = $this->_properties($class, compact('name'));
-			break;
-		}
-		$this->_render($result);
-	}
-
-	/**
-	 * Get the methods for the class.
-	 *
-	 * @param string $class
-	 * @param array $options
-	 * @return array
-	 */
-	protected function _methods($class, $options = array()) {
-		$defaults = array('name' => null);
-		$options += $defaults;
-
-		$map = function($item) {
-			if ($item->name[0] === '_') {
-				return;
-			}
-			$modifiers = array_values(Inspector::invokeMethod('_modifiers', array($item)));
-			$setAccess = array_intersect($modifiers, array('private', 'protected')) != array();
-
-			if ($setAccess) {
-				$item->setAccessible(true);
-			}
-			$args = array();
-
-			foreach ($item->getParameters() as $arg) {
-				$args[] = array(
-					'name' => $arg->getName(),
-					'optional' => $arg->isOptional(),
-					'description' => null
-				);
-			}
-			$result = compact('modifiers', 'args') + array(
-				'docComment' => $item->getDocComment(),
-				'name' => $item->getName()
-			);
-			if ($setAccess) {
-				$item->setAccessible(false);
-			}
-			return $result;
-		};
-
-		$methods = Inspector::methods($class)->map($map, array('collect' => false));
-		$results = array();
-
-		foreach (array_filter($methods) as $method) {
-			$comment = Docblock::comment($method['docComment']);
-
-			$name = $method['name'];
-			$description = trim($comment['description'] . PHP_EOL . $comment['text']);
-			$args = $method['args'];
-			$return = null;
-
-			foreach ($args as &$arg) {
-				if (isset($comment['tags']['params']['$' . $arg['name']])) {
-					$arg['description'] = $comment['tags']['params']['$' . $arg['name']]['text'];
-				}
-				$arg['usage'] = $arg['optional'] ? "[<{$arg['name']}>]" : "<{$arg['name']}>";
-			}
-			if (isset($comment['tags']['return'])) {
-				$return = trim(strtok($comment['tags']['return'], ' '));
-			}
-			$results[$name] = compact('name', 'description', 'return', 'args');
-
-			if ($name && $name == $options['name']) {
-				return array($name => $results[$name]);
-			}
-		}
-		return $results;
-	}
-
-	/**
-	 * Get the properties for the class.
-	 *
-	 * @param string $class
-	 * @param array $options
-	 * @return array
-	 */
-	protected function _properties($class, $options = array()) {
-		$defaults = array('name' => null);
-		$options += $defaults;
-
-		$properties = Inspector::properties($class);
-		$results = array();
-
-		foreach ($properties as &$property) {
-			$name = str_replace('_', '-', Inflector::underscore($property['name']));
-
-			$comment = Docblock::comment($property['docComment']);
-			$description = trim($comment['description']);
-			$type = isset($comment['tags']['var']) ? strtok($comment['tags']['var'], ' ') : null;
-
-			$usage = strlen($name) == 1 ? "-{$name}" : "--{$name}";
-
-			if ($type != 'boolean') {
-				$usage .= "=<{$type}>";
-			}
-			$usage = "[{$usage}]";
-
-			$results[$name] = compact('name', 'description', 'type', 'usage');
-
-			if ($name == $options['name']) {
-				return array($name => $results[$name]);
-			}
-		}
-		return $results;
-	}
-
-	/**
-	 * Output the formatted properties or methods.
-	 *
-	 * @see lithium\console\command\Help::_properties()
-	 * @see lithium\console\command\Help::_methods()
-	 * @param array $params From `_properties()` or `_methods()`.
-	 * @return void
-	 */
-	protected function _render($params) {
-		foreach ($params as $name => $param) {
-			if ($name === 'run' || empty($param['name'])) {
-				continue;
-			}
-			$usage = (!empty($param['usage'])) ? trim($param['usage'], ' []') : $param['name'];
-			$this->out($this->_pad($usage), 'option');
-
-			if ($param['description']) {
-				$this->out($this->_pad($param['description'], 2));
-			}
-			$this->nl();
-		}
-	}
-
-	/**
-	 * Output the formatted available commands.
-	 *
-	 * @return void
-	 */
-	protected function _renderCommands() {
-		$commands = Libraries::locate('command', null, array('recursive' => false));
-
-		foreach ($commands as $key => $command) {
-			$library = strtok($command, '\\');
-
-			if (!$key || strtok($commands[$key - 1] , '\\') != $library) {
-				$this->out("{:heading}COMMANDS{:end} {:blue}via {$library}{:end}");
-			}
-			$info = Inspector::info($command);
-			$name = strtolower(Inflector::slug($info['shortName']));
-
-			$this->out($this->_pad($name) , 'heading');
-			$this->out($this->_pad($info['description']), 2);
-		}
-
-		$message  = 'See `{:command}li3 help COMMAND{:end}`';
-		$message .= ' for more information on a specific command.';
-		$this->out($message, 2);
-	}
-
-	/**
-	 * Output the formatted usage.
-	 *
-	 * @see lithium\console\command\Help::_methods()
-	 * @see lithium\console\command\Help::_properties()
-	 * @param string $command The name of the command.
-	 * @param array $method Information about the method of the command to render usage for.
-	 * @param array $properties From `_properties()`.
-	 * @return void
-	 */
-	protected function _renderUsage($command, $method, $properties = array()) {
-		$params = array_reduce($properties, function($a, $b) {
-			return "{$a} {$b['usage']}";
-		});
-		$args = array_reduce($method['args'], function($a, $b) {
-			return "{$a} {$b['usage']}";
-		});
-		$format = "{:command}li3 %s%s{:end}{:command}%s{:end}{:option}%s{:end}";
-		$name = $method['name'] == 'run' ? '' : " {$method['name']}";
-		$this->out($this->_pad(sprintf($format, $command ?: 'COMMAND', $name, $params, $args)));
-	}
-
-	/**
-	 * Output the formatted command description.
-	 *
-	 * @param array $info Info from inspecting the class of the command.
-	 * @return void
-	 */
-	protected function _renderDescription($info) {
-		$this->out('DESCRIPTION', 'heading');
-		$break = PHP_EOL . PHP_EOL;
-		$description = trim("{$info['description']}{$break}{$info['text']}");
-		$this->out($this->_pad($description, PHP_EOL));
-	}
-
-	/**
-	 * Add left padding for prettier display.
-	 *
-	 * @param string $message the text to render.
-	 * @param integer|string $level the level of indentation.
-	 * @return string
-	 */
-	protected function _pad($message, $level = 1) {
-		$padding = str_repeat(' ', $level * 4);
-		return $padding . str_replace("\n", "\n{$padding}", $message);
-	}
-}
-
-?>

+ 0 - 729
frameworks/PHP/php-lithium/libraries/lithium/console/command/Library.php

@@ -1,729 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command;
-
-use Phar;
-use Exception;
-use RuntimeException;
-use lithium\core\Libraries;
-use lithium\util\String;
-use lithium\util\Inflector;
-
-/**
- * The Library command is used to archive and extract Phar::GZ archives. Requires zlib extension.
- * In addition, communicate with the a given server to add plugins and extensions to the
- * current application. Push archived plugins to the server.
- *
- */
-class Library extends \lithium\console\Command {
-
-	/**
-	 * Absolute path to config file.
-	 *
-	 * @var string
-	 */
-	public $conf = null;
-
-	/**
-	 * Path to where plugins will be installed. Relative to current working directory.
-	 *
-	 * @var string
-	 */
-	public $path = null;
-
-	/**
-	 * Server host to query for plugins.
-	 *
-	 * @var string
-	 */
-	public $server = 'lab.lithify.me';
-
-	/**
-	 * The port for the server.
-	 *
-	 * @var string
-	 */
-	public $port = 80;
-
-	/**
-	 * The username for the server authentication.
-	 *
-	 * @var string
-	 */
-	public $username = '';
-
-	/**
-	 * The password for corresponding username.
-	 *
-	 * @var string
-	 */
-	public $password = '';
-
-	/**
-	 * @see `force`
-	 * @var boolean
-	 */
-	public $f = false;
-
-	/**
-	 * Force operation to complete. Typically used for overwriting files.
-	 *
-	 * @var string
-	 */
-	public $force = false;
-
-	/**
-	 * Filter used for including files in archive.
-	 *
-	 * @var string
-	 */
-	public $filter = '/\.(php|htaccess|jpg|png|gif|css|js|ico|json|ini)|(empty)$/';
-
-	/**
-	 * Namespace used for newly extracted libraries.
-	 * Will default to the basename of the directory
-	 * the library is being extracted to.
-	 *
-	 * @var string
-	 */
-	public $namespace = null;
-
-	/**
-	 * When extracting a library, custom replacements
-	 * can be made on the extracted files that
-	 * are defined in this json file.
-	 *
-	 * @var string
-	 */
-	public $replacementsFile = '_replacements.json';
-
-	/**
-	 * The path to use for the `LITHIUM_LIBRARY_PATH`
-	 * in extracted templates.  It defaults to the
-	 * current value of the `LITHIUM_LIBRARY_PATH`
-	 * constant.  If `LITHIUM_LIBRARY_PATH` is not the same
-	 * as `dirname(LITHIUM_APP_PATH) . '/libraries'` then
-	 * the value of `LITHIUM_LIBRARY_PATH` will be hard-coded
-	 * to the `config/bootstrap/libraries.php` file in the
-	 * extracted library.  If you want it to use a custom
-	 * value, then pass it to this option.  For example,
-	 * if you keep your apps in the same directory as your
-	 * libraries, you could set it to `dirname(LITHIUM_APP_PATH)`
-	 *
-	 * @var string
-	 */
-	public $lithiumLibraryPath = LITHIUM_LIBRARY_PATH;
-
-	/**
-	 * Holds settings from conf file
-	 *
-	 * @var array
-	 */
-	protected $_settings = array();
-
-	/**
-	 * some classes
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'service' => 'lithium\net\http\Service',
-		'response' => 'lithium\console\Response'
-	);
-
-	/**
-	 * Auto configuration properties.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array(
-		'classes' => 'merge', 'env', 'detectors' => 'merge', 'base', 'type', 'stream'
-	);
-
-	/**
-	 * Initialize _settings from `--conf`.
-	 *
-	 * Throws an exception if the command is  initialized without a request object
-	 * which is needed by `_toPath()` in order to determine the current working directory.
-	 * This most often happens if the command is inspected using the `ReflectionClass`.
-	 *
-	 * @return void
-	 */
-	protected function _init() {
-		parent::_init();
-		if ($this->server) {
-			$this->_settings['servers'][$this->server] = true;
-		}
-		if (file_exists($this->conf)) {
-			$this->_settings += (array) json_decode($this->conf, true);
-		}
-		$this->path = $this->_toPath($this->path ?: 'libraries');
-		$this->force = $this->f ? $this->f : $this->force;
-	}
-
-	/**
-	 * Add configuration and write data in json format.
-	 *
-	 * @param string $key (server)
-	 * @param string $value value of key
-	 * @param boolean|string $options [optional]
-	 * @return mixed Returns all settings if `$key` and `$value` aren't set. The only option for
-	 *         `$key` right now is 'server'. Returns the bytes written to the configuration file.
-	 */
-	public function config($key = null, $value = null, $options = true) {
-		if (empty($key) || empty($value)) {
-			return $this->_settings;
-		}
-		switch ($key) {
-			case 'server':
-				$this->_settings['servers'][$value] = $options;
-			break;
-		}
-		return file_put_contents($this->conf, json_encode($this->_settings));
-	}
-
-	/**
-	 * Extract an archive into a path. If one param exists, the app.phar.gz template will be used.
-	 * If both parameters exist, then the first will be the template archive and the second will be
-	 * the name of the extracted archive
-	 *
-	 * - `li3 library extract myapp` : uses command/create/template/app.phar.gz
-	 * - `li3 library extract another_archive myapp` : uses
-	 *       command/create/template/another_archive.phar.gz
-	 * - `li3 library extract plugin li3_plugin` : uses command/create/template/plugin.phar.gz
-	 * - `li3 library extract /full/path/to/a.phar.gz myapp` : paths that begin with a '/'
-	 *       can extract from archives outside of the default command/create/template/
-	 *       location
-	 *
-	 * @param string $name if only param, command/create/template/app.phar.gz extracted to $name
-	 *     otherwise, the template name or full path to extract `from` phar.gz.
-	 * @param string $result if exists $name is extracted to $result
-	 * @return boolean
-	 */
-	public function extract($name = 'new', $result = null) {
-		$from = 'app';
-		$to = $name;
-
-		if ($result) {
-			$from = $name;
-			$to = $result;
-		}
-
-		$to = $this->_toPath($to);
-
-		if ($from[0] !== '/') {
-			$from = Libraries::locate('command.create.template', $from, array(
-				'filter' => false, 'type' => 'file', 'suffix' => '.phar.gz'
-			));
-			if (!$from || is_array($from)) {
-				return false;
-			}
-		}
-
-		if (file_exists($from)) {
-			try {
-				$archive = new Phar($from);
-			} catch (Exception $e) {
-				$this->error($e->getMessage());
-				return false;
-			}
-
-			if ($archive->extractTo($to)) {
-				$this->out(basename($to) . " created in " . dirname($to) . " from {$from}");
-
-				if (empty($this->namespace)) {
-					$this->namespace = Inflector::underscore(basename($to));
-				}
-
-				$replacements = $this->_findReplacements($to);
-				return $this->_replaceAfterExtract($to, compact('namespace', 'replacements'));
-			}
-		}
-		$this->error("Could not extract {$to} from {$from}");
-		return false;
-	}
-
-	/**
-	 * Helper method for `console\command\Library::extract()` to gather
-	 * replacements to perform on the newly extracted files
-	 *
-	 * It looks for a json file specified by `$this->replacementsFile`
-	 * which defaults to _replacements.json.
-	 *
-	 * Running eval on a php file to get the `$replacements`
-	 * would be more flexible than using json, but definitely much more of a
-	 * security hole if the library is not trusted.
-	 *
-	 * @param string $base File path to the extracted library
-	 * @return array A multi-dimensional array.  Keys on the top level
-	 *     are filenames or glob-style paths.  Those hold an array
-	 *     with keys being the search param and values being the
-	 *     replacement values
-	 */
-	protected function _findReplacements($base = null) {
-		$replacements = null;
-		if (file_exists($base . '/' . $this->replacementsFile)) {
-			$replacementsFilename = $base . '/' . $this->replacementsFile;
-			$replacements = json_decode(file_get_contents($replacementsFilename), true);
-			if ($replacements !== false) {
-				unlink($base . '/' . $this->replacementsFile);
-			}
-		}
-		return $replacements;
-	}
-
-	/**
-	 * Helper method for `console\command\Library::extract()` to perform after-extract string
-	 * replacements.
-	 *
-	 * In the current implementation, it only sets the correct `LITHIUM_LIBRARY_PATH` when the
-	 * app.phar.gz archive was extracted. If you get any errors, please make sure that the console
-	 * script has read and write permissions to the extracted directory.
-	 *
-	 * @param string $extracted contains the path to the extracted archive.
-	 * @param array $options Valid options are:
-	 *     - `'replacements'`: an array of string replacements indexed by filename.
-	 *       It's also possible to use glob-style wildcards in the filename such
-	 *       as `*` or `*.php` or `resources/g11n/*`.  If the filename starts
-	 *       with `*`, then that filename pattern will be recursively found
-	 *       in every sub-directory.  Additionally, each replacement can
-	 *       use `String::insert()` style strings that will be replaced
-	 *       with the data in the `data` option.
-	 *     - `'data'`: an array with data that will be used to replace
-	 *       `String::insert`-style placeholders in the `replacements` option.
-	 *       By default, this includes 'namespace' and 'library' which are
-	 *       both set to the extracted library's namespace.
-	 * @return boolean
-	 */
-	protected function _replaceAfterExtract($extracted, $options = array()) {
-		$namespace = $this->namespace;
-		$library = $namespace;
-		$data = compact('namespace', 'library');
-		$replacements = array();
-		extract($options);
-
-		if (empty($replacements)) {
-			$replacements = array(
-				'config/bootstrap/libraries.php' => array(
-					"Libraries::add('app'" => "Libraries::add('{:namespace}'"
-				),
-				'*.php' => array(
-					"namespace app\\" => "namespace {:namespace}\\"
-				)
-			);
-		}
-
-		if (dirname(LITHIUM_APP_PATH) . '/libraries' !== $this->lithiumLibraryPath) {
-			$pathinfo = pathinfo($this->lithiumLibraryPath);
-			if ($pathinfo['dirname'] !== '.') {
-				$this->lithiumLibraryPath = "'" . $this->lithiumLibraryPath . "'";
-			}
-
-			$search = 'define(\'LITHIUM_LIBRARY_PATH\', ';
-			$search .= 'dirname(LITHIUM_APP_PATH) . \'/libraries\');';
-			$replace = 'define(\'LITHIUM_LIBRARY_PATH\', ';
-			$replace .= $this->lithiumLibraryPath . ');';
-
-			if (!isset($replacements['config/bootstrap/libraries.php'])) {
-				$replacements['config/bootstrap/libraries.php'] = array();
-			}
-			$replacements['config/bootstrap/libraries.php'][$search] = $replace;
-		}
-
-		foreach ($replacements as $filename => $definitions) {
-			foreach ($definitions as $search => $replace) {
-				unset($definitions[$search]);
-				$search = String::insert($search, $data);
-				$replace = String::insert($replace, $data);
-				$definitions[$search] = $replace;
-			}
-			$paths = $this->_wildcardPaths($filename, $extracted);
-			foreach ($paths as $filepath) {
-				if (file_exists($filepath)) {
-					$content = file_get_contents($filepath);
-					if ($content === '') {
-						continue;
-					}
-					$content = str_replace(
-						array_keys($definitions),
-						array_values($definitions),
-						$content
-					);
-					if (!file_put_contents($filepath, $content)) {
-						$this->error("Could not replace content in {$filepath}");
-						return false;
-					}
-				}
-			}
-		}
-		return true;
-	}
-
-	/**
-	 * Utility function that will return an array of
-	 * file paths relative to the `$base` path that
-	 * are found using a glob-style asterisk wildcards
-	 * such as `*` or `*.php` or `resources/g11n/*`.  If the path starts
-	 * with `*`, then that filename pattern will be recursively found
-	 * in every sub-directory.
-	 *
-	 * @param string $path
-	 * @param string $base Base directory to search for matching files
-	 * @return array
-	 */
-	protected function _wildcardPaths($path, $base = '') {
-		if (strpos($path, '*') === false) {
-			return array($base . '/' . $path);
-		}
-		if ($path[0] === '*') {
-			$paths = array();
-			$dirs = array($base);
-			while (!empty($dirs)) {
-				$dir = array_shift($dirs);
-				$paths = array_merge($paths, glob($dir . '/' . $path));
-				$dirs = array_merge(
-					$dirs,
-					array_filter(glob($dir . '/*'), function($path) {
-						return is_dir($path);
-					})
-				);
-			}
-		} else {
-			$paths = array_filter(glob($base . '/' . $path), function($path) {
-				$basename = basename($path);
-				return $basename !== '.' && $basename !== '..';
-			});
-		}
-		return $paths;
-	}
-
-	/**
-	 * Create the Phar::GZ archive from a given directory. If no params, the current working
-	 * directory is archived with the name of that directory. If one param, the current working
-	 * directory will be archive with the name provided. If both params, the first is the
-	 * name or path to the library to archive and the second is the name of the resulting archive
-	 *
-	 * - `li3 library archive my_archive` : archives current working directory to my_archive.phar.gz
-	 * - `li3 library archive myapp my_archive` : archives 'myapp' to 'my_archive.phar.gz'
-	 *
-	 * @param string $name if only param, the archive name for the current working directory
-	 *     otherwise, The library name or path to the directory to compress.
-	 * @param string $result if exists, The name of the resulting archive
-	 * @return boolean
-	 */
-	public function archive($name = null, $result = null) {
-		if (ini_get('phar.readonly') === '1') {
-			throw new RuntimeException('Set `phar.readonly` to `0` in `php.ini`.');
-		}
-		$from = $name;
-		$to = $name;
-
-		if ($result) {
-			$from = $name;
-			$to = $result;
-		}
-		$path = $this->_toPath($to);
-
-		if (file_exists("{$path}.phar")) {
-			if (!$this->force) {
-				$this->error(basename($path) . ".phar already exists in " . dirname($path));
-				return false;
-			}
-			Phar::unlinkArchive("{$path}.phar");
-		}
-		try {
-			$archive = new Phar("{$path}.phar");
-		} catch (Exception $e) {
-			$this->error($e->getMessage());
-			return false;
-		}
-		$result = null;
-		$from = $this->_toPath($from);
-
-		if (is_dir($from)) {
-			$result = (boolean) $archive->buildFromDirectory($from, $this->filter);
-		}
-		if (file_exists("{$path}.phar.gz")) {
-			if (!$this->force) {
-				$this->error(basename($path) . ".phar.gz already exists in " . dirname($path));
-				return false;
-			}
-			Phar::unlinkArchive("{$path}.phar.gz");
-		}
-		if ($result) {
-			$archive->compress(Phar::GZ);
-			$this->out(basename($path) . ".phar.gz created in " . dirname($path) . " from {$from}");
-			return true;
-		}
-		$this->error("Could not create archive from {$from}");
-		return false;
-	}
-
-
-	/**
-	 * List all the plugins and extensions available on the server.
-	 *
-	 * @param string $type plugins|extensions
-	 */
-	public function find($type = 'plugins') {
-		$results = array();
-
-		foreach ($this->_settings['servers'] as $server => $enabled) {
-			if (!$enabled) {
-				continue;
-			}
-			$service = $this->_instance('service', array(
-				'host' => $server, 'port' => $this->port
-			));
-			$results[$server] = json_decode($service->get("lab/{$type}.json"));
-
-			if (empty($results[$server])) {
-				$this->out("No {$type} at {$server}");
-				continue;
-			}
-			foreach ((array) $results[$server] as $data) {
-				$name = isset($data->class) ? $data->class : $data->name;
-				$header = "{$server} > {$name}";
-				$out = array(
-					"{$data->summary}",
-					"Version: {$data->version}",
-					"Created: {$data->created}"
-				);
-				$this->header($header);
-				$this->out(array_filter($out));
-			}
-		}
-	}
-
-	/**
-	 * Install plugins or extensions to the current application.
-	 * For plugins, the install commands specified in the formula is run.
-	 *
-	 * @param string $name name of plugin to add
-	 * @return boolean
-	 */
-	public function install($name = null) {
-		$results = array();
-
-		foreach ($this->_settings['servers'] as $server => $enabled) {
-			if (!$enabled) {
-				continue;
-			}
-			$service = $this->_instance('service', array('host' => $server, 'port' => $this->port));
-
-			if ($plugin = json_decode($service->get("lab/{$name}.json"))) {
-				break;
-			}
-		}
-		if (empty($plugin->sources)) {
-			$this->error("{$name} not found.");
-			return false;
-		}
-		$hasGit = function () {
-			return (strpos(shell_exec('git --version'), 'git version') !== false);
-		};
-		foreach ((array) $plugin->sources as $source) {
-			if (strpos($source, 'phar.gz') !== false && file_exists($source)) {
-				$written = file_put_contents(
-					"{$this->path}/{$plugin->name}.phar.gz", file_get_contents($source)
-				);
-				if (!$written) {
-					$this->error("{$plugin->name}.phar.gz could not be saved");
-					return false;
-				}
-				$this->out("{$plugin->name}.phar.gz saved to {$this->path}");
-
-				try {
-					$archive = new Phar("{$this->path}/{$plugin->name}.phar.gz");
-
-					if ($archive->extractTo("{$this->path}/{$plugin->name}")) {
-						$this->out("{$plugin->name} installed to {$this->path}/{$plugin->name}");
-						$this->out("Remember to update the bootstrap.");
-						return true;
-					}
-				} catch (Exception $e) {
-					$this->error($e->getMessage());
-				}
-			}
-			$url = parse_url($source);
-
-			if (!empty($url['scheme']) && $url['scheme'] === 'git' && $hasGit()) {
-				$cmd = "cd {$this->path} && git clone --quiet {$source} {$plugin->name}";
-				$result = shell_exec($cmd);
-
-				if (is_dir("{$this->path}/{$plugin->name}")) {
-					$this->out("{$plugin->name} installed to {$this->path}/{$plugin->name}");
-					$this->out("Remember to update your bootstrap.");
-					return true;
-				}
-			}
-		}
-		$this->out("{$plugin->name} not installed.");
-		return false;
-	}
-
-	/**
-	 * Create a formula for the given library name
-	 *
-	 * @param string $name the library name or full path to the plugin
-	 * @return boolean
-	 */
-	public function formulate($name = null) {
-		if (!$name) {
-			$name = $this->in("please supply a name");
-		}
-		$result = false;
-		$path = $this->_toPath($name);
-		$name = basename($path);
-		$formula = "{$path}/config/{$name}.json";
-
-		$data = array();
-
-		if (file_exists($formula)) {
-			$data = json_decode(file_get_contents($formula), true);
-		}
-		if (empty($data['version'])) {
-			$data['version'] = $this->in("please supply a version");
-		}
-		if (empty($data['summary'])) {
-			$data['summary'] = $this->in("please supply a summary");
-		}
-		if (file_exists($path) && !file_exists($formula)) {
-			$defaults = array(
-				'name' => $name, 'version' => '0.1',
-				'summary' => "a plugin called {$name}",
-				'maintainers' => array(array(
-					'name' => '', 'email' => '', 'website' => ''
-				)),
-				'sources' => array("http://{$this->server}/lab/download/{$name}.phar.gz"),
-				'commands' => array(
-					'install' => array(), 'update' => array(), 'remove' => array()
-				),
-				'requires' => array()
-			);
-			$data += $defaults;
-
-			if (!is_dir(dirname($formula)) && !mkdir(dirname($formula), 0755, true)) {
-				$this->error("Formula for {$name} not created in {$path}");
-				return false;
-			}
-		}
-		if (is_dir(dirname($formula)) && file_put_contents($formula, json_encode($data))) {
-			$this->out("Formula for {$name} created in {$path}.");
-			return true;
-		}
-		$this->error("Formula for {$name} not created in {$path}");
-		return false;
-	}
-
-	/**
-	 * Send a plugin archive to the server. The plugin must have a formula.
-	 *
-	 * @param string $name the library name or full path to the archive to send
-	 * @return void
-	 */
-	public function push($name = null) {
-		if (!$name) {
-			$name = $this->in("please supply a name");
-		}
-		$path = $this->_toPath($name);
-		$name = basename($name);
-		$file = "{$path}.phar.gz";
-
-		if (!file_exists("phar://{$file}/config/{$name}.json")) {
-			$this->error(array(
-				"The formula for {$name} is missing.", "Run li3 library formulate {$name}"
-			));
-			return false;
-		}
-		$formula = json_decode(file_get_contents("phar://{$file}/config/{$name}.json"));
-		$isValid = (
-			!empty($formula->name) && !empty($formula->version)
-			&& !empty($formula->summary) && !empty($formula->sources)
-		);
-		if (!$isValid) {
-			$this->error(array(
-				"The formula for {$name} is not valid.", "Run li3 library formulate {$name}"
-			));
-			return false;
-		}
-		if (file_exists($file)) {
-			$service = $this->_instance('service', array(
-				'host' => $this->server, 'port' => $this->port,
-				'auth' => 'Basic', 'username' => $this->username, 'password' => $this->password
-			));
-			$boundary = md5(date('r', time()));
-			$headers = array("Content-Type: multipart/form-data; boundary={$boundary}");
-			$name = basename($file);
-			$data = join("\r\n", array(
-				"--{$boundary}",
-				"Content-Disposition: form-data; name=\"phar\"; filename=\"{$name}\"",
-				"Content-Type: application/phar", "",
-				base64_encode(file_get_contents($file)),
-				"--{$boundary}--"
-			));
-			$result = json_decode($service->post(
-				'/lab/server/receive', $data, compact('headers')
-			));
-
-			if ($service->last->response->status['code'] == 201) {
-				$this->out(array(
-					"{$result->name} added to {$this->server}.",
-					"See http://{$this->server}/lab/plugins/view/{$result->id}"
-				));
-				return $result;
-			}
-			if (!empty($result->error)) {
-				$this->error($result->error);
-				return false;
-			}
-			$this->error((array) $result);
-			return false;
-		}
-		$this->error(array("{$file} does not exist.", "Run li3 library archive {$name}"));
-		return false;
-	}
-
-	/**
-	 * Update installed plugins. For plugins, runs update commands specified in Formula.
-	 *
-	 * @todo implement
-	 * @return void
-	 */
-	public function update() {
-		$this->error('Please implement me');
-	}
-
-	/**
-	 * Take a name and return the path.
-	 *
-	 * If the name already appears to be a path, it is returned directly. Otherwise, the
-	 * `Library` class is used to find the associated path.
-	 *
-	 * @param string $name
-	 * @return string
-	 */
-	protected function _toPath($name = null) {
-		$pathinfo = pathinfo($name);
-		if ($name && $pathinfo['dirname'] !== '.') {
-			return $name;
-		}
-
-		$library = Libraries::get($name);
-
-		if (!empty($library['path'])) {
-			return $library['path'];
-		}
-
-		$path = $this->request->env('working');
-		return (!empty($name)) ? "{$path}/{$name}" : $path;
-	}
-}
-
-?>

+ 0 - 140
frameworks/PHP/php-lithium/libraries/lithium/console/command/Route.php

@@ -1,140 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-namespace lithium\console\command;
-
-use lithium\core\Libraries;
-use lithium\action\Request;
-use lithium\net\http\Router;
-use lithium\core\Environment;
-
-/**
- * The route command lets you inspect your routes and issue requests against the router.
- */
-class Route extends \lithium\console\Command {
-
-	/**
-	 * Override the default 'development' environment.
-	 *
-	 * For example:
-	 * {{{
-	 * li3 route --env=production
-	 * li3 route show /foo --env=test
-	 * }}}
-	 *
-	 * @var string
-	 */
-	public $env = 'development';
-
-	/**
-	 * Load the routes file and set the environment.
-	 *
-	 * @param array $config The default configuration, wherein the absolute path to the routes file
-	 *              to load may be specified, using the `'routes'` key.
-	 */
-	public function __construct($config = array()) {
-		$defaults = array('routes' => Libraries::get(true, 'path') . '/config/routes.php');
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-		Environment::set($this->env);
-
-		if (file_exists($this->_config['routes'])) {
-			return require $this->_config['routes'];
-		}
-		$this->error("The routes file for this library doesn't exist or can't be found.");
-	}
-
-	/**
-	 * Lists all connected routes to the router. See the `all()`
-	 * method for details and examples.
-	 *
-	 * @return void
-	 */
-	public function run() {
-		$this->all();
-	}
-
-	/**
-	 * Lists all connected routes to the router. This is a convenience
-	 * alias for the `show()` method.
-	 *
-	 * Example:
-	 * {{{
-	 * li3 route
-	 * li3 route all
-	 * }}}
-	 *
-	 * Will return an output similar to:
-	 *
-	 * {{{
-	 * Template                        	Params
-	 * --------                        	------
-	 * /                               	{"controller":"pages","action":"view"}
-	 * /pages/{:args}                  	{"controller":"pages","action":"view"}
-	 * /{:slug:[\w\-]+}                	{"controller":"posts","action":"show"}
-	 * /{:controller}/{:action}/{:args}	{"action":"index"}
-	 * }}}
-	 *
-	 * @return void
-	 */
-	public function all() {
-		$routes = Router::get();
-		$columns = array(array('Template', 'Params'), array('--------', '------'));
-
-		foreach ($routes As $route) {
-			$info = $route->export();
-			$columns[] = array($info['template'], json_encode($info['params']));
-		}
-		$this->columns($columns);
-	}
-
-	/**
-	 * Returns the corresponding params for a given URL and an optional request
-	 * method.
-	 *
-	 * Examples:
-	 * {{{
-	 * 1: li3 route show /foo
-	 * 2: li3 route show post /foo/bar/1
-	 * 3: li3 route show /test
-	 * 4: li3 route show /test --env=production
-	 * }}}
-	 *
-	 * Will return outputs similar to:
-	 *
-	 * {{{
-	 * 1: {"controller":"foo","action":"index"	}
-	 * 2: {"controller":"foo","action":"bar","args":["1"]}
-	 * 3: {"controller":"lithium\\test\\Controller","action":"index"}
-	 * 4: {"controller":"test","action":"index"}
-	 * }}}
-	 *
-	 * @return void
-	 */
-	public function show() {
-		$url = join(" ", $this->request->params['args']);
-		$method = 'GET';
-
-		if (!$url) {
-			$this->error('Please provide a valid URL');
-		}
-
-		if (preg_match('/^(GET|POST|PUT|DELETE|HEAD|OPTIONS) (.+)/i', $url, $matches)) {
-			$method = strtoupper($matches[1]);
-			$url = $matches[2];
-		}
-
-		$request = new Request(compact('url') + array('env' => array('REQUEST_METHOD' => $method)));
-		$result = Router::process($request);
-		$this->out($result->params ? json_encode($result->params) : "No route found.");
-	}
-}
-
-?>

+ 0 - 325
frameworks/PHP/php-lithium/libraries/lithium/console/command/Test.php

@@ -1,325 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command;
-
-use lithium\core\Libraries;
-use lithium\test\Dispatcher;
-use lithium\test\Unit;
-
-/**
- * Runs a given set of tests and outputs the results.
- *
- * @see lithium\test
- */
-class Test extends \lithium\console\Command {
-
-	/**
-	 * Used as the exit code for errors where no test was mapped to file.
-	 */
-	const EXIT_NO_TEST = 4;
-
-	/**
-	 * List of filters to apply before/during/after test run, separated by commas.
-	 *
-	 * For example:
-	 * {{{
-	 * lithium test lithium/tests/cases/core/ObjectTest.php --filters=Coverage
-	 * lithium test lithium/tests/cases/core/ObjectTest.php --filters=Coverage,Profiler
-	 * }}}
-	 *
-	 * @var string Name of a filter or a comma separated list of filter names. Builtin filters:
-	 *      - `Affected`:   Adds tests to the run affected by the classes covered by current tests.
-	 *      - `Complexity`: Calculates the cyclomatic complexity of class methods, and shows
-	 *                      worst-offenders and statistics.
-	 *      - `Coverage`:   Runs code coverage analysis for the executed tests.
-	 *      - `Profiler`:   Tracks timing and memory usage information for each test method.
-	 */
-	public $filters;
-
-	/**
-	 * Format to use for rendering results. Any other format than `txt` will
-	 * cause the command to enter quiet mode, surpressing headers and any other
-	 * decoration.
-	 *
-	 * @var string Either `txt` or `json`.
-	 */
-	public $format = 'txt';
-
-	/**
-	 * Enable verbose output especially for the `txt` format.
-	 *
-	 * @var boolean
-	 */
-	public $verbose = false;
-
-	/**
-	 * Enable plain mode to prevent any headers or similar decoration being output.
-	 * Good for command calls embedded into other scripts.
-	 *
-	 * @var boolean
-	 */
-	public $plain = false;
-
-	/**
-	 * An array of closures, mapped by type, which are set up to handle different test output
-	 * formats.
-	 *
-	 * @var array
-	 */
-	protected $_handlers = array();
-
-	/**
-	 * Initializes the output handlers.
-	 *
-	 * @see lithium\console\command\Test::$_handlers
-	 * @return void
-	 */
-	protected function _init() {
-		parent::_init();
-		$command = $this;
-
-		$this->_handlers += array(
-			'txt' => function($runner, $path) use ($command) {
-				if (!$command->plain) {
-					$command->header('Test');
-					$command->out(null, 1);
-				}
-				$colorize = function($result) {
-					switch (trim($result)) {
-						case '.':
-							return $result;
-						case 'pass':
-							return "{:green}{$result}{:end}";
-						case 'F':
-						case 'fail':
-							return "{:red}{$result}{:end}";
-						case 'E':
-						case 'exception':
-							return "{:purple}{$result}{:end}";
-						case 'S':
-						case 'skip':
-							return "{:cyan}{$result}{:end}";
-						default:
-							return "{:yellow}{$result}{:end}";
-					}
-				};
-
-				if ($command->verbose) {
-					$reporter = function($result) use ($command, $colorize) {
-						$command->out(sprintf(
-							'[%s] on line %4s in %s::%s()',
-							$colorize(sprintf('%9s', $result['result'])),
-							isset($result['line']) ? $result['line'] : '??',
-							isset($result['class']) ? $result['class'] : '??',
-							isset($result['method']) ? $result['method'] : '??'
-						));
-					};
-				} else {
-					$i = 0;
-					$columns = 60;
-
-					$reporter = function($result) use ($command, &$i, $columns, $colorize) {
-						$shorten = array('fail', 'skip', 'exception');
-
-						if ($result['result'] === 'pass') {
-							$symbol = '.';
-						} elseif (in_array($result['result'], $shorten)) {
-							$symbol = strtoupper($result['result'][0]);
-						} else {
-							$symbol = '?';
-						}
-						$command->out($colorize($symbol), false);
-
-						$i++;
-						if ($i % $columns === 0) {
-							$command->out();
-						}
-					};
-				}
-				$report = $runner(compact('reporter'));
-
-				if (!$command->plain) {
-					$stats = $report->stats();
-
-					$command->out(null, 2);
-					$command->out($report->render('result', $stats));
-					$command->out($report->render('errors', $stats));
-
-					if ($command->verbose) {
-						$command->out($report->render('skips', $stats));
-					}
-
-					foreach ($report->filters() as $filter => $options) {
-						$data = $report->results['filters'][$filter];
-						$command->out($report->render($options['name'], compact('data')));
-					}
-				}
-				return $report;
-			},
-			'json' => function($runner, $path) use ($command) {
-				$report = $runner();
-
-				if ($results = $report->filters()) {
-					$filters = array();
-
-					foreach ($results as $filter => $options) {
-						$filters[$options['name']] = $report->results['filters'][$filter];
-					}
-				}
-				$command->out($report->render('stats', $report->stats() + compact('filters')));
-				return $report;
-			}
-		);
-	}
-
-	/**
-	 * Runs tests given a path to a directory or file containing tests. The path to the
-	 * test(s) may be absolute or relative to the current working directory.
-	 *
-	 * {{{
-	 * li3 test lithium/tests/cases/core/ObjectTest.php
-	 * li3 test lithium/tests/cases/core
-	 * }}}
-	 *
-	 * If you are in the working directory of an application or plugin and wish to run all tests,
-	 * simply execute the following:
-	 *
-	 * {{{
-	 * li3 test tests/cases
-	 * }}}
-	 *
-	 * If you are in the working directory of an application and wish to run a plugin, execute one
-	 * of the following:
-	 *
-	 * {{{
-	 * li3 test libraries/<plugin>/tests/cases
-	 * li3 test <plugin>/tests/cases
-	 * }}}
-	 *
-	 *
-	 * This will run `<library>/tests/cases/<package>/<class>Test.php`:
-	 *
-	 * {{{
-	 * li3 test <library>/<package>/<class>.php
-	 * }}}
-	 *
-	 * @param string $path Absolute or relative path to tests or a file which
-	 *                     corresponding test should be run.
-	 * @return boolean Will exit with status `1` if one or more tests failed otherwise with `0`.
-	 */
-	public function run($path = null) {
-		if (!$path = $this->_path($path)) {
-			return false;
-		}
-		if (!preg_match('/(tests|Test\.php)/', $path)) {
-			if (!$path = Unit::get($path)) {
-				$this->error('Cannot map path to test path.');
-				return static::EXIT_NO_TEST;
-			}
-		}
-		$handlers = $this->_handlers;
-
-		if (!isset($handlers[$this->format]) || !is_callable($handlers[$this->format])) {
-			$this->error(sprintf('No handler for format `%s`... ', $this->format));
-			return false;
-		}
-		$filters = $this->filters ? array_map('trim', explode(',', $this->filters)) : array();
-		$params = compact('filters') + array('format' => $this->format);
-		$runner = function($options = array()) use ($path, $params) {
-			error_reporting(E_ALL | E_STRICT | E_DEPRECATED);
-			return Dispatcher::run($path, $params + $options);
-		};
-		$report = $handlers[$this->format]($runner, $path);
-		$stats = $report->stats();
-		return $stats['success'];
-	}
-
-	/**
-	 * Finds a library for given path.
-	 *
-	 * @param string $path Normalized (to slashes) absolute or relative path.
-	 * @return string the name of the library
-	 */
-	protected function _library($path) {
-		foreach (Libraries::get() as $name => $library) {
-			if (strpos($path, $library['path']) !== 0) {
-				continue;
-			}
-			return $name;
-		}
-	}
-
-	/**
-	 * Validates and gets a fully-namespaced class path from an absolute or
-	 * relative physical path to a directory or file. The final class path may
-	 * be partial in that in doesn't contain the class name.
-	 *
-	 * This method can be thought of the reverse of `Libraries::path()`.
-	 *
-	 * {{{
-	 * lithium/tests/cases/core/ObjectTest.php -> lithium\tests\cases\core\ObjectTest
-	 * lithium/tests/cases/core                -> lithium\tests\cases\core
-	 * lithium/core/Object.php                 -> lithium\core\Object
-	 * lithium/core/                           -> lithium\core
-	 * lithium/core                            -> lithium\core
-	 * }}}
-	 *
-	 * @see lithium\core\Libraries::path()
-	 * @param string $path The directory of or file path to one or more classes.
-	 * @return string Returns a fully-namespaced class path, or `false`, if an error occurs.
-	 */
-	protected function _path($path) {
-		$path = rtrim(str_replace('\\', '/', $path), '/');
-
-		if (!$path) {
-			$this->error('Please provide a path to tests.');
-			return false;
-		}
-		if ($path[0] === '/') {
-			$library = $this->_library($path);
-		}
-		if ($path[0] !== '/') {
-			$libraries = array_reduce(Libraries::get(), function($v, $w) {
-				$v[] = basename($w['path']);
-				return $v;
-			});
-
-			$library = basename($this->request->env('working'));
-			$parts = explode('/', str_replace("../", "", $path));
-			$plugin = array_shift($parts);
-
-			if ($plugin === 'libraries') {
-				$plugin = array_shift($parts);
-			}
-			if (in_array($plugin, $libraries)) {
-				$library = $plugin;
-				$path = join('/', $parts);
-			}
-		}
-		if (empty($library)) {
-			$this->error("No library found in path `{$path}`.");
-			return false;
-		}
-		if (!$config = Libraries::get($library)) {
-			$this->error("Library `{$library}` does not exist.");
-			return false;
-		}
-		$path = str_replace($config['path'], null, $path);
-		$realpath = $config['path'] . '/' . $path;
-
-		if (!realpath($realpath)) {
-			$this->error("Path `{$realpath}` not found.");
-			return false;
-		}
-		$class = str_replace(".php", "", str_replace('/', '\\', ltrim($path, '/')));
-		return $config['prefix'] . $class;
-	}
-}
-
-?>

+ 0 - 84
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Controller.php

@@ -1,84 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command\create;
-
-use lithium\util\Inflector;
-
-/**
- * Generate a Controller class in the `--library` namespace
- *
- * `li3 create controller Posts`
- * `li3 create --library=li3_plugin controller Posts`
- *
- */
-class Controller extends \lithium\console\command\Create {
-
-	/**
-	 * Get the fully-qualified model class that is used by the controller.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _use($request) {
-		$request->params['command'] = 'model';
-		return $this->_namespace($request) . '\\' . $this->_model($request);
-	}
-
-	/**
-	 * Get the controller class name.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _class($request) {
-		return $this->_name($request) . 'Controller';
-	}
-
-	/**
-	 * Returns the name of the controller class, minus `'Controller'`.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _name($request) {
-		return Inflector::camelize(Inflector::pluralize($request->action));
-	}
-
-	/**
-	 * Get the plural variable used for data in controller methods.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _plural($request) {
-		return Inflector::pluralize(Inflector::camelize($request->action, false));
-	}
-
-	/**
-	 * Get the model class used in controller methods.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _model($request) {
-		return Inflector::camelize(Inflector::pluralize($request->action));
-	}
-
-	/**
-	 * Get the singular variable to use for data in controller methods.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _singular($request) {
-		return Inflector::singularize(Inflector::camelize($request->action, false));
-	}
-}
-
-?>

+ 0 - 74
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Mock.php

@@ -1,74 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command\create;
-
-use lithium\util\Inflector;
-
-/**
- * Generate a Mock that extends the name of the given class in the `--library` namespace.
- *
- * `li3 create mock model Posts`
- * `li3 create --library=li3_plugin mock model Posts`
- *
- */
-class Mock extends \lithium\console\command\Create {
-
-	/**
-	 * Get the namespace for the mock.
-	 *
-	 * @param string $request
-	 * @param array|string $options
-	 * @return string
-	 */
-	protected function _namespace($request, $options = array()) {
-		$request->params['command'] = $request->action;
-		return parent::_namespace($request, array('prepend' => 'tests.mocks.'));
-	}
-
-	/**
-	 * Get the parent for the mock.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _parent($request) {
-		$namespace = parent::_namespace($request);
-		$class = Inflector::pluralize($request->action);
-		return "\\{$namespace}\\{$class}";
-	}
-
-	/**
-	 * Get the class name for the mock.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _class($request) {
-		$type = $request->action;
-		$name = $request->args();
-
-		if ($command = $this->_instance($type)) {
-			$request->params['action'] = $name;
-			$name = $command->invokeMethod('_class', array($request));
-		}
-		return  Inflector::pluralize("Mock{$name}");
-	}
-
-	/**
-	 * Get the methods for the mock to override
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _methods($request) {
-		return null;
-	}
-}
-
-?>

+ 0 - 33
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Model.php

@@ -1,33 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command\create;
-
-use lithium\util\Inflector;
-
-/**
- * Generate a Model class in the `--library` namespace
- *
- * `li3 create model Posts`
- * `li3 create --library=li3_plugin model Posts`
- *
- */
-class Model extends \lithium\console\command\Create {
-
-	/**
-	 * Get the class name for the model.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _class($request) {
-		return Inflector::camelize(Inflector::pluralize($request->action));
-	}
-}
-
-?>

+ 0 - 105
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/Test.php

@@ -1,105 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command\create;
-
-use lithium\core\Libraries;
-use lithium\util\Inflector;
-use lithium\analysis\Inspector;
-use lithium\core\ClassNotFoundException;
-
-/**
- * Generate a Test class in the `--library` namespace
- *
- * `li3 create test model Posts`
- * `li3 create --library=li3_plugin test model Posts`
- *
- */
-class Test extends \lithium\console\command\Create {
-
-	/**
-	 * Get the namespace for the test case.
-	 *
-	 * @param string $request
-	 * @param array $options
-	 * @return string
-	 */
-	protected function _namespace($request, $options = array()) {
-		$request->params['command'] = $request->action;
-		return parent::_namespace($request, array('prepend' => 'tests.cases.'));
-	}
-
-	/**
-	 * Get the class used by the test case.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _use($request) {
-		return parent::_namespace($request) . '\\' . $this->_name($request);
-	}
-
-	/**
-	 * Get the class name for the test case.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _class($request) {
-		$name = $this->_name($request);
-		return  Inflector::classify("{$name}Test");
-	}
-
-	/**
-	 * Get the methods to test.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _methods($request) {
-		$use = $this->_use($request);
-		$path = Libraries::path($use);
-
-		if (!file_exists($path)) {
-			return "";
-		}
-		$methods = (array) Inspector::methods($use, 'extents');
-		$testMethods = array();
-
-		foreach (array_keys($methods) as $method) {
-			$testMethods[] = "\tpublic function test" . ucwords($method) . "() {}";
-		}
-		return join("\n", $testMethods);
-	}
-
-	/**
-	 * Get the class to be tested
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _name($request) {
-		$type = $request->action;
-		$name = $request->args();
-
-		try {
-			$command = $this->_instance($type);
-		} catch (ClassNotFoundException $e) {
-			$command = null;
-		}
-
-		if ($command) {
-			$request->params['action'] = $name;
-			$name = $command->invokeMethod('_class', array($request));
-		}
-		$request->params['action'] = $type;
-		return $name;
-	}
-}
-
-?>

+ 0 - 92
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/View.php

@@ -1,92 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command\create;
-
-use lithium\util\Inflector;
-use lithium\util\String;
-
-/**
- * Generate a View file in the `--library` namespace
- *
- * `li3 create view Posts index`
- * `li3 create --library=li3_plugin view Posts index`
- *
- */
-class View extends \lithium\console\command\Create {
-
-	/**
-	 * Returns the name of the controller class, minus `'Controller'`.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _name($request) {
-		return Inflector::camelize(Inflector::pluralize($request->action));
-	}
-
-	/**
-	 * Get the plural data variable that is sent down from controller method.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _plural($request) {
-		return Inflector::pluralize(Inflector::camelize($request->action, false));
-	}
-
-	/**
-	 * Get the singular data variable that is sent down from controller methods.
-	 *
-	 * @param string $request
-	 * @return string
-	 */
-	protected function _singular($request) {
-		return Inflector::singularize(Inflector::camelize($request->action, false));
-	}
-
-	/**
-	 * Override the save method to handle view specific params.
-	 *
-	 * @param array $params
-	 * @return mixed
-	 */
-	protected function _save(array $params = array()) {
-		$params['path'] = Inflector::underscore($this->request->action);
-		$params['file'] = $this->request->args(0);
-
-		$contents = $this->_template();
-		$result = String::insert($contents, $params);
-
-		if (!empty($this->_library['path'])) {
-			$path = $this->_library['path'] . "/views/{$params['path']}/{$params['file']}";
-			$file = str_replace('//', '/', "{$path}.php");
-			$directory = dirname($file);
-
-			if (!is_dir($directory)) {
-				if (!mkdir($directory, 0755, true)) {
-					return false;
-				}
-			}
-			$directory = str_replace($this->_library['path'] . '/', '', $directory);
-			if (file_exists($file)) {
-				$prompt = "{$file} already exists. Overwrite?";
-				$choices = array('y', 'n');
-				if ($this->in($prompt, compact('choices')) !== 'y') {
-					return "{$params['file']} skipped.";
-				}
-			}
-			if (is_int(file_put_contents($file, $result))) {
-				return "{$params['file']}.php created in {$directory}.";
-			}
-		}
-		return false;
-	}
-}
-
-?>

BIN
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/app.phar.gz


+ 0 - 47
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/controller.txt.php

@@ -1,47 +0,0 @@
-namespace {:namespace};
-
-use {:use};
-use lithium\action\DispatchException;
-
-class {:class} extends \lithium\action\Controller {
-
-	public function index() {
-		${:plural} = {:model}::all();
-		return compact('{:plural}');
-	}
-
-	public function view() {
-		${:singular} = {:model}::first($this->request->id);
-		return compact('{:singular}');
-	}
-
-	public function add() {
-		${:singular} = {:model}::create();
-
-		if (($this->request->data) && ${:singular}->save($this->request->data)) {
-			return $this->redirect(array('{:name}::view', 'args' => array(${:singular}->id)));
-		}
-		return compact('{:singular}');
-	}
-
-	public function edit() {
-		${:singular} = {:model}::find($this->request->id);
-
-		if (!${:singular}) {
-			return $this->redirect('{:name}::index');
-		}
-		if (($this->request->data) && ${:singular}->save($this->request->data)) {
-			return $this->redirect(array('{:name}::view', 'args' => array(${:singular}->id)));
-		}
-		return compact('{:singular}');
-	}
-
-	public function delete() {
-		if (!$this->request->is('post') && !$this->request->is('delete')) {
-			$msg = "{:name}::delete can only be called with http:post or http:delete.";
-			throw new DispatchException($msg);
-		}
-		{:model}::find($this->request->id)->delete();
-		return $this->redirect('{:name}::index');
-	}
-}

+ 0 - 6
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/mock.txt.php

@@ -1,6 +0,0 @@
-namespace {:namespace};
-
-class {:class} extends {:parent} {
-
-{:methods}
-}

+ 0 - 6
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/model.txt.php

@@ -1,6 +0,0 @@
-namespace {:namespace};
-
-class {:class} extends \lithium\data\Model {
-
-	public $validates = array();
-}

BIN
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/plugin.phar.gz


BIN
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/test-app-replacements.phar.gz


+ 0 - 12
frameworks/PHP/php-lithium/libraries/lithium/console/command/create/template/test.txt.php

@@ -1,12 +0,0 @@
-namespace {:namespace};
-
-use {:use};
-
-class {:class} extends \lithium\test\Unit {
-
-	public function setUp() {}
-
-	public function tearDown() {}
-
-{:methods}
-}

+ 0 - 173
frameworks/PHP/php-lithium/libraries/lithium/console/command/g11n/Extract.php

@@ -1,173 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\console\command\g11n;
-
-use Exception;
-use lithium\g11n\Catalog;
-use lithium\core\Libraries;
-
-/**
- * The `Extract` class is a command for extracting messages from files.
- */
-class Extract extends \lithium\console\Command {
-
-	public $source;
-
-	public $destination;
-
-	public $scope;
-
-	protected function _init() {
-		parent::_init();
-		$this->source = $this->source ?: LITHIUM_APP_PATH;
-		$this->destination = $this->destination ?: Libraries::get(true, 'resources') . '/g11n';
-	}
-
-	/**
-	 * The main method of the command.
-	 *
-	 * @return void
-	 */
-	public function run() {
-		$this->header('Message Extraction');
-
-		if (!$data = $this->_extract()) {
-			$this->error('Yielded no items.');
-			return 1;
-		}
-		$count = count($data);
-		$this->out("Yielded {$count} item(s).");
-		$this->out();
-
-		$this->header('Message Template Creation');
-
-		if (!$this->_writeTemplate($data)) {
-			$this->error('Failed to write template.');
-			return 1;
-		}
-		$this->out();
-
-		return 0;
-	}
-
-	/**
-	 * Extracts translatable strings from multiple files.
-	 *
-	 * @return array Returns the catalog specified. Returns boolean `false` when an error occurs.
-	 */
-	protected function _extract() {
-		$message[] = 'A `Catalog` class configuration with an adapter that is capable of';
-		$message[] = 'handling read requests for the `messageTemplate` category is needed';
-		$message[] = 'in order to proceed. This may also be referred to as `extractor`.';
-		$this->out($message);
-		$this->out();
-
-		$name = $this->_configuration(array(
-			'adapter' => 'Code',
-			'path' => $this->source,
-			'scope' => $this->scope
-		));
-		$configs = Catalog::config();
-
-		try {
-			return Catalog::read($name, 'messageTemplate', 'root', array(
-				'scope' => $configs[$name]['scope'],
-				'lossy' => false
-			));
-		} catch (Exception $e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Prompts for data source and writes template.
-	 *
-	 * @param array $data Data to save.
-	 * @return void
-	 */
-	protected function _writeTemplate($data) {
-		$message[] = 'In order to proceed you need to choose a `Catalog` configuration';
-		$message[] = 'which is used for writing the template. The adapter for the configuration';
-		$message[] = 'should be capable of handling write requests for the `messageTemplate`';
-		$message[] = 'category.';
-		$this->out($message);
-		$this->out();
-
-		$name = $this->_configuration(array(
-			'adapter' => 'Gettext',
-			'path' => $this->destination,
-			'scope' => $this->scope
-		));
-
-		if ($name != 'temporary') {
-			$scope = $this->in('Scope:', array('default' => $this->scope));
-		}
-
-		$message = array();
-		$message[] = 'The template is now ready to be saved.';
-		$message[] = 'Please note that an existing template will be overwritten.';
-		$this->out($message);
-		$this->out();
-
-		if ($this->in('Save?', array('choices' => array('y', 'n'), 'default' => 'y')) != 'y') {
-			$this->out('Aborting upon user request.');
-			$this->stop(1);
-		}
-		try {
-			return Catalog::write($name, 'messageTemplate', 'root', $data, compact('scope'));
-		} catch (Exception $e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Helps in selecting or - if required - adding a new `Catalog` collection
-	 * used for extracting or writing the template. A special configuration
-	 * with the name `temporary` may be created. Should a configuration with
-	 * that same name exist prior to entering this method it will be unset.
-	 *
-	 * @param array $options Options paired with defaults to prompt for.
-	 * @return string The name of the selected or newly created configuration.
-	 */
-	protected function _configuration(array $options = array()) {
-		$configs = (array) Catalog::config();
-
-		if (isset($configs['temporary'])) {
-			unset($configs['temporary']);
-		}
-
-		if ($configs) {
-			$this->out('Available `Catalog` Configurations:');
-			$prompt = 'Please choose a configuration or hit enter to add a new one:';
-
-			foreach ($configs as $name => $config) {
-				$this->out(" - {$name}");
-			}
-		} else {
-			$this->out(' - No configuration found. -');
-			$prompt = 'Please hit enter to add a temporary configuration:';
-		}
-		$this->out();
-
-		$name = $this->in($prompt, array(
-			'choices' => array_keys($configs),
-			'default' => 'temporary'
-		));
-
-		if ($name == 'temporary') {
-			foreach ($options as $option => $default) {
-				$configs[$name][$option] = $this->in(ucfirst($option) . ':', compact('default'));
-			}
-			Catalog::config($configs);
-		}
-		return $name;
-	}
-}
-
-?>

+ 0 - 9
frameworks/PHP/php-lithium/libraries/lithium/console/li3

@@ -1,9 +0,0 @@
-#!/bin/sh
-#
-# Lithium: the most rad php framework
-#
-# @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
-# @license       http://opensource.org/licenses/bsd-license.php The BSD License
-#
-SELF=$0; test -L "$0" && SELF=$(readlink -n $0)
-php -f "$(dirname "$SELF")"/lithium.php -- "$@"

+ 0 - 8
frameworks/PHP/php-lithium/libraries/lithium/console/li3.bat

@@ -1,8 +0,0 @@
-@echo off
-rem
-rem Lithium: the most rad php framework
-rem
-rem @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
-rem @license       http://opensource.org/licenses/bsd-license.php The BSD License
-rem
-php -f "%~dp0lithium.php" %*

+ 0 - 112
frameworks/PHP/php-lithium/libraries/lithium/console/lithium.php

@@ -1,112 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-/**
- * This console front-controller file is the gateway to your application
- * through the command line.  It is responsible for intercepting requests, and
- * handing them off to the `Dispatcher` for processing.
- *
- * Determine if we're in an application context by moving up the directory tree
- * looking for a `config` directory with a `bootstrap.php` file in it.  If no
- * application context is found, just boot up the core framework.
- */
-$params = getopt("", array("app::"));
-$working = $params ? array_pop($params) : getcwd();
-$app = null;
-
-/**
- * If we're not running inside an application (i.e. a self-bootstrapping library), bootstrap the
- * core automatically with the default settings.
- */
-$bootstrap = function() use ($working) {
-	define('LITHIUM_LIBRARY_PATH', dirname(dirname(__DIR__)));
-	define('LITHIUM_APP_PATH', $working);
-
-	if (!include LITHIUM_LIBRARY_PATH . '/lithium/core/Libraries.php') {
-		$message  = "Lithium core could not be found.  Check the value of LITHIUM_LIBRARY_PATH in ";
-		$message .= __FILE__ . ".  It should point to the directory containing your ";
-		$message .= "/libraries directory.";
-		throw new ErrorException($message);
-	}
-
-	$resources = sys_get_temp_dir();
-	$templates = $resources . '/tmp/cache/templates/';
-	if (!is_dir($templates)) {
-		mkdir($resources . '/tmp/cache/templates/', 0777, true);
-	}
-
-	lithium\core\Libraries::add('lithium');
-	lithium\core\Libraries::add(basename($working), array(
-		'default' => true,
-		'path' => $working,
-		'resources' => $resources
-	));
-};
-
-/**
- * The following will dispatch the request and exit with the status code as
- * provided by the `Response` object returned from `run()`.
- *
- * The following will instantiate a new `Request` object and pass it off to the
- * `Dispatcher` class.  By default, the `Request` will automatically aggregate
- * all the server / environment settings, and request content (i.e. options and
- * arguments passed to the command) information.
- *
- * The `Request` is then used by the `Dispatcher` (in conjunction with the
- * `Router`) to determine the correct command to dispatch to. The response
- * information is then encapsulated in a `Response` object, which is returned
- * from the command to the `Dispatcher`.
- *
- * The `Response` object will contain information about the status code which
- * is used as the exit code when ending the execution of this script and
- * returned to the callee.
- *
- * @see lithium\console\Request
- * @see lithium\console\Response
- * @see lithium\console\Dispatcher
- * @see lithium\console\Router
- */
-$run = function() {
-	return lithium\console\Dispatcher::run(new lithium\console\Request())->status;
-};
-
-/**
- * Look to see if there's a bootstrap file. If there is, this is either a Lithium application or
- * plugin.
- */
-if (file_exists("{$working}/config/bootstrap.php")) {
-	$app = $working;
-} elseif (file_exists("{$working}/app/config/bootstrap.php")) {
-	$app = "{$working}/app";
-}
-
-/**
- * Attempt to bootstrap the application and execute the request. On failure, use the default
- * bootstrap.
- */
-if ($app) {
-	foreach (array("bootstrap.php", "bootstrap/libraries.php") as $file) {
-		if (!file_exists($path = "{$app}/config/{$file}")) {
-			continue;
-		}
-		if (preg_match("/^define\([\"']LITHIUM_LIBRARY_PATH[\"']/m", file_get_contents($path))) {
-			include "{$app}/config/bootstrap.php";
-			exit($run());
-		}
-	}
-}
-
-/**
- * We're not running inside a Lithium application. Use the default bootstrap and execute the
- * request.
- */
-$bootstrap();
-$app ? include "{$app}/config/bootstrap.php" : null;
-exit($run());
-
-?>

+ 0 - 191
frameworks/PHP/php-lithium/libraries/lithium/console/readme.md

@@ -1,191 +0,0 @@
-
-The console package contains a set of classes required to route and dispatch
-incoming console requests. Moreover it contains the console front-controller
-file (`lithium.php`) as well as wrappers for both *nix and Windows environments
-(`li3` and `li3.bat` respectively), allowing to easily invoke the
-console front-controller from the command line.
-
-A command is to the command line what an action controller is to the HTTP
-request/response flow. In that commands are quite similar to controllers.
-Commands don't leverage the full MVC as they don't utilize views, but
-directly interact with the user through `in()` and `out()`.
-
-Lithium itself provides amongst others commands for creating new applications
-or parts thereof. However commands can also be provided through other libraries
-or by your application. Commands running in the application context will have
-complete access to your application. This is especially useful to reuse
-existing logic in an application's model when creating a command to be run as
-i.e. a cron-job.
-
-### Invoking the front-controller
-
-You invoke the console front-controller through one of the wrappers
-provided, as shown below. The examples shown are relative to the root directory
-of a standard Lithium  distribution. The first is for users on a *nix command
-line the second for users on a Windows system. Please note that the preceding
-`$` in examples always indicates things that you enter on the command line.
-
-{{{
-$ libraries/lithium/console/li3
-$ libraries/lithium/console/li3.bat
-}}}
-
-However it is recommended you add the path containing the wrapper to the paths
-searched by your system. This is `$PATH` for *nix and `%PATH%` for Windows.
-
-
-#### A: Configuring your $PATH on *nix
-
-This is almost always achievable on a per-user basis through the user's
-`.profile` (Users running Bash may prefer `.bash_profile`). The file is located
-in your home directory.  Open the file and add the following line, assuming the
-`li3` wrapper exists in `/path/to/libraries/lithium/console`.
-
-{{{
-export PATH+=:/path/to/libraries/lithium/console
-}}}
-
-Once you've followed these steps, save your modified the file and reload your environment settings
-by sourcing the modified profile through the following command.
-
-{{{
-$ source ~/.profile
-}}}
-
-If you are unable, or don't wish, to modify your `$PATH` there are two other
-techniques you may use to make the wrapper available as `li3`.  You can either
-symlink the wrapper into one of the paths found in the `$PATH` environment
-variable or create an alias. If you choose an alias, you can make it permanent
-by adding the alias command to the `.bashrc` file in your home directory.
-
-{{{
-$ cd /path/to/a/directory/in/your/path
-$ ln -s /path/to/libraries/lithium/console .
-}}}
-
-{{{
-alias li3='/path/to/lithium/libraries/lithium/console/li3'
-}}}
-
-#### B: Configuring your %PATH% on Windows
-
-Please note that if you're on Windows you must also add the PHP directory to
-the `%PATH%` environment variable. As we are going to edit that variable for adding
-the location of the `li3.bat` wrapper anyway, we can kill two birds with one stone.
-
- - Open _System_ from within the _Control Panel_.
- - Open the _Advanced_ tab.
- - Clicking the _Environment Variables_ button open a dialog where you can edit the variables.
- - Double click the _PATH_ entry in order to edit it.
- - Add `;C:\path\to\php;C:\path\to\libraries\lithium\console` to the end of the value.
-
-#### Finishing up
-
-Now that you've made the wrapper available as `li3` or `li3.bat` respectively,
-you should be able to use it from the command-line simply by executing `li3` or
-`li3.bat`. Invoking the wrapper like that (without arguments) should give you a
-list of available commands.
-
-{{{
-$ li3
-$ li3.bat
-}}}
-
-### Built-in commands
-
-Using the commands which come with lithium is easy. Invoke the wrapper without
-any arguments to get a list of all available commands. Get a description about
-each command and the options and arguments it accepts or may require by using
-the `help` command.
-
-{{{
-$ li3 help
-$ li3 help create
-$ li3 help g11n
-}}}
-
-### Creating custom commands
-
-Creating your own commands is very easy. A few fundamentals:
-
-- All commands inherit from `lithium\console\Command`.
-- Commands are normally placed in your application or library's `extensions/command` directory.
-
-Here's an example command:
-
-{{{
-<?php
-
-namespace app\extensions\command;
-
-class HelloWorld extends \lithium\console\Command {
-
-	public function run() {
-		$this->header('Welcome to the Hello World command!');
-		$this->out('Hello, World!');
-	}
-}
-
-?>
-}}}
-
-If you would like to try this command, create an application or use an existing
-application, place the command into the application's `extensions/commands`
-directory and save it as `HelloWorld.php`. After doing so open a shell and
-change directory to your application's directory and run the following command:
-
-{{{
-$ li3 hello_world
-}}}
-
-Although it's probably obvious, when this command runs it will output a nice
-header with the text `Welcome to the Hello World command!` and some regular
-text `Hello, World!` after it.
-
-The public method `run()` is called on your command instance every time your
-command has been requested to run. From this method you can add your own command
-logic.
-
-#### Parsing options and arguments
-
-Parsing options and arguments to commands should be simple. In fact, the
-parsing is already done for you.
-
-Short and long (GNU-style) options in the form of `-f`, `--foo`, `--foo-bar` and `--foo=bar`
-are automatically parsed and exposed to your command instance through its
-properties. XF68-style long options (i.e. `-foo`) are not supported by default
-but support can be added by extending the console router.
-
-Arguments are passed directly to the invoked method.
-
-Let's look at an example, going back to the `hello_world` command from earlier:
-
-{{{
-<?php
-
-namespace app\extensions\command;
-
-class HelloWorld extends \lithium\console\Command {
-
-	public $recipient;
-
-	public function run() {
-		$this->header('Welcome to the Hello World command!');
-		$this->out('Hello, ' . ($this->recipient ?: 'World') . '!');
-	}
-}
-
-?>
-}}}
-
-Notice the additional property `$recipient`? Great! Now when `--recipient` is
-passed to the `hello_world` command, the recipient property on your command
-instance will be set to whatever was passed into the command at runtime.
-
-Try it out with the following command:
-
-{{{
-$ li3 hello_world --recipient=AwesomeGuy
-}}}
-
-You should get a special greeting from our good old `hello_world` command.

+ 0 - 331
frameworks/PHP/php-lithium/libraries/lithium/core/Adaptable.php

@@ -1,331 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-use lithium\core\Environment;
-use SplDoublyLinkedList;
-use lithium\core\ConfigException;
-
-/**
- * The `Adaptable` static class is the base class from which all adapter implementations extend.
- *
- * `Adaptable` provides the logic necessary for generic configuration of named adapter
- * configurations (such as the ones used in `Cache`) as well as a unified method of locating and
- * obtaining an instance to a specified adapter.
- *
- * All immediate subclasses to `Adaptable` must define the protected attributes `$_configurations`
- * and `$_adapters`. The former is where all local adapter named configurations will be
- * stored (as an array of named configuration settings), and the latter must contain the
- * `Libraries::locate()`-compatible path string (or array of strings) specifying how adapter classes
- * should be located.
- *
- * This static class should **never** be called explicitly.
- */
-class Adaptable extends \lithium\core\StaticObject {
-
-	/**
-	 * Must always be re-defined in sub-classes. Can provide initial
-	 * configurations, i.e. `'development'` or `'default'` along with
-	 * default options for each.
-	 *
-	 * Example:
-	 * {{{
-	 * array(
-	 *	'production' => array(),
-	 *	'development' => array(),
-	 *	'test' => array()
-	 * )
-	 * }}}
-	 *
-	 * @var object `Collection` of configurations, indexed by name.
-	 */
-	protected static $_configurations = array();
-
-	/**
-	 * Must only be re-defined in sub-classes if the class is using strategies.
-	 * Holds the `Libraries::locate()` compatible path string where the strategy
-	 * in question may be found i.e. `'strategy.storage.cache'`.
-	 *
-	 * @var string Path string.
-	 */
-	protected static $_strategies = null;
-
-	/**
-	 * Must always be re-defined in sub-classes. Holds the
-	 * `Libraries::locate()` compatible path string where the adapter in
-	 * question may be found i.e. `'adapter.storage.cache'`.
-	 *
-	 * @var string Path string.
-	 */
-	protected static $_adapters = null;
-
-	/**
-	 * Sets configurations for a particular adaptable implementation, or returns the current
-	 * configuration settings.
-	 *
-	 * @param array $config Configurations, indexed by name.
-	 * @return object `Collection` of configurations or void if setting configurations.
-	 */
-	public static function config($config = null) {
-		if ($config && is_array($config)) {
-			static::$_configurations = $config;
-			return;
-		}
-		if ($config) {
-			return static::_config($config);
-		}
-		$result = array();
-		static::$_configurations = array_filter(static::$_configurations);
-
-		foreach (array_keys(static::$_configurations) as $key) {
-			$result[$key] = static::_config($key);
-		}
-		return $result;
-	}
-
-	/**
-	 * Clears all configurations.
-	 *
-	 * @return void
-	 */
-	public static function reset() {
-		static::$_configurations = array();
-	}
-
-	/**
-	 * Returns adapter class name for given `$name` configuration, using
-	 * the `$_adapter` path defined in Adaptable subclasses.
-	 *
-	 * @param string $name Class name of adapter to load.
-	 * @return object Adapter object.
-	 */
-	public static function adapter($name = null) {
-		$config = static::_config($name);
-
-		if ($config === null) {
-			throw new ConfigException("Configuration `{$name}` has not been defined.");
-		}
-
-		if (isset($config['object'])) {
-			return $config['object'];
-		}
-		$class = static::_class($config, static::$_adapters);
-		$settings = static::$_configurations[$name];
-		$settings[0]['object'] = static::_initAdapter($class, $config);
-		static::$_configurations[$name] = $settings;
-		return static::$_configurations[$name][0]['object'];
-	}
-
-	/**
-	 * Obtain an `SplDoublyLinkedList` of the strategies for the given `$name` configuration, using
-	 * the `$_strategies` path defined in `Adaptable` subclasses.
-	 *
-	 * @param string $name Class name of adapter to load.
-	 * @return object `SplDoublyLinkedList` of strategies, or `null` if none are defined.
-	 */
-	public static function strategies($name) {
-		$config = static::_config($name);
-
-		if ($config === null) {
-			throw new ConfigException("Configuration `{$name}` has not been defined.");
-		}
-		if (!isset($config['strategies'])) {
-			return null;
-		}
-		$stack = new SplDoublyLinkedList();
-
-		foreach ($config['strategies'] as $key => $strategy) {
-			if (!is_array($strategy)) {
-				$name = $strategy;
-				$class = static::_strategy($name, static::$_strategies);
-				$stack->push(new $class());
-				continue;
-			}
-			$class = static::_strategy($key, static::$_strategies);
-			$index = (isset($config['strategies'][$key])) ? $key : $class;
-			$stack->push(new $class($config['strategies'][$index]));
-		}
-		return $stack;
-	}
-
-	/**
-	 * Applies strategies configured in `$name` for `$method` on `$data`.
-	 *
-	 * @param string $method The strategy method to be applied.
-	 * @param string $name The named configuration
-	 * @param mixed $data The data to which the strategies will be applied.
-	 * @param array $options If `mode` is set to 'LIFO', the strategies are applied in reverse.
-	 *        order of their definition.
-	 * @return mixed Result of application of strategies to data. If no strategies
-	 *         have been configured, this method will simply return the original data.
-	 */
-	public static function applyStrategies($method, $name, $data, array $options = array()) {
-		$options += array('mode' => null);
-
-		if (!$strategies = static::strategies($name)) {
-			return $data;
-		}
-		if (!count($strategies)) {
-			return $data;
-		}
-
-		if (isset($options['mode']) && ($options['mode'] === 'LIFO')) {
-			$strategies->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
-			unset($options['mode']);
-		}
-
-		foreach ($strategies as $strategy) {
-			if (method_exists($strategy, $method)) {
-				$data = $strategy->{$method}($data, $options);
-			}
-		}
-		return $data;
-	}
-
-	/**
-	 * Determines if the adapter specified in the named configuration is enabled.
-	 *
-	 * `Enabled` can mean various things, e.g. having a PECL memcached extension compiled
-	 * & loaded, as well as having the memcache server up & available.
-	 *
-	 * @param string $name The named configuration whose adapter will be checked.
-	 * @return boolean  True if adapter is enabled, false if not. This method will
-	 *         return null if no configuration under the given $name exists.
-	 */
-	public static function enabled($name) {
-		if (!static::_config($name)) {
-			return null;
-		}
-		$adapter = static::adapter($name);
-		return $adapter::enabled();
-	}
-
-	/**
-	 * Provides an extension point for modifying how adapters are instantiated.
-	 *
-	 * @see lithium\core\Object::__construct()
-	 * @param string $class The fully-namespaced class name of the adapter to instantiate.
-	 * @param array $config The configuration array to be passed to the adapter instance. See the
-	 *              `$config` parameter of `Object::__construct()`.
-	 * @return object The adapter's class.
-	 * @filter This method can be filtered.
-	 */
-	protected static function _initAdapter($class, array $config) {
-		return static::_filter(__FUNCTION__, compact('class', 'config'), function($self, $params) {
-			return new $params['class']($params['config']);
-		});
-	}
-
-	/**
-	 * Looks up an adapter by class by name.
-	 *
-	 * @see lithium\core\libraries::locate()
-	 * @param string $config Configuration array of class to be found.
-	 * @param array $paths Optional array of search paths that will be checked.
-	 * @return string Returns a fully-namespaced class reference to the adapter class.
-	 */
-	protected static function _class($config, $paths = array()) {
-		if (!$name = $config['adapter']) {
-			$self = get_called_class();
-			throw new ConfigException("No adapter set for configuration in class `{$self}`.");
-		}
-		if (!$class = static::_locate($paths, $name)) {
-			$self = get_called_class();
-			throw new ConfigException("Could not find adapter `{$name}` in class `{$self}`.");
-		}
-		return $class;
-	}
-
-	/**
-	 * Looks up a strategy by class by name.
-	 *
-	 * @see lithium\core\libraries::locate()
-	 * @param string $name The strategy to locate.
-	 * @param array $paths Optional array of search paths that will be checked.
-	 * @return string Returns a fully-namespaced class reference to the adapter class.
-	 */
-	protected static function _strategy($name, $paths = array()) {
-		if (!$name) {
-			$self = get_called_class();
-			throw new ConfigException("No strategy set for configuration in class `{$self}`.");
-		}
-		if (!$class = static::_locate($paths, $name)) {
-			$self = get_called_class();
-			throw new ConfigException("Could not find strategy `{$name}` in class `{$self}`.");
-		}
-		return $class;
-	}
-
-	/**
-	 * Perform library location for an array of paths or a single string-based path.
-	 *
-	 * @param string|array $paths Paths that Libraries::locate() will utilize.
-	 * @param string $name The name of the class to be located.
-	 * @return string Fully-namespaced path to the class, or null if not found.
-	 */
-	protected static function _locate($paths, $name) {
-		foreach ((array) $paths as $path) {
-			if ($class = Libraries::locate($path, $name)) {
-				return $class;
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Gets an array of settings for the given named configuration in the current
-	 * environment.
-	 *
-	 * The default types of settings for all adapters will contain keys for:
-	 * `adapter` - The class name of the adapter
-	 * `filters` - An array of filters to be applied to the adapter methods
-	 *
-	 * @see lithium\core\Environment
-	 * @param string $name Named configuration.
-	 * @return array Settings for the named configuration.
-	 */
-	protected static function _config($name) {
-		if (!isset(static::$_configurations[$name])) {
-			return null;
-		}
-		$settings = static::$_configurations[$name];
-
-		if (isset($settings[0])) {
-			return $settings[0];
-		}
-		$env = Environment::get();
-		$config = isset($settings[$env]) ? $settings[$env] : $settings;
-
-		if (isset($settings[$env]) && isset($settings[true])) {
-			$config += $settings[true];
-		}
-		static::$_configurations[$name] += array(static::_initConfig($name, $config));
-		return static::$_configurations[$name][0];
-	}
-
-	/**
-	 * A stub method called by `_config()` which allows `Adaptable` subclasses to automatically
-	 * assign or auto-generate additional configuration data, once a configuration is first
-	 * accessed. This allows configuration data to be lazy-loaded from adapters or other data
-	 * sources.
-	 *
-	 * @param string $name The name of the configuration which is being accessed. This is the key
-	 *               name containing the specific set of configuration passed into `config()`.
-	 * @param array $config Contains the configuration assigned to `$name`. If this configuration is
-	 *              segregated by environment, then this will contain the configuration for the
-	 *              current environment.
-	 * @return array Returns the final array of settings for the given named configuration.
-	 */
-	protected static function _initConfig($name, $config) {
-		$defaults = array('adapter' => null, 'filters' => array());
-		return (array) $config + $defaults;
-	}
-}
-
-?>

+ 0 - 20
frameworks/PHP/php-lithium/libraries/lithium/core/ClassNotFoundException.php

@@ -1,20 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-/**
- * A `ClassNotFoundException` may be thrown when a configured adapter or other service class defined
- * in configuration can't be located.
- */
-class ClassNotFoundException extends \RuntimeException {
-
-	protected $code = 500;
-}
-
-?>

+ 0 - 20
frameworks/PHP/php-lithium/libraries/lithium/core/ConfigException.php

@@ -1,20 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-/**
- * A `ConfigException` is thrown when a request is made to render content in a format not
- * supported.
- */
-class ConfigException extends \RuntimeException {
-
-	protected $code = 500;
-}
-
-?>

+ 0 - 348
frameworks/PHP/php-lithium/libraries/lithium/core/Environment.php

@@ -1,348 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-use lithium\util\Set;
-
-/**
- * The `Environment` class allows you to manage multiple configurations for your application,
- * depending on the context within which it is running, i.e. development, test or production.
- *
- * While those three environments are the most common, you can create any arbitrary environment
- * with any set of configuration, for example:
- *
- * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testSetAndGetCurrentEnvironment(1-3)}}}
- *
- * You can then retrieve the configurations using the key name. The correct configuration is
- * returned, automatically accounting for the current environment:
- *
- * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testSetAndGetCurrentEnvironment(15-15)}}}
- *
- * `Environment` also works with subclasses of `Adaptable`, allowing you to maintain separate
- * configurations for database servers, cache adapters, and other environment-specific classes, for
- * example:
- * {{{
- * Connections::add('default', array(
- * 	'production' => array(
- * 		'type'     => 'database',
- * 		'adapter'  => 'MySql',
- * 		'host'     => 'db1.application.local',
- * 		'login'    => 'secure',
- * 		'password' => 'secret',
- * 		'database' => 'app-production'
- * 	),
- * 	'development' => array(
- * 		'type'     => 'database',
- * 		'adapter'  => 'MySql',
- * 		'host'     => 'localhost',
- * 		'login'    => 'root',
- * 		'password' => '',
- * 		'database' => 'app'
- * 	)
- * ));
- * }}}
- *
- * This allows the database connection named `'default'` to be connected to a local database in
- * development, and a production database in production. You can define environment-specific
- * configurations for caching, logging, even session storage, i.e.:
- * {{{
- * Cache::config(array(
- * 	'userData' => array(
- * 		'development' => array('adapter' => 'File'),
- * 		'production' => array('adapter' => 'Memcache')
- * 	)
- * ));
- * }}}
- *
- * When the cache configuration is accessed in the application's code, the correct configuration is
- * automatically used:
- * {{{
- * $user = User::find($request->id);
- * Cache::write('userData', "User.{$request->id}", $user->data(), '+5 days');
- * }}}
- *
- * In this configuration, the above example will automatically send cache writes to the file system
- * during local development, and to a [ memcache](http://memcached.org/) server in production.
- *
- * When writing classes that connect to other external resources, you can automatically take
- * advantage of environment-specific configurations by extending `Adaptable` and implementing
- * your resource-handling functionality in adapter classes.
- *
- * In addition to managing your environment-specific configurations, `Environment` will also help
- * you by automatically detecting which environment your application is running in. For additional
- * information, see the documentation for `Environment::is()`.
- *
- * @see lithium\core\Adaptable
- */
-class Environment {
-
-	protected static $_configurations = array(
-		'production' => array(),
-		'development' => array(),
-		'test' => array()
-	);
-
-	/**
-	 * Holds the name of the current environment under which the application is running. Set by
-	 * passing a `Request` object or `$_SERVER` or `$_ENV` array into `Environment::set()` (which
-	 * in turn passes this on to the _detector_ used to determine the correct environment). Can be
-	 * tested or retrieved using `Environment::is()` or `Environment::get()`.
-	 *
-	 * @see lithium\correct\Environment::set()
-	 * @see lithium\correct\Environment::is()
-	 * @see lithium\correct\Environment::get()
-	 * @var string
-	 */
-	protected static $_current = '';
-
-	/**
-	 * If `Environment::is()` is used to assign a custom closure for environment detection, a copy
-	 * is kept in `$_detector`. Otherwise, `$_detector` is `null`, and the hard-coded detector is
-	 * used.
-	 *
-	 * @see lithium\core\Environment::_detector()
-	 * @see lithium\core\Environment::is()
-	 * @var object
-	 */
-	protected static $_detector = null;
-
-	/**
-	 * Resets the `Environment` class to its default state, including unsetting the current
-	 * environment, removing any environment-specific configurations, and removing the custom
-	 * environment detector, if any has been specified.
-	 *
-	 * @return void
-	 */
-	public static function reset() {
-		static::$_current = '';
-		static::$_detector = null;
-		static::$_configurations = array(
-			'production' => array(),
-			'development' => array(),
-			'test' => array()
-		);
-	}
-
-	/**
-	 * A simple boolean detector that can be used to test which environment the application is
-	 * running under. For example `Environment::is('development')` will return `true` if
-	 * `'development'` is, in fact, the current environment.
-	 *
-	 * This method also handles how the environment is detected at the beginning of the request.
-	 *
-	 * #### Custom Detection
-	 *
-	 * While the default detection rules are very simple (if the `'SERVER_ADDR'` variable is set to
-	 * `127.0.0.1`, the environment is assumed to be `'development'`, or if the string `'test'` is
-	 * found anywhere in the host name, it is assumed to be `'test'`, and in all other cases it
-	 * is assumed to be `'production'`), you can define your own detection rule set easily using a
-	 * closure that accepts an instance of the `Request` object, and returns the name of the correct
-	 * environment, as in the following example:
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testCustomDetector(1-9) }}}
-	 *
-	 * In the above example, the user-specified closure takes in a `Request` object, and using the
-	 * server data which it encapsulates, returns the correct environment name as a string.
-	 *
-	 * #### Host Mapping
-	 *
-	 * The most common use case is to set the environment depending on host name. For convenience,
-	 * the `is()` method also accepts an array that matches host names to environment names, where
-	 * each key is an environment, and each value is either an array of valid host names, or a
-	 * regular expression used to match a valid host name.
-	 *
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testDetectionWithArrayMap(1-5) }}}
-	 *
-	 * In this example, a regular expression is being used to match local domains
-	 * (i.e. `localhost`), as well as the built-in `.console` domain, for console requests. Note
-	 * that in the console, the environment can always be overridden by specifying the `--env`
-	 * option.
-	 *
-	 * Then, one or more host names are matched up to `'test'` and `'staging'`, respectively. Note
-	 * that no rule is present for production: this is because `'production'` is the default value
-	 * if no other environment matches.
-	 *
-	 * @param mixed $detect Either the name of an environment to check against the current, i.e.
-	 *              `'development'` or `'production'`, or a closure which `Environment` will use
-	 *              to determine the current environment name, or an array mapping environment names
-	 *              to host names.
-	 * @return boolean If `$detect` is a string, returns `true` if the current environment matches
-	 *         the value of `$detect`, or `false` if no match. If used to set a custom detector,
-	 *         returns `null`.
-	 */
-	public static function is($detect) {
-		if (is_callable($detect)) {
-			static::$_detector = $detect;
-		}
-		if (!is_array($detect)) {
-			return (static::$_current == $detect);
-		}
-		static::$_detector = function($request) use ($detect) {
-			if ($request->env || $request->command == 'test') {
-				return ($request->env) ? $request->env : 'test';
-			}
-			$host = method_exists($request, 'get') ? $request->get('http:host') : '.console';
-
-			foreach ($detect as $environment => $hosts) {
-				if (is_string($hosts) && preg_match($hosts, $host)) {
-					return $environment;
-				}
-				if (is_array($hosts) && in_array($host, $hosts)) {
-					return $environment;
-				}
-			}
-			return "production";
-		};
-	}
-
-	/**
-	 * Gets the current environment name, a setting associated with the current environment, or the
-	 * entire configuration array for the current environment.
-	 *
-	 * @param string $name The name of the environment setting to retrieve, or the name of an
-	 *               environment, if that environment's entire configuration is to be retrieved. If
-	 *               retrieving the current environment name, `$name` should not be passed.
-	 * @return mixed If `$name` is unspecified, returns the name of the current environment name as
-	 *         a string (i.e. `'production'`). If an environment name is specified, returns that
-	 *         environment's entire configuration as an array.
-	 */
-	public static function get($name = null) {
-		$cur = static::$_current;
-
-		if (!$name) {
-			return $cur;
-		}
-		if ($name === true) {
-			return isset(static::$_configurations[$cur]) ? static::$_configurations[$cur] : null;
-		}
-		if (isset(static::$_configurations[$name])) {
-			return static::_processDotPath($name, static::$_configurations);
-		}
-		if (!isset(static::$_configurations[$cur])) {
-			return static::_processDotPath($name, static::$_configurations);
-		}
-
-		return static::_processDotPath($name, static::$_configurations[$cur]);
-	}
-
-	protected static function _processDotPath($path, &$arrayPointer) {
-		if (isset($arrayPointer[$path])) {
-			return $arrayPointer[$path];
-		}
-		if (strpos($path, '.') === false) {
-			return null;
-		}
-		$pathKeys = explode('.', $path);
-		foreach ($pathKeys as $pathKey) {
-			if (!is_array($arrayPointer) || !isset($arrayPointer[$pathKey])) {
-				return false;
-			}
-			$arrayPointer = &$arrayPointer[$pathKey];
-		}
-		return $arrayPointer;
-	}
-
-	/**
-	 * Creates, modifies or switches to an existing environment configuration. To create a new
-	 * configuration, or to update an existing configuration, pass an environment name and an array
-	 * that defines its configuration:
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testModifyEnvironmentConfig(1-1) }}}
-	 *
-	 * You can then add to an existing configuration by calling the `set()` method again with the
-	 * same environment name:
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testModifyEnvironmentConfig(6-6) }}}
-	 *
-	 * The settings for the environment will then be the aggregate of all `set()` calls:
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testModifyEnvironmentConfig(7-7) }}}
-	 *
-	 * By passing an array to `$env`, you can assign the same configuration to multiple
-	 * environments:
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testSetMultipleEnvironments(5-7) }}}
-	 *
-	 * The `set()` method can also be called to manually set which environment to operate in:
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testSetAndGetCurrentEnvironment(5-5) }}}
-	 *
-	 * Finally, `set()` can accept a `Request` object, to automatically detect the correct
-	 * environment.
-	 *
-	 * {{{ embed:lithium\tests\cases\core\EnvironmentTest::testEnvironmentDetection(9-10) }}}
-	 *
-	 * For more information on defining custom rules to automatically detect your application's
-	 * environment, see the documentation for `Environment::is()`.
-	 *
-	 * @see lithium\action\Request
-	 * @see lithium\core\Environment::is()
-	 * @param mixed $env The name(s) of the environment(s) you wish to create, update or switch to
-	 *              (string/array), or a `Request` object or `$_SERVER` / `$_ENV` array used to
-	 *              detect (and switch to) the application's current environment.
-	 * @param array $config If creating or updating a configuration, accepts an array of settings.
-	 *              If the environment name specified in `$env` already exists, the values in
-	 *              `$config` will be recursively merged with any pre-existing settings.
-	 * @return array If creating or updating a configuration, returns an array of the environment's
-	 *               settings. If updating an existing configuration, this will be the newly-applied
-	 *               configuration merged with the pre-existing values. If setting the environment
-	 *               itself (i.e. `$config` is unspecified), returns `null`.
-	 */
-	public static function set($env, $config = null) {
-		if ($config === null) {
-			if (is_object($env) || is_array($env)) {
-				static::$_current = static::_detector()->__invoke($env);
-			} elseif (isset(static::$_configurations[$env])) {
-				static::$_current = $env;
-			}
-			return;
-		}
-		if (is_array($env)) {
-			foreach ($env as $name) {
-				static::set($name, $config);
-			}
-			return;
-		}
-		$env = ($env === true) ? static::$_current : $env;
-		$base = isset(static::$_configurations[$env]) ? static::$_configurations[$env] : array();
-		return static::$_configurations[$env] = Set::merge($base, $config);
-	}
-
-	/**
-	 * Accessor method for `Environment::$_detector`. If `$_detector` is unset, returns the default
-	 * detector built into the class. For more information on setting and using `$_detector`, see
-	 * the documentation for `Environment::is()`. The `_detector()` method is called at the
-	 * beginning of the application's life-cycle, when `Environment::set()` is passed either an
-	 * instance of a `Request` object, or the `$_SERVER` or `$_ENV` array. This object (or array)
-	 * is then passed onto `$_detector`, which returns the correct environment.
-	 *
-	 * @see lithium\core\Environment::is()
-	 * @see lithium\core\Environment::set()
-	 * @see lithium\core\Environment::$_detector
-	 * @return object Returns a callable object (anonymous function) which detects the application's
-	 *         current environment.
-	 */
-	protected static function _detector() {
-		return static::$_detector ?: function($request) {
-			$isLocal = in_array($request->env('SERVER_ADDR'), array('::1', '127.0.0.1'));
-			switch (true) {
-				case (isset($request->env)):
-					return $request->env;
-				case ($request->command == 'test'):
-					return 'test';
-				case ($request->env('PLATFORM') == 'CLI'):
-					return 'development';
-				case (preg_match('/^test\//', $request->url) && $isLocal):
-					return 'test';
-				case ($isLocal):
-					return 'development';
-				case (preg_match('/^test/', $request->env('HTTP_HOST'))):
-					return 'test';
-				default:
-					return 'production';
-			}
-		};
-	}
-}
-
-?>

+ 0 - 326
frameworks/PHP/php-lithium/libraries/lithium/core/ErrorHandler.php

@@ -1,326 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2009, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-use Exception;
-use ErrorException;
-use lithium\util\collection\Filters;
-
-/**
- * The `ErrorHandler` class allows PHP errors and exceptions to be handled in a uniform way. Using
- * the `ErrorHandler`'s configuration, it is possible to have very broad but very tight control
- * over error handling in your application.
- *
- * {{{ embed:lithium\tests\cases\core\ErrorHandlerTest::testExceptionCatching(2-7) }}}
- *
- * Using a series of cascading rules and handlers, it is possible to capture and handle very
- * specific errors and exceptions.
- */
-class ErrorHandler extends \lithium\core\StaticObject {
-
-	/**
-	 * Configuration parameters.
-	 *
-	 * @var array Config params
-	 */
-	protected static $_config = array();
-
-	/**
-	 * Types of checks available for sorting & parsing errors/exceptions.
-	 * Default checks are for `code`, `stack` and `message`.
-	 *
-	 * @var array Array of checks represented as closures, indexed by name.
-	 */
-	protected static $_checks = array();
-
-	/**
-	 * Currently registered exception handler.
-	 *
-	 * @var closure Closure representing exception handler.
-	 */
-	protected static $_exceptionHandler = null;
-
-	/**
-	 * State of error/exception handling.
-	 *
-	 * @var boolean True if custom error/exception handlers have been registered, false
-	 *      otherwise.
-	 */
-	protected static $_isRunning = false;
-
-	protected static $_runOptions = array();
-
-	/**
-	 * Setup basic error handling checks/types, as well as register the error and exception
-	 * handlers.
-	 *
-	 * Called on static class initialization (i.e. when first loaded).
-	 *
-	 * @return void
-	 */
-	public static function __init() {
-		static::$_checks = array(
-			'type'  => function($config, $info) {
-				return (boolean) array_filter((array) $config['type'], function($type) use ($info) {
-					return $type === $info['type'] || is_subclass_of($info['type'], $type);
-				});
-			},
-			'code' => function($config, $info) {
-				return ($config['code'] & $info['code']);
-			},
-			'stack' => function($config, $info) {
-				return (boolean) array_intersect((array) $config['stack'], $info['stack']);
-			},
-			'message' => function($config, $info) {
-				return preg_match($config['message'], $info['message']);
-			}
-		);
-		$self = get_called_class();
-
-		static::$_exceptionHandler = function($exception, $return = false) use ($self) {
-			if (ob_get_length()) {
-				ob_end_clean();
-			}
-			$info = compact('exception') + array(
-				'type' => get_class($exception),
-				'stack' => $self::trace($exception->getTrace())
-			);
-			foreach (array('message', 'file', 'line', 'trace') as $key) {
-				$method = 'get' . ucfirst($key);
-				$info[$key] = $exception->{$method}();
-			}
-			return $return ? $info : $self::handle($info);
-		};
-	}
-
-	/**
-	 * Configure the `ErrorHandler`.
-	 *
-	 * @param array $config Configuration directives.
-	 * @return Current configuration set.
-	 */
-	public static function config($config = array()) {
-		return (static::$_config = array_merge($config, static::$_config));
-	}
-
-	/**
-	 * Register error and exception handlers.
-	 *
-	 * This method (`ErrorHandler::run()`) needs to be called as early as possible in the bootstrap
-	 * cycle; immediately after `require`-ing `bootstrap/libraries.php` is your best bet.
-	 *
-	 * @param array $config The configuration with which to start the error handler. Available
-	 *              options include:
-	 *              - `'trapErrors'` _boolean_: Defaults to `false`. If set to `true`, PHP errors
-	 *                will be caught by `ErrorHandler` and handled in-place. Execution will resume
-	 *                in the same context in which the error occurred.
-	 *              - `'convertErrors'` _boolean_: Defaults to `true`, and specifies that all PHP
-	 *                errors should be converted to `ErrorException`s and thrown from the point
-	 *                where the error occurred. The exception will be caught at the first point in
-	 *                the stack trace inside a matching `try`/`catch` block, or that has a matching
-	 *                error handler applied using the `apply()` method.
-	 * @return void
-	 */
-	public static function run(array $config = array()) {
-		$defaults = array('trapErrors' => false, 'convertErrors' => true);
-
-		if (static::$_isRunning) {
-			return;
-		}
-		static::$_isRunning = true;
-		static::$_runOptions = $config + $defaults;
-		$self = get_called_class();
-
-		$trap = function($code, $message, $file, $line = 0, $context = null) use ($self) {
-			$trace = debug_backtrace();
-			$trace = array_slice($trace, 1, count($trace));
-			$self::handle(compact('type', 'code', 'message', 'file', 'line', 'trace', 'context'));
-		};
-
-		$convert = function($code, $message, $file, $line = 0, $context = null) use ($self) {
-			throw new ErrorException($message, 500, $code, $file, $line);
-		};
-
-		if (static::$_runOptions['trapErrors']) {
-			set_error_handler($trap);
-		} elseif (static::$_runOptions['convertErrors']) {
-			set_error_handler($convert);
-		}
-		set_exception_handler(static::$_exceptionHandler);
-	}
-
-	/**
-	 * Returns the state of the `ErrorHandler`, indicating whether or not custom error/exception
-	 * handers have been regsitered.
-	 *
-	 * @return void
-	 */
-	public static function isRunning() {
-		return static::$_isRunning;
-	}
-
-	/**
-	 * Unooks `ErrorHandler`'s exception and error handlers, and restores PHP's defaults. May have
-	 * unexpected results if it is not matched with a prior call to `run()`, or if other error
-	 * handlers are set after a call to `run()`.
-	 *
-	 * @return void
-	 */
-	public static function stop() {
-		restore_error_handler();
-		restore_exception_handler();
-		static::$_isRunning = false;
-	}
-
-	/**
-	 * Wipes out all configuration and resets the error handler to its initial state when loaded.
-	 * Mainly used for testing.
-	 *
-	 * @return void
-	 */
-	public static function reset() {
-		static::$_config = array();
-		static::$_checks = array();
-		static::$_exceptionHandler = null;
-		static::__init();
-	}
-
-	/**
-	 * Receives the handled errors and exceptions that have been caught, and processes them
-	 * in a normalized manner.
-	 *
-	 * @param object|array $info
-	 * @param array $scope
-	 * @return boolean True if successfully handled, false otherwise.
-	 */
-	public static function handle($info, $scope = array()) {
-		$checks = static::$_checks;
-		$rules = $scope ?: static::$_config;
-		$handler = static::$_exceptionHandler;
-		$info = is_object($info) ? $handler($info, true) : $info;
-
-		$defaults = array(
-			'type' => null, 'code' => 0, 'message' => null, 'file' => null, 'line' => 0,
-			'trace' => array(), 'context' => null, 'exception' => null
-		);
-		$info = (array) $info + $defaults;
-
-		$info['stack'] = static::trace($info['trace']);
-		$info['origin'] = static::_origin($info['trace']);
-
-		foreach ($rules as $config) {
-			foreach (array_keys($config) as $key) {
-				if ($key === 'conditions' || $key === 'scope' || $key === 'handler') {
-					continue;
-				}
-				if (!isset($info[$key]) || !isset($checks[$key])) {
-					continue 2;
-				}
-				if (($check = $checks[$key]) && !$check($config, $info)) {
-					continue 2;
-				}
-			}
-			if (!isset($config['handler'])) {
-				return false;
-			}
-			if ((isset($config['conditions']) && $call = $config['conditions']) && !$call($info)) {
-				return false;
-			}
-			if ((isset($config['scope'])) && static::handle($info, $config['scope']) !== false) {
-				return true;
-			}
-			$handler = $config['handler'];
-			return $handler($info) !== false;
-		}
-		return false;
-	}
-
-	/**
-	 * Determine frame from the stack trace where the error/exception was first generated.
-	 *
-	 * @param array $stack Stack trace from error/exception that was produced.
-	 * @return string Class where error/exception was generated.
-	 */
-	protected static function _origin(array $stack) {
-		foreach ($stack as $frame) {
-			if (isset($frame['class'])) {
-				return trim($frame['class'], '\\');
-			}
-		}
-	}
-
-	public static function apply($object, array $conditions, $handler) {
-		$conditions = $conditions ?: array('type' => 'Exception');
-		list($class, $method) = is_string($object) ? explode('::', $object) : $object;
-		$wrap = static::$_exceptionHandler;
-		$_self = get_called_class();
-
-		$filter = function($self, $params, $chain) use ($_self, $conditions, $handler, $wrap) {
-			try {
-				return $chain->next($self, $params, $chain);
-			} catch (Exception $e) {
-				if (!$_self::matches($e, $conditions)) {
-					throw $e;
-				}
-				return $handler($wrap($e, true), $params);
-			}
-		};
-
-		if (is_string($class)) {
-			Filters::apply($class, $method, $filter);
-		} else {
-			$class->applyFilter($method, $filter);
-		}
-	}
-
-	public static function matches($info, $conditions) {
-		$checks = static::$_checks;
-		$handler = static::$_exceptionHandler;
-		$info = is_object($info) ? $handler($info, true) : $info;
-
-		foreach (array_keys($conditions) as $key) {
-			if ($key === 'conditions' || $key === 'scope' || $key === 'handler') {
-				continue;
-			}
-			if (!isset($info[$key]) || !isset($checks[$key])) {
-				return false;
-			}
-			if (($check = $checks[$key]) && !$check($conditions, $info)) {
-				return false;
-			}
-		}
-		if ((isset($config['conditions']) && $call = $config['conditions']) && !$call($info)) {
-			return false;
-		}
-		return true;
-	}
-
-	/**
-	 * Trim down a typical stack trace to class & method calls.
-	 *
-	 * @param array $stack A `debug_backtrace()`-compatible stack trace output.
-	 * @return array Returns a flat stack array containing class and method references.
-	 */
-	public static function trace(array $stack) {
-		$result = array();
-
-		foreach ($stack as $frame) {
-			if (isset($frame['function'])) {
-				if (isset($frame['class'])) {
-					$result[] = trim($frame['class'], '\\') . '::' . $frame['function'];
-				} else {
-					$result[] = $frame['function'];
-				}
-			}
-		}
-		return $result;
-	}
-}
-
-?>

+ 0 - 1079
frameworks/PHP/php-lithium/libraries/lithium/core/Libraries.php

@@ -1,1079 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-use RuntimeException;
-use lithium\util\String;
-use lithium\util\collection\Filters;
-use lithium\core\ConfigException;
-use lithium\core\ClassNotFoundException;
-
-/**
- * Manages all aspects of class and file location, naming and mapping. Implements auto-loading for
- * the Lithium core, as well as all applications, plugins and vendor libraries registered.
- * Typically, libraries and plugins are registered in `config/bootstrap/libraries.php`.
- *
- * By convention, plugins and vendor libraries are typically located in `app-path/libraries` or
- * `/libraries` (the former may override the latter). By default, `Libraries` will use its own
- * autoloader for all plugins and vendor libraries, but can be configured to use others on a
- * per-library basis.
- *
- * `Libraries` also handles service location. Various _types_ of classes can be defined by name,
- * using _class patterns_, which define conventions for organizing classes, i.e. `'models'`, which
- * maps to `'{:library}\models\{:name}'`, which will find a model class in any registered app,
- * plugin or vendor library that follows that path (namespace) convention. You can find classes by
- * name (see the `locate()` method for more information on class-locating precedence), or find all
- * models in all registered libraries (apps / plugins / vendor libraries, etc). For more information
- * on modifying the default class organization, or defining your own class types, see the `paths()`
- * method.
- *
- * #### Auto-loading classes
- *
- * Lithium defines several rules, conventions and recommendations for naming and organizing classes.
- * The autoloader itself conforms to the [PHP Interoperability Group's draft
- * specification](http://groups.google.com/group/php-standards/web/psr-0-final-proposal). While the
- * autoloader will load any classes conforming to that specification, Lithium itself follows
- * additional constraints, which are also recommended for Lithium applications, libraries and
- * extensions, and are as follows:
- *
- * - Each library must exist in a top-level vendor namespace
- * - Each top-level vendor namespace must define a set of sub-packages, and should not directly
- *   contain classes
- * - Namespace names must be lowercased and under_scored
- * - Class names must be CamelCased
- *
- * Any libraries registered by calling `Libraries::add()` which follow the autoloader's will have
- * their classes automatically loaded when referenced.
- *
- * @see lithium\core\Libraries::add()
- * @see lithium\core\Libraries::locate()
- * @see lithium\core\Libraries::paths()
- */
-class Libraries {
-
-	/**
-	 * Stores the closures that represent the method filters. They are indexed by method name.
-	 *
-	 * @var array
-	 */
-	protected static $_methodFilters = array();
-
-	/**
-	 * The list of class libraries registered with the class loader.
-	 *
-	 * @var array
-	 */
-	protected static $_configurations = array();
-
-	/**
-	 * Contains a cascading list of search path templates, indexed by base object type.
-	 *
-	 * Used by `Libraries::locate()` to perform service location. This allows new types of
-	 * objects (i.e. models, helpers, cache adapters and data sources) to be automatically
-	 * 'discovered' when you register a new vendor library or plugin (using `Libraries::add()`).
-	 *
-	 * Because paths are checked in the order in which they appear, path templates should be
-	 * specified from most-specific to least-specific. See the `locate()` method for usage examples.
-	 *
-	 * @see lithium\core\Libraries::locate()
-	 * @see lithium\core\Libraries::paths()
-	 * @var array
-	 */
-	protected static $_paths = array(
-		'adapter' => array(
-			'{:library}\extensions\adapter\{:namespace}\{:class}\{:name}',
-			'{:library}\{:namespace}\{:class}\adapter\{:name}' => array('libraries' => 'lithium')
-		),
-		'command' => array(
-			'{:library}\extensions\command\{:namespace}\{:class}\{:name}',
-			'{:library}\console\command\{:namespace}\{:class}\{:name}' => array(
-				'libraries' => 'lithium'
-			)
-		),
-		'controllers' => array(
-			'{:library}\controllers\{:namespace}\{:class}\{:name}Controller'
-		),
-		'data' => array(
-			'{:library}\extensions\data\{:namespace}\{:class}\{:name}',
-			'{:library}\data\{:namespace}\{:class}\adapter\{:name}' => array(
-				'libraries' => 'lithium'
-			),
-			'{:library}\data\{:namespace}\{:class}\{:name}' => array('libraries' => 'lithium'),
-			'{:library}\data\{:class}\adapter\{:name}' => array('libraries' => 'lithium')
-		),
-		'helper' => array(
-			'{:library}\extensions\helper\{:name}',
-			'{:library}\template\helper\{:name}' => array('libraries' => 'lithium')
-		),
-		'libraries' => array(
-			'{:app}/libraries/{:name}',
-			'{:root}/{:name}'
-		),
-		'models' => array(
-			'{:library}\models\{:name}'
-		),
-		'strategy' => array(
-			'{:library}\extensions\strategy\{:namespace}\{:class}\{:name}',
-			'{:library}\extensions\strategy\{:class}\{:name}',
-			'{:library}\{:namespace}\{:class}\strategy\{:name}' => array('libraries' => 'lithium')
-		),
-		'socket' => array(
-			'{:library}\extensions\net\socket\{:name}',
-			'{:library}\extensions\socket\{:name}',
-			'{:library}\net\socket\{:name}'
-		),
-		'test' => array(
-			'{:library}\extensions\test\{:namespace}\{:class}\{:name}',
-			'{:library}\test\{:namespace}\{:class}\{:name}' => array('libraries' => 'lithium')
-		),
-		'tests' => array(
-			'{:library}\tests\{:namespace}\{:class}\{:name}Test'
-		)
-	);
-
-	/**
-	 * Stores the name of the default library. When adding a library configuration to the
-	 * application, if the `'default'` option flag is set to `true`, the name of the library will
-	 * be assigned. To retrieve the default library's configuration, use `Libraries::get(true)`.
-	 *
-	 * @see lithium\core\Libraries::add()
-	 * @see lithium\core\Libraries::get()
-	 * @var string
-	 */
-	protected static $_default;
-
-	/**
-	 * Holds cached class paths generated and used by `lithium\core\Libraries::load()`.
-	 *
-	 * @var array
-	 * @see lithium\core\Libraries::load()
-	 */
-	protected static $_cachedPaths = array();
-
-	/**
-	 * Holds associations between fully-namespaced class names and file's paths mapped
-	 * with `lithium\core\Libraries::map()`.
-	 *
-	 * @var array
-	 * @see lithium\core\Libraries::map()
-	 * @see lithium\core\Libraries::unmap()
-	 */
-	protected static $_map = array();
-
-	/**
-	 * Accessor method for the class path templates which `Libraries` uses to look up and load
-	 * classes. Using this method, you can define your own types of classes, or modify the default
-	 * organization of built-in class types.
-	 *
-	 * For example, in a queuing application, you can define a class type called `'job'`:
-	 * {{{
-	 * Libraries::paths(array('job' => '{:library}\extensions\job\{:name}'));
-	 * }}}
-	 *
-	 * Then, any classes you add to the `extensions/job` directory in your application will be
-	 * automatically detected when calling `Libraries::locate('job')`. Additionally, any matching
-	 * classes in the `extensions/job` directory of any plugin or vendor library you add to your
-	 * application will also be detected.
-	 *
-	 * Supposing you wanted to have the option of further organizing jobs by class type (some jobs
-	 * are related to updating caches, others to sending notifications, etc.), you can specify
-	 * multiple paths per class type, with varying levels of specificity:
-	 * {{{
-	 * Libraries::paths(array('job' => array(
-	 * 	'{:library}\extensions\job\{:class}\{:name}',
-	 * 	'{:library}\extensions\job\{:name}'
-	 * )));
-	 * }}}
-	 *
-	 * This allows you to, for example, have two different classes called `Cleanup`. One may be
-	 * located in `app\extensions\job\Cleanup`, while the other is in
-	 * `app\extensions\job\cache\Cleanup`. Calling: {{{Libraries::locate('job');}}} will find
-	 * both classes, while {{{Libraries::locate('job.cache');}}} will only find the second. You can
-	 * also find individual jobs by name: {{{Libraries::locate('job', 'Cleanup');}}}
-	 *
-	 * See `Libraries::locate()` for more information on using built-in and user-defined paths to
-	 * look up classes.
-	 *
-	 * In addition to adding custom class types, `paths()` allows you to redefine the naming and
-	 * organization of existing types. For example, if you wished to reference your model classes
-	 * as `app\models\PostModel` instead of `app\models\Post`, you can do the following:
-	 * {{{Libraries::paths(array('models' => '{:library}\models\{:name}Model'));}}} Note, however,
-	 * that this is a destructive, not an additive operation, and will replace any existing paths
-	 * defined for that type. If you wish to add a search path for an existing type, you must do
-	 * the following:
-	 * {{{
-	 * $existing = Libraries::paths('controllers');
-	 * Libraries::paths(array('controller' => array_merge(
-	 * 	array('{:library}\extensions\controllers\{:name}Controller'), (array) $existing
-	 * )));
-	 * }}}
-	 *
-	 * @see lithium\core\Libraries::locate()
-	 * @see lithium\core\Libraries::$_paths
-	 * @param mixed $path If `$path` is a string, returns the path(s) associated with that path
-	 *              type, or `null` if no paths are defined for that type.
-	 * @return mixed
-	 */
-	public static function paths($path = null) {
-		if (empty($path)) {
-			return static::$_paths;
-		}
-		if (is_string($path)) {
-			return isset(static::$_paths[$path]) ? static::$_paths[$path] : null;
-		}
-		static::$_paths = array_filter(array_merge(static::$_paths, (array) $path));
-	}
-
-	/**
-	 * Adds a class library from which files can be loaded.
-	 *
-	 * The `add()` method registers a named library configuration to your application, and is used
-	 * to allow the framework to auto-load classes on an as-needed basis.
-	 *
-	 * ### Adding libraries to your application
-	 *
-	 * In Lithium, libraries represent the broadest unit of class organization in an application,
-	 * and _everything_ is a library; this includes your application, and the Lithium framework
-	 * itself. Libraries can also be other frameworks, like Solar, Zend Framework or PEAR, or
-	 * Lithium plugins, which are simply libraries that follow the same organizational standards
-	 * as Lithium applications.
-	 *
-	 * By convention, libraries are placed in the `libraries` directory inside your application, or
-	 * the root `libraries` directory at the top level of the default distribution (i.e. the one
-	 * that contains the `lithium` directory), however, you can change this on a case-by-case basis
-	 * using the `'path'` key to specify an absolute path to the library's directory.
-	 *
-	 * @param string $name Library name, i.e. `'app'`, `'lithium'`, `'pear'` or `'aura'`.
-	 * @param array $config Specifies where the library is in the filesystem, and how classes
-	 *        should be loaded from it.  Allowed keys are:
-	 *        - `'bootstrap'` _mixed_: A file path (relative to `'path'`) to a bootstrap script that
-	 *          should be run when the library is added, or `true` to use the default bootstrap
-	 *          path, i.e. `config/bootstrap.php`.
-	 *        - `'defer'` _boolean_: If `true`, indicates that, when locating classes, this library
-	 *          should defer to other libraries in order of preference.
-	 *        - `'includePath'` _mixed_: If `true`, appends the absolutely-resolved value of
-	 *          `'path'` to the PHP include path. If a string, the value is appended to PHP's.
-	 *        - `'loader'`: An auto-loader method associated with the library, if any.
-	 *        - `'path'`: The directory containing the library.
-	 *        - `'prefix'` _string_: The class prefix this library uses, i.e. `'lithium\'`,
-	 *          `'Zend_'` or `'Solar_'`. If the library has no global prefix, set to `false`.
-	 *        - `'suffix'` _string_: Gets appended to the end of the file name. For example, most
-	 *          libraries end classes in `'.php'`, but some use `'.class.php'`, or `'.inc.php'`.
-	 *        - `'transform'` _closure_: Defines a custom way to transform a class name into its
-	 *          corresponding file path.  Accepts either an array of two strings which are
-	 *          interpreted as the pattern and replacement for a regex, or an anonymous function,
-	 *          which receives the class name and library configuration arrays as parameters, and
-	 *          returns the full physical file path as output.
-	 *        - `'resources'` _string_: If this is the default library, this maybe set to the
-	 *          absolute path to the write-enabled application resources directory, which is used
-	 *          for caching, log files, uploads, etc.
-	 * @return array Returns the resulting set of options created for this library.
-	 */
-	public static function add($name, array $config = array()) {
-		$defaults = array(
-			'path' => null,
-			'prefix' => $name . "\\",
-			'suffix' => '.php',
-			'loader' => null,
-			'includePath' => false,
-			'transform' => null,
-			'bootstrap' => true,
-			'defer' => false,
-			'default' => false
-		);
-		if ($name === 'lithium') {
-			$defaults['defer'] = true;
-			$defaults['bootstrap'] = false;
-			$defaults['path'] = dirname(__DIR__);
-			$defaults['loader'] = 'lithium\core\Libraries::load';
-		}
-		if (isset($config['default']) && $config['default']) {
-			static::$_default = $name;
-			$defaults['path'] = LITHIUM_APP_PATH;
-			$defaults['bootstrap'] = false;
-			$defaults['resources'] = LITHIUM_APP_PATH . '/resources';
-		}
-		$config += $defaults;
-
-		if (!$config['path']) {
-			if (!$config['path'] = static::_locatePath('libraries', compact('name'))) {
-				throw new ConfigException("Library `{$name}` not found.");
-			}
-		}
-		$config['path'] = str_replace('\\', '/', $config['path']);
-		static::_configure(static::$_configurations[$name] = $config);
-		return $config;
-	}
-
-	/**
-	 * Configures the application environment based on a library's settings, including appending to
-	 * the include path, loading a bootstrap file, and registering a loader with SPL's autoloading
-	 * system.
-	 *
-	 * @param array $config The new library's configuration array.
-	 * @return void
-	 */
-	protected static function _configure($config) {
-		if ($config['includePath']) {
-			$path = ($config['includePath'] === true) ? $config['path'] : $config['includePath'];
-			set_include_path(get_include_path() . PATH_SEPARATOR . $path);
-		}
-		if ($config['bootstrap'] === true) {
-			$path = "{$config['path']}/config/bootstrap.php";
-			$config['bootstrap'] = file_exists($path) ? 'config/bootstrap.php' : false;
-		}
-		if ($config['bootstrap']) {
-			require "{$config['path']}/{$config['bootstrap']}";
-		}
-		if (!empty($config['loader'])) {
-			spl_autoload_register($config['loader']);
-		}
-	}
-
-	/**
-	 * Allows library information to be retrieved in various ways, including:
-	 *
-	 * By name:
-	 * {{{ embed:lithium\tests\cases\core\LibrariesTest::testLibraryConfigAccess(1-1) }}}
-	 *
-	 * With no parameters, to return all configuration for all libraries:
-	 * {{{ embed:lithium\tests\cases\core\LibrariesTest::testLibraryConfigAccess(22-22) }}}
-	 *
-	 * By list of names with a key to extract:
-	 * {{{ embed:lithium\tests\cases\core\LibrariesTest::testLibraryConfigAccess(34-34) }}}
-	 *
-	 * With no name, and a key to extract, to return a key/value array, where the library name is
-	 * the key, and the `$key` value is the value:
-	 * {{{ embed:lithium\tests\cases\core\LibrariesTest::testLibraryConfigAccess(37-37) }}}
-	 *
-	 * By containing class name:
-	 * {{{ embed:lithium\tests\cases\core\LibrariesTest::testLibraryConfigAccess(45-45) }}}
-	 *
-	 * @param mixed $name Either the name of a library added in `Libraries::add()`, an array of
-	 *              library names, or a fully-namespaced class name (see usage examples above).
-	 * @param string $key Optional key name. If `$name` is set and is the name of a valid library
-	 *               (or an array of valid libraries), returns the given named configuration key,
-	 *               i.e. `'path'`, `'webroot'` or `'resources'`.
-	 * @return mixed A configuation array for one or more libraries, or a string value if `$key` is
-	 *               specified and `$name` is a string, or a library name (string) if `$name` is a
-	 *               fully-namespaced class name.
-	 */
-	public static function get($name = null, $key = null) {
-		$configs = static::$_configurations;
-
-		if (!$name && !$key) {
-			return $configs;
-		}
-		if ($name === true) {
-			$name = static::$_default;
-		}
-		if (is_array($name) || (!$name && $key)) {
-			$name = $name ?: array_keys(static::$_configurations);
-			$call = array(get_called_class(), 'get');
-			return array_combine($name, array_map($call, $name, array_fill(0, count($name), $key)));
-		}
-		$config = isset($configs[$name]) ? $configs[$name] : null;
-
-		if ($key) {
-			return isset($config[$key]) ? $config[$key] : null;
-		}
-		if (strpos($name, '\\') === false) {
-			return $config;
-		}
-		foreach (static::$_configurations as $library => $config) {
-			if ($config['prefix'] && strpos($name, $config['prefix']) === 0) {
-				return $library;
-			}
-		}
-	}
-
-	/**
-	 * Removes a registered library, and unregister's the library's autoloader, if it has one.
-	 *
-	 * @param mixed $name A string or array of library names indicating the libraries you wish to
-	 *        remove, i.e. `'app'` or `'lithium'`. This can also be used to unload plugins by  name.
-	 * @return void
-	 */
-	public static function remove($name) {
-		foreach ((array) $name as $library) {
-			if (isset(static::$_configurations[$library])) {
-				if (static::$_configurations[$library]['loader']) {
-					spl_autoload_unregister(static::$_configurations[$library]['loader']);
-				}
-				unset(static::$_configurations[$library]);
-			}
-		}
-	}
-
-	/**
-	 * Finds the classes or namespaces belonging to a particular library. _Note_: This method
-	 * assumes loaded class libraries use a consistent class-to-file naming convention.
-	 *
-	 * @param mixed $library The name of a library added to the application with `Libraries::add()`,
-	 *              or `true` to search all libraries.
-	 * @param array $options The options this method accepts:
-	 *
-	 *              - `'path'` _string_: A physical filesystem path relative to the directory of the
-	 *                library being searched. If provided, only the classes or namespaces within
-	 *                this path will be returned.
-	 *              - `'recursive'` _boolean_: If `true`, recursively searches all directories
-	 *                (namespaces) in the given library. If `false` (the default), only searches the
-	 *                top level of the given path.
-	 *              - `'filter'` _string_: A regular expression applied to a class after it is
-	 *                transformed into a fully-namespaced class name. The default regular expression
-	 *                filters class names based on the
-	 *                [PSR-0](http://groups.google.com/group/php-standards/web/psr-0-final-proposal)
-	 *                PHP 5.3 naming standard.
-	 *              - `'exclude'` _mixed_: Can be either a regular expression of classes/namespaces
-	 *                to exclude, or a PHP callable to be used with `array_filter()`.
-	 *              - `'namespaces'` _boolean_: Indicates whether namespaces should be included in
-	 *                the search results. If `false` (the default), only classes are returned.
-	 * @return array Returns an array of fully-namespaced class names found in the given library or
-	 *         libraries.
-	 * @todo Patch this to skip paths belonging to nested libraries in recursive searches.
-	 */
-	public static function find($library, array $options = array()) {
-		$format = function($file, $config) {
-			$trim = array(strlen($config['path']) + 1, strlen($config['suffix']));
-			$rTrim = strpos($file, $config['suffix']) !== false ? -$trim[1] : 9999;
-			$file = preg_split('/[\/\\\\]/', substr($file, $trim[0], $rTrim));
-			return $config['prefix'] . join('\\', $file);
-		};
-
-		$defaults = compact('format') + array(
-			'path' => '',
-			'recursive' => false,
-			'filter' => '/^(\w+)?(\\\\[a-z0-9_]+)+\\\\[A-Z][a-zA-Z0-9]+$/',
-			'exclude' => '',
-			'namespaces' => false
-		);
-		$options += $defaults;
-		$libs = array();
-
-		if ($options['namespaces'] && $options['filter'] === $defaults['filter']) {
-			$options['format'] = function($class, $config) use ($format, $defaults) {
-				if (is_dir($class)) {
-					return $format($class, $config);
-				}
-				if (preg_match($defaults['filter'], $class = $format($class, $config))) {
-					return $class;
-				}
-			};
-			$options['filter'] = false;
-		}
-		if ($library === true) {
-			foreach (static::$_configurations as $library => $config) {
-				$libs = array_merge($libs, static::find($library, $options));
-			}
-			return $libs;
-		}
-		if (!isset(static::$_configurations[$library])) {
-			return null;
-		}
-
-		$config = static::$_configurations[$library];
-		$options['path'] = "{$config['path']}{$options['path']}/*";
-		$libs = static::_search($config, $options);
-		return array_values(array_filter($libs));
-	}
-
-	/**
-	 * Loads the class definition specified by `$class`. Also calls the `__init()` method on the
-	 * class, if defined.  Looks through the list of libraries defined in `$_configurations`, which
-	 * are added through `lithium\core\Libraries::add()`.
-	 *
-	 * @see lithium\core\Libraries::add()
-	 * @see lithium\core\Libraries::path()
-	 * @param string $class The fully-namespaced (where applicable) name of the class to load.
-	 * @param boolean $require Specifies whether the class must be loaded or considered an
-	 *        exception. Defaults to `false`.
-	 * @return void
-	 */
-	public static function load($class, $require = false) {
-		$path = isset(static::$_cachedPaths[$class]) ? static::$_cachedPaths[$class] : null;
-		$path = $path ?: static::path($class);
-
-		if ($path && include $path) {
-			static::$_cachedPaths[$class] = $path;
-			method_exists($class, '__init') ? $class::__init() : null;
-		} elseif ($require) {
-			throw new RuntimeException("Failed to load class `{$class}` from path `{$path}`.");
-		}
-	}
-
-	/**
-	 * Associtates fully-namespaced class names to their corresponding paths on
-	 * the file system.
-	 *
-	 * Once a class is associtated to a path using `lithium\core\Libraries::map()`
-	 * the PSR-0 loader or custom class loader setted using the `transform` or `loader`
-	 * option of `lithium\core\Libraries::add()` are ignored and the associtated path
-	 * is used instead.
-	 *
-	 * @param array $classes An array of fully-namespaced class names (as keys) and
-	 *        their correponding file's paths (as values).
-	 * @return void
-	 */
-	public static function map(array $classes) {
-		foreach ($classes as $key => $value) {
-			unset(static::$_cachedPaths[$key]);
-		}
-		static::$_map = array_merge(static::$_map, $classes);
-	}
-
-	/**
-	 * Unmap fully-namespaced class names mapped using `lithium\core\Libraries::map()`.
-	 *
-	 * @see lithium\core\Libraries::map()
-	 * @param mixed $classes An array of fully-namespaced class names or
-	 *        a string with a fully-namespaced class name.
-	 */
-	public static function unmap($classes) {
-		if (!is_array($classes)) {
-			$classes = array($classes);
-		}
-		foreach ($classes as $value) {
-			unset(static::$_map[$value]);
-		}
-	}
-
-	/**
-	 * Get the corresponding physical file path for a class or namespace name.
-	 *
-	 * @param string $class The class name to locate the physical file for. If `$options['dirs']` is
-	 *        set to `true`, `$class` may also be a namespace name, in which case the corresponding
-	 *        directory will be located.
-	 * @param array $options Options for converting `$class` to a physical path:
-	 *        - `'dirs'`: Defaults to `false`. If `true`, will attempt to case-sensitively look up
-	 *          directories in addition to files (in which case `$class` is assumed to actually be a
-	 *          namespace).
-	 * @return string Returns the absolute path to the file containing `$class`, or `null` if the
-	 *         file cannot be found.
-	 */
-	public static function path($class, array $options = array()) {
-		$defaults = array('dirs' => false);
-		$options += $defaults;
-		$class = ltrim($class, '\\');
-
-		if (isset(static::$_cachedPaths[$class]) && !$options['dirs']) {
-			return static::$_cachedPaths[$class];
-		}
-		if (isset(static::$_map[$class]) && !$options['dirs']) {
-			return static::$_map[$class];
-		}
-		foreach (static::$_configurations as $name => $config) {
-			$params = $options + $config;
-			$suffix = $params['suffix'];
-
-			if ($params['prefix'] && strpos($class, $params['prefix']) !== 0) {
-				continue;
-			}
-			if ($transform = $params['transform']) {
-				if ($file = static::_transformPath($transform, $class, $params)) {
-					return $file;
-				}
-				continue;
-			}
-			$path = str_replace("\\", '/', substr($class, strlen($params['prefix'])));
-			$fullPath = "{$params['path']}/{$path}";
-
-			if (!$options['dirs']) {
-				return static::$_cachedPaths[$class] = static::realPath($fullPath . $suffix);
-			}
-			$list = glob(dirname($fullPath) . '/*');
-			$list = array_map(function($i) { return str_replace('\\', '/', $i); }, $list);
-
-			if (in_array($fullPath . $suffix, $list)) {
-				return static::$_cachedPaths[$class] = static::realPath($fullPath . $suffix);
-			}
-			return is_dir($fullPath) ? static::realPath($fullPath) : null;
-		}
-	}
-
-	/**
-	 * Wraps the PHP `realpath()` function to add support for finding paths to files inside Phar
-	 * archives.
-	 *
-	 * @param string $path An unresolved path to a file inside a Phar archive which may or may not
-	 *               exist.
-	 * @return string If `$path` is a valid path to a file inside a Phar archive, returns a string
-	 *                in the format `'phar://<path-to-phar>/<path-to-file>'`. Otherwise returns
-	 *                `null`.
-	 */
-	public static function realPath($path) {
-		if (($absolutePath = realpath($path)) !== false) {
-			return $absolutePath;
-		}
-		if (!preg_match('%^phar://([^.]+\.phar(?:\.gz)?)(.+)%', $path, $pathComponents)) {
-			return;
-		}
-		list(, $relativePath, $pharPath) = $pathComponents;
-
-		$pharPath = implode('/', array_reduce(explode('/', $pharPath), function ($parts, $value) {
-			if ($value === '..') {
-				array_pop($parts);
-			} elseif ($value !== '.') {
-				$parts[] = $value;
-			}
-			return $parts;
-		}));
-
-		if (($resolvedPath = realpath($relativePath)) !== false) {
-			if (file_exists($absolutePath = "phar://{$resolvedPath}{$pharPath}")) {
-				return $absolutePath;
-			}
-		}
-	}
-
-	/**
-	 * Handles the conversion of a class name to a file name using a custom transformation typically
-	 * defined in the `'transform'` key of a configuration defined through `Libraries::add()`.
-	 *
-	 * The transformation can either be a closure which receives two parameters (the class name
-	 * as a string, and the library configuration as an array), or an array with two values (one
-	 * being the pattern to match, the other being the replacement).
-	 *
-	 * @see lithium\core\Libraries::add()
-	 * @see lithium\core\Libraries::path()
-	 * @param mixed $transform Either a closure or an array containing a regular expression match
-	 *              and replacement. If the closure returns an empty value, or the regular
-	 *              expression fails to match, will return `null`.
-	 * @param string $class The class name which is attempting to be mapped to a file.
-	 * @param array $options The configuration of the library as passed to `Libraries::add()`, along
-	 *              with any options specified in the call to `Libraries::path()`.
-	 * @return string Returns transformed path of a class to a file, or `null` if the transformation
-	 *         did not match.
-	 */
-	protected static function _transformPath($transform, $class, array $options = array()) {
-		if ((is_callable($transform)) && $file = $transform($class, $options)) {
-			return $file;
-		}
-		if (is_array($transform)) {
-			list($match, $replace) = $transform;
-			return preg_replace($match, $replace, $class) ?: null;
-		}
-	}
-
-	/**
-	 * Uses service location (i.e. `Libraries::locate()`) to look up a named class of a particular
-	 * type, and creates an instance of it, and passes an array of parameters to the constructor.
-	 *
-	 * If the given class can't be found, an exception is thrown.
-	 *
-	 * @param string $type The type of class as defined by `Libraries::$_paths`.
-	 * @param string $name The un-namespaced name of the class to instantiate.
-	 * @param array $options An array of constructor parameters to pass to the class.
-	 * @return object If the class is found, returns an instance of it, otherwise throws an
-	 *         exception.
-	 * @throws lithium\core\ClassNotFoundException Throws an exception if the class can't be found.
-	 * @filter
-	 */
-	public static function instance($type, $name, array $options = array()) {
-		$params = compact('type', 'name', 'options');
-		$_paths =& static::$_paths;
-
-		$implementation = function($self, $params) use (&$_paths) {
-			$name = $params['name'];
-			$type = $params['type'];
-
-			if (!$name && !$type) {
-				$message = "Invalid class lookup: `\$name` and `\$type` are empty.";
-				throw new ClassNotFoundException($message);
-			}
-			if (!is_string($type) && $type !== null && !isset($_paths[$type])) {
-				throw new ClassNotFoundException("Invalid class type `{$type}`.");
-			}
-			if (!$class = $self::locate($type, $name)) {
-				throw new ClassNotFoundException("Class `{$name}` of type `{$type}` not found.");
-			}
-			if (is_object($class)) {
-				return $class;
-			}
-			if (!(is_string($class) && class_exists($class))) {
-				throw new ClassNotFoundException("Class `{$name}` of type `{$type}` not defined.");
-			}
-			return new $class($params['options']);
-		};
-		if (!isset(static::$_methodFilters[__FUNCTION__])) {
-			return $implementation(get_called_class(), $params);
-		}
-		$class = get_called_class();
-		$method = __FUNCTION__;
-		$data = array_merge(static::$_methodFilters[__FUNCTION__], array($implementation));
-		return Filters::run($class, $params, compact('data', 'class', 'method'));
-	}
-
-	/**
-	 * Apply a closure to a method in `Libraries`.
-	 *
-	 * @see lithium\util\collection\Filters
-	 * @param string $method The name of the method to apply the closure to.
-	 * @param closure $filter The closure that is used to filter the method.
-	 * @return void
-	 */
-	public static function applyFilter($method, $filter = null) {
-		if (!isset(static::$_methodFilters[$method])) {
-			static::$_methodFilters[$method] = array();
-		}
-		static::$_methodFilters[$method][] = $filter;
-	}
-
-	/**
-	 * Performs service location for an object of a specific type. If `$name` is a string, finds the
-	 * first instance of a class with the given name in any registered library (i.e. apps, plugins
-	 * or vendor libraries registered via `Libraries::add()`), based on each library's order of
-	 * precedence. For example, this will find the first model called `File` in any plugin or class
-	 * library loaded into an application, including the application itself.
-	 *
-	 * {{{Libraries::locate('models', 'File');}}}
-	 *
-	 * Order of precedence is usually based on the order in which the library was registered (via
-	 * `Libraries::add()`), unless the library was registered with the `'defer'` option set to
-	 * `true`. All libraries with the `'defer'` option set will be searched in
-	 * registration-order **after** searching all libraries **without** `'defer'` set. This means
-	 * that in the above example, if an app and a plugin both have a model named `File`, then the
-	 * model from the app will be returned first, assuming the app was registered first (and
-	 * assuming the default settings).
-	 *
-	 * If `$name` is not specified, `locate()` returns an array with all classes of the specified
-	 * type which can be found. By default, `locate()` searches all registered libraries.
-	 *
-	 * {{{Libraries::locate('models');}}}
-	 *
-	 * For example, the above will return an array of all model classes in all registered plugins
-	 * and libraries (including the app itself).
-	 *
-	 * To learn more about adding and modifying the class paths used with `locate()`, see the
-	 * documentation for the `paths()` method.
-	 *
-	 * @see lithium\core\Libraries::paths()
-	 * @see lithium\core\Libraries::add()
-	 * @see lithium\core\Libraries::_locateDeferred()
-	 * @param string $type The type of class to search for. Typically follows the name of the
-	 *               directory in which the class is stored, i.e. `'models'`, `'controllers'` or
-	 *               `'adapter'`. Some classes types, such as adapters, will require a greater
-	 *               degree of specificity when looking up the desired class. In this case, the dot
-	 *               syntax is used, as in this example when looking up cache adapters:
-	 *               `'adapter.storage.cache'`, or this example, when looking up authentication
-	 *               adapters: `'adapter.security.auth'`.
-	 * @param string $name The base name (without namespace) of the class you wish to locate. If
-	 *               unspecified, `locate()` will attempt to find all classes of the type specified
-	 *               in `$type`. If you only wish to search for classes within a single plugin or
-	 *               library, you may use the dot syntax to prefix the class name with the library
-	 *               name, i.e. `'app.Post'`, which will only look for a `Post` model within the
-	 *               app itself.
-	 * @param array $options The options to use when searching and returning class names.
-	 *              - `'type'` _string_: Defaults to `'class'`. If set to `'file'`, returns file
-	 *                names instead of class names.
-	 *              - `'library'` _string_: When specified, only the given library/plugin name will
-	 *                be searched.
-	 * @return mixed If `$name` is specified, returns the name of the first class found that matches
-	 *         `$name` and `$type`, or returns `null` if no matching classes were found in any
-	 *         registered library. If `$name` is not specified, returns an array of all classes
-	 *         found which match `$type`.
-	 */
-	public static function locate($type, $name = null, array $options = array()) {
-		if (is_object($name) || strpos($name, '\\') !== false) {
-			return $name;
-		}
-		$ident = $name ? ($type . '.' . $name) : ($type . '.*');
-		$ident .= $options ? '.' . md5(serialize($options)) : null;
-
-		if (isset(static::$_cachedPaths[$ident])) {
-			return static::$_cachedPaths[$ident];
-		}
-		$params = static::_params($type, $name);
-		$defaults = array(
-			'type' => 'class',
-			'library' => $params['library'] !== '*' ? $params['library'] : null
-		);
-		$options += $defaults;
-		unset($params['library']);
-		$paths = static::paths($params['type']);
-
-		if (!isset($paths)) {
-			return null;
-		}
-		if ($params['name'] === '*') {
-			$result = static::_locateAll($params, $options);
-			return (static::$_cachedPaths[$ident] = $result);
-		}
-		if ($options['library']) {
-			$result = static::_locateDeferred(null, $paths, $params, $options);
-			return static::$_cachedPaths[$ident] = $result;
-		}
-		foreach (array(false, true) as $defer) {
-			if ($result = static::_locateDeferred($defer, $paths, $params, $options)) {
-				return (static::$_cachedPaths[$ident] = $result);
-			}
-		}
-	}
-
-	/**
-	 * Returns or sets the the class path cache used for mapping class names to file paths, or
-	 * locating classes using `Libraries::locate()`.
-	 *
-	 * @param array $cache An array of keys and values to use when pre-populating the cache. Keys
-	 *              are either class names (which match to file paths as values), or dot-separated
-	 *              lookup paths used by `locate()` (which matches to either a single class or an
-	 *              array of classes). If `false`, the cache is cleared.
-	 * @return array Returns an array of cached class lookups, formatted per the description for
-	 *         `$cache`.
-	 */
-	public static function cache($cache = null) {
-		if ($cache === false) {
-			static::$_cachedPaths = array();
-		}
-		if (is_array($cache)) {
-			static::$_cachedPaths += $cache;
-		}
-		return static::$_cachedPaths;
-	}
-
-	/**
-	 * Performs service location lookups by library, based on the library's `'defer'` flag.
-	 * Libraries with `'defer'` set to `true` will be searched last when looking up services.
-	 *
-	 * @see lithium\core\Libraries::$_paths
-	 * @see lithium\core\Libraries::locate()
-	 * @param boolean $defer A boolean flag indicating which libraries to search, either the ones
-	 *        with the `'defer'` flag set, or the ones without.
-	 * @param array $paths List of paths to be searched for the given service (class).  These are
-	 *        defined in `lithium\core\Libraries::$_paths`, and are organized by class type.
-	 * @param array $params The list of insert parameters to be injected into each path format
-	 *        string when searching for classes.
-	 * @param array $options
-	 * @return string Returns a class path as a string if a given class is found, or null if no
-	 *         class in any path matching any of the parameters is located.
-	 */
-	protected static function _locateDeferred($defer, $paths, $params, array $options = array()) {
-		$libraries = static::$_configurations;
-
-		if (isset($options['library'])) {
-			$libraries = static::get((array) $options['library']);
-		}
-		foreach ($libraries as $library => $config) {
-			if ($config['defer'] !== $defer && $defer !== null) {
-				continue;
-			}
-
-			foreach (static::_searchPaths($paths, $library, $params) as $tpl) {
-				$params['library'] = rtrim($config['prefix'], '\\');
-				$class = str_replace('\\*', '', String::insert($tpl, $params));
-
-				if (file_exists($file = Libraries::path($class, $options))) {
-					return ($options['type'] === 'file') ? $file : $class;
-				}
-			}
-		}
-	}
-
-	/**
-	 * Returns the list of valid search path templates for the given service location lookup.
-	 *
-	 * @see lithium\core\Libraries::$_paths
-	 * @see lithium\core\Libraries::_search()
-	 * @param array $paths The list of all possible path templates from `Libraries::$_paths`.
-	 * @param string $library The name of the library being searched.
-	 * @param array $params The parameters used in the service location lookup.
-	 * @return array Returns an array of valid path template strings.
-	 */
-	protected static function _searchPaths($paths, $library, $params) {
-		$result = array();
-		$params = array('library' => null, 'type' => null) + $params;
-
-		foreach ($paths as $tpl => $opts) {
-			if (is_int($tpl)) {
-				$tpl = $opts;
-				$opts = array();
-			}
-			if (isset($opts['libraries']) && !in_array($library, (array) $opts['libraries'])) {
-				continue;
-			}
-			$result[] = $tpl;
-		}
-		return $result;
-	}
-
-	/**
-	 * Locates all possible classes for given set of parameters.
-	 *
-	 * @param array $params
-	 * @param array $options
-	 * @return array
-	 */
-	protected static function _locateAll(array $params, array $options = array()) {
-		$defaults = array('libraries' => null, 'recursive' => true, 'namespaces' => false);
-		$options += $defaults;
-
-		$paths = (array) static::$_paths[$params['type']];
-		$libraries = $options['library'] ? $options['library'] : $options['libraries'];
-		$libraries = static::get((array) $libraries);
-		$flags = array('escape' => '/');
-		$classes = array();
-
-		foreach ($libraries as $library => $config) {
-			$params['library'] = $config['path'];
-
-			foreach (static::_searchPaths($paths, $library, $params) as $tpl) {
-				$options['path'] = str_replace('\\', '/', String::insert($tpl, $params, $flags));
-				$options['path'] = str_replace('*/', '', $options['path']);
-				$classes = array_merge($classes, static::_search($config, $options));
-			}
-		}
-		return array_unique($classes);
-	}
-
-	/**
-	 * Helper function for returning known paths given a certain type.
-	 *
-	 * @see lithium\core\Libraries::$_paths
-	 * @param string $type Path type (specified in `Libraries::$_paths`).
-	 * @param string $params Path parameters.
-	 * @return string Valid path name.
-	 */
-	protected static function _locatePath($type, $params) {
-		if (!isset(static::$_paths[$type])) {
-			return;
-		}
-		$params += array('app' => LITHIUM_APP_PATH, 'root' => LITHIUM_LIBRARY_PATH);
-
-		foreach (static::$_paths[$type] as $path) {
-			if (is_dir($path = str_replace('\\', '/', String::insert($path, $params)))) {
-				return $path;
-			}
-		}
-	}
-
-	/**
-	 * Search file system.
-	 *
-	 * @param string $config
-	 * @param string $options
-	 * @param string $name
-	 * @return array
-	 */
-	protected static function _search($config, $options, $name = null) {
-		$defaults = array(
-			'path' => null,
-			'suffix' => null,
-			'namespaces' => false,
-			'recursive' => false,
-			'preFilter' => '/[A-Z][A-Za-z0-9]+\./',
-			'filter' => false,
-			'exclude' => false,
-			'format' => function ($file, $config) {
-				$trim = array(strlen($config['path']) + 1, strlen($config['suffix']));
-				$file = substr($file, $trim[0], -$trim[1]);
-				return $config['prefix'] . str_replace('/', '\\', $file);
-			}
-		);
-		$options += $defaults;
-		$path = $options['path'];
-		$suffix = $options['namespaces'] ? '' : $config['suffix'];
-		$suffix = ($options['suffix'] === null) ? $suffix : $options['suffix'];
-
-		$dFlags = GLOB_ONLYDIR & GLOB_BRACE;
-		$libs = (array) glob($path . $suffix, $options['namespaces'] ? $dFlags : GLOB_BRACE);
-
-		if ($options['recursive']) {
-			list($current, $match) = explode('/*', $path, 2);
-			$dirs = $queue = array_diff((array) glob($current . '/*', $dFlags), $libs);
-			$match = str_replace('##', '.+', preg_quote(str_replace('*', '##', $match), '/'));
-			$match = '/' . $match . preg_quote($suffix, '/') . '$/';
-
-			while ($queue) {
-				if (!is_dir($dir = array_pop($queue))) {
-					continue;
-				}
-				$libs = array_merge($libs, (array) glob("{$dir}/*{$suffix}"));
-				$queue = array_merge($queue, array_diff((array) glob("{$dir}/*", $dFlags), $libs));
-			}
-			$libs = preg_grep($match, $libs);
-		}
-		if ($suffix) {
-			$libs = $options['preFilter'] ? preg_grep($options['preFilter'], $libs) : $libs;
-		}
-		return static::_filter($libs, (array) $config, $options + compact('name'));
-	}
-
-	/**
-	 * Filters a list of library search results by the given set of options.
-	 *
-	 * @param array $libs List of found libraries.
-	 * @param array $config The configuration of the library currently being searched within.
-	 * @param array $options The options used to filter/format `$libs`.
-	 * @return array Returns a copy of `$libs`, filtered and transformed based on the configuration
-	 *         provided in `$options`.
-	 */
-	protected static function _filter($libs, array $config, array $options = array()) {
-		if (is_callable($options['format'])) {
-			foreach ($libs as $i => $file) {
-				$libs[$i] = $options['format']($file, $config);
-			}
-			$libs = $options['name'] ? preg_grep("/{$options['name']}$/", $libs) : $libs;
-		}
-		if ($exclude = $options['exclude']) {
-			if (is_string($exclude)) {
-				$libs = preg_grep($exclude, $libs, PREG_GREP_INVERT);
-			} elseif (is_callable($exclude)) {
-				$libs = array_values(array_filter($libs, $exclude));
-			}
-		}
-		if ($filter = $options['filter']) {
-			if (is_string($filter)) {
-				$libs = preg_grep($filter, $libs) ;
-			} elseif (is_callable($filter)) {
-				$libs = array_filter(array_map($filter, $libs));
-			}
-		}
-		return $libs;
-	}
-
-	/**
-	 * Get params from type.
-	 *
-	 * @param string $type
-	 * @param string $name default: '*'
-	 * @return array type, namespace, class, name
-	 */
-	protected static function _params($type, $name = "*") {
-		if (!$name) {
-			$name = '*';
-		}
-		$library = $namespace = $class = '*';
-
-		if (strpos($type, '.') !== false) {
-			$parts = explode('.', $type);
-			$type = array_shift($parts);
-
-			switch (count($parts)) {
-				case 1:
-					list($class) = $parts;
-				break;
-				case 2:
-					list($namespace, $class) = $parts;
-				break;
-				default:
-					$class = array_pop($parts);
-					$namespace = join('\\', $parts);
-				break;
-			}
-		}
-		if (strpos($name, '.') !== false) {
-			$parts = explode('.', $name);
-			$library = array_shift($parts);
-			$name = array_pop($parts);
-			$namespace = $parts ? join('\\', $parts) : "*";
-		}
-		return compact('library', 'namespace', 'type', 'class', 'name');
-	}
-}
-
-?>

+ 0 - 21
frameworks/PHP/php-lithium/libraries/lithium/core/NetworkException.php

@@ -1,21 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-/**
- * A `NetworkException` may be thrown whenever an unsuccessful attempt is made to connect to a
- * remote service over the network. This may be a web service, a database, or another network
- * resource.
- */
-class NetworkException extends \RuntimeException {
-
-	protected $code = 503;
-}
-
-?>

+ 0 - 292
frameworks/PHP/php-lithium/libraries/lithium/core/Object.php

@@ -1,292 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-use lithium\core\Libraries;
-use lithium\util\collection\Filters;
-use lithium\analysis\Inspector;
-
-/**
- * Base class in Lithium's hierarchy, from which all concrete classes inherit. This class defines
- * several conventions for how classes in Lithium should be structured:
- *
- * - **Universal constructor**: Any class which defines a `__construct()` method should take
- *   exactly one parameter (`$config`), and that parameter should always be an array. Any settings
- *   passed to the constructor will be stored in the `$_config` property of the object.
- * - **Initialization / automatic configuration**: After the constructor, the `_init()` method is
- *   called. This method can be used to initialize the object, keeping complex logic and
- *   high-overhead or difficult to test operations out of the constructor. This method is called
- *   automatically by `Object::__construct()`, but may be disabled by passing `'init' => false` to
- *   the constructor. The initializer is also used for automatically assigning object properties.
- *   See the documentation on the `_init()` method for more details.
- * - **Filters**: The `Object` class implements two methods which allow an object to easily
- *   implement filterable methods. The `_filter()` method allows methods to be implemented as
- *   filterable, and the `applyFilter()` method allows filters to be wrapped around them.
- * - **Testing / misc.**: The `__set_state()` method provides a default implementation of the PHP
- *   magic method (works with `var_export()`) which can instantiate an object with a static method
- *   call. Finally, the `_stop()` method may be used instead of `exit()`, as it can be overridden
- *   for testing purposes.
- *
- * @see lithium\core\StaticObject
- */
-class Object {
-
-	/**
-	 * Stores configuration information for object instances at time of construction.
-	 * **Do not override.** Pass any additional variables to `parent::__construct()`.
-	 *
-	 * @var array
-	 */
-	protected $_config = array();
-
-	/**
-	 * Holds an array of values that should be processed on initialization. Each value should have
-	 * a matching protected property (prefixed with `_`) defined in the class. If the property is
-	 * an array, the property name should be the key and the value should be `'merge'`. See the
-	 * `_init()` method for more details.
-	 *
-	 * @see lithium\core\Object::_init()
-	 * @var array
-	 */
-	protected $_autoConfig = array();
-
-	/**
-	 * Contains a 2-dimensional array of filters applied to this object's methods, indexed by method
-	 * name. See the associated methods for more details.
-	 *
-	 * @see lithium\core\Object::_filter()
-	 * @see lithium\core\Object::applyFilter()
-	 * @var array
-	 */
-	protected $_methodFilters = array();
-
-	/**
-	 * Parents of the current class.
-	 *
-	 * @see lithium\core\Object::_parents()
-	 * @var array
-	 */
-	protected static $_parents = array();
-
-	/**
-	 * Initializes class configuration (`$_config`), and assigns object properties using the
-	 * `_init()` method, unless otherwise specified by configuration. See below for details.
-	 *
-	 * @see lithium\core\Object::$_config
-	 * @see lithium\core\Object::_init()
-	 * @param array $config The configuration options which will be assigned to the `$_config`
-	 *              property. This method accepts one configuration option:
-	 *              - `'init'` _boolean_: Controls constructor behavior for calling the `_init()`
-	 *                method. If `false`, the method is not called, otherwise it is. Defaults to
-	 *                `true`.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('init' => true);
-		$this->_config = $config + $defaults;
-
-		if ($this->_config['init']) {
-			$this->_init();
-		}
-	}
-
-	/**
-	 * Initializer function called by the constructor unless the constructor `'init'` flag is set
-	 * to `false`. May be used for testing purposes, where objects need to be manipulated in an
-	 * un-initialized state, or for high-overhead operations that require more control than the
-	 * constructor provides. Additionally, this method iterates over the `$_autoConfig` property
-	 * to automatically assign configuration settings to their corresponding properties.
-	 *
-	 * For example, given the following: {{{
-	 * class Bar extends \lithium\core\Object {
-	 * 	protected $_autoConfig = array('foo');
-	 * 	protected $_foo;
-	 * }
-	 *
-	 * $instance = new Bar(array('foo' => 'value'));
-	 * }}}
-	 *
-	 * The `$_foo` property of `$instance` would automatically be set to `'value'`. If `$_foo` was
-	 * an array, `$_autoConfig` could be set to `array('foo' => 'merge')`, and the constructor value
-	 * of `'foo'` would be merged with the default value of `$_foo` and assigned to it.
-	 *
-	 * @see lithium\core\Object::$_autoConfig
-	 * @return void
-	 */
-	protected function _init() {
-		foreach ($this->_autoConfig as $key => $flag) {
-			if (!isset($this->_config[$key]) && !isset($this->_config[$flag])) {
-				continue;
-			}
-
-			if ($flag === 'merge') {
-				$this->{"_{$key}"} = $this->_config[$key] + $this->{"_{$key}"};
-			} else {
-				$this->{"_$flag"} = $this->_config[$flag];
-			}
-		}
-	}
-
-	/**
-	 * Apply a closure to a method of the current object instance.
-	 *
-	 * @see lithium\core\Object::_filter()
-	 * @see lithium\util\collection\Filters
-	 * @param mixed $method The name of the method to apply the closure to. Can either be a single
-	 *        method name as a string, or an array of method names. Can also be false to remove
-	 *        all filters on the current object.
-	 * @param closure $filter The closure that is used to filter the method(s), can also be false
-	 *        to remove all the current filters for the given method.
-	 * @return void
-	 */
-	public function applyFilter($method, $filter = null) {
-		if ($method === false) {
-			$this->_methodFilters = array();
-			return;
-		}
-		foreach ((array) $method as $m) {
-			if (!isset($this->_methodFilters[$m]) || $filter === false) {
-				$this->_methodFilters[$m] = array();
-			}
-			if ($filter !== false) {
-				$this->_methodFilters[$m][] = $filter;
-			}
-		}
-	}
-
-	/**
-	 * Calls a method on this object with the given parameters. Provides an OO wrapper
-	 * for call_user_func_array, and improves performance by using straight method calls
-	 * in most cases.
-	 *
-	 * @param string $method  Name of the method to call
-	 * @param array $params  Parameter list to use when calling $method
-	 * @return mixed  Returns the result of the method call
-	 */
-	public function invokeMethod($method, $params = array()) {
-		switch (count($params)) {
-			case 0:
-				return $this->{$method}();
-			case 1:
-				return $this->{$method}($params[0]);
-			case 2:
-				return $this->{$method}($params[0], $params[1]);
-			case 3:
-				return $this->{$method}($params[0], $params[1], $params[2]);
-			case 4:
-				return $this->{$method}($params[0], $params[1], $params[2], $params[3]);
-			case 5:
-				return $this->{$method}($params[0], $params[1], $params[2], $params[3], $params[4]);
-			default:
-				return call_user_func_array(array(&$this, $method), $params);
-		}
-	}
-
-	/**
-	 * PHP magic method used in conjunction with `var_export()` to allow objects to be
-	 * re-instantiated with their pre-existing properties and values intact. This method can be
-	 * called statically on any class that extends `Object` to return an instance of it.
-	 *
-	 * @param array $data An array of properties and values with which to re-instantiate the object.
-	 *        These properties can be both public and protected.
-	 * @return object Returns an instance of the requested object with the given properties set.
-	 */
-	public static function __set_state($data) {
-		$class = get_called_class();
-		$object = new $class();
-
-		foreach ($data as $property => $value) {
-			$object->{$property} = $value;
-		}
-		return $object;
-	}
-
-	/**
-	 * Will determine if a method can be called.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public function respondsTo($method, $internal = false) {
-		return Inspector::isCallable($this, $method, $internal);
-	}
-
-	/**
-	 * Returns an instance of a class with given `config`. The `name` could be a key from the
-	 * `classes` array, a fully-namespaced class name, or an object. Typically this method is used
-	 * in `_init` to create the dependencies used in the current class.
-	 *
-	 * @param string|object $name A `classes` key or fully-namespaced class name.
-	 * @param array $options The configuration passed to the constructor.
-	 * @return object
-	 */
-	protected function _instance($name, array $options = array()) {
-		if (is_string($name) && isset($this->_classes[$name])) {
-			$name = $this->_classes[$name];
-		}
-		return Libraries::instance(null, $name, $options);
-	}
-
-	/**
-	 * Executes a set of filters against a method by taking a method's main implementation as a
-	 * callback, and iteratively wrapping the filters around it. This, along with the `Filters`
-	 * class, is the core of Lithium's filters system. This system allows you to "reach into" an
-	 * object's methods which are marked as _filterable_, and intercept calls to those methods,
-	 * optionally modifying parameters or return values.
-	 *
-	 * @see lithium\core\Object::applyFilter()
-	 * @see lithium\util\collection\Filters
-	 * @param string $method The name of the method being executed, usually the value of
-	 *               `__METHOD__`.
-	 * @param array $params An associative array containing all the parameters passed into
-	 *              the method.
-	 * @param Closure $callback The method's implementation, wrapped in a closure.
-	 * @param array $filters Additional filters to apply to the method for this call only.
-	 * @return mixed Returns the return value of `$callback`, modified by any filters passed in
-	 *         `$filters` or applied with `applyFilter()`.
-	 */
-	protected function _filter($method, $params, $callback, $filters = array()) {
-		list($class, $method) = explode('::', $method);
-
-		if (empty($this->_methodFilters[$method]) && empty($filters)) {
-			return $callback($this, $params, null);
-		}
-
-		$f = isset($this->_methodFilters[$method]) ? $this->_methodFilters[$method] : array();
-		$data = array_merge($f, $filters, array($callback));
-		return Filters::run($this, $params, compact('data', 'class', 'method'));
-	}
-
-	/**
-	 * Gets and caches an array of the parent methods of a class.
-	 *
-	 * @return array Returns an array of parent classes for the current class.
-	 */
-	protected static function _parents() {
-		$class = get_called_class();
-
-		if (!isset(self::$_parents[$class])) {
-			self::$_parents[$class] = class_parents($class);
-		}
-		return self::$_parents[$class];
-	}
-
-	/**
-	 * Exit immediately. Primarily used for overrides during testing.
-	 *
-	 * @param integer|string $status integer range 0 to 254, string printed on exit
-	 * @return void
-	 */
-	protected function _stop($status = 0) {
-		exit($status);
-	}
-
-}
-
-?>

+ 0 - 175
frameworks/PHP/php-lithium/libraries/lithium/core/StaticObject.php

@@ -1,175 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\core;
-
-use lithium\core\Libraries;
-use lithium\util\collection\Filters;
-use lithium\analysis\Inspector;
-
-/**
- * Provides a base class for all static classes in the Lithium framework. Similar to its
- * counterpart, the `Object` class, `StaticObject` defines some utility methods for working with
- * the filters system, and methods useful for testing purposes.
- *
- * @see lithium\core\Object
- */
-class StaticObject {
-
-	/**
-	 * Stores the closures that represent the method filters. They are indexed by called class.
-	 *
-	 * @var array Method filters, indexed by `get_called_class()`.
-	 */
-	protected static $_methodFilters = array();
-
-	/**
-	 * Keeps a cached list of each class' inheritance tree.
-	 *
-	 * @var array
-	 */
-	protected static $_parents = array();
-
-	/**
-	 * Apply a closure to a method of the current static object.
-	 *
-	 * @see lithium\core\StaticObject::_filter()
-	 * @see lithium\util\collection\Filters
-	 * @param mixed $method The name of the method to apply the closure to. Can either be a single
-	 *        method name as a string, or an array of method names. Can also be false to remove
-	 *        all filters on the current object.
-	 * @param closure $filter The closure that is used to filter the method(s), can also be false
-	 *        to remove all the current filters for the given method.
-	 * @return void
-	 */
-	public static function applyFilter($method, $filter = null) {
-		$class = get_called_class();
-		if ($method === false) {
-			static::$_methodFilters[$class] = array();
-			return;
-		}
-		foreach ((array) $method as $m) {
-			if (!isset(static::$_methodFilters[$class][$m]) || $filter === false) {
-				static::$_methodFilters[$class][$m] = array();
-			}
-			if ($filter !== false) {
-				static::$_methodFilters[$class][$m][] = $filter;
-			}
-		}
-	}
-
-	/**
-	 * Calls a method on this object with the given parameters. Provides an OO wrapper for
-	 * `forward_static_call_array()`, and improves performance by using straight method calls
-	 * in most cases.
-	 *
-	 * @param string $method Name of the method to call.
-	 * @param array $params Parameter list to use when calling `$method`.
-	 * @return mixed Returns the result of the method call.
-	 */
-	public static function invokeMethod($method, $params = array()) {
-		switch (count($params)) {
-			case 0:
-				return static::$method();
-			case 1:
-				return static::$method($params[0]);
-			case 2:
-				return static::$method($params[0], $params[1]);
-			case 3:
-				return static::$method($params[0], $params[1], $params[2]);
-			case 4:
-				return static::$method($params[0], $params[1], $params[2], $params[3]);
-			case 5:
-				return static::$method($params[0], $params[1], $params[2], $params[3], $params[4]);
-			default:
-				return forward_static_call_array(array(get_called_class(), $method), $params);
-		}
-	}
-
-	/**
-	 * Will determine if a method can be called.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public static function respondsTo($method, $internal = false) {
-		return Inspector::isCallable(get_called_class(), $method, $internal);
-	}
-
-	/**
-	 * Returns an instance of a class with given `config`. The `name` could be a key from the
-	 * `classes` array, a fully namespaced class name, or an object. Typically this method is used
-	 * in `_init` to create the dependencies used in the current class.
-	 *
-	 * @param string|object $name A `classes` key or fully-namespaced class name.
-	 * @param array $options The configuration passed to the constructor.
-	 * @return object
-	 */
-	protected static function _instance($name, array $options = array()) {
-		if (is_string($name) && isset(static::$_classes[$name])) {
-			$name = static::$_classes[$name];
-		}
-		return Libraries::instance(null, $name, $options);
-	}
-
-	/**
-	 * Executes a set of filters against a method by taking a method's main implementation as a
-	 * callback, and iteratively wrapping the filters around it.
-	 *
-	 * @see lithium\util\collection\Filters
-	 * @param string|array $method The name of the method being executed, or an array containing
-	 *        the name of the class that defined the method, and the method name.
-	 * @param array $params An associative array containing all the parameters passed into
-	 *        the method.
-	 * @param Closure $callback The method's implementation, wrapped in a closure.
-	 * @param array $filters Additional filters to apply to the method for this call only.
-	 * @return mixed
-	 */
-	protected static function _filter($method, $params, $callback, $filters = array()) {
-		$class = get_called_class();
-		$hasNoFilters = empty(static::$_methodFilters[$class][$method]);
-
-		if ($hasNoFilters && !$filters && !Filters::hasApplied($class, $method)) {
-			return $callback($class, $params, null);
-		}
-		if (!isset(static::$_methodFilters[$class][$method])) {
-			static::$_methodFilters += array($class => array());
-			static::$_methodFilters[$class][$method] = array();
-		}
-		$data = array_merge(static::$_methodFilters[$class][$method], $filters, array($callback));
-		return Filters::run($class, $params, compact('data', 'class', 'method'));
-	}
-
-	/**
-	 * Gets and caches an array of the parent methods of a class.
-	 *
-	 * @return array Returns an array of parent classes for the current class.
-	 */
-	protected static function _parents() {
-		$class = get_called_class();
-
-		if (!isset(self::$_parents[$class])) {
-			self::$_parents[$class] = class_parents($class);
-		}
-		return self::$_parents[$class];
-	}
-
-	/**
-	 * Exit immediately. Primarily used for overrides during testing.
-	 *
-	 * @param integer|string $status integer range 0 to 254, string printed on exit
-	 * @return void
-	 */
-	protected static function _stop($status = 0) {
-		exit($status);
-	}
-
-}
-
-?>

+ 0 - 625
frameworks/PHP/php-lithium/libraries/lithium/data/Collection.php

@@ -1,625 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data;
-
-/**
- * The `Collection` class extends the generic `lithium\util\Collection` class to provide
- * context-specific features for working with sets of data persisted by a backend data store. This
- * is a general abstraction that operates on arbitrary sets of data from either relational or
- * non-relational data stores.
- */
-abstract class Collection extends \lithium\util\Collection {
-
-	/**
-	 * A reference to this object's parent `Document` object.
-	 *
-	 * @var object
-	 */
-	protected $_parent = null;
-
-	/**
-	 * If this `Collection` instance has a parent document (see `$_parent`), this value indicates
-	 * the key name of the parent document that contains it.
-	 *
-	 * @see lithium\data\Collection::$_parent
-	 * @var string
-	 */
-	protected $_pathKey = null;
-
-	/**
-	 * The fully-namespaced class name of the model object to which this entity set is bound. This
-	 * is usually the model that executed the query which created this object.
-	 *
-	 * @var string
-	 */
-	protected $_model = null;
-
-	/**
-	 * A reference to the query object that originated this entity set; usually an instance of
-	 * `lithium\data\model\Query`.
-	 *
-	 * @see lithium\data\model\Query
-	 * @var object
-	 */
-	protected $_query = null;
-
-	/**
-	 * A pointer or resource that is used to load entities from the backend data source that
-	 * originated this collection.
-	 *
-	 * @var resource
-	 */
-	protected $_result = null;
-
-	/**
-	 * Indicates whether the current position is valid or not. This overrides the default value of
-	 * the parent class.
-	 *
-	 * @var boolean
-	 * @see lithium\util\Collection::valid()
-	 */
-	protected $_valid = true;
-
-	/**
-	 * Contains an array of backend-specific statistics generated by the query that produced this
-	 * `Collection` object. These stats are accessible via the `stats()` method.
-	 *
-	 * @see lithium\data\Collection::stats()
-	 * @var array
-	 */
-	protected $_stats = array();
-
-	/**
-	 * Setted to `true` when the collection has begun iterating.
-	 * @var integer
-	 */
-	protected $_started = false;
-
-	/**
-	 * Indicates whether this array was part of a document loaded from a data source, or is part of
-	 * a new document, or is in newly-added field of an existing document.
-	 *
-	 * @var boolean
-	 */
-	protected $_exists = false;
-
-	/**
-	 * If the `Collection` has a schema object assigned (rather than loading one from a model), it
-	 * will be assigned here.
-	 *
-	 * @see lithium\data\Schema
-	 * @var lithium\data\Schema
-	 */
-	protected $_schema = null;
-
-	/**
-	 * Holds an array of values that should be processed on initialization.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array(
-		'model', 'result', 'query', 'parent', 'stats', 'pathKey', 'exists', 'schema'
-	);
-
-	/**
-	 * Class constructor.
-	 *
-	 * @param array $config
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('data' => array(), 'model' => null);
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		$data = $this->_config['data'];
-		parent::_init();
-		$this->set($data);
-		foreach (array('classes', 'model', 'result', 'query') as $key) {
-			unset($this->_config[$key]);
-		}
-	}
-
-	/**
-	 * Configures protected properties of a `Collection` so that it is parented to `$parent`.
-	 *
-	 * @param object $parent
-	 * @param array $config
-	 * @return void
-	 */
-	public function assignTo($parent, array $config = array()) {
-		foreach ($config as $key => $val) {
-			$this->{'_' . $key} = $val;
-		}
-		$this->_parent =& $parent;
-	}
-
-	/**
-	 * Returns the model which this particular collection is based off of.
-	 *
-	 * @return string The fully qualified model class name.
-	 */
-	public function model() {
-		return $this->_model;
-	}
-
-	/**
-	 * Returns the object's parent `Document` object.
-	 *
-	 * @return object
-	 */
-	public function parent() {
-		return $this->_parent;
-	}
-
-	/**
-	 * A flag indicating whether or not the items of this collection exists.
-	 *
-	 * @return boolean `True` if exists, `false` otherwise.
-	 */
-	public function exists() {
-		return $this->_exists;
-	}
-
-	public function schema($field = null) {
-		$schema = null;
-
-		switch (true) {
-			case ($this->_schema):
-				$schema = $this->_schema;
-			break;
-			case ($model = $this->_model):
-				$schema = $model::schema();
-			break;
-		}
-		if ($schema) {
-			return $field ? $schema->fields($field) : $schema;
-		}
-	}
-
-	/**
-	 * Allows several properties to be assigned at once.
-	 *
-	 * For example:
-	 * {{{
-	 * $collection->set(array('title' => 'Lorem Ipsum', 'value' => 42));
-	 * }}}
-	 *
-	 * @param $values An associative array of fields and values to assign to the `Collection`.
-	 * @return void
-	 */
-	public function set($values) {
-		foreach ($values as $key => $val) {
-			$this[$key] = $val;
-		}
-	}
-
-	/**
-	 * Returns a boolean indicating whether an offset exists for the
-	 * current `Collection`.
-	 *
-	 * @param string $offset String or integer indicating the offset or
-	 *               index of an entity in the set.
-	 * @return boolean Result.
-	 */
-	public function offsetExists($offset) {
-		$this->offsetGet($offset);
-		return array_key_exists($offset, $this->_data);
-	}
-
-	/**
-	 * Gets an `Entity` object using PHP's array syntax, i.e. `$documents[3]` or `$records[5]`.
-	 *
-	 * @param mixed $offset The offset.
-	 * @return mixed Returns an `Entity` object if exists otherwise returns `null`.
-	 */
-	public function offsetGet($offset) {
-		while (!array_key_exists($offset, $this->_data) && $this->_populate()) {}
-
-		if (array_key_exists($offset, $this->_data)) {
-			return $this->_data[$offset];
-		}
-		return null;
-	}
-
-	/**
-	 * Adds the specified object to the `Collection` instance, and assigns associated metadata to
-	 * the added object.
-	 *
-	 * @param string $offset The offset to assign the value to.
-	 * @param mixed $data The entity object to add.
-	 * @return mixed Returns the set `Entity` object.
-	 */
-	public function offsetSet($offset, $data) {
-		$this->offsetGet($offset);
-		return $this->_set($data, $offset);
-	}
-
-	/**
-	 * Unsets an offset.
-	 *
-	 * @param integer $offset The offset to unset.
-	 */
-	public function offsetUnset($offset) {
-		$this->offsetGet($offset);
-		prev($this->_data);
-		if (key($this->_data) === null) {
-			$this->rewind();
-		}
-		unset($this->_data[$offset]);
-	}
-
-	/**
-	 * Rewinds the collection to the beginning.
-	 */
-	public function rewind() {
-		$this->_started = true;
-		reset($this->_data);
-		$this->_valid = !empty($this->_data) || !is_null($this->_populate());
-		return current($this->_data);
-	}
-
-	/**
-	 * Returns the currently pointed to record's unique key.
-	 *
-	 * @param boolean $full If true, returns the complete key.
-	 * @return mixed
-	 */
-	public function key($full = false) {
-		if ($this->_started === false) {
-			$this->current();
-		}
-		if ($this->_valid) {
-			$key = key($this->_data);
-			return (is_array($key) && !$full) ? reset($key) : $key;
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the item keys.
-	 *
-	 * @return array The keys of the items.
-	 */
-	public function keys() {
-		$this->offsetGet(null);
-		return parent::keys();
-	}
-
-	/**
-	 * Returns the currently pointed to record in the set.
-	 *
-	 * @return object `Record`
-	 */
-	public function current() {
-		if (!$this->_started) {
-			$this->rewind();
-		}
-		if (!$this->_valid) {
-			return false;
-		}
-		return current($this->_data);
-	}
-
-	/**
-	 * Returns the next document in the set, and advances the object's internal pointer. If the end
-	 * of the set is reached, a new document will be fetched from the data source connection handle
-	 * If no more documents can be fetched, returns `null`.
-	 *
-	 * @return mixed Returns the next document in the set, or `false`, if no more documents are
-	 *         available.
-	 */
-	public function next() {
-		if (!$this->_started) {
-			$this->rewind();
-		}
-		next($this->_data);
-		$this->_valid = !(key($this->_data) === null);
-		if (!$this->_valid) {
-			$this->_valid = !is_null($this->_populate());
-		}
-		return current($this->_data);
-	}
-
-	/**
-	 * Checks if current position is valid.
-	 *
-	 * @return boolean `true` if valid, `false` otherwise.
-	 */
-	public function valid() {
-		if (!$this->_started) {
-			$this->rewind();
-		}
-		return $this->_valid;
-	}
-
-	/**
-	 * Overrides parent `find()` implementation to enable key/value-based filtering of entity
-	 * objects contained in this collection.
-	 *
-	 * @param mixed $filter Callback to use for filtering, or array of key/value pairs which entity
-	 *              properties will be matched against.
-	 * @param array $options Options to modify the behavior of this method. See the documentation
-	 *              for the `$options` parameter of `lithium\util\Collection::find()`.
-	 * @return mixed The filtered items. Will be an array unless `'collect'` is defined in the
-	 * `$options` argument, then an instance of this class will be returned.
-	 */
-	public function find($filter, array $options = array()) {
-		$this->offsetGet(null);
-		if (is_array($filter)) {
-			$filter = $this->_filterFromArray($filter);
-		}
-		return parent::find($filter, $options);
-	}
-
-	/**
-	 * Overrides parent `first()` implementation to enable key/value-based filtering.
-	 *
-	 * @param mixed $filter In addition to a callback (see parent), can also be an array where the
-	 *              keys and values must match the property values of the objects being inspected.
-	 * @return object Returns the first object found matching the filter criteria.
-	 */
-	public function first($filter = null) {
-		return parent::first(is_array($filter) ? $this->_filterFromArray($filter) : $filter);
-	}
-
-	/**
-	 * Creates a filter based on an array of key/value pairs that must match the items in a
-	 * `Collection`.
-	 *
-	 * @param array $filter An array of key/value pairs used to filter `Collection` items.
-	 * @return closure Returns a closure that wraps the array and attempts to match each value
-	 *         against `Collection` item properties.
-	 */
-	protected function _filterFromArray(array $filter) {
-		return function($item) use ($filter) {
-			foreach ($filter as $key => $val) {
-				if ($item->{$key} != $val) {
-					return false;
-				}
-			}
-			return true;
-		};
-	}
-
-	/**
-	 * Returns meta information for this `Collection`.
-	 *
-	 * @return array
-	 */
-	public function meta() {
-		return array('model' => $this->_model);
-	}
-
-	/**
-	 * Applies a callback to all data in the collection.
-	 *
-	 * Overridden to load any data that has not yet been loaded.
-	 *
-	 * @param callback $filter The filter to apply.
-	 * @return object This collection instance.
-	 */
-	public function each($filter) {
-		$this->offsetGet(null);
-		return parent::each($filter);
-	}
-
-	/**
-	 * Applies a callback to a copy of all data in the collection
-	 * and returns the result.
-	 *
-	 * Overriden to load any data that has not yet been loaded.
-	 *
-	 * @param callback $filter The filter to apply.
-	 * @param array $options The available options are:
-	 *              - `'collect'`: If `true`, the results will be returned wrapped
-	 *              in a new `Collection` object or subclass.
-	 * @return object The filtered data.
-	 */
-	public function map($filter, array $options = array()) {
-		$defaults = array('collect' => true);
-		$options += $defaults;
-
-		$this->offsetGet(null);
-		$data = parent::map($filter, $options);
-
-		if ($options['collect']) {
-			foreach (array('_model', '_schema', '_pathKey') as $key) {
-				$data->{$key} = $this->{$key};
-			}
-		}
-		return $data;
-	}
-
-	/**
-	 * Reduce, or fold, a collection down to a single value
-	 *
-	 * Overridden to load any data that has not yet been loaded.
-	 *
-	 * @param callback $filter The filter to apply.
-	 * @param mixed $initial Initial value
-	 * @return mixed A single reduced value
-	 */
-	public function reduce($filter, $initial = false) {
-		if (!$this->closed()) {
-			while ($this->next()) {}
-		}
-		return parent::reduce($filter);
-	}
-
-	/**
-	 * Sorts the objects in the collection, useful in situations where
-	 * you are already using the underlying datastore to sort results.
-	 *
-	 * Overriden to load any data that has not yet been loaded.
-	 *
-	 * @param mixed $field The field to sort the data on, can also be a callback
-	 * to a custom sort function.
-	 * @param array $options The available options are:
-	 *              - No options yet implemented
-	 * @return $this, useful for chaining this with other methods.
-	 */
-	public function sort($field = 'id', array $options = array()) {
-		$this->offsetGet(null);
-
-		if (is_string($field)) {
-			$sorter = function ($a, $b) use ($field) {
-				if (is_array($a)) {
-					$a = (object) $a;
-				}
-
-				if (is_array($b)) {
-					$b = (object) $b;
-				}
-
-				return strcmp($a->$field, $b->$field);
-			};
-		} else if (is_callable($field)) {
-			$sorter = $field;
-		}
-
-		return parent::sort($sorter, $options);
-	}
-
-	/**
-	 * Converts the current state of the data structure to an array.
-	 *
-	 * @return array Returns the array value of the data in this `Collection`.
-	 */
-	public function data() {
-		return $this->to('array', array('indexed' => null));
-	}
-
-	/**
-	 * Converts a `Collection` object to another type of object, or a simple type such as an array.
-	 * The supported values of `$format` depend on the format handlers registered in the static
-	 * property `Collection::$_formats`. The `Collection` class comes with built-in support for
-	 * array conversion, but other formats may be registered.
-	 *
-	 * Once the appropriate handlers are registered, a `Collection` instance can be converted into
-	 * any handler-supported format, i.e.: {{{
-	 * $collection->to('json'); // returns a JSON string
-	 * $collection->to('xml'); // returns an XML string
-	 * }}}
-	 *
-	 *  _Please note that Lithium does not ship with a default XML handler, but one can be
-	 * configured easily._
-	 *
-	 * @see lithium\util\Collection::formats()
-	 * @see lithium\util\Collection::$_formats
-	 * @param string $format By default the only supported value is `'array'`. However, additional
-	 *               format handlers can be registered using the `formats()` method.
-	 * @param array $options Options for converting this collection:
-	 *        - `'internal'` _boolean_: Indicates whether the current internal representation of the
-	 *          collection should be exported. Defaults to `false`, which uses the standard iterator
-	 *          interfaces. This is useful for exporting record sets, where records are lazy-loaded,
-	 *          and the collection must be iterated in order to fetch all objects.
-	 * @return mixed The object converted to the value specified in `$format`; usually an array or
-	 *         string.
-	 */
-	public function to($format, array $options = array()) {
-		$defaults = array('internal' => false, 'indexed' => true);
-		$options += $defaults;
-
-		$this->offsetGet(null);
-
-		$index = $options['indexed'] || ($options['indexed'] === null && $this->_parent === null);
-		if (!$index) {
-			$data = array_values($this->_data);
-		} else {
-			$data = $options['internal'] ? $this->_data : $this;
-		}
-		return $this->_to($format, $data, $options);
-	}
-
-	/**
-	 * Return's the pointer or resource that is used to load entities from the backend
-	 * data source that originated this collection. This is useful in many cases for
-	 * additional methods related to debugging queries.
-	 *
-	 * @return object The pointer or resource from the data source
-	 */
-	public function result() {
-		return $this->_result;
-	}
-
-	/**
-	 * Gets the stat or stats associated with this `Collection`.
-	 *
-	 * @param string $name Stat name.
-	 * @return mixed Single stat if `$name` supplied, else all stats for this
-	 *               `Collection`.
-	 */
-	public function stats($name = null) {
-		if ($name) {
-			return isset($this->_stats[$name]) ? $this->_stats[$name] : null;
-		}
-		return $this->_stats;
-	}
-
-	/**
-	 * Executes when the associated result resource pointer reaches the end of its data set. The
-	 * resource is freed by the connection, and the reference to the connection is unlinked.
-	 *
-	 * @return void
-	 */
-	public function close() {
-		if (!empty($this->_result)) {
-			unset($this->_result);
-			$this->_result = null;
-		}
-	}
-
-	/**
-	 * Checks to see if this entity has already fetched all available entities and freed the
-	 * associated result resource.
-	 *
-	 * @return boolean Returns true if all entities are loaded and the database resources have been
-	 *         freed, otherwise returns false.
-	 */
-	public function closed() {
-		return empty($this->_result);
-	}
-
-	/**
-	 * Ensures that the data set's connection is closed when the object is destroyed.
-	 *
-	 * @return void
-	 */
-	public function __destruct() {
-		$this->close();
-	}
-
-	/**
-	 * A method to be implemented by concrete `Collection` classes which, provided a reference to a
-	 * backend data source, and a resource representing a query result cursor, fetches new result
-	 * data and wraps it in the appropriate object type, which is added into the `Collection` and
-	 * returned.
-	 *
-	 * @return mixed Returns the next `Record`, `Document` object or other `Entity` object if
-	 *         exists. Returns `null` otherwise.
-	 */
-	abstract protected function _populate();
-
-	/**
-	 * A method to be implemented by concrete `Collection` classes which sets data to a specified
-	 * offset and wraps all data array in its appropriate object type.
-	 *
-	 * @see lithium\data\Collection::_populate()
-	 * @see lithium\data\Collection::_offsetSet()
-	 *
-	 * @param mixed $data An array or an `Entity` object to set.
-	 * @param mixed $offset The offset. If offset is `null` data is simply appended to the set.
-	 * @param array $options Any additional options to pass to the `Entity`'s constructor.
-	 * @return object Returns the inserted `Record`, `Document` object or other `Entity` object.
-	 */
-	abstract protected function _set($data = null, $offset = null, $options = array());
-}
-
-?>

+ 0 - 189
frameworks/PHP/php-lithium/libraries/lithium/data/Connections.php

@@ -1,189 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data;
-
-use lithium\core\Libraries;
-
-/**
- * The `Connections` class manages a list of named configurations that connect to external
- * resources. Connections are usually comprised of a type (i.e. `'database'` or `'http'`), a
- * reference to an adapter class (i.e. `'MySql'` or `'CouchDb'`), and authentication credentials.
- *
- * While connections can be added and removed dynamically during the course of your application
- * (using `Connections::add()`), it is most typical to define all connections at once, in
- * `config/bootstrap/connections.php`.
- *
- * The `Connections` class handles adapter classes efficiently by only loading adapter classes and
- * creating instances when they are requested (using `Connections::get()`).
- *
- * Adapters are usually subclasses of `lithium\data\Source`.
- *
- * @see lithium\data\Source
- */
-class Connections extends \lithium\core\Adaptable {
-
-	/**
-	 * A Collection of the configurations you add through Connections::add().
-	 *
-	 * @var `lithium\util\Collection`
-	 */
-	protected static $_configurations = array();
-
-	/**
-	 * Libraries::locate() compatible path to adapters for this class.
-	 *
-	 * @var string Dot-delimited path.
-	 */
-	protected static $_adapters = 'data.source';
-
-	/**
-	 * Add connection configurations to your app in `config/bootstrap/connections.php`
-	 *
-	 * For example:
-	 * {{{
-	 * Connections::add('default', array(
-	 *     'type' => 'database',
-	 *     'adapter' => 'MySql',
-	 *     'host' => 'localhost',
-	 *     'login' => 'root',
-	 *     'password' => '',
-	 *     'database' => 'my_blog'
-	 * ));
-	 * }}}
-	 *
-	 * or
-	 *
-	 * {{{
-	 * Connections::add('couch', array(
-	 * 	'type' => 'http', 'adapter' => 'CouchDb', 'host' => '127.0.0.1', 'port' => 5984
-	 * ));
-	 * }}}
-	 *
-	 * or
-	 *
-	 * {{{
-	 * Connections::add('mongo', array('type' => 'MongoDb', 'database' => 'my_app'));
-	 * }}}
-	 *
-	 * @see lithium\data\Model::$_meta
-	 * @param string $name The name by which this connection is referenced. Use this name to
-	 *        retrieve the connection again using `Connections::get()`, or to bind a model to it
-	 *        using `Model::$_meta['connection']`.
-	 * @param array $config Contains all additional configuration information used by the
-	 *        connection, including the name of the adapter class where applicable (i.e. `MySql`),
-	 *        the server name and port or socket to connect to, and (typically) the name of the
-	 *        database or other entity to use. Each adapter has its own specific configuration
-	 *        settings for handling things like connection persistence, data encoding, etc. See the
-	 *        individual adapter or data source class for more information on what configuration
-	 *        settings it supports. Basic / required options supported by most adapters:
-	 *        - `'type'` _string_: The type of data source that defines this connection; typically a
-	 *          class or namespace name. Relational database data sources, use `'database'`, while
-	 *          CouchDB and other HTTP-related data sources use `'http'`, etc. For classes which
-	 *          directly extend `lithium\data\Source`, and do not use an adapter, simply use the
-	 *          name of the class, i.e. `'MongoDb'`.
-	 *        - `'adapter'` _string_: For `type`s such as `'database'` which are adapter-driven,
-	 *          provides the name of the adapter associated with this configuration.
-	 *        - `'host'` _string_: The host name that the database should connect to. Typically
-	 *          defaults to `'localhost'`.
-	 *        - `'login'` _string_: If the connection requires authentication, specifies the login
-	 *          name to use.
-	 *        - `'password'` _string_: If the connection requires authentication, specifies the
-	 *          password to use.
-	 * @return array Returns the final post-processed connection information, as stored in the
-	 *         internal configuration array used by `Connections`.
-	 */
-	public static function add($name, array $config = array()) {
-		$defaults = array(
-			'type'     => null,
-			'adapter'  => null,
-			'login'    => '',
-			'password' => ''
-		);
-		return static::$_configurations[$name] = $config + $defaults;
-	}
-
-	/**
-	 * Read the configuration or access the connections you have set up.
-	 *
-	 * Usage:
-	 * {{{
-	 * // Gets the names of all available configurations
-	 * $configurations = Connections::get();
-	 *
-	 * // Gets the configuration array for the connection named 'db'
-	 * $config = Connections::get('db', array('config' => true));
-	 *
-	 * // Gets the instance of the connection object, configured with the settings defined for
-	 * // this object in Connections::add()
-	 * $dbConnection = Connections::get('db');
-	 *
-	 * // Gets the connection object, but only if it has already been built.
-	 * // Otherwise returns null.
-	 * $dbConnection = Connections::get('db', array('autoCreate' => false));
-	 * }}}
-	 *
-	 * @param string $name The name of the connection to get, as defined in the first parameter of
-	 *        `add()`, when the connection was initially created.
-	 * @param array $options Options to use when returning the connection:
-	 *        - `'autoCreate'`: If `false`, the connection object is only returned if it has
-	 *          already been instantiated by a previous call.
-	 *        - `'config'`: If `true`, returns an array representing the connection's internal
-	 *          configuration, instead of the connection itself.
-	 * @return mixed A configured instance of the connection, or an array of the configuration used.
-	 */
-	public static function get($name = null, array $options = array()) {
-		static $mockAdapter;
-
-		$defaults = array('config' => false, 'autoCreate' => true);
-		$options += $defaults;
-
-		if ($name === false) {
-			if (!$mockAdapter) {
-				$class = Libraries::locate('data.source', 'Mock');
-				$mockAdapter = new $class();
-			}
-			return $mockAdapter;
-		}
-
-		if (!$name) {
-			return array_keys(static::$_configurations);
-		}
-
-		if (!isset(static::$_configurations[$name])) {
-			return null;
-		}
-		if ($options['config']) {
-			return static::_config($name);
-		}
-		$settings = static::$_configurations[$name];
-
-		if (!isset($settings[0]['object']) && !$options['autoCreate']) {
-			return null;
-		}
-		return static::adapter($name);
-	}
-
-	/**
-	 * Constructs a data source or adapter object instance from a configuration array.
-	 *
-	 * @param array $config
-	 * @param array $paths
-	 * @return object
-	 */
-	protected static function _class($config, $paths = array()) {
-		if (!$config['adapter']) {
-			$config['adapter'] = $config['type'];
-		} else {
-			$paths = array_merge(array("adapter.data.source.{$config['type']}"), (array) $paths);
-		}
-		return parent::_class($config, $paths);
-	}
-}
-
-?>

+ 0 - 116
frameworks/PHP/php-lithium/libraries/lithium/data/DocumentSchema.php

@@ -1,116 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data;
-
-class DocumentSchema extends \lithium\data\Schema {
-
-	protected $_classes = array(
-		'entity' => 'lithium\data\entity\Document',
-		'set'    => 'lithium\data\collection\DocumentSet'
-	);
-
-	protected $_handlers = array();
-
-	protected function _init() {
-		$this->_autoConfig[] = 'handlers';
-		parent::_init();
-	}
-
-	public function cast($object, $key, $data, array $options = array()) {
-		$defaults = array(
-			'parent' => null,
-			'pathKey' => null,
-			'model' => null,
-			'wrap' => true,
-			'first' => false
-		);
-		$options += $defaults;
-
-		$basePathKey = $options['pathKey'];
-		$model = (!$options['model'] && $object) ? $object->model() : $options['model'];
-		$classes = $this->_classes;
-
-		$fieldName = is_int($key) ? null : $key;
-		$pathKey = $basePathKey;
-
-		if ($fieldName) {
-			$pathKey = $basePathKey ? "{$basePathKey}.{$fieldName}" : $fieldName;
-		}
-
-		if ($data instanceof $classes['set'] || $data instanceof $classes['entity']) {
-			return $data;
-		}
-		if (is_object($data) && !$this->is('array', $pathKey)) {
-			return $data;
-		}
-		return $this->_castArray($object, $data, $pathKey, $options, $defaults);
-	}
-
-	protected function _castArray($object, $val, $pathKey, $options, $defaults) {
-		$isArray = $this->is('array', $pathKey) && (!$object instanceof $this->_classes['set']);
-		$isObject = ($this->type($pathKey) === 'object');
-		$valIsArray = is_array($val);
-		$numericArray = false;
-		$class = 'entity';
-
-		if (!$valIsArray && !$isArray) {
-			return $this->_castType($val, $pathKey);
-		}
-
-		if ($valIsArray) {
-			$numericArray = !$val || array_keys($val) === range(0, count($val) - 1);
-		}
-
-		if ($isArray || ($numericArray && !$isObject)) {
-			$val = $valIsArray ? $val : array($val);
-			$class = 'set';
-		}
-
-		if ($options['wrap']) {
-			$config = array(
-				'data' => $val,
-				'parent' => $options['parent'],
-				'model' => $options['model'],
-				'schema' => $this
-			);
-			$config += compact('pathKey') + array_diff_key($options, $defaults);
-			$val = $this->_instance($class, $config);
-		} elseif ($class === 'set') {
-			$val = $val ?: array();
-			foreach ($val as &$value) {
-				$value = $this->_castType($value, $pathKey);
-			}
-		}
-		return $val;
-	}
-
-	/**
-	 * Casts a scalar (non-object/array) value to its corresponding database-native value or custom
-	 * value object based on a handler assigned to `$field`'s data type.
-	 *
-	 * @param mixed $value The value to be cast.
-	 * @param string $field The name of the field that `$value` is or will be stored in. If it is a
-	 *               nested field, `$field` should be the full dot-separated path to the
-	 *               sub-object's field.
-	 * @return mixed Returns the result of `$value`, modified by a matching handler data type
-	 *               handler, if available.
-	 */
-	protected function _castType($value, $field) {
-		if ($this->is('null', $field) && ($value === null || $value === "")) {
-			return null;
-		}
-		if (!is_scalar($value)) {
-			return $value;
-		}
-		$type = $this->type($field);
-		return isset($this->_handlers[$type]) ? $this->_handlers[$type]($value) : $value;
-	}
-}
-
-?>

+ 0 - 494
frameworks/PHP/php-lithium/libraries/lithium/data/Entity.php

@@ -1,494 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data;
-
-use BadMethodCallException;
-use UnexpectedValueException;
-use lithium\data\Collection;
-use lithium\analysis\Inspector;
-
-/**
- * `Entity` is a smart data object which represents data such as a row or document in a
- * database. Entities have fields (often known as columns in databases), and track changes to its
- * fields, as well as associated validation errors, etc.
- *
- * The `Entity` class can also be used as a base class for your own custom data objects, and is the
- * basis for generating forms with the `Form` helper.
- *
- * @see lithium\template\helper\Form
- */
-class Entity extends \lithium\core\Object {
-
-	/**
-	 * Fully-namespaced class name of model that this record is bound to. Instance methods declared
-	 * in the model may be called on the entity. See the `Model` class documentation for more
-	 * information.
-	 *
-	 * @see lithium\data\Model
-	 * @see lithium\data\Entity::__call()
-	 * @var string
-	 */
-	protected $_model = null;
-
-	/**
-	 * Associative array of the entity's fields and values.
-	 *
-	 * @var array
-	 */
-	protected $_data = array();
-
-	/**
-	 * An array containing all related records and recordsets, keyed by relationship name, as
-	 * defined in the bound model class.
-	 *
-	 * @var array
-	 */
-	protected $_relationships = array();
-
-	/**
-	 * If this record is chained off of another, contains the origin object.
-	 *
-	 * @var object
-	 */
-	protected $_parent = null;
-
-	/**
-	 * The list of validation errors associated with this object, where keys are field names, and
-	 * values are arrays containing one or more validation error messages.
-	 *
-	 * @see lithium\data\Entity::errors()
-	 * @var array
-	 */
-	protected $_errors = array();
-
-	/**
-	 * Contains the values of updated fields. These values will be persisted to the backend data
-	 * store when the document is saved.
-	 *
-	 * @var array
-	 */
-	protected $_updated = array();
-
-	/**
-	 * An array of key/value pairs corresponding to fields that should be updated using atomic
-	 * incrementing / decrementing operations. Keys match field names, and values indicate the value
-	 * each field should be incremented or decremented by.
-	 *
-	 * @see lithium\data\Entity::increment()
-	 * @see lithium\data\Entity::decrement()
-	 * @var array
-	 */
-	protected $_increment = array();
-
-	/**
-	 * A flag indicating whether or not this entity exists. Set to `false` if this is a
-	 * newly-created entity, or if this entity has been loaded and subsequently deleted. Set to
-	 * `true` if the entity has been loaded from the database, or has been created and subsequently
-	 * saved.
-	 *
-	 * @var boolean
-	 */
-	protected $_exists = false;
-
-	/**
-	 * A local copy of the schema definition. This is the same as `lithium\data\Model::$_schema`,
-	 * but can be defined here if this is a one-off object or class used for a single purpose, i.e.
-	 * to create a form.
-	 *
-	 * @var array
-	 */
-	protected $_schema = array();
-
-	/**
-	 * Auto configuration.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array(
-		'classes' => 'merge', 'parent', 'schema', 'data',
-		'model', 'exists', 'pathKey', 'relationships'
-	);
-
-	/**
-	 * Creates a new record object with default values.
-	 *
-	 * Options defined:
-	 * - 'data' _array_: Data to enter into the record. Defaults to an empty array.
-	 * - 'model' _string_: Class name that provides the data-source for this record.
-	 *   Defaults to `null`.
-	 *
-	 * @param array $config
-	 * @return object Record object.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('model' => null, 'data' => array(), 'relationships' => array());
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-		$this->_updated = $this->_data;
-	}
-
-	/**
-	 * Overloading for reading inaccessible properties.
-	 *
-	 * @param string $name Property name.
-	 * @return mixed Result.
-	 */
-	public function &__get($name) {
-		if (isset($this->_relationships[$name])) {
-			return $this->_relationships[$name];
-		}
-		if (isset($this->_updated[$name])) {
-			return $this->_updated[$name];
-		}
-		$null = null;
-		return $null;
-	}
-
-	/**
-	 * Overloading for writing to inaccessible properties.
-	 *
-	 * @param string $name Property name.
-	 * @param string $value Property value.
-	 * @return mixed Result.
-	 */
-	public function __set($name, $value = null) {
-		if (is_array($name) && !$value) {
-			return array_map(array(&$this, '__set'), array_keys($name), array_values($name));
-		}
-		$this->_updated[$name] = $value;
-	}
-
-	/**
-	 * Overloading for calling `isset()` or `empty()` on inaccessible properties.
-	 *
-	 * @param string $name Property name.
-	 * @return mixed Result.
-	 */
-	public function __isset($name) {
-		return isset($this->_updated[$name]) || isset($this->_relationships[$name]);
-	}
-
-	/**
-	 * Magic method that allows calling of model methods on this record instance, i.e.:
-	 * {{{
-	 * $record->validates();
-	 * }}}
-	 *
-	 * @param string $method Method name caught by `__call()`.
-	 * @param array $params Arguments given to the above `$method` call.
-	 * @return mixed
-	 */
-	public function __call($method, $params) {
-		if (($model = $this->_model) && method_exists($model, '_object')) {
-			array_unshift($params, $this);
-			$class = $model::invokeMethod('_object');
-			return call_user_func_array(array(&$class, $method), $params);
-		}
-		$message = "No model bound to call `{$method}`.";
-		throw new BadMethodCallException($message);
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public function respondsTo($method, $internal = false) {
-		$class = $this->_model;
-		$modelRespondsTo = false;
-		$parentRespondsTo = parent::respondsTo($method, $internal);
-		$staticRespondsTo = $class::respondsTo($method, $internal);
-		if (method_exists($class, '_object')) {
-			$model = $class::invokeMethod('_object');
-			$modelRespondsTo = $model->respondsTo($method);
-		} else {
-			$modelRespondsTo = Inspector::isCallable($class, $method, $internal);
-		}
-		return $parentRespondsTo || $staticRespondsTo || $modelRespondsTo;
-	}
-
-	/**
-	 * Allows several properties to be assigned at once, i.e.:
-	 * {{{
-	 * $record->set(array('title' => 'Lorem Ipsum', 'value' => 42));
-	 * }}}
-	 *
-	 * @param array $data An associative array of fields and values to assign to this `Entity`
-	 *        instance.
-	 * @return void
-	 */
-	public function set(array $data) {
-		foreach ($data as $name => $value) {
-			$this->__set($name, $value);
-		}
-	}
-
-	/**
-	 * Access the data fields of the record. Can also access a $named field.
-	 *
-	 * @param string $name Optionally included field name.
-	 * @return mixed Entire data array if $name is empty, otherwise the value from the named field.
-	 */
-	public function data($name = null) {
-		if ($name) {
-			return $this->__get($name);
-		}
-		return $this->to('array');
-	}
-
-	/**
-	 * Returns the model which this entity is bound to.
-	 *
-	 * @return string The fully qualified model class name.
-	 */
-	public function model() {
-		return $this->_model;
-	}
-
-	public function schema($field = null) {
-		$schema = null;
-
-		switch (true) {
-			case (is_object($this->_schema)):
-				$schema = $this->_schema;
-			break;
-			case ($model = $this->_model):
-				$schema = $model::schema();
-			break;
-		}
-		if ($schema) {
-			return $field ? $schema->fields($field) : $schema;
-		}
-		return array();
-	}
-
-	/**
-	 * Access the errors of the record.
-	 *
-	 * @see lithium\data\Entity::$_errors
-	 * @param array|string $field If an array, overwrites `$this->_errors`. If a string, and
-	 *        `$value` is not `null`, sets the corresponding key in `$this->_errors` to `$value`.
-	 * @param string $value Value to set.
-	 * @return mixed Either the `$this->_errors` array, or single value from it.
-	 */
-	public function errors($field = null, $value = null) {
-		if ($field === null) {
-			return $this->_errors;
-		}
-		if (is_array($field)) {
-			return ($this->_errors = $field);
-		}
-		if ($value === null && isset($this->_errors[$field])) {
-			return $this->_errors[$field];
-		}
-		if ($value !== null) {
-			return $this->_errors[$field] = $value;
-		}
-		return $value;
-	}
-
-	/**
-	 * A flag indicating whether or not this record exists.
-	 *
-	 * @return boolean `True` if the record was `read` from the data-source, or has been `create`d
-	 *         and `save`d. Otherwise `false`.
-	 */
-	public function exists() {
-		return $this->_exists;
-	}
-
-	/**
-	 * Called after an `Entity` is saved. Updates the object's internal state to reflect the
-	 * corresponding database entity, and sets the `Entity` object's key, if this is a newly-created
-	 * object. **Do not** call this method if you intend to update the database's copy of the
-	 * entity. Instead, see `Model::save()`.
-	 *
-	 * @see lithium\data\Model::save()
-	 * @param mixed $id The ID to assign, where applicable.
-	 * @param array $data Any additional generated data assigned to the object by the database.
-	 * @param array $options Method options:
-	 *              - `'materialize'` _boolean_: Determines whether or not the flag should be set
-	 *                that indicates that this entity exists in the data store. Defaults to `true`.
-	 *              - `'dematerialize'` _boolean_: If set to `true`, indicates that this entity has
-	 *                been deleted from the data store and no longer exists. Defaults to `false`.
-	 * @return void
-	 */
-	public function sync($id = null, array $data = array(), array $options = array()) {
-		$defaults = array('materialize' => true, 'dematerialize' => false);
-		$options += $defaults;
-		$model = $this->_model;
-		$key = array();
-
-		if ($options['materialize']) {
-			$this->_exists = true;
-		}
-		if ($options['dematerialize']) {
-			$this->_exists = false;
-		}
-		if ($id && $model) {
-			$key = $model::meta('key');
-			$key = is_array($key) ? array_combine($key, $id) : array($key => $id);
-		}
-		$this->_data = $this->_updated = ($key + $data + $this->_updated);
-	}
-
-	/**
-	 * Safely (atomically) increments the value of the specified field by an arbitrary value.
-	 * Defaults to `1` if no value is specified. Throws an exception if the specified field is
-	 * non-numeric.
-	 *
-	 * @param string $field The name of the field to be incremented.
-	 * @param string $value The value to increment the field by. Defaults to `1` if this parameter
-	 *               is not specified.
-	 * @return integer Returns the current value of `$field`, based on the value retrieved from the
-	 *         data source when the entity was loaded, plus any increments applied. Note that it may
-	 *         not reflect the most current value in the persistent backend data source.
-	 * @throws UnexpectedValueException Throws an exception when `$field` is set to a non-numeric
-	 *         type.
-	 */
-	public function increment($field, $value = 1) {
-		if (!isset($this->_updated[$field])) {
-			return $this->_updated[$field] = $value;
-		}
-		if (!is_numeric($this->_updated[$field])) {
-			throw new UnexpectedValueException("Field '{$field}' cannot be incremented.");
-		}
-		return $this->_updated[$field] += $value;
-	}
-
-	/**
-	 * Decrements a field by the specified value. Works identically to `increment()`, but in
-	 * reverse.
-	 *
-	 * @see lithium\data\Entity::increment()
-	 * @param string $field The name of the field to decrement.
-	 * @param string $value The value by which to decrement the field. Defaults to `1`.
-	 * @return integer Returns the new value of `$field`, after modification.
-	 */
-	public function decrement($field, $value = 1) {
-		return $this->increment($field, $value * -1);
-	}
-
-	/**
-	 * Gets the current state for a given field or, if no field is given, gets the array of
-	 * fields modified on this entity.
-	 *
-	 * @param string The field name to check its state.
-	 * @return mixed Returns `true` if a field is given and was updated, `false` otherwise and
-	 *		   `null` if the field was not set at all. If no field is given returns an arra
-	 *		   where the keys are entity field names, and the values are `true` for changed
-	 *         fields.
-	 */
-	public function modified($field = null) {
-		if ($field) {
-			if (!isset($this->_updated[$field]) && !isset($this->_data[$field])) {
-				return null;
-			}
-
-			if (!array_key_exists($field, $this->_updated)) {
-				return false;
-			}
-
-			$value = $this->_updated[$field];
-			if (is_object($value) && method_exists($value, 'modified')) {
-				$modified = $value->modified();
-				return $modified === true || is_array($modified) && in_array(true, $modified, true);
-			}
-
-			$isSet = isset($this->_data[$field]);
-			return !$isSet || ($this->_data[$field] !== $this->_updated[$field]);
-		}
-
-		$fields = array_fill_keys(array_keys($this->_data), false);
-
-		foreach ($this->_updated as $field => $value) {
-			if (is_object($value) && method_exists($value, 'modified')) {
-				if (!isset($this->_data[$field])) {
-					$fields[$field] = true;
-					continue;
-				}
-				$modified = $value->modified();
-
-				$fields[$field] = (
-					$modified === true || is_array($modified) && in_array(true, $modified, true)
-				);
-			} else {
-				$fields[$field] = (
-					!isset($fields[$field]) || $this->_data[$field] !== $this->_updated[$field]
-				);
-			}
-		}
-		return $fields;
-	}
-
-	public function export(array $options = array()) {
-		return array(
-			'exists'    => $this->_exists,
-			'data'      => $this->_data,
-			'update'    => $this->_updated,
-			'increment' => $this->_increment
-		);
-	}
-
-	/**
-	 * Configures protected properties of an `Entity` so that it is parented to `$parent`.
-	 *
-	 * @param object $parent
-	 * @param array $config
-	 * @return void
-	 */
-	public function assignTo($parent, array $config = array()) {
-		foreach ($config as $key => $val) {
-			$this->{'_' . $key} = $val;
-		}
-		$this->_parent =& $parent;
-	}
-
-	/**
-	 * Converts the data in the record set to a different format, i.e. an array.
-	 *
-	 * @param string $format currently only `array`
-	 * @param array $options
-	 * @return mixed
-	 */
-	public function to($format, array $options = array()) {
-		switch ($format) {
-			case 'array':
-				$data = $this->_updated;
-				$rel = array_map(function($obj) { return $obj->data(); }, $this->_relationships);
-				$data = $rel + $data;
-				$result = Collection::toArray($data, $options);
-			break;
-			case 'string':
-				$result = $this->__toString();
-			break;
-			default:
-				$result = $this;
-			break;
-		}
-		return $result;
-	}
-
-	/**
-	 * Returns a string representation of the `Entity` instance, based on the result of the
-	 * `'title'` meta value of the bound model class.
-	 *
-	 * @return string Returns the generated title of the object.
-	 */
-	public function __toString() {
-		return (string) $this->__call('title', array());
-	}
-}
-
-?>

+ 0 - 1377
frameworks/PHP/php-lithium/libraries/lithium/data/Model.php

@@ -1,1377 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data;
-
-use lithium\core\Libraries;
-use lithium\util\Set;
-use lithium\util\Inflector;
-use lithium\core\ConfigException;
-use BadMethodCallException;
-
-/**
- * The `Model` class is the starting point for the domain logic of your application.
- * Models are tasked with providing meaning to otherwise raw and unprocessed data (e.g.
- * user profile).
- *
- * Models expose a consistent and unified API to interact with an underlying datasource (e.g.
- * MongoDB, CouchDB, MySQL) for operations such as querying, saving, updating and deleting data
- * from the persistent storage.
- *
- * Models allow you to interact with your data in two fundamentally different ways: querying, and
- * data mutation (saving/updating/deleting). All query-related operations may be done through the
- * static `find()` method, along with some additional utility methods provided for convenience.
- *
- * Classes extending this one should, conventionally, be named as Plural, CamelCase and be
- * placed in the `models` directory. i.e. a posts model would be `model/Posts.php`.
- *
- * Examples:
- * {{{
- * // Return all 'post' records
- * Posts::find('all');
- * Posts::all();
- *
- * // With conditions and a limit
- * Posts::find('all', array('conditions' => array('published' => true), 'limit' => 10));
- * Posts::all(array('conditions' => array('published' => true), 'limit' => 10));
- *
- * // Integer count of all 'post' records
- * Posts::find('count');
- * Posts::count(); // This is equivalent to the above.
- *
- * // With conditions
- * Posts::find('count', array('conditions' => array('published' => true)));
- * Posts::count(array('published' => true));
- * }}}
- *
- * The actual objects returned from `find()` calls will depend on the type of data source in use.
- * MongoDB, for example, will return results as a `Document` (as will CouchDB), while MySQL will
- * return results as a `RecordSet`. Both of these classes extend a common `lithium\data\Collection`
- * class, and provide the necessary abstraction to make working with either type completely
- * transparent.
- *
- * For data mutation (saving/updating/deleting), the `Model` class acts as a broker to the proper
- * objects. When creating a new record or document, for example, a call to `Posts::create()` will
- * return an instance of `lithium\data\entity\Record` or `lithium\data\entity\Document`, which can
- * then be acted upon.
- *
- * Example:
- * {{{
- * $post = Posts::create();
- * $post->author = 'Robert';
- * $post->title = 'Newest Post!';
- * $post->content = 'Lithium rocks. That is all.';
- *
- * $post->save();
- * }}}
- *
- * @see lithium\data\entity\Record
- * @see lithium\data\entity\Document
- * @see lithium\data\collection\RecordSet
- * @see lithium\data\collection\DocumentSet
- * @see lithium\data\Connections
- */
-class Model extends \lithium\core\StaticObject {
-
-	/**
-	 * Criteria for data validation.
-	 *
-	 * Example usage:
-	 * {{{
-	 * public $validates = array(
-	 *     'title' => 'please enter a title',
-	 *     'email' => array(
-	 *         array('notEmpty', 'message' => 'Email is empty.'),
-	 *         array('email', 'message' => 'Email is not valid.'),
-	 *     )
-	 * );
-	 * }}}
-	 *
-	 * @var array
-	 */
-	public $validates = array();
-
-	/**
-	 * Model hasOne relations.
-	 * Not yet implemented.
-	 *
-	 * @var array
-	 */
-	public $hasOne = array();
-
-	/**
-	 * Model hasMany relations.
-	 * Not yet implemented.
-	 *
-	 * @var array
-	 */
-	public $hasMany = array();
-
-	/**
-	 * Model belongsTo relations.
-	 * Not yet implemented.
-	 *
-	 * @var array
-	 */
-	public $belongsTo = array();
-
-	/**
-	 * Stores model instances for internal use.
-	 *
-	 * While the `Model` public API does not require instantiation thanks to late static binding
-	 * introduced in PHP 5.3, LSB does not apply to class attributes. In order to prevent you
-	 * from needing to redeclare every single `Model` class attribute in subclasses, instances of
-	 * the models are stored and used internally.
-	 *
-	 * @var array
-	 */
-	protected static $_instances = array();
-
-	/**
-	 * List of initialized instances.
-	 *
-	 * @see lithium\data\Model::_initialize();
-	 * @var array
-	 */
-	protected static $_initialized = array();
-
-	/**
-	 * Stores the filters that are applied to the model instances stored in `Model::$_instances`.
-	 *
-	 * @var array
-	 */
-	protected $_instanceFilters = array();
-
-	/**
-	 * Class dependencies.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'connections' => 'lithium\data\Connections',
-		'query'       => 'lithium\data\model\Query',
-		'validator'   => 'lithium\util\Validator',
-		'entity'      => 'lithium\data\Entity'
-	);
-
-	/**
-	 * A list of the current relation types for this `Model`.
-	 *
-	 * @var array
-	 */
-	protected $_relations = array();
-
-	/**
-	 * List of relation types.
-	 *
-	 * Valid relation types are:
-	 *
-	 * - `belongsTo`
-	 * - `hasOne`
-	 * - `hasMany`
-	 *
-	 * @var array
-	 */
-	protected $_relationTypes = array('belongsTo', 'hasOne', 'hasMany');
-
-	/**
-	 * Store available relation names for this model which still unloaded.
-	 *
-	 * @var array This array use the following notation : `relation_name => relation_type`.
-	 */
-	protected $_relationsToLoad = array();
-
-	/**
-	 * Specifies all meta-information for this model class, including the name of the data source it
-	 * connects to, how it interacts with that class, and how its data structure is defined.
-	 *
-	 * - `connection`: The name of the connection (as defined in `Connections::add()`) to which the
-	 *   model should bind
-	 * - `key`: The primary key or identifier key for records / documents this model produces,
-	 *   i.e. `'id'` or `array('_id', '_rev')`. Defaults to `'id'`.
-	 * - `name`: The canonical name of this model. Defaults to the class name.
-	 * - `source`: The name of the database table or document collection to bind to. Defaults to the
-	 *   lower-cased and underscored name of the class, i.e. `class UserProfile` maps to
-	 *   `'user_profiles'`.
-	 * - `title`: The field or key used as the title for each record. Defaults to `'title'` or
-	 *   `'name'`, if those fields are available.
-	 *
-	 * @var array
-	 * @see lithium\data\Connections::add()
-	 */
-	protected $_meta = array(
-		'name' => null,
-		'title' => null,
-		'class' => null,
-		'source' => null,
-		'connection' => 'default'
-	);
-
-	/**
-	 * Array of closures used to lazily initialize metadata.
-	 *
-	 * @var array
-	 */
-	protected $_initializers = array();
-
-	/**
-	 * Stores the data schema.
-	 *
-	 * The schema is lazy-loaded by the first call to `Model::schema()`, unless it has been
-	 * manually defined in the `Model` subclass.
-	 *
-	 * For schemaless persistent storage (e.g. MongoDB), this is never populated automatically - if
-	 * you desire a fixed schema to interact with in those cases, you will be required to define it
-	 * yourself.
-	 *
-	 * Example:
-	 * {{{
-	 * protected $_schema = array(
-	 *     '_id'  => array('type' => 'id'), // required for Mongo
-	 *     'name' => array('type' => 'string', 'default' => 'Moe', 'null' => false),
-	 *     'sign' => array('type' => 'string', 'default' => 'bar', 'null' => false),
-	 *     'age'  => array('type' => 'integer', 'default' => 0, 'null' => false)
-	 * );
-	 * }}}
-	 *
-	 * For MongoDB specifically, you can also implement a callback in your database connection
-	 * configuration that fetches and returns the schema data, as in the following:
-	 *
-	 * {{{
-	 * // config/bootstrap/connections.php:
-	 * Connections::add('default', array(
-	 * 	'type' => 'MongoDb',
-	 * 	'host' => 'localhost',
-	 * 	'database' => 'app_name',
-	 * 	'schema' => function($db, $collection, $meta) {
-	 * 		$result = $db->connection->schemas->findOne(compact('collection'));
-	 * 		return $result ? $result['data'] : array();
-	 * 	}
-	 * ));
-	 * }}}
-	 *
-	 * This example defines an optional MongoDB convention in which the schema for each individual
-	 * collection is stored in a "schemas" collection, where each document contains the name of
-	 * 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:
-	 *
-	 * {{{
-	 *	id      => MongoId
-	 *	date    => MongoDate
-	 *	regex   => MongoRegex
-	 *	integer => integer
-	 *	float   => float
-	 *	boolean => boolean
-	 *	code    => MongoCode
-	 *	binary  => MongoBinData
-	 * }}}
-	 *
-	 * @see lithium\data\source\MongoDb::$_schema
-	 * @var array
-	 */
-	protected $_schema = array();
-
-	/**
-	 * Default query parameters.
-	 *
-	 * - `'conditions'`: The conditional query elements, e.g.
-	 *                 `'conditions' => array('published' => true)`
-	 * - `'fields'`: The fields that should be retrieved. When set to `null`, defaults to
-	 *             all fields.
-	 * - `'order'`: The order in which the data will be returned, e.g. `'order' => 'ASC'`.
-	 * - `'limit'`: The maximum number of records to return.
-	 * - `'page'`: For pagination of data.
-	 * - `'with'`: An array of relationship names to be included in the query.
-	 *
-	 * @var array
-	 */
-	protected $_query = array(
-		'conditions' => null,
-		'fields'     => null,
-		'order'      => null,
-		'limit'      => null,
-		'page'       => null,
-		'with'       => array()
-	);
-
-	/**
-	 * Custom find query properties, indexed by name.
-	 *
-	 * @see lithium\data\Model::finder()
-	 * @var array
-	 */
-	protected $_finders = array();
-
-	/**
-	 * Stores all custom instance methods created by `Model::instanceMethods`.
-	 *
-	 * @var array
-	 */
-	protected static $_instanceMethods = array();
-
-	/**
-	 * Holds an array of values that should be processed on `Model::config()`. Each value should
-	 * have a matching protected property (prefixed with `_`) defined in the class. If the
-	 * property is an array, the property name should be the key and the value should be `'merge'`.
-	 *
-	 * @see lithium\data\Model::config()
-	 * @var array
-	 */
-	protected $_autoConfig = array(
-		'meta',
-		'finders',
-		'query',
-		'schema',
-		'classes',
-		'initializers'
-	);
-
-	/**
-	 * Configures the model for use. This method will set the `Model::$_schema`, `Model::$_meta`,
-	 * `Model::$_finders` class attributes, as well as obtain a handle to the configured
-	 * persistent storage connection.
-	 *
-	 * @param array $config Possible options are:
-	 *        - `meta`: Meta-information for this model, such as the connection.
-	 *        - `finders`: Custom finders for this model.
-	 *        - `query`: Default query parameters.
-	 *        - `schema`: A `Schema` instance for this model.
-	 *        - `classes`: Classes used by this model.
-	 */
-	public static function config(array $config = array()) {
-		if (($class = get_called_class()) === __CLASS__) {
-			return;
-		}
-
-		if (!isset(static::$_instances[$class])) {
-			static::$_instances[$class] = new $class();
-		}
-		$self = static::$_instances[$class];
-
-		foreach ($self->_autoConfig as $key) {
-			if (isset($config[$key])) {
-				$_key = "_{$key}";
-				$val = $config[$key];
-				$self->$_key = is_array($val) ? $val + $self->$_key : $val;
-			}
-		}
-
-		static::$_initialized[$class] = false;
-	}
-
-	/**
-	 * Init default connection options and connects default finders.
-	 *
-	 * This method will set the `Model::$_schema`, `Model::$_meta`, `Model::$_finders` class
-	 * attributes, as well as obtain a handle to the configured persistent storage connection
-	 *
-	 * @param string $class The fully-namespaced class name to initialize.
-	 * @return object Returns the initialized model instance.
-	 */
-	protected static function _initialize($class) {
-		$self = static::$_instances[$class];
-
-		if (isset(static::$_initialized[$class]) && static::$_initialized[$class]) {
-			return $self;
-		}
-		static::$_initialized[$class] = true;
-
-		$query   = array();
-		$finders = array();
-		$meta    = array();
-		$schema  = array();
-		$source  = array();
-		$classes = $self->_classes;
-		$initializers = array();
-
-		foreach (static::_parents() as $parent) {
-			$parentConfig = get_class_vars($parent);
-
-			foreach ($self->_autoConfig as $key) {
-				if (isset($parentConfig["_{$key}"])) {
-					$val = $parentConfig["_{$key}"];
-					${$key} = is_array($val) ? ${$key} + $val : $val;
-				}
-			}
-			if ($parent === __CLASS__) {
-				break;
-			}
-		}
-
-		$tmp = $self->_meta + $meta;
-		$source = array('meta' => array(), 'finders' => array(), 'schema' => array());
-
-		if ($tmp['connection']) {
-			$conn = $classes['connections']::get($tmp['connection']);
-			$source = (($conn) ? $conn->configureClass($class) : array()) + $source;
-		}
-		$self->_classes = $classes;
-
-		$local = compact('class') + $self->_meta;
-		$self->_meta = ($local + $source['meta'] + $meta);
-
-		$self->_initializers += array(
-			'name' => function($self) {
-				return basename(str_replace('\\', '/', $self));
-			},
-			'source' => function($self) {
-				return Inflector::tableize($self::meta('name'));
-			},
-			'title' => function($self) {
-				$titleKeys = array('title', 'name');
-				$titleKeys = array_merge($titleKeys, (array) $self::meta('key'));
-				return $self::hasField($titleKeys);
-			}
-		);
-
-		if (is_object($self->_schema)) {
-			$self->_schema->append($source['schema']);
-		} elseif (is_array($self->_schema)) {
-			$self->_schema = $self->_schema + $source['schema'];
-		} else {
-			$self->_schema = $source['schema'];
-		}
-
-		$self->_finders += $source['finders'] + $self->_findFilters();
-
-		static::_relationsToLoad();
-		return $self;
-	}
-
-	/**
-	 * Returns an instance of a class with given `config`. The `name` could be a key from the
-	 * `classes` array, a fully-namespaced class name, or an object. Typically this method is used
-	 * in `_init` to create the dependencies used in the current class.
-	 *
-	 * @param string|object $name A `classes` alias or fully-namespaced class name.
-	 * @param array $options The configuration passed to the constructor.
-	 * @return object
-	 */
-	protected static function _instance($name, array $options = array()) {
-		$self = static::_object();
-		if (is_string($name) && isset($self->_classes[$name])) {
-			$name = $self->_classes[$name];
-		}
-		return Libraries::instance(null, $name, $options);
-	}
-
-	/**
-	 * Allows the use of syntactic-sugar like `Model::all()` instead of `Model::find('all')`.
-	 *
-	 * @see lithium\data\Model::find()
-	 * @see lithium\data\Model::$_meta
-	 * @link http://php.net/manual/en/language.oop5.overloading.php PHP Manual: Overloading
-	 *
-	 * @throws BadMethodCallException On unhandled call, will throw an exception.
-	 * @param string $method Method name caught by `__callStatic()`.
-	 * @param array $params Arguments given to the above `$method` call.
-	 * @return mixed Results of dispatched `Model::find()` call.
-	 */
-	public static function __callStatic($method, $params) {
-		$self = static::_object();
-		$isFinder = isset($self->_finders[$method]);
-
-		if ($isFinder && count($params) === 2 && is_array($params[1])) {
-			$params = array($params[1] + array($method => $params[0]));
-		}
-
-		if ($method === 'all' || $isFinder) {
-			if ($params && !is_array($params[0])) {
-				$params[0] = array('conditions' => static::key($params[0]));
-			}
-			return $self::find($method, $params ? $params[0] : array());
-		}
-		preg_match('/^findBy(?P<field>\w+)$|^find(?P<type>\w+)By(?P<fields>\w+)$/', $method, $args);
-
-		if (!$args) {
-			$message = "Method `%s` not defined or handled in class `%s`.";
-			throw new BadMethodCallException(sprintf($message, $method, get_class($self)));
-		}
-
-		$field = Inflector::underscore($args['field'] ? $args['field'] : $args['fields']);
-		$type = isset($args['type']) ? $args['type'] : 'first';
-		$type[0] = strtolower($type[0]);
-
-		$conditions = array($field => array_shift($params));
-		$params = (isset($params[0]) && count($params) === 1) ? $params[0] : $params;
-		return $self::find($type, compact('conditions') + $params);
-	}
-
-	/**
-	 * Magic method that allows calling `Model::_instanceMethods`'s closure like normal methods
-	 * on the model instance.
-	 *
-	 * @see lithium\data\Model::instanceMethods
-	 * @param string $method Method name caught by `__call()`.
-	 * @param array $params Arguments given to the above `$method` call.
-	 * @return mixed
-	 */
-	public function __call($method, $params) {
-		$methods = static::instanceMethods();
-		if (isset($methods[$method]) && is_callable($methods[$method])) {
-			return call_user_func_array($methods[$method], $params);
-		}
-		$message = "Unhandled method call `{$method}`.";
-		throw new BadMethodCallException($message);
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public static function respondsTo($method, $internal = false) {
-		$self = static::_object();
-		$methods = static::instanceMethods();
-		$isFinder = isset($self->_finders[$method]);
-		preg_match('/^findBy(?P<field>\w+)$|^find(?P<type>\w+)By(?P<fields>\w+)$/', $method, $args);
-		$staticRepondsTo = $isFinder || $method === 'all' || !!$args;
-		$instanceRespondsTo = isset($methods[$method]);
-		return $instanceRespondsTo || $staticRepondsTo || parent::respondsTo($method, $internal);
-	}
-
-	/**
-	 * The `find` method allows you to retrieve data from the connected data source.
-	 *
-	 * Examples:
-	 * {{{
-	 * Posts::find('all'); // returns all records
-	 * Posts::find('count'); // returns a count of all records
-	 *
-	 * // The first ten records that have 'author' set to 'Lithium'
-	 * Posts::find('all', array(
-	 *     'conditions' => array('author' => "Bob"), 'limit' => 10
-	 * ));
-	 * }}}
-	 *
-	 * @see lithium\data\Model::$_finders
-	 * @param string $type The find type, which is looked up in `Model::$_finders`. By default it
-	 *        accepts `all`, `first`, `list` and `count`,
-	 * @param array $options Options for the query. By default, accepts:
-	 *        - `conditions`: The conditional query elements, e.g.
-	 *                 `'conditions' => array('published' => true)`
-	 *        - `fields`: The fields that should be retrieved. When set to `null`, defaults to
-	 *             all fields.
-	 *        - `order`: The order in which the data will be returned, e.g. `'order' => 'ASC'`.
-	 *        - `limit`: The maximum number of records to return.
-	 *        - `page`: For pagination of data.
-	 * @return mixed
-	 * @filter This method can be filtered.
-	 */
-	public static function find($type, array $options = array()) {
-		$self = static::_object();
-		$finder = array();
-
-		if ($type === null) {
-			return null;
-		}
-		$isFinder = is_string($type) && isset($self->_finders[$type]);
-
-		if ($type !== 'all' && !is_array($type) && !$isFinder) {
-			$options['conditions'] = static::key($type);
-			$type = 'first';
-		}
-
-		if ($isFinder && is_array($self->_finders[$type])) {
-			$options = Set::merge($self->_finders[$type], $options);
-		}
-
-		$options = (array) $options + (array) $self->_query;
-		$meta = array('meta' => $self->_meta, 'name' => get_called_class());
-		$params = compact('type', 'options');
-
-		$filter = function($self, $params) use ($meta) {
-			$options = $params['options'] + array('type' => 'read', 'model' => $meta['name']);
-			$query = $self::invokeMethod('_instance', array('query', $options));
-			return $self::connection()->read($query, $options);
-		};
-		if (is_string($type) && isset($self->_finders[$type])) {
-			$finder = is_callable($self->_finders[$type]) ? array($self->_finders[$type]) : array();
-		}
-		return static::_filter(__FUNCTION__, $params, $filter, $finder);
-	}
-
-	/**
-	 * Gets or sets a finder by name.  This can be an array of default query options,
-	 * or a closure that accepts an array of query options, and a closure to execute.
-	 *
-	 * @param string $name The finder name, e.g. `first`.
-	 * @param string $finder If you are setting a finder, this is the finder definition.
-	 * @return mixed Returns finder definition if querying, or `null` if setting.
-	 */
-	public static function finder($name, $finder = null) {
-		$self = static::_object();
-
-		if (!$finder) {
-			return isset($self->_finders[$name]) ? $self->_finders[$name] : null;
-		}
-		$self->_finders[$name] = $finder;
-	}
-
-	/**
-	 * Gets or sets the default query for the model.
-	 *
-	 * @param array $query.  Possible options are:
-	 *        - `'conditions'`: The conditional query elements, e.g.
-	 *          `'conditions' => array('published' => true)`
-	 *        - `'fields'`: The fields that should be retrieved. When set to `null`, defaults to
-	 *          all fields.
-	 *        - `'order'`: The order in which the data will be returned, e.g. `'order' => 'ASC'`.
-	 *        - `'limit'`: The maximum number of records to return.
-	 *        - `'page'`: For pagination of data.
-	 *        - `'with'`: An array of relationship names to be included in the query.
-	 *
-	 * @return mixed Returns the query definition if querying, or `null` if setting.
-	 */
-	public static function query($query = null) {
-		$self = static::_object();
-
-		if (!$query) {
-			return $self->_query;
-		}
-		$self->_query += $query;
-	}
-
-	/**
-	 * Gets or sets Model's metadata.
-	 *
-	 * @see lithium\data\Model::$_meta
-	 * @param string $key Model metadata key.
-	 * @param string $value Model metadata value.
-	 * @return mixed Metadata value for a given key.
-	 */
-	public static function meta($key = null, $value = null) {
-		$self = static::_object();
-		$isArray = is_array($key);
-
-		if ($value || $isArray) {
-			$value ? $self->_meta[$key] = $value : $self->_meta = $key + $self->_meta;
-			return;
-		}
-		return $self->_getMetaKey($isArray ? null : $key);
-	}
-
-	/**
-	 * Helper method used by `meta()` to generate and cache metadata values.
-	 *
-	 * @param string $key The name of the meta value to return, or `null`, to return all values.
-	 * @return mixed Returns the value of the meta key specified by `$key`, or an array of all meta
-	 *         values if `$key` is `null`.
-	 */
-	protected function _getMetaKey($key = null) {
-		if (!$key) {
-			$all = array_keys($this->_initializers);
-			$call = array(&$this, '_getMetaKey');
-			return $all ? array_combine($all, array_map($call, $all)) + $this->_meta : $this->_meta;
-		}
-
-		if (isset($this->_meta[$key])) {
-			return $this->_meta[$key];
-		}
-		if (isset($this->_initializers[$key]) && $initializer = $this->_initializers[$key]) {
-			unset($this->_initializers[$key]);
-			return ($this->_meta[$key] = $initializer(get_called_class()));
-		}
-	}
-
-	/**
-	 * The `title()` method is invoked whenever an `Entity` object is cast or coerced
-	 * to a string. This method can also be called on the entity directly, i.e. `$post->title()`.
-	 *
-	 * By default, when generating the title for an object, it uses the the field specified in
-	 * the `'title'` key of the model's meta data definition. Override this method to generate
-	 * custom titles for objects of this model's type.
-	 *
-	 * @see lithium\data\Model::$_meta
-	 * @see lithium\data\Entity::__toString()
-	 * @param object $entity The `Entity` instance on which the title method is called.
-	 * @return string Returns the title representation of the entity on which this method is called.
-	 */
-	public function title($entity) {
-		$field = static::meta('title');
-		return $entity->{$field};
-	}
-
-	/**
-	 * If no values supplied, returns the name of the `Model` key. If values
-	 * are supplied, returns the key value.
-	 *
-	 * @param mixed $values An array of values or object with values. If `$values` is `null`,
-	 *              the meta `'key'` of the model is returned.
-	 * @return mixed Key value.
-	 */
-	public static function key($values = null) {
-		$key = static::meta('key');
-
-		if ($values === null) {
-			return $key;
-		}
-
-		$self = static::_object();
-		$entity = $self->_classes['entity'];
-		if (is_object($values) && is_string($key)) {
-			return static::_key($key, $values, $entity);
-		} elseif ($values instanceof $entity) {
-			$values = $values->to('array');
-		}
-
-		if (!is_array($values) && !is_array($key)) {
-			return array($key => $values);
-		}
-
-		$key = (array) $key;
-		$result = array();
-		foreach ($key as $value) {
-			if (!isset($values[$value])) {
-				return null;
-			}
-			$result[$value] = $values[$value];
-		}
-		return $result;
-	}
-
-	/**
-	 * Helper for the `Model::key()` function
-	 *
-	 * @see lithium\data\Model::key()
-	 * @param string $key The key
-	 * @param object $values Object with attributes.
-	 * @param string $entity The fully-namespaced entity class name.
-	 * @return mixed The key value array or `null` if the `$values` object has no attribute
-	 *         named `$key`
-	 */
-	protected static function _key($key, $values, $entity) {
-		if (isset($values->$key)) {
-			return array($key => $values->$key);
-		} elseif (!$values instanceof $entity) {
-			return array($key => $values);
-		}
-		return null;
-	}
-
-	/**
-	 * Returns a list of models related to `Model`, or a list of models related
-	 * to this model, but of a certain type.
-	 *
-	 * @param string $type A type of model relation.
-	 * @return mixed An array of relation instances or an instance of relation.
-	 *
-	 */
-	public static function relations($type = null) {
-		$self = static::_object();
-
-		if ($type === null) {
-			return static::_relations();
-		}
-
-		if (isset($self->_relations[$type])) {
-			return $self->_relations[$type];
-		}
-
-		if (isset($self->_relationsToLoad[$type])) {
-			return static::_relations(null, $type);
-		}
-
-		if (in_array($type, $self->_relationTypes, true)) {
-			return array_keys(static::_relations($type));
-		}
-		return null;
-	}
-
-	/**
-	 * This method automagically bind in the fly unloaded relations.
-	 *
-	 * @see lithium\data\model::relations()
-	 * @param $type A type of model relation.
-	 * @param $name A relation name.
-	 * @return An array of relation instances or an instance of relation.
-	 */
-	protected static function _relations($type = null, $name = null) {
-		$self = static::_object();
-
-		if ($name) {
-			if (isset($self->_relationsToLoad[$name])) {
-				$t = $self->_relationsToLoad[$name];
-				unset($self->_relationsToLoad[$name]);
-				return static::bind($t, $name, (array) $self->{$t}[$name]);
-			}
-			return isset($self->_relations[$name]) ? $self->_relations[$name] : null;
-		}
-		if (!$type) {
-			foreach ($self->_relationsToLoad as $name => $t) {
-				static::bind($t, $name, (array) $self->{$t}[$name]);
-			}
-			$self->_relationsToLoad = array();
-			return $self->_relations;
-		}
-		foreach ($self->_relationsToLoad as $name => $t) {
-			if ($type === $t) {
-				static::bind($t, $name, (array) $self->{$t}[$name]);
-				unset($self->_relationsToLoad[$name]);
-			}
-		}
-		return array_filter($self->_relations, function($i) use ($type) {
-			return $i->data('type') === $type;
-		});
-	}
-
-
-	/**
-	 * Creates a relationship binding between this model and another.
-	 *
-	 * @see lithium\data\model\Relationship
-	 * @param string $type The type of relationship to create. Must be one of `'hasOne'`,
-	 *               `'hasMany'` or `'belongsTo'`.
-	 * @param string $name The name of the relationship. If this is also the name of the model,
-	 *               the model must be in the same namespace as this model. Otherwise, the
-	 *               fully-namespaced path to the model class must be specified in `$config`.
-	 * @param array $config Any other configuration that should be specified in the relationship.
-	 *              See the `Relationship` class for more information.
-	 * @return object Returns an instance of the `Relationship` class that defines the connection.
-	 */
-	public static function bind($type, $name, array $config = array()) {
-		$self = static::_object();
-
-		if (!in_array($type, $self->_relationTypes)) {
-			throw new ConfigException("Invalid relationship type `{$type}` specified.");
-		}
-		$rel = static::connection()->relationship(get_called_class(), $type, $name, $config);
-		return $self->_relations[$name] = $rel;
-	}
-
-	/**
-	 * Lazy-initialize the schema for this Model object, if it is not already manually set in the
-	 * object. You can declare `protected $_schema = array(...)` to define the schema manually.
-	 *
-	 * @param mixed $field Optional. You may pass a field name to get schema information for just
-	 *        one field. Otherwise, an array containing all fields is returned. If `false`, the
-	 *        schema is reset to an empty value. If an array, field definitions contained are
-	 *        appended to the schema.
-	 * @return array
-	 */
-	public static function schema($field = null) {
-		$self = static::_object();
-
-		if (!is_object($self->_schema)) {
-			$self->_schema = static::connection()->describe(
-				$self::meta('source'), $self->_schema, $self->_meta
-			);
-			if (!is_object($self->_schema)) {
-				$class = get_called_class();
-				throw new ConfigException("Could not load schema object for model `{$class}`.");
-			}
-			$key = (array) $self::meta('key');
-
-			if ($self->_schema && $self->_schema->fields() && !$self->_schema->has($key)) {
-				$key = implode('`, `', $key);
-				throw new ConfigException("Missing key `{$key}` from schema.");
-			}
-		}
-		if ($field === false) {
-			return $self->_schema->reset();
-		}
-		if (is_array($field)) {
-			return $self->_schema->append($field);
-		}
-		return $field ? $self->_schema->fields($field) : $self->_schema;
-	}
-
-	/**
-	 * Checks to see if a particular field exists in a model's schema. Can check a single field, or
-	 * return the first field found in an array of multiple options.
-	 *
-	 * @param mixed $field A single field (string) or list of fields (array) to check the existence
-	 *        of.
-	 * @return mixed If `$field` is a string, returns a boolean indicating whether or not that field
-	 *         exists. If `$field` is an array, returns the first field found, or `false` if none of
-	 *         the fields in the list are found.
-	 */
-	public static function hasField($field) {
-		if (!is_array($field)) {
-			return static::schema()->fields($field);
-		}
-		foreach ($field as $f) {
-			if (static::hasField($f)) {
-				return $f;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Instantiates a new record or document object, initialized with any data passed in. For
-	 * example:
-	 *
-	 * {{{
-	 * $post = Posts::create(array('title' => 'New post'));
-	 * echo $post->title; // echoes 'New post'
-	 * $success = $post->save();
-	 * }}}
-	 *
-	 * Note that while this method creates a new object, there is no effect on the database until
-	 * the `save()` method is called.
-	 *
-	 * In addition, this method can be used to simulate loading a pre-existing object from the
-	 * database, without actually querying the database:
-	 *
-	 * {{{
-	 * $post = Posts::create(array('id' => $id, 'moreData' => 'foo'), array('exists' => true));
-	 * $post->title = 'New title';
-	 * $success = $post->save();
-	 * }}}
-	 *
-	 * This will create an update query against the object with an ID matching `$id`. Also note that
-	 * only the `title` field will be updated.
-	 *
-	 * @param array $data Any data that this object should be populated with initially.
-	 * @param array $options Options to be passed to item.
-	 * @return object Returns a new, _un-saved_ record or document object. In addition to the values
-	 *         passed to `$data`, the object will also contain any values assigned to the
-	 *         `'default'` key of each field defined in `$_schema`.
-	 * @filter
-	 */
-	public static function create(array $data = array(), array $options = array()) {
-		return static::_filter(__FUNCTION__, compact('data', 'options'), function($self, $params) {
-			$data = Set::merge(Set::expand($self::schema()->defaults()), $params['data']);
-			return $self::connection()->item($self, $data, $params['options']);
-		});
-	}
-
-	/**
-	 * Getter and setter for custom instance methods. This is used in `Entity::__call()`.
-	 *
-	 * {{{
-	 * Model::instanceMethods(array(
-	 *     'methodName' => array('Class', 'method'),
-	 *     'anotherMethod' => array($object, 'method'),
-	 *     'closureCallback' => function($entity) {}
-	 * ));
-	 * }}}
-	 *
-	 * @see lithium\data\Entity::__call()
-	 * @param array $methods
-	 * @return array
-	 */
-	public static function instanceMethods(array $methods = null) {
-		$class = get_called_class();
-
-		if (!isset(static::$_instanceMethods[$class])) {
-			static::$_instanceMethods[$class] = array();
-		}
-		if ($methods === array()) {
-			return static::$_instanceMethods[$class] = array();
-		}
-		if (!is_null($methods)) {
-			static::$_instanceMethods[$class] = $methods + static::$_instanceMethods[$class];
-		}
-		return static::$_instanceMethods[$class];
-	}
-
-	/**
-	 * An instance method (called on record and document objects) to create or update the record or
-	 * document in the database that corresponds to `$entity`.
-	 *
-	 * For example, to create a new record or document:
-	 * {{{
-	 * $post = Posts::create(); // Creates a new object, which doesn't exist in the database yet
-	 * $post->title = "My post";
-	 * $success = $post->save();
-	 * }}}
-	 *
-	 * It is also used to update existing database objects, as in the following:
-	 * {{{
-	 * $post = Posts::first($id);
-	 * $post->title = "Revised title";
-	 * $success = $post->save();
-	 * }}}
-	 *
-	 * By default, an object's data will be checked against the validation rules of the model it is
-	 * bound to. Any validation errors that result can then be accessed through the `errors()`
-	 * method.
-	 *
-	 * {{{
-	 * if (!$post->save($someData)) {
-	 * 	return array('errors' => $post->errors());
-	 * }
-	 * }}}
-	 *
-	 * To override the validation checks and save anyway, you can pass the `'validate'` option:
-	 *
-	 * {{{
-	 * $post->title = "We Don't Need No Stinkin' Validation";
-	 * $post->body = "I know what I'm doing.";
-	 * $post->save(null, array('validate' => false));
-	 * }}}
-	 *
-	 * @see lithium\data\Model::$validates
-	 * @see lithium\data\Model::validates()
-	 * @see lithium\data\Entity::errors()
-	 * @param object $entity The record or document object to be saved in the database. This
-	 *               parameter is implicit and should not be passed under normal circumstances.
-	 *               In the above example, the call to `save()` on the `$post` object is
-	 *               transparently proxied through to the `Posts` model class, and `$post` is passed
-	 *               in as the `$entity` parameter.
-	 * @param array $data Any data that should be assigned to the record before it is saved.
-	 * @param array $options Options:
-	 *        - `'callbacks'` _boolean_: If `false`, all callbacks will be disabled before
-	 *           executing. Defaults to `true`.
-	 *        - `'validate'` _mixed_: If `false`, validation will be skipped, and the record will
-	 *          be immediately saved. Defaults to `true`. May also be specified as an array, in
-	 *          which case it will replace the default validation rules specified in the
-	 *         `$validates` property of the model.
-	 *        - `'events'` _mixed_: A string or array defining one or more validation _events_.
-	 *          Events are different contexts in which data events can occur, and correspond to the
-	 *          optional `'on'` key in validation rules. They will be passed to the validates()
-	 *          method if `'validate'` is not `false`.
-	 *        - `'whitelist'` _array_: An array of fields that are allowed to be saved to this
-	 *          record.
-	 *
-	 * @return boolean Returns `true` on a successful save operation, `false` on failure.
-	 * @filter
-	 */
-	public function save($entity, $data = null, array $options = array()) {
-		$self = static::_object();
-		$_meta = array('model' => get_called_class()) + $self->_meta;
-		$_schema = $self->schema();
-
-		$defaults = array(
-			'validate' => true,
-			'events' => $entity->exists() ? 'update' : 'create',
-			'whitelist' => null,
-			'callbacks' => true,
-			'locked' => $self->_meta['locked']
-		);
-		$options += $defaults;
-		$params = compact('entity', 'data', 'options');
-
-		$filter = function($self, $params) use ($_meta, $_schema) {
-			$entity = $params['entity'];
-			$options = $params['options'];
-
-			if ($params['data']) {
-				$entity->set($params['data']);
-			}
-			if ($rules = $options['validate']) {
-				$events = $options['events'];
-				$validateOpts = is_array($rules) ? compact('rules','events') : compact('events');
-
-				if (!$entity->validates($validateOpts)) {
-					return false;
-				}
-			}
-			if (($whitelist = $options['whitelist']) || $options['locked']) {
-				$whitelist = $whitelist ?: array_keys($_schema->fields());
-			}
-
-			$type = $entity->exists() ? 'update' : 'create';
-			$queryOpts = compact('type', 'whitelist', 'entity') + $options + $_meta;
-			$query = $self::invokeMethod('_instance', array('query', $queryOpts));
-			return $self::connection()->{$type}($query, $options);
-		};
-
-		if (!$options['callbacks']) {
-			return $filter(get_called_class(), $params);
-		}
-		return static::_filter(__FUNCTION__, $params, $filter);
-	}
-
-	/**
-	 * An important part of describing the business logic of a model class is defining the
-	 * validation rules. In Lithium models, rules are defined through the `$validates` class
-	 * property, and are used by this method before saving to verify the correctness of the data
-	 * being sent to the backend data source.
-	 *
-	 * Note that these are application-level validation rules, and do not
-	 * interact with any rules or constraints defined in your data source. If such constraints fail,
-	 * an exception will be thrown by the database layer. The `validates()` method only checks
-	 * against the rules defined in application code.
-	 *
-	 * This method uses the `Validator` class to perform data validation. An array representation of
-	 * the entity object to be tested is passed to the `check()` method, along with the model's
-	 * validation rules. Any rules defined in the `Validator` class can be used to validate fields.
-	 * See the `Validator` class to add custom rules, or override built-in rules.
-	 *
-	 * @see lithium\data\Model::$validates
-	 * @see lithium\util\Validator::check()
-	 * @see lithium\data\Entity::errors()
-	 * @param string $entity Model entity to validate. Typically either a `Record` or `Document`
-	 *               object. In the following example:
-	 * {{{
-	 * $post = Posts::create($data);
-	 * $success = $post->validates();
-	 * }}}
-	 * The `$entity` parameter is equal to the `$post` object instance.
-	 * @param array $options Available options:
-	 *              - `'rules'` _array_: If specified, this array will _replace_ the default
-	 *                validation rules defined in `$validates`.
-	 *              - `'events'` _mixed_: A string or array defining one or more validation
-	 *                 _events_. Events are different contexts in which data events can occur, and
-	 *                correspond to the optional `'on'` key in validation rules. For example, by
-	 *                default, `'events'` is set to either `'create'` or `'update'`, depending on
-	 *                whether `$entity` already exists. Then, individual rules can specify
-	 *                `'on' => 'create'` or `'on' => 'update'` to only be applied at certain times.
-	 *                Using this parameter, you can set up custom events in your rules as well, such
-	 *                as `'on' => 'login'`. Note that when defining validation rules, the `'on'` key
-	 *                can also be an array of multiple events.
-	 * @return boolean Returns `true` if all validation rules on all fields succeed, otherwise
-	 *         `false`. After validation, the messages for any validation failures are assigned to
-	 *         the entity, and accessible through the `errors()` method of the entity object.
-	 * @filter
-	 */
-	public function validates($entity, array $options = array()) {
-		$defaults = array(
-			'rules' => $this->validates,
-			'events' => $entity->exists() ? 'update' : 'create',
-			'model' => get_called_class()
-		);
-		$options += $defaults;
-		$self = static::_object();
-		$validator = $self->_classes['validator'];
-		$params = compact('entity', 'options');
-
-		$filter = function($parent, $params) use (&$self, $validator) {
-			$entity = $params['entity'];
-			$options = $params['options'];
-			$rules = $options['rules'];
-			unset($options['rules']);
-
-			if ($errors = $validator::check($entity->data(), $rules, $options)) {
-				$entity->errors($errors);
-			}
-			return empty($errors);
-		};
-		return static::_filter(__FUNCTION__, $params, $filter);
-	}
-
-	/**
-	 * Deletes the data associated with the current `Model`.
-	 *
-	 * @param object $entity Entity to delete.
-	 * @param array $options Options.
-	 * @return boolean Success.
-	 * @filter
-	 */
-	public function delete($entity, array $options = array()) {
-		$params = compact('entity', 'options');
-
-		return static::_filter(__FUNCTION__, $params, function($self, $params) {
-			$options = $params + $params['options'] + array('model' => $self, 'type' => 'delete');
-			unset($options['options']);
-
-			$query = $self::invokeMethod('_instance', array('query', $options));
-			return $self::connection()->delete($query, $options);
-		});
-	}
-
-	/**
-	 * Update multiple records or documents with the given data, restricted by the given set of
-	 * criteria (optional).
-	 *
-	 * @param mixed $data Typically an array of key/value pairs that specify the new data with which
-	 *              the records will be updated. For SQL databases, this can optionally be an SQL
-	 *              fragment representing the `SET` clause of an `UPDATE` query.
-	 * @param mixed $conditions An array of key/value pairs representing the scope of the records
-	 *              to be updated.
-	 * @param array $options Any database-specific options to use when performing the operation. See
-	 *              the `delete()` method of the corresponding backend database for available
-	 *              options.
-	 * @return boolean Returns `true` if the update operation succeeded, otherwise `false`.
-	 * @filter
-	 */
-	public static function update($data, $conditions = array(), array $options = array()) {
-		$params = compact('data', 'conditions', 'options');
-
-		return static::_filter(__FUNCTION__, $params, function($self, $params) {
-			$options = $params + $params['options'] + array('model' => $self, 'type' => 'update');
-			unset($options['options']);
-
-			$query = $self::invokeMethod('_instance', array('query', $options));
-			return $self::connection()->update($query, $options);
-		});
-	}
-
-	/**
-	 * Remove multiple documents or records based on a given set of criteria. **WARNING**: If no
-	 * criteria are specified, or if the criteria (`$conditions`) is an empty value (i.e. an empty
-	 * array or `null`), all the data in the backend data source (i.e. table or collection) _will_
-	 * be deleted.
-	 *
-	 * @param mixed $conditions An array of key/value pairs representing the scope of the records or
-	 *              documents to be deleted.
-	 * @param array $options Any database-specific options to use when performing the operation. See
-	 *              the `delete()` method of the corresponding backend database for available
-	 *              options.
-	 * @return boolean Returns `true` if the remove operation succeeded, otherwise `false`.
-	 * @filter
-	 */
-	public static function remove($conditions = array(), array $options = array()) {
-		$params = compact('conditions', 'options');
-
-		return static::_filter(__FUNCTION__, $params, function($self, $params) {
-			$options = $params['options'] + $params + array('model' => $self, 'type' => 'delete');
-			unset($options['options']);
-
-			$query = $self::invokeMethod('_instance', array('query', $options));
-			return $self::connection()->delete($query, $options);
-		});
-	}
-
-	/**
-	 * Gets the connection object to which this model is bound. Throws exceptions if a connection
-	 * isn't set, or if the connection named isn't configured.
-	 *
-	 * @return object Returns an instance of `lithium\data\Source` from the connection configuration
-	 *         to which this model is bound.
-	 */
-	public static function &connection() {
-		$self = static::_object();
-		$connections = $self->_classes['connections'];
-		$name = isset($self->_meta['connection']) ? $self->_meta['connection'] : null;
-
-		if ($conn = $connections::get($name)) {
-			return $conn;
-		}
-		throw new ConfigException("The data connection `{$name}` is not configured.");
-	}
-
-	/**
-	 * Wraps `StaticObject::applyFilter()` to account for object instances.
-	 *
-	 * @see lithium\core\StaticObject::applyFilter()
-	 * @param string $method
-	 * @param mixed $closure
-	 */
-	public static function applyFilter($method, $closure = null) {
-		$instance = static::_object();
-		$methods = (array) $method;
-
-		foreach ($methods as $method) {
-			if (!isset($instance->_instanceFilters[$method])) {
-				$instance->_instanceFilters[$method] = array();
-			}
-			$instance->_instanceFilters[$method][] = $closure;
-		}
-	}
-
-	/**
-	 * Wraps `StaticObject::_filter()` to account for object instances.
-	 *
-	 * @see lithium\core\StaticObject::_filter()
-	 * @param string $method
-	 * @param array $params
-	 * @param mixed $callback
-	 * @param array $filters Defaults to empty array.
-	 * @return object
-	 */
-	protected static function _filter($method, $params, $callback, $filters = array()) {
-		if (!strpos($method, '::')) {
-			$method = get_called_class() . '::' . $method;
-		}
-		list($class, $method) = explode('::', $method, 2);
-		$instance = static::_object();
-
-		if (isset($instance->_instanceFilters[$method])) {
-			$filters = array_merge($instance->_instanceFilters[$method], $filters);
-		}
-		return parent::_filter($method, $params, $callback, $filters);
-	}
-
-	protected static function &_object() {
-		$class = get_called_class();
-
-		if (!isset(static::$_instances[$class])) {
-			static::$_instances[$class] = new $class();
-			static::config();
-		}
-		$object = static::_initialize($class);
-		return $object;
-	}
-
-	/**
-	 * Iterates through relationship types to construct relation map.
-	 *
-	 * @return void
-	 * @todo See if this can be rewritten to be lazy.
-	 */
-	protected static function _relationsToLoad() {
-		try {
-			if (!static::connection()) {
-				return;
-			}
-		} catch (ConfigExcepton $e) {
-			return;
-		}
-		$self = static::_object();
-
-		foreach ($self->_relationTypes as $type) {
-			$self->$type = Set::normalize($self->$type);
-			foreach ($self->$type as $name => $config) {
-				$self->_relationsToLoad[$name] = $type;
-			}
-		}
-	}
-
-	/**
-	 * Exports an array of custom finders which use the filter system to wrap around `find()`.
-	 *
-	 * @return void
-	 */
-	protected static function _findFilters() {
-		$self = static::_object();
-		$_query = $self->_query;
-
-		return array(
-			'first' => function($self, $params, $chain) {
-				$params['options']['limit'] = 1;
-				$data = $chain->next($self, $params, $chain);
-				$data = is_object($data) ? $data->rewind() : $data;
-				return $data ?: null;
-			},
-			'list' => function($self, $params, $chain) {
-				$result = array();
-				$meta = $self::meta();
-				$name = $meta['key'];
-
-				foreach ($chain->next($self, $params, $chain) as $entity) {
-					$key = $entity->{$name};
-					$result[is_scalar($key) ? $key : (string) $key] = $entity->title();
-				}
-				return $result;
-			},
-			'count' => function($self, $params) use ($_query) {
-				$model = $self;
-				$type = $params['type'];
-				$options = array_diff_key($params['options'], $_query);
-
-				if ($options && !isset($params['options']['conditions'])) {
-					$options = array('conditions' => $options);
-				} else {
-					$options = $params['options'];
-				}
-				$options += array('type' => 'read') + compact('model');
-				$query = $self::invokeMethod('_instance', array('query', $options));
-				return $self::connection()->calculation('count', $query, $options);
-			}
-		);
-	}
-
-	/**
-	 * Reseting the model
-	 */
-	public static function reset() {
-		$class = get_called_class();
-		unset(static::$_instances[$class]);
-	}
-}
-
-?>

+ 0 - 177
frameworks/PHP/php-lithium/libraries/lithium/data/Schema.php

@@ -1,177 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data;
-
-use RuntimeException;
-
-/**
- * This class encapsulates a schema definition, usually for a model class, and is comprised
- * of named fields and types.
- */
-class Schema extends \lithium\core\Object implements \ArrayAccess {
-
-	protected $_fields = array();
-
-	protected $_meta = array();
-
-	protected $_locked = false;
-
-	protected $_types = array();
-
-	protected $_autoConfig = array('fields', 'meta', 'locked');
-
-	public function __construct(array $config = array()) {
-		$defaults = array('fields' => array());
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-
-		foreach ($this->_fields as $key => $type) {
-			if (is_string($type)) {
-				$this->_fields[$key] = compact('type');
-				continue;
-			}
-			if (isset($this->_fields[$key][0]) && !isset($this->_fields[$key]['type'])) {
-				$this->_fields[$key]['type'] = $this->_fields[$key][0];
-				unset($this->_fields[$key][0]);
-			}
-		}
-	}
-
-	public function fields($name = null, $key = null) {
-		if (!$name) {
-			return $this->_fields;
-		}
-		$field = isset($this->_fields[$name]) ? $this->_fields[$name] : null;
-
-		if ($field && $key) {
-			return isset($field[$key]) ? $field[$key] : null;
-		}
-		return $field;
-	}
-
-	public function names() {
-		return array_keys($this->_fields);
-	}
-
-	public function defaults($name = null) {
-		if ($name) {
-			if (isset($this->_fields[$name]['default'])) {
-				return $this->_fields[$name]['default'];
-			}
-			return null;
-		}
-		$defaults = array();
-
-		foreach ($this->_fields as $key => $value) {
-			if (isset($value['default'])) {
-				$defaults[$key] = $value['default'];
-			}
-		}
-		return $defaults;
-	}
-
-	public function meta($name = null) {
-		if (!$name) {
-			return $this->_meta;
-		}
-		return isset($this->_meta[$name]) ? $this->_meta[$name] : null;
-	}
-
-	public function has($field) {
-		if (is_string($field)) {
-			return isset($this->_fields[$field]);
-		}
-		if (is_array($field)) {
-			return array_intersect($field, array_keys($this->_fields)) == $field;
-		}
-	}
-
-	/**
-	 * Detects properties of a field, i.e. if it supports arrays.
-	 *
-	 * @param string $condition
-	 * @param string $field
-	 * @return boolean
-	 */
-	public function is($condition, $field) {
-		if (!isset($this->_fields[$field])) {
-			return null;
-		}
-		return isset($this->_fields[$field][$condition]) && $this->_fields[$field][$condition];
-	}
-
-	public function type($field) {
-		if (!isset($this->_fields[$field]['type'])) {
-			return null;
-		}
-		$type = $this->_fields[$field]['type'];
-		return isset($this->_types[$type]) ? $this->_types[$type] : $type;
-	}
-
-	public function cast($object, $key, $data, array $options = array()) {
-		return $data;
-	}
-
-	public function reset() {
-		$this->_fields = array();
-	}
-
-	/**
-	 * Appends additional fields to the schema. Will not overwrite existing fields if any conflicts
-	 * arise.
-	 *
-	 * @param array $fields New schema data.
-	 * @return void
-	 */
-	public function append(array $fields) {
-		if ($this->_locked) {
-			throw new RuntimeException("Schema cannot be modified.");
-		}
-		$this->_fields += $fields;
-	}
-
-	/**
-	 * Merges another `Schema` object into the current one.
-	 *
-	 * @param object $schema Another `Schema` class object to be merged into the current one.
-	 *               If this schema contains field names that conflict with existing field names,
-	 *               the existing fields will not be overwritten.
-	 * @return void
-	 */
-	public function merge($schema) {
-		if ($this->_locked) {
-			throw new RuntimeException("Schema cannot be modified.");
-		}
-		$this->_fields += $schema->fields();
-	}
-
-	public function offsetGet($key) {
-		return $this->fields($key);
-	}
-
-	public function offsetSet($key, $value) {
-		if ($this->_locked) {
-			throw new RuntimeException("Schema cannot be modified.");
-		}
-		$this->_fields[$key] = $value;
-	}
-
-	public function offsetExists($key) {
-		return isset($this->_fields[$key]);
-	}
-
-	public function offsetUnset($key) {
-		unset($this->_fields[$key]);
-	}
-}
-
-?>

+ 0 - 301
frameworks/PHP/php-lithium/libraries/lithium/data/Source.php

@@ -1,301 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data;
-
-use lithium\core\NetworkException;
-
-/**
- * This is the base class for Lithium's data abstraction layer.
- *
- * In addition to utility methods and standardized properties, it defines the implementation tasks
- * for all Lithium classes that work with external data, such as connections to remote resources
- * (`connect()` and `disconnect()`), introspecting available data objects (`sources()` and
- * `describe()`), and a standard read/write interface (`create()`, `read()`, `update()` and
- * `delete()`).
- *
- * Subclasses may implement any other non-standard functionality, but the above methods define the
- * requirements for interacting with `Model` objects, and other classes within `lithium\data`.
- */
-abstract class Source extends \lithium\core\Object {
-
-	/**
-	 * The list of object properties to be automatically assigned from configuration passed to
-	 * `__construct()`.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('classes' => 'merge');
-
-	/**
-	 * Default entity and set classes used by subclasses of `Source`.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'entity' => 'lithium\data\Entity',
-		'set' => 'lithium\data\Collection',
-		'relationship' => 'lithium\data\model\Relationship'
-	);
-
-	/**
-	 * Stores a connection to a remote resource. Usually a database connection (`resource` type),
-	 * or an HTTP connection object ('object' type).
-	 *
-	 * @var mixed
-	 */
-	public $connection = null;
-
-	/**
-	 * Stores the status of this object's connection. Updated when `connect()` or `disconnect()` are
-	 * called, or if an error occurs that closes the object's connection.
-	 *
-	 * @var boolean
-	 */
-	protected $_isConnected = false;
-
-	/**
-	 * Constructor. Sets defaults and returns object.
-	 *
-	 * Options defined:
-	 * - 'autoConnect' `boolean` If true, a connection is made on initialization. Defaults to true.
-	 *
-	 * @param array $config
-	 * @return Source object
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('autoConnect' => true);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Ensures the connection is closed, before the object is destroyed.
-	 *
-	 * @return void
-	 */
-	public function __destruct() {
-		if ($this->isConnected()) {
-			$this->disconnect();
-		}
-	}
-
-	protected function _init() {
-		parent::_init();
-		if ($this->_config['autoConnect']) {
-			$this->connect();
-		}
-	}
-
-	/**
-	 * Checks the connection status of this data source. If the `'autoConnect'` option is set to
-	 * true and the source connection is not currently active, a connection attempt will be made
-	 * before returning the result of the connection status.
-	 *
-	 * @param array $options The options available for this method:
-	 *        - 'autoConnect': If true, and the connection is not currently active, calls
-	 *        `connect()` on this object. Defaults to `false`.
-	 * @return boolean Returns the current value of `$_isConnected`, indicating whether or not
-	 *         the object's connection is currently active.  This value may not always be accurate,
-	 *         as the connection could have timed out or otherwise been dropped by the remote
-	 *         resource during the course of the request.
-	 */
-	public function isConnected(array $options = array()) {
-		$defaults = array('autoConnect' => false);
-		$options += $defaults;
-
-		if (!$this->_isConnected && $options['autoConnect']) {
-			try {
-				$this->connect();
-			} catch (NetworkException $e) {
-				$this->_isConnected = false;
-			}
-		}
-		return $this->_isConnected;
-	}
-
-	/**
-	 * Quotes data-source-native identifiers, where applicable.
-	 *
-	 * @param string $name Identifier name.
-	 * @return string Returns `$name`, quoted if applicable.
-	 */
-	public function name($name) {
-		return $name;
-	}
-
-	/**
-	 * Abstract. Must be defined by child classes.
-	 */
-	abstract public function connect();
-
-	/**
-	 * Abstract. Must be defined by child classes.
-	 */
-	abstract public function disconnect();
-
-	/**
-	 * Returns a list of objects (sources) that models can bind to, i.e. a list of tables in the
-	 * case of a database, or REST collections, in the case of a web service.
-	 *
-	 * @param string $class The fully-name-spaced class name of the object making the request.
-	 * @return array Returns an array of objects to which models can connect.
-	 */
-	abstract public function sources($class = null);
-
-	/**
-	 * Gets the column schema for a given entity (such as a database table).
-	 *
-	 * @param mixed $entity Specifies the table name for which the schema should be returned, or
-	 *        the class name of the model object requesting the schema, in which case the model
-	 *        class will be queried for the correct table name.
-	 * @param array $schema
-	 * @param array $meta The meta-information for the model class, which this method may use in
-	 *        introspecting the schema.
-	 * @return array Returns a `Schema` object describing the given model's schema, where the
-	 *         array keys are the available fields, and the values are arrays describing each
-	 *         field, containing the following keys:
-	 *         - `'type'`: The field type name
-	 */
-	abstract public function describe($entity, $schema = array(), array $meta = array());
-
-	/**
-	 * Defines or modifies the default settings of a relationship between two models.
-	 *
-	 * @param $class the primary model of the relationship
-	 * @param $type the type of the relationship (hasMany, hasOne, belongsTo)
-	 * @param $name the name of the relationship
-	 * @param array $options relationship options
-	 * @return array Returns an array containing the configuration for a model relationship.
-	 */
-	abstract public function relationship($class, $type, $name, array $options = array());
-
-	/**
-	 * Create a record. This is the abstract method that is implemented by specific data sources.
-	 * This method should take a query object and use it to create a record in the data source.
-	 *
-	 * @param mixed $query An object which defines the update operation(s) that should be performed
-	 *        against the data store.  This can be a `Query`, a `RecordSet`, a `Record`, or a
-	 *        subclass of one of the three. Alternatively, `$query` can be an adapter-specific
-	 *        query string.
-	 * @param array $options The options from Model include,
-	 *              - `validate` _boolean_ default: true
-	 *              - `events` _string_ default: create
-	 *              - `whitelist` _array_ default: null
-	 *              - `callbacks` _boolean_ default: true
-	 *              - `locked` _boolean_ default: true
-	 * @return boolean Returns true if the operation was a success, otherwise false.
-	 */
-	abstract public function create($query, array $options = array());
-
-	/**
-	 * Abstract. Must be defined by child classes.
-	 *
-	 * @param mixed $query
-	 * @param array $options
-	 * @return boolean Returns true if the operation was a success, otherwise false.
-	 */
-	abstract public function read($query, array $options = array());
-
-	/**
-	 * Updates a set of records in a concrete data store.
-	 *
-	 * @param mixed $query An object which defines the update operation(s) that should be performed
-	 *        against the data store.  This can be a `Query`, a `RecordSet`, a `Record`, or a
-	 *        subclass of one of the three. Alternatively, `$query` can be an adapter-specific
-	 *        query string.
-	 * @param array $options Options to execute, which are defined by the concrete implementation.
-	 * @return boolean Returns true if the update operation was a success, otherwise false.
-	 */
-	abstract public function update($query, array $options = array());
-
-	/**
-	 * Abstract. Must be defined by child classes.
-	 *
-	 * @param mixed $query
-	 * @param array $options
-	 * @return boolean Returns true if the operation was a success, otherwise false.
-	 */
-	abstract public function delete($query, array $options = array());
-
-	/**
-	 * Casts data into proper format when added to a collection or entity object.
-	 *
-	 * @param mixed $entity The entity or collection for which data is being cast, or the name of
-	 *              the model class to which the entity/collection is bound.
-	 * @param array $data An array of data being assigned.
-	 * @param array $options Any associated options with, for example, instantiating new objects in
-	 *              which to wrap the data. Options implemented by `cast()` itself:
-	 *              - `first` _boolean_: Used when only one value is passed to `cast()`. Even though
-	 *                that value must be wrapped in an array, setting the `'first'` option to `true`
-	 *                causes only that one value to be returned.
-	 * @return mixed Returns the value of `$data`, cast to the proper format according to the schema
-	 *         definition of the model class specified by `$model`.
-	 */
-	public function cast($entity, array $data, array $options = array()) {
-		$defaults = array('first' => false);
-		$options += $defaults;
-		return $options['first'] ? reset($data) : $data;
-	}
-
-	/**
-	 * Returns the list of methods which format values imported from `Query` objects. Should be
-	 * overridden in subclasses.
-	 *
-	 * @see lithium\data\model\Query
-	 * @return array
-	 */
-	public function methods() {
-		return get_class_methods($this);
-	}
-
-	/**
-	 * A method which can be optionally implemented to configure a model class.
-	 *
-	 * @see lithium\data\Model::$_meta
-	 * @see lithium\data\Model::$_finders
-	 * @see lithium\data\Model::$_classes
-	 * @param string $class The name of the model class to be configured.
-	 * @return array This method should return an array one or more of the following keys: `'meta'`,
-	 *         `'classes'` or `'finders'`. These keys maps to the three corresponding properties in
-	 *         `lithium\data\Model`, and are used to override the base-level default settings and
-	 *         dependencies.
-	 */
-	public function configureClass($class) {
-		return array('meta' => array('key' => 'id', 'locked' => true));
-	}
-
-	/**
-	 * This method is responsible for factorying a new instance of a single entity object of correct
-	 * type, matching the current data source class.
-	 *
-	 * @param string $model A fully-namespaced class name representing the model class to which the
-	 *               `Entity` object will be bound.
-	 * @param array $data The default data with which the new `Entity` should be populated.
-	 * @param array $options Any additional options to pass to the `Entity`'s constructor
-	 * @return object Returns a new, un-saved `Entity` object bound to the model class specified
-	 *         in `$model`.
-	 */
-	public function item($model, array $data = array(), array $options = array()) {
-		$defaults = array('class' => 'entity');
-		$options += $defaults;
-
-		$class = $options['class'];
-		unset($options['class']);
-		return $this->_instance($class, compact('model', 'data') + $options);
-	}
-
-	/**
-	 * Applying a strategy to a `lithium\data\model\Query` object
-	 *
-	 * @param array $options The option array
-	 * @param object $context A query object to configure
-	 */
-	public function applyStrategy($options, $context) {}
-}
-
-?>

+ 0 - 139
frameworks/PHP/php-lithium/libraries/lithium/data/collection/DocumentSet.php

@@ -1,139 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\collection;
-
-use lithium\data\entity\Document;
-
-class DocumentSet extends \lithium\data\Collection {
-
-	/**
-	 * Contains the original database value of the array. This value will be compared with the
-	 * current value (`$_data`) to calculate the changes that should be sent to the database.
-	 *
-	 * @var array
-	 */
-	protected $_original = array();
-
-	protected function _init() {
-		parent::_init();
-		$this->_original = $this->_data;
-	}
-
-	public function sync($id = null, array $data = array(), array $options = array()) {
-		$defaults = array('materialize' => true);
-		$options += $defaults;
-
-		if ($options['materialize']) {
-			$this->_exists = true;
-		}
-
-		$this->offsetGet(null);
-		$this->_original = $this->_data;
-	}
-
-	/**
-	 * Determines if the `DocumentSet` has been modified since it was last saved
-	 *
-	 * @return boolean
-	 */
-	public function modified() {
-		if (count($this->_original) !== count($this->_data)) {
-			return true;
-		}
-		foreach ($this->_original as $key => $doc) {
-			$updated = $this->_data[$key];
-			if (!isset($updated)) {
-				return true;
-			}
-			if ($doc !== $updated) {
-				return true;
-			}
-			if (!is_object($updated) || !method_exists($updated, 'modified')) {
-				continue;
-			}
-			$modified = $this->_data[$key]->modified();
-
-			if (in_array(true, $modified)) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Adds conversions checks to ensure certain class types and embedded values are properly cast.
-	 *
-	 * @param string $format Currently only `array` is supported.
-	 * @param array $options
-	 * @return mixed
-	 */
-	public function to($format, array $options = array()) {
-		$options += array('handlers' => array(
-			'MongoId' => function($value) { return (string) $value; },
-			'MongoDate' => function($value) { return $value->sec; }
-		));
-
-		$this->offsetGet(null);
-		return parent::to($format, $options);
-	}
-
-	public function export(array $options = array()) {
-		$this->offsetGet(null);
-		return array(
-			'exists' => $this->_exists,
-			'key'  => $this->_pathKey,
-			'data' => array_values($this->_original),
-			'update' => array_values($this->_data)
-		);
-	}
-
-	/**
-	 * Extract the next item from the result ressource and wraps it into a `Document` object.
-	 *
-	 * @return mixed Returns the next `Document` if exists. Returns `null` otherwise
-	 */
-	protected function _populate() {
-		if ($this->closed() || !$this->_result->valid()) {
-			return;
-		}
-		$data = $this->_result->current();
-		$result = $this->_set($data, null, array('exists' => true, 'original' => true));
-		$this->_result->next();
-
-		return $result;
-	}
-
-	protected function _set($data = null, $offset = null, $options = array()) {
-		if ($schema = $this->schema()) {
-			$model = $this->_model;
-			$pathKey = $this->_pathKey;
-			$options =  compact('model', 'pathKey') + $options;
-			$data = !is_object($data) ? $schema->cast($this, $offset, $data, $options) : $data;
-			$key = $model && $data instanceof Document ? $model::key($data) : $offset;
-		} else {
-			$key = $offset;
-		}
-		if (is_array($key)) {
-			$key = count($key) === 1 ? current($key) : null;
-		}
-		if (is_object($key)) {
-			$key = (string) $key;
-		}
-		if (method_exists($data, 'assignTo')) {
-			$data->assignTo($this);
-		}
-		$key !== null ? $this->_data[$key] = $data : $this->_data[] = $data;
-		if (isset($options['original']) && $options['original']) {
-			$key !== null ? $this->_original[$key] = $data : $this->_original[] = $data;
-		}
-		return $data;
-	}
-}
-
-?>

+ 0 - 264
frameworks/PHP/php-lithium/libraries/lithium/data/collection/MultiKeyRecordSet.php

@@ -1,264 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\collection;
-
-class MultiKeyRecordSet extends \lithium\data\collection\RecordSet {
-
-	/**
-	 * An array containing each record's unique key. This allows, for example, lookups of records
-	 * with composite keys, i.e.:
-	 *
-	 * {{{
-	 * $payment = $records[array('client_id' => 42, 'invoice_id' => 21)];
-	 * }}}
-	 *
-	 * @var array
-	 */
-	protected $_index = array();
-
-	/**
-	 * A 2D array of column-mapping information, where the top-level key is the fully-namespaced
-	 * model name, and the sub-arrays are column names.
-	 *
-	 * @var array
-	 */
-	protected $_columns = array();
-
-	/**
-	 * Initializes the record set and uses the database connection to get the column list contained
-	 * in the query that created this object.
-	 *
-	 * @see lithium\data\collection\RecordSet::$_columns
-	 * @return void
-	 * @todo The part that uses _handle->schema() should be rewritten so that the column list
-	 *       is coming from the query object.
-	 */
-	protected function _init() {
-		parent::_init();
-		if ($this->_result) {
-			$this->_columns = $this->_columnMap();
-		}
-	}
-
-	/**
-	 * Checks to see if a record with the given index key is in the record set. If the record
-	 * cannot be found, and not all records have been loaded into the set, it will continue loading
-	 * records until either all available records have been loaded, or a matching key has been
-	 * found.
-	 *
-	 * @see lithium\data\collection\RecordSet::offsetGet()
-	 * @param mixed $offset The ID of the record to check for.
-	 * @return boolean Returns true if the record's ID is found in the set, otherwise false.
-	 */
-	public function offsetExists($offset) {
-		$offset = (!$offset || $offset === true) ? 0 : $offset;
-		$this->offsetGet($offset);
-		if (in_array($offset, $this->_index)) {
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Gets a record from the record set using PHP's array syntax, i.e. `$records[5]`. Using loose
-	 * typing, integer keys can be accessed using strings and vice-versa. For record sets with
-	 * composite keys, records may be accessed using arrays as array keys. Note that the order of
-	 * the keys in the array does not matter.
-	 *
-	 * Because record data in `RecordSet` is lazy-loaded from the database, new records are fetched
-	 * until one with a matching key is found.
-	 *
-	 * @see lithium\data\collection\RecordSet::$_index
-	 * @param mixed $offset The offset, or ID (index) of the record you wish to load.  If
-	 *                      `$offset` is `null`, all records are loaded into the record set, and
-	 *                      `offsetGet` returns `null`.
-	 * @return object Returns a `Record` object if a record is found with a key that matches the
-	 *                value of `$offset`, otheriwse returns `null`.
-	 */
-	public function offsetGet($offset) {
-		$offset = (!$offset || $offset === true) ? 0 : $offset;
-		if (in_array($offset, $this->_index)) {
-			return $this->_data[array_search($offset, $this->_index)];
-		}
-		if ($this->closed()) {
-			return null;
-		}
-		if ($model = $this->_model) {
-			$offsetKey = $model::key($offset);
-			while ($record = $this->_populate($offset)) {
-				$curKey = $model::key($record);
-				$keySet = $offsetKey == $curKey;
-				if (!is_null($offset) && $keySet) {
-					return $record;
-				}
-			}
-		}
-		$this->close();
-	}
-
-	/**
-	 * Assigns a value to the specified offset.
-	 *
-	 * @param integer $offset The offset to assign the value to.
-	 * @param mixed $data The value to set.
-	 * @return mixed The value which was set.
-	 */
-	public function offsetUnset($offset) {
-		$offset = (!$offset || $offset === true) ? 0 : $offset;
-		$this->offsetGet($offset);
-		unset($this->_index[$index = array_search($offset, $this->_index)]);
-		prev($this->_data);
-		if (key($this->_data) === null) {
-			$this->rewind();
-		}
-		unset($this->_data[$index]);
-	}
-
-	/**
-	 * Returns the currently pointed to record's unique key.
-	 *
-	 * @param boolean $full If true, returns the complete key.
-	 * @return mixed
-	 */
-	public function key($full = false) {
-		if ($this->_started === false) {
-			$this->current();
-		}
-		if ($this->_valid) {
-			$key = $this->_index[key($this->_data)];
-			return (is_array($key) && !$full) ? reset($key) : $key;
-		}
-		return null;
-	}
-
-	/**
-	 * Returns the item keys.
-	 *
-	 * @return array The keys of the items.
-	 */
-	public function keys() {
-		$this->offsetGet(null);
-		return $this->_index;
-	}
-
-	/**
-	 * Converts the data in the record set to a different format, i.e. an array.
-	 *
-	 * @param string $format
-	 * @param array $options
-	 * @return mixed
-	 */
-	public function to($format, array $options = array()) {
-		$default = array('indexed' => true);
-		$options += $default;
-		$options['internal'] = !$options['indexed'];
-		unset($options['indexed']);
-
-		$this->offsetGet(null);
-		if (!$options['internal'] && !is_scalar(current($this->_index))) {
-			$options['internal'] = true;
-		}
-		return $result = parent::to($format, $options);
-	}
-
-	/**
-	 * Applies a callback to all data in the collection.
-	 *
-	 * Overriden to load any data that has not yet been loaded.
-	 *
-	 * @param callback $filter The filter to apply.
-	 * @return object This collection instance.
-	 */
-	public function each($filter) {
-		$this->offsetGet(null);
-		return parent::each($filter);
-	}
-
-	/**
-	 * Filters a copy of the items in the collection.
-	 *
-	 * Overridden to load any data that has not yet been loaded.
-	 *
-	 * @param callback $filter Callback to use for filtering.
-	 * @param array $options The available options are:
-	 *              - `'collect'`: If `true`, the results will be returned wrapped
-	 *              in a new `Collection` object or subclass.
-	 * @return mixed The filtered items. Will be an array unless `'collect'` is defined in the
-	 * `$options` argument, then an instance of this class will be returned.
-	 */
-	public function find($filter, array $options = array()) {
-		$this->offsetGet(null);
-		return parent::find($filter, $options);
-	}
-
-	/**
-	 * Applies a callback to a copy of all data in the collection
-	 * and returns the result.
-	 *
-	 * Overriden to load any data that has not yet been loaded.
-	 *
-	 * @param callback $filter The filter to apply.
-	 * @param array $options The available options are:
-	 *              - `'collect'`: If `true`, the results will be returned wrapped
-	 *              in a new `Collection` object or subclass.
-	 * @return object The filtered data.
-	 */
-	public function map($filter, array $options = array()) {
-		$this->offsetGet(null);
-		return parent::map($filter, $options);
-	}
-
-	/**
-	 * Extract the next item from the result ressource and wraps it into a `Record` object.
-	 *
-	 * @return mixed Returns the next `Record` if exists. Returns `null` otherwise
-	 */
-	protected function _populate() {
-		if ($this->closed() || !$this->_result->valid()) {
-			return;
-		}
-
-		$data = $this->_result->current();
-		if ($this->_query) {
-			$data = $this->_mapRecord($data);
-		}
-		$result = $this->_set($data, null, array('exists' => true));
-		$this->_result->next();
-
-		return $result;
-	}
-
-	protected function _set($data = null, $offset = null, $options = array()) {
-		if ($model = $this->_model) {
-			$data = !is_object($data) ? $model::connection()->item($model, $data, $options) : $data;
-			$key = $model::key($data);
-		} else {
-			$key = $offset;
-		}
-
-		if ($key === array() || $key === null || is_bool($key)) {
-			$key = count($this->_data);
-		}
-
-		if (is_array($key)) {
-			$key = count($key) === 1 ? reset($key) : $key;
-		}
-
-		if (in_array($key, $this->_index)) {
-			$index = array_search($key, $this->_index);
-			$this->_data[$index] = $data;
-			return $this->_data[$index];
-		}
-		$this->_data[] = $data;
-		$this->_index[] = $key;
-		return $data;
-	}
-}
-
-?>

+ 0 - 245
frameworks/PHP/php-lithium/libraries/lithium/data/collection/RecordSet.php

@@ -1,245 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\collection;
-
-use lithium\util\Set;
-
-class RecordSet extends \lithium\data\Collection {
-
-	/**
-	 * A 2D array of column-mapping information, where the top-level key is the fully-namespaced
-	 * model name, and the sub-arrays are column names.
-	 *
-	 * @var array
-	 */
-	protected $_columns = array();
-
-	/**
-	 * A recursive array of relation dependencies where key are relations
-	 * and value are arrays with their relation dependencies
-	 *
-	 * @var array
-	 */
-	protected $_dependencies = array();
-
-	/**
-	 * Precompute index of the main model primary key(s) which allow to find
-	 * values directly is result data without the column name matching process
-	 *
-	 * @var array
-	 */
-	protected $_keyIndex = array();
-
-	/**
-	 * Initializes the record set and uses the database connection to get the column list contained
-	 * in the query that created this object.
-	 *
-	 * @see lithium\data\collection\RecordSet::$_columns
-	 * @return void
-	 * @todo The part that uses _handle->schema() should be rewritten so that the column list
-	 *       is coming from the query object.
-	 */
-	protected function _init() {
-		parent::_init();
-		if ($this->_result) {
-			$this->_columns = $this->_columnMap();
-			if ($this->_query) {
-				$columns = array_filter(array_keys($this->_columns));
-				$this->_dependencies = Set::expand(Set::normalize($columns));
-				$this->_keyIndex = $this->_keyIndex('');
-			}
-		}
-	}
-
-	/**
-	 * Extract the next item from the result ressource and wraps it into a `Record` object.
-	 *
-	 * @return mixed Returns the next `Record` if exists. Returns `null` otherwise
-	 */
-	protected function _populate() {
-		if ($this->closed() || !$this->_result->valid()) {
-			return;
-		}
-
-		$data = $this->_result->current();
-		if ($this->_query) {
-			$data = $this->_mapRecord($data);
-		}
-		$result = $this->_set($data, null, array('exists' => true));
-		$this->_result->next();
-
-		return $result;
-	}
-
-	protected function _set($data = null, $offset = null, $options = array()) {
-		if ($model = $this->_model) {
-			$data = !is_object($data) ? $model::connection()->item($model, $data, $options) : $data;
-			$key = $model::key($data);
-		} else {
-			$key = $offset;
-		}
-		if (is_array($key)) {
-			$key = count($key) === 1 ? current($key) : null;
-		}
-		return $key !== null ? $this->_data[$key] = $data : $this->_data[] = $data;
-	}
-
-	/**
-	 * Convert a PDO `Result` array to a nested `Record` object
-	 *
-	 * @param array $data 2 dimensional PDO `Result` array
-	 * @return object Returns a `Record` object
-	 */
-	protected function _mapRecord($data) {
-		$primary = $this->_model;
-		$conn = $primary::connection();
-		$main = $record = array();
-		$i = 0;
-
-		foreach ($this->_keyIndex as $key => $value) {
-			$main[$key] = $data[$key];
-		}
-
-		do {
-			$offset = 0;
-			if ($i != 0) {
-				$keys = array();
-				foreach ($this->_keyIndex as $key => $value) {
-					$keys[$key] = $data[$key];
-				}
-				if ($main != $keys) {
-					$this->_result->prev();
-					break;
-				}
-			}
-			foreach ($this->_columns as $name => $fields) {
-				$fieldCount = count($fields);
-				$record[$i][$name] = array_combine(
-					$fields, array_slice($data, $offset, $fieldCount)
-				);
-				$offset += $fieldCount;
-			}
-			$i++;
-		} while ($main && $data = $this->_result->next());
-
-		$relMap = $this->_query->relationships();
-		return $this->_hydrateRecord(
-			$this->_dependencies, $primary, $record, 0, $i, '', $relMap, $conn
-		);
-	}
-
-	/**
-	 * Hydrate a 2 dimensional PDO `Result` array
-	 *
-	 * @param array $relations The cascading with relation
-	 * @param string $primary Model classname
-	 * @param array $record Loaded Records
-	 * @param integer $min
-	 * @param integer $max
-	 * @param string $name Alias name
-	 * @param array $relMap The query relationships array
-	 * @param object $conn The connection object
-	 * @return object Returns a `Record` object
-	 */
-	protected function _hydrateRecord($relations, $primary, $record, $min, $max, $name, &$relMap, $conn) {
-		$options = array('exists' => true);
-
-		$count = count($record);
-		if (!empty($relations)) {
-			foreach ($relations as $relation => $subrelations) {
-				$relName = $name ? $name . '.' . $relation : $relation;
-				$field = $relMap[$relName]['fieldName'];
-				$relModel = $relMap[$relName]['model'];
-
-				if ($relMap[$relName]['type'] === 'hasMany') {
-					$rel = array();
-					$main = $relModel::key($record[$min][$relName]);
-					$i = $min;
-					$j = $i + 1;
-					while ($j < $max) {
-						$keys = $relModel::key($record[$j][$relName]);
-						if ($main != $keys) {
-							$rel[] = $this->_hydrateRecord(
-								$subrelations, $relModel, $record, $i, $j, $relName, $relMap, $conn
-							);
-							$main = $keys;
-							$i = $j;
-						}
-						$j++;
-					}
-					if (array_filter($record[$i][$relName])) {
-						$rel[] = $this->_hydrateRecord(
-							$subrelations, $relModel, $record, $i, $j, $relName, $relMap, $conn
-						);
-					}
-					$opts = array('class' => 'set') + $options;
-					$record[$min][$name][$field] = $conn->item($primary, $rel, $opts);
-				} else {
-					$record[$min][$name][$field] = $this->_hydrateRecord(
-						$subrelations, $relModel, $record, $min, $max, $relName, $relMap, $conn
-					);
-				}
-			}
-		}
-		return $conn->item(
-			$primary, isset($record[$min][$name]) ? $record[$min][$name] : array(), $options
-		);
-	}
-
-	protected function _columnMap() {
-		if ($this->_query && $map = $this->_query->map()) {
-			return $map;
-		}
-		if (!($model = $this->_model)) {
-			return array();
-		}
-		if (!is_object($this->_query) || !$this->_query->join()) {
-			$map = $model::connection()->schema($this->_query);
-			return $map;
-		}
-		$model = $this->_model;
-		$map = $model::connection()->schema($this->_query);
-
-		return $map;
-	}
-
-	/**
-	 * Result object contain SQL result which are generally a 2 dimentionnal array
-	 * where line are records and columns are fields.
-	 * This function extract from the Result object the index of primary key(s).
-	 *
-	 * @param string $name The name of the relation to retreive the index of
-	 *               corresponding primary key(s).
-	 * @return array An array where key are index and value are primary key fieldname
-	 */
-	protected function _keyIndex($name) {
-		if (!($model = $this->_model) || !isset($this->_columns[$name])) {
-			return array();
-		}
-		$index = 0;
-		foreach ($this->_columns as $key => $value) {
-			if ($key === $name) {
-				$flip = array_flip($value);
-				$keys = $model::meta('key');
-				if (!is_array($keys)) {
-					$keys = array($keys);
-				}
-				$keys = array_flip($keys);
-				$keys = array_intersect_key($flip, $keys);
-				foreach ($keys as &$value) {
-					$value += $index;
-				}
-				return array_flip($keys);
-			}
-			$index += count($value);
-		}
-	}
-}
-
-?>

+ 0 - 478
frameworks/PHP/php-lithium/libraries/lithium/data/entity/Document.php

@@ -1,478 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\entity;
-
-use RuntimeException;
-use UnexpectedValueException;
-
-/**
- * `Document` is an alternative to the `entity\Record` class, which is optimized for
- * organizing collections of entities from document-oriented databases such as CouchDB or MongoDB.
- * A `Document` object's fields can represent a collection of both simple and complex data types,
- * as well as other `Document` objects. Given the following data (document) structure:
- *
- * {{{
- * {
- * 	_id: 12345.
- * 	name: 'Acme, Inc.',
- * 	employees: {
- * 		'Larry': { email: '[email protected]' },
- * 		'Curly': { email: '[email protected]' },
- * 		'Moe': { email: '[email protected]' }
- * 	}
- * }
- * }}}
- *
- * You can query the object as follows:
- *
- * {{{$acme = Company::find(12345);}}}
- *
- * This returns a `Document` object, populated with the raw representation of the data.
- *
- * {{{print_r($acme->to('array'));
- *
- * // Yields:
- * //	array(
- * //	'_id' => 12345,
- * //	'name' => 'Acme, Inc.',
- * //	'employees' => array(
- * //		'Larry' => array('email' => '[email protected]'),
- * //		'Curly' => array('email' => '[email protected]'),
- * //		'Moe' => array('email' => '[email protected]')
- * //	)
- * //)}}}
- *
- * As with other database objects, a `Document` exposes its fields as object properties, like so:
- *
- * {{{echo $acme->name; // echoes 'Acme, Inc.'}}}
- *
- * However, accessing a field containing a data set will return that data set wrapped in a
- * sub-`Document` object., i.e.:
- *
- * {{{$employees = $acme->employees;
- * // returns a Document object with the data in 'employees'}}}
- */
-class Document extends \lithium\data\Entity implements \Iterator, \ArrayAccess {
-
-	/**
-	 * If this `Document` instance has a parent document (see `$_parent`), this value indicates
-	 * the key name of the parent document that contains it.
-	 *
-	 * @see lithium\data\entity\Document::$_parent
-	 * @var string
-	 */
-	protected $_pathKey = null;
-
-	/**
-	 * Contains an array of backend-specific statistics generated by the query that produced this
-	 * `Document` object. These stats are accessible via the `stats()` method.
-	 *
-	 * @see lithium\data\collection\DocumentSet::stats()
-	 * @var array
-	 */
-	protected $_stats = array();
-
-	/**
-	 * Holds the current iteration state. Used by `Document::valid()` to terminate `foreach` loops
-	 * when there are no more fields to iterate over.
-	 *
-	 * @var boolean
-	 */
-	protected $_valid = false;
-
-	/**
-	 * Removed keys list. Contains names of the fields will be removed from the backend data store
-	 *
-	 * @var array
-	 */
-	protected $_removed = array();
-
-	protected function _init() {
-		parent::_init();
-
-		$data = (array) $this->_data;
-		$this->_data = array();
-		$this->_updated = array();
-		$this->_removed = array();
-
-		$this->set($data, array('init' => true));
-		$this->sync(null, array(), array('materialize' => false));
-		unset($this->_autoConfig);
-	}
-
-	/**
-	 * PHP magic method used when accessing fields as document properties, i.e. `$document->_id`.
-	 *
-	 * @param $name The field name, as specified with an object property.
-	 * @return mixed Returns the value of the field specified in `$name`, and wraps complex data
-	 *         types in sub-`Document` objects.
-	 */
-	public function &__get($name) {
-		if (strpos($name, '.')) {
-			return $this->_getNested($name);
-		}
-
-		if (isset($this->_embedded[$name]) && !isset($this->_relationships[$name])) {
-			throw new RuntimeException("Not implemented.");
-		}
-		$result =& parent::__get($name);
-
-		if ($result !== null || array_key_exists($name, $this->_updated)) {
-			return $result;
-		}
-
-		if ($field = $this->schema($name)) {
-			if (isset($field['default'])) {
-				$this->set(array($name => $field['default']));
-				return $this->_updated[$name];
-			}
-			if (isset($field['array']) && $field['array'] && ($model = $this->_model)) {
-				$this->_updated[$name] = $model::connection()->item($model, array(), array(
-					'class' => 'set',
-					'schema' => $this->schema(),
-					'pathKey' => $this->_pathKey ? $this->_pathKey . '.' . $name : $name,
-					'parent' => $this,
-					'model' => $this->_model
-				));
-				return $this->_updated[$name];
-			}
-		}
-		$null = null;
-		return $null;
-	}
-
-	public function export(array $options = array()) {
-		foreach ($this->_updated as $key => $val) {
-			if ($val instanceof self) {
-				$path = $this->_pathKey ? "{$this->_pathKey}." : '';
-				$this->_updated[$key]->_pathKey = "{$path}{$key}";
-			}
-		}
-		return parent::export($options) + array(
-			'key' => $this->_pathKey,
-			'remove' => $this->_removed
-		);
-	}
-
-	/**
-	 * Extends the parent implementation to ensure that child documents are properly synced as well.
-	 *
-	 * @param mixed $id
-	 * @param array $data
-	 * @param array $options Options when calling this method:
-	 *              - `'recursive'` _boolean_: If `true` attempts to sync nested objects as well.
-	 *                Otherwise, only syncs the current object. Defaults to `true`.
-	 * @return void
-	 */
-	public function sync($id = null, array $data = array(), array $options = array()) {
-		$defaults = array('recursive' => true);
-		$options += $defaults;
-
-		if (!$options['recursive']) {
-			return parent::sync($id, $data, $options);
-		}
-
-		foreach ($this->_updated as $key => $val) {
-			if (is_object($val) && method_exists($val, 'sync')) {
-				$nested = isset($data[$key]) ? $data[$key] : array();
-				$this->_updated[$key]->sync(null, $nested, $options);
-			}
-		}
-		parent::sync($id, $data, $options);
-	}
-
-	/**
-	 * Instantiates a new `Document` object as a descendant of the current object, and sets all
-	 * default values and internal state.
-	 *
-	 * @param string $classType The type of class to create, either `'entity'` or `'set'`.
-	 * @param string $key The key name to which the related object is assigned.
-	 * @param array $data The internal data of the related object.
-	 * @param array $options Any other options to pass when instantiating the related object.
-	 * @return object Returns a new `Document` object instance.
-	 */
-	protected function _relation($classType, $key, $data, $options = array()) {
-		return parent::_relation($classType, $key, $data, array('exists' => false) + $options);
-	}
-
-	protected function &_getNested($name) {
-		$current = $this;
-		$null = null;
-		$path = explode('.', $name);
-		$length = count($path) - 1;
-
-		foreach ($path as $i => $key) {
-			if (!isset($current[$key])) {
-				return $null;
-			}
-			$current = $current[$key];
-
-			if (is_scalar($current) && $i < $length) {
-				return $null;
-			}
-		}
-		return $current;
-	}
-
-	/**
-	 * PHP magic method used when setting properties on the `Document` instance, i.e.
-	 * `$document->title = 'Lorem Ipsum'`. If `$value` is a complex data type (i.e. associative
-	 * array), it is wrapped in a sub-`Document` object before being appended.
-	 *
-	 * @param $name The name of the field/property to write to, i.e. `title` in the above example.
-	 * @param $value The value to write, i.e. `'Lorem Ipsum'`.
-	 * @return void
-	 */
-	public function __set($name, $value = null) {
-		$this->set(array($name => $value));
-	}
-
-	protected function _setNested($name, $value) {
-		$current =& $this;
-		$path = explode('.', $name);
-		$length = count($path) - 1;
-
-		for ($i = 0; $i < $length; $i++) {
-			$key = $path[$i];
-
-			if (isset($current[$key])) {
-				$next =& $current[$key];
-			} else {
-				unset($next);
-				$next = null;
-			}
-
-			if ($next === null && ($model = $this->_model)) {
-				$current->set(array($key => $model::connection()->item($model)));
-				$next =& $current->{$key};
-			}
-			$current =& $next;
-		}
-
-		if (is_object($current)) {
-			$current->set(array(end($path) => $value));
-		}
-	}
-
-	/**
-	 * PHP magic method used to check the presence of a field as document properties, i.e.
-	 * `$document->_id`.
-	 *
-	 * @param $name The field name, as specified with an object property.
-	 * @return boolean True if the field specified in `$name` exists, false otherwise.
-	 */
-	public function __isset($name) {
-		return isset($this->_updated[$name]);
-	}
-
-	/**
-	 * PHP magic method used when unset() is called on a `Document` instance.
-	 * Use case for this would be when you wish to edit a document and remove a field, ie.:
-	 * {{{
-	 * $doc = Post::find($id);
-	 * unset($doc->fieldName);
-	 * $doc->save();
-	 * }}}
-	 *
-	 * @param string $name The name of the field to remove.
-	 * @return void
-	 */
-	public function __unset($name) {
-		$parts = explode('.', $name, 2);
-		if (isset($parts[1])) {
-			unset($this->{$parts[0]}[$parts[1]]);
-		} else {
-			unset($this->_updated[$name]);
-			$this->_removed[$name] = true;
-		}
-	}
-
-	/**
-	 * Allows several properties to be assigned at once.
-	 *
-	 * For example:
-	 * {{{
-	 * $doc->set(array('title' => 'Lorem Ipsum', 'value' => 42));
-	 * }}}
-	 *
-	 * @param array $data An associative array of fields and values to assign to the `Document`.
-	 * @param array $options
-	 * @return void
-	 */
-	public function set(array $data, array $options = array()) {
-		$defaults = array('init' => false);
-		$options += $defaults;
-
-		$cast = ($schema = $this->schema());
-
-		foreach ($data as $key => $val) {
-			unset($this->_increment[$key]);
-			if (strpos($key, '.')) {
-				$this->_setNested($key, $val);
-				continue;
-			}
-			if ($cast) {
-				$pathKey = $this->_pathKey;
-				$model = $this->_model;
-				$parent = $this;
-				$val = $schema->cast($this, $key, $val, compact('pathKey', 'model', 'parent'));
-			}
-			if ($val instanceof self) {
-				$val->_exists = $options['init'] && $this->_exists;
-				$val->_pathKey = ($this->_pathKey ? "{$this->_pathKey}." : '') . $key;
-				$val->_model = $val->_model ?: $this->_model;
-				$val->_schema = $val->_schema ?: $this->_schema;
-			}
-			$this->_updated[$key] = $val;
-		}
-	}
-
-	/**
-	 * Allows document fields to be accessed as array keys, i.e. `$document['_id']`.
-	 *
-	 * @param mixed $offset String or integer indicating the offset or index of a document in a set,
-	 *              or the name of a field in an individual document.
-	 * @return mixed Returns either a sub-object in the document, or a scalar field value.
-	 */
-	public function offsetGet($offset) {
-		return $this->__get($offset);
-	}
-
-	/**
-	 * Allows document fields to be assigned as array keys, i.e. `$document['_id'] = $id`.
-	 *
-	 * @param mixed $offset String or integer indicating the offset or the name of a field in an
-	 *              individual document.
-	 * @param mixed $value The value to assign to the field.
-	 * @return void
-	 */
-	public function offsetSet($offset, $value) {
-		return $this->set(array($offset => $value));
-	}
-
-	/**
-	 * Allows document fields to be tested as array keys, i.e. `isset($document['_id'])`.
-	 *
-	 * @param mixed $offset String or integer indicating the offset or the name of a field in an
-	 *              individual document.
-	 * @return boolean Returns `true` if `$offset` is a field in the document, otherwise `false`.
-	 */
-	public function offsetExists($offset) {
-		return $this->__isset($offset);
-	}
-
-	/**
-	 * Allows document fields to be unset as array keys, i.e. `unset($document['_id'])`.
-	 *
-	 * @param string $key The name of a field in an individual document.
-	 * @return void
-	 */
-	public function offsetUnset($key) {
-		return $this->__unset($key);
-	}
-
-	/**
-	 * Rewinds to the first item.
-	 *
-	 * @return mixed The current item after rewinding.
-	 */
-	public function rewind() {
-		reset($this->_data);
-		reset($this->_updated);
-		$this->_valid = (count($this->_updated) > 0);
-		return current($this->_updated);
-	}
-
-	/**
-	 * Used by the `Iterator` interface to determine the current state of the iteration, and when
-	 * to stop iterating.
-	 *
-	 * @return boolean
-	 */
-	public function valid() {
-		return $this->_valid;
-	}
-
-	public function current() {
-		$current = current($this->_data);
-		return isset($this->_removed[key($this->_data)]) ? null : $current;
-	}
-
-	public function key() {
-		$key = key($this->_data);
-		return isset($this->_removed[$key]) ? false : $key;
-	}
-
-	/**
-	 * Adds conversions checks to ensure certain class types and embedded values are properly cast.
-	 *
-	 * @param string $format Currently only `array` is supported.
-	 * @param array $options
-	 * @return mixed
-	 */
-	public function to($format, array $options = array()) {
-		$defaults = array('handlers' => array(
-			'MongoId' => function($value) { return (string) $value; },
-			'MongoDate' => function($value) { return $value->sec; }
-		));
-		$options += $defaults;
-		$options['internal'] = false;
-		return parent::to($format, $options);
-	}
-
-	/**
-	 * Returns the next `Document` in the set, and advances the object's internal pointer. If the
-	 * end of the set is reached, a new document will be fetched from the data source connection
-	 * handle (`$_handle`). If no more records can be fetched, returns `null`.
-	 *
-	 * @return mixed Returns the next record in the set, or `null`, if no more records are
-	 *         available.
-	 */
-	public function next() {
-		$prev = key($this->_data);
-		$this->_valid = (next($this->_data) !== false);
-		$cur = key($this->_data);
-
-		if (isset($this->_removed[$cur])) {
-			return $this->next();
-		}
-		if (!$this->_valid && $cur !== $prev && $cur !== null) {
-			$this->_valid = true;
-		}
-		return $this->_valid ? $this->__get(key($this->_data)) : null;
-	}
-
-	/**
-	 * Safely (atomically) increments the value of the specified field by an arbitrary value.
-	 * Defaults to `1` if no value is specified. Throws an exception if the specified field is
-	 * non-numeric.
-	 *
-	 * @param string $field The name of the field to be incrememnted.
-	 * @param integer|string $value The value to increment the field by. Defaults to `1` if this
-	 *               parameter is not specified.
-	 * @return integer Returns the current value of `$field`, based on the value retrieved from the
-	 *         data source when the entity was loaded, plus any increments applied. Note that it
-	 *         may not reflect the most current value in the persistent backend data source.
-	 * @throws UnexpectedValueException Throws an exception when `$field` is set to a non-numeric
-	 *         type.
-	 */
-	public function increment($field, $value = 1) {
-		if (!isset($this->_increment[$field])) {
-			$this->_increment[$field] = 0;
-		}
-		$this->_increment[$field] += $value;
-
-		if (!is_numeric($this->_updated[$field])) {
-			throw new UnexpectedValueException("Field `{$field}` cannot be incremented.");
-		}
-		return $this->_updated[$field] += $value;
-	}
-}
-
-?>

+ 0 - 33
frameworks/PHP/php-lithium/libraries/lithium/data/entity/Record.php

@@ -1,33 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\entity;
-
-/**
- * `Record` class. Represents data such as a row from a database. Records have fields (often known
- * as columns in databases).
- */
-class Record extends \lithium\data\Entity {
-
-	/**
-	 * Converts a `Record` object to another specified format.
-	 *
-	 * @param string $format The format used by default is `array`
-	 * @param array $options
-	 * @return mixed
-	 */
-	public function to($format, array $options = array()) {
-		$defaults = array('handlers' => array(
-			'stdClass' => function($item) { return $item; }
-		));
-		$options += $defaults;
-		return parent::to($format, $options);
-	}
-}
-
-?>

+ 0 - 828
frameworks/PHP/php-lithium/libraries/lithium/data/model/Query.php

@@ -1,828 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\model;
-
-use lithium\util\Set;
-use lithium\data\Source;
-use lithium\core\ConfigException;
-use InvalidArgumentException;
-
-/**
- * The `Query` class acts as a container for all information necessary to perform a particular
- * database operation. Each `Query` object instance has a type, which is usually one of `'create'`,
- * `'read'`, `'update'` or `'delete'`.
- *
- * Because of this, `Query` objects are the primary method of communication between `Model` classes
- * and backend data sources. This helps to keep APIs abstract and flexible, since a model is only
- * required to call a single method against its backend. Since the `Query` object simply acts as a
- * structured data container, each backend can choose how to operate on the data the `Query`
- * contains. See each class method for more details on what data this class supports.
- *
- * @see lithium\data\Model
- * @see lithium\data\Source
- */
-class Query extends \lithium\core\Object {
-
-	/**
-	 * The 'type' of query to be performed. This is either `'create'`, `'read'`, `'update'` or
-	 * `'delete'`, and corresponds to the method to be executed.
-	 *
-	 * @var string
-	 */
-	protected $_type = null;
-
-	/**
-	 * Array containing mappings of relationship and field names, which allow database results to
-	 * be mapped to the correct objects.
-	 *
-	 * @var array
-	 */
-	protected $_map = array();
-
-	/**
-	 * If a `Query` is bound to a `Record` or `Document` object (i.e. for a `'create'` or
-	 * `'update'` query).
-	 *
-	 * @var object
-	 */
-	protected $_entity = null;
-
-	/**
-	 * An array of data used in a write context. Only used if no binding object is present in the
-	 * `$_entity` property.
-	 *
-	 * @var array
-	 */
-	protected $_data = array();
-
-	/**
-	 * A query can be assigned its own custom schema object, using the `schema()` method. If this
-	 * is not assigned, then the model associated with the query will be used to get the schema
-	 * information.
-	 *
-	 * @var object
-	 */
-	protected $_schema = null;
-
-	/**
-	 * Classes used by `Query`.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'schema' => 'lithium\data\Schema'
-	);
-
-	/**
-	 * The query's fields
-	 *
-	 * @see lithium\data\model\Query::fields()
-	 *
-	 * @var array
-	 */
-	protected $_fields = array(0 => array(), 1 => array());
-
-	/**
-	 * Count the number of identical models in a query for building
-	 * unique aliases
-	 *
-	 * @see lithium\data\model\Query::alias()
-	 *
-	 * @var array
-	 */
-	protected $_alias = array();
-
-	/**
-	 * Map beetween generated aliases and corresponding relation paths
-	 *
-	 * @see lithium\data\model\Query::alias()
-	 *
-	 * @var array
-	 */
-	protected $_paths = array();
-
-	/**
-	 * Map beetween generated aliases and corresponding models.
-	 *
-	 * @see lithium\data\model\Query::alias()
-	 *
-	 * @var array
-	 */
-	protected $_models = array();
-
-	/**
-	 * Auto configuration properties.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('type', 'map');
-
-	/**
-	 * Initialization methods on construct
-	 *
-	 * @var array
-	 */
-
-	protected $_initializers = array(
-		'model', 'entity', 'conditions', 'having', 'group', 'order',
-		'limit', 'offset', 'page', 'data', 'calculate', 'schema', 'comment'
-	);
-
-	/**
-	 * Boolean indicate if the query is built or not
-	 *
-	 * @var string
-	 */
-	protected $_built = false;
-
-	/**
-	 * Class constructor, which initializes the default values this object supports.
-	 * Even though only a specific list of configuration parameters is available
-	 * by default, the `Query` object uses the `__call()` method to implement
-	 * automatic getters and setters for any arbitrary piece of data.
-	 *
-	 * This means that any information may be passed into the constructor may be
-	 * used by the backend data source executing the query (or ignored, if support
-	 * is not implemented). This is useful if, for example, you wish to extend a
-	 * core data source and implement custom fucntionality.
-	 *
-	 * @param array $config Config options:
-	 *        - `'type'` _string_: The type of the query (`read`, `insert`, `update`, `delete`).
-	 *        - `'entity'` _object_: The base entity to query on. If set `'model'` is optionnal.
-	 *        - `'model'` _string_: The base model to query on.
-	 *        - `'source'` _string_: The name of the table/collection. Unnecessary
-	 *          if `model` is set.
-	 *        - `'alias'` _string_: Alias for the source. Unnecessary if `model` is set.
-	 *        - `'schema'` _object_: A schema model. Unnecessary if `model` is set.
-	 *        - `'fields'` _array_: The fields to retreive.
-	 *        - `'conditions'` _array_: The conditions of the queries
-	 *        - `'having'` _array_: The having conditions of the queries
-	 *        - `'group'` _string_: The group by parameter.
-	 *        - `'order'` _string_: The order by parameter.
-	 *        - `'limit'` _string_: The limit parameter.
-	 *        - `'offset'` _string_: The offset of the `limit` options.
-	 *        - `'page'` _string_: Convenience parameter for setting the `offset`:
-	 *          `offset` = `page` * `limit`.
-	 *        - `'with'` _array_: Contain dependencies. Works only if `model` is set.
-	 *        - `'joins'` _array_: Contain manual join dependencies.
-	 *        - `'data'` _array_: Datas for update queries.
-	 *        - `'whitelist'` _array_: Allowed fields for updating queries.
-	 *        - `'calculate'` _string_: Alias name of the count.
-	 *        - `'comment'` _string_: Comment for the query.
-	 *        - `'map'` _object_: Unnecessary if `model` is set.
-	 *        - `'relationships'` _array_: Unnecessary if `model` is set.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'model' => null,
-			'entity' => null,
-			'source' => null,
-			'alias' => null,
-			'fields' => array(),
-			'conditions' => array(),
-			'having' => array(),
-			'group' => null,
-			'order' => null,
-			'limit' => null,
-			'offset' => null,
-			'page' => null,
-			'with' => array(),
-			'joins' => array(),
-			'data' => array(),
-			'whitelist' => array(),
-			'calculate' => null,
-			'schema' => null,
-			'comment' => null,
-			'map' => array(),
-			'relationships' => array()
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-		unset($this->_config['type']);
-
-		$keys = array_keys($this->_config);
-		foreach ($this->_initializers as $key) {
-			$val = $this->_config[$key];
-			if ($val !== null) {
-				$this->_config[$key] = is_array($val) ? array() : null;
-				$this->{$key}($val);
-			}
-		}
-		if ($list = $this->_config['whitelist']) {
-			$this->_config['whitelist'] = array_combine($list, $list);
-		}
-
-		if ($this->_entity && !$this->_config['model']) {
-			$this->model($this->_entity->model());
-		}
-
-		if ($this->_config['with']) {
-			if (!$model = $this->model()) {
-				throw new ConfigException("The `'with'` option needs a valid binded model.");
-			}
-			$this->_config['with'] = Set::normalize($this->_config['with']);
-		}
-
-		if ($model = $this->model()) {
-			$this->alias($this->_config['alias'] ?: $model::meta('name'));
-		}
-
-		$this->fields($this->_config['fields']);
-
-		unset($this->_config['entity'], $this->_config['init']);
-	}
-
-	/**
-	 * Get method of type, i.e. 'read', 'update', 'create', 'delete'.
-	 *
-	 * @return string
-	 */
-	public function type() {
-		return $this->_type;
-	}
-
-	/**
-	 * Generates a schema map of the query's result set, where the keys are aliases, and the values
-	 * are arrays of field names.
-	 *
-	 * @param array $map
-	 * @return array
-	 */
-	public function map($map = null) {
-		if ($map !== null) {
-			$this->_map = $map;
-			return $this;
-		}
-		return $this->_map;
-	}
-
-	/**
-	 * Accessor method for `Query` calculate values.
-	 *
-	 * @param string $calculate Value for calculate config setting.
-	 * @return mixed Current calculate config value.
-	 */
-	public function calculate($calculate = null) {
-		if ($calculate) {
-			$this->_config['calculate'] = $calculate;
-			return $this;
-		}
-		return $this->_config['calculate'];
-	}
-
-	/**
-	 * Set and get method for the model associated with the `Query`.
-	 * Will also set the source table, i.e. `$this->_config['source']`.
-	 *
-	 * @param string $model
-	 * @return string
-	 */
-	public function model($model = null) {
-		if (!$model) {
-			return $this->_config['model'];
-		}
-		$this->_config['model'] = $model;
-		$this->_config['source'] = $this->_config['source'] ?: $model::meta('source');
-		return $this;
-	}
-
-	/**
-	 * Set and get method for conditions.
-	 *
-	 * If no conditions are set in query, it will ask the bound entity for condition array.
-	 *
-	 * @param mixed $conditions String or array to append to existing conditions.
-	 * @return array Returns an array of all conditions applied to this query.
-	 */
-	public function conditions($conditions = null) {
-		if (!$conditions) {
-			return $this->_config['conditions'] ?: $this->_entityConditions();
-		}
-		$conditions = (array) $conditions;
-		$this->_config['conditions'] = (array) $this->_config['conditions'];
-		$this->_config['conditions'] = array_merge($this->_config['conditions'], $conditions);
-		return $this;
-	}
-
-	/**
-	 * Set and get method for havings.
-	 *
-	 * @param mixed $having String or array to append to existing having.
-	 * @return array Returns an array of all having applied to this query.
-	 */
-	public function having($having = null) {
-		if (!$having) {
-			return $this->_config['having'];
-		}
-		$having = (array) $having;
-		$this->_config['having'] = (array) $this->_config['having'];
-		$this->_config['having'] = array_merge($this->_config['having'], $having);
-		return $this;
-	}
-
-	/**
-	 * Set, get or reset fields option for query.
-	 *
-	 * Usage:
-	 * {{{
-	 *	// to add a field
-	 *   $query->fields('created');
-	 * }}}
-	 * {{{
-	 *	// to add several fields
-	 *   $query->fields(array('title','body','modified'));
-	 * }}}
-	 * {{{
-	 *	// to reset fields to none
-	 *   $query->fields(false);
-	 *   // should be followed by a 2nd call to fields with required fields
-	 * }}}
-	 *
-	 * @param mixed $fields string, array or `false`
-	 * @param boolean $overwrite If `true`, existing fields will be removed before adding `$fields`.
-	 * @return array Returns an array containing all fields added to the query.
-	 */
-	public function fields($fields = null, $overwrite = false) {
-		if ($fields === false || $overwrite) {
-			$this->_fields = array(0 => array(), 1 => array());
-		}
-		if ($fields === null) {
-			return array_merge(array_keys($this->_fields[1]), $this->_fields[0]);
-		}
-		if (!$fields) {
-			return $this;
-		}
-		$fields = is_array($fields) ? $fields : array($fields);
-		foreach ($fields as $key => $field) {
-			if (is_string($field)) {
-				$this->_fields[1][$field] = true;
-			} elseif (is_array($field) && !is_numeric($key)) {
-				foreach ($field as &$val) {
-					$val = $key . '.' . $val;
-				}
-				$this->fields($field);
-			} else {
-				$this->_fields[0][] = $field;
-			}
-		}
-		return $this;
-	}
-
-	/**
-	 * Set and get method for query's limit of amount of records to return
-	 *
-	 * @param integer $limit
-	 * @return integer
-	 */
-	public function limit($limit = null) {
-		if ($limit) {
-			$this->_config['limit'] = intval($limit);
-			return $this;
-		}
-		if ($limit === false) {
-			$this->_config['limit'] = null;
-			return $this;
-		}
-		return $this->_config['limit'];
-	}
-
-	/**
-	 * Set and get method for query's offset, i.e. which records to get
-	 *
-	 * @param integer $offset
-	 * @return integer
-	 */
-	public function offset($offset = null) {
-		if ($offset !== null) {
-			$this->_config['offset'] = intval($offset);
-			return $this;
-		}
-		return $this->_config['offset'];
-	}
-
-	/**
-	 * Set and get method for page, in relation to limit, of which records to get
-	 *
-	 * @param integer $page
-	 * @return integer
-	 */
-	public function page($page = null) {
-		if ($page) {
-			$this->_config['page'] = $page = (intval($page) ?: 1);
-			$this->offset(($page - 1) * $this->_config['limit']);
-			return $this;
-		}
-		return $this->_config['page'];
-	}
-
-	/**
-	 * Set and get method for the query's order specification.
-	 *
-	 * @param array|string $order
-	 * @return mixed
-	 */
-	public function order($order = null) {
-		if ($order) {
-			$this->_config['order'] = $order;
-			return $this;
-		}
-		return $this->_config['order'];
-	}
-
-	/**
-	 * Set and get method for the `Query` group config setting.
-	 *
-	 * @param string $group New group config setting.
-	 * @return mixed Current group config setting.
-	 */
-	public function group($group = null) {
-		if ($group) {
-			$this->_config['group'] = $group;
-			return $this;
-		}
-		if ($group === false) {
-			$this->_config['group'] = null;
-			return $this;
-		}
-		return $this->_config['group'];
-	}
-
-	/**
-	 * Set and get method for current query's comment.
-	 *
-	 * Comment will have no effect on query, but will be passed along so data source can log it.
-	 *
-	 * @param string $comment
-	 * @return string
-	 */
-	public function comment($comment = null) {
-		if ($comment) {
-			$this->_config['comment'] = $comment;
-			return $this;
-		}
-		return $this->_config['comment'];
-	}
-
-	/**
-	 * Set and get method for the query's entity instance.
-	 *
-	 * @param object $entity Reference to the query's current entity object.
-	 * @return object Reference to the query's current entity object.
-	 */
-	public function &entity(&$entity = null) {
-		if ($entity) {
-			$this->_entity = $entity;
-			return $this;
-		}
-		return $this->_entity;
-	}
-
-	/**
-	 * Set and get method for the query's record's data.
-	 *
-	 * @param array $data if set, will set given array.
-	 * @return array Empty array if no data, array of data if the record has it.
-	 */
-	public function data($data = array()) {
-		$bind =& $this->_entity;
-
-		if ($data) {
-			$bind ? $bind->set($data) : $this->_data = array_merge($this->_data, $data);
-			return $this;
-		}
-		$data = $bind ? $bind->data() : $this->_data;
-		return ($list = $this->_config['whitelist']) ? array_intersect_key($data, $list) : $data;
-	}
-
-	/**
-	 * Set and get the relationships.
-	 *
-	 * @param string $relpath A dotted path.
-	 * @param array $config the config array to set.
-	 * @return mixed The relationships array or a relationship array if `$relpath` is set. Returns
-	 *         `null` if a join doesn't exist.
-	 * @throws InvalidArgumentException
-	 */
-	public function relationships($relpath = null, $config = null) {
-		if ($config) {
-			if (!$relpath) {
-				throw new InvalidArgumentException("The relation dotted path is empty.");
-			}
-			if (isset($config['model']) && isset($config['alias'])) {
-				$this->_models[$config['alias']] = $config['model'];
-			}
-			$this->_config['relationships'][$relpath] = $config;
-			return $this;
-		}
-		if (!$relpath) {
-			return $this->_config['relationships'];
-		}
-		if (isset($this->_config['relationships'][$relpath])) {
-			return $this->_config['relationships'][$relpath];
-		}
-	}
-
-	/**
-	 * Set and get the joins
-	 *
-	 * @param string $name Optional name of join. Unless two parameters are passed, this parameter
-	 *               is regonized as `$join`.
-	 * @param object|string $join A single query object or an array of query objects
-	 * @return mixed The joins array or a join array if `$name` is set. Returns `null` if a join
-	 *         doesn't exist.
-	 */
-	public function joins($name = null, $join = null) {
-		if (is_array($name)) {
-			$join = $name;
-			$name = null;
-		}
-		if ($join) {
-			if (!$name) {
-				$this->_config['joins'][] = $join;
-			} else {
-				$this->_config['joins'][$name] = $join;
-			}
-			return $this;
-		}
-		if (!$name) {
-			return $this->_config['joins'];
-		}
-		if (isset($this->_config['joins'][$name])) {
-			return $this->_config['joins'][$name];
-		}
-	}
-
-	/**
-	 * Convert the query's properties to the data sources' syntax and return it as an array.
-	 *
-	 * @param object $source Instance of the data source (`lithium\data\Source`) to use for
-	 *        conversion.
-	 * @param array $options Options to use when exporting the data.
-	 * @return array Returns an array containing a data source-specific representation of a query.
-	 */
-	public function export(Source $source, array $options = array()) {
-		$defaults = array('keys' => array());
-		$options += $defaults;
-
-		if ($options['keys']) {
-			$keys = array_flip($options['keys']);
-		} else {
-			$keys =& $this->_config;
-		}
-
-		$results = array('type' => $this->_type);
-
-		$apply = array_intersect_key($keys, array_flip($source->methods()));
-		$copy = array_diff_key($keys, $apply);
-
-		if (isset($keys['with'])) {
-			$this->applyStrategy($source);
-		}
-
-		foreach ($apply as $item => $value) {
-			$results[$item] = $source->{$item}($this->{$item}(), $this);
-		}
-
-		foreach ($copy as $item => $value) {
-			$results[$item] = $this->_config[$item];
-		}
-
-		if (array_key_exists('data', $keys)) {
-			$results['data'] = $this->_exportData();
-		}
-
-		if (array_key_exists('source', $keys)) {
-			$results['source'] = $source->name($results['source']);
-		}
-
-		if (!isset($results['fields'])) {
-			return $results;
-		}
-
-		$created = array('fields', 'values');
-
-		if (is_array($results['fields']) && array_keys($results['fields']) == $created) {
-			$results = $results['fields'] + $results;
-		}
-		return $results;
-	}
-
-	/**
-	 * Helper method used by `export()` which delegate the query generation to the datasource.
-	 *
-	 * @param object $source Instance of the data source (`lithium\data\Source`) to use for
-	 *        conversion.
-	 */
-	public function applyStrategy(Source $source) {
-		if ($this->_built) {
-			return;
-		}
-		$this->_built = true;
-		if (!$this->_config['with']) {
-			return;
-		}
-		$options = array();
-		if (isset($this->_config['strategy'])) {
-			$options['strategy'] = $this->_config['strategy'];
-		}
-		$source->applyStrategy($options, $this);
-	}
-
-	/**
-	 * Helper method used by `export()` to extract the data either from a bound entity, or from
-	 * passed configuration, and filter it through a configured whitelist, if present.
-	 *
-	 * @return array
-	 */
-	protected function _exportData() {
-		$data = $this->_entity ? $this->_entity->export() : $this->_data;
-		if (!$list = $this->_config['whitelist']) {
-			return $data;
-		}
-		$list = array_combine($list, $list);
-
-		if (!$this->_entity) {
-			return array_intersect_key($data, $list);
-		}
-
-		foreach ($data as $type => $values) {
-			if (!is_array($values)) {
-				continue;
-			}
-			$data[$type] = array_intersect_key($values, $list);
-		}
-		return $data;
-	}
-
-	public function schema($field = null) {
-		if (is_object($field)) {
-			$this->_schema = $field;
-			return;
-		}
-		if ($schema = $this->_schema) {
-			return $field ? $schema[$field] : $schema;
-		}
-		if ($model = $this->model()) {
-			return $model::schema($field);
-		} else {
-			return $this->_instance('schema');
-		}
-	}
-
-	/**
-	 * Get or Set a unique alias for the query or a query's relation if `$relpath` is set.
-	 *
-	 * @param mixed $alias The value of the alias to set for the passed `$relpath`. For getting an
-	 *        alias value set alias to `true`.
-	 * @param string $relpath A dotted relation name or `null` for identifying the query's model.
-	 * @return string An alias value or `null` for an unexisting `$relpath` alias.
-	 */
-	public function alias($alias = true, $relpath = null) {
-		if ($alias === true) {
-			if (!$relpath) {
-				return $this->_config['alias'];
-			}
-			$return = array_search($relpath, $this->_paths);
-			return $return ?: null;
-		}
-
-		if ($relpath === null) {
-			$this->_config['alias'] = $alias;
-		}
-
-		if ($relpath === null && ($model = $this->_config['model'])) {
-			$this->_models[$alias] = $model;
-		}
-
-		$relpath = (string) $relpath;
-		unset($this->_paths[array_search($relpath, $this->_paths)]);
-
-		if (!$alias && $relpath) {
-			$last = strrpos($relpath, '.');
-			$alias = $last ? substr($relpath, $last + 1) : $relpath;
-		}
-
-		if (isset($this->_alias[$alias])) {
-			$this->_alias[$alias]++;
-			$alias .= '__' . $this->_alias[$alias];
-		} else {
-			$this->_alias[$alias] = 1;
-		}
-
-		$this->_paths[$alias] = $relpath;
-		return $alias;
-	}
-
-	/**
-	 * Return the generated aliases mapped to their relation path
-	 *
-	 * @param object $source Instance of the data source (`lithium\data\Source`) to use for
-	 *        conversion.
-	 * @return array Map between aliases and their corresponding dotted relation paths.
-	 */
-	public function paths(Source $source = null) {
-		if ($source) {
-			$this->applyStrategy($source);
-		}
-		return $this->_paths;
-	}
-
-	/**
-	 * Return the generated aliases mapped to their corresponding model
-	 *
-	 * @param object $source Instance of the data source (`lithium\data\Source`) to use for
-	 *        conversion.
-	 * @return array Map between aliases and their corresponding fully-namespaced model names.
-	 */
-	public function models(Source $source = null) {
-		if ($source) {
-			$this->applyStrategy($source);
-		}
-		return $this->_models;
-	}
-
-	/**
-	 * Gets or sets a custom query field which does not have an accessor method.
-	 *
-	 * @param string $method Query part.
-	 * @param array $params Query parameters.
-	 * @return mixed Returns the value as set in the `Query` object's constructor.
-	 */
-	public function __call($method, array $params = array()) {
-		if ($params) {
-			$this->_config[$method] = current($params);
-			return $this;
-		}
-		return isset($this->_config[$method]) ? $this->_config[$method] : null;
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public function respondsTo($method, $internal = false) {
-		return isset($this->_config[$method]) || parent::respondsTo($method, $internal);
-	}
-
-	/**
-	 * Will return a find first condition on the associated model if a record is connected.
-	 * Called by conditions when it is called as a get and no condition is set.
-	 *
-	 * @return array Returns an array in the following format:
-	 *         `([model's primary key'] => [that key set in the record])`.
-	 */
-	protected function _entityConditions() {
-		if (!$this->_entity || !($model = $this->_config['model'])) {
-			return;
-		}
-		$key = $model::key($this->_entity->data());
-
-		if (!$key && $this->_type != "create") {
-			throw new ConfigException('No matching primary key found.');
-		}
-		if (is_array($key)) {
-			return $key;
-		}
-
-		$key = $model::meta('key');
-		$val = $this->_entity->{$key};
-		return $val ? array($key => $val) : array();
-	}
-
-	/**
-	 * Get/set sub queries for the query.
-	 * The getter must be called after an export since the sub queries are built
-	 * during the export according the export's `mode` option and the query `with` option.
-	 *
-	 * @see lithium\data\model\Query::export()
-	 *
-	 * @param string $relpath a dotted relation path
-	 * @param string $query a query instance
-	 * @return mixed
-	 */
-
-	public function childs($relpath = null, $query = null) {
-		if (!$model = $this->model()) {
-			throw new ConfigException("No binded model.");
-		}
-		if ($query) {
-			$this->_childs[$relpath] = $query;
-			return $this;
-		}
-		return $this->_childs;
-	}
-}
-
-?>

+ 0 - 22
frameworks/PHP/php-lithium/libraries/lithium/data/model/QueryException.php

@@ -1,22 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\model;
-
-/**
- * The `QueryException` is thrown when a CRUD operation on the database returns an
- * error.
- *
- * @see lithium\data\model\Query
- */
-class QueryException extends \RuntimeException {
-
-	protected $code = 500;
-}
-
-?>

+ 0 - 174
frameworks/PHP/php-lithium/libraries/lithium/data/model/Relationship.php

@@ -1,174 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\model;
-
-use lithium\core\Libraries;
-use lithium\util\Inflector;
-use lithium\core\ConfigException;
-use lithium\core\ClassNotFoundException;
-
-/**
- * The `Relationship` class encapsulates the data and functionality necessary to link two model
- * classes together.
- */
-class Relationship extends \lithium\core\Object {
-
-	/**
-	 * A relationship linking type defined by one document or record (or multiple) being embedded
-	 * within another.
-	 */
-	const LINK_EMBEDDED = 'embedded';
-
-	/**
-	 * The reciprocal of `LINK_EMBEDDED`, this defines a linking type wherein an embedded document
-	 * references the document that contains it.
-	 */
-	const LINK_CONTAINED = 'contained';
-
-	/**
-	 * A one-to-one or many-to-one relationship in which a key contains an ID value linking to
-	 * another document or record.
-	 */
-	const LINK_KEY = 'key';
-
-	/**
-	 * A many-to-many relationship in which a key contains an embedded array of IDs linking to other
-	 * records or documents.
-	 */
-	const LINK_KEY_LIST = 'keylist';
-
-	/**
-	 * A relationship defined by a database-native reference mechanism, linking a key to an
-	 * arbitrary record or document in another data collection or entirely separate database.
-	 */
-	const LINK_REF = 'ref';
-
-	/**
-	 * Constructs an object that represents a relationship between two model classes.
-	 *
-	 * @param array $config The relationship's configuration, which defines how the two models in
-	 *        question are bound. The available options are:
-	 *
-	 *        - `'name'` _string_: The name of the relationship in the context of the
-	 *          originating model. For example, a `Posts` model might define a relationship to
-	 *          a `Users` model like so:
-	 * {{{ public $hasMany = array('Author' => array('to' => 'Users')); }}}
-	 * In this case, the relationship is bound to the `Users` model, but `'Author'` would be the
-	 * relationship name. This is the name with which the relationship is referenced in the
-	 * originating model.
-	 *        - `'key'` _mixed_: An array of fields that define the relationship, where the
-	 *          keys are fields in the originating model, and the values are fields in the
-	 *          target model. If the relationship is not deined by keys, this array should be
-	 *          empty.
-	 *        - `'type'` _string_: The type of relationship. Should be one of `'belongsTo'`,
-	 *          `'hasOne'` or `'hasMany'`.
-	 *        - `'from'` _string_: The fully namespaced class name of the model where this
-	 *          relationship originates.
-	 *        - `'to'` _string_: The fully namespaced class name of the model that this
-	 *          relationship targets.
-	 *        - `'link'` _string_: A constant specifying how the object bound to the
-	 *          originating model is linked to the object bound to the target model. For
-	 *          relational databases, the only valid value is `LINK_KEY`, which means a foreign
-	 *          key in one object matches another key (usually the primary key) in the other.
-	 *          For document-oriented and other non-relational databases, different types of
-	 *          linking, including key lists, database reference objects (such as MongoDB's
-	 *          `MongoDBRef`), or even embedding.
-	 *        - `'fields'` _mixed_: An array of the subset of fields that should be selected
-	 *          from the related object(s) by default. If set to `true` (the default), all
-	 *          fields are selected.
-	 *        - `'fieldName'` _string_: The name of the field used when accessing the related
-	 *          data in a result set. For example, in the case of `Posts hasMany Comments`, the
-	 *          field name defaults to `'comments'`, so comment data is accessed (assuming
-	 *          `$post = Posts::first()`) as `$post->comments`.
-	 *        - `'constraints'` _mixed_: A string or array containing additional constraints
-	 *          on the relationship query. If a string, can contain a literal SQL fragment or
-	 *          other database-native value. If an array, maps fields from the related object
-	 *          either to fields elsewhere, or to arbitrary expressions. In either case, _the
-	 *          values specified here will be literally interpreted by the database_.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'name' => null,
-			'key' => array(),
-			'type' => null,
-			'to'   => null,
-			'from' => null,
-			'link' => static::LINK_KEY,
-			'fields' => true,
-			'fieldName' => null,
-			'constraints' => array()
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-		$config =& $this->_config;
-		$type = $config['type'];
-
-		$name = ($type === 'hasOne') ? Inflector::pluralize($config['name']) : $config['name'];
-		$config['fieldName'] = $config['fieldName'] ?: lcfirst($name);
-
-		if (!$config['to']) {
-			$assoc = preg_replace("/\\w+$/", "", $config['from']) . $name;
-			$config['to'] = Libraries::locate('models', $assoc);
-		}
-		if (!$config['key'] || !is_array($config['key'])) {
-			$config['key'] = $this->_keys($config['key']);
-		}
-	}
-
-	public function data($key = null) {
-		if (!$key) {
-			return $this->_config;
-		}
-		return isset($this->_config[$key]) ? $this->_config[$key] : null;
-	}
-
-	public function __call($name, $args = array()) {
-		return $this->data($name);
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public function respondsTo($method, $internal = false) {
-		return is_callable(array($this, $method), true);
-	}
-
-	protected function _keys($keys) {
-		$config = $this->_config;
-		$hasRel = ($related = ($config['type'] === 'belongsTo') ? $config['to'] : $config['from']);
-
-		if (!$hasRel || !$keys) {
-			return array();
-		}
-		if (!class_exists($related)) {
-			throw new ClassNotFoundException("Related model class '{$related}' not found.");
-		}
-		if (!$related::key()) {
-			throw new ConfigException("No key defined for related model `{$related}`.");
-		}
-		$keys = (array) $keys;
-		$related = (array) $related::key();
-
-		if (count($keys) !== count($related)) {
-			$msg  = "Unmatched keys in relationship `{$config['name']}` between models ";
-			$msg .= "`{$config['from']}` and `{$config['to']}`.";
-			throw new ConfigException($msg);
-		}
-		return array_combine($keys, $related);
-	}
-}
-
-?>

+ 0 - 1483
frameworks/PHP/php-lithium/libraries/lithium/data/source/Database.php

@@ -1,1483 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source;
-
-use PDO;
-use PDOException;
-use lithium\util\Set;
-use lithium\util\String;
-use lithium\util\Inflector;
-use InvalidArgumentException;
-use lithium\core\ConfigException;
-use lithium\core\NetworkException;
-use lithium\data\model\QueryException;
-
-/**
- * The `Database` class provides the base-level abstraction for SQL-oriented relational databases.
- * It handles all aspects of abstraction, including formatting for basic query types and SQL
- * fragments (i.e. for joins), converting `Query` objects to SQL, and various other functionality
- * which is shared across multiple relational databases.
- *
- * @see lithium\data\model\Query
- */
-abstract class Database extends \lithium\data\Source {
-
-	/**
-	 * @var PDO
-	 */
-	public $connection;
-
-	/**
-	 * The supported column types and their default values
-	 *
-	 * @var array
-	 */
-	protected $_columns = array(
-		'string' => array('length' => 255)
-	);
-
-	/**
-	 * Strings used to render the given statement
-	 *
-	 * @see lithium\data\source\Database::renderCommand()
-	 * @var array
-	 */
-	protected $_strings = array(
-		'create' => "INSERT INTO {:source} ({:fields}) VALUES ({:values});{:comment}",
-		'update' => "UPDATE {:source} SET {:fields} {:conditions};{:comment}",
-		'delete' => "DELETE {:flags} FROM {:source} {:conditions};{:comment}",
-		'schema' => "CREATE TABLE {:source} (\n{:columns}{:indexes});{:comment}",
-		'join'   => "{:type} JOIN {:source} {:alias} {:constraints}"
-	);
-
-	/**
-	 * Classes used by `Database`.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'entity' => 'lithium\data\entity\Record',
-		'set' => 'lithium\data\collection\RecordSet',
-		'relationship' => 'lithium\data\model\Relationship',
-		'result' => 'lithium\data\source\database\adapter\pdo\Result',
-		'schema' => 'lithium\data\Schema',
-		'query' => 'lithium\data\model\Query'
-	);
-
-	/**
-	 * List of SQL operators, paired with handling options.
-	 *
-	 * @var array
-	 */
-	protected $_operators = array(
-		'='  => array('multiple' => 'IN'),
-		'<'  => array(),
-		'>'  => array(),
-		'<=' => array(),
-		'>=' => array(),
-		'!=' => array('multiple' => 'NOT IN'),
-		'<>' => array('multiple' => 'NOT IN'),
-		'between' => array('format' => 'BETWEEN ? AND ?'),
-		'BETWEEN' => array('format' => 'BETWEEN ? AND ?'),
-		'like' => array(),
-		'LIKE' => array(),
-		'not like' => array(),
-		'NOT LIKE' => array()
-	);
-
-	protected $_constraintTypes = array(
-		'AND' => true,
-		'and' => true,
-		'OR' => true,
-		'or' => true
-	);
-
-	/**
-	 * A pair of opening/closing quote characters used for quoting identifiers in SQL queries.
-	 *
-	 * @var array
-	 */
-	protected $_quotes = array();
-
-	/**
-	 * Array of named callable objects representing different strategies for performing specific
-	 * types of queries.
-	 *
-	 * @var array
-	 */
-	protected $_strategies = array();
-
-	/**
-	 * Getter/Setter for the connection's encoding
-	 * Abstract. Must be defined by child class.
-	 *
-	 * @param mixed $encoding
-	 * @return mixed.
-	 */
-	abstract public function encoding($encoding = null);
-
-	/**
-	 * Return the last errors produced by a the execution of a query.
-	 * Abstract. Must be defined by child class.
-	 *
-	 */
-	abstract public function error();
-
-	/**
-	 * Execute a given query
-	 * Abstract. Must be defined by child class.
-	 *
-	 * @see lithium\data\source\Database::renderCommand()
-	 * @param string $sql The sql string to execute
-	 * @return resource
-	 */
-	abstract protected function _execute($sql);
-
-	/**
-	 * Get the last insert id from the database.
-	 * Abstract. Must be defined by child class.
-	 *
-	 * @param $query lithium\data\model\Query $context The given query.
-	 * @return void
-	 */
-	abstract protected function _insertId($query);
-
-	/**
-	 * Creates the database object and set default values for it.
-	 *
-	 * Options defined:
-	 *  - 'database' _string_ Name of the database to use. Defaults to `null`.
-	 *  - 'host' _string_ Name/address of server to connect to. Defaults to 'localhost'.
-	 *  - 'login' _string_ Username to use when connecting to server. Defaults to 'root'.
-	 *  - 'password' _string_ Password to use when connecting to server. Defaults to `''`.
-	 *  - 'persistent' _boolean_ If true a persistent connection will be attempted, provided the
-	 *    adapter supports it. Defaults to `true`.
-	 *
-	 * @param $config array Array of configuration options.
-	 * @return Database object.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'persistent' => true,
-			'host'       => 'localhost',
-			'login'      => 'root',
-			'password'   => '',
-			'database'   => null,
-			'encoding'   => null,
-			'dsn'        => null,
-			'options'    => array()
-		);
-		$this->_strings += array(
-			'read' => 'SELECT {:fields} FROM {:source} {:alias} {:joins} {:conditions} {:group} ' .
-			          '{:having} {:order} {:limit};{:comment}'
-		);
-		$this->_strategies += array(
-			'joined' => function($self, $model, $context) {
-
-				$with = $context->with();
-
-				$strategy = function($me, $model, $tree, $path, $from, &$deps) use ($self, $context, $with) {
-					foreach ($tree as $name => $childs) {
-						if (!$rel = $model::relations($name)) {
-							throw new QueryException("Model relationship `{$name}` not found.");
-						}
-
-						$constraints = array();
-						$alias = $name;
-						$relPath = $path ? $path . '.' . $name : $name;
-						if (isset($with[$relPath])) {
-							list($unallowed, $allowed) = Set::slice($with[$relPath], array(
-								'alias',
-								'constraints'
-							));
-							if ($unallowed) {
-								$message = "Only `'alias'` and `'constraints'` are allowed in ";
-								$message .= "`'with'` using the `'joined'` strategy.";
-								throw new QueryException($message);
-							}
-							extract($with[$relPath]);
-						}
-						$to = $context->alias($alias, $relPath);
-
-						$deps[$to] = $deps[$from];
-						$deps[$to][] = $from;
-
-						if ($context->relationships($relPath) === null) {
-							$context->relationships($relPath, array(
-								'type' => $rel->type(),
-								'model' => $rel->to(),
-								'fieldName' => $rel->fieldName(),
-								'alias' => $to
-							));
-							$self->join($context, $rel, $from, $to, $constraints);
-						}
-
-						if (!empty($childs)) {
-							$me($me, $rel->to(), $childs, $relPath, $to, $deps);
-						}
-					}
-				};
-
-				$tree = Set::expand(Set::normalize(array_keys($with)));
-				$alias = $context->alias();
-				$deps = array($alias => array());
-				$strategy($strategy, $model, $tree, '', $alias, $deps);
-
-				$models = $context->models();
-				foreach ($context->fields() as $field) {
-					if (!is_string($field)) {
-						continue;
-					}
-					list($alias, $field) = $self->invokeMethod('_splitFieldname', array($field));
-					$alias = $alias ?: $field;
-					if ($alias && isset($models[$alias])) {
-						foreach ($deps[$alias] as $depAlias) {
-							$depModel = $models[$depAlias];
-							$context->fields(array($depAlias => (array) $depModel::meta('key')));
-						}
-					}
-				}
-			},
-			'nested' => function($self, $model, $context) {
-				throw new QueryException("This strategy is not yet implemented.");
-			}
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	public function connect() {
-		$this->_isConnected = false;
-		$config = $this->_config;
-
-		if (!$config['database']) {
-			throw new ConfigException('No Database configured');
-		}
-		if (!$config['dsn']) {
-			throw new ConfigException('No DSN setup for DB Connection');
-		}
-		$dsn = $config['dsn'];
-
-		$options = $config['options'] + array(
-			PDO::ATTR_PERSISTENT => $config['persistent'],
-			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
-		);
-
-		try {
-			$this->connection = new PDO($dsn, $config['login'], $config['password'], $options);
-		} catch (PDOException $e) {
-			preg_match('/SQLSTATE\[(.+?)\]/', $e->getMessage(), $code);
-			$code = $code[1] ?: 0;
-			switch (true) {
-			case $code === 'HY000' || substr($code, 0, 2) === '08':
-				$msg = "Unable to connect to host `{$config['host']}`.";
-				throw new NetworkException($msg, null, $e);
-			case in_array($code, array('28000', '42000')):
-				$msg = "Host connected, but could not access database `{$config['database']}`.";
-				throw new ConfigException($msg, null, $e);
-			}
-			throw new ConfigException("An unknown configuration error has occured.", null, $e);
-		}
-		$this->_isConnected = true;
-
-		if ($this->_config['encoding']) {
-			$this->encoding($this->_config['encoding']);
-		}
-		return $this->_isConnected;
-	}
-
-	/**
-	 * Disconnects the adapter from the database.
-	 *
-	 * @return boolean Returns `true` on success, else `false`.
-	 */
-	public function disconnect() {
-		if ($this->_isConnected) {
-			unset($this->connection);
-			$this->_isConnected = false;
-		}
-		return true;
-	}
-
-	/**
-	 * Field name handler to ensure proper escaping.
-	 *
-	 * @param string $name Field or identifier name.
-	 * @return string Returns `$name` quoted according to the rules and quote characters of the
-	 *         database adapter subclass.
-	 */
-	public function name($name) {
-		$open  = reset($this->_quotes);
-		$close = next($this->_quotes);
-
-		list($first, $second) = $this->_splitFieldname($name);
-		if ($first) {
-			return "{$open}{$first}{$close}.{$open}{$second}{$close}";
-		}
-		return preg_match('/^[a-z0-9_-]+$/i', $name) ? "{$open}{$name}{$close}" : $name;
-	}
-
-	/**
-	 * Return the alias and the field name from an identifier name.
-	 *
-	 * @param string $field Field name or identifier name.
-	 * @return array Returns an array with the alias (or `null` if not applicable) as first value
-	 *         and the field name as second value.
-	 */
-	protected function _splitFieldname($field) {
-		if (is_string($field)) {
-			if (preg_match('/^[a-z0-9_-]+\.([a-z0-9_-]+|\*)$/i', $field)) {
-				return explode('.', $field, 2);
-			}
-		}
-		return array(null, $field);
-	}
-
-	/**
-	 * Return the field name from a conditions key.
-	 *
-	 * @param string $field Field or identifier name.
-	 * @return string Returns the field name without the table alias, if applicable.
-	 * @todo Eventually, this should be refactored and moved to the Query or Schema
-	 *       class. Also, by handling field resolution in this way we are not handling
-	 *       cases where query conditions use the same field name in multiple tables.
-	 *       e.g. Foos.bar and Bars.bar will both return bar.
-	 */
-	protected function _fieldName($field) {
-		if (is_string($field)) {
-			if (preg_match('/^[a-z0-9_-]+\.[a-z0-9_-]+$/i', $field)) {
-				list($first, $second) = explode('.', $field, 2);
-				return $second;
-			}
-		}
-		return $field;
-	}
-
-	/**
-	 * Converts a given value into the proper type based on a given schema definition.
-	 *
-	 * @see lithium\data\source\Database::schema()
-	 * @param mixed $value The value to be converted. Arrays will be recursively converted.
-	 * @param array $schema Formatted array from `lithium\data\source\Database::schema()`
-	 * @return mixed value with converted type
-	 */
-	public function value($value, array $schema = array()) {
-		if (is_array($value)) {
-			foreach ($value as $key => $val) {
-				$value[$key] = $this->value($val, isset($schema[$key]) ? $schema[$key] : $schema);
-			}
-			return $value;
-		}
-
-		if (is_object($value) && isset($value->scalar)) {
-			return $value->scalar;
-		}
-
-		if ($value === null) {
-			return 'NULL';
-		}
-
-		switch ($type = isset($schema['type']) ? $schema['type'] : $this->_introspectType($value)) {
-			case 'boolean':
-			case 'float':
-			case 'integer':
-				return $this->_cast($type, $value);
-			default:
-				return $this->connection->quote($this->_cast($type, $value));
-		}
-	}
-
-	/**
-	 * Inserts a new record into the database based on a the `Query`. The record is updated
-	 * with the id of the insert.
-	 *
-	 * @see lithium\util\String::insert()
-	 * @param object $query An SQL query string, or `lithium\data\model\Query` object instance.
-	 * @param array $options If $query is a string, $options contains an array of bind values to be
-	 *              escaped, quoted, and inserted into `$query` using `String::insert()`.
-	 * @return boolean Returns `true` if the query succeeded, otherwise `false`.
-	 * @filter
-	 */
-	public function create($query, array $options = array()) {
-		return $this->_filter(__METHOD__, compact('query', 'options'), function($self, $params) {
-			$query = $params['query'];
-			$model = $entity = $object = $id = null;
-
-			if (is_object($query)) {
-				$object = $query;
-				$model = $query->model();
-				$params = $query->export($self);
-				$entity =& $query->entity();
-				$query = $self->renderCommand('create', $params, $query);
-			} else {
-				$query = String::insert($query, $self->value($params['options']));
-			}
-
-			if (!$self->invokeMethod('_execute', array($query))) {
-				return false;
-			}
-
-			if ($entity) {
-				if (($model) && !$model::key($entity)) {
-					$id = $self->invokeMethod('_insertId', array($object));
-				}
-				$entity->sync($id);
-			}
-			return true;
-		});
-	}
-
-	/**
-	 * Reads records from a database using a `lithium\data\model\Query` object or raw SQL string.
-	 *
-	 * @param string|object $query `lithium\data\model\Query` object or SQL string.
-	 * @param array $options If `$query` is a raw string, contains the values that will be escaped
-	 *               and quoted. Other options:
-	 *               - `'return'` _string_: switch return between `'array'`, `'item'`, or
-	 *                 `'resource'` _string_: Defaults to `'item'`.
-	 * @return mixed Determined by `$options['return']`.
-	 * @filter
-	 */
-	public function read($query, array $options = array()) {
-		$defaults = array(
-			'return' => is_string($query) ? 'array' : 'item',
-			'schema' => null,
-			'quotes' => $this->_quotes
-		);
-		$options += $defaults;
-
-		return $this->_filter(__METHOD__, compact('query', 'options'), function($self, $params) {
-			$query = $params['query'];
-			$args = $params['options'];
-			$return = $args['return'];
-			unset($args['return']);
-
-			$model = is_object($query) ? $query->model() : null;
-
-			if (is_string($query)) {
-				$sql = String::insert($query, $self->value($args));
-			} else {
-				if (!$data = $self->invokeMethod('_queryExport', array($query))) {
-					return false;
-				}
-				$sql = $self->renderCommand($data['type'], $data);
-			}
-			$result = $self->invokeMethod('_execute', array($sql));
-
-			switch ($return) {
-				case 'resource':
-					return $result;
-				case 'array':
-					$columns = $args['schema'] ?: $self->schema($query, $result);
-
-					if (!is_array(reset($columns))) {
-						$columns = array('' => $columns);
-					}
-
-					$i = 0;
-					$records = array();
-					foreach ($result as $data) {
-						$offset = 0;
-						$records[$i] = array();
-						foreach ($columns as $path => $cols) {
-							$len = count($cols);
-							$values = array_combine($cols, array_slice($data, $offset, $len));
-							if ($path) {
-								$records[$i][$path] = $values;
-							} else {
-								$records[$i] += $values;
-							}
-							$offset += $len;
-						}
-						$i++;
-					}
-					return Set::expand($records);
-				case 'item':
-					return $self->item($query->model(), array(), compact('query', 'result') + array(
-						'class' => 'set'
-					));
-			}
-		});
-	}
-
-	/**
-	 * Helper which export the query export
-	 *
-	 * @param object $query The query object
-	 * @return array The export array
-	 */
-	protected function &_queryExport($query) {
-		$data = $query->export($this);
-		if ($query->limit() && ($model = $query->model())) {
-			foreach ($query->relationships() as $relation) {
-				if ($relation['type'] === 'hasMany') {
-					$name = $model::meta('name');
-					$key = $model::key();
-					$fields = $data['fields'];
-					$fieldname = $this->name("{$name}.{$key}");
-					$data['fields'] = "DISTINCT({$fieldname}) AS _ID_";
-					$sql = $this->renderCommand('read', $data);
-					$result = $this->_execute($sql);
-
-					$ids = array();
-					while ($row = $result->next()) {
-						$ids[] = $row[0];
-					}
-
-					if (!$ids) {
-						$return = null;
-						return $return;
-					}
-					$data['fields'] = $fields;
-					$data['limit'] = '';
-					$data['conditions'] = $this->conditions(array("{$name}.{$key}" => $ids), $query);
-					return $data;
-				}
-			}
-		}
-		return $data;
-	}
-
-	/**
-	 * Updates a record in the database based on the given `Query`.
-	 *
-	 * @param object $query A `lithium\data\model\Query` object
-	 * @param array $options none
-	 * @return boolean
-	 * @filter
-	 */
-	public function update($query, array $options = array()) {
-		return $this->_filter(__METHOD__, compact('query', 'options'), function($self, $params) {
-			$query = $params['query'];
-			$params = $query->export($self);
-			$sql = $self->renderCommand('update', $params, $query);
-			$result = (boolean) $self->invokeMethod('_execute', array($sql));
-
-			if ($result && is_object($query) && $query->entity()) {
-				$query->entity()->sync();
-			}
-			return $result;
-		});
-	}
-
-	/**
-	 * Deletes a record in the database based on the given `Query`.
-	 *
-	 * @param object $query An SQL string, or `lithium\data\model\Query` object instance.
-	 * @param array $options If `$query` is a string, `$options` is the array of quoted/escaped
-	 *              parameter values to be inserted into the query.
-	 * @return boolean Returns `true` on successful query execution (not necessarily if records are
-	 *         deleted), otherwise `false`.
-	 * @filter
-	 */
-	public function delete($query, array $options = array()) {
-		return $this->_filter(__METHOD__, compact('query', 'options'), function($self, $params) {
-			$query = $params['query'];
-			$isObject = is_object($query);
-
-			if ($isObject) {
-				$sql = $self->renderCommand('delete', $query->export($self), $query);
-			} else {
-				$sql = String::insert($query, $self->value($params['options']));
-			}
-			$result = (boolean) $self->invokeMethod('_execute', array($sql));
-
-			if ($result && $isObject && $query->entity()) {
-				$query->entity()->sync(null, array(), array('dematerialize' => true));
-			}
-			return $result;
-		});
-	}
-
-	/**
-	 * Executes calculation-related queries, such as those required for `count` and other
-	 * aggregates.
-	 *
-	 * @param string $type Only accepts `count`.
-	 * @param mixed $query The query to be executed.
-	 * @param array $options Optional arguments for the `read()` query that will be executed
-	 *        to obtain the calculation result.
-	 * @return integer Result of the calculation.
-	 */
-	public function calculation($type, $query, array $options = array()) {
-		$query->calculate($type);
-
-		switch ($type) {
-			case 'count':
-				if (strpos($fields = $this->fields($query->fields(), $query), ',') !== false) {
-					$fields = "*";
-				}
-				$query->fields("COUNT({$fields}) as count", true);
-				$query->map(array($query->alias() => array('count')));
-				list($record) = $this->read($query, $options)->data();
-				return isset($record['count']) ? intval($record['count']) : null;
-		}
-	}
-
-	/**
-	 * Defines or modifies the default settings of a relationship between two models.
-	 *
-	 * @param string $class the primary model of the relationship
-	 * @param string $type the type of the relationship (hasMany, hasOne, belongsTo)
-	 * @param string $name the name of the relationship
-	 * @param array $config relationship options
-	 * @return array Returns an array containing the configuration for a model relationship.
-	 */
-	public function relationship($class, $type, $name, array $config = array()) {
-		$field = Inflector::underscore(Inflector::singularize($name));
-		$key = "{$field}_id";
-		$primary = $class::meta('key');
-
-		if (is_array($primary)) {
-			$key = array_combine($primary, $primary);
-		} elseif ($type === 'hasMany' || $type === 'hasOne') {
-			if ($type === 'hasMany') {
-				$field = Inflector::pluralize($field);
-			}
-			$secondary = Inflector::underscore(Inflector::singularize($class::meta('name')));
-			$key = array($primary => "{$secondary}_id");
-		}
-
-		$from = $class;
-		$fieldName = $field;
-		$config += compact('type', 'name', 'key', 'from', 'fieldName');
-		return $this->_instance('relationship', $config);
-	}
-
-	/**
-	 * Determines the set of methods to be used when exporting query values.
-	 *
-	 * @return array
-	 */
-	public function methods() {
-		$result = parent::methods();
-		$key = array_search('schema', $result);
-		unset($result[$key]);
-		return $result;
-	}
-
-	/**
-	 * Returns a given `type` statement for the given data, rendered from `Database::$_strings`.
-	 *
-	 * @param string $type One of `'create'`, `'read'`, `'update'`, `'delete'` or `'join'`.
-	 * @param string $data The data to replace in the string.
-	 * @param string $context
-	 * @return string
-	 */
-	public function renderCommand($type, $data = null, $context = null) {
-		if (is_object($type)) {
-			$context = $type;
-			$data = $context->export($this);
-			$type = $context->type();
-		}
-		if (!isset($this->_strings[$type])) {
-			throw new InvalidArgumentException("Invalid query type `{$type}`.");
-		}
-		$template = $this->_strings[$type];
-		$data = array_filter($data);
-		return trim(String::insert($template, $data, array('clean' => true)));
-	}
-
-	/**
-	 * Builds an array of keyed on the fully-namespaced `Model` with array of fields as values
-	 * for the given `Query`
-	 *
-	 * @param data\model\Query $query A Query instance.
-	 * @param object $resource
-	 * @param object $context
-	 */
-	public function schema($query, $resource = null, $context = null) {
-		if (is_object($query)) {
-			$query->applyStrategy($this);
-			return $this->_schema($query, $this->_fields($query->fields(), $query));
-		}
-
-		$result = array();
-		$count = $resource->resource()->columnCount();
-
-		for ($i = 0; $i < $count; $i++) {
-			$meta = $resource->resource()->getColumnMeta($i);
-			$result[] = $meta['name'];
-		}
-		return $result;
-	}
-
-	/**
-	 * Helper method for `data\model\Database::shema()`
-	 *
-	 * @param data\model\Query $query A Query instance.
-	 * @param array $fields Array of formatted fields.
-	 */
-	protected function _schema($query, $fields = null) {
-		$model = $query->model();
-		$paths = $query->paths($this);
-		$models = $query->models($this);
-		$alias = $query->alias();
-		$result = array();
-
-		if (!$model) {
-			foreach ($fields as $field => $value) {
-				if (is_array($value)) {
-					$result[$field] = array_keys($value);
-				} else {
-					$result[''][] = $field;
-				}
-			}
-			return $result;
-		}
-		if (!$fields) {
-			foreach ($paths as $alias => $relation) {
-				$model = $models[$alias];
-				$result[$relation] = $model::schema()->names();
-			}
-			return $result;
-		}
-
-		$unalias = function ($value) {
-			if (is_object($value) && isset($value->scalar)) {
-				$value = $value->scalar;
-			}
-			$aliasing = preg_split("/\s+as\s+/i", $value);
-			return isset($aliasing[1]) ? $aliasing[1] : $value;
-		};
-
-		if (isset($fields[0])) {
-			$raw = array_map($unalias, $fields[0]);
-			unset($fields[0]);
-		}
-
-		$fields = isset($fields[$alias]) ? array($alias => $fields[$alias]) + $fields : $fields;
-
-		foreach ($fields as $field => $value) {
-			if (is_array($value)) {
-				if (isset($value['*'])) {
-					$relModel = $models[$field];
-					$result[$paths[$field]] = $relModel::schema()->names();
-				} else {
-					$result[$paths[$field]] = array_map($unalias, array_keys($value));
-				}
-			}
-		}
-
-		if (isset($raw)) {
-			$result[''] = isset($result['']) ? array_merge($raw, $result['']) : $raw;
-		}
-		return $result;
-	}
-
-	/**
-	 * Returns a string of formatted conditions to be inserted into the query statement. If the
-	 * query conditions are defined as an array, key pairs are converted to SQL strings.
-	 *
-	 * Conversion rules are as follows:
-	 *
-	 * - If `$key` is numeric and `$value` is a string, `$value` is treated as a literal SQL
-	 *   fragment and returned.
-	 *
-	 * @param string|array $conditions The conditions for this query.
-	 * @param object $context The current `lithium\data\model\Query` instance.
-	 * @param array $options
-	 *               - `prepend` _boolean_: Whether the return string should be prepended with the
-	 *                 `WHERE` keyword.
-	 * @return string Returns the `WHERE` clause of an SQL query.
-	 */
-	public function conditions($conditions, $context, array $options = array()) {
-		$defaults = array('prepend' => 'WHERE');
-		$options += $defaults;
-		return $this->_conditions($conditions, $context, $options);
-	}
-
-	/**
-	 * Returns a string of formatted havings to be inserted into the query statement. If the
-	 * query havings are defined as an array, key pairs are converted to SQL strings.
-	 *
-	 * Conversion rules are as follows:
-	 *
-	 * - If `$key` is numeric and `$value` is a string, `$value` is treated as a literal SQL
-	 *   fragment and returned.
-	 *
-	 * @param string|array $conditions The havings for this query.
-	 * @param object $context The current `lithium\data\model\Query` instance.
-	 * @param array $options
-	 *               - `prepend` _boolean_: Whether the return string should be prepended with the
-	 *                 `HAVING` keyword.
-	 * @return string Returns the `HAVING` clause of an SQL query.
-	 */
-	public function having($conditions, $context, array $options = array()) {
-		$defaults = array('prepend' => 'HAVING');
-		$options += $defaults;
-		return $this->_conditions($conditions, $context, $options);
-	}
-
-	/**
-	 * Returns a string of formatted conditions to be inserted into the query statement. If the
-	 * query conditions are defined as an array, key pairs are converted to SQL strings.
-	 *
-	 * Conversion rules are as follows:
-	 *
-	 * - If `$key` is numeric and `$value` is a string, `$value` is treated as a literal SQL
-	 *   fragment and returned.
-	 *
-	 * @param string|array $conditions The conditions for this query.
-	 * @param object $context The current `lithium\data\model\Query` instance.
-	 * @param array $options
-	 *               - `prepend` mixed: The string to prepend or false for no prepending
-	 * @return string Returns an SQL conditions clause.
-	 */
-	protected function _conditions($conditions, $context, array $options = array()) {
-		$defaults = array('prepend' => false);
-		$ops = $this->_operators;
-		$options += $defaults;
-
-		switch (true) {
-			case empty($conditions):
-				return '';
-			case is_string($conditions):
-				return $options['prepend'] ? $options['prepend'] . " {$conditions}" : $conditions;
-			case !is_array($conditions):
-				return '';
-		}
-		$result = array();
-
-		foreach ($conditions as $key => $value) {
-			$return = $this->_processConditions($key, $value, $context);
-
-			if ($return) {
-				$result[] = $return;
-			}
-		}
-		$result = join(" AND ", $result);
-		return ($options['prepend'] && $result) ? $options['prepend'] . " {$result}" : $result;
-	}
-
-	protected function _processConditions($key, $value, $context, $schema = null, $glue = 'AND') {
-		$constraintTypes =& $this->_constraintTypes;
-		$model = $context->model();
-		$models = $context->models();
-
-		list($first, $second) = $this->_splitFieldname($key);
-		if ($first && isset($models[$first]) && $class = $models[$first]) {
-			$schema = $class::schema();
-		} elseif ($model) {
-			$schema = $model::schema();
-		}
-		$fieldMeta = $schema ? (array) $schema->fields($second) : array();
-
-		switch (true) {
-			case (is_numeric($key) && is_string($value)):
-				return $value;
-			case is_object($value) && isset($value->scalar):
-				if (is_numeric($key)) {
-					return $this->value($value);
-				}
-			case is_scalar($value) || is_null($value):
-				if ($context && ($context->type() === 'read') && ($alias = $context->alias())) {
-					$key = $this->_aliasing($key, $alias);
-				}
-				if (isset($value)) {
-					return $this->name($key) . ' = ' . $this->value($value, $fieldMeta);
-				}
-				return $this->name($key) . " IS NULL";
-			case is_numeric($key) && is_array($value):
-				$result = array();
-				foreach ($value as $cKey => $cValue) {
-					$result[] = $this->_processConditions($cKey, $cValue, $context, $schema, $glue);
-				}
-				return '(' . implode(' ' . $glue . ' ', $result) . ')';
-			case (is_string($key) && is_object($value)):
-				$value = trim(rtrim($this->renderCommand($value), ';'));
-				return "{$this->name($key)} IN ({$value})";
-			case is_array($value) && isset($constraintTypes[strtoupper($key)]):
-				$result = array();
-				$glue = strtoupper($key);
-
-				foreach ($value as $cKey => $cValue) {
-					$result[] = $this->_processConditions($cKey, $cValue, $context, $schema, $glue);
-				}
-				return '(' . implode(' ' . $glue . ' ', $result) . ')';
-			case (is_string($key) && is_array($value) && isset($this->_operators[key($value)])):
-				foreach ($value as $op => $val) {
-					$result[] = $this->_operator($key, array($op => $val), $fieldMeta);
-				}
-				return '(' . implode(' ' . $glue . ' ', $result) . ')';
-			case is_array($value):
-				if (!is_numeric($op = key($value))) {
-					throw new QueryException("Unsupported operator `{$op}`.");
-				}
-				$value = join(', ', $this->value($value, $fieldMeta));
-				return "{$this->name($key)} IN ({$value})";
-		}
-	}
-
-	/**
-	 * Returns a string of formatted fields to be inserted into the query statement.
-	 *
-	 * @param array $fields Array of fields.
-	 * @param object $context Generally a `data\model\Query` instance.
-	 * @return string A SQL formatted string
-	 */
-	public function fields($fields, $context) {
-		$type = $context->type();
-		$schema = $context->schema()->fields();
-		$alias = $context->alias();
-
-		if (!is_array($fields)) {
-			return $this->_fieldsReturn($type, $context, $fields, $schema);
-		}
-
-		$context->applyStrategy($this);
-		$fields = $this->_fields($fields ? : $context->fields(), $context);
-		$context->map($this->_schema($context, $fields));
-		$toMerge = array();
-
-		if (isset($fields[0])) {
-			foreach ($fields[0] as $val) {
-				$toMerge[] = (is_object($val) && isset($val->scalar)) ? $val->scalar : $val;
-			}
-			unset($fields[0]);
-		}
-
-		$fields = isset($fields[$alias]) ? array($alias => $fields[$alias]) + $fields : $fields;
-
-		foreach ($fields as $field => $value) {
-			if (is_array($value)) {
-				if (isset($value['*'])) {
-					$toMerge[] = $this->name($field) . '.*';
-					continue;
-				}
-				foreach ($value as $fieldname => $mode) {
-					$toMerge[] = $this->_fieldsQuote($field, $fieldname);
-				}
-			}
-		}
-
-		return $this->_fieldsReturn($type, $context, $toMerge, $schema);
-	}
-
-	/**
-	 * Helper for `Database::fields()` && `Database::schema()`.
-	 * Reformat fields to be alias based.
-	 *
-	 * @param array $fields Array of fields.
-	 * @param object $context Generally a `data\model\Query` instance.
-	 * @return array Reformatted fields
-	 */
-	protected function _fields($fields, $context) {
-		$alias = $context->alias();
-		$models = $context->models($this);
-		$list = array();
-		foreach ($fields as $key => $field) {
-			if (!is_string($field)) {
-				if (isset($models[$key])) {
-					$field = array_fill_keys($field, true);
-					$list[$key] = isset($list[$key]) ? array_merge($list[$key], $field) : $field;
-				} else {
-					$list[0][] = is_array($field) ? reset($field) : $field;
-				}
-				continue;
-			}
-			if (preg_match('/^([a-z0-9_-]+|\*)$/i', $field)) {
-				isset($models[$field]) ? $list[$field]['*'] = true : $list[$alias][$field] = true;
-			} elseif (preg_match('/^([a-z0-9_-]+)\.(.*)$/i', $field, $matches)) {
-				$list[$matches[1]][$matches[2]] = true;
-			} else {
-				$list[0][] = $field;
-			}
-		}
-		return $list;
-	}
-
-	protected function _fieldsQuote($alias, $field) {
-		$open = $this->_quotes[0];
-		$close = $this->_quotes[1];
-		$aliasing = preg_split("/\s+as\s+/i", $field);
-		if (isset($aliasing[1])) {
-			list($aliasname, $fieldname) = $this->_splitFieldname($aliasing[0]);
-			$alias = $aliasname ? : $alias;
-			return "{$open}{$alias}{$close}.{$open}{$fieldname}{$close} as {$aliasing[1]}";
-		} elseif ($alias) {
-			return "{$open}{$alias}{$close}.{$open}{$field}{$close}";
-		} else {
-			return "{$open}{$field}{$close}";
-		}
-	}
-
-	protected function _fieldsReturn($type, $context, $fields, $schema) {
-		if ($type === 'create' || $type === 'update') {
-			$data = $context->data();
-			if (isset($data['data']) && is_array($data['data']) && count($data) === 1) {
-				$data = $data['data'];
-			}
-
-			if ($fields && is_array($fields) && is_int(key($fields))) {
-				$data = array_intersect_key($data, array_combine($fields, $fields));
-			}
-			$method = "_{$type}Fields";
-			return $this->{$method}($data, $schema, $context);
-		}
-		return empty($fields) ? '*' : join(', ', $fields);
-	}
-
-	/**
-	 * Returns a LIMIT statement from the given limit and the offset of the context object.
-	 *
-	 * @param integer $limit An
-	 * @param object $context The `lithium\data\model\Query` object
-	 * @return string
-	 */
-	public function limit($limit, $context) {
-		if (!$limit) {
-			return;
-		}
-		if ($offset = $context->offset() ?: '') {
-			$offset = " OFFSET {$offset}";
-		}
-		return "LIMIT {$limit}{$offset}";
-	}
-
-	/**
-	 * Returns a join statement for given array of query objects
-	 *
-	 * @param object|array $joins A single or array of `lithium\data\model\Query` objects
-	 * @param object $context The parent `lithium\data\model\Query` object
-	 * @return string
-	 */
-	public function joins(array $joins, $context) {
-		$result = null;
-
-		foreach ($joins as $key => $join) {
-			if ($result) {
-				$result .= ' ';
-			}
-			$join = is_array($join) ? $this->_instance('query', $join) : $join;
-			$options['keys'] = array('source', 'alias', 'constraints');
-			$result .= $this->renderCommand('join', $join->export($this, $options));
-		}
-		return $result;
-	}
-
-		/**
-	 * Returns a string of formatted constraints to be inserted into the query statement. If the
-	 * query constraints are defined as an array, key pairs are converted to SQL strings.
-	 *
-	 * Conversion rules are as follows:
-	 *
-	 * - If `$key` is numeric and `$value` is a string, `$value` is treated as a literal SQL
-	 *   fragment and returned.
-	 *
-	 * @param string|array $constraints The constraints for a `ON` clause.
-	 * @param object $context The current `lithium\data\model\Query` instance.
-	 * @param array $options
-	 *               - `prepend` _boolean_: Whether the return string should be prepended with the
-	 *                 `ON` keyword.
-	 * @return string Returns the `ON` clause of an SQL query.
-	 */
-	public function constraints($constraints, $context, array $options = array()) {
-		$defaults = array('prepend' => 'ON');
-		$options += $defaults;
-		if (is_array($constraints)) {
-			$constraints = $this->_constraints($constraints);
-		}
-		return $this->_conditions($constraints, $context, $options);
-	}
-
-	/**
-	 * Auto escape string value to a field name value
-	 *
-	 * @param array $constraints The constraints array
-	 * @return array The escaped constraints array
-	 */
-	protected function _constraints(array $constraints) {
-		foreach ($constraints as &$value) {
-			if (is_string($value)) {
-				$value = (object) $this->name($value);
-			} elseif (is_array($value)) {
-				$value = $this->_constraints($value);
-			}
-		}
-		return $constraints;
-	}
-
-	/**
-	 * Return formatted clause for order.
-	 *
-	 * @param mixed $order The `order` clause to be formatted
-	 * @param object $context
-	 * @return mixed Formatted `order` clause.
-	 */
-	public function order($order, $context) {
-		$direction = 'ASC';
-		$model = $context->model();
-
-		if (is_string($order)) {
-			if (!$model::schema($order)) {
-				$match = '/\s+(A|DE)SC/i';
-				return "ORDER BY {$order}" . (preg_match($match, $order) ? '' : " {$direction}");
-			}
-			$order = array($order => $direction);
-		}
-
-		if (!is_array($order)) {
-			return;
-		}
-		$result = array();
-
-		foreach ($order as $column => $dir) {
-			if (is_int($column)) {
-				$column = $dir;
-				$dir = $direction;
-			}
-			$dir = in_array($dir, array('ASC', 'asc', 'DESC', 'desc')) ? $dir : $direction;
-
-			if (!$model) {
-				$result[] = "{$column} {$dir}";
-				continue;
-			}
-			if ($field = $model::schema($column)) {
-				$name = $this->name($model::meta('name')) . '.' . $this->name($column);
-				$result[] = "{$name} {$dir}";
-				continue;
-			}
-			$result[] = "{$column} {$dir}";
-		}
-		$order = join(', ', $result);
-		return "ORDER BY {$order}";
-	}
-
-	public function group($group, $context = null) {
-		if (!$group) {
-			return null;
-		}
-		return 'GROUP BY ' . join(', ', (array) $group);
-	}
-
-	/**
-	 * Adds formatting to SQL comments before they're embedded in queries.
-	 *
-	 * @param string $comment
-	 * @return string
-	 */
-	public function comment($comment) {
-		return $comment ? "/* {$comment} */" : null;
-	}
-
-	public function alias($alias, $context) {
-		if (!$alias && ($model = $context->model())) {
-			$alias = $model::meta('name');
-		}
-		return $alias ? "AS " . $this->name($alias) : null;
-	}
-
-	public function cast($entity, array $data, array $options = array()) {
-		return $data;
-	}
-
-	/**
-	 * Cast a value according to a column type.
-	 *
-	 * @param string $type Name of the column type
-	 * @param string $value Value to cast
-	 *
-	 * @return mixed Casted value
-	 *
-	 */
-	protected function _cast($type, $value) {
-		if (is_object($value) || $value === null) {
-			return $value;
-		}
-		if ($type === 'boolean') {
-			return $this->_toNativeBoolean($value);
-		}
-		if (!isset($this->_columns[$type]) || !isset($this->_columns[$type]['formatter'])) {
-			return $value;
-		}
-
-		$column = $this->_columns[$type];
-
-		switch ($column['formatter']) {
-			case 'date':
-				return $column['formatter']($column['format'], strtotime($value));
-			default:
-				return $column['formatter']($value);
-		}
-	}
-
-	protected function _createFields($data, $schema, $context) {
-		$fields = $values = array();
-
-		foreach ($data as $field => $value) {
-			$fields[] = $this->name($field);
-			$values[] = $this->value($value, isset($schema[$field]) ? $schema[$field] : array());
-		}
-		$fields = join(', ', $fields);
-		$values = join(', ', $values);
-		return compact('fields', 'values');
-	}
-
-	protected function _updateFields($data, $schema, $context) {
-		$fields = array();
-
-		foreach ($data as $field => $value) {
-			$schema += array($field => array('default' => null));
-			$fields[] = $this->name($field) . ' = ' . $this->value($value, $schema[$field]);
-		}
-		return join(', ', $fields);
-	}
-
-	/**
-	 * Handles conversion of SQL operator keys to SQL statements.
-	 *
-	 * @param string $key Key in a conditions array. Usually a field name.
-	 * @param mixed $value An SQL operator or comparison value.
-	 * @param array $schema An array defining the schema of the field used in the criteria.
-	 * @param array $options
-	 * @return string Returns an SQL string representing part of a `WHERE` clause of a query.
-	 */
-	protected function _operator($key, $value, array $schema = array(), array $options = array()) {
-		$defaults = array('boolean' => 'AND');
-		$options += $defaults;
-
-		list($op, $value) = each($value);
-		$config = $this->_operators[$op];
-		$key = $this->name($key);
-		$values = array();
-
-		if (!is_object($value)) {
-			foreach ((array) $value as $val) {
-				$values[] = $this->value($val, $schema);
-			}
-		} elseif (isset($value->scalar)) {
-			return "{$key} {$op} {$value->scalar}";
-		}
-
-		switch (true) {
-			case (isset($config['format'])):
-				return $key . ' ' . String::insert($config['format'], $values);
-			case (is_object($value) && isset($config['multiple'])):
-				$op = $config['multiple'];
-				$value = trim(rtrim($this->renderCommand($value), ';'));
-				return "{$key} {$op} ({$value})";
-			case (count($values) > 1 && isset($config['multiple'])):
-				$op = $config['multiple'];
-				$values = join(', ', $values);
-				return "{$key} {$op} ({$values})";
-			case (count($values) > 1):
-				return join(" {$options['boolean']} ", array_map(
-					function($v) use ($key, $op) { return "{$key} {$op} {$v}"; }, $values
-				));
-		}
-		return "{$key} {$op} {$values[0]}";
-	}
-
-	/**
-	 * Returns a fully-qualified table name (i.e. with prefix), quoted.
-	 *
-	 * @param string $entity A table name or fully-namespaced model class name.
-	 * @param array $options Available options:
-	 *              - `'quoted'` _boolean_: Indicates whether the name should be quoted.
-	 * @return string Returns a quoted table name.
-	 */
-	protected function _entityName($entity, array $options = array()) {
-		$defaults = array('quoted' => false);
-		$options += $defaults;
-
-		if (class_exists($entity, false) && method_exists($entity, 'meta')) {
-			$entity = $entity::meta('source');
-		}
-		return $options['quoted'] ? $this->name($entity) : $entity;
-	}
-
-	/**
-	 * Attempts to automatically determine the column type of a value. Used by the `value()` method
-	 * of various database adapters to determine how to prepare a value if the schema is not
-	 * specified.
-	 *
-	 * @param mixed $value The value to be prepared for an SQL query.
-	 * @return string Returns the name of the column type which `$value` most likely belongs to.
-	 */
-	protected function _introspectType($value) {
-		switch (true) {
-			case (is_bool($value)):
-				return 'boolean';
-			case (is_float($value) || preg_match('/^\d+\.\d+$/', $value)):
-				return 'float';
-			case (is_int($value) || preg_match('/^\d+$/', $value)):
-				return 'integer';
-			case (is_string($value) && strlen($value) <= $this->_columns['string']['length']):
-				return 'string';
-			default:
-				return 'text';
-		}
-	}
-
-	/**
-	 * Casts a value which is being written or compared to a boolean-type database column.
-	 *
-	 * @param mixed $value A value of unknown type to be cast to boolean. Numeric values not equal
-	 *              to zero evaluate to `true`, otherwise `false`. String values equal to `'true'`,
-	 *              `'t'` or `'T'` evaluate to `true`, all others to `false`. In all other cases,
-	 *               uses PHP's default casting.
-	 * @return boolean Returns a boolean representation of `$value`, based on the comparison rules
-	 *         specified above. Database adapters may override this method if boolean type coercion
-	 *         is required and falls outside the rules defined.
-	 */
-	protected function _toBoolean($value) {
-		if (is_bool($value)) {
-			return $value;
-		}
-		if (is_int($value) || is_float($value)) {
-			return ($value !== 0);
-		}
-		if (is_string($value)) {
-			return ($value === 't' || $value === 'T' || $value === 'true');
-		}
-		return (boolean) $value;
-	}
-
-	protected function _toNativeBoolean($value) {
-		return $value ? 1 : 0;
-	}
-
-	/**
-	 * Throw a `QueryException` error
-	 *
-	 * @param string $sql The offending SQL string
-	 * @filter
-	 */
-	protected function _error($sql){
-		$params = compact('sql');
-		return $this->_filter(__METHOD__, $params, function($self, $params) {
-			$sql = $params['sql'];
-			list($code, $error) = $self->error();
-			throw new QueryException("{$sql}: {$error}", $code);
-		});
-	}
-
-	/**
-	 * Applying a strategy to a `lithium\data\model\Query` object
-	 *
-	 * @param array $options The option array
-	 * @param object $context A query object to configure
-	 */
-	public function applyStrategy($options, $context) {
-		$options += array('strategy' => 'joined');
-		if (!$model = $context->model()) {
-			throw new ConfigException('The `\'with\'` option need a valid `\'model\'` option.');
-		}
-
-		$strategy = $options['strategy'];
-		if (isset($this->_strategies[$strategy])) {
-			$strategy = $this->_strategies[$strategy];
-			$strategy($this, $model, $context);
-		} else {
-			throw new QueryException("Undefined query strategy `{$strategy}`.");
-		}
-	}
-
-	/**
-	 * Set a query's join according a Relationship.
-	 *
-	 * @param object $context A Query instance
-	 * @param object $rel A Relationship instance
-	 * @param string $fromAlias Set a specific alias for the `'from'` `Model`.
-	 * @param string $toAlias Set a specific alias for `'to'` `Model`.
-	 * @param mixed $constraints If `$constraints` is an array, it will be merged to defaults
-	 *        constraints. If `$constraints` is an object, defaults won't be merged.
-	 */
-	public function join($context, $rel, $fromAlias = null, $toAlias = null, $constraints = array()) {
-		$model = $rel->to();
-
-		if ($fromAlias === null) {
-			$from = $rel->from();
-			$fromAlias = $context->alias();
-		}
-		if ($toAlias === null) {
-			$toAlias = $context->alias(null, $rel->name());
-		}
-		if (!is_object($constraints)) {
-			$constraints = $this->on($rel, $fromAlias, $toAlias, $constraints);
-		} else {
-			$constraints = (array) $constraints;
-		}
-
-		$context->joins($toAlias, compact('constraints', 'model') + array(
-			'type' => 'LEFT',
-			'alias' => $toAlias
-		));
-	}
-
-	/**
-	 * Helper which add an alias basename to a field name if necessary
-	 *
-	 * @param string $name The field name.
-	 * @param string $alias The alias name
-	 * @param array $map An array of `'modelname' => 'aliasname'` mapping
-	 * @return string
-	 */
-	protected function _aliasing($name, $alias, $map = array()) {
-		list($first, $second) = $this->_splitFieldname($name);
-		if (!$first && preg_match('/^[a-z0-9_-]+$/i', $second)) {
-			return $alias . "." . $second;
-		} elseif (isset($map[$first])) {
-			return $map[$first] . "." . $second;
-		}
-		return $name;
-	}
-
-	/**
-	 * Build the `ON` constraints from a `Relationship` instance
-	 *
-	 * @param object $rel A Relationship instance
-	 * @param string $fromAlias Set a specific alias for the `'from'` `Model`.
-	 * @param string $toAlias Set a specific alias for `'to'` `Model`.
-	 * @param array $constraints Array of additionnal $constraints.
-	 * @return array A constraints array.
-	 */
-
-	public function on($rel, $aliasFrom = null, $aliasTo = null, $constraints = array()) {
-		$model = $rel->from();
-
-		$aliasFrom = $aliasFrom ?: $model::meta('name');
-		$aliasTo = $aliasTo ?: $rel->name();
-
-		$keyConstraints = array();
-		foreach ($rel->key() as $from => $to) {
-			$keyConstraints["{$aliasFrom}.{$from}"] = "{$aliasTo}.{$to}";
-		}
-
-		$mapAlias = array($model::meta('name') => $aliasFrom, $rel->name() => $aliasTo);
-
-		$relConstraints = $this->_on((array) $rel->constraints(), $aliasFrom, $aliasTo, $mapAlias);
-		$constraints = $this->_on($constraints, $aliasFrom, $aliasTo, array());
-
-		return $constraints + $relConstraints + $keyConstraints;
-	}
-
-	protected function _on(array $constraints, $aliasFrom, $aliasTo, $mapAlias = array()) {
-		$result = array();
-		foreach ($constraints as $key => $value) {
-			if (
-				!is_numeric($key) &&
-				!isset($this->_constraintTypes[$key]) &&
-				!isset($this->_operators[$key])
-			) {
-				$key = $this->_aliasing($key, $aliasFrom, $mapAlias);
-			}
-			if (is_string($value)) {
-				$result[$key] = $this->_aliasing($value, $aliasTo, $mapAlias);
-			} elseif (is_array($value)) {
-				$result[$key] = $this->_on($value, $aliasFrom, $aliasTo, $mapAlias);
-			} else {
-				$result[$key] = $value;
-			}
-		}
-		return $result;
-	}
-}
-
-?>

+ 0 - 311
frameworks/PHP/php-lithium/libraries/lithium/data/source/Http.php

@@ -1,311 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source;
-
-use lithium\util\String;
-use lithium\data\model\Query;
-
-/**
- * Http class to access data sources using `lithium\net\http\Service`.
- */
-class Http extends \lithium\data\Source {
-
-	/**
-	 * Service connection
-	 *
-	 * @var object lithium\net\http\Service
-	 */
-	public $connection = null;
-
-	/**
-	 * The set of array keys which will be auto-populated in the object's protected properties from
-	 * constructor parameters.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('classes' => 'merge', 'methods' => 'merge');
-
-	/**
-	 * Fully-namespaced class references
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'schema'  => 'lithium\data\Schema',
-		'service' => 'lithium\net\http\Service',
-		'relationship' => 'lithium\data\model\Relationship'
-	);
-
-	/**
-	 * Is Connected?
-	 *
-	 * @var boolean
-	 */
-	protected $_isConnected = false;
-
-	/**
-	 * List of methods and their corresponding HTTP method and path.
-	 *
-	 * @var array
-	 */
-	protected $_methods = array(
-		'create' => array('method' => 'post', 'path' => "/{:source}"),
-		'read'   => array('method' => 'get', 'path' => "/{:source}"),
-		'update' => array('method' => 'put', 'path' => "/{:source}/{:id}"),
-		'delete' => array('method' => 'delete', 'path' => "/{:source}/{:id}")
-	);
-
-	/**
-	 * Constructor
-	 *
-	 * @param array $config
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'adapter'    => null,
-			'persistent' => false,
-			'scheme'     => 'http',
-			'host'       => 'localhost',
-			'version'    => '1.1',
-			'auth'       => null,
-			'login'      => '',
-			'password'   => '',
-			'port'       => 80,
-			'timeout'    => 30,
-			'encoding'   => 'UTF-8',
-			'methods'    => array()
-		);
-		$config = $config + $defaults;
-		$config['username'] = $config['login'];
-		parent::__construct($config);
-	}
-
-	protected function _init() {
-		$config = $this->_config;
-		unset($config['type']);
-		$this->connection = $this->_instance('service', $config);
-		parent::_init();
-	}
-
-	/**
-	 * Pass properties to service connection
-	 *
-	 * @param string $property
-	 * @return mixed
-	 */
-	public function __get($property) {
-		return $this->connection->{$property};
-	}
-
-	/**
-	 * Pass methods to service connection. Path and method are determined from Http::$_method. If
-	 * not set, a GET request with the $method as the path will be used.
-	 *
-	 * @see lithium\data\source\Http::$_method
-	 * @param string $method
-	 * @param array $params
-	 * @return mixed
-	 * @filter
-	 */
-	public function __call($method, $params) {
-		if (!isset($this->_methods[$method])) {
-			if (method_exists($this->connection, $method)) {
-				return $this->connection->invokeMethod($method, $params);
-			}
-			$this->_methods[$method] = array('path' => "/{$method}");
-		}
-		$params += array(array(), array());
-
-		if (!is_object($params[0])) {
-			$config = (array) $params[0];
-
-			if (count($config) === count($config, COUNT_RECURSIVE)) {
-				$config = array('data' => $config);
-			}
-			$params[0] = new Query($this->_methods[$method] + $config);
-		}
-		$params[0] = new Query($params[0]->export($this) + $this->_methods[$method]);
-
-		return $this->_filter(__CLASS__ . "::" . $method, $params, function($self, $params) {
-			list($query, $options) = $params;
-			return $self->send($query, $options);
-		});
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public function respondsTo($method, $internal = false) {
-		return isset($this->_methods[$method]) || parent::respondsTo($method, $internal);
-	}
-
-	/**
-	 * Method to send to a specific resource.
-	 *
-	 * @param array $query a query object
-	 * @param array $options array.
-	 * @return result
-	 */
-	public function send($query = null, array $options = array()) {
-		$query = !is_object($query) ? new Query((array) $query) : $query;
-		$method = $query->method() ?: "get";
-		$path = $query->path();
-		$data = $query->data();
-		$insert = (array) $options + $data + $query->export($this);
-
-		if (preg_match_all('/\{:(\w+)\}/', $path, $matches)) {
-			$keys = array_flip($matches[1]);
-			$data = array_diff_key($data,  array_flip($matches[1]));
-		}
-		$path = String::insert($path, $insert, array('clean' => true));
-		$data += (array) $query->conditions() + array('limit' => $query->limit());
-		return $this->connection->{$method}($path, $data, (array) $options);
-	}
-
-	/**
-	 * Fake the connection since service is called for every method.
-	 *
-	 * @return boolean
-	 */
-	public function connect() {
-		if (!$this->_isConnected) {
-			$this->_isConnected = true;
-		}
-		return $this->_isConnected;
-	}
-
-	/**
-	 * Disconnect from socket.
-	 *
-	 * @return boolean
-	 */
-	public function disconnect() {
-		if ($this->_isConnected && $this->connection !== null) {
-			$this->_isConnected = false;
-		}
-		return !$this->_isConnected;
-	}
-
-	/**
-	 * Returns available data sources (typically a list of REST resources collections).
-	 *
-	 * @param object $class
-	 * @return array
-	 */
-	public function sources($class = null) {
-		return array();
-	}
-
-	/**
-	 * Describe data source.
-	 *
-	 * @param string $entity
-	 * @param array $fields
-	 * @param array $meta
-	 * @return array - returns an empty array
-	 */
-	public function describe($entity, $fields = array(), array $meta = array()) {
-		return $this->_instance('schema', compact('fields', 'meta'));
-	}
-
-	/**
-	 * Create function used to POST.
-	 *
-	 * @param object $query
-	 * @param array $options
-	 * @return void
-	 * @filter
-	 */
-	public function create($query, array $options = array()) {
-		$query = !is_object($query) ? new Query() : $query;
-		$query->method() ?: $query->method("post");
-		$query->path() ?: $query->path("/{:source}");
-		return $this->_filter(__METHOD__, array($query, $options), function($self, $params) {
-			list($query, $options) = $params;
-			return $self->send($query, $options);
-		});
-	}
-
-	/**
-	 * Read used by model to GET.
-	 *
-	 * @param object $query
-	 * @param array $options
-	 * @return string
-	 * @filter
-	 */
-	public function read($query, array $options = array()) {
-		$query = !is_object($query) ? new Query() : $query;
-		$query->method() ?: $query->method("get");
-		$query->path() ?: $query->path("/{:source}");
-		return $this->_filter(__METHOD__, array($query, $options), function($self, $params) {
-			list($query, $options) = $params;
-			return $self->send($query, $options);
-		});
-	}
-
-	/**
-	 * Update used by model to PUT.
-	 *
-	 * @param object $query
-	 * @param array $options
-	 * @return string
-	 * @filter
-	 */
-	public function update($query, array $options = array()) {
-		$query = !is_object($query) ? new Query() : $query;
-		$query->method() ?: $query->method("put");
-		$query->path() ?: $query->path("/{:source}/{:id}");
-		return $this->_filter(__METHOD__, array($query, $options), function($self, $params) {
-			list($query, $options) = $params;
-			return $self->send($query, $options);
-		});
-	}
-
-	/**
-	 * Used by model to DELETE.
-	 *
-	 * @param object $query
-	 * @param array $options
-	 * @return string
-	 * @filter
-	 */
-	public function delete($query, array $options = array()) {
-		$query = !is_object($query) ? new Query() : $query;
-		$query->method() ?: $query->method("delete");
-		$query->path() ?: $query->path("/{:source}/{:id}");
-		return $this->_filter(__METHOD__, array($query, $options), function($self, $params) {
-			list($query, $options) = $params;
-			return $self->send($query, $options);
-		});
-
-	}
-
-	/**
-	 * Defines or modifies the default settings of a relationship between two models.
-	 *
-	 * @param string $class
-	 * @param string $type
-	 * @param string $name
-	 * @param array $options
-	 * @return array Returns an array containing the configuration for a model relationship.
-	 */
-	public function relationship($class, $type, $name, array $options = array()) {
-		if (isset($this->_classes['relationship'])) {
-			return $this->_instance('relationship', compact('type', 'name') + $options);
-		}
-		return null;
-	}
-}
-
-?>

+ 0 - 64
frameworks/PHP/php-lithium/libraries/lithium/data/source/Mock.php

@@ -1,64 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source;
-
-/**
- * The `Mock` data source is used behind-the-scenes when a model does not use a backend data source.
- * It implements the necessary methods, but does not support querying and has no storage backend.
- * It can create generic entities for use in forms and elsewhere within the framework. This allows
- * developers to create domain objects with business logic and schemas, without worrying about
- * backend storage.
- */
-class Mock extends \lithium\data\Source {
-
-	protected $_classes = array(
-		'entity' => 'lithium\data\Entity',
-		'set' => 'lithium\data\Collection',
-		'relationship' => 'lithium\data\model\Relationship',
-		'schema' => 'lithium\data\Schema'
-	);
-
-	public function connect() {
-		return true;
-	}
-
-	public function disconnect() {
-		return true;
-	}
-
-	public function sources($class = null) {
-		return array();
-	}
-
-	public function describe($entity, $fields = array(), array $meta = array()) {
-		return $this->_instance('schema', compact('fields'));
-	}
-
-	public function relationship($class, $type, $name, array $options = array()) {
-		return false;
-	}
-
-	public function create($query, array $options = array()) {
-		return false;
-	}
-
-	public function read($query, array $options = array()) {
-		return false;
-	}
-
-	public function update($query, array $options = array()) {
-		return false;
-	}
-
-	public function delete($query, array $options = array()) {
-		return false;
-	}
-}
-
-?>

+ 0 - 844
frameworks/PHP/php-lithium/libraries/lithium/data/source/MongoDb.php

@@ -1,844 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source;
-
-use MongoCode;
-use MongoRegex;
-use lithium\util\Inflector;
-use lithium\core\NetworkException;
-use Exception;
-
-/**
- * A data source adapter which allows you to connect to the MongoDB database engine. MongoDB is an
- * Open Source distributed document database which bridges the gap between key/value stores and
- * relational databases. To learn more about MongoDB, see here:
- * [http://www.mongodb.org/](http://www.mongodb.org/).
- *
- * Rather than operating on records and record sets, queries against MongoDB will return nested sets
- * of `Document` objects. A `Document`'s fields can contain both simple and complex data types
- * (i.e. arrays) including other `Document` objects.
- *
- * After installing MongoDB, you can connect to it as follows:
- * {{{
- * // config/bootstrap/connections.php:
- * Connections::add('default', array('type' => 'MongoDb', 'database' => 'myDb'));
- * }}}
- *
- * By default, it will attempt to connect to a Mongo instance running on `localhost` on port
- * 27017. See `__construct()` for details on the accepted configuration settings.
- *
- * @see lithium\data\entity\Document
- * @see lithium\data\Connections::add()
- * @see lithium\data\source\MongoDb::__construct()
- */
-class MongoDb extends \lithium\data\Source {
-
-	/**
-	 * The Mongo class instance.
-	 *
-	 * @var object
-	 */
-	public $server = null;
-
-	/**
-	 * The MongoDB object instance.
-	 *
-	 * @var object
-	 */
-	public $connection = null;
-
-	/**
-	 * Classes used by this class.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'entity'       => 'lithium\data\entity\Document',
-		'set'          => 'lithium\data\collection\DocumentSet',
-		'result'       => 'lithium\data\source\mongo_db\Result',
-		'schema'       => 'lithium\data\source\mongo_db\Schema',
-		'exporter'     => 'lithium\data\source\mongo_db\Exporter',
-		'relationship' => 'lithium\data\model\Relationship',
-		'server'       => 'Mongo'
-	);
-
-	/**
-	 * Map of typical SQL-like operators to their MongoDB equivalents.
-	 *
-	 * @var array Keys are SQL-like operators, value is the MongoDB equivalent.
-	 */
-	protected $_operators = array(
-		'<'   => '$lt',
-		'>'   => '$gt',
-		'<='  => '$lte',
-		'>='  => '$gte',
-		'!='  => array('single' => '$ne', 'multiple' => '$nin'),
-		'<>'  => array('single' => '$ne', 'multiple' => '$nin'),
-		'or'  => '$or',
-		'||'  => '$or',
-		'not' => '$not',
-		'!'   => '$not',
-		'and' => '$and',
-		'&&'  => '$and',
-		'nor' => 'nor'
-	);
-
-	/**
-	 * List of comparison operators to use when performing boolean logic in a query.
-	 *
-	 * @var array
-	 */
-	protected $_boolean = array('&&', '||', 'and', '$and', 'or', '$or', 'nor', '$nor');
-
-	/**
-	 * A closure or anonymous function which receives an instance of this class, a collection name
-	 * and associated meta information, and returns an array defining the schema for an associated
-	 * model, where the keys are field names, and the values are arrays defining the type
-	 * information for each field. At a minimum, type arrays must contain a `'type'` key. For more
-	 * information on schema definitions, and an example schema callback implementation, see the
-	 * `$_schema` property of the `Model` class.
-	 *
-	 * @see lithium\data\Model::$_schema
-	 * @var Closure
-	 */
-	protected $_schema = null;
-
-	/**
-	 * List of configuration keys which will be automatically assigned to their corresponding
-	 * protected class properties.
-	 *
-	 * @var array
-	 */
-	protected $_autoConfig = array('schema', 'classes' => 'merge');
-
-	/**
-	 * Instantiates the MongoDB adapter with the default connection information.
-	 *
-	 * @see lithium\data\Connections::add()
-	 * @see lithium\data\source\MongoDb::$_schema
-	 * @link http://php.net/manual/en/mongo.construct.php PHP Manual: Mongo::__construct()
-	 * @param array $config All information required to connect to the database, including:
-	 *        - `'database'` _string_: The name of the database to connect to. Defaults to `null`.
-	 *        - `'host'` _string_: The IP or machine name where Mongo is running, followed by a
-	 *           colon, and the port number. Defaults to `'localhost:27017'`.
-	 *        - `'persistent'` _mixed_: Determines a persistent connection to attach to. See the
-	 *           `$options` parameter of
-	 *            [`Mongo::__construct()`](http://www.php.net/manual/en/mongo.construct.php) for
-	 *            more information. Defaults to `false`, meaning no persistent connection is made.
-	 *        - `'timeout'` _integer_: The number of milliseconds a connection attempt will wait
-	 *          before timing out and throwing an exception. Defaults to `100`.
-	 *        - `'schema'` _closure_: A closure or anonymous function which returns the schema
-	 *          information for a model class. See the `$_schema` property for more information.
-	 *        - `'gridPrefix'` _string_: The default prefix for MongoDB's `chunks` and `files`
-	 *          collections. Defaults to `'fs'`.
-	 *        - `'replicaSet'` _string_: See the documentation for `Mongo::__construct()`. Defaults
-	 *          to `false`.
-	 *        - `'readPreference'` _mixed_: May either be a single value such as Mongo::RP_NEAREST,
-	 *          or an array containing a read preference and a tag set such as:
-	 *          array(Mongo::RP_SECONDARY_PREFERRED, array('dc' => 'east) See the documentation for
-	 *          `Mongo::setReadPreference()`. Defaults to null.
-	 *
-	 * Typically, these parameters are set in `Connections::add()`, when adding the adapter to the
-	 * list of active connections.
-	 */
-	public function __construct(array $config = array()) {
-		$host = 'localhost:27017';
-
-		$server = $this->_classes['server'];
-		if (class_exists($server, false)) {
-			$host = $server::DEFAULT_HOST . ':' . $server::DEFAULT_PORT;
-		}
-		$defaults = compact('host') + array(
-			'persistent' => false,
-			'login'      => null,
-			'password'   => null,
-			'database'   => null,
-			'timeout'    => 100,
-			'replicaSet' => false,
-			'schema'     => null,
-			'gridPrefix' => 'fs',
-			'safe'       => false,
-			'readPreference' => null
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-
-		$this->_operators += array('like' => function($key, $value) {
-			return new MongoRegex($value);
-		});
-	}
-
-	/**
-	 * Ensures that the server connection is closed and resources are freed when the adapter
-	 * instance is destroyed.
-	 *
-	 * @return void
-	 */
-	public function __destruct() {
-		if ($this->_isConnected) {
-			$this->disconnect();
-		}
-	}
-
-	/**
-	 * With no parameter, checks to see if the `mongo` extension is installed. With a parameter,
-	 * queries for a specific supported feature.
-	 *
-	 * @param string $feature Test for support for a specific feature, i.e. `"transactions"` or
-	 *               `"arrays"`.
-	 * @return boolean Returns `true` if the particular feature (or if MongoDB) support is enabled,
-	 *         otherwise `false`.
-	 */
-	public static function enabled($feature = null) {
-		if (!$feature) {
-			return extension_loaded('mongo');
-		}
-		$features = array(
-			'arrays' => true,
-			'transactions' => false,
-			'booleans' => true,
-			'relationships' => true
-		);
-		return isset($features[$feature]) ? $features[$feature] : null;
-	}
-
-	/**
-	 * Configures a model class by overriding the default dependencies for `'set'` and
-	 * `'entity'` , and sets the primary key to `'_id'`, in keeping with Mongo's conventions.
-	 *
-	 * @see lithium\data\Model::$_meta
-	 * @see lithium\data\Model::$_classes
-	 * @param string $class The fully-namespaced model class name to be configured.
-	 * @return Returns an array containing keys `'classes'` and `'meta'`, which will be merged with
-	 *         their respective properties in `Model`.
-	 */
-	public function configureClass($class) {
-		return array('schema' => array(), 'meta' => array('key' => '_id', 'locked' => false));
-	}
-
-	/**
-	 * Connects to the Mongo server. Matches up parameters from the constructor to create a Mongo
-	 * database connection.
-	 *
-	 * @see lithium\data\source\MongoDb::__construct()
-	 * @link http://php.net/manual/en/mongo.construct.php PHP Manual: Mongo::__construct()
-	 * @return boolean Returns `true` the connection attempt was successful, otherwise `false`.
-	 */
-	public function connect() {
-		if ($this->server && $this->server->connected && $this->connection) {
-			return $this->_isConnected = true;
-		}
-
-		$cfg = $this->_config;
-		$this->_isConnected = false;
-
-		$host = is_array($cfg['host']) ? join(',', $cfg['host']) : $cfg['host'];
-		$login = $cfg['login'] ? "{$cfg['login']}:{$cfg['password']}@" : '';
-		$connection = "mongodb://{$login}{$host}" . ($login ? "/{$cfg['database']}" : '');
-
-		$options = array(
-			'connect' => true,
-			'timeout' => $cfg['timeout'],
-			'replicaSet' => $cfg['replicaSet']
-		);
-
-		try {
-			if ($persist = $cfg['persistent']) {
-				$options['persist'] = $persist === true ? 'default' : $persist;
-			}
-			$server = $this->_classes['server'];
-			$this->server = new $server($connection, $options);
-
-			if ($this->connection = $this->server->{$cfg['database']}) {
-				$this->_isConnected = true;
-			}
-
-			if ($prefs = $cfg['readPreference']) {
-				$prefs = !is_array($prefs) ? array($prefs, array()) : $prefs;
-				$this->server->setReadPreference($prefs[0], $prefs[1]);
-			}
-		} catch (Exception $e) {
-			throw new NetworkException("Could not connect to the database.", 503, $e);
-		}
-		return $this->_isConnected;
-	}
-
-	/**
-	 * Disconnect from the Mongo server.
-	 *
-	 * Don't call the Mongo->close() method. The driver documentation states this should not
-	 * be necessary since it auto disconnects when out of scope.
-	 * With version 1.2.7, when using replica sets, close() can cause a segmentation fault.
-	 *
-	 * @return boolean True
-	 */
-	public function disconnect() {
-		if ($this->server && $this->server->connected) {
-			$this->_isConnected = false;
-			unset($this->connection, $this->server);
-		}
-		return true;
-	}
-
-	/**
-	 * Returns the list of collections in the currently-connected database.
-	 *
-	 * @param string $class The fully-name-spaced class name of the model object making the request.
-	 * @return array Returns an array of objects to which models can connect.
-	 */
-	public function sources($class = null) {
-		$this->_checkConnection();
-		$conn = $this->connection;
-		return array_map(function($col) { return $col->getName(); }, $conn->listCollections());
-	}
-
-	/**
-	 * Gets the column 'schema' for a given MongoDB collection. Only returns a schema if the
-	 * `'schema'` configuration flag has been set in the constructor.
-	 *
-	 * @see lithium\data\source\MongoDb::$_schema
-	 * @param mixed $collection Specifies a collection name for which the schema should be queried.
-	 * @param mixed $fields Any schema data pre-defined by the model.
-	 * @param array $meta Any meta information pre-defined in the model.
-	 * @return array Returns an associative array describing the given collection's schema.
-	 */
-	public function describe($collection, $fields = array(), array $meta = array()) {
-		if (!$fields && ($func = $this->_schema)) {
-			$fields = $func($this, $collection, $meta);
-		}
-		return $this->_instance('schema', compact('fields'));
-	}
-
-	/**
-	 * Quotes identifiers.
-	 *
-	 * MongoDb does not need identifiers quoted, so this method simply returns the identifier.
-	 *
-	 * @param string $name The identifier to quote.
-	 * @return string The quoted identifier.
-	 */
-	public function name($name) {
-		return $name;
-	}
-
-	/**
-	 * A method dispatcher that allows direct calls to native methods in PHP's `Mongo` object. Read
-	 * more here: http://php.net/manual/class.mongo.php
-	 *
-	 * For example (assuming this instance is stored in `Connections` as `'mongo'`):
-	 * {{{// Manually repairs a MongoDB instance
-	 * Connections::get('mongo')->repairDB($db); // returns null
-	 * }}}
-	 *
-	 * @param string $method The name of native method to call. See the link above for available
-	 *        class methods.
-	 * @param array $params A list of parameters to be passed to the native method.
-	 * @return mixed The return value of the native method specified in `$method`.
-	 */
-	public function __call($method, $params) {
-		if ((!$this->server) && !$this->connect()) {
-			return null;
-		}
-		return call_user_func_array(array(&$this->server, $method), $params);
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public function respondsTo($method, $internal = false) {
-		$childRespondsTo = is_object($this->server) && is_callable(array($this->server, $method));
-		return parent::respondsTo($method, $internal) || $childRespondsTo;
-	}
-
-	/**
-	 * Normally used in cases where the query is a raw string (as opposed to a `Query` object),
-	 * to database must determine the correct column names from the result resource. Not
-	 * applicable to this data source.
-	 *
-	 * @internal param mixed $query
-	 * @internal param \lithium\data\source\resource $resource
-	 * @internal param object $context
-	 * @return array
-	 */
-	public function schema($query, $resource = null, $context = null) {
-		return array();
-	}
-
-	/**
-	 * Create new document
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return boolean
-	 * @filter
-	 */
-	public function create($query, array $options = array()) {
-		$_config = $this->_config;
-		$defaults = array('safe' => $_config['safe'], 'fsync' => false);
-		$options += $defaults;
-		$this->_checkConnection();
-
-		$params = compact('query', 'options');
-		$_exp = $this->_classes['exporter'];
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($_config, $_exp) {
-			$query   = $params['query'];
-			$options = $params['options'];
-
-			$args    = $query->export($self, array('keys' => array('source', 'data')));
-			$data    = $_exp::get('create', $args['data']);
-			$source  = $args['source'];
-
-			if ($source === "{$_config['gridPrefix']}.files" && isset($data['create']['file'])) {
-				$result = array('ok' => true);
-				$data['create']['_id'] = $self->invokeMethod('_saveFile', array($data['create']));
-			} else {
-				$result = $self->connection->{$source}->insert($data['create'], $options);
-			}
-
-			if ($result === true || isset($result['ok']) && (boolean) $result['ok'] === true) {
-				if ($query->entity()) {
-					$query->entity()->sync($data['create']['_id']);
-				}
-				return true;
-			}
-			return false;
-		});
-	}
-
-	protected function _saveFile($data) {
-		$uploadKeys = array('name', 'type', 'tmp_name', 'error', 'size');
-		$grid = $this->connection->getGridFS($this->_config['gridPrefix']);
-		$file = null;
-		$method = null;
-
-		switch (true) {
-			case  (is_array($data['file']) && array_keys($data['file']) == $uploadKeys):
-				if (!$data['file']['error'] && is_uploaded_file($data['file']['tmp_name'])) {
-					$method = 'storeFile';
-					$file = $data['file']['tmp_name'];
-					$data['filename'] = $data['file']['name'];
-				}
-			break;
-			case $data['file']:
-				$method = 'storeBytes';
-				$file = $data['file'];
-			break;
-		}
-
-		if (!$method || !$file) {
-			return;
-		}
-
-		if (isset($data['_id'])) {
-			$data += (array) get_object_vars($grid->get($data['_id']));
-			$grid->delete($data['_id']);
-		}
-		unset($data['file']);
-		return $grid->{$method}($file, $data);
-	}
-
-	/**
-	 * Read from document
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return object
-	 * @filter
-	 */
-	public function read($query, array $options = array()) {
-		$this->_checkConnection();
-		$defaults = array('return' => 'resource');
-		$options += $defaults;
-
-		$params = compact('query', 'options');
-		$_config = $this->_config;
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($_config) {
-			$query = $params['query'];
-			$options = $params['options'];
-			$args = $query->export($self);
-			$source = $args['source'];
-
-			if ($group = $args['group']) {
-				$result = $self->invokeMethod('_group', array($group, $args, $options));
-				$config = array('class' => 'set') + compact('query') + $result;
-				return $self->item($query->model(), $config['data'], $config);
-			}
-			$collection = $self->connection->{$source};
-
-			if ($source === "{$_config['gridPrefix']}.files") {
-				$collection = $self->connection->getGridFS($_config['gridPrefix']);
-			}
-			$result = $collection->find($args['conditions'], $args['fields']);
-
-			if ($query->calculate()) {
-				return $result;
-			}
-
-			$resource = $result->sort($args['order'])->limit($args['limit'])->skip($args['offset']);
-			$result = $self->invokeMethod('_instance', array('result', compact('resource')));
-			$config = compact('result', 'query') + array('class' => 'set');
-			return $self->item($query->model(), array(), $config);
-		});
-	}
-
-	protected function _group($group, $args, $options) {
-		$conditions = $args['conditions'];
-		$group += array('$reduce' => $args['reduce'], 'initial' => $args['initial']);
-		$command = array('group' => $group + array('ns' => $args['source'], 'cond' => $conditions));
-
-		$stats = $this->connection->command($command);
-		$data = isset($stats['retval']) ? $stats['retval'] : null;
-		unset($stats['retval']);
-		return compact('data', 'stats');
-	}
-
-	/**
-	 * Update document
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return boolean
-	 * @filter
-	 */
-	public function update($query, array $options = array()) {
-		$_config = $this->_config;
-		$defaults = array(
-			'upsert' => false,
-			'multiple' => true,
-			'safe' => $_config['safe'],
-			'fsync' => false
-		);
-		$options += $defaults;
-		$this->_checkConnection();
-
-		$params = compact('query', 'options');
-		$_exp = $this->_classes['exporter'];
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($_config, $_exp) {
-			$options = $params['options'];
-			$query  = $params['query'];
-			$args   = $query->export($self, array('keys' => array('conditions', 'source', 'data')));
-			$source = $args['source'];
-			$data   = $args['data'];
-
-			if ($query->entity()) {
-				$data = $_exp::get('update', $data);
-			}
-
-			if ($source === "{$_config['gridPrefix']}.files" && isset($data['update']['file'])) {
-				$args['data']['_id'] = $self->invokeMethod('_saveFile', array($data['update']));
-			}
-			$update = $query->entity() ? $_exp::toCommand($data) : $data;
-
-			if ($options['multiple'] && !preg_grep('/^\$/', array_keys($update))) {
-				$update = array('$set' => $update);
-			}
-			if ($self->connection->{$source}->update($args['conditions'], $update, $options)) {
-				$query->entity() ? $query->entity()->sync() : null;
-				return true;
-			}
-			return false;
-		});
-	}
-
-	/**
-	 * Delete document
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return boolean
-	 * @filter
-	 */
-	public function delete($query, array $options = array()) {
-		$this->_checkConnection();
-		$_config = $this->_config;
-		$defaults = array('justOne' => false, 'safe' => $_config['safe'], 'fsync' => false);
-		$options = array_intersect_key($options + $defaults, $defaults);
-		$params = compact('query', 'options');
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($_config) {
-			$query = $params['query'];
-			$options = $params['options'];
-			$args = $query->export($self, array('keys' => array('source', 'conditions')));
-			$source = $args['source'];
-			$conditions = $args['conditions'];
-
-			if ($source === "{$_config['gridPrefix']}.files") {
-				$result = $self->invokeMethod('_deleteFile', array($conditions));
-			} else {
-				$result = $self->connection->{$args['source']}->remove($conditions, $options);
-			}
-			if ($result && $query->entity()) {
-				$query->entity()->sync(null, array(), array('dematerialize' => true));
-			}
-			return $result;
-		});
-	}
-
-	protected function _deleteFile($conditions, $options = array()) {
-		$defaults = array('safe' => true);
-		$options += $defaults;
-		return $this->connection
-			->getGridFS($this->_config['gridPrefix'])
-			->remove($conditions, $options);
-	}
-
-	/**
-	 * Executes calculation-related queries, such as those required for `count`.
-	 *
-	 * @param string $type Only accepts `count`.
-	 * @param mixed $query The query to be executed.
-	 * @param array $options Optional arguments for the `read()` query that will be executed
-	 *        to obtain the calculation result.
-	 * @return integer Result of the calculation.
-	 */
-	public function calculation($type, $query, array $options = array()) {
-		$query->calculate($type);
-
-		switch ($type) {
-			case 'count':
-				return $this->read($query, $options)->count();
-		}
-	}
-
-	/**
-	 * Document relationships.
-	 *
-	 * @param string $class
-	 * @param string $type Relationship type, e.g. `belongsTo`.
-	 * @param string $name
-	 * @param array $config
-	 * @return array
-	 */
-	public function relationship($class, $type, $name, array $config = array()) {
-		$key = Inflector::camelize($type === 'belongsTo' ? $class::meta('name') : $name, false);
-
-		$config += compact('name', 'type', 'key');
-		$config['from'] = $class;
-		$relationship = $this->_classes['relationship'];
-
-		$defaultLinks = array(
-			'hasOne' => $relationship::LINK_EMBEDDED,
-			'hasMany' => $relationship::LINK_EMBEDDED,
-			'belongsTo' => $relationship::LINK_CONTAINED
-		);
-		$config += array('link' => $defaultLinks[$type]);
-		return new $relationship($config);
-	}
-
-	/**
-	 * Formats `group` clauses for MongoDB.
-	 *
-	 * @param string|array $group The group clause.
-	 * @param object $context
-	 * @return array Formatted `group` clause.
-	 */
-	public function group($group, $context) {
-		if (!$group) {
-			return;
-		}
-		if (is_string($group) && strpos($group, 'function') === 0) {
-			return array('$keyf' => new MongoCode($group));
-		}
-		$group = (array) $group;
-
-		foreach ($group as $i => $field) {
-			if (is_int($i)) {
-				$group[$field] = true;
-				unset($group[$i]);
-			}
-		}
-		return array('key' => $group);
-	}
-
-	/**
-	 * Maps incoming conditions with their corresponding MongoDB-native operators.
-	 *
-	 * @param array $conditions Array of conditions
-	 * @param object $context Context with which this method was called; currently
-	 *        inspects the return value of `$context->type()`.
-	 * @return array Transformed conditions
-	 */
-	public function conditions($conditions, $context) {
-		if (!$conditions) {
-			return array();
-		}
-		if ($code = $this->_isMongoCode($conditions)) {
-			return $code;
-		}
-		$schema = null;
-		$model = null;
-
-		if ($context) {
-			$schema = $context->schema();
-			$model = $context->model();
-		}
-		return $this->_conditions($conditions, $model, $schema, $context);
-	}
-
-	/**
-	 * Protected helper method used to format conditions.
-	 *
-	 * @param array $conditions The conditions array to be processed.
-	 * @param string $model The name of the model class used in the query.
-	 * @param object $schema The object containing the schema definition.
-	 * @param object $context The `Query` object.
-	 * @return array Processed query conditions.
-	 */
-	protected function _conditions(array $conditions, $model, $schema, $context) {
-		$ops = $this->_operators;
-		$castOpts = array('first' => true, 'database' => $this, 'wrap' => false);
-
-		$cast = function($key, $value) use (&$schema, &$castOpts) {
-			return $schema ? $schema->cast(null, $key, $value, $castOpts) : $value;
-		};
-
-		foreach ($conditions as $key => $value) {
-			if (in_array($key, $this->_boolean)) {
-				$operator = isset($ops[$key]) ? $ops[$key] : $key;
-
-				foreach ($value as $i => $compare) {
-					$value[$i] = $this->_conditions($compare, $model, $schema, $context);
-				}
-				unset($conditions[$key]);
-				$conditions[$operator] = $value;
-				continue;
-			}
-			/**
-			 * @todo Catch Document/Array objects used in conditions and extract their values.
-			 */
-			if (is_object($value)) {
-				continue;
-			}
-			if (!is_array($value)) {
-				$conditions[$key] = $cast($key, $value);
-				continue;
-			}
-			$current = key($value);
-
-			if (!isset($ops[$current]) && $current[0] !== '$') {
-				$conditions[$key] = array('$in' => $cast($key, $value));
-				continue;
-			}
-			$conditions[$key] = $this->_operators($key, $value, $schema);
-		}
-		return $conditions;
-	}
-
-	protected function _isMongoCode($conditions) {
-		if (is_string($conditions)) {
-			$conditions = new MongoCode($conditions);
-		}
-		if ($conditions instanceof MongoCode) {
-			return array('$where' => $conditions);
-		}
-	}
-
-	protected function _operators($field, $operators, $schema) {
-		$castOpts = compact('schema');
-		$castOpts += array('first' => true, 'database' => $this, 'wrap' => false);
-
-		$cast = function($key, $value) use (&$schema, &$castOpts) {
-			return $schema ? $schema->cast(null, $key, $value, $castOpts) : $value;
-		};
-
-		foreach ($operators as $key => $value) {
-			if (!isset($this->_operators[$key])) {
-				$operators[$key] = $cast($field, $value);
-				continue;
-			}
-			$operator = $this->_operators[$key];
-
-			if (is_array($operator)) {
-				$operator = $operator[is_array($value) ? 'multiple' : 'single'];
-			}
-			if (is_callable($operator)) {
-				return $operator($key, $value, $schema);
-			}
-			unset($operators[$key]);
-			$operators[$operator] = $cast($field, $value);
-		}
-		return $operators;
-	}
-
-	/**
-	 * Return formatted identifiers for fields.
-	 *
-	 * MongoDB does nt require field identifer escaping; as a result, this method is not
-	 * implemented.
-	 *
-	 * @param array $fields Fields to be parsed
-	 * @param object $context
-	 * @return array Parsed fields array
-	 */
-	public function fields($fields, $context) {
-		return $fields ?: array();
-	}
-
-	/**
-	 * Return formatted clause for limit.
-	 *
-	 * MongoDB doesn't require limit identifer formatting; as a result, this method is not
-	 * implemented.
-	 *
-	 * @param mixed $limit The `limit` clause to be formatted.
-	 * @param object $context The `Query` object instance.
-	 * @return mixed Formatted `limit` clause.
-	 */
-	public function limit($limit, $context) {
-		return $limit ?: 0;
-	}
-
-	/**
-	 * Return formatted clause for order.
-	 *
-	 * @param mixed $order The `order` clause to be formatted
-	 * @param object $context
-	 * @return mixed Formatted `order` clause.
-	 */
-	public function order($order, $context) {
-		if (!$order) {
-			return array();
-		}
-		if (is_string($order)) {
-			return array($order => 1);
-		}
-		if (!is_array($order)) {
-			return array();
-		}
-		foreach ($order as $key => $value) {
-			if (!is_string($key)) {
-				unset($order[$key]);
-				$order[$value] = 1;
-				continue;
-			}
-			if (is_string($value)) {
-				$order[$key] = strtolower($value) === 'asc' ? 1 : -1;
-			}
-		}
-		return $order;
-	}
-
-	protected function _checkConnection() {
-		if (!$this->_isConnected && !$this->connect()) {
-			throw new NetworkException("Could not connect to the database.");
-		}
-	}
-}
-
-?>

+ 0 - 196
frameworks/PHP/php-lithium/libraries/lithium/data/source/Result.php

@@ -1,196 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source;
-
-abstract class Result extends \lithium\core\Object implements \Iterator {
-
-	/**
-	 * Contains the cached result set.
-	 */
-	protected $_cache = null;
-
-	/**
-	 * The current position of the iterator.
-	 */
-	protected $_iterator = 0;
-
-	/**
-	 * Contains the current element of the result set.
-	 */
-	protected $_current = false;
-
-	/**
-	 * Setted to `true` when the collection has begun iterating.
-	 * @var integer
-	 */
-	protected $_started = false;
-
-	/**
-	 * If the result resource has been initialized
-	 */
-	protected $_init = false;
-
-	/**
-	 * Indicates whether the current position is valid or not.
-	 *
-	 * @var boolean
-	 * @see lithium\data\source\Result::valid()
-	 */
-	protected $_valid = false;
-
-	/**
-	 * If the result resource has been initialized
-	 */
-	protected $_key = null;
-
-	/**
-	 * The bound resource.
-	 */
-	protected $_resource = null;
-
-	/**
-	 * Autoconfig.
-	 */
-	protected $_autoConfig = array('resource');
-
-	/**
-	 * Returns the used resource.
-	 */
-	public function resource() {
-		return $this->_resource;
-	}
-
-	/**
-	 * Checks if current position is valid.
-	 *
-	 * @return boolean `true` if valid, `false` otherwise.
-	 */
-	public function valid() {
-		if (!$this->_init) {
-			$this->_valid = $this->_fetch();
-		}
-		return $this->_valid;
-	}
-
-	/**
-	 * Rewinds the result set to the first position.
-	 */
-	public function rewind() {
-		$this->_iterator = 0;
-		$this->_started = false;
-		$this->_key = null;
-		$this->_current = false;
-		$this->_init = false;
-	}
-
-	/**
-	 * Contains the current result.
-	 *
-	 * @return array The current result (or `null` if there is none).
-	 */
-	public function current() {
-		if (!$this->_init) {
-			$this->_fetch();
-		}
-		$this->_started = true;
-		return $this->_current;
-	}
-
-	/**
-	 * Returns the current key position on the result.
-	 *
-	 * @return integer The current iterator position.
-	 */
-	public function key() {
-		if (!$this->_init) {
-			$this->_fetch();
-		}
-		$this->_started = true;
-		return $this->_key;
-	}
-
-	/**
-	 * Fetches the previous element from the cache.
-	 *
-	 * @return mixed The previous result (or `false` if there is none).
-	 */
-	public function prev() {
-		if (!$this->_cache) {
-			return;
-		}
-		if (isset($this->_cache[--$this->_iterator - 1])) {
-			$this->_key = $this->_iterator - 1;
-			return $this->_current = $this->_cache[$this->_iterator - 1];
-		}
-		return false;
-	}
-
-	/**
-	 * Fetches the next element from the resource.
-	 *
-	 * @return mixed The next result (or `false` if there is none).
-	 */
-	public function next() {
-		if ($this->_started === false) {
-			return $this->current();
-		}
-		$this->_valid = $this->_fetch();
-		if (!$this->_valid) {
-			$this->_key = null;
-			$this->_current = false;
-		}
-		return $this->current();
-	}
-
-	/**
-	 * Fetches the current element from the resource.
-	 *
-	 * @return boolean Return `true` on success or `false` otherwise.
-	 */
-	protected function _fetch() {
-		$this->_init = true;
-		if ($this->_fetchFromCache() || $this->_fetchFromResource()) {
-			return true;
-		}
-		return false;
-	}
-
-	abstract protected function _fetchFromResource();
-
-	/**
-	 * Returns the result from the primed cache.
-	 *
-	 * @return boolean Return `true` on success or `false` if it has not been cached yet.
-	 */
-	protected function _fetchFromCache() {
-		if ($this->_iterator < count($this->_cache)) {
-			$this->_key = $this->_iterator;
-			$this->_current = $this->_cache[$this->_iterator++];
-			return true;
-		}
-		return false;
-	}
-
-	/**
-	 * Close the resource.
-	 */
-	public function close() {
-		unset($this->_resource);
-		$this->_resource = null;
-	}
-
-	/**
-	 * The destructor.
-	 */
-	public function __destruct() {
-		$this->close();
-	}
-}
-
-?>

+ 0 - 363
frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/MySql.php

@@ -1,363 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source\database\adapter;
-
-use PDO;
-use PDOException;
-
-/**
- * Extends the `Database` class to implement the necessary SQL-formatting and resultset-fetching
- * features for working with MySQL databases.
- *
- * For more information on configuring the database connection, see the `__construct()` method.
- *
- * @see lithium\data\source\database\adapter\MySql::__construct()
- */
-class MySql extends \lithium\data\source\Database {
-
-	/**
-	 * MySQL column type definitions.
-	 *
-	 * @var array
-	 */
-	protected $_columns = array(
-		'primary_key' => array('name' => 'NOT NULL AUTO_INCREMENT'),
-		'string' => array('name' => 'varchar', 'length' => 255),
-		'text' => array('name' => 'text'),
-		'integer' => array('name' => 'int', 'length' => 11, 'formatter' => 'intval'),
-		'float' => array('name' => 'float', 'formatter' => 'floatval'),
-		'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
-		'timestamp' => array(
-			'name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'
-		),
-		'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
-		'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
-		'binary' => array('name' => 'blob'),
-		'boolean' => array('name' => 'tinyint', 'length' => 1)
-	);
-
-	/**
-	 * Pair of opening and closing quote characters used for quoting identifiers in queries.
-	 *
-	 * @var array
-	 */
-	protected $_quotes = array('`', '`');
-
-	/**
-	 * MySQL-specific value denoting whether or not table aliases should be used in DELETE and
-	 * UPDATE queries.
-	 *
-	 * @var boolean
-	 */
-	protected $_useAlias = true;
-
-	/**
-	 * Constructs the MySQL adapter and sets the default port to 3306.
-	 *
-	 * @see lithium\data\source\Database::__construct()
-	 * @see lithium\data\Source::__construct()
-	 * @see lithium\data\Connections::add()
-	 * @param array $config Configuration options for this class. For additional configuration,
-	 *        see `lithium\data\source\Database` and `lithium\data\Source`. Available options
-	 *        defined by this class:
-	 *        - `'database'`: The name of the database to connect to. Defaults to 'lithium'.
-	 *        - `'host'`: The IP or machine name where MySQL is running, followed by a colon,
-	 *          followed by a port number or socket. Defaults to `'localhost:3306'`.
-	 *        - `'persistent'`: If a persistent connection (if available) should be made.
-	 *          Defaults to true.
-	 *
-	 * Typically, these parameters are set in `Connections::add()`, when adding the adapter to the
-	 * list of active connections.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('host' => 'localhost:3306', 'encoding' => null);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Check for required PHP extension, or supported database feature.
-	 *
-	 * @param string $feature Test for support for a specific feature, i.e. `"transactions"` or
-	 *        `"arrays"`.
-	 * @return boolean Returns `true` if the particular feature (or if MySQL) support is enabled,
-	 *         otherwise `false`.
-	 */
-	public static function enabled($feature = null) {
-		if (!$feature) {
-			return extension_loaded('pdo_mysql');
-		}
-		$features = array(
-			'arrays' => false,
-			'transactions' => false,
-			'booleans' => true,
-			'relationships' => true
-		);
-		return isset($features[$feature]) ? $features[$feature] : null;
-	}
-
-	/**
-	 * Connects to the database using the options provided to the class constructor.
-	 *
-	 * @return boolean Returns `true` if a database connection could be established, otherwise
-	 *         `false`.
-	 */
-	public function connect() {
-		if (!$this->_config['dsn']) {
-			$host = $this->_config['host'];
-			list($host, $port) = explode(':', $host) + array(1 => "3306");
-			$dsn = "mysql:host=%s;port=%s;dbname=%s";
-			$this->_config['dsn'] = sprintf($dsn, $host, $port, $this->_config['database']);
-		}
-
-		if (!parent::connect()) {
-			return false;
-		}
-
-		$info = $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION);
-		$this->_useAlias = (boolean) version_compare($info, "4.1", ">=");
-		return true;
-	}
-
-	/**
-	 * Returns the list of tables in the currently-connected database.
-	 *
-	 * @param string $model The fully-name-spaced class name of the model object making the request.
-	 * @return array Returns an array of sources to which models can connect.
-	 * @filter This method can be filtered.
-	 */
-	public function sources($model = null) {
-		$_config = $this->_config;
-		$params = compact('model');
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($_config) {
-			$name = $self->name($_config['database']);
-
-			if (!$result = $self->invokeMethod('_execute', array("SHOW TABLES FROM {$name};"))) {
-				return null;
-			}
-			$sources = array();
-
-			while ($data = $result->next()) {
-				$sources[] = array_shift($data);
-			}
-			return $sources;
-		});
-	}
-
-	/**
-	 * Gets the column schema for a given MySQL table.
-	 *
-	 * @param mixed $entity Specifies the table name for which the schema should be returned, or
-	 *        the class name of the model object requesting the schema, in which case the model
-	 *        class will be queried for the correct table name.
-	 * @param array $fields Any schema data pre-defined by the model.
-	 * @param array $meta
-	 * @return array Returns an associative array describing the given table's schema, where the
-	 *         array keys are the available fields, and the values are arrays describing each
-	 *         field, containing the following keys:
-	 *         - `'type'`: The field type name
-	 * @filter This method can be filtered.
-	 */
-	public function describe($entity,  $fields = array(), array $meta = array()) {
-		$params = compact('entity', 'meta', 'fields');
-		return $this->_filter(__METHOD__, $params, function($self, $params) {
-			extract($params);
-
-			if ($fields) {
-				return $self->invokeMethod('_instance', array('schema', compact('fields')));
-			}
-			$name = $self->invokeMethod('_entityName', array($entity, array('quoted' => true)));
-			$columns = $self->read("DESCRIBE {$name}", array('return' => 'array', 'schema' => array(
-				'field', 'type', 'null', 'key', 'default', 'extra'
-			)));
-			$fields = array();
-
-			foreach ($columns as $column) {
-				$match = $self->invokeMethod('_column', array($column['type']));
-
-				$fields[$column['field']] = $match + array(
-					'null'     => ($column['null'] === 'YES' ? true : false),
-					'default'  => $column['default']
-				);
-			}
-			return $self->invokeMethod('_instance', array('schema', compact('fields')));
-		});
-	}
-
-	/**
-	 * Gets or sets the encoding for the connection.
-	 *
-	 * @param $encoding
-	 * @return mixed If setting the encoding; returns true on success, else false.
-	 *         When getting, returns the encoding.
-	 */
-	public function encoding($encoding = null) {
-		$encodingMap = array('UTF-8' => 'utf8');
-
-		if (empty($encoding)) {
-			$query = $this->connection->query("SHOW VARIABLES LIKE 'character_set_client'");
-			$encoding = $query->fetchColumn(1);
-			return ($key = array_search($encoding, $encodingMap)) ? $key : $encoding;
-		}
-		$encoding = isset($encodingMap[$encoding]) ? $encodingMap[$encoding] : $encoding;
-
-		try {
-			$this->connection->exec("SET NAMES '{$encoding}'");
-			return true;
-		} catch (PDOException $e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Converts a given value into the proper type based on a given schema definition.
-	 *
-	 * @see lithium\data\source\Database::schema()
-	 * @param mixed $value The value to be converted. Arrays will be recursively converted.
-	 * @param array $schema Formatted array from `lithium\data\source\Database::schema()`
-	 * @return mixed Value with converted type.
-	 */
-	public function value($value, array $schema = array()) {
-		if (($result = parent::value($value, $schema)) !== null) {
-			return $result;
-		}
-		return $this->connection->quote((string) $value);
-	}
-
-	/**
-	 * Retrieves database error message and error code.
-	 *
-	 * @return array
-	 */
-	public function error() {
-		if ($error = $this->connection->errorInfo()) {
-			return array($error[1], $error[2]);
-		}
-	}
-
-	public function alias($alias, $context) {
-		if ($context->type() === 'update' || $context->type() === 'delete') {
-			return;
-		}
-		return parent::alias($alias, $context);
-	}
-
-	/**
-	 * @todo Eventually, this will need to rewrite aliases for DELETE and UPDATE queries, same with
-	 *       order().
-	 * @param string $conditions
-	 * @param string $context
-	 * @param array $options
-	 * @return void
-	 */
-	public function conditions($conditions, $context, array $options = array()) {
-		return parent::conditions($conditions, $context, $options);
-	}
-
-	/**
-	 * Execute a given query.
-	 *
-	 * @see lithium\data\source\Database::renderCommand()
-	 * @param string $sql The sql string to execute
-	 * @param array $options Available options:
-	 *        - 'buffered': If set to `false` uses mysql_unbuffered_query which
-	 *          sends the SQL query query to MySQL without automatically fetching and buffering the
-	 *          result rows as `mysql_query()` does (for less memory usage).
-	 * @return resource Returns the result resource handle if the query is successful.
-	 * @filter
-	 */
-	protected function _execute($sql, array $options = array()) {
-		$defaults = array('buffered' => true);
-		$options += $defaults;
-		$this->connection->exec("USE  `{$this->_config['database']}`");
-
-		$conn = $this->connection;
-
-		$params = compact('sql', 'options');
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($conn) {
-			$sql = $params['sql'];
-			$options = $params['options'];
-			$conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $options['buffered']);
-
-			try {
-				$resource = $conn->query($sql);
-			} catch(PDOException $e) {
-				$self->invokeMethod('_error', array($sql));
-			};
-			return $self->invokeMethod('_instance', array('result', compact('resource')));
-		});
-	}
-
-	/**
-	 * Gets the last auto-generated ID from the query that inserted a new record.
-	 *
-	 * @param object $query The `Query` object associated with the query which generated
-	 * @return mixed Returns the last inserted ID key for an auto-increment column or a column
-	 *         bound to a sequence.
-	 */
-	protected function _insertId($query) {
-		$resource = $this->_execute('SELECT LAST_INSERT_ID() AS insertID');
-		list($id) = $resource->next();
-		return ($id && $id !== '0') ? $id : null;
-	}
-
-	/**
-	 * Converts database-layer column types to basic types.
-	 *
-	 * @param string $real Real database-layer column type (i.e. `"varchar(255)"`)
-	 * @return array Column type (i.e. "string") plus 'length' when appropriate.
-	 */
-	protected function _column($real) {
-		if (is_array($real)) {
-			return $real['type'] . (isset($real['length']) ? "({$real['length']})" : '');
-		}
-
-		if (!preg_match('/(?P<type>\w+)(?:\((?P<length>[\d,]+)\))?/', $real, $column)) {
-			return $real;
-		}
-		$column = array_intersect_key($column, array('type' => null, 'length' => null));
-
-		if (isset($column['length']) && $column['length']) {
-			$length = explode(',', $column['length']) + array(null, null);
-			$column['length'] = $length[0] ? intval($length[0]) : null;
-			$length[1] ? $column['precision'] = intval($length[1]) : null;
-		}
-
-		switch (true) {
-			case in_array($column['type'], array('date', 'time', 'datetime', 'timestamp')):
-				return $column;
-			case ($column['type'] === 'tinyint' && $column['length'] == '1'):
-			case ($column['type'] === 'boolean'):
-				return array('type' => 'boolean');
-			break;
-			case (strpos($column['type'], 'int') !== false):
-				$column['type'] = 'integer';
-			break;
-			case (strpos($column['type'], 'char') !== false || $column['type'] === 'tinytext'):
-				$column['type'] = 'string';
-			break;
-			case (strpos($column['type'], 'text') !== false):
-				$column['type'] = 'text';
-			break;
-			case (strpos($column['type'], 'blob') !== false || $column['type'] === 'binary'):
-				$column['type'] = 'binary';
-			break;
-			case preg_match('/float|double|decimal/', $column['type']):
-				$column['type'] = 'float';
-			break;
-			default:
-				$column['type'] = 'text';
-			break;
-		}
-		return $column;
-	}
-}
-
-?>

+ 0 - 439
frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/PostgreSql.php

@@ -1,439 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright	  Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license		  http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source\database\adapter;
-
-use PDO;
-use PDOException;
-
-/**
- * Extends the `Database` class to implement the necessary SQL-formatting and resultset-fetching
- * features for working with PostgreSQL databases.
- *
- * For more information on configuring the database connection, see the `__construct()` method.
- *
- * @see lithium\data\source\database\adapter\PostgreSql::__construct()
- */
-class PostgreSql extends \lithium\data\source\Database {
-
-	/**
-	 * PostgreSQL column type definitions.
-	 *
-	 * @var array
-	 */
-	protected $_columns = array(
-		'primary_key' => array('name' => 'SERIAL not null'),
-		'string' => array('name' => 'varchar', 'length' => 255),
-		'text' => array('name' => 'text'),
-		'integer' => array('name' => 'integer', 'formatter' => 'intval'),
-		'float' => array('name' => 'float', 'formatter' => 'floatval'),
-		'datetime' => array(
-			'name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'
-		),
-		'timestamp' => array(
-			'name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'
-		),
-		'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
-		'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
-		'binary' => array('name' => 'bytea'),
-		'boolean' => array('name' => 'boolean'),
-		'number' => array('name' => 'numeric'),
-		'inet' => array('name' => 'inet')
-	);
-
-	/**
-	 * Pair of opening and closing quote characters used for quoting identifiers in queries.
-	 *
-	 * @var array
-	 */
-	protected $_quotes = array('"', '"');
-
-	/**
-	 * PostgreSQL-specific value denoting whether or not table aliases should be used in DELETE and
-	 * UPDATE queries.
-	 *
-	 * @var boolean
-	 */
-	protected $_useAlias = true;
-
-	/**
-	 * Constructs the PostgreSQL adapter and sets the default port to 5432.
-	 *
-	 * @see lithium\data\source\Database::__construct()
-	 * @see lithium\data\Source::__construct()
-	 * @see lithium\data\Connections::add()
-	 * @param array $config Configuration options for this class. For additional configuration,
-	 *        see `lithium\data\source\Database` and `lithium\data\Source`. Available options
-	 *        defined by this class:
-	 *        - `'database'`: The name of the database to connect to. Defaults to 'lithium'.
-	 *        - `'host'`: The IP or machine name where PostgreSQL is running, followed by a colon,
-	 *        followed by a port number or socket. Defaults to `'localhost:5432'`.
-	 *        - `'persistent'`: If a persistent connection (if available) should be made.
-	 *        Defaults to true.
-	 *        - `'schema'`: The name of the database schema to use. Defaults to 'public'
-	 *
-	 * Typically, these parameters are set in `Connections::add()`, when adding the adapter to the
-	 * list of active connections.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array(
-			'host' => 'localhost:5432',
-			'encoding' => null,
-			'schema' => 'public',
-			'timezone' => null
-		);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Check for required PHP extension, or supported database feature.
-	 *
-	 * @param string $feature Test for support for a specific feature, i.e. `"transactions"` or
-	 *        `"arrays"`.
-	 * @return boolean Returns `true` if the particular feature (or if PostgreSQL) support is
-	 *         enabled, otherwise `false`.
-	 */
-	public static function enabled($feature = null) {
-		if (!$feature) {
-			return extension_loaded('pdo_pgsql');
-		}
-		$features = array(
-			'arrays' => false,
-			'transactions' => true,
-			'booleans' => true,
-			'relationships' => true
-		);
-		return isset($features[$feature]) ? $features[$feature] : null;
-	}
-
-	/**
-	 * Connects to the database using the options provided to the class constructor.
-	 *
-	 * @return boolean Returns `true` if a database connection could be established, otherwise
-	 *         `false`.
-	 */
-	public function connect() {
-		if (!$this->_config['dsn']) {
-			$host = $this->_config['host'];
-			list($host, $port) = explode(':', $host) + array(1 => "5432");
-			$dsn = "pgsql:host=%s;port=%s;dbname=%s";
-			$this->_config['dsn'] = sprintf($dsn, $host, $port, $this->_config['database']);
-		}
-
-		if (!parent::connect()) {
-			return false;
-		}
-
-		if ($this->_config['schema']) {
-			$this->search_path($this->_config['schema']);
-		}
-
-		if ($this->_config['timezone']) {
-			$this->timezone($this->_config['timezone']);
-		}
-		return true;
-	}
-
-	/**
-	 * Returns the list of tables in the currently-connected database.
-	 *
-	 * @param string $model The fully-name-spaced class name of the model object making the request.
-	 * @return array Returns an array of sources to which models can connect.
-	 * @filter This method can be filtered.
-	 */
-	public function sources($model = null) {
-		$_config = $this->_config;
-		$params = compact('model');
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($_config) {
-			$schema = $self->connection->quote($_config['schema']);
-
-			$sql = "SELECT table_name as name FROM INFORMATION_SCHEMA.tables";
-			$sql .= " WHERE table_schema = {$schema}";
-
-			if (!$result = $self->invokeMethod('_execute', array($sql))) {
-				return null;
-			}
-			$sources = array();
-
-			while ($data = $result->next()) {
-				$sources[] = array_shift($data);
-			}
-			return $sources;
-		});
-	}
-
-	/**
-	 * Gets the column schema for a given PostgreSQL table.
-	 *
-	 * @param mixed $entity Specifies the table name for which the schema should be returned, or
-	 *        the class name of the model object requesting the schema, in which case the model
-	 *        class will be queried for the correct table name.
-	 * @param array $fields Any schema data pre-defined by the model.
-	 * @param array $meta
-	 * @return array Returns an associative array describing the given table's schema, where the
-	 *         array keys are the available fields, and the values are arrays describing each
-	 *         field, containing the following keys:
-	 *         - `'type'`: The field type name
-	 * @filter This method can be filtered.
-	 */
-	public function describe($entity, $fields = array(), array $meta = array()) {
-		$schema = $this->_config['schema'];
-		$params = compact('entity', 'meta', 'fields', 'schema');
-		return $this->_filter(__METHOD__, $params, function($self, $params) {
-			extract($params);
-
-			if ($fields) {
-				return $self->invokeMethod('_instance', array('schema', compact('fields')));
-			}
-			$name = $self->connection->quote($self->invokeMethod('_entityName', array($entity)));
-			$schema = $self->connection->quote($schema);
-
-			$sql = "SELECT DISTINCT table_schema AS schema, column_name AS field, data_type AS type,
-					is_nullable AS null, column_default AS default, ordinal_position AS position,
-					character_maximum_length AS char_length, character_octet_length AS oct_length
-					FROM information_schema.columns
-					WHERE table_name = {$name} AND table_schema = {$schema} ORDER BY position";
-
-			$columns = $self->connection->query($sql)->fetchAll(PDO::FETCH_ASSOC);
-
-			$fields = array();
-
-			foreach ($columns as $column) {
-				$match = $self->invokeMethod('_column', array($column['type']));
-
-				if (preg_match('/nextval\([\'"]?([\w.]+)/', $column['default'])) {
-					$default = null;
-				} else {
-					$default = $column['default'];
-				}
-				$fields[$column['field']] = $match + array(
-					'null'	   => ($column['null'] == 'YES' ? true : false),
-					'default'  => $default
-				);
-				if ($fields[$column['field']]['type'] == 'string') {
-					$fields[$column['field']]['length'] = $column['char_length'];
-				}
-			}
-			return $self->invokeMethod('_instance', array('schema', compact('fields')));
-		});
-	}
-
-	/**
-	 * Gets or sets the search path for the connection
-	 * @param $search_path
-	 * @return mixed If setting the search_path; returns ture on success, else false
-	 *         When getting, returns the search_path
-	 */
-	public function search_path($search_path) {
-		if (empty($search_path)) {
-			$query = $this->connection->query('SHOW search_path');
-			$search_path = $query->fetchColumn(1);
-			return explode(",", $search_path);
-		}
-		try{
-			$this->connection->exec("SET search_path TO ${search_path}");
-			return true;
-		} catch (PDOException $e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Gets or sets the time zone for the connection
-	 * @param $timezone
-	 * @return mixed If setting the time zone; returns true on success, else false
-	 *         When getting, returns the time zone
-	 */
-	public function timezone($timezone = null) {
-		if (empty($timezone)) {
-			$query = $this->connection->query('SHOW TIME ZONE');
-			return $query->fetchColumn();
-		}
-		try {
-			$this->connection->exec("SET TIME ZONE '{$timezone}'");
-			return true;
-		} catch (PDOException $e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Gets or sets the encoding for the connection.
-	 *
-	 * @param $encoding
-	 * @return mixed If setting the encoding; returns true on success, else false.
-	 *         When getting, returns the encoding.
-	 */
-	public function encoding($encoding = null) {
-		$encodingMap = array('UTF-8' => 'UTF8');
-
-		if (empty($encoding)) {
-			$query = $this->connection->query("SHOW client_encoding");
-			$encoding = $query->fetchColumn();
-			return ($key = array_search($encoding, $encodingMap)) ? $key : $encoding;
-		}
-		$encoding = isset($encodingMap[$encoding]) ? $encodingMap[$encoding] : $encoding;
-		try {
-			$this->connection->exec("SET NAMES '{$encoding}'");
-			return true;
-		} catch (PDOException $e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Converts a given value into the proper type based on a given schema definition.
-	 *
-	 * @see lithium\data\source\Database::schema()
-	 * @param mixed $value The value to be converted. Arrays will be recursively converted.
-	 * @param array $schema Formatted array from `lithium\data\source\Database::schema()`
-	 * @return mixed Value with converted type.
-	 */
-	public function value($value, array $schema = array()) {
-		if (($result = parent::value($value, $schema)) !== null) {
-			return $result;
-		}
-		return $this->connection->quote((string) $value);
-	}
-
-	/**
-	 * Retrieves database error message and error code.
-	 *
-	 * @return array
-	 */
-	public function error() {
-		if ($error = $this->connection->errorInfo()) {
-			return array($error[1], $error[2]);
-		}
-		return null;
-	}
-
-	public function alias($alias, $context) {
-		if ($context->type() == 'update' || $context->type() == 'delete') {
-			return;
-		}
-		return parent::alias($alias, $context);
-	}
-
-	/**
-	 * @todo Eventually, this will need to rewrite aliases for DELETE and UPDATE queries, same with
-	 *       order().
-	 * @param string $conditions
-	 * @param string $context
-	 * @param array $options
-	 * @return void
-	 */
-	public function conditions($conditions, $context, array $options = array()) {
-		return parent::conditions($conditions, $context, $options);
-	}
-
-	/**
-	 * Execute a given query.
-	 *
-	 * @see lithium\data\source\Database::renderCommand()
-	 * @param string $sql The sql string to execute
-	 * @param array $options Available options:
-	 * @return resource Returns the result resource handle if the query is successful.
-	 * @filter
-	 */
-	protected function _execute($sql, array $options = array()) {
-		$conn = $this->connection;
-
-		$params = compact('sql', 'options');
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($conn) {
-			$sql = $params['sql'];
-			$options = $params['options'];
-
-			try {
-				$resource = $conn->query($sql);
-			} catch(PDOException $e) {
-				$self->invokeMethod('_error', array($sql));
-			};
-
-			return $self->invokeMethod('_instance', array('result', compact('resource')));
-		});
-	}
-
-	/**
-	 * Gets the last auto-generated ID from the query that inserted a new record.
-	 *
-	 * @param object $query The `Query` object associated with the query which generated
-	 * @return mixed Returns the last inserted ID key for an auto-increment column or a column
-	 *         bound to a sequence.
-	 */
-	protected function _insertId($query) {
-		$model = $query->model();
-		$field = $model::key();
-		$source = $model::meta('source');
-		$sequence = "{$source}_{$field}_seq";
-		$id = $this->connection->lastInsertId($sequence);
-		return ($id && $id !== '0') ? $id : null;
-	}
-
-	/**
-	 * Converts database-layer column types to basic types.
-	 *
-	 * @param string $real Real database-layer column type (i.e. `"varchar(255)"`)
-	 * @return array Column type (i.e. "string") plus 'length' when appropriate.
-	 */
-	protected function _column($real) {
-		if (is_array($real)) {
-			return $real['type'] . (isset($real['length']) ? "({$real['length']})" : '');
-		}
-
-		if (!preg_match('/(?P<type>\w+)(?:\((?P<length>[\d,]+)\))?/', $real, $column)) {
-			return $real;
-		}
-		$column = array_intersect_key($column, array('type' => null, 'length' => null));
-
-		if (isset($column['length']) && $column['length']) {
-			$length = explode(',', $column['length']) + array(null, null);
-			$column['length'] = $length[0] ? intval($length[0]) : null;
-			$length[1] ? $column['precision'] = intval($length[1]) : null;
-		}
-
-		switch (true) {
-			case in_array($column['type'], array('date', 'time', 'datetime')):
-				return $column;
-			case ($column['type'] == 'timestamp'):
-				$column['type'] = 'datetime';
-			break;
-			case ($column['type'] == 'tinyint' && $column['length'] == '1'):
-			case ($column['type'] == 'boolean'):
-				return array('type' => 'boolean');
-			break;
-			case (strpos($column['type'], 'int') !== false):
-				$column['type'] = 'integer';
-			break;
-			case (strpos($column['type'], 'char') !== false || $column['type'] == 'tinytext'):
-				$column['type'] = 'string';
-			break;
-			case (strpos($column['type'], 'text') !== false):
-				$column['type'] = 'text';
-			break;
-			case (strpos($column['type'], 'blob') !== false || $column['type'] == 'binary'):
-				$column['type'] = 'binary';
-			break;
-			case preg_match('/float|double|decimal/', $column['type']):
-				$column['type'] = 'float';
-			break;
-			default:
-				$column['type'] = 'text';
-			break;
-		}
-		return $column;
-	}
-
-	protected function _toNativeBoolean($value) {
-		return $this->connection->quote($value ? 't' : 'f');
-	}
-}
-
-?>

+ 0 - 327
frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/Sqlite3.php

@@ -1,327 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- *
- */
-
-namespace lithium\data\source\database\adapter;
-
-use PDOException;
-use lithium\core\ConfigException;
-
-/**
- * Sqlite database driver
- *
- * @todo fix encoding methods to use class query methods instead of sqlite3 natives
- */
-class Sqlite3 extends \lithium\data\source\Database {
-
-	/**
-	 * Pair of opening and closing quote characters used for quoting identifiers in queries.
-	 *
-	 * @link http://www.sqlite.org/lang_keywords.html
-	 * @var array
-	 */
-	protected $_quotes = array('"', '"');
-
-	/**
-	 * Sqlite column type definitions.
-	 *
-	 * @var array
-	 */
-	protected $_columns = array(
-		'primary_key' => array('name' => 'primary key autoincrement'),
-		'string' => array('name' => 'varchar', 'length' => 255),
-		'text' => array('name' => 'text'),
-		'integer' => array('name' => 'integer', 'formatter' => 'intval'),
-		'float' => array('name' => 'float', 'formatter' => 'floatval'),
-		'datetime' => array('name' => 'datetime', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'),
-		'timestamp' => array(
-			'name' => 'timestamp', 'format' => 'Y-m-d H:i:s', 'formatter' => 'date'
-		),
-		'time' => array('name' => 'time', 'format' => 'H:i:s', 'formatter' => 'date'),
-		'date' => array('name' => 'date', 'format' => 'Y-m-d', 'formatter' => 'date'),
-		'binary' => array('name' => 'blob'),
-		'boolean' => array('name' => 'boolean')
-	);
-
-	/**
-	 * Holds commonly regular expressions used in this class.
-	 *
-	 * @see lithium\data\source\database\adapter\Sqlite3::describe()
-	 * @see lithium\data\source\database\adapter\Sqlite3::_column()
-	 * @var array
-	 */
-	protected $_regex = array(
-		'column' => '(?P<type>[^(]+)(?:\((?P<length>[^)]+)\))?'
-	);
-
-	/**
-	 * Constructs the Sqlite adapter
-	 *
-	 * @see lithium\data\source\Database::__construct()
-	 * @see lithium\data\Source::__construct()
-	 * @see lithium\data\Connections::add()
-	 * @param array $config Configuration options for this class. For additional configuration,
-	 *        see `lithium\data\source\Database` and `lithium\data\Source`. Available options
-	 *        defined by this class:
-	 *        - `'database'` _string_: database name. Defaults to none
-	 *        - `'flags'` _integer_: Optional flags used to determine how to open the SQLite
-	 *          database. By default, open uses SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE.
-	 *        - `'key'` _string_: An optional encryption key used when encrypting and decrypting
-	 *          an SQLite database.
-	 *
-	 * Typically, these parameters are set in `Connections::add()`, when adding the adapter to the
-	 * list of active connections.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('database' => ':memory:', 'encoding' => null);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Check for required PHP extension, or supported database feature.
-	 *
-	 * @param string $feature Test for support for a specific feature, i.e. `'transactions'`.
-	 * @return boolean Returns `true` if the particular feature (or if Sqlite) support is enabled,
-	 *         otherwise `false`.
-	 */
-	public static function enabled($feature = null) {
-		if (!$feature) {
-			return extension_loaded('pdo_sqlite');
-		}
-		$features = array(
-			'arrays' => false,
-			'transactions' => false,
-			'booleans' => true,
-			'relationships' => true
-		);
-		return isset($features[$feature]) ? $features[$feature] : null;
-	}
-
-	/**
-	 * Connects to the database using options provided to the class constructor.
-	 *
-	 * @return boolean True if the database could be connected, else false
-	 */
-	public function connect() {
-		if (!$this->_config['database']) {
-			throw new ConfigException('No Database configured');
-		}
-
-		if (empty($this->_config['dsn'])) {
-			$this->_config['dsn'] = sprintf("sqlite:%s", $this->_config['database']);
-		}
-
-		return parent::connect();
-	}
-
-	/**
-	 * Disconnects the adapter from the database.
-	 *
-	 * @return boolean True on success, else false.
-	 */
-	public function disconnect() {
-		if ($this->_isConnected) {
-			unset($this->connection);
-			$this->_isConnected = false;
-		}
-		return true;
-	}
-
-	/**
-	 * Returns the list of tables in the currently-connected database.
-	 *
-	 * @param string $model The fully-name-spaced class name of the model object making the request.
-	 * @return array Returns an array of objects to which models can connect.
-	 * @filter This method can be filtered.
-	 */
-	public function sources($model = null) {
-		$config = $this->_config;
-
-		return $this->_filter(__METHOD__, compact('model'), function($self, $params) use ($config) {
-			$sql = "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;";
-			$result = $self->invokeMethod('_execute', array($sql));
-			$sources = array();
-
-			while ($data = $result->next()) {
-				$sources[] = reset($data);
-			}
-			return $sources;
-		});
-	}
-
-	/**
-	 * Gets the column schema for a given Sqlite3 table.
-	 *
-	 * A column type may not always be available, i.e. when during creation of
-	 * the column no type was declared. Those columns are internally treated
-	 * by SQLite3 as having a `NONE` affinity. The final schema will contain no
-	 * information about type and length of such columns (both values will be
-	 * `null`).
-	 *
-	 * @param mixed $entity Specifies the table name for which the schema should be returned, or
-	 *        the class name of the model object requesting the schema, in which case the model
-	 *        class will be queried for the correct table name.
-	 * @param array $fields Any schema data pre-defined by the model.
-	 * @param array $meta
-	 * @return array Returns an associative array describing the given table's schema, where the
-	 *         array keys are the available fields, and the values are arrays describing each
-	 *         field, containing the following keys:
-	 *         - `'type'`: The field type name
-	 * @filter This method can be filtered.
-	 */
-	public function describe($entity, $fields = array(), array $meta = array()) {
-		$params = compact('entity', 'meta', 'fields');
-		$regex = $this->_regex;
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($regex) {
-			extract($params);
-
-			if ($fields) {
-				return $self->invokeMethod('_instance', array('schema', compact('fields')));
-			}
-			$name = $self->invokeMethod('_entityName', array($entity, array('quoted' => true)));
-			$columns = $self->read("PRAGMA table_info({$name})", array('return' => 'array'));
-			$fields = array();
-			foreach ($columns as $column) {
-				preg_match("/{$regex['column']}/", $column['type'], $matches);
-
-				$fields[$column['name']] = array(
-					'type' => isset($matches['type']) ? $matches['type'] : null,
-					'length' => isset($matches['length']) ? $matches['length'] : null,
-					'null' => $column['notnull'] == 1,
-					'default' => $column['dflt_value']
-				);
-			}
-			return $self->invokeMethod('_instance', array('schema', compact('fields')));
-		});
-	}
-
-	/**
-	 * Gets the last auto-generated ID from the query that inserted a new record.
-	 *
-	 * @param object $query The `Query` object associated with the query which generated
-	 * @return mixed Returns the last inserted ID key for an auto-increment column or a column
-	 *         bound to a sequence.
-	 */
-	protected function _insertId($query) {
-		return $this->connection->lastInsertId();
-	}
-
-	/**
-	 * Gets or sets the encoding for the connection.
-	 *
-	 * @param string $encoding If setting the encoding, this is the name of the encoding to set,
-	 *               i.e. `'utf8'` or `'UTF-8'` (both formats are valid).
-	 * @return mixed If setting the encoding; returns `true` on success, or `false` on
-	 *         failure. When getting, returns the encoding as a string.
-	 */
-	public function encoding($encoding = null) {
-		$encodingMap = array('UTF-8' => 'utf8');
-
-		if (!$encoding) {
-			$query = $this->connection->query('PRAGMA encoding');
-			$encoding = $query->fetchColumn();
-			return ($key = array_search($encoding, $encodingMap)) ? $key : $encoding;
-		}
-		$encoding = isset($encodingMap[$encoding]) ? $encodingMap[$encoding] : $encoding;
-
-		try {
-			$this->connection->exec("PRAGMA encoding = \"{$encoding}\"");
-			return true;
-		} catch (PDOException $e) {
-			return false;
-		}
-	}
-
-	/**
-	 * Retrieves database error message and error code.
-	 *
-	 * @return array
-	 */
-	public function error() {
-		if ($error = $this->connection->errorInfo()) {
-			return array($error[1], $error[2]);
-		}
-	}
-
-	/**
-	 * Execute a given query.
-	 *
-	 * @see lithium\data\source\Database::renderCommand()
-	 * @param string $sql The sql string to execute
-	 * @param array $options No available options.
-	 * @return resource
-	 * @filter
-	 */
-	protected function _execute($sql, array $options = array()) {
-		$conn = $this->connection;
-		$params = compact('sql', 'options');
-		return $this->_filter(__METHOD__, $params, function($self, $params) use ($conn) {
-			$sql = $params['sql'];
-			$options = $params['options'];
-			try {
-				$resource = $conn->query($sql);
-			} catch(PDOException $e) {
-				$self->invokeMethod('_error', array($sql));
-			};
-			return $self->invokeMethod('_instance', array('result', compact('resource')));
-		});
-	}
-
-	/**
-	 * Converts database-layer column types to basic types.
-	 *
-	 * @param string $real Real database-layer column type (i.e. "varchar(255)")
-	 * @return string Abstract column type (i.e. "string")
-	 */
-	protected function _column($real) {
-		if (is_array($real)) {
-			return $real['type'] . (isset($real['length']) ? "({$real['length']})" : '');
-		}
-
-		if (!preg_match("/{$this->_regex['column']}/", $real, $column)) {
-			return $real;
-		}
-		$column = array_intersect_key($column, array('type' => null, 'length' => null));
-
-		if (isset($column['length']) && $column['length']) {
-			$length = explode(',', $column['length']) + array(null, null);
-			$column['length'] = $length[0] ? intval($length[0]) : null;
-			$length[1] ? $column['precision'] = intval($length[1]) : null;
-		}
-
-		switch (true) {
-			case in_array($column['type'], array('date', 'time', 'datetime', 'timestamp')):
-				return $column;
-			case ($column['type'] === 'tinyint' && $column['length'] == '1'):
-			case ($column['type'] === 'boolean'):
-				return array('type' => 'boolean');
-			break;
-			case (strpos($column['type'], 'int') !== false):
-				$column['type'] = 'integer';
-			break;
-			case (strpos($column['type'], 'char') !== false || $column['type'] === 'tinytext'):
-				$column['type'] = 'string';
-			break;
-			case (strpos($column['type'], 'text') !== false):
-				$column['type'] = 'text';
-			break;
-			case (strpos($column['type'], 'blob') !== false || $column['type'] === 'binary'):
-				$column['type'] = 'binary';
-			break;
-			case preg_match('/float|double|decimal/', $column['type']):
-				$column['type'] = 'float';
-			break;
-			default:
-				$column['type'] = 'text';
-			break;
-		}
-		return $column;
-	}
-}
-
-?>

+ 0 - 57
frameworks/PHP/php-lithium/libraries/lithium/data/source/database/adapter/pdo/Result.php

@@ -1,57 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source\database\adapter\pdo;
-
-use PDO;
-use PDOStatement;
-use PDOException;
-
-/**
- * This class is a wrapper around the MySQL result returned and can be used to iterate over it.
- *
- * It also provides a simple caching mechanism which stores the result after the first load.
- * You are then free to iterate over the result back and forth through the provided methods
- * and don't have to think about hitting the database too often.
- *
- * On initialization, it needs a `PDOStatement` to operate on. You are then free to use all
- * methods provided by the `Iterator` interface.
- *
- * @link http://php.net/manual/de/class.pdostatement.php The PDOStatement class.
- * @link http://php.net/manual/de/class.iterator.php The Iterator interface.
- */
-class Result extends \lithium\data\source\Result {
-
-	public $named = false;
-
-	/**
-	 * Fetches the result from the resource and caches it.
-	 *
-	 * @return boolean Return `true` on success or `false` if it is not valid.
-	 */
-	protected function _fetchFromResource() {
-		if ($this->_resource instanceof PDOStatement) {
-			try {
-				$mode = $this->named ? PDO::FETCH_NAMED : PDO::FETCH_NUM;
-				if ($result = $this->_resource->fetch($mode)) {
-					$this->_key = $this->_iterator;
-					$this->_current = $this->_cache[$this->_iterator++] = $result;
-					return true;
-				}
-			} catch (PDOException $e) {}
-		}
-		$this->_resource = null;
-		return false;
-	}
-
-	public function __destruct() {
-		$this->close();
-	}
-}
-
-?>

+ 0 - 512
frameworks/PHP/php-lithium/libraries/lithium/data/source/http/adapter/CouchDb.php

@@ -1,512 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2012, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source\http\adapter;
-
-use lithium\core\ConfigException;
-
-/**
- * A data source adapter which allows you to connect to Apache CouchDB.
- *
- * By default, it will attempt to connect to the CouchDB running on `localhost` on port
- * 5984 using HTTP version 1.0.
- *
- * @link http://couchdb.apache.org
- */
-class CouchDb extends \lithium\data\source\Http {
-
-	/**
-	 * Increment value of current result set loop
-	 * used by `result` to handle rows of json responses.
-	 *
-	 * @var string
-	 */
-	protected $_iterator = 0;
-
-	/**
-	 * True if Database exists.
-	 *
-	 * @var boolean
-	 */
-	protected $_db = false;
-
-	/**
-	 * Classes used by `CouchDb`.
-	 *
-	 * @var array
-	 */
-	protected $_classes = array(
-		'service' => 'lithium\net\http\Service',
-		'entity'  => 'lithium\data\entity\Document',
-		'set'     => 'lithium\data\collection\DocumentSet',
-		'schema'  => 'lithium\data\DocumentSchema'
-	);
-
-	protected $_handlers = array();
-
-	/**
-	 * Constructor.
-	 * @param array $config
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('port' => 5984, 'version' => 1, 'database' => null);
-		parent::__construct($config + $defaults);
-	}
-
-	protected function _init() {
-		parent::_init();
-		$this->_handlers += array(
-			'integer' => function($v) { return (integer) $v; },
-			'float'   => function($v) { return (float) $v; },
-			'boolean' => function($v) { return (boolean) $v; }
-		);
-	}
-
-	/**
-	 * Ensures that the server connection is closed and resources are freed when the adapter
-	 * instance is destroyed.
-	 *
-	 * @return void
-	 */
-	public function __destruct() {
-		if (!$this->_isConnected) {
-			return;
-		}
-		$this->disconnect();
-		$this->_db = false;
-		unset($this->connection);
-	}
-
-	/**
-	 * Configures a model class by setting the primary key to `'id'`, in keeping with CouchDb
-	 * conventions.
-	 *
-	 * @see lithium\data\Model::$_meta
-	 * @see lithium\data\Model::$_classes
-	 * @param string $class The fully-namespaced model class name to be configured.
-	 * @return Returns an array containing keys `'classes'` and `'meta'`, which will be merged with
-	 *         their respective properties in `Model`.
-	 */
-	public function configureClass($class) {
-		return array(
-			'meta' => array('key' => 'id', 'locked' => false),
-			'schema' => array(
-				'id' => array('type' => 'string'),
-				'rev' => array('type' => 'string')
-			)
-		);
-	}
-
-	/**
-	 * Magic for passing methods to http service.
-	 *
-	 * @param string $method
-	 * @param array $params
-	 * @return void
-	 */
-	public function __call($method, $params = array()) {
-		list($path, $data, $options) = ($params + array('/', array(), array()));
-		return json_decode($this->connection->{$method}($path, $data, $options));
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public function respondsTo($method, $internal = false) {
-		$parentRespondsTo = parent::respondsTo($method, $internal);
-		return $parentRespondsTo || is_callable(array($this->connection, $method));
-	}
-
-	/**
-	 * Returns an array of object types accessible through this database.
-	 *
-	 * @param object $class
-	 * @return void
-	 */
-	public function sources($class = null) {
-	}
-
-	/**
-	 * Describe database, create if it does not exist.
-	 *
-	 * @throws ConfigException
-	 * @param string $entity
-	 * @param array $schema Any schema data pre-defined by the model.
-	 * @param array $meta
-	 * @return void
-	 */
-	public function describe($entity, $schema = array(), array $meta = array()) {
-		$database = $this->_config['database'];
-
-		if (!$this->_db) {
-			$result = $this->get($database);
-
-			if (isset($result->db_name)) {
-				$this->_db = true;
-			}
-			if (!$this->_db) {
-				if (isset($result->error)) {
-					if ($result->error === 'not_found') {
-						$result = $this->put($database);
-					}
-				}
-				if (isset($result->ok) || isset($result->db_name)) {
-					$this->_db = true;
-				}
-			}
-		}
-		if (!$this->_db) {
-			throw new ConfigException("Database `{$entity}` is not available.");
-		}
-		return $this->_instance('schema', array(array('fields' => $schema)));
-	}
-
-	/**
-	 * Quotes identifiers.
-	 *
-	 * CouchDb does not need identifiers quoted, so this method simply returns the identifier.
-	 *
-	 * @param string $name The identifier to quote.
-	 * @return string The quoted identifier.
-	 */
-	public function name($name) {
-		return $name;
-	}
-
-	/**
-	 * Create new document.
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return boolean
-	 * @filter
-	 */
-	public function create($query, array $options = array()) {
-		$defaults = array('model' => $query->model());
-		$options += $defaults;
-		$params = compact('query', 'options');
-		$conn =& $this->connection;
-		$config = $this->_config;
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use (&$conn, $config) {
-			$request = array('type' => 'json');
-			$query = $params['query'];
-			$options = $params['options'];
-			$data = $query->data();
-			$data += array('type' => $options['model']::meta('source'));
-
-			if (isset($data['id'])) {
-				return $self->update($query, $options);
-			}
-			$result = $conn->post($config['database'], $data, $request);
-			$result = is_string($result) ? json_decode($result, true) : $result;
-
-			if (isset($result['_id']) || (isset($result['ok']) && $result['ok'] === true)) {
-				$result = $self->invokeMethod('_format', array($result, $options));
-				$query->entity()->sync($result['id'], $result);
-				return true;
-			}
-			return false;
-		});
-	}
-
-	/**
-	 * Read from document.
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return object
-	 * @filter
-	 */
-	public function read($query, array $options = array()) {
-		$defaults = array('return' => 'resource', 'model' => $query->model());
-		$options += $defaults;
-		$params = compact('query', 'options');
-		$conn =& $this->connection;
-		$config = $this->_config;
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use (&$conn, $config) {
-			$query = $params['query'];
-			$options = $params['options'];
-			$params = $query->export($self);
-			extract($params, EXTR_OVERWRITE);
-			list($_path, $conditions) = (array) $conditions;
-			$model = $query->model();
-
-			if (empty($_path)) {
-				$_path = '_all_docs';
-				$conditions['include_docs'] = 'true';
-			}
-			$path = "{$config['database']}/{$_path}";
-			$args = (array) $conditions + (array) $limit + (array) $order;
-			$result = $conn->get($path, $args);
-			$result = is_string($result) ? json_decode($result, true) : $result;
-			$data = $stats = array();
-
-			if (isset($result['_id'])) {
-				$data = array($result);
-			} elseif (isset($result['rows'])) {
-				$data = $result['rows'];
-				unset($result['rows']);
-				$stats = $result;
-			}
-			foreach ($data as $key => $val) {
-				$data[$key] = $self->item($model, $val, array('exists' => true));
-			}
-			$stats += array('total_rows' => null, 'offset' => null);
-			$opts = compact('stats') + array('class' => 'set', 'exists' => true);
-			return $self->item($query->model(), $data, $opts);
-		});
-	}
-
-	/**
-	 * Update document.
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return boolean
-	 * @filter
-	 */
-	public function update($query, array $options = array()) {
-		$params = compact('query', 'options');
-		$conn =& $this->connection;
-		$config = $this->_config;
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use (&$conn, $config) {
-			$query = $params['query'];
-			$options = $params['options'];
-			$params = $query->export($self);
-			extract($params, EXTR_OVERWRITE);
-			list($_path, $conditions) = (array) $conditions;
-			$data = $query->data();
-
-			foreach (array('id', 'rev') as $key) {
-				$data["_{$key}"] = isset($data[$key]) ? (string) $data[$key] : null;
-				unset($data[$key]);
-			}
-			$data = (array) $conditions + array_filter((array) $data);
-			$result = $conn->put("{$config['database']}/{$_path}", $data, array('type' => 'json'));
-			$result = is_string($result) ? json_decode($result, true) : $result;
-
-			if (isset($result['_id']) || (isset($result['ok']) && $result['ok'] === true)) {
-				$result = $self->invokeMethod('_format', array($result, $options));
-				$query->entity()->sync($result['id'], array('rev' => $result['rev']));
-				return true;
-			}
-			if (isset($result['error'])) {
-				$query->entity()->errors(array($result['error']));
-			}
-			return false;
-		});
-	}
-
-	/**
-	 * Delete document.
-	 *
-	 * @param string $query
-	 * @param array $options
-	 * @return boolean
-	 * @filter
-	 */
-	public function delete($query, array $options = array()) {
-		$params = compact('query', 'options');
-		$conn =& $this->connection;
-		$config = $this->_config;
-
-		return $this->_filter(__METHOD__, $params, function($self, $params) use (&$conn, $config) {
-			$query = $params['query'];
-			$params = $query->export($self);
-			list($_path, $conditions) = $params['conditions'];
-			$data = $query->data();
-
-			if (!empty($data['rev'])) {
-				$conditions['rev'] = $data['rev'];
-			}
-			$result = json_decode($conn->delete("{$config['database']}/{$_path}", $conditions));
-			$result = (isset($result->ok) && $result->ok === true);
-
-			if ($query->entity()) {
-				$query->entity()->sync(null, array(), array('dematerialize' => true));
-			}
-			return $result;
-		});
-	}
-
-	/**
-	 * Executes calculation-related queries, such as those required for `count`.
-	 *
-	 * @param string $type Only accepts `count`.
-	 * @param mixed $query The query to be executed.
-	 * @param array $options Optional arguments for the `read()` query that will be executed
-	 *        to obtain the calculation result.
-	 * @return integer Result of the calculation.
-	 */
-	public function calculation($type, $query, array $options = array()) {
-		switch ($type) {
-			case 'count':
-				return $this->read($query, $options)->stats('total_rows');
-			default:
-				return null;
-		}
-	}
-
-	/**
-	 * Returns a newly-created `Document` object, bound to a model and populated with default data
-	 * and options.
-	 *
-	 * @param string $model A fully-namespaced class name representing the model class to which the
-	 *               `Document` object will be bound.
-	 * @param array $data The default data with which the new `Document` should be populated.
-	 * @param array $options Any additional options to pass to the `Document`'s constructor
-	 * @return object Returns a new, un-saved `Document` object bound to the model class specified
-	 *         in `$model`.
-	 */
-	public function item($model, array $data = array(), array $options = array()) {
-		if (isset($data['doc'])) {
-			return parent::item($model, $this->_format($data['doc']), $options);
-		}
-		if (isset($data['value'])) {
-			$data = $data['value'];
-		}
-		return parent::item($model, $this->_format($data), $options);
-	}
-
-	/**
-	 * Casts data into proper format when added to a collection or entity object.
-	 *
-	 * @param mixed $entity The entity or collection for which data is being cast, or the name of
-	 *              the model class to which the entity/collection is bound.
-	 * @param array $data An array of data being assigned.
-	 * @param array $options Any associated options with, for example, instantiating new objects in
-	 *              which to wrap the data. Options implemented by `cast()` itself:
-	 *              - `first` _boolean_: Used when only one value is passed to `cast()`. Even though
-	 *                that value must be wrapped in an array, setting the `'first'` option to `true`
-	 *                causes only that one value to be returned.
-	 * @return mixed Returns the value of `$data`, cast to the proper format according to the schema
-	 *         definition of the model class specified by `$model`.
-	 */
-	public function cast($entity, array $data, array $options = array()) {
-		$defaults = array('pathKey' => null, 'model' => null);
-		$options += $defaults;
-		$model = $options['model'] ?: $entity->model();
-
-		foreach ($data as $key => $val) {
-			if (!is_array($val)) {
-				continue;
-			}
-			$pathKey = $options['pathKey'] ? "{$options['pathKey']}.{$key}" : $key;
-			$class = (range(0, count($val) - 1) === array_keys($val)) ? 'set' : 'entity';
-			$data[$key] = $this->item($model, $val, compact('class', 'pathKey') + $options);
-		}
-		return parent::cast($entity, $data, $options);
-	}
-
-	/**
-	 * Handle conditions.
-	 *
-	 * @param string $conditions
-	 * @param string $context
-	 * @return array
-	 */
-	public function conditions($conditions, $context) {
-		$path = null;
-		if (isset($conditions['design'])) {
-			$paths = array('design', 'view');
-			foreach ($paths as $element) {
-				if (isset($conditions[$element])) {
-					$path .= "_{$element}/{$conditions[$element]}/";
-					unset($conditions[$element]);
-				}
-			}
-		}
-		if (isset($conditions['id'])) {
-			$path = "{$conditions['id']}";
-			unset($conditions['id']);
-		}
-		if (isset($conditions['path'])) {
-			$path = "{$conditions['path']}";
-			unset($conditions['path']);
-		}
-		return array($path, $conditions);
-	}
-
-	/**
-	 * Fields for query.
-	 *
-	 * @param string $fields
-	 * @param string $context
-	 * @return array
-	 */
-	public function fields($fields, $context) {
-		return $fields ?: array();
-	}
-
-	/**
-	 * Limit for query.
-	 *
-	 * @param string $limit
-	 * @param string $context
-	 * @return array
-	 */
-	public function limit($limit, $context) {
-		return compact('limit') ?: array();
-	}
-
-	/**
-	 * Order for query.
-	 *
-	 * @param string $order
-	 * @param string $context
-	 * @return array
-	 */
-	public function order($order, $context) {
-		return (array) $order ?: array();
-	}
-
-	/**
-	 * With no parameter, always returns `true`, since CouchDB only depends on HTTP. With a
-	 * parameter, queries for a specific supported feature.
-	 *
-	 * @param string $feature Test for support for a specific feature, i.e. `"transactions"` or
-	 *               `"arrays"`.
-	 * @return boolean Returns `true` if the particular feature support is enabled, otherwise
-	 *         `false`.
-	 */
-	public static function enabled($feature = null) {
-		if (!$feature) {
-			return true;
-		}
-		$features = array(
-			'arrays' => true,
-			'transactions' => false,
-			'booleans' => true,
-			'relationships' => false
-		);
-		return isset($features[$feature]) ? $features[$feature] : null;
-	}
-
-	/**
-	 * Formats a CouchDb result set into a standard result to be passed to item.
-	 *
-	 * @param array $data data returned from query
-	 * @return array
-	 */
-	protected function _format(array $data) {
-		foreach (array("id", "rev") as $key) {
-			$data[$key] = isset($data["_{$key}"]) ? $data["_{$key}"] : null;
-			unset($data["_{$key}"]);
-		}
-		return $data;
-	}
-}
-
-?>

+ 0 - 189
frameworks/PHP/php-lithium/libraries/lithium/data/source/mongo_db/Exporter.php

@@ -1,189 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source\mongo_db;
-
-use lithium\util\Set;
-
-class Exporter extends \lithium\core\StaticObject {
-
-	protected static $_classes = array(
-		'set' => 'lithium\data\collection\DocumentSet'
-	);
-
-	protected static $_commands = array(
-		'create'    => null,
-		'update'    => '$set',
-		'increment' => '$inc',
-		'remove'    => '$unset',
-		'rename'    => '$rename'
-	);
-
-	public static function get($type, $export, array $options = array()) {
-		$defaults = array('whitelist' => array());
-		$options += $defaults;
-
-		if (!method_exists(get_called_class(), $method = "_{$type}") || !$export) {
-			return;
-		}
-		return static::$method($export, array('finalize' => true) + $options);
-	}
-
-	public static function toCommand($changes) {
-		$result = array();
-
-		foreach (static::$_commands as $from => $to) {
-			if (!isset($changes[$from])) {
-				continue;
-			}
-			if (!$to) {
-				$result = array_merge($result, $changes[$from]);
-			}
-			$result[$to] = $changes[$from];
-		}
-		unset($result['$set']['_id']);
-		return $result;
-	}
-
-	protected static function _create($export, array $options) {
-		$export += array('data' => array(), 'update' => array(), 'key' => '');
-		$data = Set::merge($export['data'], $export['update']);
-
-		if (array_keys($data) == range(0, count($data) - 1)) {
-			$data = $export['update'];
-		}
-		$localOpts = array('finalize' => false) + $options;
-
-		foreach ($data as $key => $val) {
-			if (is_object($val) && method_exists($val, 'export')) {
-				$data[$key] = static::_create($val->export($options), $localOpts);
-			}
-		}
-		return ($options['finalize']) ? array('create' => $data) : $data;
-	}
-
-	/**
-	 * Calculates changesets for update operations, and produces an array which can be converted to
-	 * a set of native MongoDB update operations.
-	 *
-	 * @todo Implement remove and rename.
-	 * @param array $export An array of fields exported from a call to `Document::export()`, and
-	 *              should contain the following keys:
-	 *              - `'data'` _array_: An array representing the original data loaded from the
-	 *                 database for the document.
-	 *              - `'update'` _array_: An array representing the current state of the document,
-	 *                containing any modifications made.
-	 *              - `'key'` _string_: If this is a nested document, this is a dot-separated path
-	 *                from the root-level document.
-	 * @return array Returns an array representing the changes to be made to the document. These
-	 *         are converted to database-native commands by the `toCommand()` method.
-	 */
-	protected static function _update($export) {
-		$export += array(
-			'data' => array(),
-			'update' => array(),
-			'remove' => array(),
-			'rename' => array(),
-			'key' => ''
-		);
-		$path = $export['key'] ? "{$export['key']}." : "";
-		$result = array('update' => array(), 'remove' => array());
-		$left = static::_diff($export['data'], $export['update']);
-		$right = static::_diff($export['update'], $export['data']);
-
-		$objects = array_filter($export['update'], function($value) {
-			return (is_object($value) && method_exists($value, 'export'));
-		});
-		array_map(function($key) use (&$left) { unset($left[$key]); }, array_keys($right));
-
-		foreach ($left as $key => $value) {
-			$result = static::_append($result, "{$path}{$key}", $value, 'remove');
-		}
-		$update = $right + $objects;
-
-		foreach ($update as $key => $value) {
-			$original = $export['data'];
-			$isArray = is_object($value) && get_class($value) === static::$_classes['set'];
-
-			$options = array(
-				'indexed' => null,
-				'handlers' => array(
-					'MongoDate' => function($value) { return $value; },
-					'MongoId' => function($value) { return $value; }
-				)
-			);
-
-			if ($isArray) {
-				$newValue = $value->to('array', $options);
-				$originalValue = null;
-				if (isset($original[$key])) {
-					$originalValue = $original[$key]->to('array', $options);
-				}
-				if ($newValue !== $originalValue) {
-					$value = $value->to('array', $options);
-				}
-			}
-			$result = static::_append($result, "{$path}{$key}", $value, 'update');
-		}
-		return array_filter($result);
-	}
-
-	/**
-	 * Handle diffing operations between `Document` object states. Implemented because all of PHP's
-	 * array comparison functions are broken when working with objects.
-	 *
-	 * @param array $left The left-hand comparison array.
-	 * @param array $right The right-hand comparison array.
-	 * @return array Returns an array of the differences of `$left` compared to `$right`.
-	 */
-	protected static function _diff($left, $right) {
-		$result = array();
-
-		foreach ($left as $key => $value) {
-			if (!array_key_exists($key, $right) || $left[$key] !== $right[$key]) {
-				$result[$key] = $value;
-			}
-		}
-		return $result;
-	}
-
-	/**
-	 * Handles appending nested objects to document changesets.
-	 *
-	 * @param array $changes The full set of changes to be made to the database.
-	 * @param string $key The key of the field to append, which may be a dot-separated path if the
-	 *               value is or is contained within a nested object.
-	 * @param mixed $value The value to append to the changeset. Can be a scalar value, array, a
-	 *              nested object, or part of a nested object.
-	 * @param string $change The type of change, as to whether update/remove or rename etc.
-	 * @return array Returns the value of `$changes`, with any new changed values appended.
-	 */
-	protected static function _append($changes, $key, $value, $change) {
-		$options = array('finalize' => false);
-
-		if (!is_object($value) || !method_exists($value, 'export')) {
-			$changes[$change][$key] = ($change === 'update') ? $value : true;
-			return $changes;
-		}
-		if (!$value->exists()) {
-			$changes[$change][$key] = static::_create($value->export(), $options);
-			return $changes;
-		}
-		if ($change === 'update') {
-			$export = compact('key') + $value->export();
-			return Set::merge($changes, static::_update($export));
-		}
-		if ($children = static::_update($value->export())) {
-			return Set::merge($changes, $children);
-		}
-		$changes[$change][$key] = true;
-		return $changes;
-	}
-}
-
-?>

+ 0 - 33
frameworks/PHP/php-lithium/libraries/lithium/data/source/mongo_db/Result.php

@@ -1,33 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source\mongo_db;
-
-use MongoGridFSFile;
-
-class Result extends \lithium\data\source\Result {
-
-	/**
-	 * Fetches the result from the resource and caches it.
-	 *
-	 * @return boolean Return `true` on success or `false` if it is not valid.
-	 */
-	protected function _fetchFromResource() {
-		if ($this->_resource && $this->_resource->hasNext()) {
-			$result = $this->_resource->getNext();
-			$isFile = ($result instanceof MongoGridFSFile);
-			$result = $isFile ? array('file' => $result) + $result->file : $result;
-			$this->_key = $this->_iterator;
-			$this->_current = $this->_cache[$this->_iterator++] = $result;
-			return true;
-		}
-		return false;
-	}
-}
-
-?>

+ 0 - 58
frameworks/PHP/php-lithium/libraries/lithium/data/source/mongo_db/Schema.php

@@ -1,58 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\data\source\mongo_db;
-
-use MongoId;
-use MongoCode;
-use MongoDate;
-use MongoRegex;
-use MongoBinData;
-
-class Schema extends \lithium\data\DocumentSchema {
-
-	protected $_handlers = array();
-
-	protected $_types = array(
-		'MongoId'      => 'id',
-		'MongoDate'    => 'date',
-		'MongoCode'    => 'code',
-		'MongoBinData' => 'binary',
-		'datetime'     => 'date',
-		'timestamp'    => 'date',
-		'int'          => 'integer'
-	);
-
-	public function __construct(array $config = array()) {
-		$defaults = array('fields' => array('_id' => array('type' => 'id')));
-		parent::__construct(array_filter($config) + $defaults);
-	}
-
-	protected function _init() {
-		$this->_autoConfig[] = 'handlers';
-		parent::_init();
-
-		$this->_handlers += array(
-			'id' => function($v) {
-				return is_string($v) && preg_match('/^[0-9a-f]{24}$/', $v) ? new MongoId($v) : $v;
-			},
-			'date' => function($v) {
-				$v = is_numeric($v) ? intval($v) : strtotime($v);
-				return !$v ? new MongoDate() : new MongoDate($v);
-			},
-			'regex'   => function($v) { return new MongoRegex($v); },
-			'integer' => function($v) { return (integer) $v; },
-			'float'   => function($v) { return (float) $v; },
-			'boolean' => function($v) { return (boolean) $v; },
-			'code'    => function($v) { return new MongoCode($v); },
-			'binary'  => function($v) { return new MongoBinData($v); }
-		);
-	}
-}
-
-?>

+ 0 - 152
frameworks/PHP/php-lithium/libraries/lithium/g11n/Catalog.php

@@ -1,152 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n;
-
-use lithium\core\Libraries;
-
-/**
- * Globalization data is not just translated messages, it is validation rules, formats and a lot
- * more. Generally speaking is the `Catalog` class allowing us to retrieve and store globalized
- * data, providing low-level functionality to other classes.
- *
- * The class is able to aggregate data from different sources which allows to complement sparse
- * data. Not all categories must be supported by an individual adapter.
- */
-class Catalog extends \lithium\core\Adaptable {
-
-	/**
-	 * A Collection of the configurations you add through Catalog::config().
-	 *
-	 * @var Collection
-	 */
-	protected static $_configurations = array();
-
-	/**
-	 * Libraries::locate() compatible path to adapters for this class.
-	 *
-	 * @see lithium\core\Libraries::locate()
-	 * @var string Dot-delimited path.
-	 */
-	protected static $_adapters = 'adapter.g11n.catalog';
-
-	/**
-	 * Sets configurations for this Adaptable implementation.
-	 *
-	 * @param array $config Configurations, indexed by name.
-	 * @return array `Collection` of configurations or void if setting configurations.
-	 */
-	public static function config($config = null) {
-		$defaults = array('scope' => null);
-
-		if (is_array($config)) {
-			foreach ($config as $i => $item) {
-				$config[$i] += $defaults;
-			}
-		}
-		return parent::config($config);
-	}
-
-	/**
-	 * Reads data.
-	 *
-	 * Results are aggregated by querying all requested configurations for the requested
-	 * locale then repeating this process for all locales down the locale cascade. This
-	 * allows for sparse data which is complemented by data from other sources or for more
-	 * generic locales. Aggregation can be controlled by either specifying the configurations
-	 * or a scope to use.
-	 *
-	 * Usage:
-	 * {{{
-	 * Catalog::read(true, 'message', 'zh');
-	 * Catalog::read('default', 'message', 'zh');
-	 * Catalog::read('default', 'validation.postalCode', 'en_US');
-	 * }}}
-	 *
-	 * @param mixed $name Provide a single configuration name as a string or multiple ones as
-	 *        an array which will be used to read from. Pass `true` to use all configurations.
-	 * @param string $category A (dot-delimeted) category.
-	 * @param string $locale A locale identifier.
-	 * @param array $options Valid options are:
-	 *        - `'scope'`: The scope to use.
-	 *        - `'lossy'`: Whether or not to use the compact and lossy format, defaults to `true`.
-	 * @return array If available the requested data, else `null`.
-	 */
-	public static function read($name, $category, $locale, array $options = array()) {
-		$defaults = array('scope' => null, 'lossy' => true);
-		$options += $defaults;
-
-		$category = strtok($category, '.');
-		$id = strtok('.');
-
-		$names = $name === true ? array_keys(static::$_configurations) : (array) $name;
-		$results = array();
-
-		foreach (Locale::cascade($locale) as $cascaded) {
-			foreach ($names as $name) {
-				$adapter = static::adapter($name);
-
-				if ($result = $adapter->read($category, $cascaded, $options['scope'])) {
-					$results += $result;
-				}
-			}
-		}
-		if ($options['lossy']) {
-			array_walk($results, function(&$value) {
-				$value = $value['translated'];
-			});
-		}
-
-		if ($id) {
-			return isset($results[$id]) ? $results[$id] : null;
-		}
-		return $results ?: null;
-	}
-
-	/**
-	 * Writes data.
-	 *
-	 * Usage:
-	 * {{{
-	 * $data = array(
-	 * 	'color' => '色'
-	 * );
-	 * Catalog::write('runtime', 'message', 'ja', $data);
-	 * }}}
-	 *
-	 * @param string $name Provide a configuration name to use for writing.
-	 * @param string $category A (dot-delimited) category.
-	 * @param string $locale A locale identifier.
-	 * @param mixed $data If method is used without specifying an id must be an array.
-	 * @param array $options Valid options are:
-	 *        - `'scope'`: The scope to use.
-	 * @return boolean Success.
-	 */
-	public static function write($name, $category, $locale, $data, array $options = array()) {
-		$defaults = array('scope' => null);
-		$options += $defaults;
-
-		$category = strtok($category, '.');
-		$id = strtok('.');
-
-		if ($id) {
-			$data = array($id => $data);
-		}
-
-		array_walk($data, function(&$value, $key) {
-			if (!is_array($value) || !array_key_exists('translated', $value)) {
-				$value = array('id' => $key, 'translated' => $value);
-			}
-		});
-
-		$adapter = static::adapter($name);
-		return $adapter->write($category, $locale, $options['scope'], $data);
-	}
-}
-
-?>

+ 0 - 321
frameworks/PHP/php-lithium/libraries/lithium/g11n/Locale.php

@@ -1,321 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n;
-
-use BadMethodCallException;
-use InvalidArgumentException;
-use lithium\action\Request as ActionRequest;
-use lithium\console\Request as ConsoleRequest;
-
-/**
- * The `Locale` class provides methods to deal with locale identifiers.  The locale
- * (here: _locale identifier_) is used to distinguish among different sets of common
- * preferences.
- *
- * In order to avoid unnecessary overhead all methods throughout the framework accepting
- * a locale require it to be well-formed according to the structure laid out below. For
- * assuring the correct format use `Locale::canonicalize()` once on the locale.
- *
- * However the methods within this class will also work with not-so-well-formed locales.
- * They accept both underscores and hyphens as separators between and don't care about the
- * case of the individual tags.
- *
- * The identifier used by Lithium is based in its structure upon Unicode's
- * language identifier and is compliant to BCP 47.
- *
- * `language[_Script][_TERRITORY][_VARIANT]`
- *  - `language` The spoken language, here represented by an ISO 639-1 code,
- *    where not available ISO 639-3 and ISO 639-5 codes are allowed too) tag.
- *    The tag should  be lower-cased and is required.
- *  - `Script` The tag should have it's first character capitalized, all others
- *    lower-cased. The tag is optional.
- *  - `TERRITORY` A geographical area, here represented by an ISO 3166-1 code.
- *     Should be all upper-cased and is optional.
- *  - `VARIANT` Should be all upper-cased and is optional.
- *
- * @link http://www.unicode.org/reports/tr35/tr35-12.html#Identifiers
- * @link http://www.rfc-editor.org/rfc/bcp/bcp47.txt
- * @link http://www.iana.org/assignments/language-subtag-registry
- */
-class Locale extends \lithium\core\StaticObject {
-
-	/**
-	 * Properties for locale tags.
-	 *
-	 * @var array
-	 */
-	protected static $_tags = array(
-		'language' => array('formatter' => 'strtolower'),
-		'script' => array('formatter' => array('strtolower', 'ucfirst')),
-		'territory' => array('formatter' => 'strtoupper'),
-		'variant' => array('formatter' => 'strtoupper')
-	);
-
-	/**
-	 * Magic method enabling `language`, `script`, `territory` and `variant`
-	 * methods to parse and retrieve individual tags from a locale.
-	 *
-	 * {{{
-	 *     Locale::language('en_US'); // returns 'en'
-	 *     Locale::territory('en_US'); // returns 'US'
-	 * }}}
-	 *
-	 * @see lithium\g11n\Locale::$_tags
-	 * @see lithium\g11n\Locale::decompose()
-	 * @param string $method
-	 * @param array $params
-	 * @return mixed
-	 */
-	public static function __callStatic($method, $params = array()) {
-		$tags = static::invokeMethod('decompose', $params);
-
-		if (!isset(static::$_tags[$method])) {
-			throw new BadMethodCallException("Invalid locale tag `{$method}`.");
-		}
-		return isset($tags[$method]) ? $tags[$method] : null;
-	}
-
-	/**
-	 * Custom check to determine if our given magic methods can be responded to.
-	 *
-	 * @param  string  $method     Method name.
-	 * @param  bool    $internal   Interal call or not.
-	 * @return bool
-	 */
-	public static function respondsTo($method, $internal = false) {
-		return isset(static::$_tags[$method]) || parent::respondsTo($method, $internal);
-	}
-
-	/**
-	 * Composes a locale from locale tags.  This is the pendant to `Locale::decompose()`.
-	 *
-	 * @param array $tags An array as obtained from `Locale::decompose()`.
-	 * @return string A locale with tags separated by underscores or `null`
-	 *         if none of the passed tags could be used to compose a locale.
-	 */
-	public static function compose($tags) {
-		$result = array();
-
-		foreach (static::$_tags as $name => $tag) {
-			if (isset($tags[$name])) {
-				$result[] = $tags[$name];
-			}
-		}
-		if ($result) {
-			return implode('_', $result);
-		}
-	}
-
-	/**
-	 * Parses a locale into locale tags.  This is the pendant to `Locale::compose()``.
-	 *
-	 * @param string $locale A locale in an arbitrary form (i.e. `'en_US'` or `'EN-US'`).
-	 * @return array Parsed language, script, territory and variant tags.
-	 * @throws InvalidArgumentException
-	 */
-	public static function decompose($locale) {
-		$regex  = '(?P<language>[a-z]{2,3})';
-		$regex .= '(?:[_-](?P<script>[a-z]{4}))?';
-		$regex .= '(?:[_-](?P<territory>[a-z]{2}))?';
-		$regex .= '(?:[_-](?P<variant>[a-z]{5,}))?';
-
-		if (!preg_match("/^{$regex}$/i", $locale, $matches)) {
-			throw new InvalidArgumentException("Locale `{$locale}` could not be parsed.");
-		}
-		return array_filter(array_intersect_key($matches, static::$_tags));
-	}
-
-	/**
-	 * Returns a locale in its canonical form with tags formatted properly.
-	 *
-	 * @param string $locale A locale in an arbitrary form (i.e. `'ZH-HANS-HK_REVISED'`).
-	 * @return string A locale in it's canonical form (i.e. `'zh_Hans_HK_REVISED'`).
-	 */
-	public static function canonicalize($locale) {
-		$tags = static::decompose($locale);
-
-		foreach ($tags as $name => &$tag) {
-			foreach ((array) static::$_tags[$name]['formatter'] as $formatter) {
-				$tag = $formatter($tag);
-			}
-		}
-		return static::compose($tags);
-	}
-
-	/**
-	 * Cascades a locale.
-	 *
-	 * Usage:
-	 * {{{
-	 * Locale::cascade('en_US');
-	 * // returns array('en_US', 'en', 'root')
-	 *
-	 * Locale::cascade('zh_Hans_HK_REVISED');
-	 * // returns array('zh_Hans_HK_REVISED', 'zh_Hans_HK', 'zh_Hans', 'zh', 'root')
-	 * }}}
-	 *
-	 * @link http://www.unicode.org/reports/tr35/tr35-13.html#Locale_Inheritance
-	 * @param string $locale A locale in an arbitrary form (i.e. `'en_US'` or `'EN-US'`).
-	 * @return array Indexed array of locales (starting with the most specific one).
-	 */
-	public static function cascade($locale) {
-		$locales[] = $locale;
-
-		if ($locale === 'root') {
-			return $locales;
-		}
-		$tags = static::decompose($locale);
-
-		while (count($tags) > 1) {
-			array_pop($tags);
-			$locales[] = static::compose($tags);
-		}
-		$locales[] = 'root';
-		return $locales;
-	}
-
-	/**
-	 * Searches an array of locales for the best match to a locale. The locale
-	 * is iteratively simplified until either it matches one of the locales
-	 * in the list or the locale can't be further simplified.
-	 *
-	 * This method partially implements the lookup matching scheme as described
-	 * in RFC 4647, section 3.4 and thus does not strictly conform to the
-	 * specification.
-	 *
-	 * Differences to specification:
-	 * - No support for wildcards in the to-be-matched locales.
-	 * - No support for locales with private subtags.
-	 * - No support for a default return value.
-	 * - Passed locales are required to be in canonical form (i.e. `'ja_JP'`).
-	 *
-	 * @link http://www.ietf.org/rfc/rfc4647.txt
-	 * @param array $locales Locales to match against `$locale`.
-	 * @param string $locale A locale in it's canonical form (i.e. `'zh_Hans_HK_REVISED'`).
-	 * @return string The matched locale.
-	 */
-	public static function lookup($locales, $locale) {
-		$tags = static::decompose($locale);
-		$count = count($tags);
-		while ($count > 0) {
-			if (($key = array_search(static::compose($tags), $locales)) !== false) {
-				return $locales[$key];
-			} elseif ($count === 1) {
-				foreach ($locales as $currentLocale) {
-					if (strpos($currentLocale, current($tags) . '_') === 0) {
-						return $currentLocale;
-					}
-				}
-			}
-			if (($key = array_search(static::compose($tags), $locales)) !== false) {
-				return $locales[$key];
-			}
-			array_pop($tags);
-			$count = count($tags);
-		}
-	}
-
-	/**
-	 * Determines the preferred locale from a request or array. Optionally negotiates
-	 * the preferred locale with available locales.
-	 *
-	 * @see lithium\g11n\Locale::_preferredAction()
-	 * @see lithium\g11n\Locale::_preferredConsole()
-	 * @see lithium\g11n\Locale::lookup()
-	 * @param object|array $request An action or console request object or an array of locales.
-	 * @param array $available A list of locales to negotiate the preferred locale with.
-	 * @return string The preferred locale in it's canonical form (i.e. `'fr_CA'`).
-	 * @todo Rewrite this to remove hard-coded class names.
-	 */
-	public static function preferred($request, $available = null) {
-		if (is_array($request)) {
-			$result = $request;
-		} elseif ($request instanceof ActionRequest) {
-			$result = static::_preferredAction($request);
-		} elseif ($request instanceof ConsoleRequest) {
-			$result = static::_preferredConsole($request);
-		} else {
-			return null;
-		}
-		if (!$available) {
-			return array_shift($result);
-		}
-		foreach ((array) $result as $locale) {
-			if ($match = static::lookup($available, $locale)) {
-				return $match;
-			}
-		}
-	}
-
-	/**
-	 * Detects preferred locales from an action request by looking at the
-	 * `'Accept-Language'` header as described by RFC 2616, section 14.4.
-	 *
-	 * @link http://www.ietf.org/rfc/rfc2616.txt
-	 * @param object $request An instance of `lithium\action\Request`.
-	 * @return array Preferred locales in their canonical form (i.e. `'fr_CA'`).
-	 */
-	protected static function _preferredAction($request) {
-		$result = array();
-		$regex  = "/^\s*(?P<locale>\w\w(?:[-]\w\w)?)(?:;q=(?P<quality>(0|1|0\.\d+)))?\s*$/";
-
-		foreach (explode(',', $request->env('HTTP_ACCEPT_LANGUAGE')) as $part) {
-			if (preg_match($regex, $part, $matches)) {
-				$locale = static::canonicalize($matches['locale']);
-				$quality = isset($matches['quality']) ? $matches['quality'] : 1;
-				$result[$quality][] = $locale;
-			}
-		}
-
-		krsort($result);
-		$return = array();
-
-		foreach ($result as $locales) {
-			$return = array_merge($return, array_values($locales));
-		}
-		return $return;
-	}
-
-	/**
-	 * Detects preferred locales from a console request by looking at certain
-	 * environment variables. The environment variables may be present or not
-	 * depending on your system. If multiple variables are present the following
-	 * hierarchy is used: `'LANGUAGE'`,  `'LC_ALL'`, `'LANG'`.
-	 *
-	 * The locales of the `'LC_ALL'` and the `'LANG'` are formatted according
-	 * to the posix standard: `language(_territory)(.encoding)(@modifier)`.
-	 * Locales having such a format are automatically canonicalized and transformed
-	 * into the `Locale` class' format.
-	 *
-	 * @link http://www.linux.com/archive/feature/53781
-	 * @param object $request An instance of `lithium\console\Request`.
-	 * @return array Preferred locales in their canonical form (i.e. `'fr_CA'`).
-	 */
-	protected static function _preferredConsole($request) {
-		$regex = '(?P<locale>[\w\_]+)(\.|@|$)+';
-		$result = array();
-
-		if ($value = $request->env('LANGUAGE')) {
-			return explode(':', $value);
-		}
-		foreach (array('LC_ALL', 'LANG') as $variable)  {
-			$value = $request->env($variable);
-
-			if (!$value || $value === 'C' || $value === 'POSIX') {
-				continue;
-			}
-			if (preg_match("/{$regex}/", $value, $matches)) {
-				return (array) $matches['locale'];
-			}
-		}
-		return $result;
-	}
-}
-
-?>

+ 0 - 220
frameworks/PHP/php-lithium/libraries/lithium/g11n/Message.php

@@ -1,220 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n;
-
-use lithium\core\Environment;
-use lithium\util\String;
-use lithium\g11n\Catalog;
-
-/**
- * The `Message` class is concerned with an aspect of globalizing static message strings
- * throughout the framework and applications.  When referring to message globalization the
- * phrase of ""translating a message" is widely used. This leads to the assumption that it's
- * a single step process whereas it' a multi step one. A short description of each step is
- * given here in order to help understanding the purpose of this class through the context
- * of the process as a whole.
- *
- *  1. Marking messages as translatable.  `$t()` and `$tn()` (implemented in `aliases()`)
- *     are recognized as message marking and picked up by the extraction parser.
- *
- *  2. Extracting marked messages.  Messages can be extracted through the `g11n`
- *     command which in turn utilizes the `Catalog` class with the built-in `Code`
- *     adapter or other custom adapters which are concerned with extracting
- *     translatable content.
- *
- *  3. Creating a message template from extracted messages.  Templates are created
- *     by the `g11n` command using the `Catalog` class with an adapter for a format
- *     you prefer.
- *
- *  4. Translating messages.  The actual translation of messages by translators
- *     happens outside using external applications.
- *
- *  5. Storing translated messages.  Translations are most often stored by the external
- *     applications itself.
- *
- *  6. Retrieving the translation for a message. See description for `Message::translate()`.
- *
- * @see lithium\g11n\Catalog
- * @see lithium\console\command\G11n
- * @see lithium\g11n\catalog\adapter\Code
- */
-class Message extends \lithium\core\StaticObject {
-
-	/**
-	 * Holds cached message pages generated and used
-	 * by `lithium\g11n\Message::_translated()`.
-	 *
-	 * @var array
-	 * @see lithium\g11n\Message::_translated()
-	 */
-	protected static $_cachedPages = array();
-
-	/**
-	 * Translates a message according to the current or provided locale
-	 * and into it's correct plural form.
-	 *
-	 * Usage:
-	 * {{{
-	 * Message::translate('Mind the gap.');
-	 * Message::translate('house', array('count' => 23));
-	 * }}}
-	 *
-	 * `String::insert()`-style placeholders may be used within the message
-	 * and replacements provided directly within the `options`  argument.
-	 *
-	 * Example:
-	 * {{{
-	 * Message::translate('I can see {:count} bike.');
-	 * Message::translate('This painting is {:color}.', array(
-	 * 	'color' => Message::translate('silver'),
-	 * ));
-	 * }}}
-	 *
-	 * @see lithium\util\String::insert()
-	 * @param string $id The id to use when looking up the translation.
-	 * @param array $options Valid options are:
-	 *              - `'count'`: Used to determine the correct plural form. You can either pass
-	 *                           a signed or unsigned integer, the behavior when passing other types
-	 *                           is yet undefined.
-	 *                           The count is made absolute before being passed to the pluralization
-	 *                           function. This has the effect that that with i.e. an English
-	 *                           pluralization function passing `-1` results in a singular
-	 *                           translation.
-	 *              - `'locale'`: The target locale, defaults to current locale.
-	 *              - `'scope'`: The scope of the message.
-	 *              - `'default'`: Is used as a fall back if `_translated()` returns
-	 *                             without a result.
-	 *              - `'noop'`: If `true` no whatsoever lookup takes place.
-	 * @return string The translation or the value of the `'default'` option if none
-	 *                     could be found.
-	 */
-	public static function translate($id, array $options = array()) {
-		$defaults = array(
-			'count' => 1,
-			'locale' => Environment::get('locale'),
-			'scope' => null,
-			'default' => null,
-			'noop' => false
-		);
-		$options += $defaults;
-
-		if ($options['noop']) {
-			$result = null;
-		} else {
-			$result = static::_translated($id, abs($options['count']), $options['locale'], array(
-				'scope' => $options['scope']
-			));
-		}
-
-		if ($result || $options['default']) {
-			return String::insert($result ?: $options['default'], $options);
-		}
-	}
-
-	/**
-	 * Returns an array containing named closures which are aliases for `translate()`.
-	 * They can be embedded as content filters in the template layer using a filter for
-	 * `Media::_handle()` or be used in other places where needed.
-	 *
-	 * Usage:
-	 * {{{
-	 * 	$t('bike');
-	 * 	$tn('bike', 'bikes', 3);
-	 * }}}
-	 *
-	 * Using in a method:
-	 * {{{
-	 * 	public function index() {
-	 * 		extract(Message::aliases());
-	 * 		$notice = $t('look');
-	 * 	}
-	 * }}}
-	 *
-	 * @see lithium\net\http\Media::_handle()
-	 * @return array Named aliases (`'t'` and `'tn'`) for translation functions.
-	 */
-	public static function aliases() {
-		$t = function($message, array $options = array()) {
-			return Message::translate($message, $options + array('default' => $message));
-		};
-		$tn = function($message1, $message2, $count, array $options = array()) {
-			return Message::translate($message1, $options + compact('count') + array(
-				'default' => $count == 1 ? $message1 : $message2
-			));
-		};
-		return compact('t', 'tn');
-	}
-
-	/**
-	 * Returns or sets the page cache used for mapping message ids to translations.
-	 *
-	 * @param array $cache A multidimensional array to use when pre-populating the cache. The
-	 *              structure of the array is `scope/locale/id`. If `false`, the cache is cleared.
-	 * @return array Returns an array of cached pages, formatted per the description for `$cache`.
-	 */
-	public static function cache($cache = null) {
-		if ($cache === false) {
-			static::$_cachedPages = array();
-		}
-		if (is_array($cache)) {
-			static::$_cachedPages += $cache;
-		}
-		return static::$_cachedPages;
-	}
-
-	/**
-	 * Retrieves translations through the `Catalog` class by using `$id` as the lookup
-	 * key and taking the current or - if specified - the provided locale as well as the
-	 * scope into account.  Hereupon the correct plural form is determined by passing the
-	 * value of the `'count'` option to a closure.
-	 *
-	 * @see lithium\g11n\Catalog
-	 * @param string $id The lookup key.
-	 * @param integer $count Used to determine the correct plural form.
-	 * @param string $locale The target locale.
-	 * @param array $options Passed through to `Catalog::read()`. Valid options are:
-	 *              - `'scope'`: The scope of the message.
-	 * @return string The translation or `null` if none could be found or the plural
-	 *         form could not be determined.
-	 * @filter
-	 */
-	protected static function _translated($id, $count, $locale, array $options = array()) {
-		$params = compact('id', 'count', 'locale', 'options');
-
-		$cache =& static::$_cachedPages;
-		return static::_filter(__FUNCTION__, $params, function($self, $params) use (&$cache) {
-			extract($params);
-
-			if (!isset($cache[$options['scope']][$locale])) {
-				$cache[$options['scope']][$locale] = Catalog::read(
-					true, 'message', $locale, $options
-				);
-			}
-			$page = $cache[$options['scope']][$locale];
-
-			if (!isset($page[$id])) {
-				return null;
-			}
-			if (!is_array($page[$id])) {
-				return $page[$id];
-			}
-
-			if (!isset($page['pluralRule']) || !is_callable($page['pluralRule'])) {
-				return null;
-			}
-			$key = $page['pluralRule']($count);
-
-			if (isset($page[$id][$key])) {
-				return $page[$id][$key];
-			}
-		});
-	}
-}
-
-?>

+ 0 - 168
frameworks/PHP/php-lithium/libraries/lithium/g11n/Multibyte.php

@@ -1,168 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-namespace lithium\g11n;
-use lithium\core\Libraries;
-
-/**
- * The `Multibyte` class helps operating with UTF-8 encoded strings. Here
- * multibyte is synonymous to UTF-8 which is probably the most widespread
- * multibyte encoding in recent web application development.
- *
- * Over time - as the importance of multibyte encoding support grew - a variety
- * of extensions appeared. While each achieves its goal somewhat differently
- * and might be preferred over the other, they still all do that one thing.
- *
- * What can a framework provide, those extensions aren't? It can provide
- * abstractions that allow portable code. While this might not be a requirement
- * for application code, it's a definite must for the framework's core code.
- *
- * As previously mentioned extensions appeared in a semi-evolutionary way. This
- * leaves us with the situation where extensions are heterogeneously spread out
- * over environments. There certainly is no clear winner and we're left with
- * the situation of "supporting them all".
- *
- * Technically this class does very little in terms of abstraction. Its main
- * purpose is to allow adapting to changing environments: virtually creating
- * something you can rely on, something that's always there while it actually
- * is there only in one way or the other. And - yes - some convenience methods
- * are also on board.
- */
-class Multibyte extends \lithium\core\Adaptable {
-
-	/**
-	 * Contains adapter configurations for `Multibyte` adapters.
-	 *
-	 * @var array
-	 */
-	protected static $_configurations = array();
-
-	/**
-	 * `Libraries::locate()`-compatible path to adapters for this class.
-	 *
-	 * @see lithium\core\Libraries::locate()
-	 * @var string Dot-delimited path.
-	 */
-	protected static $_adapters = 'adapter.g11n.multibyte';
-
-	/**
-	 * Checks if a given string is UTF-8 encoded and is valid UTF-8.
-	 *
-	 * In _quick_ mode it will check only for non ASCII characters being used
-	 * indicating any multibyte encoding. Don't use quick mode for integrity
-	 * validation of UTF-8 encoded strings.
-	 *
-	 * @link http://www.w3.org/International/questions/qa-forms-utf-8.en
-	 * @param string $string The string to analyze.
-	 * @param array $options Allows to toggle mode via the `'quick'` option, defaults to `false`.
-	 * @return boolean Returns `true` if the string is UTF-8.
-	 */
-	public static function is($string, array $options = array()) {
-		$defaults = array('quick' => false);
-		$options += $defaults;
-
-		if ($options['quick']) {
-			$regex = '/[^\x09\x0A\x0D\x20-\x7E]/m';
-		} else {
-			$regex  = '/\A(';
-			$regex .= '[\x09\x0A\x0D\x20-\x7E]';            // ASCII
-			$regex .= '|[\xC2-\xDF][\x80-\xBF]';            // non-overlong 2-byte
-			$regex .= '|\xE0[\xA0-\xBF][\x80-\xBF]';        // excluding overlongs
-			$regex .= '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}'; // straight 3-byte
-			$regex .= '|\xED[\x80-\x9F][\x80-\xBF]';        // excluding surrogates
-			$regex .= '|\xF0[\x90-\xBF][\x80-\xBF]{2}';     // planes 1-3
-			$regex .= '|[\xF1-\xF3][\x80-\xBF]{3}';         // planes 4-15
-			$regex .= '|\xF4[\x80-\x8F][\x80-\xBF]{2}';     // plane 16
-			$regex .= ')*\z/m';
-		}
-		return (boolean) preg_match($regex, $string);
-	}
-
-	/**
-	 * Gets the string length. Multibyte enabled version of `strlen()`.
-	 *
-	 * @link http://php.net/manual/en/function.strlen.php
-	 * @param string $string The string being measured for length.
-	 * @param array $options Allows for selecting the adapter to use via the
-	 *               `name` options. Will use the `'default'` adapter by default.
-	 * @return integer The length of the string on success.
-	 */
-	public static function strlen($string, array $options = array()) {
-		$defaults = array('name' => 'default');
-		$options += $defaults;
-		return static::adapter($options['name'])->strlen($string);
-	}
-
-	/**
-	 * Finds the position of the _first_ occurrence of a string within a string.
-	 * Multibyte enabled version of `strpos()`.
-	 *
-	 * Not all adapters must support interpreting - thus applying - passed
-	 * numeric values as ordinal values of a character.
-	 *
-	 * @link http://php.net/manual/en/function.strpos.php
-	 * @param string $haystack The string being checked.
-	 * @param string $needle The string to find in the haystack.
-	 * @param integer $offset If specified, search will start this number of
-	 *                characters counted from the beginning of the string. The
-	 *                offset cannot be negative.
-	 * @param array $options Allows for selecting the adapter to use via the
-	 *               `name` options. Will use the `'default'` adapter by default.
-	 * @return integer Returns the numeric position of the first occurrence of
-	 *                 the needle in the haystack string. If needle is not found,
-	 *                 it returns `false`.
-	 */
-	public static function strpos($haystack, $needle, $offset = 0, array $options = array()) {
-		$defaults = array('name' => 'default');
-		$options += $defaults;
-		return static::adapter($options['name'])->strpos($haystack, $needle, $offset);
-	}
-
-	/**
-	 * Finds the position of the _last_ occurrence of a string within a string.
-	 * Multibyte enabled version of `strrpos()`.
-	 *
-	 * Not all adapters must support interpreting - thus applying - passed
-	 * numeric values as ordinal values of a character. The `Iconv` adapter
-	 * doesn't support an offset as `strpos()` does - this constitutes the
-	 * lowest common denominator here.
-	 *
-	 * @link http://php.net/manual/en/function.strrpos.php
-	 * @param string $haystack The string being checked.
-	 * @param string $needle The string to find in the haystack.
-	 * @param array $options Allows for selecting the adapter to use via the
-	 *               `name` options. Will use the `'default'` adapter by default.
-	 * @return integer Returns the numeric position of the last occurrence of
-	 *                 the needle in the haystack string. If needle is not found,
-	 *                 it returns `false`.
-	 */
-	public static function strrpos($haystack, $needle, array $options = array()) {
-		$defaults = array('name' => 'default');
-		$options += $defaults;
-		return static::adapter($options['name'])->strrpos($haystack, $needle);
-	}
-
-	/**
-	 * Returns the portion of string specified by the start and length parameters.
-	 * Multibyte enabled version of `substr()`.
-	 *
-	 * @link http://php.net/manual/en/function.substr.php
-	 * @param string $string The string to extract the substring from.
-	 * @param integer $start Position of first character in string (offset).
-	 * @param integer $length Maximum numbers of characters to use from string.
-	 * @param array $options Allows for selecting the adapter to use via the
-	 *               `name` options. Will use the `'default'` adapter by default.
-	 * @return string The substring extracted from given string.
-	 */
-	public static function substr($string, $start, $length = null, array $options = array()) {
-		$defaults = array('name' => 'default');
-		$options += $defaults;
-		return static::adapter($options['name'])->substr($string, $start, $length);
-	}
-}
-
-?>

+ 0 - 102
frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/Adapter.php

@@ -1,102 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\catalog;
-
-/**
- * This is the foundation class for all g11n catalog adapters.
- */
-class Adapter extends \lithium\core\Object {
-
-	/**
-	 * Reads data.
-	 *
-	 * Override this method in subclasses if you want the adapter
-	 * to have read support. The method is expected to return `null`
-	 * if the passed category is not supported.
-	 *
-	 * @param string $category A category.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @return null This currently does nothing.
-	 */
-	public function read($category, $locale, $scope) {
-		return null;
-	}
-
-	/**
-	 * Writes data.
-	 *
-	 * Override this method in subclasses if you want the adapter
-	 * to have write support. The method is expected to return `false`
-	 * if the passed category is not supported.
-	 *
-	 * Please note that existing data is silently overwritten.
-	 *
-	 * @param string $category A category.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @param array $data The data to write.
-	 * @return false This currently does nothing.
-	 */
-	public function write($category, $locale, $scope, array $data) {
-		return false;
-	}
-
-	/**
-	 * Prepares an item before it is being written.
-	 *
-	 * Override this method in sublcasses if you need to
-	 * i.e. escape the item's values.
-	 *
-	 * @param array $item
-	 * @return array
-	 */
-	protected function _prepareForWrite(array $item) {
-		return $item;
-	}
-
-	/**
-	 * Merges an item into given data.
-	 *
-	 * @param array $data Data to merge item into.
-	 * @param array $item Item to merge into $data. The item must have an `'id'` key.
-	 * @return array The merged data.
-	 */
-	protected function _merge(array $data, array $item) {
-		if (!isset($item['id'])) {
-			return $data;
-		}
-		$id = $item['id'];
-
-		$defaults = array(
-			'ids' => array(),
-			'translated' => null,
-			'flags' => array(),
-			'comments' => array(),
-			'occurrences' => array()
-		);
-		$item += $defaults;
-
-		if (!isset($data[$id])) {
-			$data[$id] = $item;
-			return $data;
-		}
-		foreach (array('ids', 'flags', 'comments', 'occurrences') as $field) {
-			$data[$id][$field] = array_merge($data[$id][$field], $item[$field]);
-		}
-		if (!isset($data[$id]['translated'])) {
-			$data[$id]['translated'] = $item['translated'];
-		} elseif (is_array($item['translated'])) {
-			$data[$id]['translated'] = (array) $data[$id]['translated'] + $item['translated'];
-		}
-		return $data;
-	}
-}
-
-?>

+ 0 - 191
frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Code.php

@@ -1,191 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\catalog\adapter;
-
-use RecursiveIteratorIterator;
-use RecursiveDirectoryIterator;
-use lithium\core\ConfigException;
-use lithium\template\view\Compiler;
-
-/**
- * The `Code` class is an adapter which treats files containing code as just another source
- * of globalized data.
- *
- * In fact it allows for extracting messages which are needed to build
- * message catalog templates. Currently only code written in PHP is supported through a parser
- * using the built-in tokenizer.
- *
- * @see lithium\g11n\Message
- * @see lithium\template\View
- */
-class Code extends \lithium\g11n\catalog\Adapter {
-
-	/**
-	 * Constructor.
-	 *
-	 * @param array $config Available configuration options are:
-	 *        - `'path'`: The path to the directory holding the data.
-	 *        - `'scope'`: Scope to use.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('path' => null, 'scope' => null);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Initializer.  Checks if the configured path exists.
-	 *
-	 * @return void
-	 * @throws \Exception
-	 */
-	protected function _init() {
-		parent::_init();
-		if (!is_dir($this->_config['path'])) {
-			$message = "Code directory does not exist at path `{$this->_config['path']}`.";
-			throw new ConfigException($message);
-		}
-	}
-
-	/**
-	 * Reads data.
-	 *
-	 * @param string $category A category. `'messageTemplate'` is the only category supported.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @return array Returns the message template. If the scope is not equal to the current scope
-	 * or `$category` is not `'messageTemplate'` null is returned.
-	 */
-	public function read($category, $locale, $scope) {
-		if ($scope !== $this->_config['scope']) {
-			return null;
-		}
-		$path = $this->_config['path'];
-
-		switch ($category) {
-			case 'messageTemplate':
-				return $this->_readMessageTemplate($path);
-			default:
-				return null;
-		}
-	}
-
-	/**
-	 * Extracts data from files within configured path recursively.
-	 *
-	 * @param string $path Base path to start extracting from.
-	 * @return array
-	 */
-	protected function _readMessageTemplate($path) {
-		$base = new RecursiveDirectoryIterator($path);
-		$iterator = new RecursiveIteratorIterator($base);
-		$data = array();
-
-		foreach ($iterator as $item) {
-			$file = $item->getPathname();
-
-			switch (pathinfo($file, PATHINFO_EXTENSION)) {
-				case 'php':
-					$data += $this->_parsePhp($file);
-				break;
-			}
-		}
-		return $data;
-	}
-
-	/**
-	 * Parses a PHP file for messages marked as translatable.  Recognized as message
-	 * marking are `$t()` and `$tn()` which are implemented in the `View` class. This
-	 * is a rather simple and stupid parser but also fast and easy to grasp. It doesn't
-	 * actively attempt to detect and work around syntax errors in marker functions.
-	 *
-	 * @see lithium\g11n\Message::aliases()
-	 * @param string $file Absolute path to a PHP file.
-	 * @return array
-	 */
-	protected function _parsePhp($file) {
-		$contents = file_get_contents($file);
-		$contents = Compiler::compile($contents);
-
-		$defaults = array(
-			'ids' => array(),
-			'open' => false,
-			'position' => 0,
-			'occurrence' => array('file' => $file, 'line' => null)
-		);
-		extract($defaults);
-		$data = array();
-
-		if (strpos($contents, '$t(') === false && strpos($contents, '$tn(') === false) {
-			return $data;
-		}
-
-		$tokens = token_get_all($contents);
-		unset($contents);
-
-		foreach ($tokens as $key => $token) {
-			if (!is_array($token)) {
-				$token = array(0 => null, 1 => $token, 2 => null);
-			}
-
-			if ($open) {
-				if ($position >= ($open === 'singular' ? 1 : 2)) {
-					$data = $this->_merge($data, array(
-						'id' => $ids['singular'],
-						'ids' => $ids,
-						'occurrences' => array($occurrence)
-					));
-					extract($defaults, EXTR_OVERWRITE);
-				} elseif ($token[0] === T_CONSTANT_ENCAPSED_STRING) {
-					$ids[$ids ? 'plural' : 'singular'] = $token[1];
-					$position++;
-				}
-			} else {
-				if (isset($tokens[$key + 1]) && $tokens[$key + 1] === '(') {
-					if ($token[1] === '$t') {
-						$open = 'singular';
-					} elseif ($token[1] === '$tn') {
-						$open = 'plural';
-					} else {
-						continue;
-					}
-					$occurrence['line'] = $token[2];
-				}
-			}
-		}
-		return $data;
-	}
-
-	/**
-	 * Merges an item into given data and removes quotation marks
-	 * from the beginning and end of message strings.
-	 *
-	 * @see lithium\g11n\catalog\Adapter::_merge()
-	 * @param array $data Data to merge item into.
-	 * @param array $item Item to merge into $data.
-	 * @return array The merged data.
-	 */
-	protected function _merge(array $data, array $item) {
-		$filter = function ($value) use (&$filter) {
-			if (is_array($value)) {
-				return array_map($filter, $value);
-			}
-			return substr($value, 1, -1);
-		};
-		$fields = array('id', 'ids', 'translated');
-
-		foreach ($fields as $field) {
-			if (isset($item[$field])) {
-				$item[$field] = $filter($item[$field]);
-			}
-		}
-		return parent::_merge($data, $item);
-	}
-}
-
-?>

+ 0 - 519
frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Gettext.php

@@ -1,519 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\catalog\adapter;
-
-use RangeException;
-use lithium\core\ConfigException;
-
-/**
- * The `Gettext` class is an adapter for reading and writing PO and MO files without the
- * requirement of having the gettext extension enabled or installed. Moreover it doesn't
- * require the usage of the non thread safe `setlocale()`.
- *
- * The adapter works with the directory structure below. The example shows the structure
- * for the directory as given by the `'path'` configuration setting. It closely ressembles
- * the standard gettext directory structure with a few slight adjustments to the way
- * templates are being named.
- *
- * {{{
- * resources/g11n/po
- * ├── <locale>
- * |   ├── LC_MESSAGES
- * |   |   ├── default.po
- * |   |   ├── default.mo
- * |   |   ├── <scope>.po
- * |   |   └── <scope>.mo
- * |   ├── LC_VALIDATION
- * |   |   └── ...
- * |   └── ...
- * ├── <locale>
- * |   └── ...
- * ├── message_default.pot
- * ├── message_<scope>.pot
- * ├── validation_default.pot
- * ├── validation_<scope>.pot
- * └── ...
- * }}}
- *
- * @see lithium\g11n\Locale
- * @link http://php.net/setlocale PHP Manual: setlocale()
- * @link http://www.gnu.org/software/gettext/manual/gettext.html GNU Gettext Utilities
- */
-class Gettext extends \lithium\g11n\catalog\Adapter {
-
-	/**
-	 * Magic used for validating the format of a MO file as well as
-	 * detecting if the machine used to create that file was little endian.
-	 *
-	 * @see lithium\g11n\catalog\adapter\Gettext::_parseMo()
-	 * @var float
-	 */
-	const MO_LITTLE_ENDIAN_MAGIC = 0x950412de;
-
-	/**
-	 * Magic used for validating the format of a MO file as well as
-	 * detecting if the machine used to create that file was big endian.
-	 *
-	 * @see lithium\g11n\catalog\adapter\Gettext::_parseMo()
-	 * @var float
-	 */
-	const MO_BIG_ENDIAN_MAGIC = 0xde120495;
-
-	/**
-	 * The size of the header of a MO file in bytes.
-	 *
-	 * @see lithium\g11n\catalog\adapter\Gettext::_parseMo()
-	 * @var integer Number of bytes.
-	 */
-	const MO_HEADER_SIZE = 28;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param array $config Available configuration options are:
-	 *        - `'path'`: The path to the directory holding the data.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('path' => null);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Initializer.  Checks if the configured path exists.
-	 *
-	 * @return void
-	 * @throws ConfigException
-	 */
-	protected function _init() {
-		parent::_init();
-		if (!is_dir($this->_config['path'])) {
-			$message = "Gettext directory does not exist at path `{$this->_config['path']}`.";
-			throw new ConfigException($message);
-		}
-	}
-
-	/**
-	 * Reads data.
-	 *
-	 * @param string $category A category.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @return array
-	 */
-	public function read($category, $locale, $scope) {
-		$files = $this->_files($category, $locale, $scope);
-
-		foreach ($files as $file) {
-			$method = '_parse' . ucfirst(pathinfo($file, PATHINFO_EXTENSION));
-
-			if (!file_exists($file) || !is_readable($file)) {
-				continue;
-			}
-			$stream = fopen($file, 'rb');
-			$data = $this->invokeMethod($method, array($stream));
-			fclose($stream);
-
-			if ($data) {
-				$data['pluralRule'] = array(
-					'id' => 'pluralRule',
-					'translated' => function($count) {
-						return $count !== 1;
-					}
-				);
-				return $data;
-			}
-		}
-	}
-
-	/**
-	 * Writes data.
-	 *
-	 * @param string $category A category.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @param array $data The data to write.
-	 * @return boolean
-	 */
-	public function write($category, $locale, $scope, array $data) {
-		$files = $this->_files($category, $locale, $scope);
-
-		foreach ($files as $file) {
-			$method = '_compile' . ucfirst(pathinfo($file, PATHINFO_EXTENSION));
-
-			if (!$stream = fopen($file, 'wb')) {
-				return false;
-			}
-			$this->invokeMethod($method, array($stream, $data));
-			fclose($stream);
-		}
-		return true;
-	}
-
-	/**
-	 * Returns absolute paths to files according to configuration.
-	 *
-	 * @param string $category
-	 * @param string $locale
-	 * @param string $scope
-	 * @return array
-	 */
-	protected function _files($category, $locale, $scope) {
-		$path = $this->_config['path'];
-		$scope = $scope ?: 'default';
-
-		if (($pos = strpos($category, 'Template')) !== false) {
-			$category = substr($category, 0, $pos);
-			return array("{$path}/{$category}_{$scope}.pot");
-		}
-
-		if ($category === 'message') {
-			$category = 'messages';
-		}
-		$category = strtoupper($category);
-
-		return array(
-			"{$path}/{$locale}/LC_{$category}/{$scope}.mo",
-			"{$path}/{$locale}/LC_{$category}/{$scope}.po"
-		);
-	}
-
-	/**
-	 * Parses portable object (PO) format.
-	 *
-	 * This parser sacrifices some features of the reference implementation the
-	 * differences to that implementation are as follows.
-	 * - No support for comments spanning multiple lines.
-	 * - Translator and extracted comments are treated as being the same type.
-	 * - Message IDs are allowed to have other encodings as just US-ASCII.
-	 *
-	 * Items with an empty id are ignored. For more information see `_merge()`.
-	 *
-	 * @param resource $stream
-	 * @return array
-	 */
-	protected function _parsePo($stream) {
-		$defaults = array(
-			'ids' => array(),
-			'translated' => null,
-			'flags' => array(),
-			'comments' => array(),
-			'occurrences' => array()
-		);
-		$data = array();
-		$item = $defaults;
-
-		while ($line = fgets($stream)) {
-			$line = trim($line);
-
-			if ($line === '') {
-				$data = $this->_merge($data, $item);
-				$item = $defaults;
-			} elseif (substr($line, 0, 3) === '#~ ') {
-				$item['flags']['obsolete'] = true;
-			} elseif (substr($line, 0, 3) === '#, ') {
-				$item['flags'][substr($line, 3)] = true;
-			} elseif (substr($line, 0, 3) === '#: ') {
-				$item['occurrences'][] = array(
-					'file' => strtok(substr($line, 3), ':'),
-					'line' => strtok(':')
-				);
-			} elseif (substr($line, 0, 3) === '#. ') {
-				$item['comments'][] = substr($line, 3);
-			} elseif ($line[0] === '#') {
-				$item['comments'][] = ltrim(substr($line, 1));
-			} elseif (substr($line, 0, 7) === 'msgid "') {
-				$item['ids']['singular'] = substr($line, 7, -1);
-			} elseif (substr($line, 0, 9) === 'msgctxt "') {
-				$item['context'] = substr($line, 9, -1);
-			} elseif (substr($line, 0, 8) === 'msgstr "') {
-				$item['translated'] = substr($line, 8, -1);
-			} elseif ($line[0] === '"') {
-				$continues = isset($item['translated']) ? 'translated' : 'ids';
-
-				if (is_array($item[$continues])) {
-					end($item[$continues]);
-					$item[$continues][key($item[$continues])] .= substr($line, 1, -1);
-				} else {
-					$item[$continues] .= substr($line, 1, -1);
-				}
-			} elseif (substr($line, 0, 14) === 'msgid_plural "') {
-				$item['ids']['plural'] = substr($line, 14, -1);
-			} elseif (substr($line, 0, 7) === 'msgstr[') {
-				$item['translated'][(integer) substr($line, 7, 1)] = substr($line, 11, -1);
-			}
-		}
-		return $this->_merge($data, $item);
-	}
-
-	/**
-	 * Parses portable object template (POT) format.
-	 *
-	 * @param resource $stream
-	 * @return array
-	 */
-	protected function _parsePot($stream) {
-		return $this->_parsePo($stream);
-	}
-
-	/**
-	 * Parses machine object (MO) format, independent of the machine's endian it
-	 * was created on. Both 32bit and 64bit systems are supported.
-	 *
-	 * @param resource $stream
-	 * @return array
-	 * @throws RangeException If stream content has an invalid format.
-	 */
-	protected function _parseMo($stream) {
-		$stat = fstat($stream);
-
-		if ($stat['size'] < self::MO_HEADER_SIZE) {
-			throw new RangeException("MO stream content has an invalid format.");
-		}
-		$magic = unpack('V1', fread($stream, 4));
-		$magic = hexdec(substr(dechex(current($magic)), -8));
-
-		if ($magic == self::MO_LITTLE_ENDIAN_MAGIC) {
-			$isBigEndian = false;
-		} elseif ($magic == self::MO_BIG_ENDIAN_MAGIC) {
-			$isBigEndian = true;
-		} else {
-			throw new RangeException("MO stream content has an invalid format.");
-		}
-
-		$header = array(
-			'formatRevision' => null,
-			'count' => null,
-			'offsetId' => null,
-			'offsetTranslated' => null,
-			'sizeHashes' => null,
-			'offsetHashes' => null
-		);
-		foreach ($header as &$value) {
-			$value = $this->_readLong($stream, $isBigEndian);
-		}
-		extract($header);
-		$data = array();
-
-		for ($i = 0; $i < $count; $i++) {
-			$singularId = $pluralId = null;
-			$translated = null;
-
-			fseek($stream, $offsetId + $i * 8);
-
-			$length = $this->_readLong($stream, $isBigEndian);
-			$offset = $this->_readLong($stream, $isBigEndian);
-
-			if ($length < 1) {
-				continue;
-			}
-
-			fseek($stream, $offset);
-			$singularId = fread($stream, $length);
-
-			if (strpos($singularId, "\000") !== false) {
-				list($singularId, $pluralId) = explode("\000", $singularId);
-			}
-
-			fseek($stream, $offsetTranslated + $i * 8);
-			$length = $this->_readLong($stream, $isBigEndian);
-			$offset = $this->_readLong($stream, $isBigEndian);
-
-			fseek($stream, $offset);
-			$translated = fread($stream, $length);
-
-			if (strpos($translated, "\000") !== false) {
-				$translated = explode("\000", $translated);
-			}
-
-			$ids = array('singular' => $singularId, 'plural' => $pluralId);
-			$data = $this->_merge($data, compact('ids', 'translated'));
-		}
-		return $data;
-	}
-
-	/**
-	 * Reads an unsigned long from stream respecting endianess.
-	 *
-	 * @param resource $stream
-	 * @param boolean $isBigEndian
-	 * @return integer
-	 */
-	protected function _readLong($stream, $isBigEndian) {
-		$result = unpack($isBigEndian ? 'N1' : 'V1', fread($stream, 4));
-		$result = current($result);
-		return (integer) substr($result, -8);
-	}
-
-	/**
-	 * Compiles data into portable object (PO) format.
-	 *
-	 * To improve portability accross libraries the header is generated according
-	 * to the format of the output of `xgettext`. This means using the same names for
-	 * placeholders as well as including an empty entry. The empty entry at the
-	 * beginning aids in parsing the file as it _attracts_ the preceding comments and
-	 * following metadata when parsed which could otherwise be mistaken as a continued
-	 * translation. The only difference in the header format is the initial header which
-	 * just features one line of text.
-	 *
-	 * @param resource $stream
-	 * @param array $data
-	 * @return boolean
-	 */
-	protected function _compilePo($stream, array $data) {
-		$output[] = '# This file is distributed under the same license as the PACKAGE package.';
-		$output[] = '#';
-		$output[] = 'msgid ""';
-		$output[] = 'msgstr ""';
-		$output[] = '"Project-Id-Version: PACKAGE VERSION\n"';
-		$output[] = '"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"';
-		$output[] = '"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"';
-		$output[] = '"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"';
-		$output[] = '"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"';
-		$output[] = '"MIME-Version: 1.0\n"';
-		$output[] = '"Content-Type: text/plain; charset=UTF-8\n"';
-		$output[] = '"Content-Transfer-Encoding: 8bit\n"';
-		$output[] = '"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"';
-		$output[] = '';
-		$output = implode("\n", $output) . "\n";
-		fwrite($stream, $output);
-
-		foreach ($data as $key => $item) {
-			$output = array();
-			$item = $this->_prepareForWrite($item);
-
-			foreach ($item['occurrences'] as $occurrence) {
-				$output[] = "#: {$occurrence['file']}:{$occurrence['line']}";
-			}
-			foreach ($item['comments'] as $comment) {
-				$output[] = "#. {$comment}";
-			}
-			foreach ($item['flags'] as $flag => $value) {
-				$output[] = "#, {$flag}";
-			}
-			$output[] = "msgid \"{$item['ids']['singular']}\"";
-
-			if (isset($item['ids']['plural'])) {
-				$output[] = "msgid_plural \"{$item['ids']['plural']}\"";
-
-				foreach ((array) $item['translated'] ?: array(null, null) as $key => $value) {
-					$output[] = "msgstr[{$key}] \"{$value}\"";
-				}
-			} else {
-				if (is_array($item['translated'])) {
-					$item['translated'] = array_pop($item['translated']);
-				}
-				$output[] = "msgstr \"{$item['translated']}\"";
-			}
-			$output[] = '';
-			$output = implode("\n", $output) . "\n";
-			fwrite($stream, $output);
-		}
-		return true;
-	}
-
-	/**
-	 * Compiles data into portable object template (POT) format.
-	 *
-	 * @param resource $stream
-	 * @param array $data
-	 * @return boolean Success.
-	 */
-	protected function _compilePot($stream, array $data) {
-		return $this->_compilePo($stream, $data);
-	}
-
-	/**
-	 * Compiles data into machine object (MO) format.
-	 *
-	 * @param resource $stream
-	 * @param array $data
-	 * @return void
-	 * @todo Determine if needed and implement compiler.
-	 */
-	protected function _compileMo($stream, array $data) {}
-
-	/**
-	 * Prepares an item before it is being written and escapes fields.
-	 *
-	 * All characters from \000 to \037 (this includes new line and tab characters)
-	 * as well as the backslash (`\`) and the double quote (`"`) are escaped.
-	 *
-	 * Literal Windows CRLFs (`\r\n`) are converted to LFs (`\n`) to improve cross platform
-	 * compatibility. Escaped single quotes (`'`) are unescaped as they should not need to be.
-	 * Double escaped characters are maintained and not escaped once again.
-	 *
-	 * @link http://www.asciitable.com
-	 * @see lithium\g11n\catalog\Adapter::_prepareForWrite()
-	 * @param array $item
-	 * @return array
-	 */
-	protected function _prepareForWrite(array $item) {
-		$filter = function ($value) use (&$filter) {
-			if (is_array($value)) {
-				return array_map($filter, $value);
-			}
-			$value = strtr($value, array("\\'" => "'", "\\\\" => "\\", "\r\n" => "\n"));
-			$value = addcslashes($value, "\0..\37\\\"");
-			return $value;
-		};
-		$fields = array('id', 'ids', 'translated');
-
-		foreach ($fields as $field) {
-			if (isset($item[$field])) {
-				$item[$field] = $filter($item[$field]);
-			}
-		}
-		if (!isset($item['ids']['singular'])) {
-			$item['ids']['singular'] = $item['id'];
-		}
-		if (isset($item['occurrences'])) {
-			foreach ($item['occurrences'] as &$occurrence) {
-				$occurrence['file'] = str_replace(LITHIUM_APP_PATH, '', $occurrence['file']);
-			}
-		}
-		return parent::_prepareForWrite($item);
-	}
-
-	/**
-	 * Merges an item into given data and unescapes fields.
-	 *
-	 * Please note that items with an id containing exclusively whitespace characters
-	 * or are empty are **not** being merged. Whitespace characters are space, tab, vertical
-	 * tab, line feed, carriage return and form feed.
-	 *
-	 * @see lithium\g11n\catalog\Adapter::_merge()
-	 * @param array $data Data to merge item into.
-	 * @param array $item Item to merge into $data.
-	 * @return array The merged data.
-	 */
-	protected function _merge(array $data, array $item) {
-		$filter = function ($value) use (&$filter) {
-			if (is_array($value)) {
-				return array_map($filter, $value);
-			}
-			return stripcslashes($value);
-		};
-		$fields = array('id', 'ids', 'translated');
-
-		foreach ($fields as $field) {
-			if (isset($item[$field])) {
-				$item[$field] = $filter($item[$field]);
-			}
-		}
-		if (isset($item['ids']['singular'])) {
-			$item['id'] = $item['ids']['singular'];
-		}
-		if (empty($item['id']) || ctype_space($item['id'])) {
-			return $data;
-		}
-		return parent::_merge($data, $item);
-	}
-}
-
-?>

+ 0 - 67
frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Memory.php

@@ -1,67 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\catalog\adapter;
-
-/**
- * The `Memory` class is an adapter for reading and writing data during runtime.
- *
- * Written data is stored in memory and lost after the end of the script execution. The
- * adapter is also very useful for testing.
- */
-class Memory extends \lithium\g11n\catalog\Adapter {
-
-	/**
-	 * Holds data during runtime.
-	 *
-	 * @var array
-	 */
-	protected $_data = array();
-
-	/**
-	 * Reads data.
-	 *
-	 * @param string $category A category.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @return array
-	 */
-	public function read($category, $locale, $scope) {
-		$scope = $scope ?: 'default';
-
-		if (isset($this->_data[$scope][$category][$locale])) {
-			return $this->_data[$scope][$category][$locale];
-		}
-	}
-
-	/**
-	 * Writes data.
-	 *
-	 * @param string $category A category.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @param array $data The data to write.
-	 * @return boolean
-	 */
-	public function write($category, $locale, $scope, array $data) {
-		$scope = $scope ?: 'default';
-
-		if (!isset($this->_data[$scope][$category][$locale])) {
-			$this->_data[$scope][$category][$locale] = array();
-		}
-		foreach ($data as $item) {
-			$this->_data[$scope][$category][$locale] = $this->_merge(
-				$this->_data[$scope][$category][$locale],
-				$this->_prepareForWrite($item)
-			);
-		}
-		return true;
-	}
-}
-
-?>

+ 0 - 121
frameworks/PHP/php-lithium/libraries/lithium/g11n/catalog/adapter/Php.php

@@ -1,121 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\catalog\adapter;
-
-use lithium\core\ConfigException;
-
-/**
- * The `Php` class is an adapter for reading from PHP files which hold g11n data
- * in form of arrays.
- *
- * An example PHP file must contain a `return` statement which returns an array if the
- * the file is included.
- *
- * {{{
- * <?php
- * return array(
- * 	'postalCode' => '\d+',
- * 	'phone' => '\d+\-\d+'
- * );
- * ?>
- * }}}
- *
- * The adapter works with a directory structure below. The example shows the structure
- * for the directory as given by the `'path'` configuration setting. It is similar to
- * the one used by the the `Gettext` adapter.
- *
- * {{{
- * resources/g11n/php
- * ├── <locale>
- * |   ├── message
- * |   |   ├── default.php
- * |   |   └── <scope>.php
- * |   ├── validation
- * |   |   └── ...
- * |   └── ...
- * ├── <locale>
- * |   └── ...
- * ├── message_default.php
- * ├── message_<scope>.php
- * ├── validation_default.php
- * ├── validation_<scope>.php
- * └── ...
- * }}}
- *
- * @see lithium\g11n\catalog\adapter\Gettext
- */
-class Php extends \lithium\g11n\catalog\Adapter {
-
-	/**
-	 * Constructor.
-	 *
-	 * @param array $config Available configuration options are:
-	 *        - `'path'`: The path to the directory holding the data.
-	 */
-	public function __construct(array $config = array()) {
-		$defaults = array('path' => null);
-		parent::__construct($config + $defaults);
-	}
-
-	/**
-	 * Initializer.  Checks if the configured path exists.
-	 *
-	 * @return void
-	 * @throws \Exception
-	 */
-	protected function _init() {
-		parent::_init();
-		if (!is_dir($this->_config['path'])) {
-			$message = "Php directory does not exist at path `{$this->_config['path']}`.";
-			throw new ConfigException($message);
-		}
-	}
-
-	/**
-	 * Reads data.
-	 *
-	 * @param string $category A category.
-	 * @param string $locale A locale identifier.
-	 * @param string $scope The scope for the current operation.
-	 * @return array
-	 */
-	public function read($category, $locale, $scope) {
-		$path = $this->_config['path'];
-		$file = $this->_file($category, $locale, $scope);
-		$data = array();
-
-		if (file_exists($file)) {
-			foreach (require $file as $id => $translated) {
-				$data = $this->_merge($data, compact('id', 'translated'));
-			}
-		}
-		return $data;
-	}
-
-	/**
-	 * Helper method for transforming a category, locale and scope into a filename.
-	 *
-	 * @param string $category Category name.
-	 * @param string $locale Locale identifier.
-	 * @param string $scope Current operation scope.
-	 * @return string Filename.
-	 */
-	protected function _file($category, $locale, $scope) {
-		$path = $this->_config['path'];
-		$scope = $scope ?: 'default';
-
-		if (($pos = strpos($category, 'Template')) !== false) {
-			$category = substr($category, 0, $pos);
-			return "{$path}/{$category}_{$scope}.php";
-		}
-		return "{$path}/{$locale}/{$category}/{$scope}.php";
-	}
-}
-
-?>

+ 0 - 81
frameworks/PHP/php-lithium/libraries/lithium/g11n/multibyte/adapter/Iconv.php

@@ -1,81 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\multibyte\adapter;
-
-/**
- * The `Iconv` class is an adapter which uses certain string functions from
- * `ext/iconv`. You will need to have the extension installed to use this adapter.
- *
- * No known limitations affecting used functionality. Returns `false` when
- * seeing badly formed UTF-8 sequences. Additionally triggers an error.
- *
- * @link http://php.net/manual/en/book.iconv.php
- */
-class Iconv extends \lithium\core\Object {
-
-	/**
-	 * Determines if this adapter is enabled by checking if the `iconv` extension is loaded.
-	 *
-	 * @return boolean Returns `true` if enabled, otherwise `false`.
-	 */
-	public static function enabled() {
-		return extension_loaded('iconv');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strlen()`.
-	 *
-	 * @link http://php.net/manual/en/function.iconv-strlen.php
-	 * @param string $string
-	 * @return integer|boolean
-	 */
-	public function strlen($string) {
-		return iconv_strlen($string, 'UTF-8');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strpos()`.
-	 *
-	 * @link http://php.net/manual/en/function.iconv-strpos.php
-	 * @param string $haystack
-	 * @param string $needle
-	 * @param integer $offset
-	 * @return integer|boolean
-	 */
-	public function strpos($haystack, $needle, $offset) {
-		return iconv_strpos($haystack, $needle, $offset, 'UTF-8');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strrpos()`.
-	 *
-	 * @link http://php.net/manual/en/function.iconv-strpos.php
-	 * @param string $haystack
-	 * @param string $needle
-	 * @return integer|boolean
-	 */
-	public function strrpos($haystack, $needle) {
-		return iconv_strrpos($haystack, $needle, 'UTF-8');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `substr()`.
-	 *
-	 * @link http://php.net/manual/en/function.iconv-substr.php
-	 * @param string $string
-	 * @param integer $start
-	 * @param integer $length
-	 * @return string|boolean
-	 */
-	public function substr($string, $start, $length) {
-		return iconv_substr($string, $start, $length, 'UTF-8');
-	}
-}
-
-?>

+ 0 - 83
frameworks/PHP/php-lithium/libraries/lithium/g11n/multibyte/adapter/Intl.php

@@ -1,83 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\multibyte\adapter;
-
-/**
- * The `Intl` class is an adapter which uses certain string functions from
- * `ext/intl`. You will need to have the extension installed to use this adapter.
- *
- * Internally works with a fixed encoding of UTF-8. This means you can't use
- * this adapter for anything different than UTF-8 encoded strings. Silently
- * returns `null` or `false` when input string contains badly formed UTF-8
- * sequences.
- *
- * @link http://php.net/manual/en/book.intl.php
- */
-class Intl extends \lithium\core\Object {
-
-	/**
-	 * Determines if this adapter is enabled by checking if the `intl` extension is loaded.
-	 *
-	 * @return boolean Returns `true` if enabled, otherwise `false`.
-	 */
-	public static function enabled() {
-		return extension_loaded('intl');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strlen()`.
-	 *
-	 * @link http://php.net/manual/en/function.grapheme-strlen.php
-	 * @param string $string
-	 * @return integer|void
-	 */
-	public function strlen($string) {
-		return grapheme_strlen($string);
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strpos()`.
-	 *
-	 * @link http://php.net/manual/en/function.grapheme-strpos.php
-	 * @param string $haystack
-	 * @param string $needle
-	 * @param integer $offset
-	 * @return integer|boolean
-	 */
-	public function strpos($haystack, $needle, $offset) {
-		return grapheme_strpos($haystack, $needle, $offset);
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strrpos()`.
-	 *
-	 * @link http://php.net/manual/en/function.grapheme-strpos.php
-	 * @param string $haystack
-	 * @param string $needle
-	 * @return integer|boolean
-	 */
-	public function strrpos($haystack, $needle) {
-		return grapheme_strrpos($haystack, $needle);
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `substr()`.
-	 *
-	 * @link http://php.net/manual/en/function.grapheme-substr.php
-	 * @param string $string
-	 * @param integer $start
-	 * @param integer $length
-	 * @return string|boolean
-	 */
-	public function substr($string, $start, $length) {
-		return grapheme_substr($string, $start, $length);
-	}
-}
-
-?>

+ 0 - 81
frameworks/PHP/php-lithium/libraries/lithium/g11n/multibyte/adapter/Mbstring.php

@@ -1,81 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-namespace lithium\g11n\multibyte\adapter;
-
-/**
- * The `Mbstring` class is an adapter which uses certain string functions from
- * `ext/mbstring`. You will need to have the extension installed to use this adapter.
- *
- * No known limitations affecting used functionality. Silently strips
- * out badly formed UTF-8 sequences.
- *
- * @link http://php.net/manual/en/book.mbstring.php
- */
-class Mbstring extends \lithium\core\Object {
-
-	/**
-	 * Determines if this adapter is enabled by checking if the `mbstring` extension is loaded.
-	 *
-	 * @return boolean Returns `true` if enabled, otherwise `false`.
-	 */
-	public static function enabled() {
-		return extension_loaded('mbstring');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strlen()`.
-	 *
-	 * @link http://php.net/manual/en/function.mb-strlen.php
-	 * @param string $string
-	 * @return integer
-	 */
-	public function strlen($string) {
-		return mb_strlen($string, 'UTF-8');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strpos()`.
-	 *
-	 * @link http://php.net/manual/en/function.mb-strpos.php
-	 * @param string $haystack
-	 * @param string $needle
-	 * @param integer $offset
-	 * @return integer|boolean
-	 */
-	public function strpos($haystack, $needle, $offset) {
-		return mb_strpos($haystack, $needle, $offset, 'UTF-8');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `strrpos()`.
-	 *
-	 * @link http://php.net/manual/en/function.mb-strpos.php
-	 * @param string $haystack
-	 * @param string $needle
-	 * @return integer|boolean
-	 */
-	public function strrpos($haystack, $needle) {
-		return mb_strrpos($haystack, $needle, 0, 'UTF-8');
-	}
-
-	/**
-	 * Here used as a multibyte enabled equivalent of `substr()`.
-	 *
-	 * @link http://php.net/manual/en/function.mb-substr.php
-	 * @param string $string
-	 * @param integer $start
-	 * @param integer $length
-	 * @return string|boolean
-	 */
-	public function substr($string, $start, $length) {
-		return mb_substr($string, $start, $length, 'UTF-8');
-	}
-}
-
-?>

+ 0 - 16
frameworks/PHP/php-lithium/libraries/lithium/g11n/resources/php/da_DK/validation/default.php

@@ -1,16 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-/**
- * Validation data for `da_DK`.
- */
-return array(
-	'ssn' => '/\\A\\b[0-9]{6}-[0-9]{4}\\b\\z/i'
-);
-
-?>

+ 0 - 21
frameworks/PHP/php-lithium/libraries/lithium/g11n/resources/php/de/message/default.php

@@ -1,21 +0,0 @@
-<?php
-/**
- * Lithium: the most rad php framework
- *
- * @copyright     Copyright 2013, Union of RAD (http://union-of-rad.org)
- * @license       http://opensource.org/licenses/bsd-license.php The BSD License
- */
-
-/**
- * Message data for `de`.
- *
- * Plural rule and forms derived from the GNU gettext documentation.
- *
- * @link http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms
- */
-return array(
-	'pluralForms' => 2,
-	'pluralRule' => function ($n) { return $n != 1 ? 1 : 0; }
-);
-
-?>

Some files were not shown because too many files changed in this diff