Give us contact

Do you prefer to ask us directly?

Call us +420 605 203 938 (the Czech Republic)

or use this contacts

AyMINE

Related links


FI - Finance Management

Export collection of objects

Universally usable export of the object collection with

Export of objects always starts with single or more roots. Export methods of each object request export themselves as well as all related objects.
Scope of the export is determined by input collection of objects (typically defined by user).

Export functionality description

Export flow-chart scheme:

See the Import-Export section for description of objects.

Export phases

Export has two phases

Phase 1: Identify objects for export

  • In this phase each object starting the root adds object to export to the list
  • Each inserted object is called to add other objects. However, for each object instance is the export register method called only once. Object can even reject export

Phase 2: Export identified object

In this phase method works with collection from the 1st phase. No new object could be inserted to the list

Each object from the list is called to export itself. In This step each objects exports its own data but nothing more.

Right control

User cannot export object that (s)he has not right to see.

Export calls right control for each object included to the export. It is called by the export process and object cannot over skip that.

Compare import and export

Import method is more complicated than export because it should manage the referential integrity. Export method is quite straightforward in this case.

Import method simply try to import as much as possible from the exported package. The import implementation does not contain any internal business logic.
Export is more complicated in that. The exported object method decides what other objects shall also be exported with them. It depends on the business logic and different type of export might result in the different list of related exported objects.

Export examples

Export methodology (IQMS system) exports all parts of the methodology including task patterns (working procedure). But it does not export any data about really processed tasks or about the history of the task pattern updated (task or activity records). Neither of them is relevant for methodology

Export task or even task pattern for audit purposes will contain list of all activities (tskActivityRec) that are not part of the methodology export.

Objects supporting export-import

Although export / import functions is supported by abstract ancestor of all objects, each object (or family of objects) might define its own support both for import and export. At least it shall manage the relationsships to other objects – typically create a requiest for exporting subordinated objects or other related objects.

Prepare object export

Support could be quite easy but the default method does not export anything:


/** Called during export should prepare object attributes for export
 * Objects has full access to its loaded data in this function and can:
   * * save additional data necessary for import
   * * clear some fields that should not be exported
   */
protected function prepareExport(frmEIManager $manager, frmEIObjEnv $env): void
{
   /* nothing, descendant can ovveride  */
}

Persistent ancestor export or internal fields of the object and manages relations to the system objects (they are mostly nullified). Objects precess export steps that are not covered by the persistent ancestor.

PrepareExport is overrided in case that:

  • Object exports data about relations – stores information about exported related objects (guid) to be able to find them durin import

Method never calls methods of another objects.

Nevertheless, method is used to export information about related object.

Export definition example

Task pattern has linked project roles that gets the task created from pattern in a project. Links are stored in the M:N relation and the task pattern should manage export and import of the relation:

Export relations
   protected function prepareExport(frmEIManager $manager, frmEIObjEnv $env): void
   {
      ...

      // manage export of the relations between defTask – only relations to this objects are managed
      $db = static::MyDB();
      $qRelations = $db->objQuery(/*...find all realation*/);
      if ($qRelations) $env->transData['relations'] = $qRelations
      }
      ...
   }

initExport

public static function initExport(frmEIManager $manager, int $objID): frmEIObjEnv|false

Initialise export – persistant ancestor checks rights of the user to work with object -> The ancestor should be called at first. After the control it invodes makeExport method that makes export technically.

There are not reason to override the initExport method except:

  • Master object that manages the export (area) calls initExport for all objects that shall be exported
  • It calles initExport... methods of the related objects which export is not initialised by default – slave relation-depenedent objects are not directly identified by the master object (area/methodlogy etc.) adn the initExport of single related object should initiate their export (see later the method initExportFromObject)
  • Objects that are not exportable, return directly false and do not call the ancestor
Import relations

Import of the relatons should check if related object is alread imported. Only if it is imported the relations could be created. If not, method returns status frmEIObjEnvStatus::partlyImported and import is called again.

