From 8fe965cd0c20f5450f14c4d89949fd72d24c6dd4 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Thu, 9 Jul 2020 12:09:27 +0200 Subject: [PATCH] Factorize clone requests; add some tests (#7624) * Factorize clone requests; add some tests Remove all overrides (thanks to @cedric-anne!) Get from existing data Add a method to retrieve field name --- inc/calendar.class.php | 4 --- inc/calendar_holiday.class.php | 20 --------------- inc/calendarsegment.class.php | 20 --------------- inc/commondbchild.class.php | 35 +++++++++------------------ inc/commondbconnexity.class.php | 19 ++++++++------- inc/commondbrelation.class.php | 22 +++++++++++++++++ inc/contract.class.php | 4 --- inc/contract_item.class.php | 29 ---------------------- inc/contract_supplier.class.php | 20 --------------- inc/contractcost.class.php | 19 --------------- inc/features/clonable.class.php | 11 +-------- inc/projectcost.class.php | 20 --------------- inc/projecttask.class.php | 25 +++++-------------- tests/functionnal/Computer.php | 39 ++++++++++++++++++++++++++++++ tests/functionnal/Itil_Project.php | 30 +++++++++++++++++------ 15 files changed, 113 insertions(+), 204 deletions(-) diff --git a/inc/calendar.class.php b/inc/calendar.class.php index a046caed0a9..b0c231a3342 100644 --- a/inc/calendar.class.php +++ b/inc/calendar.class.php @@ -654,8 +654,4 @@ function updateDurationCache($calendars_id) { static function getDayNumberInWeek($date) { return (int)date('w', $date); } - - public function getOverrideFieldName(): string { - return 'calendars_id'; - } } diff --git a/inc/calendar_holiday.class.php b/inc/calendar_holiday.class.php index 77eb2928c7c..fd7f6403b61 100644 --- a/inc/calendar_holiday.class.php +++ b/inc/calendar_holiday.class.php @@ -47,26 +47,6 @@ class Calendar_Holiday extends CommonDBRelation { static public $checkItem_2_Rights = self::DONT_CHECK_ITEM_RIGHTS; - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - static::$items_id_1 => $items_id - ] - ]); - } - /** * @since 0.84 **/ diff --git a/inc/calendarsegment.class.php b/inc/calendarsegment.class.php index 96003f90fc8..ff3dff8cdcf 100644 --- a/inc/calendarsegment.class.php +++ b/inc/calendarsegment.class.php @@ -75,26 +75,6 @@ function prepareInputForAdd($input) { return parent::prepareInputForAdd($input); } - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - static::$items_id => $items_id - ] - ]); - } - /** * Duplicate all segments from a calendar to his clone * diff --git a/inc/commondbchild.class.php b/inc/commondbchild.class.php index 16906e2239a..d2540ac7f00 100644 --- a/inc/commondbchild.class.php +++ b/inc/commondbchild.class.php @@ -94,29 +94,6 @@ static function getSQLCriteriaToSearchForItem($itemtype, $items_id) { return null; } - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @since 9.5 - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - static::$itemtype => $itemtype, - static::$items_id => $items_id - ] - ]); - } - /** * @since 0.84 @@ -882,4 +859,16 @@ function affectChild($id, $items_id = 0, $itemtype = '') { return $this->update($input); } + + public static final function getItemField($itemtype): string { + if (isset(static::$items_id) && getItemtypeForForeignKeyField(static::$items_id) == $itemtype) { + return static::$items_id; + } + + if (isset (static::$itemtype) && preg_match('/^itemtype/', static::$itemtype)) { + return static::$items_id; + } + + throw new \RuntimeException('Cannot guess '); + } } diff --git a/inc/commondbconnexity.class.php b/inc/commondbconnexity.class.php index 9b4e14396b8..96fb84a16de 100644 --- a/inc/commondbconnexity.class.php +++ b/inc/commondbconnexity.class.php @@ -189,17 +189,18 @@ static function getItemsAssociatedTo($itemtype, $items_id) { */ static function getItemsAssociationRequest($itemtype, $items_id) { global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - 'itemtype' => $itemtype, - 'items_id' => $items_id - ] - ]); + return $DB->request(static::getSQLCriteriaToSearchForItem($itemtype, $items_id)); } + /** + * Get item field name for cloning + * + * @param string $itemtype Item type + * + * @return string + */ + abstract public static function getItemField($itemtype): string; + /** * get associated item (defined by $itemtype and $items_id) * diff --git a/inc/commondbrelation.class.php b/inc/commondbrelation.class.php index d8d60f0b8ee..e8849efa46a 100644 --- a/inc/commondbrelation.class.php +++ b/inc/commondbrelation.class.php @@ -1830,4 +1830,26 @@ static function countForMainItem(CommonDBTM $item, $extra_types_where = []) { } return $nb; } + + public static final function getItemField($itemtype): string { + if (isset(static::$items_id_1) && getItemtypeForForeignKeyField(static::$items_id_1) == $itemtype) { + return static::$items_id_1; + } + if (isset(static::$items_id_2) && getItemtypeForForeignKeyField(static::$items_id_2) == $itemtype) { + return static::$items_id_2; + } + + if (isset(static::$itemtype_1) && isset(static::$itemtype_2) && preg_match('/^itemtype/', static::$itemtype_1) && preg_match('/^itemtype/', static::$itemtype_2)) { + throw new \RuntimeException('Bad relation (' . $itemtype . ', ' .static::class . ', ' . static::$itemtype_1 . ', ' . static::$itemtype_2 . ')'); + } + + if (isset(static::$itemtype_1) && preg_match('/^itemtype/', static::$itemtype_1)) { + return static::$items_id_1; + } + if (isset(static::$itemtype_2) && preg_match('/^itemtype/', static::$itemtype_2)) { + return static::$items_id_2; + } + + throw new \RuntimeException('Cannot guess '); + } } diff --git a/inc/contract.class.php b/inc/contract.class.php index 58815d46226..4081907da3d 100644 --- a/inc/contract.class.php +++ b/inc/contract.class.php @@ -1795,8 +1795,4 @@ static function getMassiveActionsForItemtype(array &$actions, $itemtype, $is_del static function getIcon() { return "fas fa-file-signature"; } - - public function getOverrideFieldName(): string { - return 'contracts_id'; - } } diff --git a/inc/contract_item.class.php b/inc/contract_item.class.php index 63d7d82b8e9..0d881c93a91 100644 --- a/inc/contract_item.class.php +++ b/inc/contract_item.class.php @@ -696,33 +696,4 @@ static function getRelationMassiveActionsSpecificities() { return $specificities; } - - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - $where = []; - if ($itemtype == 'Contract') { - $where = [ - 'contracts_id' => $items_id - ]; - } else { - $where = [ - 'itemtype' => $itemtype, - 'items_id' => $items_id - ]; - } - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => $where - ]); - } } diff --git a/inc/contract_supplier.class.php b/inc/contract_supplier.class.php index a627bda703e..02ccec8f62f 100644 --- a/inc/contract_supplier.class.php +++ b/inc/contract_supplier.class.php @@ -343,24 +343,4 @@ static function showForContract(Contract $contract) { } echo ""; } - - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - static::$items_id_1 => $items_id - ] - ]); - } } diff --git a/inc/contractcost.class.php b/inc/contractcost.class.php index 8bfea7fb763..beb3ade1fd2 100644 --- a/inc/contractcost.class.php +++ b/inc/contractcost.class.php @@ -179,25 +179,6 @@ function rawSearchOptions() { return $tab; } - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - static::$items_id => $items_id - ] - ]); - } /** * Duplicate all costs from a contract template to its clone diff --git a/inc/features/clonable.class.php b/inc/features/clonable.class.php index b979d564672..8d2a1b56016 100644 --- a/inc/features/clonable.class.php +++ b/inc/features/clonable.class.php @@ -50,20 +50,10 @@ trait Clonable { */ abstract public function getCloneRelations() :array; - /** - * Get override field name - * - * @return string - */ - public function getOverrideFieldName(): string { - return 'items_id'; - } - public function post_clone($source, $history) { parent::post_clone($source, $history); $clone_relations = $this->getCloneRelations(); - $override_input[$this->getOverrideFieldName()] = $this->getID(); foreach ($clone_relations as $classname) { if (!is_a($classname, CommonDBConnexity::class, true)) { Toolbox::logWarning( @@ -75,6 +65,7 @@ public function post_clone($source, $history) { continue; } + $override_input[$classname::getItemField($this->getType())] = $this->getID(); $relation_items = $classname::getItemsAssociatedTo($this->getType(), $source->getID()); foreach ($relation_items as $relation_item) { $relation_item->clone($override_input, $history); diff --git a/inc/projectcost.class.php b/inc/projectcost.class.php index c62d7cee39d..eb33c4abb22 100644 --- a/inc/projectcost.class.php +++ b/inc/projectcost.class.php @@ -190,26 +190,6 @@ function rawSearchOptions() { return $tab; } - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - static::$items_id => $items_id - ] - ]); - } - /** * Duplicate all costs from a project template to its clone diff --git a/inc/projecttask.class.php b/inc/projecttask.class.php index 2594ecc8334..7e947d7270d 100644 --- a/inc/projecttask.class.php +++ b/inc/projecttask.class.php @@ -155,25 +155,6 @@ function cleanDBonPurge() { parent::cleanDBonPurge(); } - /** - * get the request results to get items associated to the given one (defined by $itemtype and $items_id) - * - * @param string $itemtype the type of the item we want the resulting items to be associated to - * @param string $items_id the name of the item we want the resulting items to be associated to - * - * @return array the items associated to the given one (empty if none was found) - **/ - static function getItemsAssociationRequest($itemtype, $items_id) { - global $DB; - - return $DB->request([ - 'SELECT' => 'id', - 'FROM' => static::getTable(), - 'WHERE' => [ - static::$items_id => $items_id - ] - ]); - } /** * Duplicate all tasks from a project template to his clone @@ -2075,4 +2056,10 @@ public function getInputFromVCalendar(VCalendar $vcalendar) { return $input; } + + + public function prepareInputForClone($input) { + $input['uuid'] = \Ramsey\Uuid\Uuid::uuid4(); + return parent::prepareInputForClone($input); + } } diff --git a/tests/functionnal/Computer.php b/tests/functionnal/Computer.php index 599b8d67b87..a909e6717c6 100644 --- a/tests/functionnal/Computer.php +++ b/tests/functionnal/Computer.php @@ -395,6 +395,41 @@ public function testClone() { ]) )->isGreaterThan(0); + //add device + $cpu = new \DeviceProcessor(); + $cpuid = $cpu->add( + [ + 'designation' => 'Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz', + 'frequence' => '1700' + ] + ); + + $this->integer((int)$cpuid)->isGreaterThan(0); + + $link = new \Item_DeviceProcessor(); + $linkid = $link->add( + [ + 'items_id' => $id, + 'itemtype' => 'Computer', + 'deviceprocessors_id' => $cpuid + ] + ); + $this->integer((int)$linkid)->isGreaterThan(0); + + //add document + $document = new \Document(); + $docid = (int)$document->add(['name' => 'Test link document']); + $this->integer($docid)->isGreaterThan(0); + + $docitem = new \Document_Item(); + $this->integer( + $docitem->add([ + 'documents_id' => $docid, + 'itemtype' => 'Computer', + 'items_id' => $id + ]) + )->isGreaterThan(0); + //clone! $added = $computer->clone(); $this->integer((int)$added)->isGreaterThan(0); @@ -437,5 +472,9 @@ public function testClone() { ) )->isIdenticalTo($expected); } + + //check processor has been cloned + $this->boolean($link->getFromDBByCrit(['itemtype' => 'Computer', 'items_id' => $added]))->isTrue(); + $this->boolean($docitem->getFromDBByCrit(['itemtype' => 'Computer', 'items_id' => $added]))->isTrue(); } } diff --git a/tests/functionnal/Itil_Project.php b/tests/functionnal/Itil_Project.php index f432a80c580..ff9a10c3a31 100644 --- a/tests/functionnal/Itil_Project.php +++ b/tests/functionnal/Itil_Project.php @@ -84,14 +84,30 @@ public function testLink() { )->isEqualTo(count($items)); } - // Clone project should clone its links to ITIL items + //add a task + $ptask = new \ProjectTask(); + $ptid = (int)$ptask->add([ + 'name' => 'Task for test project Clone', + 'projects_id' => $baseProjectId + ]); + $this->integer($ptid)->isGreaterThan(0); + + // Clone project should clone its links to ITIL items and task + $cloneProjectId = (int)$project->add([ + 'name' => 'Some project clone', + '_oldID' => $baseProjectId, + ]); + $this->integer($cloneProjectId)->isGreaterThan(0); + + $this->integer($cloneProjectId)->isNotEqualTo($baseProjectId, 'Project has not been cloned (same id)!'); + $this->integer( - (int)$project->add([ - 'name' => 'Some project clone', - '_oldID' => $baseProjectId, - ]) - )->isGreaterThan(0); - $cloneProjectId = $project->fields['id']; + countElementsInTable($ptask::getTable(), ['projects_id' => $baseProjectId]) + )->isEqualTo(1); + + $this->integer( + countElementsInTable($ptask::getTable(), ['projects_id' => $cloneProjectId]) + )->isEqualTo(1); $this->integer( countElementsInTable($itil_project::getTable(), ['projects_id' => $cloneProjectId])