Further model loading refactoring and refactored merge() in Doctrine_Record
This commit is contained in:
parent
0ac4d757c7
commit
542f9b0d72
106
lib/Doctrine.php
106
lib/Doctrine.php
@ -441,13 +441,13 @@ final class Doctrine
|
||||
private static $_debug = false;
|
||||
|
||||
/**
|
||||
* _loadedModels
|
||||
* _loadedModelFiles
|
||||
*
|
||||
* Array of all the loaded models and the path to each one for autoloading
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_loadedModels = array();
|
||||
private static $_loadedModelFiles = array();
|
||||
|
||||
/**
|
||||
* _validators
|
||||
@ -517,13 +517,44 @@ final class Doctrine
|
||||
foreach ($it as $file) {
|
||||
$e = explode('.', $file->getFileName());
|
||||
if (end($e) === 'php' && strpos($file->getFileName(), '.inc') === false) {
|
||||
self::$_loadedModels[$e[0]] = $file->getPathName();
|
||||
self::$_loadedModelFiles[$e[0]] = $file->getPathName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$loadedModels = array();
|
||||
|
||||
$modelFiles = array_keys(self::$_loadedModelFiles);
|
||||
|
||||
foreach ($modelFiles as $name) {
|
||||
if (class_exists($name)) {
|
||||
$declaredBefore = get_declared_classes();
|
||||
|
||||
if (self::isValidModelClass($name) && !in_array($name, $loadedModels)) {
|
||||
$loadedModels[] = $name;
|
||||
}
|
||||
} else {
|
||||
// Determine class names by the actual inclusion of the model file
|
||||
// The possibility exists that the class name(s) contained in the model
|
||||
// file is not the same as the actual model file name itself
|
||||
if (isset(self::$_loadedModelFiles[$name])) {
|
||||
require_once self::$_loadedModelFiles[$name];
|
||||
$declaredAfter = get_declared_classes();
|
||||
// Using array_slice since array_diff is broken is some versions
|
||||
$foundClasses = array_slice($declaredAfter, count($declaredBefore) - 1);
|
||||
if ($foundClasses) {
|
||||
foreach ($foundClasses as $name) {
|
||||
if (self::isValidModelClass($name) && !in_array($name, $loadedModels)) {
|
||||
$loadedModels[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::getLoadedModels(array_keys(self::$_loadedModels));
|
||||
return self::filterInvalidModels($loadedModels);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -541,57 +572,51 @@ final class Doctrine
|
||||
{
|
||||
if ($classes === null) {
|
||||
$classes = get_declared_classes();
|
||||
$classes = array_merge($classes, array_keys(self::$_loadedModels));
|
||||
$classes = array_merge($classes, array_keys(self::$_loadedModelFiles));
|
||||
}
|
||||
|
||||
$loadedModels = array();
|
||||
return self::filterInvalidModels($classes);
|
||||
}
|
||||
|
||||
/**
|
||||
* filterInvalidModels
|
||||
*
|
||||
* Filter through an array of classes and return all the classes that are valid models
|
||||
*
|
||||
* @param classes Array of classes to filter through, otherwise uses get_declared_classes()
|
||||
* @return array $loadedModels
|
||||
*/
|
||||
public static function filterInvalidModels($classes)
|
||||
{
|
||||
$validModels = array();
|
||||
|
||||
foreach ((array) $classes as $name) {
|
||||
try {
|
||||
$declaredBefore = get_declared_classes();
|
||||
$class = new ReflectionClass($name);
|
||||
if (self::isValidModelClass($class)) {
|
||||
$loadedModels[] = $name;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// Determine class names by the actual inclusion of the model file
|
||||
// The possibility exists that the class name(s) contained in the model
|
||||
// file is not the same as the actual model file name itself
|
||||
if (isset(self::$_loadedModels[$name])) {
|
||||
try {
|
||||
require_once self::$_loadedModels[$name];
|
||||
$declaredAfter = get_declared_classes();
|
||||
// Using array_slice since array_diff is broken is some versions
|
||||
$foundClasses = array_slice($declaredAfter, count($declaredBefore)-1);
|
||||
if ($foundClasses) {
|
||||
foreach ($foundClasses as $name) {
|
||||
$class = new ReflectionClass($name);
|
||||
if (self::isValidModelClass($class)) {
|
||||
$loadedModels[] = $name;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
continue;
|
||||
}
|
||||
if (self::isValidModelClass($name) && !in_array($name, $validModels)) {
|
||||
$validModels[] = $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $validModels;
|
||||
}
|
||||
return $loadedModels;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* isValidModelClass
|
||||
*
|
||||
* Checks whether a reflection class is a valid Doctrine model class
|
||||
* Checks if what is passed is a valid Doctrine_Record
|
||||
*
|
||||
* @param class A reflection class to validate
|
||||
* @param mixed $class Can be a string named after the class, an instance of the class, or an instance of the class reflected
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isValidModelClass($class)
|
||||
{
|
||||
if ($class instanceof Doctrine_Record) {
|
||||
$class = get_class($class);
|
||||
}
|
||||
|
||||
if (is_string($class) && class_exists($class)) {
|
||||
$class = new ReflectionClass($class);
|
||||
}
|
||||
|
||||
if ($class instanceof ReflectionClass) {
|
||||
// Skip the following classes
|
||||
// - abstract classes
|
||||
@ -600,13 +625,14 @@ final class Doctrine
|
||||
if (!$class->isAbstract() &&
|
||||
$class->isSubClassOf('Doctrine_Record') &&
|
||||
$class->hasMethod('setTableDefinition')) {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* getConnectionByTableName
|
||||
*
|
||||
@ -1001,7 +1027,7 @@ final class Doctrine
|
||||
return true;
|
||||
}
|
||||
|
||||
$loadedModels = self::$_loadedModels;
|
||||
$loadedModels = self::$_loadedModelFiles;
|
||||
|
||||
if (isset($loadedModels[$className]) && file_exists($loadedModels[$className])) {
|
||||
require_once($loadedModels[$className]);
|
||||
|
@ -670,12 +670,11 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
|
||||
* @param string $array
|
||||
* @return void
|
||||
*/
|
||||
|
||||
public function fromArray($array)
|
||||
public function fromArray($array, $deep = true)
|
||||
{
|
||||
$data = array();
|
||||
foreach ($array as $rowKey => $row) {
|
||||
$this[$rowKey]->fromArray($row);
|
||||
$this[$rowKey]->fromArray($row, $deep);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,7 +274,7 @@ class Doctrine_Data
|
||||
*/
|
||||
public function purge($models = array())
|
||||
{
|
||||
$models = Doctrine::getLoadedModels($models);
|
||||
$models = Doctrine::filterInvalidModels($models);
|
||||
|
||||
foreach ($models as $model)
|
||||
{
|
||||
|
@ -1124,7 +1124,7 @@ class Doctrine_Export extends Doctrine_Connection_Module
|
||||
*/
|
||||
public function exportClassesSql(array $classes)
|
||||
{
|
||||
$models = Doctrine::getLoadedModels($classes);
|
||||
$models = Doctrine::filterInvalidModels($classes);
|
||||
|
||||
$sql = array();
|
||||
|
||||
|
@ -1174,7 +1174,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
* @param boolean $deep - Return also the relations
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($deep = false, $prefixKey = false)
|
||||
public function toArray($deep = true, $prefixKey = false)
|
||||
{
|
||||
$a = array();
|
||||
|
||||
@ -1184,10 +1184,12 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
}
|
||||
$a[$column] = $value;
|
||||
}
|
||||
|
||||
if ($this->_table->getIdentifierType() == Doctrine::IDENTIFIER_AUTOINC) {
|
||||
$i = $this->_table->getIdentifier();
|
||||
$a[$i] = $this->getIncremented();
|
||||
}
|
||||
|
||||
if ($deep) {
|
||||
foreach ($this->_references as $key => $relation) {
|
||||
if ( ! $relation instanceof Doctrine_Null) {
|
||||
@ -1195,21 +1197,59 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($a, $this->_values);
|
||||
}
|
||||
public function fromArray($array)
|
||||
|
||||
/**
|
||||
* merge
|
||||
*
|
||||
* merges this record with an array of values
|
||||
* or with another existing instance of this object
|
||||
*
|
||||
* @param mixed $data Data to merge. Either another instance of this model or an array
|
||||
* @param bool $deep Bool value for whether or not to merge the data deep
|
||||
* @return void
|
||||
*/
|
||||
public function merge($data, $deep = true)
|
||||
{
|
||||
if ($data instanceof $this) {
|
||||
$array = $data->toArray($deep);
|
||||
} else if (is_array($data)) {
|
||||
$array = $data;
|
||||
}
|
||||
|
||||
return $this->fromArray($array, $deep);
|
||||
}
|
||||
|
||||
/**
|
||||
* fromArray
|
||||
*
|
||||
* @param string $array
|
||||
* @param bool $deep Bool value for whether or not to merge the data deep
|
||||
* @return void
|
||||
*/
|
||||
public function fromArray($array, $deep = true)
|
||||
{
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $key => $value) {
|
||||
if ($this->getTable()->hasRelation($key)) {
|
||||
$this->$key->fromArray($value);
|
||||
if ($this->getTable()->hasRelation($key) && $deep) {
|
||||
$this->$key->fromArray($value, $deep);
|
||||
} else if($this->getTable()->hasColumn($key)) {
|
||||
$this->set($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public function exportTo($type, $deep = false)
|
||||
|
||||
/**
|
||||
* exportTo
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $deep
|
||||
* @return void
|
||||
*/
|
||||
public function exportTo($type, $deep = true)
|
||||
{
|
||||
if ($type == 'array') {
|
||||
return $this->toArray($deep);
|
||||
@ -1217,6 +1257,15 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
return Doctrine_Parser::dump($this->toArray($deep, true), $type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* importFrom
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $data
|
||||
* @return void
|
||||
* @author Jonathan H. Wage
|
||||
*/
|
||||
public function importFrom($type, $data)
|
||||
{
|
||||
if ($type == 'array') {
|
||||
@ -1294,12 +1343,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
*
|
||||
* @return Doctrine_Record
|
||||
*/
|
||||
public function copy($deep = false)
|
||||
public function copy($deep = true)
|
||||
{
|
||||
if ($deep) {
|
||||
return $this->copyDeep();
|
||||
}
|
||||
|
||||
$data = $this->_data;
|
||||
|
||||
if ($this->_table->getIdentifierType() === Doctrine::IDENTIFIER_AUTOINC) {
|
||||
@ -1317,28 +1362,19 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* copyDeep
|
||||
* returns a copy of this object and all its related objects
|
||||
*
|
||||
* @return Doctrine_Record
|
||||
*/
|
||||
public function copyDeep() {
|
||||
$copy = $this->copy();
|
||||
|
||||
if ($deep) {
|
||||
foreach ($this->_references as $key => $value) {
|
||||
if ($value instanceof Doctrine_Collection) {
|
||||
foreach ($value as $record) {
|
||||
$copy->{$key}[] = $record->copyDeep();
|
||||
$rt->{$key}[] = $record->copy($deep);
|
||||
}
|
||||
} else {
|
||||
$copy->set($key, $value->copyDeep());
|
||||
$rt->set($key, $value->copy($deep));
|
||||
}
|
||||
}
|
||||
return $copy;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1476,66 +1512,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
|
||||
$this->_references[$name] = $rel->fetchRelatedFor($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* merge
|
||||
* merges this record with an array of values
|
||||
*
|
||||
* @param array $values
|
||||
* @return void
|
||||
*/
|
||||
public function merge(array $values)
|
||||
{
|
||||
foreach ($this->_table->getFieldNames() as $fieldName) {
|
||||
try {
|
||||
if (isset($values[$fieldName])) {
|
||||
$this->set($fieldName, $values[$fieldName]);
|
||||
}
|
||||
} catch (Doctrine_Exception $e) {
|
||||
// silence all exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mergeDeep
|
||||
* merges this record with an array of values
|
||||
*
|
||||
* @pre it is expected that the array keys representing a hasMany
|
||||
* relationship are the keyColumn set with INDEXBY
|
||||
*
|
||||
* @param array $values
|
||||
* @param $rmFromCollection if some records are not found in the array,
|
||||
* they are removed from the collection<->relation
|
||||
* @return void
|
||||
*/
|
||||
public function mergeDeep(array $values, $rmFromCollection = false)
|
||||
{
|
||||
$this->merge($values);
|
||||
|
||||
foreach ($values as $rel_name => $rel_data) {
|
||||
if ($this->getTable()->hasRelation($rel_name)) {
|
||||
$rel = $this->get($rel_name);
|
||||
if ($rel instanceof Doctrine_Collection) {
|
||||
foreach ($rel as $key => $record) {
|
||||
if (isset($rel_data[$key])) {
|
||||
$record->mergeDeep($rel_data[$key], $rmFromCollection);
|
||||
unset($rel_data[$key]);
|
||||
} elseif ($rmFromCollection) {
|
||||
$rel->remove($key);
|
||||
}
|
||||
}
|
||||
foreach ($rel_data as $key => $new_data) {
|
||||
$new_record = $rel->getTable()->create();
|
||||
$new_record->mergeDeep($new_data);
|
||||
$rel->add($new_record, $key);
|
||||
}
|
||||
} else {
|
||||
$rel->mergeDeep($rel_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* call
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user