Remember: Method shall mark imported relations as imported because it can be called repeatedly with some relations imported and some not.

   public function makeImport(frmEIManager $manager, frmEIObjEnv $env): frmEIObjEnvStatus
   {
      if ($lret === frmEIObjEnvStatus::totalyImported && isset($env->transData['relations'])) {
         // import relations
         foreach ($env->transData['relations'] as $rel) {
            if (!isset($rel->imported)) {
               $ret = $manager->isObject(__CLASS__, $rel->beforeID);   // ch
               switch ($ret) {
                  case frmEIManager::obj_notImported:
                     $beforeID = (new objLinkData(__CLASS__))->getObjFromGuid($rel->guid, $manager->sysClientID);
                     if (!isset($beforeID)) {
                        $manager->log->log('WARNING', __CLASS__ .  " {$this->name} lost single relation to the object. No couterpart available");
                        $rel->imported = true;  // not object to link
                     }
                     break;
                  case frmEIManager::obj_unloaded:  // counterpart available but not yet loaded
                     $ret = frmEIObjEnvStatus::partlyImported;
                     break;
                  default: // return id of the imported object
                     $beforeID = $ret;
                     $rel->imported = true;
               }
               if (isset($beforeID)) {
                  $insData['beforeID'] = $beforeID;
                  if (isset($rel->gapDelay)) $insData['gapDelay'] = $rel->gapDelay;
                  if (isset($rel->shortDesc)) $insData['shortDesc'] = $rel->shortDesc;
                  $tskDB->makeINSERT('tskRelBefAfter', $insData);
                  $rel->imported = true;
               }
            }
         }         
      }
      ...
   }


Make export

Export is made by method makeExport. Method is quite universal and objects rarely needs to change it. In fact, no one object have ever needed to change directly the method makeExport directly because all related data could be exported in by the prepareEport method called in the right time during the export

/** Export all content to the envelope
    * 
    * REMEMBER: Requires defined persistent object including attributes!
    * * Do not include database-managed attributes dtLastModif and dtCreated are not intended to be in the attribute list
    */
   public static function makeExport(frmEIManager $manager, frmEIObjEnv $env)

Export / Import slave object – object translation

Export of a slave object is always initiated by master object. During the import slave object could be imported after the the master object.

Typical example of the slave object is the translation to another language. Translation is stored in the object sysObjTranslation and the relation to the master object is stored in the common pairs of fields objectName / objectID.

Object translation export

Export should be initiated by master. In the tsk module the export is initiated by the tskPersistent object so that all descendants (all objects from the tsk module )

Export is quiite simple. When called method exports all translation related to the master object:

/** Prepare for export
 * – translations are always called by master object
*/
public static function initExportFromObject(frmEIManager $manager, string $objectName, string $objectID): void
{
   if ($objectName == __CLASS__) return;    // protection against stupid recursion
   $list = static::MyDB()->getSQLIDList("SELECT sysObjTranslationID FROM sysObjTranslation WHERE objectName = '$objectName' AND objectID = $objectID");
   if (count($list) == 0) return;   // no relations available
   foreach ($list as $oID) {
      $manager->addExportedObject(__CLASS__, $oID);
   }
}

Persistent ancestor tskPersistent calls:

sysObjTranslation::initExportFromObject($manager, $objectName, $objectID);

Object translation import

Import is called automatically the import manager. (Manager imports all object in the export list). The slave object

  • Checks if master object exists and is already imported. (Remember, that master object might never exists in import – even when exported, its import might be rejected for some reason, typically when it is in conflict with some other object already existing in the target environment. )
  • If master object is not yet imported, the slave object waits for next turn and tries the master object again
  • If master object is already imported, its new objectID replace the objectID from the source environment and the object is imported

Example of the translation import:

/** Look for referenced objects and import translation when translatated object is already in the database */
public function makeImport(frmEIManager $manager, frmEIObjEnv $env): frmEIObjEnvStatus
{
   $ret = $manager->isObject($this->objectName, $this->objectID);
   switch ($ret) {
      case frmEIManager::obj_notImported: return frmEIObjEnvStatus::neverImported;
      case frmEIManager::obj_unloaded: return frmEIObjEnvStatus::notImported;
      default: 
         $this->objectID = $ret;
         return parent::makeImport($manager, $env);
   }
}