diff --git a/lib/Doctrine/Export/Schema.php b/lib/Doctrine/Export/Schema.php index e737bf2fd..a691fc802 100644 --- a/lib/Doctrine/Export/Schema.php +++ b/lib/Doctrine/Export/Schema.php @@ -46,11 +46,15 @@ class Doctrine_Export_Schema * @param string $directory * @return void */ - public function buildSchema($directory, $models = array()) + public function buildSchema($directory = null, $models = array()) { $array = array(); - $loadedModels = Doctrine::loadModels($directory); + if ($directory) { + $loadedModels = Doctrine::loadModels($directory); + } else { + $loadedModels = Doctrine::getLoadedModels(); + } $parent = new ReflectionClass('Doctrine_Record'); @@ -140,7 +144,7 @@ class Doctrine_Export_Schema * @param string $directory * @return void */ - public function exportSchema($schema, $format, $directory, $models = array()) + public function exportSchema($schema, $format, $directory = null, $models = array()) { $array = $this->buildSchema($directory, $models); diff --git a/lib/Doctrine/Import/Schema.php b/lib/Doctrine/Import/Schema.php index ec0dca044..4deb122c1 100644 --- a/lib/Doctrine/Import/Schema.php +++ b/lib/Doctrine/Import/Schema.php @@ -41,7 +41,17 @@ class Doctrine_Import_Schema { public $relations = array(); - + public function buildSchema($schema, $format) + { + $array = array(); + foreach ((array) $schema AS $s) { + $array = array_merge($array, $this->parseSchema($s, $format)); + } + + $this->buildRelationships($array); + + return array('schema' => $array, 'relations' => $this->relations); + } /** * importSchema * @@ -58,12 +68,9 @@ class Doctrine_Import_Schema $builder = new Doctrine_Import_Builder(); $builder->setTargetPath($directory); - $array = array(); - foreach ((array) $schema AS $s) { - $array = array_merge($array, $this->parseSchema($s, $format)); - } + $schema = $this->buildSchema($schema, $format); - $this->buildRelationships($array); + $array = $schema['schema']; foreach ($array as $name => $properties) { if (!empty($models) && !in_array($properties['className'], $models)) { diff --git a/lib/Doctrine/Resource.php b/lib/Doctrine/Resource.php index 5043334af..f433dfd38 100644 --- a/lib/Doctrine/Resource.php +++ b/lib/Doctrine/Resource.php @@ -23,6 +23,7 @@ * Doctrine_Resource * * @author Konsta Vesterinen + * @author Jonathan H. Wage * @package Doctrine * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version $Revision$ @@ -32,34 +33,37 @@ */ class Doctrine_Resource { - public static function request($url, $request) - { - $url .= strstr($url, '?') ? '&':'?'; - $url .= http_build_query($request); - - $response = file_get_contents($url); - - return $response; - } + protected $_config = null; + protected $_defaultFormat = 'xml'; - public function hydrate(array $array, $model, $config, $passedKey = null) + public function __construct($config) { - $collection = new Doctrine_Resource_Collection($model, $config); - - foreach ($array as $record) { - $r = new Doctrine_Resource_Record($model, $config); - - foreach ($record as $key => $value) { - if (is_array($value)) { - $r->data[$key] = $this->hydrate($value, $model, $config, $key); - } else { - $r->data[$key] = $value; - } - } - - $collection->data[] = $r; + foreach ($config as $key => $value) { + $this->getConfig()->set($key, $value); } - return $collection; + $loadDoctrine = false; + foreach ($this->getConfig()->getAll() as $key => $value) { + if ($key == 'url') { + $this->loadDoctrine = true; + } + } + + if (!$this->getConfig()->has('format') OR !$this->getConfig()->get('format')) { + $this->getConfig()->set('format', $this->_defaultFormat); + } + } + + public function getConfig($key = null) + { + if ($this->_config === null) { + $this->_config = new Doctrine_Resource_Config(); + } + + if ($key === null) { + return $this->_config; + } else { + return $this->_config->get($key); + } } } diff --git a/lib/Doctrine/Resource/Client.php b/lib/Doctrine/Resource/Client.php index 46bea5fb2..cf7269343 100644 --- a/lib/Doctrine/Resource/Client.php +++ b/lib/Doctrine/Resource/Client.php @@ -23,6 +23,7 @@ * Doctrine_Resource_Client * * @author Konsta Vesterinen + * @author Jonathan H. Wage * @package Doctrine * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version $Revision$ @@ -32,25 +33,57 @@ */ class Doctrine_Resource_Client extends Doctrine_Resource { - public $config = array(); + public $loadDoctrine = false; - public function __construct($config) + static public function getInstance($config = null) { - $this->config = $config; + static $instance; + + if (!$instance) { + $instance = new Doctrine_Resource_Client($config); + + if ($instance->loadDoctrine === true) { + $instance->loadDoctrine(); + } + } + + return $instance; + } + + public function loadDoctrine() + { + $path = '/tmp/' . md5(serialize($this->getConfig())); + + if (file_exists($path)) { + $schema = file_get_contents($path); + } else { + $request = new Doctrine_Resource_Request(); + $request->set('type', 'load'); + $request->set('format', 'xml'); + + $schema = $request->execute(); + + file_put_contents($path, $schema); + } + + $import = new Doctrine_Import_Schema(); + $schema = $import->buildSchema($path, 'xml'); + + $this->getConfig()->set('schema', $schema); } public function newQuery() { - return new Doctrine_Resource_Query($this->config); + return new Doctrine_Resource_Query(); } - public function newRecord($model) + public function newRecord($model, $loadRelations = true) { - return new Doctrine_Resource_Record($model, $this->config); + return new Doctrine_Resource_Record($model, $loadRelations); } public function newCollection($model) { - return new Doctrine_Resource_Collection($model, $this->config); + return new Doctrine_Resource_Collection($model); } -} +} \ No newline at end of file diff --git a/lib/Doctrine/Resource/Collection.php b/lib/Doctrine/Resource/Collection.php index 597f93047..21dbf6375 100644 --- a/lib/Doctrine/Resource/Collection.php +++ b/lib/Doctrine/Resource/Collection.php @@ -23,6 +23,7 @@ * Doctrine_Resource_Collection * * @author Konsta Vesterinen + * @author Jonathan H. Wage * @package Doctrine * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version $Revision$ @@ -32,50 +33,57 @@ */ class Doctrine_Resource_Collection extends Doctrine_Access implements Countable, IteratorAggregate { - public $data = array(); - public $config = array(); - public $model = null; + protected $_data = array(); + protected $_config = array(); + protected $_model = null; - public function __construct($model, $config) + public function __construct($model) { - $this->model = $model; - $this->config = $config; + $this->_model = $model; + } + + public function getConfig($key = null) + { + return Doctrine_Resource_Client::getInstance()->getConfig($key); } public function count() { - return count($data); + return count($this->_data); } public function get($get) { - if (isset($this->data[$get])) { - return $this->data[$get]; + if (isset($this->_data[$get])) { + return $this->_data[$get]; } } public function set($set, $value) { - $this->data[$set] = $value; + $this->_data[$set] = $value; + } + + public function add($value) + { + $this->_data[] = $value; } public function getIterator() { - $data = $this->data; - - return new ArrayIterator($data); + return new ArrayIterator($this->_data); } public function getFirst() { - return isset($this->data[0]) ? $this->data[0]:null; + return isset($this->_data[0]) ? $this->_data[0]:null; } public function toArray() { $array = array(); - foreach ($this->data as $key => $record) { + foreach ($this->_data as $key => $record) { $array[$key] = $record->toArray(); } @@ -84,7 +92,7 @@ class Doctrine_Resource_Collection extends Doctrine_Access implements Countable, public function save() { - foreach ($this->data as $record) { + foreach ($this as $record) { $record->save(); } } diff --git a/lib/Doctrine/Resource/Query.php b/lib/Doctrine/Resource/Query.php index 1d037b177..f6d564281 100644 --- a/lib/Doctrine/Resource/Query.php +++ b/lib/Doctrine/Resource/Query.php @@ -23,6 +23,7 @@ * Doctrine_Resource_Query * * @author Konsta Vesterinen + * @author Jonathan H. Wage * @package Doctrine * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version $Revision$ @@ -30,66 +31,58 @@ * @link www.phpdoctrine.com * @since 1.0 */ -class Doctrine_Resource_Query extends Doctrine_Resource +class Doctrine_Resource_Query { - public $config = array(); - public $parts = array(); - public $dql = null; - public $defaultFormat = 'xml'; + protected $_parts = array(); + protected $_dql = null; + protected $_params = array(); - public function __construct($config) + public function getConfig($key = null) { - $this->config = $config; + return Doctrine_Resource_Client::getInstance()->getConfig($key); } public function query($dql, $params = array()) { - $this->dql = $dql; + $this->_dql = $dql; return $this->execute($params); } public function execute($params = array()) { - $request = array(); - $request['dql'] = $this->getDql(); - $request['params'] = $params; - $request['format'] = $this->getFormat(); - $request['type'] = 'query'; + $request = new Doctrine_Resource_Request(); + $request->set('dql', $this->getDql()); + $request->set('params', $params); + $request->set('format', $this->getConfig()->get('format')); + $request->set('type', 'query'); - $response = self::request($this->config['url'], $request); + $response = $request->execute(); - return $this->parseResponse($response); + $array = Doctrine_Parser::load($response, $this->getConfig()->get('format')); + + return $request->hydrate($array, $this->getModel()); } public function getDql() { - if (!$this->dql && !empty($this->parts)) { + if (!$this->_dql && !empty($this->_parts)) { $q = ''; - $q .= ( ! empty($this->parts['select']))? 'SELECT ' . implode(', ', $this->parts['select']) : ''; - $q .= ( ! empty($this->parts['from']))? ' FROM ' . implode(' ', $this->parts['from']) : ''; - $q .= ( ! empty($this->parts['where']))? ' WHERE ' . implode(' AND ', $this->parts['where']) : ''; - $q .= ( ! empty($this->parts['groupby']))? ' GROUP BY ' . implode(', ', $this->parts['groupby']) : ''; - $q .= ( ! empty($this->parts['having']))? ' HAVING ' . implode(' AND ', $this->parts['having']) : ''; - $q .= ( ! empty($this->parts['orderby']))? ' ORDER BY ' . implode(', ', $this->parts['orderby']) : ''; - $q .= ( ! empty($this->parts['limit']))? ' LIMIT ' . implode(' ', $this->parts['limit']) : ''; - $q .= ( ! empty($this->parts['offset']))? ' OFFSET ' . implode(' ', $this->parts['offset']) : ''; + $q .= ( ! empty($this->_parts['select']))? 'SELECT ' . implode(', ', $this->_parts['select']) : ''; + $q .= ( ! empty($this->_parts['from']))? ' FROM ' . implode(' ', $this->_parts['from']) : ''; + $q .= ( ! empty($this->_parts['where']))? ' WHERE ' . implode(' AND ', $this->_parts['where']) : ''; + $q .= ( ! empty($this->_parts['groupby']))? ' GROUP BY ' . implode(', ', $this->_parts['groupby']) : ''; + $q .= ( ! empty($this->_parts['having']))? ' HAVING ' . implode(' AND ', $this->_parts['having']) : ''; + $q .= ( ! empty($this->_parts['orderby']))? ' ORDER BY ' . implode(', ', $this->_parts['orderby']) : ''; + $q .= ( ! empty($this->_parts['limit']))? ' LIMIT ' . implode(' ', $this->_parts['limit']) : ''; + $q .= ( ! empty($this->_parts['offset']))? ' OFFSET ' . implode(' ', $this->_parts['offset']) : ''; return $q; } else { - return $this->dql; + return $this->_dql; } } - public function parseResponse($response) - { - $array = Doctrine_Parser::load($response, $this->getFormat()); - - $hydrated = $this->hydrate($array, $this->getModel(), $this->config); - - return $hydrated; - } - public function buildUrl($array) { $url = ''; @@ -115,18 +108,6 @@ class Doctrine_Resource_Query extends Doctrine_Resource return $e[0]; } - public function setFormat($format) - { - $this->config['format'] = $format; - - return $this; - } - - public function getFormat() - { - return isset($this->config['format']) ? $this->config['format']:$this->defaultFormat; - } - /** * addSelect * adds fields to the SELECT part of the query @@ -253,7 +234,7 @@ class Doctrine_Resource_Query extends Doctrine_Resource */ public function distinct($flag = true) { - $this->parts['distinct'] = (bool) $flag; + $this->_parts['distinct'] = (bool) $flag; return $this; } @@ -267,7 +248,7 @@ class Doctrine_Resource_Query extends Doctrine_Resource */ public function forUpdate($flag = true) { - $this->parts[self::FOR_UPDATE] = (bool) $flag; + $this->_parts[self::FOR_UPDATE] = (bool) $flag; return $this; } @@ -446,7 +427,7 @@ class Doctrine_Resource_Query extends Doctrine_Resource */ public function parseQueryPart($queryPartName, $queryPart) { - $this->parts[$queryPartName][] = $queryPart; + $this->_parts[$queryPartName][] = $queryPart; return $this; } diff --git a/lib/Doctrine/Resource/Record.php b/lib/Doctrine/Resource/Record.php index 7ded8fd19..ff0439c2a 100644 --- a/lib/Doctrine/Resource/Record.php +++ b/lib/Doctrine/Resource/Record.php @@ -23,6 +23,7 @@ * Doctrine_Resource_Record * * @author Konsta Vesterinen + * @author Jonathan H. Wage * @package Doctrine * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version $Revision$ @@ -32,70 +33,117 @@ */ class Doctrine_Resource_Record extends Doctrine_Record_Abstract implements Countable, IteratorAggregate { - public $data = array(); - public $config = array(); - public $model = null; + protected $_data = array(); + protected $_model = null; + protected $_schema = null; - public function __construct($model, $config) + public function __construct($model, $loadRelations = true) { - $this->model = $model; - $this->config = $config; + $this->_model = $model; + + $schema = $this->getConfig('schema'); + + if (isset($schema['schema'][$model]) && $schema['schema'][$model]) { + $this->_schema = $schema['schema'][$model]; + } + + if (isset($schema['relations'][$model]) && $schema['relations'][$model]) { + $this->_schema['relations'] = $schema['relations'][$model]; + } + + $this->initialize($loadRelations); + } + + public function initialize($loadRelations = true) + { + if (!$this->_schema) { + return false; + } + + $schema = $this->_schema; + $relations = $this->_schema['relations']; + + if (isset($schema['columns'])) { + $columns = $schema['columns']; + + foreach ($columns as $column) { + if (!isset($this->_data[$column['name']]) || $this->_data[$column['name']]) { + $this->_data[$column['name']] = null; + } + } + } + + if (isset($schema['relations']) && $loadRelations) { + $relations = $schema['relations']; + + foreach ($relations as $relation) { + if ($relation['type'] === Doctrine_Relation::ONE) { + $this->_data[$relation['alias']] = Doctrine_Resource_Client::getInstance()->newRecord($relation['class'], false); + } else { + $this->_data[$relation['alias']] = Doctrine_Resource_Client::getInstance()->newCollection($relation['class']); + } + } + } + } + + public function getConfig($key = null) + { + return Doctrine_Resource_Client::getInstance()->getConfig($key); } public function get($get) { - if (!isset($this->data[$get])) { - $this->data[$get] = null; + if (!isset($this->_data[$get])) { + $this->_data[$get] = null; + } else { + $this->_data[$get] = Doctrine_Resource_Client::getInstance()->newRecord($get, false); } - return $this->data[$get]; + return $this->_data[$get]; } public function set($set, $value) { - $this->data[$set] = $value; + $this->_data[$set] = $value; } public function count() { - return count($this->data); + return count($this->_data); } public function getIterator() { - $data = $this->data; - - return new ArrayIterator($data); - } - - public function newRequest($type) - { - $request = array(); - $request['format'] = isset($this->config['format']) ? $this->config['format']:'xml'; - $request['type'] = $type; - $request['model'] = $this->model; - - return $request; + return new ArrayIterator($this->_data); } public function save() { - $request = $this->newRequest('save'); - $request['data'] = $this->toArray(); + $format = $this->getConfig('format') ? $this->getConfig('format'):'xml'; - $response = Doctrine_Resource::request($this->config['url'], $request); + $request = new Doctrine_Resource_Request(); + $request->set('format', $format); + $request->set('type', 'save'); + $request->set('model', $this->getModel()); + $request->set('data', $this->toArray()); - $array = Doctrine_Parser::load($response, $request['format']); + $response = $request->execute(); - $resource = new Doctrine_Resource(); - $this->data = $resource->hydrate(array($array), $this->model, $this->config)->getFirst()->data; + $array = Doctrine_Parser::load($response, $format); + + $this->_data = $request->hydrate(array($array), $this->_model)->getFirst()->_data; + } + + public function getModel() + { + return $this->_model; } public function toArray() { $array = array(); - foreach ($this->data as $key => $value) { + foreach ($this->_data as $key => $value) { if ($value instanceof Doctrine_Resource_Collection OR $value instanceof Doctrine_Resource_Record) { $array[$key] = $value->toArray(); } else { diff --git a/lib/Doctrine/Resource/Server.php b/lib/Doctrine/Resource/Server.php index 0f042060d..b7e1e56af 100644 --- a/lib/Doctrine/Resource/Server.php +++ b/lib/Doctrine/Resource/Server.php @@ -23,6 +23,7 @@ * Doctrine_Resource_Server * * @author Konsta Vesterinen + * @author Jonathan H. Wage * @package Doctrine * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @version $Revision$ @@ -30,20 +31,23 @@ * @link www.phpdoctrine.com * @since 1.0 */ -class Doctrine_Resource_Server extends Doctrine_Resource +class Doctrine_Resource_Server extends Doctrine_resource { - public $config = array(); - public $format = 'xml'; - - public function __construct($config) + static public function getInstance($config = null) { - $this->config = array_merge($config, $this->config); + static $instance; + + if (!$instance) { + $instance = new Doctrine_Resource_Server($config); + } + + return $instance; } public function executeSave($request) { - $model = $request['model']; - $data = $request['data']; + $model = $request->get('model'); + $data = $request->get('data'); $record = new $model(); $record->fromArray($data); @@ -54,31 +58,57 @@ class Doctrine_Resource_Server extends Doctrine_Resource public function executeQuery($request) { - $dql = $request['dql']; - $params = isset($request['params']) ? $request['params']:array(); + $dql = $request->get('dql'); + $params = $request->get('params') ? $request->get('params'):array(); $conn = Doctrine_Manager::connection(); return $conn->query($dql, $params)->toArray(true, true); } + public function executeLoad($request) + { + $path = '/tmp/' . rand() . '.' . $request->get('format'); + + $models = $this->getConfig('models') ? $this->getConfig('models'):array(); + + $export = new Doctrine_Export_Schema(); + $export->exportSchema($path, $request->get('format'), null, $models); + + $schema = Doctrine_Parser::load($path, $request->get('format')); + + unlink($path); + + return $schema; + } + public function execute($request) { if (!isset($request['type'])) { - throw new Doctrine_Resource_Exception('You must specify a request type: query or save'); + throw new Doctrine_Resource_Exception('You must specify a request type'); } $format = isset($request['format']) ? $request['format']:'xml'; $type = $request['type']; $funcName = 'execute' . Doctrine::classify($type); - $result = $this->$funcName($request); + $request = new Doctrine_Resource_Request($request); - return Doctrine_Parser::dump($result, $format); + if (method_exists($this, $funcName)) { + $result = $this->$funcName($request); + } else { + throw new Doctrine_Resource_Exception('Unknown Doctrine Resource Server function'); + } + + if ($result) { + return Doctrine_Parser::dump($result, $format); + } else { + return false; + } } public function run($request) { echo $this->execute($request); } -} +} \ No newline at end of file diff --git a/playground/index.php b/playground/index.php index 77f0fe315..2b011ce4a 100644 --- a/playground/index.php +++ b/playground/index.php @@ -7,18 +7,20 @@ require_once('data.php'); $action = isset($_REQUEST['action']) ? $_REQUEST['action']:'client'; if ($action == 'server') { - $config = array(); + $config = array('name' => 'Doctrine_Resource_Test_Server', + 'models' => $tables); - $server = new Doctrine_Resource_Server($config); + $server = Doctrine_Resource_Server::getInstance($config); $server->run($_REQUEST); + } else { $config = array('url' => 'http://localhost/~jwage/doctrine_trunk/playground/index.php?action=server'); - $client = new Doctrine_Resource_Client($config); - $record = $client->newRecord('User'); - $record->name = 'jon wage'; - $record->loginname = 'test'; - $record->save(); + $client = Doctrine_Resource_Client::getInstance($config); - print_r($record->toArray()); + $user = $client->newRecord('User'); + $user->name = 'jonathan h. wage'; + $user->save(); + + print_r($user->toArray()); } \ No newline at end of file