Skip to content
This repository was archived by the owner on Oct 20, 2023. It is now read-only.

refs issue#83 fixing field merge with hasOne and hasMany associations #150

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 46 additions & 16 deletions Model/Behavior/InheritableBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class InheritableBehavior extends ModelBehavior {
* Set up the behavior.
* Finds parent model and determines type field settings
*
* @param Model $Model
* @param Model $Model Model to determine parent and type field setting
* @param array $config Behavior configuration
* @internal param \Model $model
* @return void
Expand All @@ -69,7 +69,7 @@ public function setup(Model $Model, $config = array()) {
* Before find callback
* Filter query conditions with the correct `type' field condition.
*
* @param Model $model
* @param Model $Model Model
* @param array $query Find query
* @return array Updated query
*/
Expand All @@ -95,9 +95,9 @@ public function beforeFind(Model $Model, $query) {
* After find callback
* In case of CTI inheritance, data contained in the 'ParentAlias' key are merged with Model data
*
* @param Model $Model
* @param array $results
* @param boolean $primary
* @param Model $Model Model
* @param array $results results
* @param bool $primary primary
* @return array Results
*/
public function afterFind(Model $Model, $results = array(), $primary = false) {
Expand Down Expand Up @@ -141,8 +141,8 @@ public function afterFind(Model $Model, $results = array(), $primary = false) {
*
* Set the `type' field before saving the record in case of STI model
*
* @param Model $Model
* @param array $options
* @param Model $Model Model
* @param array $options options
* @return true
*/
public function beforeSave(Model $Model, $options = array()) {
Expand All @@ -159,7 +159,7 @@ public function beforeSave(Model $Model, $options = array()) {
* After delete callback
* Deletes the parent model in case of CTI model
*
* @param Model $Model
* @param Model $Model Model
* @return true
*/
public function afterDelete(Model $Model) {
Expand All @@ -174,7 +174,7 @@ public function afterDelete(Model $Model) {
*
* Deconstructs complex types by calling model parent's method
*
* @param Model $Model
* @param Model $Model Model
* @param array $options
* @return true
*/
Expand All @@ -191,7 +191,7 @@ public function beforeValidate(Model $Model, $options = array()) {
/**
* Beforefind callback for STI models
*
* @param Model $Model
* @param Model $Model Model
* @param array $query Find query
* @return Updated query
*/
Expand Down Expand Up @@ -222,7 +222,7 @@ protected function _singleTableBeforeFind(Model $Model, $query) {
* BeforeSave callback for STI models
* Sets the inheritance field to the correct Model alias
*
* @param Model $Model
* @param Model $Model Model
* @return true
*/
protected function _singleTableBeforeSave(Model $Model) {
Expand All @@ -239,8 +239,8 @@ protected function _singleTableBeforeSave(Model $Model) {
/**
* Binds the parent model for a CTI model
*
* @param Model $Model
* @return boolean Success of the binding
* @param Model $Model Model
* @return bool Success of the binding
*/
public function classTableBindParent(Model $Model) {
$bind = array('belongsTo' => array(
Expand All @@ -250,18 +250,48 @@ public function classTableBindParent(Model $Model) {
'foreignKey' => $Model->primaryKey
)
));
$assocs = array_flip($Model->parent->getAssociated());
$ppk = $Model->parent->primaryKey;
if (array_key_exists('hasOne', $assocs)) {
$hasOne = $this->classParentAssociations($ppk, 'hasOne', $assocs);
$bind = array_merge($bind, $hasOne);
}
if (array_key_exists('hasMany', $assocs)) {
$hasMany = $this->classParentAssociations($ppk, 'hasMany', $assocs);
$bind = array_merge($bind, $hasMany);
}
$success = $Model->bindModel($bind, false);
//Putting the parent association as the first one, so any dependent join on the parent model will be in the right order
//Putting the parent association as the first one,
//so any dependent join on the parent model will be in the right order
$assoc = $Model->belongsTo[$Model->parent->alias];
unset($Model->belongsTo[$Model->parent->alias]);
$Model->belongsTo = array_merge(array($Model->parent->alias => $assoc), $Model->belongsTo);
return $success;
}

/**
* Return the parent model association for a CTI model
*
* @param string $ppk Parent primary key
* @param string $name Association name
* @param array $assoc Association parent array
* @return array Association parent model
*/

public function classParentAssociations($ppk, $name, $assoc) {
$data = array($name => array(
Hash::get($assoc, $name) => array(
'className' => Hash::get($assoc, $name),
'foreignKey' => $ppk
)
));
return $data;
}

/**
* Binds additional belongsTo association from the parent for a CTI model
*
* @param Model $Model
* @param Model $Model Model
* @param array $binds, additional models to bind. They will be filtered to left only belongsTo associations
*/
protected function _classTableBindContains(Model $Model, $binds) {
Expand All @@ -287,7 +317,7 @@ protected function _classTableBindContains(Model $Model, $binds) {
* After save callback for CTI models
* Saves data for the parent model
*
* @param Model $Model
* @param Model $Model Model
* @return true
*/
protected function _saveParentModel(Model $Model) {
Expand Down
36 changes: 32 additions & 4 deletions Test/Case/Model/Behavior/InheritableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ class InheritableAsset extends CakeTestModel {

public $name = 'Asset';

public $validate = array('title' => array('rule' => 'notEmpty'));
public $validate = array('title' => array('rule' => 'notBlank'));
}

class Asset extends CakeTestModel {

public $validate = array(
'title' => array('rule' => 'notEmpty'),
'title' => array('rule' => 'notBlank'),
'expiration' => array('rule' => 'date', 'allowEmpty' => true)
);
}
Expand All @@ -55,7 +55,7 @@ class InheritableLink extends InheritableAsset {

public $actsAs = array('Utils.Inheritable' => array('method' => 'CTI'));

public $validate = array('url' => array('rule' => 'notEmpty'));
public $validate = array('url' => array('rule' => 'notBlank'));
}

class InheritableImage extends InheritableAsset {
Expand All @@ -65,6 +65,16 @@ class InheritableImage extends InheritableAsset {
public $actsAs = array('Utils.Inheritable' => array('method' => 'CTI'));
}

class Person extends CakeTestModel {

public $hasOne = 'Address';
}

class Client extends Person {

public $actsAs = array('Utils.Inheritable' => array('method' => 'CTI'));
}


/**
* InheritableTest class
Expand All @@ -84,7 +94,9 @@ class InheritableTest extends CakeTestCase {
'plugin.utils.content',
'plugin.utils.asset',
'plugin.utils.link',
'plugin.utils.image'
'plugin.utils.image',
'plugin.utils.person',
'plugin.utils.address'
);

/**
Expand All @@ -108,6 +120,8 @@ public function setUp() {
$this->Asset = ClassRegistry::init('InheritableAsset');
$this->Link = ClassRegistry::init('InheritableLink');
$this->Image = ClassRegistry::init('InheritableImage');
$this->Client = ClassRegistry::init('Client');
$this->Person = ClassRegistry::init('Person');
}

/**
Expand Down Expand Up @@ -433,6 +447,20 @@ public function testComplexTypeValidation() {
$this->assertFalse($this->Link->validates());
}

/**
* testClassParentAssociations
*
* @link https://github.com/CakeDC/utils/issues/83
* @return void
*/
public function testClassParentAssociations() {
$parentAssociations = array_flip($this->Person->getAssociated());
$this->Client->Behaviors->load('Inheritable');
$this->Client->Behaviors->Inheritable->classParentAssociations($this->Client->parent->primaryKey, 'hasOne', $parentAssociations);
$this->Client->Behaviors->unload('Inheritable');
$this->assertTrue(isset($this->Client->Address));
}

/**
* Convenience function to assert Matches using Set::matches
*
Expand Down
40 changes: 40 additions & 0 deletions Test/Fixture/AddressFixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
* AddressFixture
*
*/
class AddressFixture extends CakeTestFixture {

/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'),
'person_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false),
'direction' => array('type' => 'text', 'null' => true, 'default' => null, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
'modified' => array('type' => 'datetime', 'null' => true, 'default' => null),
'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => 1)
),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')
);

/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'person_id' => 1,
'direction' => 'Lorem ipsum dolor sit amet, aliquet feugiat. Convallis morbi fringilla gravida, phasellus feugiat dapibus velit nunc, pulvinar eget sollicitudin venenatis cum nullam, vivamus ut a sed, mollitia lectus. Nulla vestibulum massa neque ut et, id hendrerit sit, feugiat in taciti enim proin nibh, tempor dignissim, rhoncus duis vestibulum nunc mattis convallis.',
'created' => '2015-07-08 23:12:27',
'modified' => '2015-07-08 23:12:27'
),
);

}
40 changes: 40 additions & 0 deletions Test/Fixture/BankAccountFixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
* BankAccountFixture
*
*/
class BankAccountFixture extends CakeTestFixture {

/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'),
'client_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false),
'number_account' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 50, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
'modified' => array('type' => 'datetime', 'null' => true, 'default' => null),
'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => 1)
),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')
);

/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'client_id' => 1,
'number_account' => 'Lorem ipsum dolor sit amet',
'created' => '2015-07-08 23:14:14',
'modified' => '2015-07-08 23:14:14'
),
);

}
42 changes: 42 additions & 0 deletions Test/Fixture/ClientFixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* ClientFixture
*
*/
class ClientFixture extends CakeTestFixture {

/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'),
'parent_id' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false),
'bank_account_id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false),
'number' => array('type' => 'integer', 'null' => true, 'default' => null, 'unsigned' => false),
'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
'modified' => array('type' => 'datetime', 'null' => true, 'default' => null),
'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => 1)
),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')
);

/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'parent_id' => 1,
'bank_account_id' => 1,
'number' => 1,
'created' => '2015-07-08 23:15:03',
'modified' => '2015-07-08 23:15:03'
),
);

}
38 changes: 38 additions & 0 deletions Test/Fixture/PersonFixture.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
/**
* PersonFixture
*
*/
class PersonFixture extends CakeTestFixture {

/**
* Fields
*
* @var array
*/
public $fields = array(
'id' => array('type' => 'integer', 'null' => false, 'default' => null, 'unsigned' => false, 'key' => 'primary'),
'name' => array('type' => 'string', 'null' => true, 'default' => null, 'length' => 50, 'collate' => 'utf8_general_ci', 'charset' => 'utf8'),
'created' => array('type' => 'datetime', 'null' => true, 'default' => null),
'modified' => array('type' => 'datetime', 'null' => true, 'default' => null),
'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => 1)
),
'tableParameters' => array('charset' => 'utf8', 'collate' => 'utf8_general_ci', 'engine' => 'InnoDB')
);

/**
* Records
*
* @var array
*/
public $records = array(
array(
'id' => 1,
'name' => 'Lorem ipsum dolor sit amet',
'created' => '2015-07-08 23:15:18',
'modified' => '2015-07-08 23:15:18'
),
);

}