:: Version 3.0.0 ::

Force a field to be mandatory on sub-classes only

Prerequisite: You must be familiar with the wiki syntax and have already created an extension.

learning:
Force a field to be filled for some sub-classes only
level:
Intermediate
domains:
PHP, Constrain
min version:
2.1.0

This use case is just one way of forcing a field to be provided.

This method can force a field to be provided, on the Console, CSV import and in the Portal, FIXMECSV import to be checked.
But it does not work for DataSynchro and REST/JSON API.

Mandatory for Datacenter devices

In this use case, we want the location_id field declared on the PhysicalDevice class to be mandatory on DatacenterDevice only. To summarize:

  • Location must be mandatory on every classes under DatacenterDevice: NAS, Network Device, SAN switch, Server, Storage System and Tape library,
  • Location must remains optional on all other Physical Devices classes, such as Mobile Phone for eg.

FYI: In the standard datamodel, DatacenterDevice is one of the child class of PhysicalDevice and location_id is an optional field on Physical Devices.

This case is tricky as iTop Datamodel does not allow to overwrite on a sub-class, an attribute defined on a parent class. location_id field is declared on PhysicalDevice class which is the parent class of DatacenterDevice.

This code will fail at datamodel compilation, because location_id is not directly a field of DatacenterDevice class:
itop_design / classes
  <class id="DatacenterDevice">
    <fields>
      <field id="location_id">
        <is_null_allowed _delta="redefine">false</is_null_allowed>
      </field>
    </fields>
  </class>

To adress this use case, we must overload 2 methods, one for the “Creation Form” and one for the “Modify Form”. We force location to be provided at creation and we prevent location from being removed on modification. Location can still be changed in object modification form.

class:DatacenterDevice
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
{       
    // This function is invoked when the object is EDITED on the Console
    // It is called for each and every field of the object, 
    // but we just want to change the behavior for a single field
    if ($sAttCode == 'location_id')
    {
        // Combine our mandatory Flag with those impose by a parent class
        return(OPT_ATT_MANDATORY | parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState));
    }
    return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
}
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
{       
    // This function is invoked when the object is CREATED on the Console
    // It is called for each and every field of the object, 
    // but we just want to change the behavior for a single field
    if (($sAttCode == 'location_id'))
    {
        // Combine our mandatory Flag with those impose by a parent class
        return(OPT_ATT_MANDATORY | parent::GetInitialStateAttributeFlags($sAttCode, $aReasons));
    }
    // For other fields than "location_id" ask the parent class to do the job
    return parent::GetInitialStateAttributeFlags($sAttCode, $aReasons);
}
We are using location_id and not location_name because AttributeExternalField are not requested in the form, only the id is

Migration: No visible effect on setup, but objects not compliant can no more be modified in the Console or Portal, until a location is provided. Create an audit rule to retrieve objects not compliant to this new constrain and fix them.

Only Server and Network Devices

In this use case, we want the location_id field to be mandatory for Server and NetworkDevice but not for the other sub-classes of PhysicalDevice.

The solution is similar to the above case, just declare the above methods on each class Server and NetworkDevice.

class:Server
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
{ ... }
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
{ ...}
class:NetworkDevice
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
{ ... }
public function GetInitialStateAttributeFlags($sAttCode, &$aReasons = array())
{ ...}

All DatacenterDevice but Tape library

This use case: we want the location_id field to be mandatory for all DatacenterDevice except for Tape library

The solution is similar to the above case, just declare the above methods on class DatacenterDevice and within the function test if the finalclass is not TapeLibrary.

Here is the method to get and test the finalclass value within PHP method

If ($this->Get('finalclass') != 'TapeLibrary') { ...
3_0_0/customization/mandatory-field-subclass.txt · Last modified: 2021/07/06 15:44 (external edit)
Back to top
Contact us