class_sinapsRequest.inc 20.41 KiB
<?php
/*
  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
  Copyright (C) 2017-2019 FusionDirectory
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
class sinapsRequestException extends Exception
class sinapsRequest
  protected $data;
  public function __construct($xml)
    $this->data = new SimpleXMLElement($xml);
    if (!isset($this->data->domaine)) {
      throw new sinapsRequestException('XML content is missing "domaine" tag');
    if (!isset($this->data->domaine['code'])) {
      throw new sinapsRequestException('"domaine" tag is missing "code" attribute');
    if (!isset($this->data->domaine->donnees->operation)) {
      throw new sinapsRequestException('XML content is missing "domaine>donnees>operation" tag');
    if (!isset($this->data->domaine->donnees->operation['codeOperation'])) {
      throw new sinapsRequestException('"operation" tag is missing "codeOperation" attribute');
    if (!isset($this->data->domaine->identifiantTransaction)) {
      throw new sinapsRequestException('"identifiantTransaction" tag is missing from "domaine" tag');
  public function codeDomaine()
    return $this->data->domaine['code'];
  public function codeOperation()
    return $this->data->domaine->donnees->operation['codeOperation'];
  public function operationVersion()
    return $this->data->domaine->donnees->operation['version'];
  public function identifiantTransaction()
    return $this->data->domaine->identifiantTransaction;
  public function getOperationStructure()
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
return $this->data->domaine->donnees->operation->structure; } public function getOperationPersonne() { return $this->data->domaine->donnees->operation->personne; } public static function acquittementFonctionnel($responseCode = 200, $codeAcquittement = 0, $message = '', $identifiantObjApp = NULL, $synchrone = TRUE) { $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?> <Acquittement xmlns:acq="http://referentiels.SINAPS.amue.fr/acquittementFonctionnel"> </Acquittement>'); $xml->addChild('ResponseCode', $responseCode); $xml->addChild('messageAcquittement', $message); $xml->addChild('codeAcquittement', $codeAcquittement); if ($identifiantObjApp) { $xml->addChild('identifiantObjApp', $identifiantObjApp); } else { $xml->addChild('identifiantObjApp'); } if ($synchrone) { /* Hack because SINAPS API makes no sense and needs a prefix for Acquittement only for synchrone mode */ return preg_replace( array('|<Acquittement |', '|</Acquittement>$|'), array('<acq:Acquittement ', '</acq:Acquittement>'), $xml->asXML(), 1 ); } else { return $xml->asXML(); } } public function acquittementTechnique($responseCode = 200, $message = '') { $xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?> <WebServiceHTTPResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="acquittementTechnique.xsd"> </WebServiceHTTPResponse>'); $xml->addChild('IdentifiantTransaction', $this->identifiantTransaction()); $xml->addChild('ResponseCode', $responseCode); $xml->addChild('ResponseMessage', $message); return $xml->asXML(); } public function getSupannEntiteValues($identifiantApplication, $identifiantApplicationSync, $uuidPrefix, $ldapUuidToCodeEntiteCallback) { $structure = $this->getOperationStructure(); $now = new DateTime(); $mapping = array( 'libelle20' => array('entite','ou'), 'descriptifLong' => array('entite','description'), 'codeStructure' => array('entite','supannCodeEntite'), 'codeSousType' => array('entite','supannTypeEntite'), 'dateDebutValidite' => array('supannStructureExt','fdSupannStartDate'), 'dateFinValidite' => array('supannStructureExt','fdSupannEndDate'), ); $values = array( 'entite' => array( 'supannRefId' => array(), 'postalAddress' => '', 'supannCodeEntiteParent' => array(), ), ); $uuid = '';
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
if (isset($structure->referenceCroisee->identifiantsExternes)) { foreach ($structure->referenceCroisee->identifiantsExternes as $ref) { if ($ref->identifiantApplication == $identifiantApplication) { $uuid = $ref->identifiantExterne; } elseif (in_array($ref->identifiantApplication, $identifiantApplicationSync)) { $values['entite']['supannRefId'][] = '{'.$ref->identifiantApplication.'}'.$ref->identifiantExterne; } } } if (empty($uuid)) { $uuid = static::genUUID(); } array_unshift($values['entite']['supannRefId'], '{'.$uuidPrefix.'}'.$uuid); foreach ($mapping as $sinapsAttr => list($fdTab,$fdAttr)) { if (isset($structure->$sinapsAttr)) { $values[$fdTab][$fdAttr] = (string)$structure->$sinapsAttr; } else { $values[$fdTab][$fdAttr] = ''; } } if (isset($structure->methodesDeContact->methodeDeContact)) { foreach ($structure->methodesDeContact->methodeDeContact as $method) { if (!$this->checkValidite($method, $now)) { continue; } switch ((string)$method->codeTypeMethodeContact) { case 'ADR': if ((string)$method->adresse->temoinAdressePrincipale != 'true') { trigger_error('Ignore adresse non principale'); continue; } $adresse = $this->convertAddress($method->adresse); if ($adresse === FALSE) { trigger_error('Ignore adresse non FR non ETR'); continue; } $values['entite']['postalAddress'] = $adresse; break; default: trigger_error('ignoring codeTypeMethodeContact '.$method->codeTypeMethodeContact); } } } if (isset($structure->liensStructure->lienStructure)) { foreach ($structure->liensStructure->lienStructure as $lienStructure) { if (((string)$lienStructure->codeTypeLien == 'HIE') && isset($lienStructure->codeStructureMere)) { if (!$this->checkValidite($lienStructure, $now)) { continue; } $mereUUID = $this->getUUIDFromReferenceCroisee($identifiantApplication, $lienStructure->referenceCroisee); if (!empty($mereUUID)) { $values['entite']['supannCodeEntiteParent'][] = $ldapUuidToCodeEntiteCallback($mereUUID)['supannCodeEntite']; } } } } return $values; } public function getUserValues($identifiantApplication, array $identifiantApplicationSync, $uuidPrefix, $ldapUuidToCodeEntiteCallback, array $userRoles) { $personne = $this->getOperationPersonne(); $now = new DateTime(); $mapping = array(
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
'civilite' => array('supannAccount','supannCivilite'), 'nomUsage' => array('user','sn'), 'dateNaissance' => array('personalInfo','dateOfBirth'), 'sexe' => array('personalInfo','gender'), ); $values = array( 'lock' => FALSE, 'user' => array( 'homePhone' => '', 'postalAddress' => '', 'homePostalAddress' => '', 'employeeNumber' => '', ), 'supannAccount' => array( 'supannRefId' => array(), 'supannEntiteAffectation' => array(), 'supannRoleGenerique' => array(), 'supannTypeEntiteAffectation' => array(), 'supannRoleEntite' => array(), 'supannActivite' => array(), 'supannEmpCorps' => '', 'supannEntiteAffectationPrincipale' => '', ), 'personalInfo' => array( 'fdPrivateMail' => array(), ), ); $uuid = ''; if (isset($personne->referenceCroisee->identifiantsExternes)) { foreach ($personne->referenceCroisee->identifiantsExternes as $ref) { if ($ref->identifiantApplication == $identifiantApplication) { $uuid = (string)$ref->identifiantExterne; } elseif (in_array($ref->identifiantApplication, $identifiantApplicationSync)) { $values['supannAccount']['supannRefId'][] = '{'.$ref->identifiantApplication.'}'.$ref->identifiantExterne; } if ($ref->identifiantApplication == 'SAP') { $values['user']['employeeNumber'] = $ref->identifiantExterne; } } } if (empty($uuid)) { $uuid = static::genUUID(); } array_unshift($values['supannAccount']['supannRefId'], '{'.$uuidPrefix.'}'.$uuid); /* Check if the user still has at least one role which means he exists, otherwise this is a deletion */ $userRoleExists = array(); foreach ($userRoles as $typeRole) { if (preg_match('|^([^/]+)/(.+)$|', $typeRole, $m)) { $userRoleExists[$m[1]][] = $m[2]; } else { $userRoleExists[$typeRole] = TRUE; } } $deletion = TRUE; if (isset($personne->rattachements->rattachement)) { foreach ($personne->rattachements->rattachement as $rattachement) { if (isset($rattachement->roles->role)) { foreach ($rattachement->roles->role as $role) { if (isset($userRoleExists[(string)$role->typeRole])) { if ($userRoleExists[(string)$role->typeRole] === TRUE) { $deletion = FALSE; break 2; } if (in_array_ics((string)$role->externe->typeExterne, $userRoleExists[(string)$role->typeRole])) { if (!empty($role->externe->identifiantStructureInterne)) {
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
/* Store identifiantStructureInterne in supannEntiteAffectationPrincipale */ $UUID = (string)$role->externe->identifiantStructureInterne; $entite = $ldapUuidToCodeEntiteCallback($UUID); if (isset($entite['supannTypeEntite'])) { $values['supannAccount']['supannTypeEntiteAffectation'][] = $entite['supannTypeEntite']; } $values['supannAccount']['supannEntiteAffectation'][] = $entite['supannCodeEntite']; $values['supannAccount']['supannEntiteAffectationPrincipale'] = $entite['supannCodeEntite']; } $deletion = FALSE; break 2; } } } } } } if ($deletion) { /* This is a deletion */ /* Store current date as end of contract */ $values['personalInfo']['fdContractEndDate'] = $now->format('d.m.Y'); /* Lock the account */ $values['lock'] = TRUE; /* Remove all contact info */ $values['user']['telephoneNumber'] = ''; $values['user']['facsimileTelephoneNumber'] = ''; $values['user']['mobile'] = ''; $values['mailAccount'] = FALSE; return $values; } foreach ($mapping as $sinapsAttr => list($fdTab,$fdAttr)) { if (isset($personne->$sinapsAttr)) { $values[$fdTab][$fdAttr] = (string)$personne->$sinapsAttr; } else { $values[$fdTab][$fdAttr] = ''; } } if (isset($personne->prenoms)) { $values['user']['givenName'] = preg_replace('/;.*$/', '', $personne->prenoms); } if (isset($personne->methodesDeContact->methodeContact)) { foreach ($personne->methodesDeContact->methodeContact as $method) { if (!$this->checkValidite($method, $now)) { continue; } switch ((string)$method->typeMethodeContact) { case 'TELPERSO': $values['user']['homePhone'] = (string)$method->valeur; break; case 'MAILPERSO': $values['personalInfo']['fdPrivateMail'][] = (string)$method->valeur; break; case 'ADR': if ((string)$method->adresse->temoinAdressePrincipale != 'true') { trigger_error('Ignore adresse non principale'); continue; } $adresse = $this->convertAddress($method->adresse); if ($adresse === FALSE) { trigger_error('Ignore adresse non FR non ETR'); continue; } if ((string)$method->adresse->codeTypeAdresse == 'ADRPERSO') { $values['user']['homePostalAddress'] = $adresse; } else { $values['user']['postalAddress'] = $adresse; }
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
break; default: trigger_error('ignoring codeTypeMethodeContact '.$method->typeMethodeContact); } } } if (isset($personne->rattachements->rattachement)) { foreach ($personne->rattachements->rattachement as $rattachement) { if (!$this->checkValidite($rattachement, $now)) { continue; } if (isset($rattachement->roles->role)) { foreach ($rattachement->roles->role as $role) { if (!$this->checkValidite($role, $now)) { continue; } if ($role->typeRole != 'PR') { continue; } if (isset($role->personneRessource->affectations->affectation)) { $quotiteMax = NULL; foreach ($role->personneRessource->affectations->affectation as $affectation) { if (!$this->checkValidite($affectation, $now)) { continue; } $UUID = (string)$affectation->identifiantStructureInterne; $quotite = (isset($affectation->quotite) ? (int)$affectation->quotite : 0); if (!empty($UUID)) { $entite = $ldapUuidToCodeEntiteCallback($UUID); if (isset($entite['supannTypeEntite'])) { $values['supannAccount']['supannTypeEntiteAffectation'][] = $entite['supannTypeEntite']; } $values['supannAccount']['supannEntiteAffectation'][] = $entite['supannCodeEntite']; if (($quotiteMax === NULL) || ($quotite > $quotiteMax)) { $quotiteMax = $quotite; $values['supannAccount']['supannEntiteAffectationPrincipale'] = $entite['supannCodeEntite']; } } } } if (isset($role->personneRessource->elementsDeCarriere->elementCarriere)) { foreach ($role->personneRessource->elementsDeCarriere->elementCarriere as $elementCarriere) { if (!$this->checkValidite($elementCarriere, $now)) { continue; } /* Warning: supannEmpCorps and employeeType are mono-value so we replace them */ if (isset($elementCarriere->corps)) { $values['supannAccount']['supannEmpCorps'] = (string)$elementCarriere->corps; } if (isset($elementCarriere->bapReferens)) { $values['supannAccount']['supannActivite'][] = (string)$elementCarriere->bapReferens; } } } } } if (isset($rattachement->fonctionsOccupees->fonctionOccupee)) { foreach ($rattachement->fonctionsOccupees->fonctionOccupee as $fonctionOccupee) { if (!$this->checkValidite($fonctionOccupee, $now)) { continue; } $values['supannAccount']['supannRoleGenerique'][] = (string)$fonctionOccupee->fonctionRh; $UUID = (string)$fonctionOccupee->identifiantStructureInterne; if (!empty($UUID)) { $entite = $ldapUuidToCodeEntiteCallback($UUID, TRUE); $values['supannAccount']['supannTypeEntiteAffectation'][] = $entite['supannTypeEntite']; $values['supannAccount']['supannEntiteAffectation'][] = $entite['supannCodeEntite']; $values['supannAccount']['supannRoleEntite'][] =
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
'[role='.$fonctionOccupee->fonctionRh.']'. '[type='.$entite['supannTypeEntite'].']'. '[code='.$entite['supannCodeEntite'].']'; } } } } } foreach (array('supannRefId','supannEntiteAffectation','supannRoleGenerique','supannTypeEntiteAffectation','supannRoleEntite','supannActivite') as $arrayattribute) { $values['supannAccount'][$arrayattribute] = array_values(array_unique($values['supannAccount'][$arrayattribute])); } return $values; } protected function convertAddress(SimpleXMLElement $address) { $adresse = ''; if (!empty($address->adresseFR)) { if (!empty($address->adresseFR->batiment)) { $adresse .= $address->adresseFR->batiment; if (!empty($address->adresseFR->etage)) { $adresse .= ', '.$address->adresseFR->etage; } $adresse .= "\n"; } $adresse .= $address->adresseFR->numeroVoie; if (!empty($address->adresseFR->codeBTQC)) { $adresse .= ' '.$address->adresseFR->codeBTQC; } $adresse .= ' '.$address->adresseFR->typeVoie; $adresse .= ' '.$address->adresseFR->nomVoie; $adresse .= "\n"; if (!empty($address->adresseFR->complement)) { $adresse .= $address->adresseFR->complement."\n"; } if (!empty($address->adresseFR->lieuDit)) { $adresse .= $address->adresseFR->lieuDit."\n"; } $adresse .= $address->adresseFR->codePostal; $adresse .= ' '.$address->adresseFR->BD; $adresse .= "\n"; $adresse .= "FRANCE\n"; } elseif (!empty($address->adresseEtr)) { if (!empty($address->adresseEtr->batiment)) { $adresse .= $address->adresseEtr->batiment; if (!empty($address->adresseEtr->etage)) { $adresse .= ', '.$address->adresseEtr->etage; } $adresse .= "\n"; } $adresse .= $address->adresseEtr->numeroVoie; $adresse .= ' '.$address->adresseEtr->nomVoie; $adresse .= "\n"; if (!empty($address->adresseEtr->complement)) { $adresse .= $address->adresseEtr->complement."\n"; } $adresse .= $address->adresseEtr->codePostal; $adresse .= ' '.$address->adresseEtr->ville; $adresse .= "\n"; $adresse .= $address->adresseEtr->etat."\n"; $adresse .= $address->adresseEtr->pays."\n"; } else { $adresse = FALSE; } return $adresse; }
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
protected function checkValidite(SimpleXMLElement $object, DateTime $now) { if ($object->dateDebutValidite) { $dateDebutValidite = new DateTime($object->dateDebutValidite); if ($dateDebutValidite >= $now) { // Object is not valid yet, skip it return FALSE; } } if ($object->dateFinValidite) { $dateFinValidite = new DateTime($object->dateFinValidite); if ($dateFinValidite < $now) { // Object is not valid anymore, skip it return FALSE; } } return TRUE; } protected function getUUIDFromReferenceCroisee($identifiantApplication, $referenceCroisee) { foreach ($referenceCroisee->identifiantsExternes as $ref) { if ($ref->identifiantApplication == $identifiantApplication) { return $ref->identifiantExterne; } } return ''; } public static function genUUID() { //UUID v4 return sprintf( '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', // 32 bits for "time_low" mt_rand(0, 0xffff), mt_rand(0, 0xffff), // 16 bits for "time_mid" mt_rand(0, 0xffff), // 16 bits for "time_hi_and_version", // four most significant bits holds version number 4 mt_rand(0, 0x0fff) | 0x4000, // 16 bits, 8 bits for "clk_seq_hi_res", // 8 bits for "clk_seq_low", // two most significant bits holds zero and one for variant DCE1.1 mt_rand(0, 0x3fff) | 0x8000, // 48 bits for "node" mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) ); } }