From 67eca1fcff3dbbc81aafb139aa957cd49832e456 Mon Sep 17 00:00:00 2001 From: Jeffrey Guo Date: Sun, 17 Aug 2014 21:33:11 +1200 Subject: [PATCH] assign one object to another corrected name convention and sql issue corrected grammar in description --- .../BehatExtension/Context/FixtureContext.php | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/src/SilverStripe/BehatExtension/Context/FixtureContext.php b/src/SilverStripe/BehatExtension/Context/FixtureContext.php index a55b70b..d5ee003 100644 --- a/src/SilverStripe/BehatExtension/Context/FixtureContext.php +++ b/src/SilverStripe/BehatExtension/Context/FixtureContext.php @@ -219,7 +219,59 @@ class FixtureContext extends BehatContext } } - + /** + * Assign a type of object to another type of object + * The base object will be created if it does not exist already + * Assumption: one object has relationship (has_one, has_many or many_many ) with the other object + * @example I assign the "TaxonomyTerm" "For customers" to the "Page" "Page1" + * @Given /^I assign (?:(an|a|the) )"(?[^"]+)" "(?[^"]+)" to (?:(an|a|the) )"(?[^"]+)" "(?[^"]+)"$/ + */ + public function stepIAssignObjToObj($type, $value, $relationType, $relationId) { + $class = $this->convertTypeToClass($type); + $relationClass = $this->convertTypeToClass($relationType); + + // Check if this fixture object already exists - if not, we create it + $relationObj = $this->fixtureFactory->get($relationClass, $relationId); + if(!$relationObj) $relationObj = $this->fixtureFactory->createObject($relationClass, $relationId); + + // Check if there is relationship defined in many_many (includes belongs_many_many) + $manyField = null; + $oneField = null; + if ($relationObj->many_many()) { + $manyField = array_search($class, $relationObj->many_many()); + } + if(empty($manyField) && $relationObj->has_many()) { + $manyField = array_search($class, $relationObj->has_many()); + } + if(empty($manyField) && $relationObj->has_one()) { + $oneField = array_search($class, $relationObj->has_one()); + } + if(empty($manyField) && empty($oneField)) { + throw new \Exception("'$relationClass' has no relationship (has_one, has_many and many_many) with '$class'!"); + } + + // Get the searchable field to check if the fixture object already exists + $temObj = new $class; + if(isset($temObj->Name)) $field = "Name"; + else if(isset($temObj->Title)) $field = "Title"; + else $field = "ID"; + + // Check if the fixture object exists - if not, we create it + $obj = \DataObject::get()->filter($field, $value)->first(); + if(!$obj) $obj = $this->fixtureFactory->createObject($class, $value); + // If has_many or many_many, add this fixture object to the relation object + // If has_one, set value to the joint field with this fixture object's ID + if($manyField) { + $relationObj->$manyField()->add($obj); + } else if($oneField) { + // E.g. $has_one = array('PanelOffer' => 'Offer'); + // then the join field is PanelOfferID. This is the common rule in the CMS + $relationObj->{$oneField . 'ID'} = $obj->ID; + } + + $relationObj->write(); + } + /** * Example: Given the "page" "Page 1" is not published *