Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding ability for server to go through ORM or DBAL by itself. Initia…

…l entry of js client.
  • Loading branch information...
commit 1725df8c1d6b8db9294e158a020a7dd958778735 1 parent c576b5f
@jwage jwage authored
View
2  README.markdown
@@ -97,7 +97,7 @@ the server request you want to process:
);
$server = new \Doctrine\REST\Server\Server($em, $request);
- $server->addEntityAlias('Entities\User', 'user');
+ $server->setEntityAlias('Entities\User', 'user');
$xml = $server->execute();
View
38 client.php
@@ -0,0 +1,38 @@
+<?php
+
+require '/Users/jwage/Sites/doctrine2git/lib/Doctrine/Common/ClassLoader.php';
+
+use Doctrine\REST\Client\Client,
+ Doctrine\REST\Client\EntityConfiguration,
+ Doctrine\REST\Client\Manager,
+ Doctrine\REST\Client\Entity,
+ Doctrine\Common\ClassLoader;
+
+$classLoader = new ClassLoader('Doctrine\REST', __DIR__ . '/lib');
+$classLoader->register();
+
+$client = new Client();
+
+$manager = new Manager($client);
+$manager->registerEntity('User');
+
+Entity::setManager($manager);
+
+class User extends Entity
+{
+ public $id;
+ public $username;
+ public $password;
+
+ public static function configure(EntityConfiguration $entityConfiguration)
+ {
+ $entityConfiguration->setUrl('http://localhost/rest/server.php');
+ $entityConfiguration->setName('user');
+ }
+}
+
+$user = User::find(9);
+$user->username = 'teetertertsting';
+$user->password = 'w00t';
+$user->save();
+print_r($user);
View
74 js/example.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <title>jAct demo</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
+ <script src="jActiveResource.js"></script>
+
+ <script>
+ function loadEditForm(id) {
+ User.find(id, function(user) {
+ $('#identifier').attr('value', user.id);
+ $('#username').attr('value', user.username);
+ $('#password').attr('value', user.username);
+ });
+ }
+
+ $(function() {
+ jActiveResource.define('User', {
+ url: 'http://localhost/rest/server.php/user',
+
+ username: null,
+ password: null,
+
+ toString: function () {
+ return 'username=' + this.username + '&password=' + this.password;
+ }
+ });
+
+ User.findAll(null, function(users) {
+ for (var i in users) {
+ user = users[i];
+ $('#users').append('<li id="user_' + user.id + '">' + user.id + ': ' + user.username + ' <a href="javascript: loadEditForm(' + user.id + ');">Edit</a> | <a href="javascript: UserFactory.destroy(' + user.id + ', function(data) { $(\'#user_\' + ' + user.id + ').remove(); });">Delete</a></li>');
+ }
+ });
+
+ $('#create_user').submit(function(data) {
+ var user = User.create();
+
+ user.id = $('#identifier').attr('value');
+ user.username = $('#username').attr('value');
+ user.password = $('#password').attr('value');
+
+ user.save(function (user) {
+ if ($('#user_' + user.id).length) {
+ $('#user_' + user.id).after('<li id="user_' + user.id + '">' + user.id + ': ' + user.username + ' <a href="javascript: loadEditForm(' + user.id + ');">Edit</a> | <a href="javascript: UserFactory.destroy(' + user.id + ', function(data) { $(\'#user_\' + ' + user.id + ').remove(); });">Delete</a></li>').remove();
+ } else {
+ $('#users').append('<li id="user_' + user.id + '">' + user.id + ': ' + user.username + ' <a href="javascript: loadEditForm(' + user.id + ');">Edit</a> | <a href="javascript: UserFactory.destroy(' + user.id + ', function(data) { $(\'#user_\' + ' + user.id + ').remove(); });">Delete</a></li>');
+ }
+ });
+
+ return false;
+ });
+ });
+ </script>
+
+ </head>
+ <body>
+
+ <h2>Create User</h3>
+ <form id="create_user">
+ <input type="hidden" name="identifier" id="identifier" />
+ Username: <input type="text" id="username" name="username" /><br/>
+ Password: <input type="password" id="password" name="password" /><br/>
+ <input type="submit" name="save" value="Save" />
+ </form>
+
+ <h2>Users</h2>
+ <ul id="users">
+
+ </ul>
+
+ </body>
+</html>
View
61 js/jActiveResource.js
@@ -0,0 +1,61 @@
+var jActiveResource = jQuery.extend({
+ create: function() {
+ return jQuery.extend(this);
+ },
+
+ define: function (name, definition) {
+ var instance = jQuery.extend(this, definition);
+ eval(name + ' = instance;');
+ eval(name + 'Factory = jQuery.extend(jActiveResourceFactory);')
+ },
+
+ find: function(id, callback) {
+ this.execute('get', this.getUrl(id), null, callback);
+ },
+
+ findAll: function(data, callback) {
+ this.execute('get', this.getUrl(), data, callback);
+ },
+
+ destroy: function(id, callback) {
+ this.execute('delete', this.getUrl(this.id), null, callback);
+ },
+
+ save: function(callback) {
+ this.execute('post', this.getUrl(this.id), this.toString(), callback);
+ },
+
+ getUrl: function(id, action, parameters) {
+ if (id) {
+ return this.url + '/' + id + '.json';
+ } else {
+ return this.url + '.json';
+ }
+ },
+
+ execute: function(method, url, data, callback) {
+ $.ajax({
+ type: method,
+ dataType: 'json',
+ url: url,
+ data: data,
+ success: function(data) {
+ if (data.length > 0) {
+ var results = new Array();
+ for (i = 0; i < data.length; i++) {
+ results[i] = jQuery.extend(this.prototype, data[i]);
+ }
+ callback(results)
+ } else {
+ callback(jQuery.extend(this.prototype, data));
+ }
+ }
+ });
+ }
+});
+
+var jActiveResourceFactory = jActiveResource.extend({
+ destroy: function(id, callback) {
+ this.execute('delete', this.getUrl(id), null, callback);
+ }
+});
View
5 lib/Doctrine/REST/Client/Client.php
@@ -78,16 +78,13 @@ public function execute(Request $request)
switch ($request->getMethod()) {
case self::POST:
+ case self::PUT:
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($request->getParameters()));
break;
case self::DELETE:
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
- case self::PUT:
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
- curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($request->getParameters()));
- break;
case self::GET:
default:
break;
View
6 lib/Doctrine/REST/Client/EntityConfiguration.php
@@ -85,7 +85,11 @@ public function getProperties()
public function setValue($entity, $field, $value)
{
- $this->_reflectionProperties[$field]->setValue($entity, $value);
+ if (isset($this->_reflectionProperties[$field])) {
+ $this->_reflectionProperties[$field]->setValue($entity, $value);
+ } else {
+ $entity->$field = $value;
+ }
}
public function getValue($entity, $field)
View
83 lib/Doctrine/REST/Server/Action/AbstractAction.php
@@ -21,7 +21,8 @@
namespace Doctrine\REST\Server\Action;
-use \Doctrine\REST\Server\RequestHandler;
+use Doctrine\REST\Server\RequestHandler,
+ Doctrine\ORM\EntityManager;
/**
* Abstract server action class for REST server actions to extend from.
@@ -35,21 +36,32 @@
abstract class AbstractAction
{
protected $_requestHandler;
- protected $_em;
+ protected $_source;
protected $_request;
public function __construct(RequestHandler $requestHandler)
{
$this->_requestHandler = $requestHandler;
- $this->_em = $requestHandler->getEntityManager();
+ $this->_source = $requestHandler->getSource();
$this->_request = $requestHandler->getRequest();
}
- abstract public function execute();
+ public function executeORM()
+ {
+ }
+
+ public function executeDBAL()
+ {
+ }
+
+ protected function _getEntity()
+ {
+ return $this->_requestHandler->getEntity();
+ }
- protected function _resolveEntityAlias($alias)
+ protected function _getEntityIdentifierKey()
{
- return $this->_requestHandler->resolveEntityAlias($alias);
+ return $this->_requestHandler->getEntityIdentifierKey($this->_getEntity());
}
protected function _setQueryFirstAndMax($q)
@@ -61,31 +73,60 @@ protected function _setQueryFirstAndMax($q)
if (isset($this->_request['_page'])) {
$page = $this->_request['_page'];
$first = ($page - 1) * $maxPerPage;
- $q->setFirstResult($first);
- $q->setMaxResults($maxPerPage);
} else {
if (isset($this->_request['_first'])) {
- $q->setFirstResult($this->_request['_first']);
+ $first = $this->_request['_first'];
} else {
- $q->setFirstResult(0);
+ $first = 0;
}
if (isset($this->_request['_max'])) {
- $q->setMaxResults($this->_request['_max']);
- } else {
- $q->setMaxResults($maxPerPage);
+ $maxPerPage = $this->_request['_max'];
}
}
+
+ if ($this->_source instanceof EntityManager) {
+ $q->setFirstResult($first);
+ $q->setMaxResults($maxPerPage);
+ } else {
+ $platform = $this->_source->getDatabasePlatform();
+ return $platform->modifyLimitQuery($q, $maxPerPage, $first);
+ }
}
- protected function _getFindByIdQuery($entity, $id)
+ protected function _findEntityById()
{
- $qb = $this->_em->createQueryBuilder()
- ->select('a')
- ->from($entity, 'a')
- ->where('a.id = ?1')
- ->setParameter('1', $id);
- $q = $qb->getQuery();
- return $q;
+ if ($this->_source instanceof EntityManager) {
+ $entity = $this->_getEntity();
+ $id = $this->_request['_id'];
+
+ $qb = $this->_source->createQueryBuilder()
+ ->select('a')
+ ->from($entity, 'a')
+ ->where('a.id = ?1')
+ ->setParameter('1', $id);
+ $query = $qb->getQuery();
+
+ return $query->getSingleResult();
+ } else {
+ $entity = $this->_getEntity();
+ $identifierKey = $this->_getEntityIdentifierKey($entity);
+
+ $query = sprintf('SELECT * FROM %s WHERE %s = ?', $entity, $identifierKey);
+
+ return $this->_source->fetchRow($query, array($this->_request['_id']));
+ }
+ }
+
+ protected function _updateEntityInstance($entity)
+ {
+ $data = $this->_gatherData($this->_request->getData());
+ foreach ($data as $key => $value) {
+ $setter = 'set' . ucfirst($key);
+ if (is_callable(array($entity, $setter))) {
+ $entity->$setter($value);
+ }
+ }
+ return $entity;
}
protected function _gatherData()
View
48 lib/Doctrine/REST/Server/Action/AbstractSaveAction.php
@@ -1,48 +0,0 @@
-<?php
-/*
- * $Id$
- *
- * 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
- * OWNER 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.
- *
- * This software consists of voluntary contributions made by many individuals
- * and is licensed under the LGPL. For more information, see
- * <http://www.doctrine-project.org>.
-*/
-
-namespace Doctrine\REST\Server\Action;
-
-use \Doctrine\REST\Server\RequestHandler;
-
-/**
- * Abstract class for insert and update server actions to extend from.
- *
- * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
- * @link www.doctrine-project.org
- * @since 2.0
- * @version $Revision$
- * @author Jonathan H. Wage <jonwage@gmail.com>
- */
-abstract class AbstractSaveAction extends AbstractAction
-{
- protected function _updateEntityInstance($entity)
- {
- $data = $this->_gatherData($this->_request->getData());
- foreach ($data as $key => $value) {
- $setter = 'set' . ucfirst($key);
- if (is_callable(array($entity, $setter))) {
- $entity->$setter($value);
- }
- }
- return $entity;
- }
-}
View
24 lib/Doctrine/REST/Server/Action/DeleteAction.php
@@ -32,18 +32,22 @@
*/
class DeleteAction extends AbstractAction
{
- public function execute()
+ public function executeORM()
{
- $query = $this->_getFindByIdQuery(
- $this->_resolveEntityAlias($this->_request['_entity']),
- $this->_request['_id']
- );
- $entity = $query->getSingleResult();
+ if ($entity = $this->_findEntityById()) {
+ $this->_source->remove($entity);
+ $this->_source->flush();
+ return $entity;
+ }
+ }
- if ($entity) {
- $this->_em->remove($entity);
- $this->_em->flush();
+ public function executeDBAL()
+ {
+ if ($entity = $this->_findEntityById()) {
+ $this->_source->delete($this->_getEntity(), array(
+ $this->_getEntityIdentifierKey() => $this->_request['_id']
+ ));
+ return $entity;
}
- return $entity;
}
}
View
15 lib/Doctrine/REST/Server/Action/GetAction.php
@@ -34,17 +34,12 @@ class GetAction extends AbstractAction
{
public function execute()
{
- $query = $this->_getFindByIdQuery(
- $this->_resolveEntityAlias($this->_request['_entity']),
- $this->_request['_id']
- );
- $this->_setQueryFirstAndMax($query);
+ $entity = $this->_findEntityById();
- $result = $query->getSingleResult();
-
- if ( ! $result) {
- throw new \InvalidArgumentException(sprintf('Could not find the "%s" with an ids of "%s"', $this->_request['_entity'], implode(', ', (array) $this->_request['_id'])));
+ if ( ! $entity) {
+ throw new \InvalidArgumentException(sprintf('Could not find the "%s" with an id of "%s"', $this->_request['_entity'], implode(', ', (array) $this->_request['_id'])));
}
- return $result;
+
+ return $entity;
}
}
View
34 lib/Doctrine/REST/Server/Action/InsertAction.php
@@ -30,16 +30,34 @@
* @version $Revision$
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
-class InsertAction extends AbstractSaveAction
+class InsertAction extends AbstractAction
{
- public function execute()
+ public function executeORM()
{
- $entityName = $this->_resolveEntityAlias($this->_request['_entity']);
- $entity = new $entityName();
- $this->_updateEntityInstance($entity);
- $this->_em->persist($entity);
- $this->_em->flush();
+ $entity = $this->_getEntity();
- return $entity;
+ $instance = new $entity();
+ $this->_updateEntityInstance($instance);
+ $this->_source->persist($instance);
+ $this->_source->flush();
+
+ return $instance;
+ }
+
+ public function executeDBAL()
+ {
+ $entity = $this->_getEntity();
+ $identifierKey = $this->_getEntityIdentifierKey();
+
+ $data = $this->_gatherData();
+
+ unset($data['id']);
+ $this->_source->insert($entity, $data);
+ $data = array_merge(
+ array($identifierKey => $this->_source->lastInsertId()),
+ $data
+ );
+
+ return $data;
}
}
View
32 lib/Doctrine/REST/Server/Action/ListAction.php
@@ -32,11 +32,12 @@
*/
class ListAction extends AbstractAction
{
- public function execute()
+ public function executeORM()
{
- $qb = $this->_em->createQueryBuilder()
+ $entity = $this->_getEntity();
+ $qb = $this->_source->createQueryBuilder()
->select('a')
- ->from($this->_resolveEntityAlias($this->_request['_entity']), 'a');
+ ->from($entity, 'a');
$data = $this->_gatherData();
foreach ($data as $key => $value) {
@@ -46,7 +47,28 @@ public function execute()
$query = $qb->getQuery();
$this->_setQueryFirstAndMax($query);
- $collection = $query->execute();
- return $collection;
+ $results = $query->execute();
+
+ return $results;
+ }
+
+ public function executeDBAL()
+ {
+ $entity = $this->_getEntity();
+
+ $params = array();
+ $query = sprintf('SELECT * FROM %s', $entity);
+ if ($data = $this->_gatherData()) {
+ $query .= ' WHERE ';
+ foreach ($data as $key => $value) {
+ $query .= $key . ' = ? AND ';
+ $params[] = $value;
+ }
+ $query = substr($query, 0, strlen($query) - 5);
+ }
+ $query = $this->_setQueryFirstAndMax($query);
+ $results = $this->_source->fetchAll($query, $params);
+
+ return $results;
}
}
View
21 lib/Doctrine/REST/Server/Action/UpdateAction.php
@@ -30,15 +30,28 @@
* @version $Revision$
* @author Jonathan H. Wage <jonwage@gmail.com>
*/
-class UpdateAction extends AbstractSaveAction
+class UpdateAction extends AbstractAction
{
- public function execute()
+ public function executeORM()
{
- if ($entity = $this->_em->find($this->_resolveEntityAlias($this->_request['_entity']), $this->_request['_id'])) {
+ if ($entity = $this->_findEntityById()) {
$this->_updateEntityInstance($entity);
- $this->_em->flush();
+ $this->_source->flush();
}
return $entity;
}
+
+ public function executeDBAL()
+ {
+ $entity = $this->_getEntity();
+ $identifierKey = $this->_getEntityIdentifierKey($entity);
+
+ $data = $this->_gatherData();
+ $this->_source->update($entity, $data, array(
+ $identifierKey => $this->_request['_id']
+ ));
+
+ return $this->_findEntityById();
+ }
}
View
50 lib/Doctrine/REST/Server/PHPRequestParser.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Doctrine\REST\Server;
+
+class PHPRequestParser
+{
+ public function getRequestArray()
+ {
+ $path = $_SERVER['PATH_INFO'];
+ $path = ltrim($path, '/');
+ $e = explode('/', $path);
+ $count = count($e);
+ $end = end($e);
+ $e2 = explode('.', $end);
+ $e[count($e) - 1] = $e2[0];
+ $format = isset($e2[1]) ? $e2[1] : 'xml';
+ $entity = $e[0];
+ $id = isset($e[1]) ? $e[1] : null;
+ $action = isset($e[2]) ? $e[2] : null;
+ $method = isset($_REQUEST['_method']) ? $_REQUEST['_method'] : $_SERVER['REQUEST_METHOD'];
+ $method = strtoupper($method);
+
+ if ($count === 1) {
+ if ($method === 'POST' || $method === 'PUT') {
+ $action = 'insert';
+ } else if ($method === 'GET') {
+ $action = 'list';
+ }
+ } else if ($count === 2) {
+ if ($method === 'POST' || $method === 'PUT') {
+ $action = 'update';
+ } else if ($method === 'GET') {
+ $action = 'get';
+ } else if ($method === 'DELETE') {
+ $action = 'delete';
+ }
+ } else if ($count === 3) {
+ $action = $action;
+ }
+
+ $data = array_merge(array(
+ '_entity' => $entity,
+ '_id' => $id,
+ '_action' => $action,
+ '_format' => $format
+ ), $_REQUEST);
+
+ return $data;
+ }
+}
View
112 lib/Doctrine/REST/Server/RequestHandler.php
@@ -21,7 +21,8 @@
namespace Doctrine\REST\Server;
-use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\EntityManager,
+ Doctrine\DBAL\Connection;
/**
* Class responsible for transforming a REST server request to a response.
@@ -34,13 +35,13 @@
*/
class RequestHandler
{
- private $_em;
+ private $_source;
private $_request;
private $_response;
private $_username;
private $_password;
private $_credentialsCallback;
- private $_entityAliases = array();
+ private $_entities = array();
private $_actions = array(
'delete' => 'Doctrine\\REST\\Server\\Action\\DeleteAction',
@@ -50,25 +51,46 @@ class RequestHandler
'list' => 'Doctrine\\REST\\Server\\Action\\ListAction'
);
- public function __construct(EntityManager $em, Request $request, Response $response)
+ public function __construct($source, Request $request, Response $response)
{
- $this->_em = $em;
+ $this->_source = $source;
$this->_request = $request;
$this->_response = $response;
$this->_response->setRequestHandler($this);
$this->_credentialsCallback = array($this, 'checkCredentials');
}
- public function addEntityAlias($entity, $alias)
+ public function configureEntity($entity, $configuration)
{
- $this->_entityAliases[$alias] = $entity;
+ $this->_entities[$entity] = $configuration;
+ }
+
+ public function setEntityAlias($entity, $alias)
+ {
+ $this->_entities[$entity]['alias'] = $alias;
+ }
+
+ public function addEntityAction($entity, $action, $className)
+ {
+ $this->_entities[$entity]['actions'][$action] = $className;
+ }
+
+ public function setEntityIdentifierKey($entity, $identifierKey)
+ {
+ $this->_entities[$entity]['identifierKey'] = $identifierKey;
+ }
+
+ public function getEntityIdentifierKey($entity)
+ {
+ return isset($this->_entities[$entity]['identifierKey']) ? $this->_entities[$entity]['identifierKey'] : 'id';
}
public function resolveEntityAlias($alias)
{
- if (isset($this->_entityAliases[$alias]))
- {
- return $this->_entityAliases[$alias];
+ foreach ($this->_entities as $entity => $configuration) {
+ if (isset($configuration['alias']) && $configuration['alias'] === $alias) {
+ return $entity;
+ }
}
return $alias;
}
@@ -132,9 +154,9 @@ public function getActions()
return $this->_actions;
}
- public function getEntityManager()
+ public function getSource()
{
- return $this->_em;
+ return $this->_source;
}
public function getRequest()
@@ -147,47 +169,51 @@ public function getResponse()
return $this->_response;
}
+ public function getEntity()
+ {
+ return $this->resolveEntityAlias($this->_request['_entity']);
+ }
+
public function execute()
{
try {
- $this->_executeAction();
+ $entity = $this->getEntity();
+ $actionInstance = $this->getAction($entity, $this->_request['_action']);
+
+ if (method_exists($actionInstance, 'execute')) {
+ $result = $actionInstance->execute();
+ } else {
+ if ($this->_source instanceof EntityManager) {
+ $result = $actionInstance->executeORM();
+ } else {
+ $result = $actionInstance->executeDBAL();
+ }
+ }
+
+ $this->_response->setResponseData(
+ $this->_transformResultForResponse($result)
+ );
} catch (\Exception $e) {
$this->_response->setError($this->_getExceptionErrorMessage($e));
}
return $this->_response;
}
- public function getAction($actionName)
+ public function getAction($entity, $actionName)
{
- if ( ! is_object($this->_actions[$actionName])) {
- $actionClassName = $this->_actions[$actionName];
- if (class_exists($actionClassName)) {
+ if (isset($this->_actions[$actionName])) {
+ if ( ! is_object($this->_actions[$actionName])) {
+ $actionClassName = $this->_actions[$actionName];
$this->_actions[$actionName] = new $actionClassName($this);
- } else {
- throw new \Exception(sprintf('Invalid action specified %s', $actionName));
}
+ return $this->_actions[$actionName];
}
- return $this->_actions[$actionName];
- }
-
- private function _executeAction()
- {
- $actionInstance = $this->getAction($this->_request['_action']);
-
- $result = $actionInstance->execute();
-
- if ($result !== false) {
- $this->_response->setResponseData(
- $this->_transformResultForResponse($result)
- );
- } else {
- $this->_response->setError(
- sprintf(
- 'An error occurred executing the action named "%s" with a request method of "%s."',
- $this->_request['_action'],
- $this->_request['_method']
- )
- );
+ if (isset($this->_entities[$entity]['actions'][$actionName])) {
+ if ( ! is_object($this->_entities[$entity]['actions'][$actionName])) {
+ $actionClassName = $this->_entities[$entity]['actions'][$actionName];
+ $this->_entities[$entity]['actions'][$actionName] = new $actionClassName($this);
+ }
+ return $this->_entities[$entity]['actions'][$actionName];
}
}
@@ -209,12 +235,12 @@ private function _transformResultForResponse($result, $array = null)
}
if (is_object($result)) {
$entityName = get_class($result);
- try {
- $class = $this->_em->getMetadataFactory()->getMetadataFor($entityName);
+ if ($this->_source instanceof EntityManager) {
+ $class = $this->_source->getMetadataFactory()->getMetadataFor($entityName);
foreach ($class->fieldMappings as $fieldMapping) {
$array[$fieldMapping['fieldName']] = $class->getReflectionProperty($fieldMapping['fieldName'])->getValue($result);
}
- } catch (\Exception $e) {
+ } else {
$vars = get_object_vars($result);
foreach ($vars as $key => $value) {
$array[$key] = $value;
View
17 lib/Doctrine/REST/Server/Response.php
@@ -84,12 +84,14 @@ public function getContent()
private function _sendHeaders()
{
- if ( ! isset($_SERVER['PHP_AUTH_USER'])) {
- header('WWW-Authenticate: Basic realm="Doctrine REST API"');
- header('HTTP/1.0 401 Unauthorized');
- } else {
- if ( ! $this->_requestHandler->hasValidCredentials()) {
- $this->setError('Invalid credentials specified.');
+ if ($this->_requestHandler->getUsername()) {
+ if ( ! isset($_SERVER['PHP_AUTH_USER'])) {
+ header('WWW-Authenticate: Basic realm="Doctrine REST API"');
+ header('HTTP/1.0 401 Unauthorized');
+ } else {
+ if ( ! $this->_requestHandler->hasValidCredentials()) {
+ $this->setError('Invalid credentials specified.');
+ }
}
}
@@ -116,6 +118,9 @@ private function _arrayToXml($array, $rootNodeName = 'doctrine', $xml = null, $c
}
foreach($array as $key => $value) {
+ if (is_numeric($key)) {
+ $key = $rootNodeName . $key;
+ }
$key = preg_replace('/[^A-Za-z_]/i', '', $key);
if (is_array($value) && ! empty($value)) {
View
21 lib/Doctrine/REST/Server/Server.php
@@ -21,7 +21,8 @@
namespace Doctrine\REST\Server;
-use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\EntityManager,
+ Doctrine\ORM\Connection;
/**
* Simple REST server facade.
@@ -38,11 +39,11 @@ class Server
private $_request;
private $_response;
- public function __construct(EntityManager $em, array $requestData = array())
+ public function __construct($source, array $requestData = array())
{
$this->_request = new Request($requestData);
$this->_response = new Response($this->_request);
- $this->_requestHandler = new RequestHandler($em, $this->_request, $this->_response);
+ $this->_requestHandler = new RequestHandler($source, $this->_request, $this->_response);
}
public function execute()
@@ -51,9 +52,14 @@ public function execute()
return $this->_requestHandler->getResponse()->getContent();
}
- public function addEntityAlias($entity, $alias)
+ public function setEntityIdentifierKey($entity, $identifierKey)
{
- $this->_requestHandler->addEntityAlias($entity, $alias);
+ $this->_requestHandler->setEntityIdentifierKey($entity, $identifierKey);
+ }
+
+ public function setEntityAlias($entity, $alias)
+ {
+ $this->_requestHandler->setEntityAlias($entity, $alias);
}
public function registerAction($action, $className)
@@ -61,6 +67,11 @@ public function registerAction($action, $className)
$this->_requestHandler->registerAction($action, $className);
}
+ public function addEntityAction($entity, $action, $className)
+ {
+ $this->_requestHandler->addEntityAction($entity, $action, $className);
+ }
+
public function setUsername($username)
{
$this->_requestHandler->setUsername($username);
View
42 server.php
@@ -0,0 +1,42 @@
+<?php
+
+use Doctrine\REST\Server\Server,
+ Doctrine\Common\ClassLoader;
+
+require '/Users/jwage/Sites/doctrine2git/lib/Doctrine/Common/ClassLoader.php';
+
+$classLoader = new ClassLoader('Doctrine\REST', __DIR__ . '/lib');
+$classLoader->register();
+
+$classLoader = new ClassLoader('Doctrine', '/Users/jwage/Sites/doctrine2git/lib');
+$classLoader->register();
+
+$config = new \Doctrine\ORM\Configuration();
+$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
+$config->setProxyDir('/tmp');
+$config->setProxyNamespace('Proxies');
+$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
+
+$connectionOptions = array(
+ 'driver' => 'pdo_mysql',
+ 'dbname' => 'rest_test',
+ 'user' => 'root'
+);
+
+$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);
+
+$parser = new \Doctrine\REST\Server\PHPRequestParser();
+$requestData = $parser->getRequestArray();
+
+class TestAction
+{
+ public function executeDBAL()
+ {
+ return array('test' => 'test');
+ }
+}
+
+$server = new \Doctrine\REST\Server\Server($em->getConnection(), $requestData);
+$server->addEntityAction('user', 'test', 'TestAction');
+$server->execute();
+$server->getResponse()->send();
View
44 tests/Doctrine/Tests/REST/FunctionalTest.php
@@ -17,12 +17,13 @@ class FunctionalTest extends \PHPUnit_Framework_TestCase
private $_manager;
private $_client;
- public function setUp()
+ public function setUpRest($type)
{
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
$config->setProxyDir('/tmp');
$config->setProxyNamespace('Proxies');
+ $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver());
$connectionOptions = array(
'driver' => 'pdo_sqlite',
@@ -36,7 +37,11 @@ public function setUp()
$schemaTool->dropSchema($classes);
$schemaTool->createSchema($classes);
- $this->_client = new TestFunctionalClient('user', $em);
+ if ($type === 'orm') {
+ $this->_client = new TestFunctionalClient('user', $em);
+ } else {
+ $this->_client = new TestFunctionalClient('user', $em->getConnection());
+ }
$this->_manager = new Manager($this->_client);
$this->_manager->registerEntity('Doctrine\Tests\REST\User');
@@ -44,7 +49,19 @@ public function setUp()
Entity::setManager($this->_manager);
}
- public function testIdentityMap()
+ public function testOrm()
+ {
+ $this->setUpRest('orm');
+ $this->_testActiveRecordApi();
+ }
+
+ public function testDbal()
+ {
+ $this->setUpRest('dbal');
+ $this->_testActiveRecordApi();
+ }
+
+ private function _testActiveRecordApi()
{
$user1 = new User();
$user1->setUsername('jwage');
@@ -64,6 +81,12 @@ public function testIdentityMap()
$this->assertEquals(3, $user3->getId());
+ $user3->setUsername('romanb_new');
+ $user3->save();
+
+ $user3test = User::find($user3->getId());
+ $this->assertEquals('romanb_new', $user3test->getUsername());
+
$test = User::findAll();
$this->assertEquals(3, count($test));
$this->assertTrue($user1 === $test[0]);
@@ -73,6 +96,7 @@ public function testIdentityMap()
$user3->delete();
$test = User::findAll();
+
$this->assertEquals(2, count($test));
}
}
@@ -80,21 +104,23 @@ public function testIdentityMap()
class TestFunctionalClient extends Client
{
public $name;
- public $ormEm;
+ public $source;
public $data = array();
public $count = 0;
- public function __construct($name, $ormEm)
+ public function __construct($name, $source)
{
$this->name = $name;
- $this->ormEm = $ormEm;
+ $this->source = $source;
}
public function execServer($request, $requestArray, $parameters = array(), $responseType = 'xml')
{
$requestArray = array_merge($requestArray, (array) $parameters);
- $server = new Server($this->ormEm, $requestArray);
- $server->addEntityAlias('Doctrine\Tests\REST\DoctrineUser', 'user');
+ $server = new Server($this->source, $requestArray);
+ if ($this->source instanceof EntityManager) {
+ $server->setEntityAlias('Doctrine\Tests\REST\DoctrineUser', 'user');
+ }
$response = $server->getRequestHandler()->execute();
$data = $request->getResponseTransformerImpl()->transform($response->getContent());
return $data;
@@ -193,7 +219,7 @@ public function setUsername($username)
/**
* @Entity
- * @Table(name="User")
+ * @Table(name="user")
*/
class DoctrineUser
{
View
2  tests/Doctrine/Tests/REST/TestInit.php
@@ -27,7 +27,7 @@ function autoload($className)
set_include_path(
__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'lib'
. PATH_SEPARATOR .
- '/Users/jwage/Sites/doctrine2/lib'
+ '/Users/jwage/Sites/doctrine2git/lib'
. PATH_SEPARATOR .
get_include_path()
);
Please sign in to comment.
Something went wrong with that request. Please try again.